1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2016 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;---------------------------------------------------------------------------
29 ;; Register numbers -- All machine registers should be defined here
31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (IP_REGNUM 12) ; Scratch register
34 (SP_REGNUM 13) ; Stack pointer
35 (LR_REGNUM 14) ; Return address register
36 (PC_REGNUM 15) ; Program counter
37 (LAST_ARM_REGNUM 15) ;
38 (CC_REGNUM 100) ; Condition code pseudo register
39 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
42 ;; 3rd operand to select_dominance_cc_mode
49 ;; conditional compare combination
60 ;;---------------------------------------------------------------------------
63 ;; Processor type. This is created automatically from arm-cores.def.
64 (include "arm-tune.md")
66 ;; Instruction classification types
69 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70 ; generating ARM code. This is used to control the length of some insn
71 ; patterns that share the same RTL in both ARM and Thumb code.
72 (define_attr "is_thumb" "yes,no"
73 (const (if_then_else (symbol_ref "TARGET_THUMB")
74 (const_string "yes") (const_string "no"))))
76 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
79 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
80 (define_attr "is_thumb1" "yes,no"
81 (const (if_then_else (symbol_ref "TARGET_THUMB1")
82 (const_string "yes") (const_string "no"))))
84 ; We use this attribute to disable alternatives that can produce 32-bit
85 ; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
86 ; that contain 32-bit instructions.
87 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
89 ; This attribute is used to disable a predicated alternative when we have
91 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
93 ;; Operand number of an input operand that is shifted. Zero if the
94 ;; given instruction does not shift one of its input operands.
95 (define_attr "shift" "" (const_int 0))
97 ;; [For compatibility with AArch64 in pipeline models]
98 ;; Attribute that specifies whether or not the instruction touches fp
100 (define_attr "fp" "no,yes" (const_string "no"))
102 ; Floating Point Unit. If we only have floating point emulation, then there
103 ; is no point in scheduling the floating point insns. (Well, for best
104 ; performance we should try and group them together).
105 (define_attr "fpu" "none,vfp"
106 (const (symbol_ref "arm_fpu_attr")))
108 ; Predicated means that the insn form is conditionally executed based on a
109 ; predicate. We default to 'no' because no Thumb patterns match this rule
110 ; and not all ARM insns do.
111 (define_attr "predicated" "yes,no" (const_string "no"))
113 ; LENGTH of an instruction (in bytes)
114 (define_attr "length" ""
117 ; The architecture which supports the instruction (or alternative).
118 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
119 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
120 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
121 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
122 ; Baseline. This attribute is used to compute attribute "enabled",
123 ; use type "any" to enable an alternative in all cases.
124 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
125 (const_string "any"))
127 (define_attr "arch_enabled" "no,yes"
128 (cond [(eq_attr "arch" "any")
131 (and (eq_attr "arch" "a")
132 (match_test "TARGET_ARM"))
135 (and (eq_attr "arch" "t")
136 (match_test "TARGET_THUMB"))
139 (and (eq_attr "arch" "t1")
140 (match_test "TARGET_THUMB1"))
143 (and (eq_attr "arch" "t2")
144 (match_test "TARGET_THUMB2"))
147 (and (eq_attr "arch" "32")
148 (match_test "TARGET_32BIT"))
151 (and (eq_attr "arch" "v6")
152 (match_test "TARGET_32BIT && arm_arch6"))
155 (and (eq_attr "arch" "nov6")
156 (match_test "TARGET_32BIT && !arm_arch6"))
159 (and (eq_attr "arch" "v6t2")
160 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
163 (and (eq_attr "arch" "v8mb")
164 (match_test "TARGET_THUMB1 && arm_arch8"))
167 (and (eq_attr "arch" "avoid_neon_for_64bits")
168 (match_test "TARGET_NEON")
169 (not (match_test "TARGET_PREFER_NEON_64BITS")))
172 (and (eq_attr "arch" "neon_for_64bits")
173 (match_test "TARGET_NEON")
174 (match_test "TARGET_PREFER_NEON_64BITS"))
177 (and (eq_attr "arch" "iwmmxt2")
178 (match_test "TARGET_REALLY_IWMMXT2"))
181 (and (eq_attr "arch" "armv6_or_vfpv3")
182 (match_test "arm_arch6 || TARGET_VFP3"))
185 (and (eq_attr "arch" "neon")
186 (match_test "TARGET_NEON"))
190 (const_string "no")))
192 (define_attr "opt" "any,speed,size"
193 (const_string "any"))
195 (define_attr "opt_enabled" "no,yes"
196 (cond [(eq_attr "opt" "any")
199 (and (eq_attr "opt" "speed")
200 (match_test "optimize_function_for_speed_p (cfun)"))
203 (and (eq_attr "opt" "size")
204 (match_test "optimize_function_for_size_p (cfun)"))
205 (const_string "yes")]
206 (const_string "no")))
208 (define_attr "use_literal_pool" "no,yes"
209 (cond [(and (eq_attr "type" "f_loads,f_loadd")
210 (match_test "CONSTANT_P (operands[1])"))
211 (const_string "yes")]
212 (const_string "no")))
214 ; Enable all alternatives that are both arch_enabled and insn_enabled.
215 ; FIXME:: opt_enabled has been temporarily removed till the time we have
216 ; an attribute that allows the use of such alternatives.
217 ; This depends on caching of speed_p, size_p on a per
218 ; alternative basis. The problem is that the enabled attribute
219 ; cannot depend on any state that is not cached or is not constant
220 ; for a compilation unit. We probably need a generic "hot/cold"
221 ; alternative which if implemented can help with this. We disable this
222 ; until such a time as this is implemented and / or the improvements or
223 ; regressions with removing this attribute are double checked.
224 ; See ashldi3_neon and <shift>di3_neon in neon.md.
226 (define_attr "enabled" "no,yes"
227 (cond [(and (eq_attr "predicable_short_it" "no")
228 (and (eq_attr "predicated" "yes")
229 (match_test "arm_restrict_it")))
232 (and (eq_attr "enabled_for_depr_it" "no")
233 (match_test "arm_restrict_it"))
236 (and (eq_attr "use_literal_pool" "yes")
237 (match_test "arm_disable_literal_pool"))
240 (eq_attr "arch_enabled" "no")
242 (const_string "yes")))
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed. If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address. It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
257 (define_attr "pool_range" ""
258 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259 (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262 (attr "arm_neg_pool_range")))
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268 [(set_attr "conds" "clob")
269 (set_attr "length" "4")
270 (set_attr "pool_range" "250")])
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions. It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
280 ; USE means that the condition codes are used by the insn in the process of
281 ; outputting code, this means (at present) that we can't use the insn in
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ; well defined manner.
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ; they are altered at all
290 ; UNCONDITIONAL means the instruction can not be conditionally executed and
291 ; that the instruction does not use or alter the condition codes.
293 ; NOCOND means that the instruction does not use or alter the condition
294 ; codes but can be converted into a conditionally exectuted instruction.
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
298 (ior (eq_attr "is_thumb1" "yes")
299 (eq_attr "type" "call"))
300 (const_string "clob")
301 (if_then_else (eq_attr "is_neon_type" "no")
302 (const_string "nocond")
303 (const_string "unconditional"))))
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by
307 ; gen...). We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
311 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
312 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor. Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320 (if_then_else (eq_attr "type"
323 (const_string "no")))
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328 (if_then_else (eq_attr "type"
329 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345 (const_string "single")
346 (const_string "multi")))
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label. Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
357 ;;---------------------------------------------------------------------------
360 (include "unspecs.md")
362 ;;---------------------------------------------------------------------------
365 (include "iterators.md")
367 ;;---------------------------------------------------------------------------
370 (include "predicates.md")
371 (include "constraints.md")
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
376 (define_attr "tune_cortexr4" "yes,no"
378 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
380 (const_string "no"))))
382 ;; True if the generic scheduling description should be used.
384 (define_attr "generic_sched" "yes,no"
386 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
388 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389 cortexa9,cortexa12,cortexa15,cortexa17,\
390 cortexa53,cortexa57,cortexm4,cortexm7,\
391 exynosm1,marvell_pj4,xgene1")
392 (eq_attr "tune_cortexr4" "yes"))
394 (const_string "yes"))))
396 (define_attr "generic_vfp" "yes,no"
398 (and (eq_attr "fpu" "vfp")
399 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
400 cortexa8,cortexa9,cortexa53,cortexm4,\
401 cortexm7,marvell_pj4,xgene1")
402 (eq_attr "tune_cortexr4" "no"))
404 (const_string "no"))))
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
436 ;;---------------------------------------------------------------------------
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
445 (define_expand "adddi3"
447 [(set (match_operand:DI 0 "s_register_operand" "")
448 (plus:DI (match_operand:DI 1 "s_register_operand" "")
449 (match_operand:DI 2 "arm_adddi_operand" "")))
450 (clobber (reg:CC CC_REGNUM))])]
455 if (!REG_P (operands[1]))
456 operands[1] = force_reg (DImode, operands[1]);
457 if (!REG_P (operands[2]))
458 operands[2] = force_reg (DImode, operands[2]);
463 (define_insn_and_split "*arm_adddi3"
464 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
465 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
466 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
467 (clobber (reg:CC CC_REGNUM))]
468 "TARGET_32BIT && !TARGET_NEON"
470 "TARGET_32BIT && reload_completed
471 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
472 [(parallel [(set (reg:CC_C CC_REGNUM)
473 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
475 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
476 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
477 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
480 operands[3] = gen_highpart (SImode, operands[0]);
481 operands[0] = gen_lowpart (SImode, operands[0]);
482 operands[4] = gen_highpart (SImode, operands[1]);
483 operands[1] = gen_lowpart (SImode, operands[1]);
484 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
485 operands[2] = gen_lowpart (SImode, operands[2]);
487 [(set_attr "conds" "clob")
488 (set_attr "length" "8")
489 (set_attr "type" "multiple")]
492 (define_insn_and_split "*adddi_sesidi_di"
493 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
494 (plus:DI (sign_extend:DI
495 (match_operand:SI 2 "s_register_operand" "r,r"))
496 (match_operand:DI 1 "s_register_operand" "0,r")))
497 (clobber (reg:CC CC_REGNUM))]
500 "TARGET_32BIT && reload_completed"
501 [(parallel [(set (reg:CC_C CC_REGNUM)
502 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
504 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
505 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
508 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
511 operands[3] = gen_highpart (SImode, operands[0]);
512 operands[0] = gen_lowpart (SImode, operands[0]);
513 operands[4] = gen_highpart (SImode, operands[1]);
514 operands[1] = gen_lowpart (SImode, operands[1]);
515 operands[2] = gen_lowpart (SImode, operands[2]);
517 [(set_attr "conds" "clob")
518 (set_attr "length" "8")
519 (set_attr "type" "multiple")]
522 (define_insn_and_split "*adddi_zesidi_di"
523 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
524 (plus:DI (zero_extend:DI
525 (match_operand:SI 2 "s_register_operand" "r,r"))
526 (match_operand:DI 1 "s_register_operand" "0,r")))
527 (clobber (reg:CC CC_REGNUM))]
530 "TARGET_32BIT && reload_completed"
531 [(parallel [(set (reg:CC_C CC_REGNUM)
532 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
534 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
535 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
536 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
539 operands[3] = gen_highpart (SImode, operands[0]);
540 operands[0] = gen_lowpart (SImode, operands[0]);
541 operands[4] = gen_highpart (SImode, operands[1]);
542 operands[1] = gen_lowpart (SImode, operands[1]);
543 operands[2] = gen_lowpart (SImode, operands[2]);
545 [(set_attr "conds" "clob")
546 (set_attr "length" "8")
547 (set_attr "type" "multiple")]
550 (define_expand "addv<mode>4"
551 [(match_operand:SIDI 0 "register_operand")
552 (match_operand:SIDI 1 "register_operand")
553 (match_operand:SIDI 2 "register_operand")
554 (match_operand 3 "")]
557 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
558 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
563 (define_expand "uaddv<mode>4"
564 [(match_operand:SIDI 0 "register_operand")
565 (match_operand:SIDI 1 "register_operand")
566 (match_operand:SIDI 2 "register_operand")
567 (match_operand 3 "")]
570 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
571 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
576 (define_expand "addsi3"
577 [(set (match_operand:SI 0 "s_register_operand" "")
578 (plus:SI (match_operand:SI 1 "s_register_operand" "")
579 (match_operand:SI 2 "reg_or_int_operand" "")))]
582 if (TARGET_32BIT && CONST_INT_P (operands[2]))
584 arm_split_constant (PLUS, SImode, NULL_RTX,
585 INTVAL (operands[2]), operands[0], operands[1],
586 optimize && can_create_pseudo_p ());
592 ; If there is a scratch available, this will be faster than synthesizing the
595 [(match_scratch:SI 3 "r")
596 (set (match_operand:SI 0 "arm_general_register_operand" "")
597 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
598 (match_operand:SI 2 "const_int_operand" "")))]
600 !(const_ok_for_arm (INTVAL (operands[2]))
601 || const_ok_for_arm (-INTVAL (operands[2])))
602 && const_ok_for_arm (~INTVAL (operands[2]))"
603 [(set (match_dup 3) (match_dup 2))
604 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
608 ;; The r/r/k alternative is required when reloading the address
609 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
610 ;; put the duplicated register first, and not try the commutative version.
611 (define_insn_and_split "*arm_addsi3"
612 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
613 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
614 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
629 subw%?\\t%0, %1, #%n2
630 subw%?\\t%0, %1, #%n2
633 && CONST_INT_P (operands[2])
634 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
635 && (reload_completed || !arm_eliminable_register (operands[1]))"
636 [(clobber (const_int 0))]
638 arm_split_constant (PLUS, SImode, curr_insn,
639 INTVAL (operands[2]), operands[0],
643 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
644 (set_attr "predicable" "yes")
645 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
646 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
647 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
648 (const_string "alu_imm")
649 (const_string "alu_sreg")))
653 (define_insn_and_split "adddi3_compareV"
654 [(set (reg:CC_V CC_REGNUM)
657 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
658 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
659 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
660 (set (match_operand:DI 0 "register_operand" "=&r")
661 (plus:DI (match_dup 1) (match_dup 2)))]
664 "&& reload_completed"
665 [(parallel [(set (reg:CC_C CC_REGNUM)
666 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
668 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
669 (parallel [(set (reg:CC_V CC_REGNUM)
672 (sign_extend:DI (match_dup 4))
673 (sign_extend:DI (match_dup 5)))
674 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
675 (plus:DI (sign_extend:DI
676 (plus:SI (match_dup 4) (match_dup 5)))
677 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
678 (set (match_dup 3) (plus:SI (plus:SI
679 (match_dup 4) (match_dup 5))
680 (ltu:SI (reg:CC_C CC_REGNUM)
684 operands[3] = gen_highpart (SImode, operands[0]);
685 operands[0] = gen_lowpart (SImode, operands[0]);
686 operands[4] = gen_highpart (SImode, operands[1]);
687 operands[1] = gen_lowpart (SImode, operands[1]);
688 operands[5] = gen_highpart (SImode, operands[2]);
689 operands[2] = gen_lowpart (SImode, operands[2]);
691 [(set_attr "conds" "set")
692 (set_attr "length" "8")
693 (set_attr "type" "multiple")]
696 (define_insn "addsi3_compareV"
697 [(set (reg:CC_V CC_REGNUM)
700 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
701 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
702 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
703 (set (match_operand:SI 0 "register_operand" "=r")
704 (plus:SI (match_dup 1) (match_dup 2)))]
706 "adds%?\\t%0, %1, %2"
707 [(set_attr "conds" "set")
708 (set_attr "type" "alus_sreg")]
711 (define_insn "*addsi3_compareV_upper"
712 [(set (reg:CC_V CC_REGNUM)
716 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
717 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
718 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
719 (plus:DI (sign_extend:DI
720 (plus:SI (match_dup 1) (match_dup 2)))
721 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
722 (set (match_operand:SI 0 "register_operand" "=r")
724 (plus:SI (match_dup 1) (match_dup 2))
725 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
727 "adcs%?\\t%0, %1, %2"
728 [(set_attr "conds" "set")
729 (set_attr "type" "adcs_reg")]
732 (define_insn_and_split "adddi3_compareC"
733 [(set (reg:CC_C CC_REGNUM)
736 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
737 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
738 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
739 (set (match_operand:DI 0 "register_operand" "=&r")
740 (plus:DI (match_dup 1) (match_dup 2)))]
743 "&& reload_completed"
744 [(parallel [(set (reg:CC_C CC_REGNUM)
745 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
747 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
748 (parallel [(set (reg:CC_C CC_REGNUM)
751 (zero_extend:DI (match_dup 4))
752 (zero_extend:DI (match_dup 5)))
753 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
754 (plus:DI (zero_extend:DI
755 (plus:SI (match_dup 4) (match_dup 5)))
756 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
757 (set (match_dup 3) (plus:SI
758 (plus:SI (match_dup 4) (match_dup 5))
759 (ltu:SI (reg:CC_C CC_REGNUM)
763 operands[3] = gen_highpart (SImode, operands[0]);
764 operands[0] = gen_lowpart (SImode, operands[0]);
765 operands[4] = gen_highpart (SImode, operands[1]);
766 operands[5] = gen_highpart (SImode, operands[2]);
767 operands[1] = gen_lowpart (SImode, operands[1]);
768 operands[2] = gen_lowpart (SImode, operands[2]);
770 [(set_attr "conds" "set")
771 (set_attr "length" "8")
772 (set_attr "type" "multiple")]
775 (define_insn "*addsi3_compareC_upper"
776 [(set (reg:CC_C CC_REGNUM)
780 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
781 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
782 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
783 (plus:DI (zero_extend:DI
784 (plus:SI (match_dup 1) (match_dup 2)))
785 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
786 (set (match_operand:SI 0 "register_operand" "=r")
788 (plus:SI (match_dup 1) (match_dup 2))
789 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
791 "adcs%?\\t%0, %1, %2"
792 [(set_attr "conds" "set")
793 (set_attr "type" "adcs_reg")]
796 (define_insn "addsi3_compareC"
797 [(set (reg:CC_C CC_REGNUM)
800 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
801 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
803 (plus:SI (match_dup 1) (match_dup 2)))))
804 (set (match_operand:SI 0 "register_operand" "=r")
805 (plus:SI (match_dup 1) (match_dup 2)))]
807 "adds%?\\t%0, %1, %2"
808 [(set_attr "conds" "set")
809 (set_attr "type" "alus_sreg")]
812 (define_insn "addsi3_compare0"
813 [(set (reg:CC_NOOV CC_REGNUM)
815 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
816 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
818 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
819 (plus:SI (match_dup 1) (match_dup 2)))]
823 subs%?\\t%0, %1, #%n2
825 [(set_attr "conds" "set")
826 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
829 (define_insn "*addsi3_compare0_scratch"
830 [(set (reg:CC_NOOV CC_REGNUM)
832 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
833 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
840 [(set_attr "conds" "set")
841 (set_attr "predicable" "yes")
842 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
845 (define_insn "*compare_negsi_si"
846 [(set (reg:CC_Z CC_REGNUM)
848 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
849 (match_operand:SI 1 "s_register_operand" "l,r")))]
852 [(set_attr "conds" "set")
853 (set_attr "predicable" "yes")
854 (set_attr "arch" "t2,*")
855 (set_attr "length" "2,4")
856 (set_attr "predicable_short_it" "yes,no")
857 (set_attr "type" "alus_sreg")]
860 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
861 ;; addend is a constant.
862 (define_insn "cmpsi2_addneg"
863 [(set (reg:CC CC_REGNUM)
865 (match_operand:SI 1 "s_register_operand" "r,r")
866 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
867 (set (match_operand:SI 0 "s_register_operand" "=r,r")
868 (plus:SI (match_dup 1)
869 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
870 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
873 subs%?\\t%0, %1, #%n3"
874 [(set_attr "conds" "set")
875 (set_attr "type" "alus_sreg")]
878 ;; Convert the sequence
880 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
884 ;; bcs dest ((unsigned)rn >= 1)
885 ;; similarly for the beq variant using bcc.
886 ;; This is a common looping idiom (while (n--))
888 [(set (match_operand:SI 0 "arm_general_register_operand" "")
889 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
891 (set (match_operand 2 "cc_register" "")
892 (compare (match_dup 0) (const_int -1)))
894 (if_then_else (match_operator 3 "equality_operator"
895 [(match_dup 2) (const_int 0)])
896 (match_operand 4 "" "")
897 (match_operand 5 "" "")))]
898 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
902 (match_dup 1) (const_int 1)))
903 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
905 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
908 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
909 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
912 operands[2], const0_rtx);"
915 ;; The next four insns work because they compare the result with one of
916 ;; the operands, and we know that the use of the condition code is
917 ;; either GEU or LTU, so we can use the carry flag from the addition
918 ;; instead of doing the compare a second time.
919 (define_insn "*addsi3_compare_op1"
920 [(set (reg:CC_C CC_REGNUM)
922 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
923 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
925 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
926 (plus:SI (match_dup 1) (match_dup 2)))]
930 subs%?\\t%0, %1, #%n2
932 [(set_attr "conds" "set")
933 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
936 (define_insn "*addsi3_compare_op2"
937 [(set (reg:CC_C CC_REGNUM)
939 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
940 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
942 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
943 (plus:SI (match_dup 1) (match_dup 2)))]
947 subs%?\\t%0, %1, #%n2
949 [(set_attr "conds" "set")
950 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
953 (define_insn "*compare_addsi2_op0"
954 [(set (reg:CC_C CC_REGNUM)
956 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
957 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
966 [(set_attr "conds" "set")
967 (set_attr "predicable" "yes")
968 (set_attr "arch" "t2,t2,*,*,*")
969 (set_attr "predicable_short_it" "yes,yes,no,no,no")
970 (set_attr "length" "2,2,4,4,4")
971 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
974 (define_insn "*compare_addsi2_op1"
975 [(set (reg:CC_C CC_REGNUM)
977 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
978 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
987 [(set_attr "conds" "set")
988 (set_attr "predicable" "yes")
989 (set_attr "arch" "t2,t2,*,*,*")
990 (set_attr "predicable_short_it" "yes,yes,no,no,no")
991 (set_attr "length" "2,2,4,4,4")
992 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
995 (define_insn "*addsi3_carryin_<optab>"
996 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
997 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
998 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
999 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1004 sbc%?\\t%0, %1, #%B2"
1005 [(set_attr "conds" "use")
1006 (set_attr "predicable" "yes")
1007 (set_attr "arch" "t2,*,*")
1008 (set_attr "length" "4")
1009 (set_attr "predicable_short_it" "yes,no,no")
1010 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1013 (define_insn "*addsi3_carryin_alt2_<optab>"
1014 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1015 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1016 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1017 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1022 sbc%?\\t%0, %1, #%B2"
1023 [(set_attr "conds" "use")
1024 (set_attr "predicable" "yes")
1025 (set_attr "arch" "t2,*,*")
1026 (set_attr "length" "4")
1027 (set_attr "predicable_short_it" "yes,no,no")
1028 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1031 (define_insn "*addsi3_carryin_shift_<optab>"
1032 [(set (match_operand:SI 0 "s_register_operand" "=r")
1034 (match_operator:SI 2 "shift_operator"
1035 [(match_operand:SI 3 "s_register_operand" "r")
1036 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1037 (match_operand:SI 1 "s_register_operand" "r"))
1038 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1040 "adc%?\\t%0, %1, %3%S2"
1041 [(set_attr "conds" "use")
1042 (set_attr "predicable" "yes")
1043 (set_attr "predicable_short_it" "no")
1044 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1045 (const_string "alu_shift_imm")
1046 (const_string "alu_shift_reg")))]
1049 (define_insn "*addsi3_carryin_clobercc_<optab>"
1050 [(set (match_operand:SI 0 "s_register_operand" "=r")
1051 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1052 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1053 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1054 (clobber (reg:CC CC_REGNUM))]
1056 "adcs%?\\t%0, %1, %2"
1057 [(set_attr "conds" "set")
1058 (set_attr "type" "adcs_reg")]
1061 (define_expand "subv<mode>4"
1062 [(match_operand:SIDI 0 "register_operand")
1063 (match_operand:SIDI 1 "register_operand")
1064 (match_operand:SIDI 2 "register_operand")
1065 (match_operand 3 "")]
1068 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1069 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1074 (define_expand "usubv<mode>4"
1075 [(match_operand:SIDI 0 "register_operand")
1076 (match_operand:SIDI 1 "register_operand")
1077 (match_operand:SIDI 2 "register_operand")
1078 (match_operand 3 "")]
1081 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1082 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1087 (define_insn_and_split "subdi3_compare1"
1088 [(set (reg:CC CC_REGNUM)
1090 (match_operand:DI 1 "register_operand" "r")
1091 (match_operand:DI 2 "register_operand" "r")))
1092 (set (match_operand:DI 0 "register_operand" "=&r")
1093 (minus:DI (match_dup 1) (match_dup 2)))]
1096 "&& reload_completed"
1097 [(parallel [(set (reg:CC CC_REGNUM)
1098 (compare:CC (match_dup 1) (match_dup 2)))
1099 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1100 (parallel [(set (reg:CC CC_REGNUM)
1101 (compare:CC (match_dup 4) (match_dup 5)))
1102 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1103 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1105 operands[3] = gen_highpart (SImode, operands[0]);
1106 operands[0] = gen_lowpart (SImode, operands[0]);
1107 operands[4] = gen_highpart (SImode, operands[1]);
1108 operands[1] = gen_lowpart (SImode, operands[1]);
1109 operands[5] = gen_highpart (SImode, operands[2]);
1110 operands[2] = gen_lowpart (SImode, operands[2]);
1112 [(set_attr "conds" "set")
1113 (set_attr "length" "8")
1114 (set_attr "type" "multiple")]
1117 (define_insn "subsi3_compare1"
1118 [(set (reg:CC CC_REGNUM)
1120 (match_operand:SI 1 "register_operand" "r")
1121 (match_operand:SI 2 "register_operand" "r")))
1122 (set (match_operand:SI 0 "register_operand" "=r")
1123 (minus:SI (match_dup 1) (match_dup 2)))]
1125 "subs%?\\t%0, %1, %2"
1126 [(set_attr "conds" "set")
1127 (set_attr "type" "alus_sreg")]
1130 (define_insn "*subsi3_carryin"
1131 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1132 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
1133 (match_operand:SI 2 "s_register_operand" "r,r"))
1134 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1139 [(set_attr "conds" "use")
1140 (set_attr "arch" "*,a")
1141 (set_attr "predicable" "yes")
1142 (set_attr "predicable_short_it" "no")
1143 (set_attr "type" "adc_reg,adc_imm")]
1146 (define_insn "*subsi3_carryin_const"
1147 [(set (match_operand:SI 0 "s_register_operand" "=r")
1148 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1149 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1150 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1152 "sbc\\t%0, %1, #%B2"
1153 [(set_attr "conds" "use")
1154 (set_attr "type" "adc_imm")]
1157 (define_insn "*subsi3_carryin_compare"
1158 [(set (reg:CC CC_REGNUM)
1159 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1160 (match_operand:SI 2 "s_register_operand" "r")))
1161 (set (match_operand:SI 0 "s_register_operand" "=r")
1162 (minus:SI (minus:SI (match_dup 1)
1164 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1167 [(set_attr "conds" "set")
1168 (set_attr "type" "adcs_reg")]
1171 (define_insn "*subsi3_carryin_compare_const"
1172 [(set (reg:CC CC_REGNUM)
1173 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1174 (match_operand:SI 2 "arm_not_operand" "K")))
1175 (set (match_operand:SI 0 "s_register_operand" "=r")
1176 (minus:SI (plus:SI (match_dup 1)
1178 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1180 "sbcs\\t%0, %1, #%B2"
1181 [(set_attr "conds" "set")
1182 (set_attr "type" "adcs_imm")]
1185 (define_insn "*subsi3_carryin_shift"
1186 [(set (match_operand:SI 0 "s_register_operand" "=r")
1188 (match_operand:SI 1 "s_register_operand" "r")
1189 (match_operator:SI 2 "shift_operator"
1190 [(match_operand:SI 3 "s_register_operand" "r")
1191 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1192 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1194 "sbc%?\\t%0, %1, %3%S2"
1195 [(set_attr "conds" "use")
1196 (set_attr "predicable" "yes")
1197 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1198 (const_string "alu_shift_imm")
1199 (const_string "alu_shift_reg")))]
1202 (define_insn "*rsbsi3_carryin_shift"
1203 [(set (match_operand:SI 0 "s_register_operand" "=r")
1205 (match_operator:SI 2 "shift_operator"
1206 [(match_operand:SI 3 "s_register_operand" "r")
1207 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1208 (match_operand:SI 1 "s_register_operand" "r"))
1209 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1211 "rsc%?\\t%0, %1, %3%S2"
1212 [(set_attr "conds" "use")
1213 (set_attr "predicable" "yes")
1214 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1215 (const_string "alu_shift_imm")
1216 (const_string "alu_shift_reg")))]
1219 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1221 [(set (match_operand:SI 0 "s_register_operand" "")
1222 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1223 (match_operand:SI 2 "s_register_operand" ""))
1225 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1227 [(set (match_dup 3) (match_dup 1))
1228 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1230 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1233 (define_expand "addsf3"
1234 [(set (match_operand:SF 0 "s_register_operand" "")
1235 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1236 (match_operand:SF 2 "s_register_operand" "")))]
1237 "TARGET_32BIT && TARGET_HARD_FLOAT"
1241 (define_expand "adddf3"
1242 [(set (match_operand:DF 0 "s_register_operand" "")
1243 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1244 (match_operand:DF 2 "s_register_operand" "")))]
1245 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1249 (define_expand "subdi3"
1251 [(set (match_operand:DI 0 "s_register_operand" "")
1252 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1253 (match_operand:DI 2 "s_register_operand" "")))
1254 (clobber (reg:CC CC_REGNUM))])]
1259 if (!REG_P (operands[1]))
1260 operands[1] = force_reg (DImode, operands[1]);
1261 if (!REG_P (operands[2]))
1262 operands[2] = force_reg (DImode, operands[2]);
1267 (define_insn_and_split "*arm_subdi3"
1268 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1269 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1270 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1271 (clobber (reg:CC CC_REGNUM))]
1272 "TARGET_32BIT && !TARGET_NEON"
1273 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1274 "&& reload_completed"
1275 [(parallel [(set (reg:CC CC_REGNUM)
1276 (compare:CC (match_dup 1) (match_dup 2)))
1277 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1278 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1279 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1281 operands[3] = gen_highpart (SImode, operands[0]);
1282 operands[0] = gen_lowpart (SImode, operands[0]);
1283 operands[4] = gen_highpart (SImode, operands[1]);
1284 operands[1] = gen_lowpart (SImode, operands[1]);
1285 operands[5] = gen_highpart (SImode, operands[2]);
1286 operands[2] = gen_lowpart (SImode, operands[2]);
1288 [(set_attr "conds" "clob")
1289 (set_attr "length" "8")
1290 (set_attr "type" "multiple")]
1293 (define_insn_and_split "*subdi_di_zesidi"
1294 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1295 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1297 (match_operand:SI 2 "s_register_operand" "r,r"))))
1298 (clobber (reg:CC CC_REGNUM))]
1300 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1301 "&& reload_completed"
1302 [(parallel [(set (reg:CC CC_REGNUM)
1303 (compare:CC (match_dup 1) (match_dup 2)))
1304 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1305 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1306 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1308 operands[3] = gen_highpart (SImode, operands[0]);
1309 operands[0] = gen_lowpart (SImode, operands[0]);
1310 operands[4] = gen_highpart (SImode, operands[1]);
1311 operands[1] = gen_lowpart (SImode, operands[1]);
1312 operands[5] = GEN_INT (~0);
1314 [(set_attr "conds" "clob")
1315 (set_attr "length" "8")
1316 (set_attr "type" "multiple")]
1319 (define_insn_and_split "*subdi_di_sesidi"
1320 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1321 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1323 (match_operand:SI 2 "s_register_operand" "r,r"))))
1324 (clobber (reg:CC CC_REGNUM))]
1326 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1327 "&& reload_completed"
1328 [(parallel [(set (reg:CC CC_REGNUM)
1329 (compare:CC (match_dup 1) (match_dup 2)))
1330 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1331 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1332 (ashiftrt:SI (match_dup 2)
1334 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1336 operands[3] = gen_highpart (SImode, operands[0]);
1337 operands[0] = gen_lowpart (SImode, operands[0]);
1338 operands[4] = gen_highpart (SImode, operands[1]);
1339 operands[1] = gen_lowpart (SImode, operands[1]);
1341 [(set_attr "conds" "clob")
1342 (set_attr "length" "8")
1343 (set_attr "type" "multiple")]
1346 (define_insn_and_split "*subdi_zesidi_di"
1347 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1348 (minus:DI (zero_extend:DI
1349 (match_operand:SI 2 "s_register_operand" "r,r"))
1350 (match_operand:DI 1 "s_register_operand" "0,r")))
1351 (clobber (reg:CC CC_REGNUM))]
1353 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1355 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1356 "&& reload_completed"
1357 [(parallel [(set (reg:CC CC_REGNUM)
1358 (compare:CC (match_dup 2) (match_dup 1)))
1359 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1360 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1361 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1363 operands[3] = gen_highpart (SImode, operands[0]);
1364 operands[0] = gen_lowpart (SImode, operands[0]);
1365 operands[4] = gen_highpart (SImode, operands[1]);
1366 operands[1] = gen_lowpart (SImode, operands[1]);
1368 [(set_attr "conds" "clob")
1369 (set_attr "length" "8")
1370 (set_attr "type" "multiple")]
1373 (define_insn_and_split "*subdi_sesidi_di"
1374 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1375 (minus:DI (sign_extend:DI
1376 (match_operand:SI 2 "s_register_operand" "r,r"))
1377 (match_operand:DI 1 "s_register_operand" "0,r")))
1378 (clobber (reg:CC CC_REGNUM))]
1380 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1382 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1383 "&& reload_completed"
1384 [(parallel [(set (reg:CC CC_REGNUM)
1385 (compare:CC (match_dup 2) (match_dup 1)))
1386 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1387 (set (match_dup 3) (minus:SI (minus:SI
1388 (ashiftrt:SI (match_dup 2)
1391 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1393 operands[3] = gen_highpart (SImode, operands[0]);
1394 operands[0] = gen_lowpart (SImode, operands[0]);
1395 operands[4] = gen_highpart (SImode, operands[1]);
1396 operands[1] = gen_lowpart (SImode, operands[1]);
1398 [(set_attr "conds" "clob")
1399 (set_attr "length" "8")
1400 (set_attr "type" "multiple")]
1403 (define_insn_and_split "*subdi_zesidi_zesidi"
1404 [(set (match_operand:DI 0 "s_register_operand" "=r")
1405 (minus:DI (zero_extend:DI
1406 (match_operand:SI 1 "s_register_operand" "r"))
1408 (match_operand:SI 2 "s_register_operand" "r"))))
1409 (clobber (reg:CC CC_REGNUM))]
1411 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1412 "&& reload_completed"
1413 [(parallel [(set (reg:CC CC_REGNUM)
1414 (compare:CC (match_dup 1) (match_dup 2)))
1415 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1416 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1417 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1419 operands[3] = gen_highpart (SImode, operands[0]);
1420 operands[0] = gen_lowpart (SImode, operands[0]);
1422 [(set_attr "conds" "clob")
1423 (set_attr "length" "8")
1424 (set_attr "type" "multiple")]
1427 (define_expand "subsi3"
1428 [(set (match_operand:SI 0 "s_register_operand" "")
1429 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1430 (match_operand:SI 2 "s_register_operand" "")))]
1433 if (CONST_INT_P (operands[1]))
1437 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1438 operands[1] = force_reg (SImode, operands[1]);
1441 arm_split_constant (MINUS, SImode, NULL_RTX,
1442 INTVAL (operands[1]), operands[0],
1444 optimize && can_create_pseudo_p ());
1448 else /* TARGET_THUMB1 */
1449 operands[1] = force_reg (SImode, operands[1]);
1454 ; ??? Check Thumb-2 split length
1455 (define_insn_and_split "*arm_subsi3_insn"
1456 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1457 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1458 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1470 "&& (CONST_INT_P (operands[1])
1471 && !const_ok_for_arm (INTVAL (operands[1])))"
1472 [(clobber (const_int 0))]
1474 arm_split_constant (MINUS, SImode, curr_insn,
1475 INTVAL (operands[1]), operands[0], operands[2], 0);
1478 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1479 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1480 (set_attr "predicable" "yes")
1481 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1482 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1486 [(match_scratch:SI 3 "r")
1487 (set (match_operand:SI 0 "arm_general_register_operand" "")
1488 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1489 (match_operand:SI 2 "arm_general_register_operand" "")))]
1491 && !const_ok_for_arm (INTVAL (operands[1]))
1492 && const_ok_for_arm (~INTVAL (operands[1]))"
1493 [(set (match_dup 3) (match_dup 1))
1494 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1498 (define_insn "subsi3_compare0"
1499 [(set (reg:CC_NOOV CC_REGNUM)
1501 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1502 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1504 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1505 (minus:SI (match_dup 1) (match_dup 2)))]
1510 rsbs%?\\t%0, %2, %1"
1511 [(set_attr "conds" "set")
1512 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1515 (define_insn "subsi3_compare"
1516 [(set (reg:CC CC_REGNUM)
1517 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1518 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1519 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1520 (minus:SI (match_dup 1) (match_dup 2)))]
1525 rsbs%?\\t%0, %2, %1"
1526 [(set_attr "conds" "set")
1527 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1530 (define_expand "subsf3"
1531 [(set (match_operand:SF 0 "s_register_operand" "")
1532 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1533 (match_operand:SF 2 "s_register_operand" "")))]
1534 "TARGET_32BIT && TARGET_HARD_FLOAT"
1538 (define_expand "subdf3"
1539 [(set (match_operand:DF 0 "s_register_operand" "")
1540 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1541 (match_operand:DF 2 "s_register_operand" "")))]
1542 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1547 ;; Multiplication insns
1549 (define_expand "mulhi3"
1550 [(set (match_operand:HI 0 "s_register_operand" "")
1551 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1552 (match_operand:HI 2 "s_register_operand" "")))]
1553 "TARGET_DSP_MULTIPLY"
1556 rtx result = gen_reg_rtx (SImode);
1557 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1558 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1563 (define_expand "mulsi3"
1564 [(set (match_operand:SI 0 "s_register_operand" "")
1565 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1566 (match_operand:SI 1 "s_register_operand" "")))]
1571 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1572 (define_insn "*arm_mulsi3"
1573 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1574 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1575 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1576 "TARGET_32BIT && !arm_arch6"
1577 "mul%?\\t%0, %2, %1"
1578 [(set_attr "type" "mul")
1579 (set_attr "predicable" "yes")]
1582 (define_insn "*arm_mulsi3_v6"
1583 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1584 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1585 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1586 "TARGET_32BIT && arm_arch6"
1587 "mul%?\\t%0, %1, %2"
1588 [(set_attr "type" "mul")
1589 (set_attr "predicable" "yes")
1590 (set_attr "arch" "t2,t2,*")
1591 (set_attr "length" "4")
1592 (set_attr "predicable_short_it" "yes,yes,no")]
1595 (define_insn "*mulsi3_compare0"
1596 [(set (reg:CC_NOOV CC_REGNUM)
1597 (compare:CC_NOOV (mult:SI
1598 (match_operand:SI 2 "s_register_operand" "r,r")
1599 (match_operand:SI 1 "s_register_operand" "%0,r"))
1601 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1602 (mult:SI (match_dup 2) (match_dup 1)))]
1603 "TARGET_ARM && !arm_arch6"
1604 "muls%?\\t%0, %2, %1"
1605 [(set_attr "conds" "set")
1606 (set_attr "type" "muls")]
1609 (define_insn "*mulsi3_compare0_v6"
1610 [(set (reg:CC_NOOV CC_REGNUM)
1611 (compare:CC_NOOV (mult:SI
1612 (match_operand:SI 2 "s_register_operand" "r")
1613 (match_operand:SI 1 "s_register_operand" "r"))
1615 (set (match_operand:SI 0 "s_register_operand" "=r")
1616 (mult:SI (match_dup 2) (match_dup 1)))]
1617 "TARGET_ARM && arm_arch6 && optimize_size"
1618 "muls%?\\t%0, %2, %1"
1619 [(set_attr "conds" "set")
1620 (set_attr "type" "muls")]
1623 (define_insn "*mulsi_compare0_scratch"
1624 [(set (reg:CC_NOOV CC_REGNUM)
1625 (compare:CC_NOOV (mult:SI
1626 (match_operand:SI 2 "s_register_operand" "r,r")
1627 (match_operand:SI 1 "s_register_operand" "%0,r"))
1629 (clobber (match_scratch:SI 0 "=&r,&r"))]
1630 "TARGET_ARM && !arm_arch6"
1631 "muls%?\\t%0, %2, %1"
1632 [(set_attr "conds" "set")
1633 (set_attr "type" "muls")]
1636 (define_insn "*mulsi_compare0_scratch_v6"
1637 [(set (reg:CC_NOOV CC_REGNUM)
1638 (compare:CC_NOOV (mult:SI
1639 (match_operand:SI 2 "s_register_operand" "r")
1640 (match_operand:SI 1 "s_register_operand" "r"))
1642 (clobber (match_scratch:SI 0 "=r"))]
1643 "TARGET_ARM && arm_arch6 && optimize_size"
1644 "muls%?\\t%0, %2, %1"
1645 [(set_attr "conds" "set")
1646 (set_attr "type" "muls")]
1649 ;; Unnamed templates to match MLA instruction.
1651 (define_insn "*mulsi3addsi"
1652 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1654 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1655 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1656 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1657 "TARGET_32BIT && !arm_arch6"
1658 "mla%?\\t%0, %2, %1, %3"
1659 [(set_attr "type" "mla")
1660 (set_attr "predicable" "yes")]
1663 (define_insn "*mulsi3addsi_v6"
1664 [(set (match_operand:SI 0 "s_register_operand" "=r")
1666 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1667 (match_operand:SI 1 "s_register_operand" "r"))
1668 (match_operand:SI 3 "s_register_operand" "r")))]
1669 "TARGET_32BIT && arm_arch6"
1670 "mla%?\\t%0, %2, %1, %3"
1671 [(set_attr "type" "mla")
1672 (set_attr "predicable" "yes")
1673 (set_attr "predicable_short_it" "no")]
1676 (define_insn "*mulsi3addsi_compare0"
1677 [(set (reg:CC_NOOV CC_REGNUM)
1680 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1681 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1682 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1684 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1685 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1687 "TARGET_ARM && arm_arch6"
1688 "mlas%?\\t%0, %2, %1, %3"
1689 [(set_attr "conds" "set")
1690 (set_attr "type" "mlas")]
1693 (define_insn "*mulsi3addsi_compare0_v6"
1694 [(set (reg:CC_NOOV CC_REGNUM)
1697 (match_operand:SI 2 "s_register_operand" "r")
1698 (match_operand:SI 1 "s_register_operand" "r"))
1699 (match_operand:SI 3 "s_register_operand" "r"))
1701 (set (match_operand:SI 0 "s_register_operand" "=r")
1702 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1704 "TARGET_ARM && arm_arch6 && optimize_size"
1705 "mlas%?\\t%0, %2, %1, %3"
1706 [(set_attr "conds" "set")
1707 (set_attr "type" "mlas")]
1710 (define_insn "*mulsi3addsi_compare0_scratch"
1711 [(set (reg:CC_NOOV CC_REGNUM)
1714 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1715 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1716 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1718 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1719 "TARGET_ARM && !arm_arch6"
1720 "mlas%?\\t%0, %2, %1, %3"
1721 [(set_attr "conds" "set")
1722 (set_attr "type" "mlas")]
1725 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1726 [(set (reg:CC_NOOV CC_REGNUM)
1729 (match_operand:SI 2 "s_register_operand" "r")
1730 (match_operand:SI 1 "s_register_operand" "r"))
1731 (match_operand:SI 3 "s_register_operand" "r"))
1733 (clobber (match_scratch:SI 0 "=r"))]
1734 "TARGET_ARM && arm_arch6 && optimize_size"
1735 "mlas%?\\t%0, %2, %1, %3"
1736 [(set_attr "conds" "set")
1737 (set_attr "type" "mlas")]
1740 (define_insn "*mulsi3subsi"
1741 [(set (match_operand:SI 0 "s_register_operand" "=r")
1743 (match_operand:SI 3 "s_register_operand" "r")
1744 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1745 (match_operand:SI 1 "s_register_operand" "r"))))]
1746 "TARGET_32BIT && arm_arch_thumb2"
1747 "mls%?\\t%0, %2, %1, %3"
1748 [(set_attr "type" "mla")
1749 (set_attr "predicable" "yes")
1750 (set_attr "predicable_short_it" "no")]
1753 (define_expand "maddsidi4"
1754 [(set (match_operand:DI 0 "s_register_operand" "")
1757 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1758 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1759 (match_operand:DI 3 "s_register_operand" "")))]
1760 "TARGET_32BIT && arm_arch3m"
1763 (define_insn "*mulsidi3adddi"
1764 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1767 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1768 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1769 (match_operand:DI 1 "s_register_operand" "0")))]
1770 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1771 "smlal%?\\t%Q0, %R0, %3, %2"
1772 [(set_attr "type" "smlal")
1773 (set_attr "predicable" "yes")]
1776 (define_insn "*mulsidi3adddi_v6"
1777 [(set (match_operand:DI 0 "s_register_operand" "=r")
1780 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1781 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1782 (match_operand:DI 1 "s_register_operand" "0")))]
1783 "TARGET_32BIT && arm_arch6"
1784 "smlal%?\\t%Q0, %R0, %3, %2"
1785 [(set_attr "type" "smlal")
1786 (set_attr "predicable" "yes")
1787 (set_attr "predicable_short_it" "no")]
1790 ;; 32x32->64 widening multiply.
1791 ;; As with mulsi3, the only difference between the v3-5 and v6+
1792 ;; versions of these patterns is the requirement that the output not
1793 ;; overlap the inputs, but that still means we have to have a named
1794 ;; expander and two different starred insns.
1796 (define_expand "mulsidi3"
1797 [(set (match_operand:DI 0 "s_register_operand" "")
1799 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1800 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1801 "TARGET_32BIT && arm_arch3m"
1805 (define_insn "*mulsidi3_nov6"
1806 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1808 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1809 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1810 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1811 "smull%?\\t%Q0, %R0, %1, %2"
1812 [(set_attr "type" "smull")
1813 (set_attr "predicable" "yes")]
1816 (define_insn "*mulsidi3_v6"
1817 [(set (match_operand:DI 0 "s_register_operand" "=r")
1819 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1820 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1821 "TARGET_32BIT && arm_arch6"
1822 "smull%?\\t%Q0, %R0, %1, %2"
1823 [(set_attr "type" "smull")
1824 (set_attr "predicable" "yes")
1825 (set_attr "predicable_short_it" "no")]
1828 (define_expand "umulsidi3"
1829 [(set (match_operand:DI 0 "s_register_operand" "")
1831 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1832 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1833 "TARGET_32BIT && arm_arch3m"
1837 (define_insn "*umulsidi3_nov6"
1838 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1840 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1841 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1842 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1843 "umull%?\\t%Q0, %R0, %1, %2"
1844 [(set_attr "type" "umull")
1845 (set_attr "predicable" "yes")]
1848 (define_insn "*umulsidi3_v6"
1849 [(set (match_operand:DI 0 "s_register_operand" "=r")
1851 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1852 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1853 "TARGET_32BIT && arm_arch6"
1854 "umull%?\\t%Q0, %R0, %1, %2"
1855 [(set_attr "type" "umull")
1856 (set_attr "predicable" "yes")
1857 (set_attr "predicable_short_it" "no")]
1860 (define_expand "umaddsidi4"
1861 [(set (match_operand:DI 0 "s_register_operand" "")
1864 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1865 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1866 (match_operand:DI 3 "s_register_operand" "")))]
1867 "TARGET_32BIT && arm_arch3m"
1870 (define_insn "*umulsidi3adddi"
1871 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1874 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1875 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1876 (match_operand:DI 1 "s_register_operand" "0")))]
1877 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1878 "umlal%?\\t%Q0, %R0, %3, %2"
1879 [(set_attr "type" "umlal")
1880 (set_attr "predicable" "yes")]
1883 (define_insn "*umulsidi3adddi_v6"
1884 [(set (match_operand:DI 0 "s_register_operand" "=r")
1887 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1888 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1889 (match_operand:DI 1 "s_register_operand" "0")))]
1890 "TARGET_32BIT && arm_arch6"
1891 "umlal%?\\t%Q0, %R0, %3, %2"
1892 [(set_attr "type" "umlal")
1893 (set_attr "predicable" "yes")
1894 (set_attr "predicable_short_it" "no")]
1897 (define_expand "smulsi3_highpart"
1899 [(set (match_operand:SI 0 "s_register_operand" "")
1903 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1904 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1906 (clobber (match_scratch:SI 3 ""))])]
1907 "TARGET_32BIT && arm_arch3m"
1911 (define_insn "*smulsi3_highpart_nov6"
1912 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1916 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1917 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1919 (clobber (match_scratch:SI 3 "=&r,&r"))]
1920 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1921 "smull%?\\t%3, %0, %2, %1"
1922 [(set_attr "type" "smull")
1923 (set_attr "predicable" "yes")]
1926 (define_insn "*smulsi3_highpart_v6"
1927 [(set (match_operand:SI 0 "s_register_operand" "=r")
1931 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1932 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1934 (clobber (match_scratch:SI 3 "=r"))]
1935 "TARGET_32BIT && arm_arch6"
1936 "smull%?\\t%3, %0, %2, %1"
1937 [(set_attr "type" "smull")
1938 (set_attr "predicable" "yes")
1939 (set_attr "predicable_short_it" "no")]
1942 (define_expand "umulsi3_highpart"
1944 [(set (match_operand:SI 0 "s_register_operand" "")
1948 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1949 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1951 (clobber (match_scratch:SI 3 ""))])]
1952 "TARGET_32BIT && arm_arch3m"
1956 (define_insn "*umulsi3_highpart_nov6"
1957 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1961 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1962 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1964 (clobber (match_scratch:SI 3 "=&r,&r"))]
1965 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1966 "umull%?\\t%3, %0, %2, %1"
1967 [(set_attr "type" "umull")
1968 (set_attr "predicable" "yes")]
1971 (define_insn "*umulsi3_highpart_v6"
1972 [(set (match_operand:SI 0 "s_register_operand" "=r")
1976 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1977 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1979 (clobber (match_scratch:SI 3 "=r"))]
1980 "TARGET_32BIT && arm_arch6"
1981 "umull%?\\t%3, %0, %2, %1"
1982 [(set_attr "type" "umull")
1983 (set_attr "predicable" "yes")
1984 (set_attr "predicable_short_it" "no")]
1987 (define_insn "mulhisi3"
1988 [(set (match_operand:SI 0 "s_register_operand" "=r")
1989 (mult:SI (sign_extend:SI
1990 (match_operand:HI 1 "s_register_operand" "%r"))
1992 (match_operand:HI 2 "s_register_operand" "r"))))]
1993 "TARGET_DSP_MULTIPLY"
1994 "smulbb%?\\t%0, %1, %2"
1995 [(set_attr "type" "smulxy")
1996 (set_attr "predicable" "yes")]
1999 (define_insn "*mulhisi3tb"
2000 [(set (match_operand:SI 0 "s_register_operand" "=r")
2001 (mult:SI (ashiftrt:SI
2002 (match_operand:SI 1 "s_register_operand" "r")
2005 (match_operand:HI 2 "s_register_operand" "r"))))]
2006 "TARGET_DSP_MULTIPLY"
2007 "smultb%?\\t%0, %1, %2"
2008 [(set_attr "type" "smulxy")
2009 (set_attr "predicable" "yes")
2010 (set_attr "predicable_short_it" "no")]
2013 (define_insn "*mulhisi3bt"
2014 [(set (match_operand:SI 0 "s_register_operand" "=r")
2015 (mult:SI (sign_extend:SI
2016 (match_operand:HI 1 "s_register_operand" "r"))
2018 (match_operand:SI 2 "s_register_operand" "r")
2020 "TARGET_DSP_MULTIPLY"
2021 "smulbt%?\\t%0, %1, %2"
2022 [(set_attr "type" "smulxy")
2023 (set_attr "predicable" "yes")
2024 (set_attr "predicable_short_it" "no")]
2027 (define_insn "*mulhisi3tt"
2028 [(set (match_operand:SI 0 "s_register_operand" "=r")
2029 (mult:SI (ashiftrt:SI
2030 (match_operand:SI 1 "s_register_operand" "r")
2033 (match_operand:SI 2 "s_register_operand" "r")
2035 "TARGET_DSP_MULTIPLY"
2036 "smultt%?\\t%0, %1, %2"
2037 [(set_attr "type" "smulxy")
2038 (set_attr "predicable" "yes")
2039 (set_attr "predicable_short_it" "no")]
2042 (define_insn "maddhisi4"
2043 [(set (match_operand:SI 0 "s_register_operand" "=r")
2044 (plus:SI (mult:SI (sign_extend:SI
2045 (match_operand:HI 1 "s_register_operand" "r"))
2047 (match_operand:HI 2 "s_register_operand" "r")))
2048 (match_operand:SI 3 "s_register_operand" "r")))]
2049 "TARGET_DSP_MULTIPLY"
2050 "smlabb%?\\t%0, %1, %2, %3"
2051 [(set_attr "type" "smlaxy")
2052 (set_attr "predicable" "yes")
2053 (set_attr "predicable_short_it" "no")]
2056 ;; Note: there is no maddhisi4ibt because this one is canonical form
2057 (define_insn "*maddhisi4tb"
2058 [(set (match_operand:SI 0 "s_register_operand" "=r")
2059 (plus:SI (mult:SI (ashiftrt:SI
2060 (match_operand:SI 1 "s_register_operand" "r")
2063 (match_operand:HI 2 "s_register_operand" "r")))
2064 (match_operand:SI 3 "s_register_operand" "r")))]
2065 "TARGET_DSP_MULTIPLY"
2066 "smlatb%?\\t%0, %1, %2, %3"
2067 [(set_attr "type" "smlaxy")
2068 (set_attr "predicable" "yes")
2069 (set_attr "predicable_short_it" "no")]
2072 (define_insn "*maddhisi4tt"
2073 [(set (match_operand:SI 0 "s_register_operand" "=r")
2074 (plus:SI (mult:SI (ashiftrt:SI
2075 (match_operand:SI 1 "s_register_operand" "r")
2078 (match_operand:SI 2 "s_register_operand" "r")
2080 (match_operand:SI 3 "s_register_operand" "r")))]
2081 "TARGET_DSP_MULTIPLY"
2082 "smlatt%?\\t%0, %1, %2, %3"
2083 [(set_attr "type" "smlaxy")
2084 (set_attr "predicable" "yes")
2085 (set_attr "predicable_short_it" "no")]
2088 (define_insn "maddhidi4"
2089 [(set (match_operand:DI 0 "s_register_operand" "=r")
2091 (mult:DI (sign_extend:DI
2092 (match_operand:HI 1 "s_register_operand" "r"))
2094 (match_operand:HI 2 "s_register_operand" "r")))
2095 (match_operand:DI 3 "s_register_operand" "0")))]
2096 "TARGET_DSP_MULTIPLY"
2097 "smlalbb%?\\t%Q0, %R0, %1, %2"
2098 [(set_attr "type" "smlalxy")
2099 (set_attr "predicable" "yes")
2100 (set_attr "predicable_short_it" "no")])
2102 ;; Note: there is no maddhidi4ibt because this one is canonical form
2103 (define_insn "*maddhidi4tb"
2104 [(set (match_operand:DI 0 "s_register_operand" "=r")
2106 (mult:DI (sign_extend:DI
2108 (match_operand:SI 1 "s_register_operand" "r")
2111 (match_operand:HI 2 "s_register_operand" "r")))
2112 (match_operand:DI 3 "s_register_operand" "0")))]
2113 "TARGET_DSP_MULTIPLY"
2114 "smlaltb%?\\t%Q0, %R0, %1, %2"
2115 [(set_attr "type" "smlalxy")
2116 (set_attr "predicable" "yes")
2117 (set_attr "predicable_short_it" "no")])
2119 (define_insn "*maddhidi4tt"
2120 [(set (match_operand:DI 0 "s_register_operand" "=r")
2122 (mult:DI (sign_extend:DI
2124 (match_operand:SI 1 "s_register_operand" "r")
2128 (match_operand:SI 2 "s_register_operand" "r")
2130 (match_operand:DI 3 "s_register_operand" "0")))]
2131 "TARGET_DSP_MULTIPLY"
2132 "smlaltt%?\\t%Q0, %R0, %1, %2"
2133 [(set_attr "type" "smlalxy")
2134 (set_attr "predicable" "yes")
2135 (set_attr "predicable_short_it" "no")])
2137 (define_expand "mulsf3"
2138 [(set (match_operand:SF 0 "s_register_operand" "")
2139 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2140 (match_operand:SF 2 "s_register_operand" "")))]
2141 "TARGET_32BIT && TARGET_HARD_FLOAT"
2145 (define_expand "muldf3"
2146 [(set (match_operand:DF 0 "s_register_operand" "")
2147 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2148 (match_operand:DF 2 "s_register_operand" "")))]
2149 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2155 (define_expand "divsf3"
2156 [(set (match_operand:SF 0 "s_register_operand" "")
2157 (div:SF (match_operand:SF 1 "s_register_operand" "")
2158 (match_operand:SF 2 "s_register_operand" "")))]
2159 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
2162 (define_expand "divdf3"
2163 [(set (match_operand:DF 0 "s_register_operand" "")
2164 (div:DF (match_operand:DF 1 "s_register_operand" "")
2165 (match_operand:DF 2 "s_register_operand" "")))]
2166 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2169 ;; Boolean and,ior,xor insns
2171 ;; Split up double word logical operations
2173 ;; Split up simple DImode logical operations. Simply perform the logical
2174 ;; operation on the upper and lower halves of the registers.
2176 [(set (match_operand:DI 0 "s_register_operand" "")
2177 (match_operator:DI 6 "logical_binary_operator"
2178 [(match_operand:DI 1 "s_register_operand" "")
2179 (match_operand:DI 2 "s_register_operand" "")]))]
2180 "TARGET_32BIT && reload_completed
2181 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2182 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2183 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2184 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2187 operands[3] = gen_highpart (SImode, operands[0]);
2188 operands[0] = gen_lowpart (SImode, operands[0]);
2189 operands[4] = gen_highpart (SImode, operands[1]);
2190 operands[1] = gen_lowpart (SImode, operands[1]);
2191 operands[5] = gen_highpart (SImode, operands[2]);
2192 operands[2] = gen_lowpart (SImode, operands[2]);
2197 [(set (match_operand:DI 0 "s_register_operand" "")
2198 (match_operator:DI 6 "logical_binary_operator"
2199 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2200 (match_operand:DI 1 "s_register_operand" "")]))]
2201 "TARGET_32BIT && reload_completed"
2202 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2203 (set (match_dup 3) (match_op_dup:SI 6
2204 [(ashiftrt:SI (match_dup 2) (const_int 31))
2208 operands[3] = gen_highpart (SImode, operands[0]);
2209 operands[0] = gen_lowpart (SImode, operands[0]);
2210 operands[4] = gen_highpart (SImode, operands[1]);
2211 operands[1] = gen_lowpart (SImode, operands[1]);
2212 operands[5] = gen_highpart (SImode, operands[2]);
2213 operands[2] = gen_lowpart (SImode, operands[2]);
2217 ;; The zero extend of operand 2 means we can just copy the high part of
2218 ;; operand1 into operand0.
2220 [(set (match_operand:DI 0 "s_register_operand" "")
2222 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2223 (match_operand:DI 1 "s_register_operand" "")))]
2224 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2225 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2226 (set (match_dup 3) (match_dup 4))]
2229 operands[4] = gen_highpart (SImode, operands[1]);
2230 operands[3] = gen_highpart (SImode, operands[0]);
2231 operands[0] = gen_lowpart (SImode, operands[0]);
2232 operands[1] = gen_lowpart (SImode, operands[1]);
2236 ;; The zero extend of operand 2 means we can just copy the high part of
2237 ;; operand1 into operand0.
2239 [(set (match_operand:DI 0 "s_register_operand" "")
2241 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2242 (match_operand:DI 1 "s_register_operand" "")))]
2243 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2244 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2245 (set (match_dup 3) (match_dup 4))]
2248 operands[4] = gen_highpart (SImode, operands[1]);
2249 operands[3] = gen_highpart (SImode, operands[0]);
2250 operands[0] = gen_lowpart (SImode, operands[0]);
2251 operands[1] = gen_lowpart (SImode, operands[1]);
2255 (define_expand "anddi3"
2256 [(set (match_operand:DI 0 "s_register_operand" "")
2257 (and:DI (match_operand:DI 1 "s_register_operand" "")
2258 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2263 (define_insn_and_split "*anddi3_insn"
2264 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2265 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2266 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2267 "TARGET_32BIT && !TARGET_IWMMXT"
2269 switch (which_alternative)
2271 case 0: /* fall through */
2272 case 6: return "vand\t%P0, %P1, %P2";
2273 case 1: /* fall through */
2274 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2275 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2279 case 5: /* fall through */
2281 default: gcc_unreachable ();
2284 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2285 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2286 [(set (match_dup 3) (match_dup 4))
2287 (set (match_dup 5) (match_dup 6))]
2290 operands[3] = gen_lowpart (SImode, operands[0]);
2291 operands[5] = gen_highpart (SImode, operands[0]);
2293 operands[4] = simplify_gen_binary (AND, SImode,
2294 gen_lowpart (SImode, operands[1]),
2295 gen_lowpart (SImode, operands[2]));
2296 operands[6] = simplify_gen_binary (AND, SImode,
2297 gen_highpart (SImode, operands[1]),
2298 gen_highpart_mode (SImode, DImode, operands[2]));
2301 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2302 multiple,multiple,neon_logic,neon_logic")
2303 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2304 avoid_neon_for_64bits,avoid_neon_for_64bits")
2305 (set_attr "length" "*,*,8,8,8,8,*,*")
2309 (define_insn_and_split "*anddi_zesidi_di"
2310 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2311 (and:DI (zero_extend:DI
2312 (match_operand:SI 2 "s_register_operand" "r,r"))
2313 (match_operand:DI 1 "s_register_operand" "0,r")))]
2316 "TARGET_32BIT && reload_completed"
2317 ; The zero extend of operand 2 clears the high word of the output
2319 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2320 (set (match_dup 3) (const_int 0))]
2323 operands[3] = gen_highpart (SImode, operands[0]);
2324 operands[0] = gen_lowpart (SImode, operands[0]);
2325 operands[1] = gen_lowpart (SImode, operands[1]);
2327 [(set_attr "length" "8")
2328 (set_attr "type" "multiple")]
2331 (define_insn "*anddi_sesdi_di"
2332 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2333 (and:DI (sign_extend:DI
2334 (match_operand:SI 2 "s_register_operand" "r,r"))
2335 (match_operand:DI 1 "s_register_operand" "0,r")))]
2338 [(set_attr "length" "8")
2339 (set_attr "type" "multiple")]
2342 (define_expand "andsi3"
2343 [(set (match_operand:SI 0 "s_register_operand" "")
2344 (and:SI (match_operand:SI 1 "s_register_operand" "")
2345 (match_operand:SI 2 "reg_or_int_operand" "")))]
2350 if (CONST_INT_P (operands[2]))
2352 if (INTVAL (operands[2]) == 255 && arm_arch6)
2354 operands[1] = convert_to_mode (QImode, operands[1], 1);
2355 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2359 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2360 operands[2] = force_reg (SImode, operands[2]);
2363 arm_split_constant (AND, SImode, NULL_RTX,
2364 INTVAL (operands[2]), operands[0],
2366 optimize && can_create_pseudo_p ());
2372 else /* TARGET_THUMB1 */
2374 if (!CONST_INT_P (operands[2]))
2376 rtx tmp = force_reg (SImode, operands[2]);
2377 if (rtx_equal_p (operands[0], operands[1]))
2381 operands[2] = operands[1];
2389 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2391 operands[2] = force_reg (SImode,
2392 GEN_INT (~INTVAL (operands[2])));
2394 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2399 for (i = 9; i <= 31; i++)
2401 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2403 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2407 else if ((HOST_WIDE_INT_1 << i) - 1
2408 == ~INTVAL (operands[2]))
2410 rtx shift = GEN_INT (i);
2411 rtx reg = gen_reg_rtx (SImode);
2413 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2414 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2420 operands[2] = force_reg (SImode, operands[2]);
2426 ; ??? Check split length for Thumb-2
2427 (define_insn_and_split "*arm_andsi3_insn"
2428 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2429 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2430 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2435 bic%?\\t%0, %1, #%B2
2439 && CONST_INT_P (operands[2])
2440 && !(const_ok_for_arm (INTVAL (operands[2]))
2441 || const_ok_for_arm (~INTVAL (operands[2])))"
2442 [(clobber (const_int 0))]
2444 arm_split_constant (AND, SImode, curr_insn,
2445 INTVAL (operands[2]), operands[0], operands[1], 0);
2448 [(set_attr "length" "4,4,4,4,16")
2449 (set_attr "predicable" "yes")
2450 (set_attr "predicable_short_it" "no,yes,no,no,no")
2451 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2454 (define_insn "*andsi3_compare0"
2455 [(set (reg:CC_NOOV CC_REGNUM)
2457 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2458 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2460 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2461 (and:SI (match_dup 1) (match_dup 2)))]
2465 bics%?\\t%0, %1, #%B2
2466 ands%?\\t%0, %1, %2"
2467 [(set_attr "conds" "set")
2468 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2471 (define_insn "*andsi3_compare0_scratch"
2472 [(set (reg:CC_NOOV CC_REGNUM)
2474 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2475 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2477 (clobber (match_scratch:SI 2 "=X,r,X"))]
2481 bics%?\\t%2, %0, #%B1
2483 [(set_attr "conds" "set")
2484 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2487 (define_insn "*zeroextractsi_compare0_scratch"
2488 [(set (reg:CC_NOOV CC_REGNUM)
2489 (compare:CC_NOOV (zero_extract:SI
2490 (match_operand:SI 0 "s_register_operand" "r")
2491 (match_operand 1 "const_int_operand" "n")
2492 (match_operand 2 "const_int_operand" "n"))
2495 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2496 && INTVAL (operands[1]) > 0
2497 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2498 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2500 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2501 << INTVAL (operands[2]));
2502 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2505 [(set_attr "conds" "set")
2506 (set_attr "predicable" "yes")
2507 (set_attr "predicable_short_it" "no")
2508 (set_attr "type" "logics_imm")]
2511 (define_insn_and_split "*ne_zeroextractsi"
2512 [(set (match_operand:SI 0 "s_register_operand" "=r")
2513 (ne:SI (zero_extract:SI
2514 (match_operand:SI 1 "s_register_operand" "r")
2515 (match_operand:SI 2 "const_int_operand" "n")
2516 (match_operand:SI 3 "const_int_operand" "n"))
2518 (clobber (reg:CC CC_REGNUM))]
2520 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2521 && INTVAL (operands[2]) > 0
2522 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2523 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2526 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2527 && INTVAL (operands[2]) > 0
2528 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2529 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2530 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2531 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2533 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2535 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2536 (match_dup 0) (const_int 1)))]
2538 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2539 << INTVAL (operands[3]));
2541 [(set_attr "conds" "clob")
2542 (set (attr "length")
2543 (if_then_else (eq_attr "is_thumb" "yes")
2546 (set_attr "type" "multiple")]
2549 (define_insn_and_split "*ne_zeroextractsi_shifted"
2550 [(set (match_operand:SI 0 "s_register_operand" "=r")
2551 (ne:SI (zero_extract:SI
2552 (match_operand:SI 1 "s_register_operand" "r")
2553 (match_operand:SI 2 "const_int_operand" "n")
2556 (clobber (reg:CC CC_REGNUM))]
2560 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2561 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2563 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2565 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2566 (match_dup 0) (const_int 1)))]
2568 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2570 [(set_attr "conds" "clob")
2571 (set_attr "length" "8")
2572 (set_attr "type" "multiple")]
2575 (define_insn_and_split "*ite_ne_zeroextractsi"
2576 [(set (match_operand:SI 0 "s_register_operand" "=r")
2577 (if_then_else:SI (ne (zero_extract:SI
2578 (match_operand:SI 1 "s_register_operand" "r")
2579 (match_operand:SI 2 "const_int_operand" "n")
2580 (match_operand:SI 3 "const_int_operand" "n"))
2582 (match_operand:SI 4 "arm_not_operand" "rIK")
2584 (clobber (reg:CC CC_REGNUM))]
2586 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2587 && INTVAL (operands[2]) > 0
2588 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2589 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2590 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2593 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2594 && INTVAL (operands[2]) > 0
2595 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2596 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2597 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2598 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2599 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2601 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2603 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2604 (match_dup 0) (match_dup 4)))]
2606 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2607 << INTVAL (operands[3]));
2609 [(set_attr "conds" "clob")
2610 (set_attr "length" "8")
2611 (set_attr "type" "multiple")]
2614 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2615 [(set (match_operand:SI 0 "s_register_operand" "=r")
2616 (if_then_else:SI (ne (zero_extract:SI
2617 (match_operand:SI 1 "s_register_operand" "r")
2618 (match_operand:SI 2 "const_int_operand" "n")
2621 (match_operand:SI 3 "arm_not_operand" "rIK")
2623 (clobber (reg:CC CC_REGNUM))]
2624 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2626 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2627 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2628 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2630 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2632 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2633 (match_dup 0) (match_dup 3)))]
2635 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2637 [(set_attr "conds" "clob")
2638 (set_attr "length" "8")
2639 (set_attr "type" "multiple")]
2642 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2644 [(set (match_operand:SI 0 "s_register_operand" "")
2645 (match_operator:SI 1 "shiftable_operator"
2646 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2647 (match_operand:SI 3 "const_int_operand" "")
2648 (match_operand:SI 4 "const_int_operand" ""))
2649 (match_operand:SI 5 "s_register_operand" "")]))
2650 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2652 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2655 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2658 HOST_WIDE_INT temp = INTVAL (operands[3]);
2660 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2661 operands[4] = GEN_INT (32 - temp);
2666 [(set (match_operand:SI 0 "s_register_operand" "")
2667 (match_operator:SI 1 "shiftable_operator"
2668 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2669 (match_operand:SI 3 "const_int_operand" "")
2670 (match_operand:SI 4 "const_int_operand" ""))
2671 (match_operand:SI 5 "s_register_operand" "")]))
2672 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2674 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2677 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2680 HOST_WIDE_INT temp = INTVAL (operands[3]);
2682 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2683 operands[4] = GEN_INT (32 - temp);
2687 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2688 ;;; represented by the bitfield, then this will produce incorrect results.
2689 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2690 ;;; which have a real bit-field insert instruction, the truncation happens
2691 ;;; in the bit-field insert instruction itself. Since arm does not have a
2692 ;;; bit-field insert instruction, we would have to emit code here to truncate
2693 ;;; the value before we insert. This loses some of the advantage of having
2694 ;;; this insv pattern, so this pattern needs to be reevalutated.
2696 (define_expand "insv"
2697 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2698 (match_operand 1 "general_operand" "")
2699 (match_operand 2 "general_operand" ""))
2700 (match_operand 3 "reg_or_int_operand" ""))]
2701 "TARGET_ARM || arm_arch_thumb2"
2704 int start_bit = INTVAL (operands[2]);
2705 int width = INTVAL (operands[1]);
2706 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2707 rtx target, subtarget;
2709 if (arm_arch_thumb2)
2711 if (unaligned_access && MEM_P (operands[0])
2712 && s_register_operand (operands[3], GET_MODE (operands[3]))
2713 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2717 if (BYTES_BIG_ENDIAN)
2718 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2723 base_addr = adjust_address (operands[0], SImode,
2724 start_bit / BITS_PER_UNIT);
2725 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2729 rtx tmp = gen_reg_rtx (HImode);
2731 base_addr = adjust_address (operands[0], HImode,
2732 start_bit / BITS_PER_UNIT);
2733 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2734 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2738 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2740 bool use_bfi = TRUE;
2742 if (CONST_INT_P (operands[3]))
2744 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2748 emit_insn (gen_insv_zero (operands[0], operands[1],
2753 /* See if the set can be done with a single orr instruction. */
2754 if (val == mask && const_ok_for_arm (val << start_bit))
2760 if (!REG_P (operands[3]))
2761 operands[3] = force_reg (SImode, operands[3]);
2763 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2772 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2775 target = copy_rtx (operands[0]);
2776 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2777 subreg as the final target. */
2778 if (GET_CODE (target) == SUBREG)
2780 subtarget = gen_reg_rtx (SImode);
2781 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2782 < GET_MODE_SIZE (SImode))
2783 target = SUBREG_REG (target);
2788 if (CONST_INT_P (operands[3]))
2790 /* Since we are inserting a known constant, we may be able to
2791 reduce the number of bits that we have to clear so that
2792 the mask becomes simple. */
2793 /* ??? This code does not check to see if the new mask is actually
2794 simpler. It may not be. */
2795 rtx op1 = gen_reg_rtx (SImode);
2796 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2797 start of this pattern. */
2798 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2799 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2801 emit_insn (gen_andsi3 (op1, operands[0],
2802 gen_int_mode (~mask2, SImode)));
2803 emit_insn (gen_iorsi3 (subtarget, op1,
2804 gen_int_mode (op3_value << start_bit, SImode)));
2806 else if (start_bit == 0
2807 && !(const_ok_for_arm (mask)
2808 || const_ok_for_arm (~mask)))
2810 /* A Trick, since we are setting the bottom bits in the word,
2811 we can shift operand[3] up, operand[0] down, OR them together
2812 and rotate the result back again. This takes 3 insns, and
2813 the third might be mergeable into another op. */
2814 /* The shift up copes with the possibility that operand[3] is
2815 wider than the bitfield. */
2816 rtx op0 = gen_reg_rtx (SImode);
2817 rtx op1 = gen_reg_rtx (SImode);
2819 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2820 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2821 emit_insn (gen_iorsi3 (op1, op1, op0));
2822 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2824 else if ((width + start_bit == 32)
2825 && !(const_ok_for_arm (mask)
2826 || const_ok_for_arm (~mask)))
2828 /* Similar trick, but slightly less efficient. */
2830 rtx op0 = gen_reg_rtx (SImode);
2831 rtx op1 = gen_reg_rtx (SImode);
2833 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2834 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2835 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2836 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2840 rtx op0 = gen_int_mode (mask, SImode);
2841 rtx op1 = gen_reg_rtx (SImode);
2842 rtx op2 = gen_reg_rtx (SImode);
2844 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2846 rtx tmp = gen_reg_rtx (SImode);
2848 emit_insn (gen_movsi (tmp, op0));
2852 /* Mask out any bits in operand[3] that are not needed. */
2853 emit_insn (gen_andsi3 (op1, operands[3], op0));
2855 if (CONST_INT_P (op0)
2856 && (const_ok_for_arm (mask << start_bit)
2857 || const_ok_for_arm (~(mask << start_bit))))
2859 op0 = gen_int_mode (~(mask << start_bit), SImode);
2860 emit_insn (gen_andsi3 (op2, operands[0], op0));
2864 if (CONST_INT_P (op0))
2866 rtx tmp = gen_reg_rtx (SImode);
2868 emit_insn (gen_movsi (tmp, op0));
2873 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2875 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2879 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2881 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2884 if (subtarget != target)
2886 /* If TARGET is still a SUBREG, then it must be wider than a word,
2887 so we must be careful only to set the subword we were asked to. */
2888 if (GET_CODE (target) == SUBREG)
2889 emit_move_insn (target, subtarget);
2891 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2898 (define_insn "insv_zero"
2899 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2900 (match_operand:SI 1 "const_int_M_operand" "M")
2901 (match_operand:SI 2 "const_int_M_operand" "M"))
2905 [(set_attr "length" "4")
2906 (set_attr "predicable" "yes")
2907 (set_attr "predicable_short_it" "no")
2908 (set_attr "type" "bfm")]
2911 (define_insn "insv_t2"
2912 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2913 (match_operand:SI 1 "const_int_M_operand" "M")
2914 (match_operand:SI 2 "const_int_M_operand" "M"))
2915 (match_operand:SI 3 "s_register_operand" "r"))]
2917 "bfi%?\t%0, %3, %2, %1"
2918 [(set_attr "length" "4")
2919 (set_attr "predicable" "yes")
2920 (set_attr "predicable_short_it" "no")
2921 (set_attr "type" "bfm")]
2924 ; constants for op 2 will never be given to these patterns.
2925 (define_insn_and_split "*anddi_notdi_di"
2926 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2927 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2928 (match_operand:DI 2 "s_register_operand" "r,0")))]
2931 "TARGET_32BIT && reload_completed
2932 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2933 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2934 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2935 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2938 operands[3] = gen_highpart (SImode, operands[0]);
2939 operands[0] = gen_lowpart (SImode, operands[0]);
2940 operands[4] = gen_highpart (SImode, operands[1]);
2941 operands[1] = gen_lowpart (SImode, operands[1]);
2942 operands[5] = gen_highpart (SImode, operands[2]);
2943 operands[2] = gen_lowpart (SImode, operands[2]);
2945 [(set_attr "length" "8")
2946 (set_attr "predicable" "yes")
2947 (set_attr "type" "multiple")]
2950 (define_insn_and_split "*anddi_notzesidi_di"
2951 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2952 (and:DI (not:DI (zero_extend:DI
2953 (match_operand:SI 2 "s_register_operand" "r,r")))
2954 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2957 bic%?\\t%Q0, %Q1, %2
2959 ; (not (zero_extend ...)) allows us to just copy the high word from
2960 ; operand1 to operand0.
2963 && operands[0] != operands[1]"
2964 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2965 (set (match_dup 3) (match_dup 4))]
2968 operands[3] = gen_highpart (SImode, operands[0]);
2969 operands[0] = gen_lowpart (SImode, operands[0]);
2970 operands[4] = gen_highpart (SImode, operands[1]);
2971 operands[1] = gen_lowpart (SImode, operands[1]);
2973 [(set_attr "length" "4,8")
2974 (set_attr "predicable" "yes")
2975 (set_attr "predicable_short_it" "no")
2976 (set_attr "type" "multiple")]
2979 (define_insn_and_split "*anddi_notdi_zesidi"
2980 [(set (match_operand:DI 0 "s_register_operand" "=r")
2981 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2983 (match_operand:SI 1 "s_register_operand" "r"))))]
2986 "TARGET_32BIT && reload_completed"
2987 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2988 (set (match_dup 3) (const_int 0))]
2991 operands[3] = gen_highpart (SImode, operands[0]);
2992 operands[0] = gen_lowpart (SImode, operands[0]);
2993 operands[2] = gen_lowpart (SImode, operands[2]);
2995 [(set_attr "length" "8")
2996 (set_attr "predicable" "yes")
2997 (set_attr "predicable_short_it" "no")
2998 (set_attr "type" "multiple")]
3001 (define_insn_and_split "*anddi_notsesidi_di"
3002 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3003 (and:DI (not:DI (sign_extend:DI
3004 (match_operand:SI 2 "s_register_operand" "r,r")))
3005 (match_operand:DI 1 "s_register_operand" "0,r")))]
3008 "TARGET_32BIT && reload_completed"
3009 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3010 (set (match_dup 3) (and:SI (not:SI
3011 (ashiftrt:SI (match_dup 2) (const_int 31)))
3015 operands[3] = gen_highpart (SImode, operands[0]);
3016 operands[0] = gen_lowpart (SImode, operands[0]);
3017 operands[4] = gen_highpart (SImode, operands[1]);
3018 operands[1] = gen_lowpart (SImode, operands[1]);
3020 [(set_attr "length" "8")
3021 (set_attr "predicable" "yes")
3022 (set_attr "predicable_short_it" "no")
3023 (set_attr "type" "multiple")]
3026 (define_insn "andsi_notsi_si"
3027 [(set (match_operand:SI 0 "s_register_operand" "=r")
3028 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3029 (match_operand:SI 1 "s_register_operand" "r")))]
3031 "bic%?\\t%0, %1, %2"
3032 [(set_attr "predicable" "yes")
3033 (set_attr "predicable_short_it" "no")
3034 (set_attr "type" "logic_reg")]
3037 (define_insn "andsi_not_shiftsi_si"
3038 [(set (match_operand:SI 0 "s_register_operand" "=r")
3039 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3040 [(match_operand:SI 2 "s_register_operand" "r")
3041 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3042 (match_operand:SI 1 "s_register_operand" "r")))]
3044 "bic%?\\t%0, %1, %2%S4"
3045 [(set_attr "predicable" "yes")
3046 (set_attr "shift" "2")
3047 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3048 (const_string "logic_shift_imm")
3049 (const_string "logic_shift_reg")))]
3052 ;; Shifted bics pattern used to set up CC status register and not reusing
3053 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3054 ;; does not support shift by register.
3055 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3056 [(set (reg:CC_NOOV CC_REGNUM)
3058 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3059 [(match_operand:SI 1 "s_register_operand" "r")
3060 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3061 (match_operand:SI 3 "s_register_operand" "r"))
3063 (clobber (match_scratch:SI 4 "=r"))]
3064 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3065 "bics%?\\t%4, %3, %1%S0"
3066 [(set_attr "predicable" "yes")
3067 (set_attr "predicable_short_it" "no")
3068 (set_attr "conds" "set")
3069 (set_attr "shift" "1")
3070 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3071 (const_string "logic_shift_imm")
3072 (const_string "logic_shift_reg")))]
3075 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3076 ;; getting reused later.
3077 (define_insn "andsi_not_shiftsi_si_scc"
3078 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3080 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3081 [(match_operand:SI 1 "s_register_operand" "r")
3082 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3083 (match_operand:SI 3 "s_register_operand" "r"))
3085 (set (match_operand:SI 4 "s_register_operand" "=r")
3086 (and:SI (not:SI (match_op_dup 0
3090 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3091 "bics%?\\t%4, %3, %1%S0"
3092 [(set_attr "predicable" "yes")
3093 (set_attr "predicable_short_it" "no")
3094 (set_attr "conds" "set")
3095 (set_attr "shift" "1")
3096 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3097 (const_string "logic_shift_imm")
3098 (const_string "logic_shift_reg")))]
3101 (define_insn "*andsi_notsi_si_compare0"
3102 [(set (reg:CC_NOOV CC_REGNUM)
3104 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3105 (match_operand:SI 1 "s_register_operand" "r"))
3107 (set (match_operand:SI 0 "s_register_operand" "=r")
3108 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3111 [(set_attr "conds" "set")
3112 (set_attr "type" "logics_shift_reg")]
3115 (define_insn "*andsi_notsi_si_compare0_scratch"
3116 [(set (reg:CC_NOOV CC_REGNUM)
3118 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3119 (match_operand:SI 1 "s_register_operand" "r"))
3121 (clobber (match_scratch:SI 0 "=r"))]
3124 [(set_attr "conds" "set")
3125 (set_attr "type" "logics_shift_reg")]
3128 (define_expand "iordi3"
3129 [(set (match_operand:DI 0 "s_register_operand" "")
3130 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3131 (match_operand:DI 2 "neon_logic_op2" "")))]
3136 (define_insn_and_split "*iordi3_insn"
3137 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3138 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3139 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3140 "TARGET_32BIT && !TARGET_IWMMXT"
3142 switch (which_alternative)
3144 case 0: /* fall through */
3145 case 6: return "vorr\t%P0, %P1, %P2";
3146 case 1: /* fall through */
3147 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3148 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3154 default: gcc_unreachable ();
3157 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3158 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3159 [(set (match_dup 3) (match_dup 4))
3160 (set (match_dup 5) (match_dup 6))]
3163 operands[3] = gen_lowpart (SImode, operands[0]);
3164 operands[5] = gen_highpart (SImode, operands[0]);
3166 operands[4] = simplify_gen_binary (IOR, SImode,
3167 gen_lowpart (SImode, operands[1]),
3168 gen_lowpart (SImode, operands[2]));
3169 operands[6] = simplify_gen_binary (IOR, SImode,
3170 gen_highpart (SImode, operands[1]),
3171 gen_highpart_mode (SImode, DImode, operands[2]));
3174 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3175 multiple,neon_logic,neon_logic")
3176 (set_attr "length" "*,*,8,8,8,8,*,*")
3177 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3180 (define_insn "*iordi_zesidi_di"
3181 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3182 (ior:DI (zero_extend:DI
3183 (match_operand:SI 2 "s_register_operand" "r,r"))
3184 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3187 orr%?\\t%Q0, %Q1, %2
3189 [(set_attr "length" "4,8")
3190 (set_attr "predicable" "yes")
3191 (set_attr "predicable_short_it" "no")
3192 (set_attr "type" "logic_reg,multiple")]
3195 (define_insn "*iordi_sesidi_di"
3196 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3197 (ior:DI (sign_extend:DI
3198 (match_operand:SI 2 "s_register_operand" "r,r"))
3199 (match_operand:DI 1 "s_register_operand" "0,r")))]
3202 [(set_attr "length" "8")
3203 (set_attr "predicable" "yes")
3204 (set_attr "type" "multiple")]
3207 (define_expand "iorsi3"
3208 [(set (match_operand:SI 0 "s_register_operand" "")
3209 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3210 (match_operand:SI 2 "reg_or_int_operand" "")))]
3213 if (CONST_INT_P (operands[2]))
3217 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3218 operands[2] = force_reg (SImode, operands[2]);
3221 arm_split_constant (IOR, SImode, NULL_RTX,
3222 INTVAL (operands[2]), operands[0],
3224 optimize && can_create_pseudo_p ());
3228 else /* TARGET_THUMB1 */
3230 rtx tmp = force_reg (SImode, operands[2]);
3231 if (rtx_equal_p (operands[0], operands[1]))
3235 operands[2] = operands[1];
3243 (define_insn_and_split "*iorsi3_insn"
3244 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3245 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3246 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3251 orn%?\\t%0, %1, #%B2
3255 && CONST_INT_P (operands[2])
3256 && !(const_ok_for_arm (INTVAL (operands[2]))
3257 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3258 [(clobber (const_int 0))]
3260 arm_split_constant (IOR, SImode, curr_insn,
3261 INTVAL (operands[2]), operands[0], operands[1], 0);
3264 [(set_attr "length" "4,4,4,4,16")
3265 (set_attr "arch" "32,t2,t2,32,32")
3266 (set_attr "predicable" "yes")
3267 (set_attr "predicable_short_it" "no,yes,no,no,no")
3268 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3272 [(match_scratch:SI 3 "r")
3273 (set (match_operand:SI 0 "arm_general_register_operand" "")
3274 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3275 (match_operand:SI 2 "const_int_operand" "")))]
3277 && !const_ok_for_arm (INTVAL (operands[2]))
3278 && const_ok_for_arm (~INTVAL (operands[2]))"
3279 [(set (match_dup 3) (match_dup 2))
3280 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3284 (define_insn "*iorsi3_compare0"
3285 [(set (reg:CC_NOOV CC_REGNUM)
3286 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3287 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3289 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3290 (ior:SI (match_dup 1) (match_dup 2)))]
3292 "orrs%?\\t%0, %1, %2"
3293 [(set_attr "conds" "set")
3294 (set_attr "type" "logics_imm,logics_reg")]
3297 (define_insn "*iorsi3_compare0_scratch"
3298 [(set (reg:CC_NOOV CC_REGNUM)
3299 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3300 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3302 (clobber (match_scratch:SI 0 "=r,r"))]
3304 "orrs%?\\t%0, %1, %2"
3305 [(set_attr "conds" "set")
3306 (set_attr "type" "logics_imm,logics_reg")]
3309 (define_expand "xordi3"
3310 [(set (match_operand:DI 0 "s_register_operand" "")
3311 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3312 (match_operand:DI 2 "arm_xordi_operand" "")))]
3317 (define_insn_and_split "*xordi3_insn"
3318 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3319 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3320 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3321 "TARGET_32BIT && !TARGET_IWMMXT"
3323 switch (which_alternative)
3328 case 4: /* fall through */
3330 case 0: /* fall through */
3331 case 5: return "veor\t%P0, %P1, %P2";
3332 default: gcc_unreachable ();
3335 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3336 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3337 [(set (match_dup 3) (match_dup 4))
3338 (set (match_dup 5) (match_dup 6))]
3341 operands[3] = gen_lowpart (SImode, operands[0]);
3342 operands[5] = gen_highpart (SImode, operands[0]);
3344 operands[4] = simplify_gen_binary (XOR, SImode,
3345 gen_lowpart (SImode, operands[1]),
3346 gen_lowpart (SImode, operands[2]));
3347 operands[6] = simplify_gen_binary (XOR, SImode,
3348 gen_highpart (SImode, operands[1]),
3349 gen_highpart_mode (SImode, DImode, operands[2]));
3352 [(set_attr "length" "*,8,8,8,8,*")
3353 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3354 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3357 (define_insn "*xordi_zesidi_di"
3358 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3359 (xor:DI (zero_extend:DI
3360 (match_operand:SI 2 "s_register_operand" "r,r"))
3361 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3364 eor%?\\t%Q0, %Q1, %2
3366 [(set_attr "length" "4,8")
3367 (set_attr "predicable" "yes")
3368 (set_attr "predicable_short_it" "no")
3369 (set_attr "type" "logic_reg")]
3372 (define_insn "*xordi_sesidi_di"
3373 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3374 (xor:DI (sign_extend:DI
3375 (match_operand:SI 2 "s_register_operand" "r,r"))
3376 (match_operand:DI 1 "s_register_operand" "0,r")))]
3379 [(set_attr "length" "8")
3380 (set_attr "predicable" "yes")
3381 (set_attr "type" "multiple")]
3384 (define_expand "xorsi3"
3385 [(set (match_operand:SI 0 "s_register_operand" "")
3386 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3387 (match_operand:SI 2 "reg_or_int_operand" "")))]
3389 "if (CONST_INT_P (operands[2]))
3393 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3394 operands[2] = force_reg (SImode, operands[2]);
3397 arm_split_constant (XOR, SImode, NULL_RTX,
3398 INTVAL (operands[2]), operands[0],
3400 optimize && can_create_pseudo_p ());
3404 else /* TARGET_THUMB1 */
3406 rtx tmp = force_reg (SImode, operands[2]);
3407 if (rtx_equal_p (operands[0], operands[1]))
3411 operands[2] = operands[1];
3418 (define_insn_and_split "*arm_xorsi3"
3419 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3420 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3421 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3429 && CONST_INT_P (operands[2])
3430 && !const_ok_for_arm (INTVAL (operands[2]))"
3431 [(clobber (const_int 0))]
3433 arm_split_constant (XOR, SImode, curr_insn,
3434 INTVAL (operands[2]), operands[0], operands[1], 0);
3437 [(set_attr "length" "4,4,4,16")
3438 (set_attr "predicable" "yes")
3439 (set_attr "predicable_short_it" "no,yes,no,no")
3440 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3443 (define_insn "*xorsi3_compare0"
3444 [(set (reg:CC_NOOV CC_REGNUM)
3445 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3446 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3448 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3449 (xor:SI (match_dup 1) (match_dup 2)))]
3451 "eors%?\\t%0, %1, %2"
3452 [(set_attr "conds" "set")
3453 (set_attr "type" "logics_imm,logics_reg")]
3456 (define_insn "*xorsi3_compare0_scratch"
3457 [(set (reg:CC_NOOV CC_REGNUM)
3458 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3459 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3463 [(set_attr "conds" "set")
3464 (set_attr "type" "logics_imm,logics_reg")]
3467 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3468 ; (NOT D) we can sometimes merge the final NOT into one of the following
3472 [(set (match_operand:SI 0 "s_register_operand" "")
3473 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3474 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3475 (match_operand:SI 3 "arm_rhs_operand" "")))
3476 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3478 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3479 (not:SI (match_dup 3))))
3480 (set (match_dup 0) (not:SI (match_dup 4)))]
3484 (define_insn_and_split "*andsi_iorsi3_notsi"
3485 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3486 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3487 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3488 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3490 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3491 "&& reload_completed"
3492 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3493 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3495 /* If operands[3] is a constant make sure to fold the NOT into it
3496 to avoid creating a NOT of a CONST_INT. */
3497 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3498 if (CONST_INT_P (not_rtx))
3500 operands[4] = operands[0];
3501 operands[5] = not_rtx;
3505 operands[5] = operands[0];
3506 operands[4] = not_rtx;
3509 [(set_attr "length" "8")
3510 (set_attr "ce_count" "2")
3511 (set_attr "predicable" "yes")
3512 (set_attr "predicable_short_it" "no")
3513 (set_attr "type" "multiple")]
3516 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3517 ; insns are available?
3519 [(set (match_operand:SI 0 "s_register_operand" "")
3520 (match_operator:SI 1 "logical_binary_operator"
3521 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3522 (match_operand:SI 3 "const_int_operand" "")
3523 (match_operand:SI 4 "const_int_operand" ""))
3524 (match_operator:SI 9 "logical_binary_operator"
3525 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3526 (match_operand:SI 6 "const_int_operand" ""))
3527 (match_operand:SI 7 "s_register_operand" "")])]))
3528 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3530 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3531 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3534 [(ashift:SI (match_dup 2) (match_dup 4))
3538 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3541 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3545 [(set (match_operand:SI 0 "s_register_operand" "")
3546 (match_operator:SI 1 "logical_binary_operator"
3547 [(match_operator:SI 9 "logical_binary_operator"
3548 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3549 (match_operand:SI 6 "const_int_operand" ""))
3550 (match_operand:SI 7 "s_register_operand" "")])
3551 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3552 (match_operand:SI 3 "const_int_operand" "")
3553 (match_operand:SI 4 "const_int_operand" ""))]))
3554 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3556 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3557 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3560 [(ashift:SI (match_dup 2) (match_dup 4))
3564 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3567 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3571 [(set (match_operand:SI 0 "s_register_operand" "")
3572 (match_operator:SI 1 "logical_binary_operator"
3573 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3574 (match_operand:SI 3 "const_int_operand" "")
3575 (match_operand:SI 4 "const_int_operand" ""))
3576 (match_operator:SI 9 "logical_binary_operator"
3577 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3578 (match_operand:SI 6 "const_int_operand" ""))
3579 (match_operand:SI 7 "s_register_operand" "")])]))
3580 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3582 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3583 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3586 [(ashift:SI (match_dup 2) (match_dup 4))
3590 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3593 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3597 [(set (match_operand:SI 0 "s_register_operand" "")
3598 (match_operator:SI 1 "logical_binary_operator"
3599 [(match_operator:SI 9 "logical_binary_operator"
3600 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3601 (match_operand:SI 6 "const_int_operand" ""))
3602 (match_operand:SI 7 "s_register_operand" "")])
3603 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3604 (match_operand:SI 3 "const_int_operand" "")
3605 (match_operand:SI 4 "const_int_operand" ""))]))
3606 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3608 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3609 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3612 [(ashift:SI (match_dup 2) (match_dup 4))
3616 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3619 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3623 ;; Minimum and maximum insns
3625 (define_expand "smaxsi3"
3627 (set (match_operand:SI 0 "s_register_operand" "")
3628 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3629 (match_operand:SI 2 "arm_rhs_operand" "")))
3630 (clobber (reg:CC CC_REGNUM))])]
3633 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3635 /* No need for a clobber of the condition code register here. */
3636 emit_insn (gen_rtx_SET (operands[0],
3637 gen_rtx_SMAX (SImode, operands[1],
3643 (define_insn "*smax_0"
3644 [(set (match_operand:SI 0 "s_register_operand" "=r")
3645 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3648 "bic%?\\t%0, %1, %1, asr #31"
3649 [(set_attr "predicable" "yes")
3650 (set_attr "predicable_short_it" "no")
3651 (set_attr "type" "logic_shift_reg")]
3654 (define_insn "*smax_m1"
3655 [(set (match_operand:SI 0 "s_register_operand" "=r")
3656 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3659 "orr%?\\t%0, %1, %1, asr #31"
3660 [(set_attr "predicable" "yes")
3661 (set_attr "predicable_short_it" "no")
3662 (set_attr "type" "logic_shift_reg")]
3665 (define_insn_and_split "*arm_smax_insn"
3666 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3667 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3668 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3669 (clobber (reg:CC CC_REGNUM))]
3672 ; cmp\\t%1, %2\;movlt\\t%0, %2
3673 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3675 [(set (reg:CC CC_REGNUM)
3676 (compare:CC (match_dup 1) (match_dup 2)))
3678 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3682 [(set_attr "conds" "clob")
3683 (set_attr "length" "8,12")
3684 (set_attr "type" "multiple")]
3687 (define_expand "sminsi3"
3689 (set (match_operand:SI 0 "s_register_operand" "")
3690 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3691 (match_operand:SI 2 "arm_rhs_operand" "")))
3692 (clobber (reg:CC CC_REGNUM))])]
3695 if (operands[2] == const0_rtx)
3697 /* No need for a clobber of the condition code register here. */
3698 emit_insn (gen_rtx_SET (operands[0],
3699 gen_rtx_SMIN (SImode, operands[1],
3705 (define_insn "*smin_0"
3706 [(set (match_operand:SI 0 "s_register_operand" "=r")
3707 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3710 "and%?\\t%0, %1, %1, asr #31"
3711 [(set_attr "predicable" "yes")
3712 (set_attr "predicable_short_it" "no")
3713 (set_attr "type" "logic_shift_reg")]
3716 (define_insn_and_split "*arm_smin_insn"
3717 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3718 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3719 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3720 (clobber (reg:CC CC_REGNUM))]
3723 ; cmp\\t%1, %2\;movge\\t%0, %2
3724 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3726 [(set (reg:CC CC_REGNUM)
3727 (compare:CC (match_dup 1) (match_dup 2)))
3729 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3733 [(set_attr "conds" "clob")
3734 (set_attr "length" "8,12")
3735 (set_attr "type" "multiple,multiple")]
3738 (define_expand "umaxsi3"
3740 (set (match_operand:SI 0 "s_register_operand" "")
3741 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3742 (match_operand:SI 2 "arm_rhs_operand" "")))
3743 (clobber (reg:CC CC_REGNUM))])]
3748 (define_insn_and_split "*arm_umaxsi3"
3749 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3750 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3751 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3752 (clobber (reg:CC CC_REGNUM))]
3755 ; cmp\\t%1, %2\;movcc\\t%0, %2
3756 ; cmp\\t%1, %2\;movcs\\t%0, %1
3757 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3759 [(set (reg:CC CC_REGNUM)
3760 (compare:CC (match_dup 1) (match_dup 2)))
3762 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3766 [(set_attr "conds" "clob")
3767 (set_attr "length" "8,8,12")
3768 (set_attr "type" "store1")]
3771 (define_expand "uminsi3"
3773 (set (match_operand:SI 0 "s_register_operand" "")
3774 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3775 (match_operand:SI 2 "arm_rhs_operand" "")))
3776 (clobber (reg:CC CC_REGNUM))])]
3781 (define_insn_and_split "*arm_uminsi3"
3782 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3783 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3784 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3785 (clobber (reg:CC CC_REGNUM))]
3788 ; cmp\\t%1, %2\;movcs\\t%0, %2
3789 ; cmp\\t%1, %2\;movcc\\t%0, %1
3790 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3792 [(set (reg:CC CC_REGNUM)
3793 (compare:CC (match_dup 1) (match_dup 2)))
3795 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3799 [(set_attr "conds" "clob")
3800 (set_attr "length" "8,8,12")
3801 (set_attr "type" "store1")]
3804 (define_insn "*store_minmaxsi"
3805 [(set (match_operand:SI 0 "memory_operand" "=m")
3806 (match_operator:SI 3 "minmax_operator"
3807 [(match_operand:SI 1 "s_register_operand" "r")
3808 (match_operand:SI 2 "s_register_operand" "r")]))
3809 (clobber (reg:CC CC_REGNUM))]
3810 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3812 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3813 operands[1], operands[2]);
3814 output_asm_insn (\"cmp\\t%1, %2\", operands);
3816 output_asm_insn (\"ite\t%d3\", operands);
3817 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3818 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3821 [(set_attr "conds" "clob")
3822 (set (attr "length")
3823 (if_then_else (eq_attr "is_thumb" "yes")
3826 (set_attr "type" "store1")]
3829 ; Reject the frame pointer in operand[1], since reloading this after
3830 ; it has been eliminated can cause carnage.
3831 (define_insn "*minmax_arithsi"
3832 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3833 (match_operator:SI 4 "shiftable_operator"
3834 [(match_operator:SI 5 "minmax_operator"
3835 [(match_operand:SI 2 "s_register_operand" "r,r")
3836 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3837 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3838 (clobber (reg:CC CC_REGNUM))]
3839 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3842 enum rtx_code code = GET_CODE (operands[4]);
3845 if (which_alternative != 0 || operands[3] != const0_rtx
3846 || (code != PLUS && code != IOR && code != XOR))
3851 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3852 operands[2], operands[3]);
3853 output_asm_insn (\"cmp\\t%2, %3\", operands);
3857 output_asm_insn (\"ite\\t%d5\", operands);
3859 output_asm_insn (\"it\\t%d5\", operands);
3861 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3863 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3866 [(set_attr "conds" "clob")
3867 (set (attr "length")
3868 (if_then_else (eq_attr "is_thumb" "yes")
3871 (set_attr "type" "multiple")]
3874 ; Reject the frame pointer in operand[1], since reloading this after
3875 ; it has been eliminated can cause carnage.
3876 (define_insn_and_split "*minmax_arithsi_non_canon"
3877 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3879 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3880 (match_operator:SI 4 "minmax_operator"
3881 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3882 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3883 (clobber (reg:CC CC_REGNUM))]
3884 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3885 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3887 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3888 [(set (reg:CC CC_REGNUM)
3889 (compare:CC (match_dup 2) (match_dup 3)))
3891 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3893 (minus:SI (match_dup 1)
3895 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3899 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3900 operands[2], operands[3]);
3901 enum rtx_code rc = minmax_code (operands[4]);
3902 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3903 operands[2], operands[3]);
3905 if (mode == CCFPmode || mode == CCFPEmode)
3906 rc = reverse_condition_maybe_unordered (rc);
3908 rc = reverse_condition (rc);
3909 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3910 if (CONST_INT_P (operands[3]))
3911 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3913 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3915 [(set_attr "conds" "clob")
3916 (set (attr "length")
3917 (if_then_else (eq_attr "is_thumb" "yes")
3920 (set_attr "type" "multiple")]
3923 (define_code_iterator SAT [smin smax])
3924 (define_code_iterator SATrev [smin smax])
3925 (define_code_attr SATlo [(smin "1") (smax "2")])
3926 (define_code_attr SAThi [(smin "2") (smax "1")])
3928 (define_insn "*satsi_<SAT:code>"
3929 [(set (match_operand:SI 0 "s_register_operand" "=r")
3930 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3931 (match_operand:SI 1 "const_int_operand" "i"))
3932 (match_operand:SI 2 "const_int_operand" "i")))]
3933 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3934 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3938 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3939 &mask, &signed_sat))
3942 operands[1] = GEN_INT (mask);
3944 return "ssat%?\t%0, %1, %3";
3946 return "usat%?\t%0, %1, %3";
3948 [(set_attr "predicable" "yes")
3949 (set_attr "predicable_short_it" "no")
3950 (set_attr "type" "alus_imm")]
3953 (define_insn "*satsi_<SAT:code>_shift"
3954 [(set (match_operand:SI 0 "s_register_operand" "=r")
3955 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3956 [(match_operand:SI 4 "s_register_operand" "r")
3957 (match_operand:SI 5 "const_int_operand" "i")])
3958 (match_operand:SI 1 "const_int_operand" "i"))
3959 (match_operand:SI 2 "const_int_operand" "i")))]
3960 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3961 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3965 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3966 &mask, &signed_sat))
3969 operands[1] = GEN_INT (mask);
3971 return "ssat%?\t%0, %1, %4%S3";
3973 return "usat%?\t%0, %1, %4%S3";
3975 [(set_attr "predicable" "yes")
3976 (set_attr "predicable_short_it" "no")
3977 (set_attr "shift" "3")
3978 (set_attr "type" "logic_shift_reg")])
3980 ;; Shift and rotation insns
3982 (define_expand "ashldi3"
3983 [(set (match_operand:DI 0 "s_register_operand" "")
3984 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3985 (match_operand:SI 2 "general_operand" "")))]
3990 /* Delay the decision whether to use NEON or core-regs until
3991 register allocation. */
3992 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3997 /* Only the NEON case can handle in-memory shift counts. */
3998 if (!reg_or_int_operand (operands[2], SImode))
3999 operands[2] = force_reg (SImode, operands[2]);
4002 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4003 ; /* No special preparation statements; expand pattern as above. */
4006 rtx scratch1, scratch2;
4008 if (operands[2] == CONST1_RTX (SImode))
4010 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
4014 /* Ideally we should use iwmmxt here if we could know that operands[1]
4015 ends up already living in an iwmmxt register. Otherwise it's
4016 cheaper to have the alternate code being generated than moving
4017 values to iwmmxt regs and back. */
4019 /* If we're optimizing for size, we prefer the libgcc calls. */
4020 if (optimize_function_for_size_p (cfun))
4023 /* Expand operation using core-registers.
4024 'FAIL' would achieve the same thing, but this is a bit smarter. */
4025 scratch1 = gen_reg_rtx (SImode);
4026 scratch2 = gen_reg_rtx (SImode);
4027 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4028 operands[2], scratch1, scratch2);
4034 (define_insn "arm_ashldi3_1bit"
4035 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4036 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4038 (clobber (reg:CC CC_REGNUM))]
4040 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4041 [(set_attr "conds" "clob")
4042 (set_attr "length" "8")
4043 (set_attr "type" "multiple")]
4046 (define_expand "ashlsi3"
4047 [(set (match_operand:SI 0 "s_register_operand" "")
4048 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4049 (match_operand:SI 2 "arm_rhs_operand" "")))]
4052 if (CONST_INT_P (operands[2])
4053 && (UINTVAL (operands[2])) > 31)
4055 emit_insn (gen_movsi (operands[0], const0_rtx));
4061 (define_expand "ashrdi3"
4062 [(set (match_operand:DI 0 "s_register_operand" "")
4063 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4064 (match_operand:SI 2 "reg_or_int_operand" "")))]
4069 /* Delay the decision whether to use NEON or core-regs until
4070 register allocation. */
4071 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4075 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4076 ; /* No special preparation statements; expand pattern as above. */
4079 rtx scratch1, scratch2;
4081 if (operands[2] == CONST1_RTX (SImode))
4083 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4087 /* Ideally we should use iwmmxt here if we could know that operands[1]
4088 ends up already living in an iwmmxt register. Otherwise it's
4089 cheaper to have the alternate code being generated than moving
4090 values to iwmmxt regs and back. */
4092 /* If we're optimizing for size, we prefer the libgcc calls. */
4093 if (optimize_function_for_size_p (cfun))
4096 /* Expand operation using core-registers.
4097 'FAIL' would achieve the same thing, but this is a bit smarter. */
4098 scratch1 = gen_reg_rtx (SImode);
4099 scratch2 = gen_reg_rtx (SImode);
4100 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4101 operands[2], scratch1, scratch2);
4107 (define_insn "arm_ashrdi3_1bit"
4108 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4109 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4111 (clobber (reg:CC CC_REGNUM))]
4113 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4114 [(set_attr "conds" "clob")
4115 (set_attr "length" "8")
4116 (set_attr "type" "multiple")]
4119 (define_expand "ashrsi3"
4120 [(set (match_operand:SI 0 "s_register_operand" "")
4121 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4122 (match_operand:SI 2 "arm_rhs_operand" "")))]
4125 if (CONST_INT_P (operands[2])
4126 && UINTVAL (operands[2]) > 31)
4127 operands[2] = GEN_INT (31);
4131 (define_expand "lshrdi3"
4132 [(set (match_operand:DI 0 "s_register_operand" "")
4133 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4134 (match_operand:SI 2 "reg_or_int_operand" "")))]
4139 /* Delay the decision whether to use NEON or core-regs until
4140 register allocation. */
4141 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4145 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4146 ; /* No special preparation statements; expand pattern as above. */
4149 rtx scratch1, scratch2;
4151 if (operands[2] == CONST1_RTX (SImode))
4153 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4157 /* Ideally we should use iwmmxt here if we could know that operands[1]
4158 ends up already living in an iwmmxt register. Otherwise it's
4159 cheaper to have the alternate code being generated than moving
4160 values to iwmmxt regs and back. */
4162 /* If we're optimizing for size, we prefer the libgcc calls. */
4163 if (optimize_function_for_size_p (cfun))
4166 /* Expand operation using core-registers.
4167 'FAIL' would achieve the same thing, but this is a bit smarter. */
4168 scratch1 = gen_reg_rtx (SImode);
4169 scratch2 = gen_reg_rtx (SImode);
4170 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4171 operands[2], scratch1, scratch2);
4177 (define_insn "arm_lshrdi3_1bit"
4178 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4179 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4181 (clobber (reg:CC CC_REGNUM))]
4183 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4184 [(set_attr "conds" "clob")
4185 (set_attr "length" "8")
4186 (set_attr "type" "multiple")]
4189 (define_expand "lshrsi3"
4190 [(set (match_operand:SI 0 "s_register_operand" "")
4191 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4192 (match_operand:SI 2 "arm_rhs_operand" "")))]
4195 if (CONST_INT_P (operands[2])
4196 && (UINTVAL (operands[2])) > 31)
4198 emit_insn (gen_movsi (operands[0], const0_rtx));
4204 (define_expand "rotlsi3"
4205 [(set (match_operand:SI 0 "s_register_operand" "")
4206 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4207 (match_operand:SI 2 "reg_or_int_operand" "")))]
4210 if (CONST_INT_P (operands[2]))
4211 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4214 rtx reg = gen_reg_rtx (SImode);
4215 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4221 (define_expand "rotrsi3"
4222 [(set (match_operand:SI 0 "s_register_operand" "")
4223 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4224 (match_operand:SI 2 "arm_rhs_operand" "")))]
4229 if (CONST_INT_P (operands[2])
4230 && UINTVAL (operands[2]) > 31)
4231 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4233 else /* TARGET_THUMB1 */
4235 if (CONST_INT_P (operands [2]))
4236 operands [2] = force_reg (SImode, operands[2]);
4241 (define_insn "*arm_shiftsi3"
4242 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4243 (match_operator:SI 3 "shift_operator"
4244 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4245 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4247 "* return arm_output_shift(operands, 0);"
4248 [(set_attr "predicable" "yes")
4249 (set_attr "arch" "t2,t2,*,*")
4250 (set_attr "predicable_short_it" "yes,yes,no,no")
4251 (set_attr "length" "4")
4252 (set_attr "shift" "1")
4253 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4256 (define_insn "*shiftsi3_compare0"
4257 [(set (reg:CC_NOOV CC_REGNUM)
4258 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4259 [(match_operand:SI 1 "s_register_operand" "r,r")
4260 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4262 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4263 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4265 "* return arm_output_shift(operands, 1);"
4266 [(set_attr "conds" "set")
4267 (set_attr "shift" "1")
4268 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4271 (define_insn "*shiftsi3_compare0_scratch"
4272 [(set (reg:CC_NOOV CC_REGNUM)
4273 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4274 [(match_operand:SI 1 "s_register_operand" "r,r")
4275 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4277 (clobber (match_scratch:SI 0 "=r,r"))]
4279 "* return arm_output_shift(operands, 1);"
4280 [(set_attr "conds" "set")
4281 (set_attr "shift" "1")
4282 (set_attr "type" "shift_imm,shift_reg")]
4285 (define_insn "*not_shiftsi"
4286 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4287 (not:SI (match_operator:SI 3 "shift_operator"
4288 [(match_operand:SI 1 "s_register_operand" "r,r")
4289 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4292 [(set_attr "predicable" "yes")
4293 (set_attr "predicable_short_it" "no")
4294 (set_attr "shift" "1")
4295 (set_attr "arch" "32,a")
4296 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4298 (define_insn "*not_shiftsi_compare0"
4299 [(set (reg:CC_NOOV CC_REGNUM)
4301 (not:SI (match_operator:SI 3 "shift_operator"
4302 [(match_operand:SI 1 "s_register_operand" "r,r")
4303 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4305 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4306 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4308 "mvns%?\\t%0, %1%S3"
4309 [(set_attr "conds" "set")
4310 (set_attr "shift" "1")
4311 (set_attr "arch" "32,a")
4312 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4314 (define_insn "*not_shiftsi_compare0_scratch"
4315 [(set (reg:CC_NOOV CC_REGNUM)
4317 (not:SI (match_operator:SI 3 "shift_operator"
4318 [(match_operand:SI 1 "s_register_operand" "r,r")
4319 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4321 (clobber (match_scratch:SI 0 "=r,r"))]
4323 "mvns%?\\t%0, %1%S3"
4324 [(set_attr "conds" "set")
4325 (set_attr "shift" "1")
4326 (set_attr "arch" "32,a")
4327 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4329 ;; We don't really have extzv, but defining this using shifts helps
4330 ;; to reduce register pressure later on.
4332 (define_expand "extzv"
4333 [(set (match_operand 0 "s_register_operand" "")
4334 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4335 (match_operand 2 "const_int_operand" "")
4336 (match_operand 3 "const_int_operand" "")))]
4337 "TARGET_THUMB1 || arm_arch_thumb2"
4340 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4341 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4343 if (arm_arch_thumb2)
4345 HOST_WIDE_INT width = INTVAL (operands[2]);
4346 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4348 if (unaligned_access && MEM_P (operands[1])
4349 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4353 if (BYTES_BIG_ENDIAN)
4354 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4359 base_addr = adjust_address (operands[1], SImode,
4360 bitpos / BITS_PER_UNIT);
4361 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4365 rtx dest = operands[0];
4366 rtx tmp = gen_reg_rtx (SImode);
4368 /* We may get a paradoxical subreg here. Strip it off. */
4369 if (GET_CODE (dest) == SUBREG
4370 && GET_MODE (dest) == SImode
4371 && GET_MODE (SUBREG_REG (dest)) == HImode)
4372 dest = SUBREG_REG (dest);
4374 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4377 base_addr = adjust_address (operands[1], HImode,
4378 bitpos / BITS_PER_UNIT);
4379 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4380 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4384 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4386 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4394 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4397 operands[3] = GEN_INT (rshift);
4401 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4405 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4406 operands[3], gen_reg_rtx (SImode)));
4411 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4413 (define_expand "extzv_t1"
4414 [(set (match_operand:SI 4 "s_register_operand" "")
4415 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4416 (match_operand:SI 2 "const_int_operand" "")))
4417 (set (match_operand:SI 0 "s_register_operand" "")
4418 (lshiftrt:SI (match_dup 4)
4419 (match_operand:SI 3 "const_int_operand" "")))]
4423 (define_expand "extv"
4424 [(set (match_operand 0 "s_register_operand" "")
4425 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4426 (match_operand 2 "const_int_operand" "")
4427 (match_operand 3 "const_int_operand" "")))]
4430 HOST_WIDE_INT width = INTVAL (operands[2]);
4431 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4433 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4434 && (bitpos % BITS_PER_UNIT) == 0)
4438 if (BYTES_BIG_ENDIAN)
4439 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4443 base_addr = adjust_address (operands[1], SImode,
4444 bitpos / BITS_PER_UNIT);
4445 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4449 rtx dest = operands[0];
4450 rtx tmp = gen_reg_rtx (SImode);
4452 /* We may get a paradoxical subreg here. Strip it off. */
4453 if (GET_CODE (dest) == SUBREG
4454 && GET_MODE (dest) == SImode
4455 && GET_MODE (SUBREG_REG (dest)) == HImode)
4456 dest = SUBREG_REG (dest);
4458 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4461 base_addr = adjust_address (operands[1], HImode,
4462 bitpos / BITS_PER_UNIT);
4463 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4464 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4469 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4471 else if (GET_MODE (operands[0]) == SImode
4472 && GET_MODE (operands[1]) == SImode)
4474 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4482 ; Helper to expand register forms of extv with the proper modes.
4484 (define_expand "extv_regsi"
4485 [(set (match_operand:SI 0 "s_register_operand" "")
4486 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4487 (match_operand 2 "const_int_operand" "")
4488 (match_operand 3 "const_int_operand" "")))]
4493 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4495 (define_insn "unaligned_loadsi"
4496 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4497 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4498 UNSPEC_UNALIGNED_LOAD))]
4500 "ldr%?\t%0, %1\t@ unaligned"
4501 [(set_attr "arch" "t2,any")
4502 (set_attr "length" "2,4")
4503 (set_attr "predicable" "yes")
4504 (set_attr "predicable_short_it" "yes,no")
4505 (set_attr "type" "load1")])
4507 (define_insn "unaligned_loadhis"
4508 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4510 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4511 UNSPEC_UNALIGNED_LOAD)))]
4513 "ldrsh%?\t%0, %1\t@ unaligned"
4514 [(set_attr "arch" "t2,any")
4515 (set_attr "length" "2,4")
4516 (set_attr "predicable" "yes")
4517 (set_attr "predicable_short_it" "yes,no")
4518 (set_attr "type" "load_byte")])
4520 (define_insn "unaligned_loadhiu"
4521 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4523 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4524 UNSPEC_UNALIGNED_LOAD)))]
4526 "ldrh%?\t%0, %1\t@ unaligned"
4527 [(set_attr "arch" "t2,any")
4528 (set_attr "length" "2,4")
4529 (set_attr "predicable" "yes")
4530 (set_attr "predicable_short_it" "yes,no")
4531 (set_attr "type" "load_byte")])
4533 (define_insn "unaligned_storesi"
4534 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4535 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4536 UNSPEC_UNALIGNED_STORE))]
4538 "str%?\t%1, %0\t@ unaligned"
4539 [(set_attr "arch" "t2,any")
4540 (set_attr "length" "2,4")
4541 (set_attr "predicable" "yes")
4542 (set_attr "predicable_short_it" "yes,no")
4543 (set_attr "type" "store1")])
4545 (define_insn "unaligned_storehi"
4546 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4547 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4548 UNSPEC_UNALIGNED_STORE))]
4550 "strh%?\t%1, %0\t@ unaligned"
4551 [(set_attr "arch" "t2,any")
4552 (set_attr "length" "2,4")
4553 (set_attr "predicable" "yes")
4554 (set_attr "predicable_short_it" "yes,no")
4555 (set_attr "type" "store1")])
4558 (define_insn "*extv_reg"
4559 [(set (match_operand:SI 0 "s_register_operand" "=r")
4560 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4561 (match_operand:SI 2 "const_int_M_operand" "M")
4562 (match_operand:SI 3 "const_int_M_operand" "M")))]
4564 "sbfx%?\t%0, %1, %3, %2"
4565 [(set_attr "length" "4")
4566 (set_attr "predicable" "yes")
4567 (set_attr "predicable_short_it" "no")
4568 (set_attr "type" "bfm")]
4571 (define_insn "extzv_t2"
4572 [(set (match_operand:SI 0 "s_register_operand" "=r")
4573 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4574 (match_operand:SI 2 "const_int_M_operand" "M")
4575 (match_operand:SI 3 "const_int_M_operand" "M")))]
4577 "ubfx%?\t%0, %1, %3, %2"
4578 [(set_attr "length" "4")
4579 (set_attr "predicable" "yes")
4580 (set_attr "predicable_short_it" "no")
4581 (set_attr "type" "bfm")]
4585 ;; Division instructions
4586 (define_insn "divsi3"
4587 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4588 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4589 (match_operand:SI 2 "s_register_operand" "r,r")))]
4594 [(set_attr "arch" "32,v8mb")
4595 (set_attr "predicable" "yes")
4596 (set_attr "predicable_short_it" "no")
4597 (set_attr "type" "sdiv")]
4600 (define_insn "udivsi3"
4601 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4602 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4603 (match_operand:SI 2 "s_register_operand" "r,r")))]
4608 [(set_attr "arch" "32,v8mb")
4609 (set_attr "predicable" "yes")
4610 (set_attr "predicable_short_it" "no")
4611 (set_attr "type" "udiv")]
4615 ;; Unary arithmetic insns
4617 (define_expand "negvsi3"
4618 [(match_operand:SI 0 "register_operand")
4619 (match_operand:SI 1 "register_operand")
4620 (match_operand 2 "")]
4623 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4624 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4629 (define_expand "negvdi3"
4630 [(match_operand:DI 0 "register_operand")
4631 (match_operand:DI 1 "register_operand")
4632 (match_operand 2 "")]
4635 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4636 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4642 (define_insn_and_split "negdi2_compare"
4643 [(set (reg:CC CC_REGNUM)
4646 (match_operand:DI 1 "register_operand" "0,r")))
4647 (set (match_operand:DI 0 "register_operand" "=r,&r")
4648 (minus:DI (const_int 0) (match_dup 1)))]
4651 "&& reload_completed"
4652 [(parallel [(set (reg:CC CC_REGNUM)
4653 (compare:CC (const_int 0) (match_dup 1)))
4654 (set (match_dup 0) (minus:SI (const_int 0)
4656 (parallel [(set (reg:CC CC_REGNUM)
4657 (compare:CC (const_int 0) (match_dup 3)))
4660 (minus:SI (const_int 0) (match_dup 3))
4661 (ltu:SI (reg:CC_C CC_REGNUM)
4664 operands[2] = gen_highpart (SImode, operands[0]);
4665 operands[0] = gen_lowpart (SImode, operands[0]);
4666 operands[3] = gen_highpart (SImode, operands[1]);
4667 operands[1] = gen_lowpart (SImode, operands[1]);
4669 [(set_attr "conds" "set")
4670 (set_attr "length" "8")
4671 (set_attr "type" "multiple")]
4674 (define_expand "negdi2"
4676 [(set (match_operand:DI 0 "s_register_operand" "")
4677 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4678 (clobber (reg:CC CC_REGNUM))])]
4683 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4689 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4690 ;; The first alternative allows the common case of a *full* overlap.
4691 (define_insn_and_split "*arm_negdi2"
4692 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4693 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4694 (clobber (reg:CC CC_REGNUM))]
4696 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4697 "&& reload_completed"
4698 [(parallel [(set (reg:CC CC_REGNUM)
4699 (compare:CC (const_int 0) (match_dup 1)))
4700 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4701 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4702 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4704 operands[2] = gen_highpart (SImode, operands[0]);
4705 operands[0] = gen_lowpart (SImode, operands[0]);
4706 operands[3] = gen_highpart (SImode, operands[1]);
4707 operands[1] = gen_lowpart (SImode, operands[1]);
4709 [(set_attr "conds" "clob")
4710 (set_attr "length" "8")
4711 (set_attr "type" "multiple")]
4714 (define_insn "*negsi2_carryin_compare"
4715 [(set (reg:CC CC_REGNUM)
4716 (compare:CC (const_int 0)
4717 (match_operand:SI 1 "s_register_operand" "r")))
4718 (set (match_operand:SI 0 "s_register_operand" "=r")
4719 (minus:SI (minus:SI (const_int 0)
4721 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4724 [(set_attr "conds" "set")
4725 (set_attr "type" "alus_imm")]
4728 (define_expand "negsi2"
4729 [(set (match_operand:SI 0 "s_register_operand" "")
4730 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4735 (define_insn "*arm_negsi2"
4736 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4737 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4739 "rsb%?\\t%0, %1, #0"
4740 [(set_attr "predicable" "yes")
4741 (set_attr "predicable_short_it" "yes,no")
4742 (set_attr "arch" "t2,*")
4743 (set_attr "length" "4")
4744 (set_attr "type" "alu_sreg")]
4747 (define_expand "negsf2"
4748 [(set (match_operand:SF 0 "s_register_operand" "")
4749 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4750 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4754 (define_expand "negdf2"
4755 [(set (match_operand:DF 0 "s_register_operand" "")
4756 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4757 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4760 (define_insn_and_split "*zextendsidi_negsi"
4761 [(set (match_operand:DI 0 "s_register_operand" "=r")
4762 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4767 (neg:SI (match_dup 1)))
4771 operands[2] = gen_lowpart (SImode, operands[0]);
4772 operands[3] = gen_highpart (SImode, operands[0]);
4774 [(set_attr "length" "8")
4775 (set_attr "type" "multiple")]
4778 ;; Negate an extended 32-bit value.
4779 (define_insn_and_split "*negdi_extendsidi"
4780 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4781 (neg:DI (sign_extend:DI
4782 (match_operand:SI 1 "s_register_operand" "l,r"))))
4783 (clobber (reg:CC CC_REGNUM))]
4786 "&& reload_completed"
4789 rtx low = gen_lowpart (SImode, operands[0]);
4790 rtx high = gen_highpart (SImode, operands[0]);
4792 if (reg_overlap_mentioned_p (low, operands[1]))
4794 /* Input overlaps the low word of the output. Use:
4797 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4798 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4800 emit_insn (gen_rtx_SET (high,
4801 gen_rtx_ASHIFTRT (SImode, operands[1],
4804 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4806 emit_insn (gen_rtx_SET (high,
4807 gen_rtx_MINUS (SImode,
4808 gen_rtx_MINUS (SImode,
4811 gen_rtx_LTU (SImode,
4816 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4817 emit_insn (gen_rtx_SET (high,
4818 gen_rtx_MINUS (SImode,
4819 gen_rtx_MINUS (SImode,
4822 gen_rtx_LTU (SImode,
4829 /* No overlap, or overlap on high word. Use:
4833 Flags not needed for this sequence. */
4834 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4835 emit_insn (gen_rtx_SET (high,
4836 gen_rtx_AND (SImode,
4837 gen_rtx_NOT (SImode, operands[1]),
4839 emit_insn (gen_rtx_SET (high,
4840 gen_rtx_ASHIFTRT (SImode, high,
4845 [(set_attr "length" "12")
4846 (set_attr "arch" "t2,*")
4847 (set_attr "type" "multiple")]
4850 (define_insn_and_split "*negdi_zero_extendsidi"
4851 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4852 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4853 (clobber (reg:CC CC_REGNUM))]
4855 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4856 ;; Don't care what register is input to sbc,
4857 ;; since we just need to propagate the carry.
4858 "&& reload_completed"
4859 [(parallel [(set (reg:CC CC_REGNUM)
4860 (compare:CC (const_int 0) (match_dup 1)))
4861 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4862 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4863 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4865 operands[2] = gen_highpart (SImode, operands[0]);
4866 operands[0] = gen_lowpart (SImode, operands[0]);
4868 [(set_attr "conds" "clob")
4869 (set_attr "length" "8")
4870 (set_attr "type" "multiple")] ;; length in thumb is 4
4873 ;; abssi2 doesn't really clobber the condition codes if a different register
4874 ;; is being set. To keep things simple, assume during rtl manipulations that
4875 ;; it does, but tell the final scan operator the truth. Similarly for
4878 (define_expand "abssi2"
4880 [(set (match_operand:SI 0 "s_register_operand" "")
4881 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4882 (clobber (match_dup 2))])]
4886 operands[2] = gen_rtx_SCRATCH (SImode);
4888 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4891 (define_insn_and_split "*arm_abssi2"
4892 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4893 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4894 (clobber (reg:CC CC_REGNUM))]
4897 "&& reload_completed"
4900 /* if (which_alternative == 0) */
4901 if (REGNO(operands[0]) == REGNO(operands[1]))
4903 /* Emit the pattern:
4904 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4905 [(set (reg:CC CC_REGNUM)
4906 (compare:CC (match_dup 0) (const_int 0)))
4907 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4908 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4910 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4911 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4912 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4913 (gen_rtx_LT (SImode,
4914 gen_rtx_REG (CCmode, CC_REGNUM),
4916 (gen_rtx_SET (operands[0],
4917 (gen_rtx_MINUS (SImode,
4924 /* Emit the pattern:
4925 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4927 (xor:SI (match_dup 1)
4928 (ashiftrt:SI (match_dup 1) (const_int 31))))
4930 (minus:SI (match_dup 0)
4931 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4933 emit_insn (gen_rtx_SET (operands[0],
4934 gen_rtx_XOR (SImode,
4935 gen_rtx_ASHIFTRT (SImode,
4939 emit_insn (gen_rtx_SET (operands[0],
4940 gen_rtx_MINUS (SImode,
4942 gen_rtx_ASHIFTRT (SImode,
4948 [(set_attr "conds" "clob,*")
4949 (set_attr "shift" "1")
4950 (set_attr "predicable" "no, yes")
4951 (set_attr "length" "8")
4952 (set_attr "type" "multiple")]
4955 (define_insn_and_split "*arm_neg_abssi2"
4956 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4957 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4958 (clobber (reg:CC CC_REGNUM))]
4961 "&& reload_completed"
4964 /* if (which_alternative == 0) */
4965 if (REGNO (operands[0]) == REGNO (operands[1]))
4967 /* Emit the pattern:
4968 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4970 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4971 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4972 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4974 gen_rtx_REG (CCmode, CC_REGNUM),
4976 gen_rtx_SET (operands[0],
4977 (gen_rtx_MINUS (SImode,
4983 /* Emit the pattern:
4984 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4986 emit_insn (gen_rtx_SET (operands[0],
4987 gen_rtx_XOR (SImode,
4988 gen_rtx_ASHIFTRT (SImode,
4992 emit_insn (gen_rtx_SET (operands[0],
4993 gen_rtx_MINUS (SImode,
4994 gen_rtx_ASHIFTRT (SImode,
5001 [(set_attr "conds" "clob,*")
5002 (set_attr "shift" "1")
5003 (set_attr "predicable" "no, yes")
5004 (set_attr "length" "8")
5005 (set_attr "type" "multiple")]
5008 (define_expand "abssf2"
5009 [(set (match_operand:SF 0 "s_register_operand" "")
5010 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5011 "TARGET_32BIT && TARGET_HARD_FLOAT"
5014 (define_expand "absdf2"
5015 [(set (match_operand:DF 0 "s_register_operand" "")
5016 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5017 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5020 (define_expand "sqrtsf2"
5021 [(set (match_operand:SF 0 "s_register_operand" "")
5022 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5023 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
5026 (define_expand "sqrtdf2"
5027 [(set (match_operand:DF 0 "s_register_operand" "")
5028 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5029 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5032 (define_insn_and_split "one_cmpldi2"
5033 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5034 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5041 "TARGET_32BIT && reload_completed
5042 && arm_general_register_operand (operands[0], DImode)"
5043 [(set (match_dup 0) (not:SI (match_dup 1)))
5044 (set (match_dup 2) (not:SI (match_dup 3)))]
5047 operands[2] = gen_highpart (SImode, operands[0]);
5048 operands[0] = gen_lowpart (SImode, operands[0]);
5049 operands[3] = gen_highpart (SImode, operands[1]);
5050 operands[1] = gen_lowpart (SImode, operands[1]);
5052 [(set_attr "length" "*,8,8,*")
5053 (set_attr "predicable" "no,yes,yes,no")
5054 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5055 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5058 (define_expand "one_cmplsi2"
5059 [(set (match_operand:SI 0 "s_register_operand" "")
5060 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5065 (define_insn "*arm_one_cmplsi2"
5066 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5067 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5070 [(set_attr "predicable" "yes")
5071 (set_attr "predicable_short_it" "yes,no")
5072 (set_attr "arch" "t2,*")
5073 (set_attr "length" "4")
5074 (set_attr "type" "mvn_reg")]
5077 (define_insn "*notsi_compare0"
5078 [(set (reg:CC_NOOV CC_REGNUM)
5079 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5081 (set (match_operand:SI 0 "s_register_operand" "=r")
5082 (not:SI (match_dup 1)))]
5085 [(set_attr "conds" "set")
5086 (set_attr "type" "mvn_reg")]
5089 (define_insn "*notsi_compare0_scratch"
5090 [(set (reg:CC_NOOV CC_REGNUM)
5091 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5093 (clobber (match_scratch:SI 0 "=r"))]
5096 [(set_attr "conds" "set")
5097 (set_attr "type" "mvn_reg")]
5100 ;; Fixed <--> Floating conversion insns
5102 (define_expand "floatsihf2"
5103 [(set (match_operand:HF 0 "general_operand" "")
5104 (float:HF (match_operand:SI 1 "general_operand" "")))]
5108 rtx op1 = gen_reg_rtx (SFmode);
5109 expand_float (op1, operands[1], 0);
5110 op1 = convert_to_mode (HFmode, op1, 0);
5111 emit_move_insn (operands[0], op1);
5116 (define_expand "floatdihf2"
5117 [(set (match_operand:HF 0 "general_operand" "")
5118 (float:HF (match_operand:DI 1 "general_operand" "")))]
5122 rtx op1 = gen_reg_rtx (SFmode);
5123 expand_float (op1, operands[1], 0);
5124 op1 = convert_to_mode (HFmode, op1, 0);
5125 emit_move_insn (operands[0], op1);
5130 (define_expand "floatsisf2"
5131 [(set (match_operand:SF 0 "s_register_operand" "")
5132 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5133 "TARGET_32BIT && TARGET_HARD_FLOAT"
5137 (define_expand "floatsidf2"
5138 [(set (match_operand:DF 0 "s_register_operand" "")
5139 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5140 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5144 (define_expand "fix_trunchfsi2"
5145 [(set (match_operand:SI 0 "general_operand" "")
5146 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5150 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5151 expand_fix (operands[0], op1, 0);
5156 (define_expand "fix_trunchfdi2"
5157 [(set (match_operand:DI 0 "general_operand" "")
5158 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5162 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5163 expand_fix (operands[0], op1, 0);
5168 (define_expand "fix_truncsfsi2"
5169 [(set (match_operand:SI 0 "s_register_operand" "")
5170 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5171 "TARGET_32BIT && TARGET_HARD_FLOAT"
5175 (define_expand "fix_truncdfsi2"
5176 [(set (match_operand:SI 0 "s_register_operand" "")
5177 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5178 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5184 (define_expand "truncdfsf2"
5185 [(set (match_operand:SF 0 "s_register_operand" "")
5187 (match_operand:DF 1 "s_register_operand" "")))]
5188 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5192 /* DFmode -> HFmode conversions have to go through SFmode. */
5193 (define_expand "truncdfhf2"
5194 [(set (match_operand:HF 0 "general_operand" "")
5196 (match_operand:DF 1 "general_operand" "")))]
5201 op1 = convert_to_mode (SFmode, operands[1], 0);
5202 op1 = convert_to_mode (HFmode, op1, 0);
5203 emit_move_insn (operands[0], op1);
5208 ;; Zero and sign extension instructions.
5210 (define_insn "zero_extend<mode>di2"
5211 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5212 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5213 "<qhs_zextenddi_cstr>")))]
5214 "TARGET_32BIT <qhs_zextenddi_cond>"
5216 [(set_attr "length" "8,4,8,8")
5217 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5218 (set_attr "ce_count" "2")
5219 (set_attr "predicable" "yes")
5220 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5223 (define_insn "extend<mode>di2"
5224 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5225 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5226 "<qhs_extenddi_cstr>")))]
5227 "TARGET_32BIT <qhs_sextenddi_cond>"
5229 [(set_attr "length" "8,4,8,8,8")
5230 (set_attr "ce_count" "2")
5231 (set_attr "shift" "1")
5232 (set_attr "predicable" "yes")
5233 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5234 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5237 ;; Splits for all extensions to DImode
5239 [(set (match_operand:DI 0 "s_register_operand" "")
5240 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5241 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5242 [(set (match_dup 0) (match_dup 1))]
5244 rtx lo_part = gen_lowpart (SImode, operands[0]);
5245 machine_mode src_mode = GET_MODE (operands[1]);
5247 if (REG_P (operands[0])
5248 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5249 emit_clobber (operands[0]);
5250 if (!REG_P (lo_part) || src_mode != SImode
5251 || !rtx_equal_p (lo_part, operands[1]))
5253 if (src_mode == SImode)
5254 emit_move_insn (lo_part, operands[1]);
5256 emit_insn (gen_rtx_SET (lo_part,
5257 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5258 operands[1] = lo_part;
5260 operands[0] = gen_highpart (SImode, operands[0]);
5261 operands[1] = const0_rtx;
5265 [(set (match_operand:DI 0 "s_register_operand" "")
5266 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5267 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5268 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5270 rtx lo_part = gen_lowpart (SImode, operands[0]);
5271 machine_mode src_mode = GET_MODE (operands[1]);
5273 if (REG_P (operands[0])
5274 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5275 emit_clobber (operands[0]);
5277 if (!REG_P (lo_part) || src_mode != SImode
5278 || !rtx_equal_p (lo_part, operands[1]))
5280 if (src_mode == SImode)
5281 emit_move_insn (lo_part, operands[1]);
5283 emit_insn (gen_rtx_SET (lo_part,
5284 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5285 operands[1] = lo_part;
5287 operands[0] = gen_highpart (SImode, operands[0]);
5290 (define_expand "zero_extendhisi2"
5291 [(set (match_operand:SI 0 "s_register_operand" "")
5292 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5295 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5297 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5300 if (!arm_arch6 && !MEM_P (operands[1]))
5302 rtx t = gen_lowpart (SImode, operands[1]);
5303 rtx tmp = gen_reg_rtx (SImode);
5304 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5305 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5311 [(set (match_operand:SI 0 "s_register_operand" "")
5312 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5313 "!TARGET_THUMB2 && !arm_arch6"
5314 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5315 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5317 operands[2] = gen_lowpart (SImode, operands[1]);
5320 (define_insn "*arm_zero_extendhisi2"
5321 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5322 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5323 "TARGET_ARM && arm_arch4 && !arm_arch6"
5327 [(set_attr "type" "alu_shift_reg,load_byte")
5328 (set_attr "predicable" "yes")]
5331 (define_insn "*arm_zero_extendhisi2_v6"
5332 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5333 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5334 "TARGET_ARM && arm_arch6"
5338 [(set_attr "predicable" "yes")
5339 (set_attr "type" "extend,load_byte")]
5342 (define_insn "*arm_zero_extendhisi2addsi"
5343 [(set (match_operand:SI 0 "s_register_operand" "=r")
5344 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5345 (match_operand:SI 2 "s_register_operand" "r")))]
5347 "uxtah%?\\t%0, %2, %1"
5348 [(set_attr "type" "alu_shift_reg")
5349 (set_attr "predicable" "yes")
5350 (set_attr "predicable_short_it" "no")]
5353 (define_expand "zero_extendqisi2"
5354 [(set (match_operand:SI 0 "s_register_operand" "")
5355 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5358 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5360 emit_insn (gen_andsi3 (operands[0],
5361 gen_lowpart (SImode, operands[1]),
5365 if (!arm_arch6 && !MEM_P (operands[1]))
5367 rtx t = gen_lowpart (SImode, operands[1]);
5368 rtx tmp = gen_reg_rtx (SImode);
5369 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5370 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5376 [(set (match_operand:SI 0 "s_register_operand" "")
5377 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5379 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5380 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5382 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5385 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5390 (define_insn "*arm_zero_extendqisi2"
5391 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5392 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5393 "TARGET_ARM && !arm_arch6"
5396 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5397 [(set_attr "length" "8,4")
5398 (set_attr "type" "alu_shift_reg,load_byte")
5399 (set_attr "predicable" "yes")]
5402 (define_insn "*arm_zero_extendqisi2_v6"
5403 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5404 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5405 "TARGET_ARM && arm_arch6"
5408 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5409 [(set_attr "type" "extend,load_byte")
5410 (set_attr "predicable" "yes")]
5413 (define_insn "*arm_zero_extendqisi2addsi"
5414 [(set (match_operand:SI 0 "s_register_operand" "=r")
5415 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5416 (match_operand:SI 2 "s_register_operand" "r")))]
5418 "uxtab%?\\t%0, %2, %1"
5419 [(set_attr "predicable" "yes")
5420 (set_attr "predicable_short_it" "no")
5421 (set_attr "type" "alu_shift_reg")]
5425 [(set (match_operand:SI 0 "s_register_operand" "")
5426 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5427 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5428 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5429 [(set (match_dup 2) (match_dup 1))
5430 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5435 [(set (match_operand:SI 0 "s_register_operand" "")
5436 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5437 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5438 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5439 [(set (match_dup 2) (match_dup 1))
5440 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5446 [(set (match_operand:SI 0 "s_register_operand" "")
5447 (IOR_XOR:SI (and:SI (ashift:SI
5448 (match_operand:SI 1 "s_register_operand" "")
5449 (match_operand:SI 2 "const_int_operand" ""))
5450 (match_operand:SI 3 "const_int_operand" ""))
5452 (match_operator 5 "subreg_lowpart_operator"
5453 [(match_operand:SI 4 "s_register_operand" "")]))))]
5455 && (UINTVAL (operands[3])
5456 == (GET_MODE_MASK (GET_MODE (operands[5]))
5457 & (GET_MODE_MASK (GET_MODE (operands[5]))
5458 << (INTVAL (operands[2])))))"
5459 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5461 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5462 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5465 (define_insn "*compareqi_eq0"
5466 [(set (reg:CC_Z CC_REGNUM)
5467 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5471 [(set_attr "conds" "set")
5472 (set_attr "predicable" "yes")
5473 (set_attr "predicable_short_it" "no")
5474 (set_attr "type" "logic_imm")]
5477 (define_expand "extendhisi2"
5478 [(set (match_operand:SI 0 "s_register_operand" "")
5479 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5484 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5487 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5489 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5493 if (!arm_arch6 && !MEM_P (operands[1]))
5495 rtx t = gen_lowpart (SImode, operands[1]);
5496 rtx tmp = gen_reg_rtx (SImode);
5497 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5498 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5505 [(set (match_operand:SI 0 "register_operand" "")
5506 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5507 (clobber (match_scratch:SI 2 ""))])]
5509 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5510 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5512 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5515 ;; This pattern will only be used when ldsh is not available
5516 (define_expand "extendhisi2_mem"
5517 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5519 (zero_extend:SI (match_dup 7)))
5520 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5521 (set (match_operand:SI 0 "" "")
5522 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5527 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5529 mem1 = change_address (operands[1], QImode, addr);
5530 mem2 = change_address (operands[1], QImode,
5531 plus_constant (Pmode, addr, 1));
5532 operands[0] = gen_lowpart (SImode, operands[0]);
5534 operands[2] = gen_reg_rtx (SImode);
5535 operands[3] = gen_reg_rtx (SImode);
5536 operands[6] = gen_reg_rtx (SImode);
5539 if (BYTES_BIG_ENDIAN)
5541 operands[4] = operands[2];
5542 operands[5] = operands[3];
5546 operands[4] = operands[3];
5547 operands[5] = operands[2];
5553 [(set (match_operand:SI 0 "register_operand" "")
5554 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5556 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5557 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5559 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5562 (define_insn "*arm_extendhisi2"
5563 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5564 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5565 "TARGET_ARM && arm_arch4 && !arm_arch6"
5569 [(set_attr "length" "8,4")
5570 (set_attr "type" "alu_shift_reg,load_byte")
5571 (set_attr "predicable" "yes")]
5574 ;; ??? Check Thumb-2 pool range
5575 (define_insn "*arm_extendhisi2_v6"
5576 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5577 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5578 "TARGET_32BIT && arm_arch6"
5582 [(set_attr "type" "extend,load_byte")
5583 (set_attr "predicable" "yes")
5584 (set_attr "predicable_short_it" "no")]
5587 (define_insn "*arm_extendhisi2addsi"
5588 [(set (match_operand:SI 0 "s_register_operand" "=r")
5589 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5590 (match_operand:SI 2 "s_register_operand" "r")))]
5592 "sxtah%?\\t%0, %2, %1"
5593 [(set_attr "type" "alu_shift_reg")]
5596 (define_expand "extendqihi2"
5598 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5600 (set (match_operand:HI 0 "s_register_operand" "")
5601 (ashiftrt:SI (match_dup 2)
5606 if (arm_arch4 && MEM_P (operands[1]))
5608 emit_insn (gen_rtx_SET (operands[0],
5609 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5612 if (!s_register_operand (operands[1], QImode))
5613 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5614 operands[0] = gen_lowpart (SImode, operands[0]);
5615 operands[1] = gen_lowpart (SImode, operands[1]);
5616 operands[2] = gen_reg_rtx (SImode);
5620 (define_insn "*arm_extendqihi_insn"
5621 [(set (match_operand:HI 0 "s_register_operand" "=r")
5622 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5623 "TARGET_ARM && arm_arch4"
5625 [(set_attr "type" "load_byte")
5626 (set_attr "predicable" "yes")]
5629 (define_expand "extendqisi2"
5630 [(set (match_operand:SI 0 "s_register_operand" "")
5631 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5634 if (!arm_arch4 && MEM_P (operands[1]))
5635 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5637 if (!arm_arch6 && !MEM_P (operands[1]))
5639 rtx t = gen_lowpart (SImode, operands[1]);
5640 rtx tmp = gen_reg_rtx (SImode);
5641 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5642 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5648 [(set (match_operand:SI 0 "register_operand" "")
5649 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5651 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5652 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5654 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5657 (define_insn "*arm_extendqisi"
5658 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5659 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5660 "TARGET_ARM && arm_arch4 && !arm_arch6"
5664 [(set_attr "length" "8,4")
5665 (set_attr "type" "alu_shift_reg,load_byte")
5666 (set_attr "predicable" "yes")]
5669 (define_insn "*arm_extendqisi_v6"
5670 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5672 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5673 "TARGET_ARM && arm_arch6"
5677 [(set_attr "type" "extend,load_byte")
5678 (set_attr "predicable" "yes")]
5681 (define_insn "*arm_extendqisi2addsi"
5682 [(set (match_operand:SI 0 "s_register_operand" "=r")
5683 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5684 (match_operand:SI 2 "s_register_operand" "r")))]
5686 "sxtab%?\\t%0, %2, %1"
5687 [(set_attr "type" "alu_shift_reg")
5688 (set_attr "predicable" "yes")
5689 (set_attr "predicable_short_it" "no")]
5692 (define_expand "extendsfdf2"
5693 [(set (match_operand:DF 0 "s_register_operand" "")
5694 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5695 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5699 /* HFmode -> DFmode conversions have to go through SFmode. */
5700 (define_expand "extendhfdf2"
5701 [(set (match_operand:DF 0 "general_operand" "")
5702 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5707 op1 = convert_to_mode (SFmode, operands[1], 0);
5708 op1 = convert_to_mode (DFmode, op1, 0);
5709 emit_insn (gen_movdf (operands[0], op1));
5714 ;; Move insns (including loads and stores)
5716 ;; XXX Just some ideas about movti.
5717 ;; I don't think these are a good idea on the arm, there just aren't enough
5719 ;;(define_expand "loadti"
5720 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5721 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5724 ;;(define_expand "storeti"
5725 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5726 ;; (match_operand:TI 1 "s_register_operand" ""))]
5729 ;;(define_expand "movti"
5730 ;; [(set (match_operand:TI 0 "general_operand" "")
5731 ;; (match_operand:TI 1 "general_operand" ""))]
5737 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5738 ;; operands[1] = copy_to_reg (operands[1]);
5739 ;; if (MEM_P (operands[0]))
5740 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5741 ;; else if (MEM_P (operands[1]))
5742 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5746 ;; emit_insn (insn);
5750 ;; Recognize garbage generated above.
5753 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5754 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5758 ;; register mem = (which_alternative < 3);
5759 ;; register const char *template;
5761 ;; operands[mem] = XEXP (operands[mem], 0);
5762 ;; switch (which_alternative)
5764 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5765 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5766 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5767 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5768 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5769 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5771 ;; output_asm_insn (template, operands);
5775 (define_expand "movdi"
5776 [(set (match_operand:DI 0 "general_operand" "")
5777 (match_operand:DI 1 "general_operand" ""))]
5780 if (can_create_pseudo_p ())
5782 if (!REG_P (operands[0]))
5783 operands[1] = force_reg (DImode, operands[1]);
5785 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5786 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5788 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5789 when expanding function calls. */
5790 gcc_assert (can_create_pseudo_p ());
5791 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5793 /* Perform load into legal reg pair first, then move. */
5794 rtx reg = gen_reg_rtx (DImode);
5795 emit_insn (gen_movdi (reg, operands[1]));
5798 emit_move_insn (gen_lowpart (SImode, operands[0]),
5799 gen_lowpart (SImode, operands[1]));
5800 emit_move_insn (gen_highpart (SImode, operands[0]),
5801 gen_highpart (SImode, operands[1]));
5804 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5805 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5807 /* Avoid STRD's from an odd-numbered register pair in ARM state
5808 when expanding function prologue. */
5809 gcc_assert (can_create_pseudo_p ());
5810 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5811 ? gen_reg_rtx (DImode)
5813 emit_move_insn (gen_lowpart (SImode, split_dest),
5814 gen_lowpart (SImode, operands[1]));
5815 emit_move_insn (gen_highpart (SImode, split_dest),
5816 gen_highpart (SImode, operands[1]));
5817 if (split_dest != operands[0])
5818 emit_insn (gen_movdi (operands[0], split_dest));
5824 (define_insn "*arm_movdi"
5825 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5826 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5828 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5830 && ( register_operand (operands[0], DImode)
5831 || register_operand (operands[1], DImode))"
5833 switch (which_alternative)
5840 return output_move_double (operands, true, NULL);
5843 [(set_attr "length" "8,12,16,8,8")
5844 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5845 (set_attr "arm_pool_range" "*,*,*,1020,*")
5846 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5847 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5848 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5852 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5853 (match_operand:ANY64 1 "immediate_operand" ""))]
5856 && (arm_const_double_inline_cost (operands[1])
5857 <= arm_max_const_double_inline_cost ())"
5860 arm_split_constant (SET, SImode, curr_insn,
5861 INTVAL (gen_lowpart (SImode, operands[1])),
5862 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5863 arm_split_constant (SET, SImode, curr_insn,
5864 INTVAL (gen_highpart_mode (SImode,
5865 GET_MODE (operands[0]),
5867 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5872 ; If optimizing for size, or if we have load delay slots, then
5873 ; we want to split the constant into two separate operations.
5874 ; In both cases this may split a trivial part into a single data op
5875 ; leaving a single complex constant to load. We can also get longer
5876 ; offsets in a LDR which means we get better chances of sharing the pool
5877 ; entries. Finally, we can normally do a better job of scheduling
5878 ; LDR instructions than we can with LDM.
5879 ; This pattern will only match if the one above did not.
5881 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5882 (match_operand:ANY64 1 "const_double_operand" ""))]
5883 "TARGET_ARM && reload_completed
5884 && arm_const_double_by_parts (operands[1])"
5885 [(set (match_dup 0) (match_dup 1))
5886 (set (match_dup 2) (match_dup 3))]
5888 operands[2] = gen_highpart (SImode, operands[0]);
5889 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5891 operands[0] = gen_lowpart (SImode, operands[0]);
5892 operands[1] = gen_lowpart (SImode, operands[1]);
5897 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5898 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5899 "TARGET_EITHER && reload_completed"
5900 [(set (match_dup 0) (match_dup 1))
5901 (set (match_dup 2) (match_dup 3))]
5903 operands[2] = gen_highpart (SImode, operands[0]);
5904 operands[3] = gen_highpart (SImode, operands[1]);
5905 operands[0] = gen_lowpart (SImode, operands[0]);
5906 operands[1] = gen_lowpart (SImode, operands[1]);
5908 /* Handle a partial overlap. */
5909 if (rtx_equal_p (operands[0], operands[3]))
5911 rtx tmp0 = operands[0];
5912 rtx tmp1 = operands[1];
5914 operands[0] = operands[2];
5915 operands[1] = operands[3];
5922 ;; We can't actually do base+index doubleword loads if the index and
5923 ;; destination overlap. Split here so that we at least have chance to
5926 [(set (match_operand:DI 0 "s_register_operand" "")
5927 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5928 (match_operand:SI 2 "s_register_operand" ""))))]
5930 && reg_overlap_mentioned_p (operands[0], operands[1])
5931 && reg_overlap_mentioned_p (operands[0], operands[2])"
5933 (plus:SI (match_dup 1)
5936 (mem:DI (match_dup 4)))]
5938 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5942 (define_expand "movsi"
5943 [(set (match_operand:SI 0 "general_operand" "")
5944 (match_operand:SI 1 "general_operand" ""))]
5948 rtx base, offset, tmp;
5952 /* Everything except mem = const or mem = mem can be done easily. */
5953 if (MEM_P (operands[0]))
5954 operands[1] = force_reg (SImode, operands[1]);
5955 if (arm_general_register_operand (operands[0], SImode)
5956 && CONST_INT_P (operands[1])
5957 && !(const_ok_for_arm (INTVAL (operands[1]))
5958 || const_ok_for_arm (~INTVAL (operands[1]))))
5960 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5962 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5967 arm_split_constant (SET, SImode, NULL_RTX,
5968 INTVAL (operands[1]), operands[0], NULL_RTX,
5969 optimize && can_create_pseudo_p ());
5974 else /* TARGET_THUMB1... */
5976 if (can_create_pseudo_p ())
5978 if (!REG_P (operands[0]))
5979 operands[1] = force_reg (SImode, operands[1]);
5983 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5985 split_const (operands[1], &base, &offset);
5986 if (GET_CODE (base) == SYMBOL_REF
5987 && !offset_within_block_p (base, INTVAL (offset)))
5989 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5990 emit_move_insn (tmp, base);
5991 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5996 /* Recognize the case where operand[1] is a reference to thread-local
5997 data and load its address to a register. */
5998 if (arm_tls_referenced_p (operands[1]))
6000 rtx tmp = operands[1];
6003 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6005 addend = XEXP (XEXP (tmp, 0), 1);
6006 tmp = XEXP (XEXP (tmp, 0), 0);
6009 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6010 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6012 tmp = legitimize_tls_address (tmp,
6013 !can_create_pseudo_p () ? operands[0] : 0);
6016 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6017 tmp = force_operand (tmp, operands[0]);
6022 && (CONSTANT_P (operands[1])
6023 || symbol_mentioned_p (operands[1])
6024 || label_mentioned_p (operands[1])))
6025 operands[1] = legitimize_pic_address (operands[1], SImode,
6026 (!can_create_pseudo_p ()
6033 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6034 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6035 ;; so this does not matter.
6036 (define_insn "*arm_movt"
6037 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6038 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6039 (match_operand:SI 2 "general_operand" "i,i")))]
6040 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6042 movt%?\t%0, #:upper16:%c2
6043 movt\t%0, #:upper16:%c2"
6044 [(set_attr "arch" "32,v8mb")
6045 (set_attr "predicable" "yes")
6046 (set_attr "predicable_short_it" "no")
6047 (set_attr "length" "4")
6048 (set_attr "type" "alu_sreg")]
6051 (define_insn "*arm_movsi_insn"
6052 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6053 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6054 "TARGET_ARM && ! TARGET_IWMMXT
6055 && !(TARGET_HARD_FLOAT && TARGET_VFP)
6056 && ( register_operand (operands[0], SImode)
6057 || register_operand (operands[1], SImode))"
6065 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6066 (set_attr "predicable" "yes")
6067 (set_attr "pool_range" "*,*,*,*,4096,*")
6068 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6072 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6073 (match_operand:SI 1 "const_int_operand" ""))]
6075 && (!(const_ok_for_arm (INTVAL (operands[1]))
6076 || const_ok_for_arm (~INTVAL (operands[1]))))"
6077 [(clobber (const_int 0))]
6079 arm_split_constant (SET, SImode, NULL_RTX,
6080 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6085 ;; A normal way to do (symbol + offset) requires three instructions at least
6086 ;; (depends on how big the offset is) as below:
6087 ;; movw r0, #:lower16:g
6088 ;; movw r0, #:upper16:g
6091 ;; A better way would be:
6092 ;; movw r0, #:lower16:g+4
6093 ;; movw r0, #:upper16:g+4
6095 ;; The limitation of this way is that the length of offset should be a 16-bit
6096 ;; signed value, because current assembler only supports REL type relocation for
6097 ;; such case. If the more powerful RELA type is supported in future, we should
6098 ;; update this pattern to go with better way.
6100 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6101 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6102 (match_operand:SI 2 "const_int_operand" ""))))]
6105 && arm_disable_literal_pool
6107 && GET_CODE (operands[1]) == SYMBOL_REF"
6108 [(clobber (const_int 0))]
6110 int offset = INTVAL (operands[2]);
6112 if (offset < -0x8000 || offset > 0x7fff)
6114 arm_emit_movpair (operands[0], operands[1]);
6115 emit_insn (gen_rtx_SET (operands[0],
6116 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6120 rtx op = gen_rtx_CONST (SImode,
6121 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6122 arm_emit_movpair (operands[0], op);
6127 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6128 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6129 ;; and lo_sum would be merged back into memory load at cprop. However,
6130 ;; if the default is to prefer movt/movw rather than a load from the constant
6131 ;; pool, the performance is better.
6133 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6134 (match_operand:SI 1 "general_operand" ""))]
6135 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6136 && !flag_pic && !target_word_relocations
6137 && !arm_tls_referenced_p (operands[1])"
6138 [(clobber (const_int 0))]
6140 arm_emit_movpair (operands[0], operands[1]);
6144 ;; When generating pic, we need to load the symbol offset into a register.
6145 ;; So that the optimizer does not confuse this with a normal symbol load
6146 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6147 ;; since that is the only type of relocation we can use.
6149 ;; Wrap calculation of the whole PIC address in a single pattern for the
6150 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6151 ;; a PIC address involves two loads from memory, so we want to CSE it
6152 ;; as often as possible.
6153 ;; This pattern will be split into one of the pic_load_addr_* patterns
6154 ;; and a move after GCSE optimizations.
6156 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6157 (define_expand "calculate_pic_address"
6158 [(set (match_operand:SI 0 "register_operand" "")
6159 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6160 (unspec:SI [(match_operand:SI 2 "" "")]
6165 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6167 [(set (match_operand:SI 0 "register_operand" "")
6168 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6169 (unspec:SI [(match_operand:SI 2 "" "")]
6172 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6173 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6174 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6177 ;; operand1 is the memory address to go into
6178 ;; pic_load_addr_32bit.
6179 ;; operand2 is the PIC label to be emitted
6180 ;; from pic_add_dot_plus_eight.
6181 ;; We do this to allow hoisting of the entire insn.
6182 (define_insn_and_split "pic_load_addr_unified"
6183 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6184 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6185 (match_operand:SI 2 "" "")]
6186 UNSPEC_PIC_UNIFIED))]
6189 "&& reload_completed"
6190 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6191 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6192 (match_dup 2)] UNSPEC_PIC_BASE))]
6193 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6194 [(set_attr "type" "load1,load1,load1")
6195 (set_attr "pool_range" "4096,4094,1022")
6196 (set_attr "neg_pool_range" "4084,0,0")
6197 (set_attr "arch" "a,t2,t1")
6198 (set_attr "length" "8,6,4")]
6201 ;; The rather odd constraints on the following are to force reload to leave
6202 ;; the insn alone, and to force the minipool generation pass to then move
6203 ;; the GOT symbol to memory.
6205 (define_insn "pic_load_addr_32bit"
6206 [(set (match_operand:SI 0 "s_register_operand" "=r")
6207 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6208 "TARGET_32BIT && flag_pic"
6210 [(set_attr "type" "load1")
6211 (set (attr "pool_range")
6212 (if_then_else (eq_attr "is_thumb" "no")
6215 (set (attr "neg_pool_range")
6216 (if_then_else (eq_attr "is_thumb" "no")
6221 (define_insn "pic_load_addr_thumb1"
6222 [(set (match_operand:SI 0 "s_register_operand" "=l")
6223 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6224 "TARGET_THUMB1 && flag_pic"
6226 [(set_attr "type" "load1")
6227 (set (attr "pool_range") (const_int 1018))]
6230 (define_insn "pic_add_dot_plus_four"
6231 [(set (match_operand:SI 0 "register_operand" "=r")
6232 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6234 (match_operand 2 "" "")]
6238 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6239 INTVAL (operands[2]));
6240 return \"add\\t%0, %|pc\";
6242 [(set_attr "length" "2")
6243 (set_attr "type" "alu_sreg")]
6246 (define_insn "pic_add_dot_plus_eight"
6247 [(set (match_operand:SI 0 "register_operand" "=r")
6248 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6250 (match_operand 2 "" "")]
6254 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6255 INTVAL (operands[2]));
6256 return \"add%?\\t%0, %|pc, %1\";
6258 [(set_attr "predicable" "yes")
6259 (set_attr "type" "alu_sreg")]
6262 (define_insn "tls_load_dot_plus_eight"
6263 [(set (match_operand:SI 0 "register_operand" "=r")
6264 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6266 (match_operand 2 "" "")]
6270 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6271 INTVAL (operands[2]));
6272 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6274 [(set_attr "predicable" "yes")
6275 (set_attr "type" "load1")]
6278 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6279 ;; followed by a load. These sequences can be crunched down to
6280 ;; tls_load_dot_plus_eight by a peephole.
6283 [(set (match_operand:SI 0 "register_operand" "")
6284 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6286 (match_operand 1 "" "")]
6288 (set (match_operand:SI 2 "arm_general_register_operand" "")
6289 (mem:SI (match_dup 0)))]
6290 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6292 (mem:SI (unspec:SI [(match_dup 3)
6299 (define_insn "pic_offset_arm"
6300 [(set (match_operand:SI 0 "register_operand" "=r")
6301 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6302 (unspec:SI [(match_operand:SI 2 "" "X")]
6303 UNSPEC_PIC_OFFSET))))]
6304 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6305 "ldr%?\\t%0, [%1,%2]"
6306 [(set_attr "type" "load1")]
6309 (define_expand "builtin_setjmp_receiver"
6310 [(label_ref (match_operand 0 "" ""))]
6314 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6316 if (arm_pic_register != INVALID_REGNUM)
6317 arm_load_pic_register (1UL << 3);
6321 ;; If copying one reg to another we can set the condition codes according to
6322 ;; its value. Such a move is common after a return from subroutine and the
6323 ;; result is being tested against zero.
6325 (define_insn "*movsi_compare0"
6326 [(set (reg:CC CC_REGNUM)
6327 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6329 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6334 subs%?\\t%0, %1, #0"
6335 [(set_attr "conds" "set")
6336 (set_attr "type" "alus_imm,alus_imm")]
6339 ;; Subroutine to store a half word from a register into memory.
6340 ;; Operand 0 is the source register (HImode)
6341 ;; Operand 1 is the destination address in a register (SImode)
6343 ;; In both this routine and the next, we must be careful not to spill
6344 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6345 ;; can generate unrecognizable rtl.
6347 (define_expand "storehi"
6348 [;; store the low byte
6349 (set (match_operand 1 "" "") (match_dup 3))
6350 ;; extract the high byte
6352 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6353 ;; store the high byte
6354 (set (match_dup 4) (match_dup 5))]
6358 rtx op1 = operands[1];
6359 rtx addr = XEXP (op1, 0);
6360 enum rtx_code code = GET_CODE (addr);
6362 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6364 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6366 operands[4] = adjust_address (op1, QImode, 1);
6367 operands[1] = adjust_address (operands[1], QImode, 0);
6368 operands[3] = gen_lowpart (QImode, operands[0]);
6369 operands[0] = gen_lowpart (SImode, operands[0]);
6370 operands[2] = gen_reg_rtx (SImode);
6371 operands[5] = gen_lowpart (QImode, operands[2]);
6375 (define_expand "storehi_bigend"
6376 [(set (match_dup 4) (match_dup 3))
6378 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6379 (set (match_operand 1 "" "") (match_dup 5))]
6383 rtx op1 = operands[1];
6384 rtx addr = XEXP (op1, 0);
6385 enum rtx_code code = GET_CODE (addr);
6387 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6389 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6391 operands[4] = adjust_address (op1, QImode, 1);
6392 operands[1] = adjust_address (operands[1], QImode, 0);
6393 operands[3] = gen_lowpart (QImode, operands[0]);
6394 operands[0] = gen_lowpart (SImode, operands[0]);
6395 operands[2] = gen_reg_rtx (SImode);
6396 operands[5] = gen_lowpart (QImode, operands[2]);
6400 ;; Subroutine to store a half word integer constant into memory.
6401 (define_expand "storeinthi"
6402 [(set (match_operand 0 "" "")
6403 (match_operand 1 "" ""))
6404 (set (match_dup 3) (match_dup 2))]
6408 HOST_WIDE_INT value = INTVAL (operands[1]);
6409 rtx addr = XEXP (operands[0], 0);
6410 rtx op0 = operands[0];
6411 enum rtx_code code = GET_CODE (addr);
6413 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6415 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6417 operands[1] = gen_reg_rtx (SImode);
6418 if (BYTES_BIG_ENDIAN)
6420 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6421 if ((value & 255) == ((value >> 8) & 255))
6422 operands[2] = operands[1];
6425 operands[2] = gen_reg_rtx (SImode);
6426 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6431 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6432 if ((value & 255) == ((value >> 8) & 255))
6433 operands[2] = operands[1];
6436 operands[2] = gen_reg_rtx (SImode);
6437 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6441 operands[3] = adjust_address (op0, QImode, 1);
6442 operands[0] = adjust_address (operands[0], QImode, 0);
6443 operands[2] = gen_lowpart (QImode, operands[2]);
6444 operands[1] = gen_lowpart (QImode, operands[1]);
6448 (define_expand "storehi_single_op"
6449 [(set (match_operand:HI 0 "memory_operand" "")
6450 (match_operand:HI 1 "general_operand" ""))]
6451 "TARGET_32BIT && arm_arch4"
6453 if (!s_register_operand (operands[1], HImode))
6454 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6458 (define_expand "movhi"
6459 [(set (match_operand:HI 0 "general_operand" "")
6460 (match_operand:HI 1 "general_operand" ""))]
6465 if (can_create_pseudo_p ())
6467 if (MEM_P (operands[0]))
6471 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6474 if (CONST_INT_P (operands[1]))
6475 emit_insn (gen_storeinthi (operands[0], operands[1]));
6478 if (MEM_P (operands[1]))
6479 operands[1] = force_reg (HImode, operands[1]);
6480 if (BYTES_BIG_ENDIAN)
6481 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6483 emit_insn (gen_storehi (operands[1], operands[0]));
6487 /* Sign extend a constant, and keep it in an SImode reg. */
6488 else if (CONST_INT_P (operands[1]))
6490 rtx reg = gen_reg_rtx (SImode);
6491 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6493 /* If the constant is already valid, leave it alone. */
6494 if (!const_ok_for_arm (val))
6496 /* If setting all the top bits will make the constant
6497 loadable in a single instruction, then set them.
6498 Otherwise, sign extend the number. */
6500 if (const_ok_for_arm (~(val | ~0xffff)))
6502 else if (val & 0x8000)
6506 emit_insn (gen_movsi (reg, GEN_INT (val)));
6507 operands[1] = gen_lowpart (HImode, reg);
6509 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6510 && MEM_P (operands[1]))
6512 rtx reg = gen_reg_rtx (SImode);
6514 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6515 operands[1] = gen_lowpart (HImode, reg);
6517 else if (!arm_arch4)
6519 if (MEM_P (operands[1]))
6522 rtx offset = const0_rtx;
6523 rtx reg = gen_reg_rtx (SImode);
6525 if ((REG_P (base = XEXP (operands[1], 0))
6526 || (GET_CODE (base) == PLUS
6527 && (CONST_INT_P (offset = XEXP (base, 1)))
6528 && ((INTVAL(offset) & 1) != 1)
6529 && REG_P (base = XEXP (base, 0))))
6530 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6534 new_rtx = widen_memory_access (operands[1], SImode,
6535 ((INTVAL (offset) & ~3)
6536 - INTVAL (offset)));
6537 emit_insn (gen_movsi (reg, new_rtx));
6538 if (((INTVAL (offset) & 2) != 0)
6539 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6541 rtx reg2 = gen_reg_rtx (SImode);
6543 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6548 emit_insn (gen_movhi_bytes (reg, operands[1]));
6550 operands[1] = gen_lowpart (HImode, reg);
6554 /* Handle loading a large integer during reload. */
6555 else if (CONST_INT_P (operands[1])
6556 && !const_ok_for_arm (INTVAL (operands[1]))
6557 && !const_ok_for_arm (~INTVAL (operands[1])))
6559 /* Writing a constant to memory needs a scratch, which should
6560 be handled with SECONDARY_RELOADs. */
6561 gcc_assert (REG_P (operands[0]));
6563 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6564 emit_insn (gen_movsi (operands[0], operands[1]));
6568 else if (TARGET_THUMB2)
6570 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6571 if (can_create_pseudo_p ())
6573 if (!REG_P (operands[0]))
6574 operands[1] = force_reg (HImode, operands[1]);
6575 /* Zero extend a constant, and keep it in an SImode reg. */
6576 else if (CONST_INT_P (operands[1]))
6578 rtx reg = gen_reg_rtx (SImode);
6579 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6581 emit_insn (gen_movsi (reg, GEN_INT (val)));
6582 operands[1] = gen_lowpart (HImode, reg);
6586 else /* TARGET_THUMB1 */
6588 if (can_create_pseudo_p ())
6590 if (CONST_INT_P (operands[1]))
6592 rtx reg = gen_reg_rtx (SImode);
6594 emit_insn (gen_movsi (reg, operands[1]));
6595 operands[1] = gen_lowpart (HImode, reg);
6598 /* ??? We shouldn't really get invalid addresses here, but this can
6599 happen if we are passed a SP (never OK for HImode/QImode) or
6600 virtual register (also rejected as illegitimate for HImode/QImode)
6601 relative address. */
6602 /* ??? This should perhaps be fixed elsewhere, for instance, in
6603 fixup_stack_1, by checking for other kinds of invalid addresses,
6604 e.g. a bare reference to a virtual register. This may confuse the
6605 alpha though, which must handle this case differently. */
6606 if (MEM_P (operands[0])
6607 && !memory_address_p (GET_MODE (operands[0]),
6608 XEXP (operands[0], 0)))
6610 = replace_equiv_address (operands[0],
6611 copy_to_reg (XEXP (operands[0], 0)));
6613 if (MEM_P (operands[1])
6614 && !memory_address_p (GET_MODE (operands[1]),
6615 XEXP (operands[1], 0)))
6617 = replace_equiv_address (operands[1],
6618 copy_to_reg (XEXP (operands[1], 0)));
6620 if (MEM_P (operands[1]) && optimize > 0)
6622 rtx reg = gen_reg_rtx (SImode);
6624 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6625 operands[1] = gen_lowpart (HImode, reg);
6628 if (MEM_P (operands[0]))
6629 operands[1] = force_reg (HImode, operands[1]);
6631 else if (CONST_INT_P (operands[1])
6632 && !satisfies_constraint_I (operands[1]))
6634 /* Handle loading a large integer during reload. */
6636 /* Writing a constant to memory needs a scratch, which should
6637 be handled with SECONDARY_RELOADs. */
6638 gcc_assert (REG_P (operands[0]));
6640 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6641 emit_insn (gen_movsi (operands[0], operands[1]));
6648 (define_expand "movhi_bytes"
6649 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6651 (zero_extend:SI (match_dup 6)))
6652 (set (match_operand:SI 0 "" "")
6653 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6658 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6660 mem1 = change_address (operands[1], QImode, addr);
6661 mem2 = change_address (operands[1], QImode,
6662 plus_constant (Pmode, addr, 1));
6663 operands[0] = gen_lowpart (SImode, operands[0]);
6665 operands[2] = gen_reg_rtx (SImode);
6666 operands[3] = gen_reg_rtx (SImode);
6669 if (BYTES_BIG_ENDIAN)
6671 operands[4] = operands[2];
6672 operands[5] = operands[3];
6676 operands[4] = operands[3];
6677 operands[5] = operands[2];
6682 (define_expand "movhi_bigend"
6684 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6687 (ashiftrt:SI (match_dup 2) (const_int 16)))
6688 (set (match_operand:HI 0 "s_register_operand" "")
6692 operands[2] = gen_reg_rtx (SImode);
6693 operands[3] = gen_reg_rtx (SImode);
6694 operands[4] = gen_lowpart (HImode, operands[3]);
6698 ;; Pattern to recognize insn generated default case above
6699 (define_insn "*movhi_insn_arch4"
6700 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6701 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6704 && (register_operand (operands[0], HImode)
6705 || register_operand (operands[1], HImode))"
6707 mov%?\\t%0, %1\\t%@ movhi
6708 mvn%?\\t%0, #%B1\\t%@ movhi
6709 movw%?\\t%0, %L1\\t%@ movhi
6710 strh%?\\t%1, %0\\t%@ movhi
6711 ldrh%?\\t%0, %1\\t%@ movhi"
6712 [(set_attr "predicable" "yes")
6713 (set_attr "pool_range" "*,*,*,*,256")
6714 (set_attr "neg_pool_range" "*,*,*,*,244")
6715 (set_attr "arch" "*,*,v6t2,*,*")
6716 (set_attr_alternative "type"
6717 [(if_then_else (match_operand 1 "const_int_operand" "")
6718 (const_string "mov_imm" )
6719 (const_string "mov_reg"))
6720 (const_string "mvn_imm")
6721 (const_string "mov_imm")
6722 (const_string "store1")
6723 (const_string "load1")])]
6726 (define_insn "*movhi_bytes"
6727 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6728 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6731 mov%?\\t%0, %1\\t%@ movhi
6732 mov%?\\t%0, %1\\t%@ movhi
6733 mvn%?\\t%0, #%B1\\t%@ movhi"
6734 [(set_attr "predicable" "yes")
6735 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6738 ;; We use a DImode scratch because we may occasionally need an additional
6739 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6740 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6741 (define_expand "reload_outhi"
6742 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6743 (match_operand:HI 1 "s_register_operand" "r")
6744 (match_operand:DI 2 "s_register_operand" "=&l")])]
6747 arm_reload_out_hi (operands);
6749 thumb_reload_out_hi (operands);
6754 (define_expand "reload_inhi"
6755 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6756 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6757 (match_operand:DI 2 "s_register_operand" "=&r")])]
6761 arm_reload_in_hi (operands);
6763 thumb_reload_out_hi (operands);
6767 (define_expand "movqi"
6768 [(set (match_operand:QI 0 "general_operand" "")
6769 (match_operand:QI 1 "general_operand" ""))]
6772 /* Everything except mem = const or mem = mem can be done easily */
6774 if (can_create_pseudo_p ())
6776 if (CONST_INT_P (operands[1]))
6778 rtx reg = gen_reg_rtx (SImode);
6780 /* For thumb we want an unsigned immediate, then we are more likely
6781 to be able to use a movs insn. */
6783 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6785 emit_insn (gen_movsi (reg, operands[1]));
6786 operands[1] = gen_lowpart (QImode, reg);
6791 /* ??? We shouldn't really get invalid addresses here, but this can
6792 happen if we are passed a SP (never OK for HImode/QImode) or
6793 virtual register (also rejected as illegitimate for HImode/QImode)
6794 relative address. */
6795 /* ??? This should perhaps be fixed elsewhere, for instance, in
6796 fixup_stack_1, by checking for other kinds of invalid addresses,
6797 e.g. a bare reference to a virtual register. This may confuse the
6798 alpha though, which must handle this case differently. */
6799 if (MEM_P (operands[0])
6800 && !memory_address_p (GET_MODE (operands[0]),
6801 XEXP (operands[0], 0)))
6803 = replace_equiv_address (operands[0],
6804 copy_to_reg (XEXP (operands[0], 0)));
6805 if (MEM_P (operands[1])
6806 && !memory_address_p (GET_MODE (operands[1]),
6807 XEXP (operands[1], 0)))
6809 = replace_equiv_address (operands[1],
6810 copy_to_reg (XEXP (operands[1], 0)));
6813 if (MEM_P (operands[1]) && optimize > 0)
6815 rtx reg = gen_reg_rtx (SImode);
6817 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6818 operands[1] = gen_lowpart (QImode, reg);
6821 if (MEM_P (operands[0]))
6822 operands[1] = force_reg (QImode, operands[1]);
6824 else if (TARGET_THUMB
6825 && CONST_INT_P (operands[1])
6826 && !satisfies_constraint_I (operands[1]))
6828 /* Handle loading a large integer during reload. */
6830 /* Writing a constant to memory needs a scratch, which should
6831 be handled with SECONDARY_RELOADs. */
6832 gcc_assert (REG_P (operands[0]));
6834 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6835 emit_insn (gen_movsi (operands[0], operands[1]));
6841 (define_insn "*arm_movqi_insn"
6842 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6843 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6845 && ( register_operand (operands[0], QImode)
6846 || register_operand (operands[1], QImode))"
6857 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6858 (set_attr "predicable" "yes")
6859 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6860 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6861 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6865 (define_expand "movhf"
6866 [(set (match_operand:HF 0 "general_operand" "")
6867 (match_operand:HF 1 "general_operand" ""))]
6872 if (MEM_P (operands[0]))
6873 operands[1] = force_reg (HFmode, operands[1]);
6875 else /* TARGET_THUMB1 */
6877 if (can_create_pseudo_p ())
6879 if (!REG_P (operands[0]))
6880 operands[1] = force_reg (HFmode, operands[1]);
6886 (define_insn "*arm32_movhf"
6887 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6888 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6889 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_VFP)
6890 && ( s_register_operand (operands[0], HFmode)
6891 || s_register_operand (operands[1], HFmode))"
6893 switch (which_alternative)
6895 case 0: /* ARM register from memory */
6896 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6897 case 1: /* memory from ARM register */
6898 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6899 case 2: /* ARM register from ARM register */
6900 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6901 case 3: /* ARM register from constant */
6906 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6908 ops[0] = operands[0];
6909 ops[1] = GEN_INT (bits);
6910 ops[2] = GEN_INT (bits & 0xff00);
6911 ops[3] = GEN_INT (bits & 0x00ff);
6913 if (arm_arch_thumb2)
6914 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6916 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6923 [(set_attr "conds" "unconditional")
6924 (set_attr "type" "load1,store1,mov_reg,multiple")
6925 (set_attr "length" "4,4,4,8")
6926 (set_attr "predicable" "yes")
6927 (set_attr "predicable_short_it" "no")]
6930 (define_expand "movsf"
6931 [(set (match_operand:SF 0 "general_operand" "")
6932 (match_operand:SF 1 "general_operand" ""))]
6937 if (MEM_P (operands[0]))
6938 operands[1] = force_reg (SFmode, operands[1]);
6940 else /* TARGET_THUMB1 */
6942 if (can_create_pseudo_p ())
6944 if (!REG_P (operands[0]))
6945 operands[1] = force_reg (SFmode, operands[1]);
6951 ;; Transform a floating-point move of a constant into a core register into
6952 ;; an SImode operation.
6954 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6955 (match_operand:SF 1 "immediate_operand" ""))]
6958 && CONST_DOUBLE_P (operands[1])"
6959 [(set (match_dup 2) (match_dup 3))]
6961 operands[2] = gen_lowpart (SImode, operands[0]);
6962 operands[3] = gen_lowpart (SImode, operands[1]);
6963 if (operands[2] == 0 || operands[3] == 0)
6968 (define_insn "*arm_movsf_soft_insn"
6969 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6970 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6972 && TARGET_SOFT_FLOAT
6973 && (!MEM_P (operands[0])
6974 || register_operand (operands[1], SFmode))"
6977 ldr%?\\t%0, %1\\t%@ float
6978 str%?\\t%1, %0\\t%@ float"
6979 [(set_attr "predicable" "yes")
6980 (set_attr "predicable_short_it" "no")
6981 (set_attr "type" "mov_reg,load1,store1")
6982 (set_attr "arm_pool_range" "*,4096,*")
6983 (set_attr "thumb2_pool_range" "*,4094,*")
6984 (set_attr "arm_neg_pool_range" "*,4084,*")
6985 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6988 (define_expand "movdf"
6989 [(set (match_operand:DF 0 "general_operand" "")
6990 (match_operand:DF 1 "general_operand" ""))]
6995 if (MEM_P (operands[0]))
6996 operands[1] = force_reg (DFmode, operands[1]);
6998 else /* TARGET_THUMB */
7000 if (can_create_pseudo_p ())
7002 if (!REG_P (operands[0]))
7003 operands[1] = force_reg (DFmode, operands[1]);
7009 ;; Reloading a df mode value stored in integer regs to memory can require a
7011 (define_expand "reload_outdf"
7012 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7013 (match_operand:DF 1 "s_register_operand" "r")
7014 (match_operand:SI 2 "s_register_operand" "=&r")]
7018 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7021 operands[2] = XEXP (operands[0], 0);
7022 else if (code == POST_INC || code == PRE_DEC)
7024 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7025 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7026 emit_insn (gen_movdi (operands[0], operands[1]));
7029 else if (code == PRE_INC)
7031 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7033 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7036 else if (code == POST_DEC)
7037 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7039 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7040 XEXP (XEXP (operands[0], 0), 1)));
7042 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7045 if (code == POST_DEC)
7046 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7052 (define_insn "*movdf_soft_insn"
7053 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7054 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7055 "TARGET_32BIT && TARGET_SOFT_FLOAT
7056 && ( register_operand (operands[0], DFmode)
7057 || register_operand (operands[1], DFmode))"
7059 switch (which_alternative)
7066 return output_move_double (operands, true, NULL);
7069 [(set_attr "length" "8,12,16,8,8")
7070 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7071 (set_attr "arm_pool_range" "*,*,*,1020,*")
7072 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7073 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7074 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7078 ;; load- and store-multiple insns
7079 ;; The arm can load/store any set of registers, provided that they are in
7080 ;; ascending order, but these expanders assume a contiguous set.
7082 (define_expand "load_multiple"
7083 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7084 (match_operand:SI 1 "" ""))
7085 (use (match_operand:SI 2 "" ""))])]
7088 HOST_WIDE_INT offset = 0;
7090 /* Support only fixed point registers. */
7091 if (!CONST_INT_P (operands[2])
7092 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7093 || INTVAL (operands[2]) < 2
7094 || !MEM_P (operands[1])
7095 || !REG_P (operands[0])
7096 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7097 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7101 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7102 INTVAL (operands[2]),
7103 force_reg (SImode, XEXP (operands[1], 0)),
7104 FALSE, operands[1], &offset);
7107 (define_expand "store_multiple"
7108 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7109 (match_operand:SI 1 "" ""))
7110 (use (match_operand:SI 2 "" ""))])]
7113 HOST_WIDE_INT offset = 0;
7115 /* Support only fixed point registers. */
7116 if (!CONST_INT_P (operands[2])
7117 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7118 || INTVAL (operands[2]) < 2
7119 || !REG_P (operands[1])
7120 || !MEM_P (operands[0])
7121 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7122 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7126 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7127 INTVAL (operands[2]),
7128 force_reg (SImode, XEXP (operands[0], 0)),
7129 FALSE, operands[0], &offset);
7133 (define_expand "setmemsi"
7134 [(match_operand:BLK 0 "general_operand" "")
7135 (match_operand:SI 1 "const_int_operand" "")
7136 (match_operand:SI 2 "const_int_operand" "")
7137 (match_operand:SI 3 "const_int_operand" "")]
7140 if (arm_gen_setmem (operands))
7147 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7148 ;; We could let this apply for blocks of less than this, but it clobbers so
7149 ;; many registers that there is then probably a better way.
7151 (define_expand "movmemqi"
7152 [(match_operand:BLK 0 "general_operand" "")
7153 (match_operand:BLK 1 "general_operand" "")
7154 (match_operand:SI 2 "const_int_operand" "")
7155 (match_operand:SI 3 "const_int_operand" "")]
7160 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7161 && !optimize_function_for_size_p (cfun))
7163 if (gen_movmem_ldrd_strd (operands))
7168 if (arm_gen_movmemqi (operands))
7172 else /* TARGET_THUMB1 */
7174 if ( INTVAL (operands[3]) != 4
7175 || INTVAL (operands[2]) > 48)
7178 thumb_expand_movmemqi (operands);
7185 ;; Compare & branch insns
7186 ;; The range calculations are based as follows:
7187 ;; For forward branches, the address calculation returns the address of
7188 ;; the next instruction. This is 2 beyond the branch instruction.
7189 ;; For backward branches, the address calculation returns the address of
7190 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7191 ;; instruction for the shortest sequence, and 4 before the branch instruction
7192 ;; if we have to jump around an unconditional branch.
7193 ;; To the basic branch range the PC offset must be added (this is +4).
7194 ;; So for forward branches we have
7195 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7196 ;; And for backward branches we have
7197 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7199 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7200 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7202 (define_expand "cbranchsi4"
7203 [(set (pc) (if_then_else
7204 (match_operator 0 "expandable_comparison_operator"
7205 [(match_operand:SI 1 "s_register_operand" "")
7206 (match_operand:SI 2 "nonmemory_operand" "")])
7207 (label_ref (match_operand 3 "" ""))
7213 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7215 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7219 if (thumb1_cmpneg_operand (operands[2], SImode))
7221 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7222 operands[3], operands[0]));
7225 if (!thumb1_cmp_operand (operands[2], SImode))
7226 operands[2] = force_reg (SImode, operands[2]);
7229 (define_expand "cbranchsf4"
7230 [(set (pc) (if_then_else
7231 (match_operator 0 "expandable_comparison_operator"
7232 [(match_operand:SF 1 "s_register_operand" "")
7233 (match_operand:SF 2 "arm_float_compare_operand" "")])
7234 (label_ref (match_operand 3 "" ""))
7236 "TARGET_32BIT && TARGET_HARD_FLOAT"
7237 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7238 operands[3])); DONE;"
7241 (define_expand "cbranchdf4"
7242 [(set (pc) (if_then_else
7243 (match_operator 0 "expandable_comparison_operator"
7244 [(match_operand:DF 1 "s_register_operand" "")
7245 (match_operand:DF 2 "arm_float_compare_operand" "")])
7246 (label_ref (match_operand 3 "" ""))
7248 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7249 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7250 operands[3])); DONE;"
7253 (define_expand "cbranchdi4"
7254 [(set (pc) (if_then_else
7255 (match_operator 0 "expandable_comparison_operator"
7256 [(match_operand:DI 1 "s_register_operand" "")
7257 (match_operand:DI 2 "cmpdi_operand" "")])
7258 (label_ref (match_operand 3 "" ""))
7262 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7264 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7270 ;; Comparison and test insns
7272 (define_insn "*arm_cmpsi_insn"
7273 [(set (reg:CC CC_REGNUM)
7274 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7275 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7283 [(set_attr "conds" "set")
7284 (set_attr "arch" "t2,t2,any,any,any")
7285 (set_attr "length" "2,2,4,4,4")
7286 (set_attr "predicable" "yes")
7287 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7288 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7291 (define_insn "*cmpsi_shiftsi"
7292 [(set (reg:CC CC_REGNUM)
7293 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7294 (match_operator:SI 3 "shift_operator"
7295 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7296 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7299 [(set_attr "conds" "set")
7300 (set_attr "shift" "1")
7301 (set_attr "arch" "32,a,a")
7302 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7304 (define_insn "*cmpsi_shiftsi_swp"
7305 [(set (reg:CC_SWP CC_REGNUM)
7306 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7307 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7308 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7309 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7312 [(set_attr "conds" "set")
7313 (set_attr "shift" "1")
7314 (set_attr "arch" "32,a,a")
7315 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7317 (define_insn "*arm_cmpsi_negshiftsi_si"
7318 [(set (reg:CC_Z CC_REGNUM)
7320 (neg:SI (match_operator:SI 1 "shift_operator"
7321 [(match_operand:SI 2 "s_register_operand" "r")
7322 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7323 (match_operand:SI 0 "s_register_operand" "r")))]
7326 [(set_attr "conds" "set")
7327 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7328 (const_string "alus_shift_imm")
7329 (const_string "alus_shift_reg")))
7330 (set_attr "predicable" "yes")]
7333 ;; DImode comparisons. The generic code generates branches that
7334 ;; if-conversion can not reduce to a conditional compare, so we do
7337 (define_insn_and_split "*arm_cmpdi_insn"
7338 [(set (reg:CC_NCV CC_REGNUM)
7339 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7340 (match_operand:DI 1 "arm_di_operand" "rDi")))
7341 (clobber (match_scratch:SI 2 "=r"))]
7343 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7344 "&& reload_completed"
7345 [(set (reg:CC CC_REGNUM)
7346 (compare:CC (match_dup 0) (match_dup 1)))
7347 (parallel [(set (reg:CC CC_REGNUM)
7348 (compare:CC (match_dup 3) (match_dup 4)))
7350 (minus:SI (match_dup 5)
7351 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7353 operands[3] = gen_highpart (SImode, operands[0]);
7354 operands[0] = gen_lowpart (SImode, operands[0]);
7355 if (CONST_INT_P (operands[1]))
7357 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7360 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7364 operands[4] = gen_highpart (SImode, operands[1]);
7365 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7367 operands[1] = gen_lowpart (SImode, operands[1]);
7368 operands[2] = gen_lowpart (SImode, operands[2]);
7370 [(set_attr "conds" "set")
7371 (set_attr "length" "8")
7372 (set_attr "type" "multiple")]
7375 (define_insn_and_split "*arm_cmpdi_unsigned"
7376 [(set (reg:CC_CZ CC_REGNUM)
7377 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7378 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7381 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7382 "&& reload_completed"
7383 [(set (reg:CC CC_REGNUM)
7384 (compare:CC (match_dup 2) (match_dup 3)))
7385 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7386 (set (reg:CC CC_REGNUM)
7387 (compare:CC (match_dup 0) (match_dup 1))))]
7389 operands[2] = gen_highpart (SImode, operands[0]);
7390 operands[0] = gen_lowpart (SImode, operands[0]);
7391 if (CONST_INT_P (operands[1]))
7392 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7394 operands[3] = gen_highpart (SImode, operands[1]);
7395 operands[1] = gen_lowpart (SImode, operands[1]);
7397 [(set_attr "conds" "set")
7398 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7399 (set_attr "arch" "t2,t2,t2,a")
7400 (set_attr "length" "6,6,10,8")
7401 (set_attr "type" "multiple")]
7404 (define_insn "*arm_cmpdi_zero"
7405 [(set (reg:CC_Z CC_REGNUM)
7406 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7408 (clobber (match_scratch:SI 1 "=r"))]
7410 "orrs%?\\t%1, %Q0, %R0"
7411 [(set_attr "conds" "set")
7412 (set_attr "type" "logics_reg")]
7415 ; This insn allows redundant compares to be removed by cse, nothing should
7416 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7417 ; is deleted later on. The match_dup will match the mode here, so that
7418 ; mode changes of the condition codes aren't lost by this even though we don't
7419 ; specify what they are.
7421 (define_insn "*deleted_compare"
7422 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7424 "\\t%@ deleted compare"
7425 [(set_attr "conds" "set")
7426 (set_attr "length" "0")
7427 (set_attr "type" "no_insn")]
7431 ;; Conditional branch insns
7433 (define_expand "cbranch_cc"
7435 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7436 (match_operand 2 "" "")])
7437 (label_ref (match_operand 3 "" ""))
7440 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7441 operands[1], operands[2], NULL_RTX);
7442 operands[2] = const0_rtx;"
7446 ;; Patterns to match conditional branch insns.
7449 (define_insn "arm_cond_branch"
7451 (if_then_else (match_operator 1 "arm_comparison_operator"
7452 [(match_operand 2 "cc_register" "") (const_int 0)])
7453 (label_ref (match_operand 0 "" ""))
7457 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7459 arm_ccfsm_state += 2;
7462 return \"b%d1\\t%l0\";
7464 [(set_attr "conds" "use")
7465 (set_attr "type" "branch")
7466 (set (attr "length")
7468 (and (match_test "TARGET_THUMB2")
7469 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7470 (le (minus (match_dup 0) (pc)) (const_int 256))))
7475 (define_insn "*arm_cond_branch_reversed"
7477 (if_then_else (match_operator 1 "arm_comparison_operator"
7478 [(match_operand 2 "cc_register" "") (const_int 0)])
7480 (label_ref (match_operand 0 "" ""))))]
7483 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7485 arm_ccfsm_state += 2;
7488 return \"b%D1\\t%l0\";
7490 [(set_attr "conds" "use")
7491 (set_attr "type" "branch")
7492 (set (attr "length")
7494 (and (match_test "TARGET_THUMB2")
7495 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7496 (le (minus (match_dup 0) (pc)) (const_int 256))))
7505 (define_expand "cstore_cc"
7506 [(set (match_operand:SI 0 "s_register_operand" "")
7507 (match_operator:SI 1 "" [(match_operand 2 "" "")
7508 (match_operand 3 "" "")]))]
7510 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7511 operands[2], operands[3], NULL_RTX);
7512 operands[3] = const0_rtx;"
7515 (define_insn_and_split "*mov_scc"
7516 [(set (match_operand:SI 0 "s_register_operand" "=r")
7517 (match_operator:SI 1 "arm_comparison_operator_mode"
7518 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7520 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7523 (if_then_else:SI (match_dup 1)
7527 [(set_attr "conds" "use")
7528 (set_attr "length" "8")
7529 (set_attr "type" "multiple")]
7532 (define_insn_and_split "*mov_negscc"
7533 [(set (match_operand:SI 0 "s_register_operand" "=r")
7534 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7535 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7537 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7540 (if_then_else:SI (match_dup 1)
7544 operands[3] = GEN_INT (~0);
7546 [(set_attr "conds" "use")
7547 (set_attr "length" "8")
7548 (set_attr "type" "multiple")]
7551 (define_insn_and_split "*mov_notscc"
7552 [(set (match_operand:SI 0 "s_register_operand" "=r")
7553 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7554 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7556 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7559 (if_then_else:SI (match_dup 1)
7563 operands[3] = GEN_INT (~1);
7564 operands[4] = GEN_INT (~0);
7566 [(set_attr "conds" "use")
7567 (set_attr "length" "8")
7568 (set_attr "type" "multiple")]
7571 (define_expand "cstoresi4"
7572 [(set (match_operand:SI 0 "s_register_operand" "")
7573 (match_operator:SI 1 "expandable_comparison_operator"
7574 [(match_operand:SI 2 "s_register_operand" "")
7575 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7576 "TARGET_32BIT || TARGET_THUMB1"
7578 rtx op3, scratch, scratch2;
7582 if (!arm_add_operand (operands[3], SImode))
7583 operands[3] = force_reg (SImode, operands[3]);
7584 emit_insn (gen_cstore_cc (operands[0], operands[1],
7585 operands[2], operands[3]));
7589 if (operands[3] == const0_rtx)
7591 switch (GET_CODE (operands[1]))
7594 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7598 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7602 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7603 NULL_RTX, 0, OPTAB_WIDEN);
7604 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7605 NULL_RTX, 0, OPTAB_WIDEN);
7606 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7607 operands[0], 1, OPTAB_WIDEN);
7611 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7613 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7614 NULL_RTX, 1, OPTAB_WIDEN);
7618 scratch = expand_binop (SImode, ashr_optab, operands[2],
7619 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7620 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7621 NULL_RTX, 0, OPTAB_WIDEN);
7622 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7626 /* LT is handled by generic code. No need for unsigned with 0. */
7633 switch (GET_CODE (operands[1]))
7636 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7637 NULL_RTX, 0, OPTAB_WIDEN);
7638 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7642 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7643 NULL_RTX, 0, OPTAB_WIDEN);
7644 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7648 op3 = force_reg (SImode, operands[3]);
7650 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7651 NULL_RTX, 1, OPTAB_WIDEN);
7652 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7653 NULL_RTX, 0, OPTAB_WIDEN);
7654 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7660 if (!thumb1_cmp_operand (op3, SImode))
7661 op3 = force_reg (SImode, op3);
7662 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7663 NULL_RTX, 0, OPTAB_WIDEN);
7664 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7665 NULL_RTX, 1, OPTAB_WIDEN);
7666 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7671 op3 = force_reg (SImode, operands[3]);
7672 scratch = force_reg (SImode, const0_rtx);
7673 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7679 if (!thumb1_cmp_operand (op3, SImode))
7680 op3 = force_reg (SImode, op3);
7681 scratch = force_reg (SImode, const0_rtx);
7682 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7688 if (!thumb1_cmp_operand (op3, SImode))
7689 op3 = force_reg (SImode, op3);
7690 scratch = gen_reg_rtx (SImode);
7691 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7695 op3 = force_reg (SImode, operands[3]);
7696 scratch = gen_reg_rtx (SImode);
7697 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7700 /* No good sequences for GT, LT. */
7707 (define_expand "cstoresf4"
7708 [(set (match_operand:SI 0 "s_register_operand" "")
7709 (match_operator:SI 1 "expandable_comparison_operator"
7710 [(match_operand:SF 2 "s_register_operand" "")
7711 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7712 "TARGET_32BIT && TARGET_HARD_FLOAT"
7713 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7714 operands[2], operands[3])); DONE;"
7717 (define_expand "cstoredf4"
7718 [(set (match_operand:SI 0 "s_register_operand" "")
7719 (match_operator:SI 1 "expandable_comparison_operator"
7720 [(match_operand:DF 2 "s_register_operand" "")
7721 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7722 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7723 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7724 operands[2], operands[3])); DONE;"
7727 (define_expand "cstoredi4"
7728 [(set (match_operand:SI 0 "s_register_operand" "")
7729 (match_operator:SI 1 "expandable_comparison_operator"
7730 [(match_operand:DI 2 "s_register_operand" "")
7731 (match_operand:DI 3 "cmpdi_operand" "")]))]
7734 if (!arm_validize_comparison (&operands[1],
7738 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7745 ;; Conditional move insns
7747 (define_expand "movsicc"
7748 [(set (match_operand:SI 0 "s_register_operand" "")
7749 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7750 (match_operand:SI 2 "arm_not_operand" "")
7751 (match_operand:SI 3 "arm_not_operand" "")))]
7758 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7759 &XEXP (operands[1], 1)))
7762 code = GET_CODE (operands[1]);
7763 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7764 XEXP (operands[1], 1), NULL_RTX);
7765 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7769 (define_expand "movsfcc"
7770 [(set (match_operand:SF 0 "s_register_operand" "")
7771 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7772 (match_operand:SF 2 "s_register_operand" "")
7773 (match_operand:SF 3 "s_register_operand" "")))]
7774 "TARGET_32BIT && TARGET_HARD_FLOAT"
7777 enum rtx_code code = GET_CODE (operands[1]);
7780 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7781 &XEXP (operands[1], 1)))
7784 code = GET_CODE (operands[1]);
7785 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7786 XEXP (operands[1], 1), NULL_RTX);
7787 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7791 (define_expand "movdfcc"
7792 [(set (match_operand:DF 0 "s_register_operand" "")
7793 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7794 (match_operand:DF 2 "s_register_operand" "")
7795 (match_operand:DF 3 "s_register_operand" "")))]
7796 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7799 enum rtx_code code = GET_CODE (operands[1]);
7802 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7803 &XEXP (operands[1], 1)))
7805 code = GET_CODE (operands[1]);
7806 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7807 XEXP (operands[1], 1), NULL_RTX);
7808 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7812 (define_insn "*cmov<mode>"
7813 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7814 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7815 [(match_operand 2 "cc_register" "") (const_int 0)])
7816 (match_operand:SDF 3 "s_register_operand"
7818 (match_operand:SDF 4 "s_register_operand"
7819 "<F_constraint>")))]
7820 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7823 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7830 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7835 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7841 [(set_attr "conds" "use")
7842 (set_attr "type" "fcsel")]
7845 (define_insn_and_split "*movsicc_insn"
7846 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7848 (match_operator 3 "arm_comparison_operator"
7849 [(match_operand 4 "cc_register" "") (const_int 0)])
7850 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7851 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7862 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7863 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7864 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7865 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7866 "&& reload_completed"
7869 enum rtx_code rev_code;
7873 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7875 gen_rtx_SET (operands[0], operands[1])));
7877 rev_code = GET_CODE (operands[3]);
7878 mode = GET_MODE (operands[4]);
7879 if (mode == CCFPmode || mode == CCFPEmode)
7880 rev_code = reverse_condition_maybe_unordered (rev_code);
7882 rev_code = reverse_condition (rev_code);
7884 rev_cond = gen_rtx_fmt_ee (rev_code,
7888 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7890 gen_rtx_SET (operands[0], operands[2])));
7893 [(set_attr "length" "4,4,4,4,8,8,8,8")
7894 (set_attr "conds" "use")
7895 (set_attr_alternative "type"
7896 [(if_then_else (match_operand 2 "const_int_operand" "")
7897 (const_string "mov_imm")
7898 (const_string "mov_reg"))
7899 (const_string "mvn_imm")
7900 (if_then_else (match_operand 1 "const_int_operand" "")
7901 (const_string "mov_imm")
7902 (const_string "mov_reg"))
7903 (const_string "mvn_imm")
7904 (const_string "multiple")
7905 (const_string "multiple")
7906 (const_string "multiple")
7907 (const_string "multiple")])]
7910 (define_insn "*movsfcc_soft_insn"
7911 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7912 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7913 [(match_operand 4 "cc_register" "") (const_int 0)])
7914 (match_operand:SF 1 "s_register_operand" "0,r")
7915 (match_operand:SF 2 "s_register_operand" "r,0")))]
7916 "TARGET_ARM && TARGET_SOFT_FLOAT"
7920 [(set_attr "conds" "use")
7921 (set_attr "type" "mov_reg")]
7925 ;; Jump and linkage insns
7927 (define_expand "jump"
7929 (label_ref (match_operand 0 "" "")))]
7934 (define_insn "*arm_jump"
7936 (label_ref (match_operand 0 "" "")))]
7940 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7942 arm_ccfsm_state += 2;
7945 return \"b%?\\t%l0\";
7948 [(set_attr "predicable" "yes")
7949 (set (attr "length")
7951 (and (match_test "TARGET_THUMB2")
7952 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7953 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7956 (set_attr "type" "branch")]
7959 (define_expand "call"
7960 [(parallel [(call (match_operand 0 "memory_operand" "")
7961 (match_operand 1 "general_operand" ""))
7962 (use (match_operand 2 "" ""))
7963 (clobber (reg:SI LR_REGNUM))])]
7969 /* In an untyped call, we can get NULL for operand 2. */
7970 if (operands[2] == NULL_RTX)
7971 operands[2] = const0_rtx;
7973 /* Decide if we should generate indirect calls by loading the
7974 32-bit address of the callee into a register before performing the
7976 callee = XEXP (operands[0], 0);
7977 if (GET_CODE (callee) == SYMBOL_REF
7978 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7980 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7982 pat = gen_call_internal (operands[0], operands[1], operands[2]);
7983 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7988 (define_expand "call_internal"
7989 [(parallel [(call (match_operand 0 "memory_operand" "")
7990 (match_operand 1 "general_operand" ""))
7991 (use (match_operand 2 "" ""))
7992 (clobber (reg:SI LR_REGNUM))])])
7994 (define_insn "*call_reg_armv5"
7995 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7996 (match_operand 1 "" ""))
7997 (use (match_operand 2 "" ""))
7998 (clobber (reg:SI LR_REGNUM))]
7999 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8001 [(set_attr "type" "call")]
8004 (define_insn "*call_reg_arm"
8005 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8006 (match_operand 1 "" ""))
8007 (use (match_operand 2 "" ""))
8008 (clobber (reg:SI LR_REGNUM))]
8009 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8011 return output_call (operands);
8013 ;; length is worst case, normally it is only two
8014 [(set_attr "length" "12")
8015 (set_attr "type" "call")]
8019 (define_expand "call_value"
8020 [(parallel [(set (match_operand 0 "" "")
8021 (call (match_operand 1 "memory_operand" "")
8022 (match_operand 2 "general_operand" "")))
8023 (use (match_operand 3 "" ""))
8024 (clobber (reg:SI LR_REGNUM))])]
8030 /* In an untyped call, we can get NULL for operand 2. */
8031 if (operands[3] == 0)
8032 operands[3] = const0_rtx;
8034 /* Decide if we should generate indirect calls by loading the
8035 32-bit address of the callee into a register before performing the
8037 callee = XEXP (operands[1], 0);
8038 if (GET_CODE (callee) == SYMBOL_REF
8039 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8041 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8043 pat = gen_call_value_internal (operands[0], operands[1],
8044 operands[2], operands[3]);
8045 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8050 (define_expand "call_value_internal"
8051 [(parallel [(set (match_operand 0 "" "")
8052 (call (match_operand 1 "memory_operand" "")
8053 (match_operand 2 "general_operand" "")))
8054 (use (match_operand 3 "" ""))
8055 (clobber (reg:SI LR_REGNUM))])])
8057 (define_insn "*call_value_reg_armv5"
8058 [(set (match_operand 0 "" "")
8059 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8060 (match_operand 2 "" "")))
8061 (use (match_operand 3 "" ""))
8062 (clobber (reg:SI LR_REGNUM))]
8063 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8065 [(set_attr "type" "call")]
8068 (define_insn "*call_value_reg_arm"
8069 [(set (match_operand 0 "" "")
8070 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8071 (match_operand 2 "" "")))
8072 (use (match_operand 3 "" ""))
8073 (clobber (reg:SI LR_REGNUM))]
8074 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8076 return output_call (&operands[1]);
8078 [(set_attr "length" "12")
8079 (set_attr "type" "call")]
8082 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8083 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8085 (define_insn "*call_symbol"
8086 [(call (mem:SI (match_operand:SI 0 "" ""))
8087 (match_operand 1 "" ""))
8088 (use (match_operand 2 "" ""))
8089 (clobber (reg:SI LR_REGNUM))]
8091 && !SIBLING_CALL_P (insn)
8092 && (GET_CODE (operands[0]) == SYMBOL_REF)
8093 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8096 rtx op = operands[0];
8098 /* Switch mode now when possible. */
8099 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8100 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8101 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8103 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8105 [(set_attr "type" "call")]
8108 (define_insn "*call_value_symbol"
8109 [(set (match_operand 0 "" "")
8110 (call (mem:SI (match_operand:SI 1 "" ""))
8111 (match_operand:SI 2 "" "")))
8112 (use (match_operand 3 "" ""))
8113 (clobber (reg:SI LR_REGNUM))]
8115 && !SIBLING_CALL_P (insn)
8116 && (GET_CODE (operands[1]) == SYMBOL_REF)
8117 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8120 rtx op = operands[1];
8122 /* Switch mode now when possible. */
8123 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8124 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8125 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8127 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8129 [(set_attr "type" "call")]
8132 (define_expand "sibcall_internal"
8133 [(parallel [(call (match_operand 0 "memory_operand" "")
8134 (match_operand 1 "general_operand" ""))
8136 (use (match_operand 2 "" ""))])])
8138 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8139 (define_expand "sibcall"
8140 [(parallel [(call (match_operand 0 "memory_operand" "")
8141 (match_operand 1 "general_operand" ""))
8143 (use (match_operand 2 "" ""))])]
8149 if ((!REG_P (XEXP (operands[0], 0))
8150 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8151 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8152 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8153 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8155 if (operands[2] == NULL_RTX)
8156 operands[2] = const0_rtx;
8158 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8159 arm_emit_call_insn (pat, operands[0], true);
8164 (define_expand "sibcall_value_internal"
8165 [(parallel [(set (match_operand 0 "" "")
8166 (call (match_operand 1 "memory_operand" "")
8167 (match_operand 2 "general_operand" "")))
8169 (use (match_operand 3 "" ""))])])
8171 (define_expand "sibcall_value"
8172 [(parallel [(set (match_operand 0 "" "")
8173 (call (match_operand 1 "memory_operand" "")
8174 (match_operand 2 "general_operand" "")))
8176 (use (match_operand 3 "" ""))])]
8182 if ((!REG_P (XEXP (operands[1], 0))
8183 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8184 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8185 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8186 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8188 if (operands[3] == NULL_RTX)
8189 operands[3] = const0_rtx;
8191 pat = gen_sibcall_value_internal (operands[0], operands[1],
8192 operands[2], operands[3]);
8193 arm_emit_call_insn (pat, operands[1], true);
8198 (define_insn "*sibcall_insn"
8199 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8200 (match_operand 1 "" ""))
8202 (use (match_operand 2 "" ""))]
8203 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8205 if (which_alternative == 1)
8206 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8209 if (arm_arch5 || arm_arch4t)
8210 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8212 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8215 [(set_attr "type" "call")]
8218 (define_insn "*sibcall_value_insn"
8219 [(set (match_operand 0 "" "")
8220 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8221 (match_operand 2 "" "")))
8223 (use (match_operand 3 "" ""))]
8224 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8226 if (which_alternative == 1)
8227 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8230 if (arm_arch5 || arm_arch4t)
8231 return \"bx%?\\t%1\";
8233 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8236 [(set_attr "type" "call")]
8239 (define_expand "<return_str>return"
8241 "(TARGET_ARM || (TARGET_THUMB2
8242 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8243 && !IS_STACKALIGN (arm_current_func_type ())))
8244 <return_cond_false>"
8249 thumb2_expand_return (<return_simple_p>);
8256 ;; Often the return insn will be the same as loading from memory, so set attr
8257 (define_insn "*arm_return"
8259 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8262 if (arm_ccfsm_state == 2)
8264 arm_ccfsm_state += 2;
8267 return output_return_instruction (const_true_rtx, true, false, false);
8269 [(set_attr "type" "load1")
8270 (set_attr "length" "12")
8271 (set_attr "predicable" "yes")]
8274 (define_insn "*cond_<return_str>return"
8276 (if_then_else (match_operator 0 "arm_comparison_operator"
8277 [(match_operand 1 "cc_register" "") (const_int 0)])
8280 "TARGET_ARM <return_cond_true>"
8283 if (arm_ccfsm_state == 2)
8285 arm_ccfsm_state += 2;
8288 return output_return_instruction (operands[0], true, false,
8291 [(set_attr "conds" "use")
8292 (set_attr "length" "12")
8293 (set_attr "type" "load1")]
8296 (define_insn "*cond_<return_str>return_inverted"
8298 (if_then_else (match_operator 0 "arm_comparison_operator"
8299 [(match_operand 1 "cc_register" "") (const_int 0)])
8302 "TARGET_ARM <return_cond_true>"
8305 if (arm_ccfsm_state == 2)
8307 arm_ccfsm_state += 2;
8310 return output_return_instruction (operands[0], true, true,
8313 [(set_attr "conds" "use")
8314 (set_attr "length" "12")
8315 (set_attr "type" "load1")]
8318 (define_insn "*arm_simple_return"
8323 if (arm_ccfsm_state == 2)
8325 arm_ccfsm_state += 2;
8328 return output_return_instruction (const_true_rtx, true, false, true);
8330 [(set_attr "type" "branch")
8331 (set_attr "length" "4")
8332 (set_attr "predicable" "yes")]
8335 ;; Generate a sequence of instructions to determine if the processor is
8336 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8339 (define_expand "return_addr_mask"
8341 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8343 (set (match_operand:SI 0 "s_register_operand" "")
8344 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8346 (const_int 67108860)))] ; 0x03fffffc
8349 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8352 (define_insn "*check_arch2"
8353 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8354 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8357 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8358 [(set_attr "length" "8")
8359 (set_attr "conds" "set")
8360 (set_attr "type" "multiple")]
8363 ;; Call subroutine returning any type.
8365 (define_expand "untyped_call"
8366 [(parallel [(call (match_operand 0 "" "")
8368 (match_operand 1 "" "")
8369 (match_operand 2 "" "")])]
8374 rtx par = gen_rtx_PARALLEL (VOIDmode,
8375 rtvec_alloc (XVECLEN (operands[2], 0)));
8376 rtx addr = gen_reg_rtx (Pmode);
8380 emit_move_insn (addr, XEXP (operands[1], 0));
8381 mem = change_address (operands[1], BLKmode, addr);
8383 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8385 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8387 /* Default code only uses r0 as a return value, but we could
8388 be using anything up to 4 registers. */
8389 if (REGNO (src) == R0_REGNUM)
8390 src = gen_rtx_REG (TImode, R0_REGNUM);
8392 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8394 size += GET_MODE_SIZE (GET_MODE (src));
8397 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8401 for (i = 0; i < XVECLEN (par, 0); i++)
8403 HOST_WIDE_INT offset = 0;
8404 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8407 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8409 mem = change_address (mem, GET_MODE (reg), NULL);
8410 if (REGNO (reg) == R0_REGNUM)
8412 /* On thumb we have to use a write-back instruction. */
8413 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8414 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8415 size = TARGET_ARM ? 16 : 0;
8419 emit_move_insn (mem, reg);
8420 size = GET_MODE_SIZE (GET_MODE (reg));
8424 /* The optimizer does not know that the call sets the function value
8425 registers we stored in the result block. We avoid problems by
8426 claiming that all hard registers are used and clobbered at this
8428 emit_insn (gen_blockage ());
8434 (define_expand "untyped_return"
8435 [(match_operand:BLK 0 "memory_operand" "")
8436 (match_operand 1 "" "")]
8441 rtx addr = gen_reg_rtx (Pmode);
8445 emit_move_insn (addr, XEXP (operands[0], 0));
8446 mem = change_address (operands[0], BLKmode, addr);
8448 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8450 HOST_WIDE_INT offset = 0;
8451 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8454 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8456 mem = change_address (mem, GET_MODE (reg), NULL);
8457 if (REGNO (reg) == R0_REGNUM)
8459 /* On thumb we have to use a write-back instruction. */
8460 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8461 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8462 size = TARGET_ARM ? 16 : 0;
8466 emit_move_insn (reg, mem);
8467 size = GET_MODE_SIZE (GET_MODE (reg));
8471 /* Emit USE insns before the return. */
8472 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8473 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8475 /* Construct the return. */
8476 expand_naked_return ();
8482 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8483 ;; all of memory. This blocks insns from being moved across this point.
8485 (define_insn "blockage"
8486 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8489 [(set_attr "length" "0")
8490 (set_attr "type" "block")]
8493 (define_insn "probe_stack"
8494 [(set (match_operand:SI 0 "memory_operand" "=m")
8495 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8498 [(set_attr "type" "store1")
8499 (set_attr "predicable" "yes")]
8502 (define_insn "probe_stack_range"
8503 [(set (match_operand:SI 0 "register_operand" "=r")
8504 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8505 (match_operand:SI 2 "register_operand" "r")]
8506 VUNSPEC_PROBE_STACK_RANGE))]
8509 return output_probe_stack_range (operands[0], operands[2]);
8511 [(set_attr "type" "multiple")
8512 (set_attr "conds" "clob")]
8515 (define_expand "casesi"
8516 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8517 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8518 (match_operand:SI 2 "const_int_operand" "") ; total range
8519 (match_operand:SI 3 "" "") ; table label
8520 (match_operand:SI 4 "" "")] ; Out of range label
8521 "TARGET_32BIT || optimize_size || flag_pic"
8524 enum insn_code code;
8525 if (operands[1] != const0_rtx)
8527 rtx reg = gen_reg_rtx (SImode);
8529 emit_insn (gen_addsi3 (reg, operands[0],
8530 gen_int_mode (-INTVAL (operands[1]),
8536 code = CODE_FOR_arm_casesi_internal;
8537 else if (TARGET_THUMB1)
8538 code = CODE_FOR_thumb1_casesi_internal_pic;
8540 code = CODE_FOR_thumb2_casesi_internal_pic;
8542 code = CODE_FOR_thumb2_casesi_internal;
8544 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8545 operands[2] = force_reg (SImode, operands[2]);
8547 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8548 operands[3], operands[4]));
8553 ;; The USE in this pattern is needed to tell flow analysis that this is
8554 ;; a CASESI insn. It has no other purpose.
8555 (define_insn "arm_casesi_internal"
8556 [(parallel [(set (pc)
8558 (leu (match_operand:SI 0 "s_register_operand" "r")
8559 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8560 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8561 (label_ref (match_operand 2 "" ""))))
8562 (label_ref (match_operand 3 "" ""))))
8563 (clobber (reg:CC CC_REGNUM))
8564 (use (label_ref (match_dup 2)))])]
8568 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8569 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8571 [(set_attr "conds" "clob")
8572 (set_attr "length" "12")
8573 (set_attr "type" "multiple")]
8576 (define_expand "indirect_jump"
8578 (match_operand:SI 0 "s_register_operand" ""))]
8581 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8582 address and use bx. */
8586 tmp = gen_reg_rtx (SImode);
8587 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8593 ;; NB Never uses BX.
8594 (define_insn "*arm_indirect_jump"
8596 (match_operand:SI 0 "s_register_operand" "r"))]
8598 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8599 [(set_attr "predicable" "yes")
8600 (set_attr "type" "branch")]
8603 (define_insn "*load_indirect_jump"
8605 (match_operand:SI 0 "memory_operand" "m"))]
8607 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8608 [(set_attr "type" "load1")
8609 (set_attr "pool_range" "4096")
8610 (set_attr "neg_pool_range" "4084")
8611 (set_attr "predicable" "yes")]
8621 [(set (attr "length")
8622 (if_then_else (eq_attr "is_thumb" "yes")
8625 (set_attr "type" "mov_reg")]
8629 [(trap_if (const_int 1) (const_int 0))]
8633 return \".inst\\t0xe7f000f0\";
8635 return \".inst\\t0xdeff\";
8637 [(set (attr "length")
8638 (if_then_else (eq_attr "is_thumb" "yes")
8641 (set_attr "type" "trap")
8642 (set_attr "conds" "unconditional")]
8646 ;; Patterns to allow combination of arithmetic, cond code and shifts
8648 (define_insn "*<arith_shift_insn>_multsi"
8649 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8651 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8652 (match_operand:SI 3 "power_of_two_operand" ""))
8653 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8655 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8656 [(set_attr "predicable" "yes")
8657 (set_attr "predicable_short_it" "no")
8658 (set_attr "shift" "2")
8659 (set_attr "arch" "a,t2")
8660 (set_attr "type" "alu_shift_imm")])
8662 (define_insn "*<arith_shift_insn>_shiftsi"
8663 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8665 (match_operator:SI 2 "shift_nomul_operator"
8666 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8667 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8668 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8669 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8670 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8671 [(set_attr "predicable" "yes")
8672 (set_attr "predicable_short_it" "no")
8673 (set_attr "shift" "3")
8674 (set_attr "arch" "a,t2,a")
8675 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8678 [(set (match_operand:SI 0 "s_register_operand" "")
8679 (match_operator:SI 1 "shiftable_operator"
8680 [(match_operator:SI 2 "shiftable_operator"
8681 [(match_operator:SI 3 "shift_operator"
8682 [(match_operand:SI 4 "s_register_operand" "")
8683 (match_operand:SI 5 "reg_or_int_operand" "")])
8684 (match_operand:SI 6 "s_register_operand" "")])
8685 (match_operand:SI 7 "arm_rhs_operand" "")]))
8686 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8689 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8692 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8695 (define_insn "*arith_shiftsi_compare0"
8696 [(set (reg:CC_NOOV CC_REGNUM)
8698 (match_operator:SI 1 "shiftable_operator"
8699 [(match_operator:SI 3 "shift_operator"
8700 [(match_operand:SI 4 "s_register_operand" "r,r")
8701 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8702 (match_operand:SI 2 "s_register_operand" "r,r")])
8704 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8705 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8708 "%i1s%?\\t%0, %2, %4%S3"
8709 [(set_attr "conds" "set")
8710 (set_attr "shift" "4")
8711 (set_attr "arch" "32,a")
8712 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8714 (define_insn "*arith_shiftsi_compare0_scratch"
8715 [(set (reg:CC_NOOV CC_REGNUM)
8717 (match_operator:SI 1 "shiftable_operator"
8718 [(match_operator:SI 3 "shift_operator"
8719 [(match_operand:SI 4 "s_register_operand" "r,r")
8720 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8721 (match_operand:SI 2 "s_register_operand" "r,r")])
8723 (clobber (match_scratch:SI 0 "=r,r"))]
8725 "%i1s%?\\t%0, %2, %4%S3"
8726 [(set_attr "conds" "set")
8727 (set_attr "shift" "4")
8728 (set_attr "arch" "32,a")
8729 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8731 (define_insn "*sub_shiftsi"
8732 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8733 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8734 (match_operator:SI 2 "shift_operator"
8735 [(match_operand:SI 3 "s_register_operand" "r,r")
8736 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8738 "sub%?\\t%0, %1, %3%S2"
8739 [(set_attr "predicable" "yes")
8740 (set_attr "shift" "3")
8741 (set_attr "arch" "32,a")
8742 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8744 (define_insn "*sub_shiftsi_compare0"
8745 [(set (reg:CC_NOOV CC_REGNUM)
8747 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8748 (match_operator:SI 2 "shift_operator"
8749 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8750 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8752 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8753 (minus:SI (match_dup 1)
8754 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8756 "subs%?\\t%0, %1, %3%S2"
8757 [(set_attr "conds" "set")
8758 (set_attr "shift" "3")
8759 (set_attr "arch" "32,a,a")
8760 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8762 (define_insn "*sub_shiftsi_compare0_scratch"
8763 [(set (reg:CC_NOOV CC_REGNUM)
8765 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8766 (match_operator:SI 2 "shift_operator"
8767 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8768 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8770 (clobber (match_scratch:SI 0 "=r,r,r"))]
8772 "subs%?\\t%0, %1, %3%S2"
8773 [(set_attr "conds" "set")
8774 (set_attr "shift" "3")
8775 (set_attr "arch" "32,a,a")
8776 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8779 (define_insn_and_split "*and_scc"
8780 [(set (match_operand:SI 0 "s_register_operand" "=r")
8781 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8782 [(match_operand 2 "cc_register" "") (const_int 0)])
8783 (match_operand:SI 3 "s_register_operand" "r")))]
8785 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8786 "&& reload_completed"
8787 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8788 (cond_exec (match_dup 4) (set (match_dup 0)
8789 (and:SI (match_dup 3) (const_int 1))))]
8791 machine_mode mode = GET_MODE (operands[2]);
8792 enum rtx_code rc = GET_CODE (operands[1]);
8794 /* Note that operands[4] is the same as operands[1],
8795 but with VOIDmode as the result. */
8796 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8797 if (mode == CCFPmode || mode == CCFPEmode)
8798 rc = reverse_condition_maybe_unordered (rc);
8800 rc = reverse_condition (rc);
8801 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8803 [(set_attr "conds" "use")
8804 (set_attr "type" "multiple")
8805 (set_attr "length" "8")]
8808 (define_insn_and_split "*ior_scc"
8809 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8810 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8811 [(match_operand 2 "cc_register" "") (const_int 0)])
8812 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8817 "&& reload_completed
8818 && REGNO (operands [0]) != REGNO (operands[3])"
8819 ;; && which_alternative == 1
8820 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8821 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8822 (cond_exec (match_dup 4) (set (match_dup 0)
8823 (ior:SI (match_dup 3) (const_int 1))))]
8825 machine_mode mode = GET_MODE (operands[2]);
8826 enum rtx_code rc = GET_CODE (operands[1]);
8828 /* Note that operands[4] is the same as operands[1],
8829 but with VOIDmode as the result. */
8830 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8831 if (mode == CCFPmode || mode == CCFPEmode)
8832 rc = reverse_condition_maybe_unordered (rc);
8834 rc = reverse_condition (rc);
8835 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8837 [(set_attr "conds" "use")
8838 (set_attr "length" "4,8")
8839 (set_attr "type" "logic_imm,multiple")]
8842 ; A series of splitters for the compare_scc pattern below. Note that
8843 ; order is important.
8845 [(set (match_operand:SI 0 "s_register_operand" "")
8846 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8848 (clobber (reg:CC CC_REGNUM))]
8849 "TARGET_32BIT && reload_completed"
8850 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8853 [(set (match_operand:SI 0 "s_register_operand" "")
8854 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8856 (clobber (reg:CC CC_REGNUM))]
8857 "TARGET_32BIT && reload_completed"
8858 [(set (match_dup 0) (not:SI (match_dup 1)))
8859 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8862 [(set (match_operand:SI 0 "s_register_operand" "")
8863 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8865 (clobber (reg:CC CC_REGNUM))]
8866 "arm_arch5 && TARGET_32BIT"
8867 [(set (match_dup 0) (clz:SI (match_dup 1)))
8868 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8872 [(set (match_operand:SI 0 "s_register_operand" "")
8873 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8875 (clobber (reg:CC CC_REGNUM))]
8876 "TARGET_32BIT && reload_completed"
8878 [(set (reg:CC CC_REGNUM)
8879 (compare:CC (const_int 1) (match_dup 1)))
8881 (minus:SI (const_int 1) (match_dup 1)))])
8882 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8883 (set (match_dup 0) (const_int 0)))])
8886 [(set (match_operand:SI 0 "s_register_operand" "")
8887 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8888 (match_operand:SI 2 "const_int_operand" "")))
8889 (clobber (reg:CC CC_REGNUM))]
8890 "TARGET_32BIT && reload_completed"
8892 [(set (reg:CC CC_REGNUM)
8893 (compare:CC (match_dup 1) (match_dup 2)))
8894 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8895 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8896 (set (match_dup 0) (const_int 1)))]
8898 operands[3] = GEN_INT (-INTVAL (operands[2]));
8902 [(set (match_operand:SI 0 "s_register_operand" "")
8903 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8904 (match_operand:SI 2 "arm_add_operand" "")))
8905 (clobber (reg:CC CC_REGNUM))]
8906 "TARGET_32BIT && reload_completed"
8908 [(set (reg:CC_NOOV CC_REGNUM)
8909 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8911 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8912 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8913 (set (match_dup 0) (const_int 1)))])
8915 (define_insn_and_split "*compare_scc"
8916 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8917 (match_operator:SI 1 "arm_comparison_operator"
8918 [(match_operand:SI 2 "s_register_operand" "r,r")
8919 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8920 (clobber (reg:CC CC_REGNUM))]
8923 "&& reload_completed"
8924 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8925 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8926 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8929 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8930 operands[2], operands[3]);
8931 enum rtx_code rc = GET_CODE (operands[1]);
8933 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8935 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8936 if (mode == CCFPmode || mode == CCFPEmode)
8937 rc = reverse_condition_maybe_unordered (rc);
8939 rc = reverse_condition (rc);
8940 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8942 [(set_attr "type" "multiple")]
8945 ;; Attempt to improve the sequence generated by the compare_scc splitters
8946 ;; not to use conditional execution.
8948 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
8952 [(set (reg:CC CC_REGNUM)
8953 (compare:CC (match_operand:SI 1 "register_operand" "")
8955 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8956 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8957 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8958 (set (match_dup 0) (const_int 1)))]
8959 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8960 [(set (match_dup 0) (clz:SI (match_dup 1)))
8961 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8964 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8968 [(set (reg:CC CC_REGNUM)
8969 (compare:CC (match_operand:SI 1 "register_operand" "")
8971 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8972 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8973 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8974 (set (match_dup 0) (const_int 1)))
8975 (match_scratch:SI 2 "r")]
8976 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8978 [(set (reg:CC CC_REGNUM)
8979 (compare:CC (const_int 0) (match_dup 1)))
8980 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8982 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8983 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8986 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
8987 ;; sub Rd, Reg1, reg2
8991 [(set (reg:CC CC_REGNUM)
8992 (compare:CC (match_operand:SI 1 "register_operand" "")
8993 (match_operand:SI 2 "arm_rhs_operand" "")))
8994 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8995 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8996 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8997 (set (match_dup 0) (const_int 1)))]
8998 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8999 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9000 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9001 (set (match_dup 0) (clz:SI (match_dup 0)))
9002 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9006 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9007 ;; sub T1, Reg1, reg2
9011 [(set (reg:CC CC_REGNUM)
9012 (compare:CC (match_operand:SI 1 "register_operand" "")
9013 (match_operand:SI 2 "arm_rhs_operand" "")))
9014 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9015 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9016 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9017 (set (match_dup 0) (const_int 1)))
9018 (match_scratch:SI 3 "r")]
9019 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9020 [(set (match_dup 3) (match_dup 4))
9022 [(set (reg:CC CC_REGNUM)
9023 (compare:CC (const_int 0) (match_dup 3)))
9024 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9026 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9027 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9029 if (CONST_INT_P (operands[2]))
9030 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9032 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9035 (define_insn "*cond_move"
9036 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9037 (if_then_else:SI (match_operator 3 "equality_operator"
9038 [(match_operator 4 "arm_comparison_operator"
9039 [(match_operand 5 "cc_register" "") (const_int 0)])
9041 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9042 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9045 if (GET_CODE (operands[3]) == NE)
9047 if (which_alternative != 1)
9048 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9049 if (which_alternative != 0)
9050 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9053 if (which_alternative != 0)
9054 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9055 if (which_alternative != 1)
9056 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9059 [(set_attr "conds" "use")
9060 (set_attr_alternative "type"
9061 [(if_then_else (match_operand 2 "const_int_operand" "")
9062 (const_string "mov_imm")
9063 (const_string "mov_reg"))
9064 (if_then_else (match_operand 1 "const_int_operand" "")
9065 (const_string "mov_imm")
9066 (const_string "mov_reg"))
9067 (const_string "multiple")])
9068 (set_attr "length" "4,4,8")]
9071 (define_insn "*cond_arith"
9072 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9073 (match_operator:SI 5 "shiftable_operator"
9074 [(match_operator:SI 4 "arm_comparison_operator"
9075 [(match_operand:SI 2 "s_register_operand" "r,r")
9076 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9077 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9078 (clobber (reg:CC CC_REGNUM))]
9081 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9082 return \"%i5\\t%0, %1, %2, lsr #31\";
9084 output_asm_insn (\"cmp\\t%2, %3\", operands);
9085 if (GET_CODE (operands[5]) == AND)
9086 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9087 else if (GET_CODE (operands[5]) == MINUS)
9088 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9089 else if (which_alternative != 0)
9090 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9091 return \"%i5%d4\\t%0, %1, #1\";
9093 [(set_attr "conds" "clob")
9094 (set_attr "length" "12")
9095 (set_attr "type" "multiple")]
9098 (define_insn "*cond_sub"
9099 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9100 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9101 (match_operator:SI 4 "arm_comparison_operator"
9102 [(match_operand:SI 2 "s_register_operand" "r,r")
9103 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9104 (clobber (reg:CC CC_REGNUM))]
9107 output_asm_insn (\"cmp\\t%2, %3\", operands);
9108 if (which_alternative != 0)
9109 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9110 return \"sub%d4\\t%0, %1, #1\";
9112 [(set_attr "conds" "clob")
9113 (set_attr "length" "8,12")
9114 (set_attr "type" "multiple")]
9117 (define_insn "*cmp_ite0"
9118 [(set (match_operand 6 "dominant_cc_register" "")
9121 (match_operator 4 "arm_comparison_operator"
9122 [(match_operand:SI 0 "s_register_operand"
9123 "l,l,l,r,r,r,r,r,r")
9124 (match_operand:SI 1 "arm_add_operand"
9125 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9126 (match_operator:SI 5 "arm_comparison_operator"
9127 [(match_operand:SI 2 "s_register_operand"
9128 "l,r,r,l,l,r,r,r,r")
9129 (match_operand:SI 3 "arm_add_operand"
9130 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9136 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9138 {\"cmp%d5\\t%0, %1\",
9139 \"cmp%d4\\t%2, %3\"},
9140 {\"cmn%d5\\t%0, #%n1\",
9141 \"cmp%d4\\t%2, %3\"},
9142 {\"cmp%d5\\t%0, %1\",
9143 \"cmn%d4\\t%2, #%n3\"},
9144 {\"cmn%d5\\t%0, #%n1\",
9145 \"cmn%d4\\t%2, #%n3\"}
9147 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9152 \"cmn\\t%0, #%n1\"},
9153 {\"cmn\\t%2, #%n3\",
9155 {\"cmn\\t%2, #%n3\",
9158 static const char * const ite[2] =
9163 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9164 CMP_CMP, CMN_CMP, CMP_CMP,
9165 CMN_CMP, CMP_CMN, CMN_CMN};
9167 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9169 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9170 if (TARGET_THUMB2) {
9171 output_asm_insn (ite[swap], operands);
9173 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9176 [(set_attr "conds" "set")
9177 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9178 (set_attr "type" "multiple")
9179 (set_attr_alternative "length"
9185 (if_then_else (eq_attr "is_thumb" "no")
9188 (if_then_else (eq_attr "is_thumb" "no")
9191 (if_then_else (eq_attr "is_thumb" "no")
9194 (if_then_else (eq_attr "is_thumb" "no")
9199 (define_insn "*cmp_ite1"
9200 [(set (match_operand 6 "dominant_cc_register" "")
9203 (match_operator 4 "arm_comparison_operator"
9204 [(match_operand:SI 0 "s_register_operand"
9205 "l,l,l,r,r,r,r,r,r")
9206 (match_operand:SI 1 "arm_add_operand"
9207 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9208 (match_operator:SI 5 "arm_comparison_operator"
9209 [(match_operand:SI 2 "s_register_operand"
9210 "l,r,r,l,l,r,r,r,r")
9211 (match_operand:SI 3 "arm_add_operand"
9212 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9218 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9222 {\"cmn\\t%0, #%n1\",
9225 \"cmn\\t%2, #%n3\"},
9226 {\"cmn\\t%0, #%n1\",
9229 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9231 {\"cmp%d4\\t%2, %3\",
9232 \"cmp%D5\\t%0, %1\"},
9233 {\"cmp%d4\\t%2, %3\",
9234 \"cmn%D5\\t%0, #%n1\"},
9235 {\"cmn%d4\\t%2, #%n3\",
9236 \"cmp%D5\\t%0, %1\"},
9237 {\"cmn%d4\\t%2, #%n3\",
9238 \"cmn%D5\\t%0, #%n1\"}
9240 static const char * const ite[2] =
9245 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9246 CMP_CMP, CMN_CMP, CMP_CMP,
9247 CMN_CMP, CMP_CMN, CMN_CMN};
9249 comparison_dominates_p (GET_CODE (operands[5]),
9250 reverse_condition (GET_CODE (operands[4])));
9252 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9253 if (TARGET_THUMB2) {
9254 output_asm_insn (ite[swap], operands);
9256 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9259 [(set_attr "conds" "set")
9260 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9261 (set_attr_alternative "length"
9267 (if_then_else (eq_attr "is_thumb" "no")
9270 (if_then_else (eq_attr "is_thumb" "no")
9273 (if_then_else (eq_attr "is_thumb" "no")
9276 (if_then_else (eq_attr "is_thumb" "no")
9279 (set_attr "type" "multiple")]
9282 (define_insn "*cmp_and"
9283 [(set (match_operand 6 "dominant_cc_register" "")
9286 (match_operator 4 "arm_comparison_operator"
9287 [(match_operand:SI 0 "s_register_operand"
9288 "l,l,l,r,r,r,r,r,r")
9289 (match_operand:SI 1 "arm_add_operand"
9290 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9291 (match_operator:SI 5 "arm_comparison_operator"
9292 [(match_operand:SI 2 "s_register_operand"
9293 "l,r,r,l,l,r,r,r,r")
9294 (match_operand:SI 3 "arm_add_operand"
9295 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9300 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9302 {\"cmp%d5\\t%0, %1\",
9303 \"cmp%d4\\t%2, %3\"},
9304 {\"cmn%d5\\t%0, #%n1\",
9305 \"cmp%d4\\t%2, %3\"},
9306 {\"cmp%d5\\t%0, %1\",
9307 \"cmn%d4\\t%2, #%n3\"},
9308 {\"cmn%d5\\t%0, #%n1\",
9309 \"cmn%d4\\t%2, #%n3\"}
9311 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9316 \"cmn\\t%0, #%n1\"},
9317 {\"cmn\\t%2, #%n3\",
9319 {\"cmn\\t%2, #%n3\",
9322 static const char *const ite[2] =
9327 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9328 CMP_CMP, CMN_CMP, CMP_CMP,
9329 CMN_CMP, CMP_CMN, CMN_CMN};
9331 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9333 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9334 if (TARGET_THUMB2) {
9335 output_asm_insn (ite[swap], operands);
9337 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9340 [(set_attr "conds" "set")
9341 (set_attr "predicable" "no")
9342 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9343 (set_attr_alternative "length"
9349 (if_then_else (eq_attr "is_thumb" "no")
9352 (if_then_else (eq_attr "is_thumb" "no")
9355 (if_then_else (eq_attr "is_thumb" "no")
9358 (if_then_else (eq_attr "is_thumb" "no")
9361 (set_attr "type" "multiple")]
9364 (define_insn "*cmp_ior"
9365 [(set (match_operand 6 "dominant_cc_register" "")
9368 (match_operator 4 "arm_comparison_operator"
9369 [(match_operand:SI 0 "s_register_operand"
9370 "l,l,l,r,r,r,r,r,r")
9371 (match_operand:SI 1 "arm_add_operand"
9372 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9373 (match_operator:SI 5 "arm_comparison_operator"
9374 [(match_operand:SI 2 "s_register_operand"
9375 "l,r,r,l,l,r,r,r,r")
9376 (match_operand:SI 3 "arm_add_operand"
9377 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9382 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9386 {\"cmn\\t%0, #%n1\",
9389 \"cmn\\t%2, #%n3\"},
9390 {\"cmn\\t%0, #%n1\",
9393 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9395 {\"cmp%D4\\t%2, %3\",
9396 \"cmp%D5\\t%0, %1\"},
9397 {\"cmp%D4\\t%2, %3\",
9398 \"cmn%D5\\t%0, #%n1\"},
9399 {\"cmn%D4\\t%2, #%n3\",
9400 \"cmp%D5\\t%0, %1\"},
9401 {\"cmn%D4\\t%2, #%n3\",
9402 \"cmn%D5\\t%0, #%n1\"}
9404 static const char *const ite[2] =
9409 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9410 CMP_CMP, CMN_CMP, CMP_CMP,
9411 CMN_CMP, CMP_CMN, CMN_CMN};
9413 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9415 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9416 if (TARGET_THUMB2) {
9417 output_asm_insn (ite[swap], operands);
9419 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9423 [(set_attr "conds" "set")
9424 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9425 (set_attr_alternative "length"
9431 (if_then_else (eq_attr "is_thumb" "no")
9434 (if_then_else (eq_attr "is_thumb" "no")
9437 (if_then_else (eq_attr "is_thumb" "no")
9440 (if_then_else (eq_attr "is_thumb" "no")
9443 (set_attr "type" "multiple")]
9446 (define_insn_and_split "*ior_scc_scc"
9447 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9448 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9449 [(match_operand:SI 1 "s_register_operand" "r")
9450 (match_operand:SI 2 "arm_add_operand" "rIL")])
9451 (match_operator:SI 6 "arm_comparison_operator"
9452 [(match_operand:SI 4 "s_register_operand" "r")
9453 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9454 (clobber (reg:CC CC_REGNUM))]
9456 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9459 "TARGET_32BIT && reload_completed"
9463 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9464 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9466 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9468 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9471 [(set_attr "conds" "clob")
9472 (set_attr "length" "16")
9473 (set_attr "type" "multiple")]
9476 ; If the above pattern is followed by a CMP insn, then the compare is
9477 ; redundant, since we can rework the conditional instruction that follows.
9478 (define_insn_and_split "*ior_scc_scc_cmp"
9479 [(set (match_operand 0 "dominant_cc_register" "")
9480 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9481 [(match_operand:SI 1 "s_register_operand" "r")
9482 (match_operand:SI 2 "arm_add_operand" "rIL")])
9483 (match_operator:SI 6 "arm_comparison_operator"
9484 [(match_operand:SI 4 "s_register_operand" "r")
9485 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9487 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9488 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9489 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9492 "TARGET_32BIT && reload_completed"
9496 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9497 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9499 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9501 [(set_attr "conds" "set")
9502 (set_attr "length" "16")
9503 (set_attr "type" "multiple")]
9506 (define_insn_and_split "*and_scc_scc"
9507 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9508 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9509 [(match_operand:SI 1 "s_register_operand" "r")
9510 (match_operand:SI 2 "arm_add_operand" "rIL")])
9511 (match_operator:SI 6 "arm_comparison_operator"
9512 [(match_operand:SI 4 "s_register_operand" "r")
9513 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9514 (clobber (reg:CC CC_REGNUM))]
9516 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9519 "TARGET_32BIT && reload_completed
9520 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9525 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9526 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9528 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9530 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9533 [(set_attr "conds" "clob")
9534 (set_attr "length" "16")
9535 (set_attr "type" "multiple")]
9538 ; If the above pattern is followed by a CMP insn, then the compare is
9539 ; redundant, since we can rework the conditional instruction that follows.
9540 (define_insn_and_split "*and_scc_scc_cmp"
9541 [(set (match_operand 0 "dominant_cc_register" "")
9542 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9543 [(match_operand:SI 1 "s_register_operand" "r")
9544 (match_operand:SI 2 "arm_add_operand" "rIL")])
9545 (match_operator:SI 6 "arm_comparison_operator"
9546 [(match_operand:SI 4 "s_register_operand" "r")
9547 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9549 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9550 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9551 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9554 "TARGET_32BIT && reload_completed"
9558 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9559 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9561 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9563 [(set_attr "conds" "set")
9564 (set_attr "length" "16")
9565 (set_attr "type" "multiple")]
9568 ;; If there is no dominance in the comparison, then we can still save an
9569 ;; instruction in the AND case, since we can know that the second compare
9570 ;; need only zero the value if false (if true, then the value is already
9572 (define_insn_and_split "*and_scc_scc_nodom"
9573 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9574 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9575 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9576 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9577 (match_operator:SI 6 "arm_comparison_operator"
9578 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9579 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9580 (clobber (reg:CC CC_REGNUM))]
9582 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9585 "TARGET_32BIT && reload_completed"
9586 [(parallel [(set (match_dup 0)
9587 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9588 (clobber (reg:CC CC_REGNUM))])
9589 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9591 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9594 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9595 operands[4], operands[5]),
9597 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9599 [(set_attr "conds" "clob")
9600 (set_attr "length" "20")
9601 (set_attr "type" "multiple")]
9605 [(set (reg:CC_NOOV CC_REGNUM)
9606 (compare:CC_NOOV (ior:SI
9607 (and:SI (match_operand:SI 0 "s_register_operand" "")
9609 (match_operator:SI 1 "arm_comparison_operator"
9610 [(match_operand:SI 2 "s_register_operand" "")
9611 (match_operand:SI 3 "arm_add_operand" "")]))
9613 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9616 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9618 (set (reg:CC_NOOV CC_REGNUM)
9619 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9624 [(set (reg:CC_NOOV CC_REGNUM)
9625 (compare:CC_NOOV (ior:SI
9626 (match_operator:SI 1 "arm_comparison_operator"
9627 [(match_operand:SI 2 "s_register_operand" "")
9628 (match_operand:SI 3 "arm_add_operand" "")])
9629 (and:SI (match_operand:SI 0 "s_register_operand" "")
9632 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9635 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9637 (set (reg:CC_NOOV CC_REGNUM)
9638 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9641 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9643 (define_insn_and_split "*negscc"
9644 [(set (match_operand:SI 0 "s_register_operand" "=r")
9645 (neg:SI (match_operator 3 "arm_comparison_operator"
9646 [(match_operand:SI 1 "s_register_operand" "r")
9647 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9648 (clobber (reg:CC CC_REGNUM))]
9651 "&& reload_completed"
9654 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9656 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9658 /* Emit mov\\t%0, %1, asr #31 */
9659 emit_insn (gen_rtx_SET (operands[0],
9660 gen_rtx_ASHIFTRT (SImode,
9665 else if (GET_CODE (operands[3]) == NE)
9667 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9668 if (CONST_INT_P (operands[2]))
9669 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9670 GEN_INT (- INTVAL (operands[2]))));
9672 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9674 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9678 gen_rtx_SET (operands[0],
9684 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9685 emit_insn (gen_rtx_SET (cc_reg,
9686 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9687 enum rtx_code rc = GET_CODE (operands[3]);
9689 rc = reverse_condition (rc);
9690 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9695 gen_rtx_SET (operands[0], const0_rtx)));
9696 rc = GET_CODE (operands[3]);
9697 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9702 gen_rtx_SET (operands[0],
9708 [(set_attr "conds" "clob")
9709 (set_attr "length" "12")
9710 (set_attr "type" "multiple")]
9713 (define_insn_and_split "movcond_addsi"
9714 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9716 (match_operator 5 "comparison_operator"
9717 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9718 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9720 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9721 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9722 (clobber (reg:CC CC_REGNUM))]
9725 "&& reload_completed"
9726 [(set (reg:CC_NOOV CC_REGNUM)
9728 (plus:SI (match_dup 3)
9731 (set (match_dup 0) (match_dup 1))
9732 (cond_exec (match_dup 6)
9733 (set (match_dup 0) (match_dup 2)))]
9736 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9737 operands[3], operands[4]);
9738 enum rtx_code rc = GET_CODE (operands[5]);
9739 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9740 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9741 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9742 rc = reverse_condition (rc);
9744 std::swap (operands[1], operands[2]);
9746 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9749 [(set_attr "conds" "clob")
9750 (set_attr "enabled_for_depr_it" "no,yes,yes")
9751 (set_attr "type" "multiple")]
9754 (define_insn "movcond"
9755 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9757 (match_operator 5 "arm_comparison_operator"
9758 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9759 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9760 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9761 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9762 (clobber (reg:CC CC_REGNUM))]
9765 if (GET_CODE (operands[5]) == LT
9766 && (operands[4] == const0_rtx))
9768 if (which_alternative != 1 && REG_P (operands[1]))
9770 if (operands[2] == const0_rtx)
9771 return \"and\\t%0, %1, %3, asr #31\";
9772 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9774 else if (which_alternative != 0 && REG_P (operands[2]))
9776 if (operands[1] == const0_rtx)
9777 return \"bic\\t%0, %2, %3, asr #31\";
9778 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9780 /* The only case that falls through to here is when both ops 1 & 2
9784 if (GET_CODE (operands[5]) == GE
9785 && (operands[4] == const0_rtx))
9787 if (which_alternative != 1 && REG_P (operands[1]))
9789 if (operands[2] == const0_rtx)
9790 return \"bic\\t%0, %1, %3, asr #31\";
9791 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9793 else if (which_alternative != 0 && REG_P (operands[2]))
9795 if (operands[1] == const0_rtx)
9796 return \"and\\t%0, %2, %3, asr #31\";
9797 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9799 /* The only case that falls through to here is when both ops 1 & 2
9802 if (CONST_INT_P (operands[4])
9803 && !const_ok_for_arm (INTVAL (operands[4])))
9804 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9806 output_asm_insn (\"cmp\\t%3, %4\", operands);
9807 if (which_alternative != 0)
9808 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9809 if (which_alternative != 1)
9810 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9813 [(set_attr "conds" "clob")
9814 (set_attr "length" "8,8,12")
9815 (set_attr "type" "multiple")]
9818 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9820 (define_insn "*ifcompare_plus_move"
9821 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9822 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9823 [(match_operand:SI 4 "s_register_operand" "r,r")
9824 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9826 (match_operand:SI 2 "s_register_operand" "r,r")
9827 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9828 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9829 (clobber (reg:CC CC_REGNUM))]
9832 [(set_attr "conds" "clob")
9833 (set_attr "length" "8,12")
9834 (set_attr "type" "multiple")]
9837 (define_insn "*if_plus_move"
9838 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9840 (match_operator 4 "arm_comparison_operator"
9841 [(match_operand 5 "cc_register" "") (const_int 0)])
9843 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9844 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9845 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9849 sub%d4\\t%0, %2, #%n3
9850 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9851 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9852 [(set_attr "conds" "use")
9853 (set_attr "length" "4,4,8,8")
9854 (set_attr_alternative "type"
9855 [(if_then_else (match_operand 3 "const_int_operand" "")
9856 (const_string "alu_imm" )
9857 (const_string "alu_sreg"))
9858 (const_string "alu_imm")
9859 (const_string "multiple")
9860 (const_string "multiple")])]
9863 (define_insn "*ifcompare_move_plus"
9864 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9865 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9866 [(match_operand:SI 4 "s_register_operand" "r,r")
9867 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9868 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9870 (match_operand:SI 2 "s_register_operand" "r,r")
9871 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9872 (clobber (reg:CC CC_REGNUM))]
9875 [(set_attr "conds" "clob")
9876 (set_attr "length" "8,12")
9877 (set_attr "type" "multiple")]
9880 (define_insn "*if_move_plus"
9881 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9883 (match_operator 4 "arm_comparison_operator"
9884 [(match_operand 5 "cc_register" "") (const_int 0)])
9885 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9887 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9888 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9892 sub%D4\\t%0, %2, #%n3
9893 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9894 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9895 [(set_attr "conds" "use")
9896 (set_attr "length" "4,4,8,8")
9897 (set_attr_alternative "type"
9898 [(if_then_else (match_operand 3 "const_int_operand" "")
9899 (const_string "alu_imm" )
9900 (const_string "alu_sreg"))
9901 (const_string "alu_imm")
9902 (const_string "multiple")
9903 (const_string "multiple")])]
9906 (define_insn "*ifcompare_arith_arith"
9907 [(set (match_operand:SI 0 "s_register_operand" "=r")
9908 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9909 [(match_operand:SI 5 "s_register_operand" "r")
9910 (match_operand:SI 6 "arm_add_operand" "rIL")])
9911 (match_operator:SI 8 "shiftable_operator"
9912 [(match_operand:SI 1 "s_register_operand" "r")
9913 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9914 (match_operator:SI 7 "shiftable_operator"
9915 [(match_operand:SI 3 "s_register_operand" "r")
9916 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9917 (clobber (reg:CC CC_REGNUM))]
9920 [(set_attr "conds" "clob")
9921 (set_attr "length" "12")
9922 (set_attr "type" "multiple")]
9925 (define_insn "*if_arith_arith"
9926 [(set (match_operand:SI 0 "s_register_operand" "=r")
9927 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9928 [(match_operand 8 "cc_register" "") (const_int 0)])
9929 (match_operator:SI 6 "shiftable_operator"
9930 [(match_operand:SI 1 "s_register_operand" "r")
9931 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9932 (match_operator:SI 7 "shiftable_operator"
9933 [(match_operand:SI 3 "s_register_operand" "r")
9934 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9936 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9937 [(set_attr "conds" "use")
9938 (set_attr "length" "8")
9939 (set_attr "type" "multiple")]
9942 (define_insn "*ifcompare_arith_move"
9943 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9944 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9945 [(match_operand:SI 2 "s_register_operand" "r,r")
9946 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9947 (match_operator:SI 7 "shiftable_operator"
9948 [(match_operand:SI 4 "s_register_operand" "r,r")
9949 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9950 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9951 (clobber (reg:CC CC_REGNUM))]
9954 /* If we have an operation where (op x 0) is the identity operation and
9955 the conditional operator is LT or GE and we are comparing against zero and
9956 everything is in registers then we can do this in two instructions. */
9957 if (operands[3] == const0_rtx
9958 && GET_CODE (operands[7]) != AND
9959 && REG_P (operands[5])
9960 && REG_P (operands[1])
9961 && REGNO (operands[1]) == REGNO (operands[4])
9962 && REGNO (operands[4]) != REGNO (operands[0]))
9964 if (GET_CODE (operands[6]) == LT)
9965 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9966 else if (GET_CODE (operands[6]) == GE)
9967 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9969 if (CONST_INT_P (operands[3])
9970 && !const_ok_for_arm (INTVAL (operands[3])))
9971 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9973 output_asm_insn (\"cmp\\t%2, %3\", operands);
9974 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9975 if (which_alternative != 0)
9976 return \"mov%D6\\t%0, %1\";
9979 [(set_attr "conds" "clob")
9980 (set_attr "length" "8,12")
9981 (set_attr "type" "multiple")]
9984 (define_insn "*if_arith_move"
9985 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9986 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9987 [(match_operand 6 "cc_register" "") (const_int 0)])
9988 (match_operator:SI 5 "shiftable_operator"
9989 [(match_operand:SI 2 "s_register_operand" "r,r")
9990 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9991 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9995 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9996 [(set_attr "conds" "use")
9997 (set_attr "length" "4,8")
9998 (set_attr_alternative "type"
9999 [(if_then_else (match_operand 3 "const_int_operand" "")
10000 (const_string "alu_shift_imm" )
10001 (const_string "alu_shift_reg"))
10002 (const_string "multiple")])]
10005 (define_insn "*ifcompare_move_arith"
10006 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10007 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10008 [(match_operand:SI 4 "s_register_operand" "r,r")
10009 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10010 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10011 (match_operator:SI 7 "shiftable_operator"
10012 [(match_operand:SI 2 "s_register_operand" "r,r")
10013 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10014 (clobber (reg:CC CC_REGNUM))]
10017 /* If we have an operation where (op x 0) is the identity operation and
10018 the conditional operator is LT or GE and we are comparing against zero and
10019 everything is in registers then we can do this in two instructions */
10020 if (operands[5] == const0_rtx
10021 && GET_CODE (operands[7]) != AND
10022 && REG_P (operands[3])
10023 && REG_P (operands[1])
10024 && REGNO (operands[1]) == REGNO (operands[2])
10025 && REGNO (operands[2]) != REGNO (operands[0]))
10027 if (GET_CODE (operands[6]) == GE)
10028 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10029 else if (GET_CODE (operands[6]) == LT)
10030 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10033 if (CONST_INT_P (operands[5])
10034 && !const_ok_for_arm (INTVAL (operands[5])))
10035 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10037 output_asm_insn (\"cmp\\t%4, %5\", operands);
10039 if (which_alternative != 0)
10040 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10041 return \"%I7%D6\\t%0, %2, %3\";
10043 [(set_attr "conds" "clob")
10044 (set_attr "length" "8,12")
10045 (set_attr "type" "multiple")]
10048 (define_insn "*if_move_arith"
10049 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10051 (match_operator 4 "arm_comparison_operator"
10052 [(match_operand 6 "cc_register" "") (const_int 0)])
10053 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10054 (match_operator:SI 5 "shiftable_operator"
10055 [(match_operand:SI 2 "s_register_operand" "r,r")
10056 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10059 %I5%D4\\t%0, %2, %3
10060 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10061 [(set_attr "conds" "use")
10062 (set_attr "length" "4,8")
10063 (set_attr_alternative "type"
10064 [(if_then_else (match_operand 3 "const_int_operand" "")
10065 (const_string "alu_shift_imm" )
10066 (const_string "alu_shift_reg"))
10067 (const_string "multiple")])]
10070 (define_insn "*ifcompare_move_not"
10071 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10073 (match_operator 5 "arm_comparison_operator"
10074 [(match_operand:SI 3 "s_register_operand" "r,r")
10075 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10076 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10078 (match_operand:SI 2 "s_register_operand" "r,r"))))
10079 (clobber (reg:CC CC_REGNUM))]
10082 [(set_attr "conds" "clob")
10083 (set_attr "length" "8,12")
10084 (set_attr "type" "multiple")]
10087 (define_insn "*if_move_not"
10088 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10090 (match_operator 4 "arm_comparison_operator"
10091 [(match_operand 3 "cc_register" "") (const_int 0)])
10092 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10093 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10097 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10098 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10099 [(set_attr "conds" "use")
10100 (set_attr "type" "mvn_reg")
10101 (set_attr "length" "4,8,8")
10102 (set_attr "type" "mvn_reg,multiple,multiple")]
10105 (define_insn "*ifcompare_not_move"
10106 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10108 (match_operator 5 "arm_comparison_operator"
10109 [(match_operand:SI 3 "s_register_operand" "r,r")
10110 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10112 (match_operand:SI 2 "s_register_operand" "r,r"))
10113 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10114 (clobber (reg:CC CC_REGNUM))]
10117 [(set_attr "conds" "clob")
10118 (set_attr "length" "8,12")
10119 (set_attr "type" "multiple")]
10122 (define_insn "*if_not_move"
10123 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10125 (match_operator 4 "arm_comparison_operator"
10126 [(match_operand 3 "cc_register" "") (const_int 0)])
10127 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10128 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10132 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10133 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10134 [(set_attr "conds" "use")
10135 (set_attr "type" "mvn_reg,multiple,multiple")
10136 (set_attr "length" "4,8,8")]
10139 (define_insn "*ifcompare_shift_move"
10140 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10142 (match_operator 6 "arm_comparison_operator"
10143 [(match_operand:SI 4 "s_register_operand" "r,r")
10144 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10145 (match_operator:SI 7 "shift_operator"
10146 [(match_operand:SI 2 "s_register_operand" "r,r")
10147 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10148 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10149 (clobber (reg:CC CC_REGNUM))]
10152 [(set_attr "conds" "clob")
10153 (set_attr "length" "8,12")
10154 (set_attr "type" "multiple")]
10157 (define_insn "*if_shift_move"
10158 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10160 (match_operator 5 "arm_comparison_operator"
10161 [(match_operand 6 "cc_register" "") (const_int 0)])
10162 (match_operator:SI 4 "shift_operator"
10163 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10164 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10165 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10169 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10170 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10171 [(set_attr "conds" "use")
10172 (set_attr "shift" "2")
10173 (set_attr "length" "4,8,8")
10174 (set_attr_alternative "type"
10175 [(if_then_else (match_operand 3 "const_int_operand" "")
10176 (const_string "mov_shift" )
10177 (const_string "mov_shift_reg"))
10178 (const_string "multiple")
10179 (const_string "multiple")])]
10182 (define_insn "*ifcompare_move_shift"
10183 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10185 (match_operator 6 "arm_comparison_operator"
10186 [(match_operand:SI 4 "s_register_operand" "r,r")
10187 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10188 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10189 (match_operator:SI 7 "shift_operator"
10190 [(match_operand:SI 2 "s_register_operand" "r,r")
10191 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10192 (clobber (reg:CC CC_REGNUM))]
10195 [(set_attr "conds" "clob")
10196 (set_attr "length" "8,12")
10197 (set_attr "type" "multiple")]
10200 (define_insn "*if_move_shift"
10201 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10203 (match_operator 5 "arm_comparison_operator"
10204 [(match_operand 6 "cc_register" "") (const_int 0)])
10205 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10206 (match_operator:SI 4 "shift_operator"
10207 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10208 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10212 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10213 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10214 [(set_attr "conds" "use")
10215 (set_attr "shift" "2")
10216 (set_attr "length" "4,8,8")
10217 (set_attr_alternative "type"
10218 [(if_then_else (match_operand 3 "const_int_operand" "")
10219 (const_string "mov_shift" )
10220 (const_string "mov_shift_reg"))
10221 (const_string "multiple")
10222 (const_string "multiple")])]
10225 (define_insn "*ifcompare_shift_shift"
10226 [(set (match_operand:SI 0 "s_register_operand" "=r")
10228 (match_operator 7 "arm_comparison_operator"
10229 [(match_operand:SI 5 "s_register_operand" "r")
10230 (match_operand:SI 6 "arm_add_operand" "rIL")])
10231 (match_operator:SI 8 "shift_operator"
10232 [(match_operand:SI 1 "s_register_operand" "r")
10233 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10234 (match_operator:SI 9 "shift_operator"
10235 [(match_operand:SI 3 "s_register_operand" "r")
10236 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10237 (clobber (reg:CC CC_REGNUM))]
10240 [(set_attr "conds" "clob")
10241 (set_attr "length" "12")
10242 (set_attr "type" "multiple")]
10245 (define_insn "*if_shift_shift"
10246 [(set (match_operand:SI 0 "s_register_operand" "=r")
10248 (match_operator 5 "arm_comparison_operator"
10249 [(match_operand 8 "cc_register" "") (const_int 0)])
10250 (match_operator:SI 6 "shift_operator"
10251 [(match_operand:SI 1 "s_register_operand" "r")
10252 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10253 (match_operator:SI 7 "shift_operator"
10254 [(match_operand:SI 3 "s_register_operand" "r")
10255 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10257 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10258 [(set_attr "conds" "use")
10259 (set_attr "shift" "1")
10260 (set_attr "length" "8")
10261 (set (attr "type") (if_then_else
10262 (and (match_operand 2 "const_int_operand" "")
10263 (match_operand 4 "const_int_operand" ""))
10264 (const_string "mov_shift")
10265 (const_string "mov_shift_reg")))]
10268 (define_insn "*ifcompare_not_arith"
10269 [(set (match_operand:SI 0 "s_register_operand" "=r")
10271 (match_operator 6 "arm_comparison_operator"
10272 [(match_operand:SI 4 "s_register_operand" "r")
10273 (match_operand:SI 5 "arm_add_operand" "rIL")])
10274 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10275 (match_operator:SI 7 "shiftable_operator"
10276 [(match_operand:SI 2 "s_register_operand" "r")
10277 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10278 (clobber (reg:CC CC_REGNUM))]
10281 [(set_attr "conds" "clob")
10282 (set_attr "length" "12")
10283 (set_attr "type" "multiple")]
10286 (define_insn "*if_not_arith"
10287 [(set (match_operand:SI 0 "s_register_operand" "=r")
10289 (match_operator 5 "arm_comparison_operator"
10290 [(match_operand 4 "cc_register" "") (const_int 0)])
10291 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10292 (match_operator:SI 6 "shiftable_operator"
10293 [(match_operand:SI 2 "s_register_operand" "r")
10294 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10296 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10297 [(set_attr "conds" "use")
10298 (set_attr "type" "mvn_reg")
10299 (set_attr "length" "8")]
10302 (define_insn "*ifcompare_arith_not"
10303 [(set (match_operand:SI 0 "s_register_operand" "=r")
10305 (match_operator 6 "arm_comparison_operator"
10306 [(match_operand:SI 4 "s_register_operand" "r")
10307 (match_operand:SI 5 "arm_add_operand" "rIL")])
10308 (match_operator:SI 7 "shiftable_operator"
10309 [(match_operand:SI 2 "s_register_operand" "r")
10310 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10311 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10312 (clobber (reg:CC CC_REGNUM))]
10315 [(set_attr "conds" "clob")
10316 (set_attr "length" "12")
10317 (set_attr "type" "multiple")]
10320 (define_insn "*if_arith_not"
10321 [(set (match_operand:SI 0 "s_register_operand" "=r")
10323 (match_operator 5 "arm_comparison_operator"
10324 [(match_operand 4 "cc_register" "") (const_int 0)])
10325 (match_operator:SI 6 "shiftable_operator"
10326 [(match_operand:SI 2 "s_register_operand" "r")
10327 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10328 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10330 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10331 [(set_attr "conds" "use")
10332 (set_attr "type" "multiple")
10333 (set_attr "length" "8")]
10336 (define_insn "*ifcompare_neg_move"
10337 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10339 (match_operator 5 "arm_comparison_operator"
10340 [(match_operand:SI 3 "s_register_operand" "r,r")
10341 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10342 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10343 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10344 (clobber (reg:CC CC_REGNUM))]
10347 [(set_attr "conds" "clob")
10348 (set_attr "length" "8,12")
10349 (set_attr "type" "multiple")]
10352 (define_insn_and_split "*if_neg_move"
10353 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10355 (match_operator 4 "arm_comparison_operator"
10356 [(match_operand 3 "cc_register" "") (const_int 0)])
10357 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10358 (match_operand:SI 1 "s_register_operand" "0,0")))]
10361 "&& reload_completed"
10362 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10363 (set (match_dup 0) (neg:SI (match_dup 2))))]
10365 [(set_attr "conds" "use")
10366 (set_attr "length" "4")
10367 (set_attr "arch" "t2,32")
10368 (set_attr "enabled_for_depr_it" "yes,no")
10369 (set_attr "type" "logic_shift_imm")]
10372 (define_insn "*ifcompare_move_neg"
10373 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10375 (match_operator 5 "arm_comparison_operator"
10376 [(match_operand:SI 3 "s_register_operand" "r,r")
10377 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10378 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10379 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10380 (clobber (reg:CC CC_REGNUM))]
10383 [(set_attr "conds" "clob")
10384 (set_attr "length" "8,12")
10385 (set_attr "type" "multiple")]
10388 (define_insn_and_split "*if_move_neg"
10389 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10391 (match_operator 4 "arm_comparison_operator"
10392 [(match_operand 3 "cc_register" "") (const_int 0)])
10393 (match_operand:SI 1 "s_register_operand" "0,0")
10394 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10397 "&& reload_completed"
10398 [(cond_exec (match_dup 5)
10399 (set (match_dup 0) (neg:SI (match_dup 2))))]
10401 machine_mode mode = GET_MODE (operands[3]);
10402 rtx_code rc = GET_CODE (operands[4]);
10404 if (mode == CCFPmode || mode == CCFPEmode)
10405 rc = reverse_condition_maybe_unordered (rc);
10407 rc = reverse_condition (rc);
10409 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10411 [(set_attr "conds" "use")
10412 (set_attr "length" "4")
10413 (set_attr "arch" "t2,32")
10414 (set_attr "enabled_for_depr_it" "yes,no")
10415 (set_attr "type" "logic_shift_imm")]
10418 (define_insn "*arith_adjacentmem"
10419 [(set (match_operand:SI 0 "s_register_operand" "=r")
10420 (match_operator:SI 1 "shiftable_operator"
10421 [(match_operand:SI 2 "memory_operand" "m")
10422 (match_operand:SI 3 "memory_operand" "m")]))
10423 (clobber (match_scratch:SI 4 "=r"))]
10424 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10430 HOST_WIDE_INT val1 = 0, val2 = 0;
10432 if (REGNO (operands[0]) > REGNO (operands[4]))
10434 ldm[1] = operands[4];
10435 ldm[2] = operands[0];
10439 ldm[1] = operands[0];
10440 ldm[2] = operands[4];
10443 base_reg = XEXP (operands[2], 0);
10445 if (!REG_P (base_reg))
10447 val1 = INTVAL (XEXP (base_reg, 1));
10448 base_reg = XEXP (base_reg, 0);
10451 if (!REG_P (XEXP (operands[3], 0)))
10452 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10454 arith[0] = operands[0];
10455 arith[3] = operands[1];
10469 if (val1 !=0 && val2 != 0)
10473 if (val1 == 4 || val2 == 4)
10474 /* Other val must be 8, since we know they are adjacent and neither
10476 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10477 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10479 ldm[0] = ops[0] = operands[4];
10481 ops[2] = GEN_INT (val1);
10482 output_add_immediate (ops);
10484 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10486 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10490 /* Offset is out of range for a single add, so use two ldr. */
10493 ops[2] = GEN_INT (val1);
10494 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10496 ops[2] = GEN_INT (val2);
10497 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10500 else if (val1 != 0)
10503 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10505 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10510 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10512 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10514 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10517 [(set_attr "length" "12")
10518 (set_attr "predicable" "yes")
10519 (set_attr "type" "load1")]
10522 ; This pattern is never tried by combine, so do it as a peephole
10525 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10526 (match_operand:SI 1 "arm_general_register_operand" ""))
10527 (set (reg:CC CC_REGNUM)
10528 (compare:CC (match_dup 1) (const_int 0)))]
10530 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10531 (set (match_dup 0) (match_dup 1))])]
10536 [(set (match_operand:SI 0 "s_register_operand" "")
10537 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10539 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10540 [(match_operand:SI 3 "s_register_operand" "")
10541 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10542 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10544 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10545 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10550 ;; This split can be used because CC_Z mode implies that the following
10551 ;; branch will be an equality, or an unsigned inequality, so the sign
10552 ;; extension is not needed.
10555 [(set (reg:CC_Z CC_REGNUM)
10557 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10559 (match_operand 1 "const_int_operand" "")))
10560 (clobber (match_scratch:SI 2 ""))]
10562 && ((UINTVAL (operands[1]))
10563 == ((UINTVAL (operands[1])) >> 24) << 24)"
10564 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10565 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10567 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10570 ;; ??? Check the patterns above for Thumb-2 usefulness
10572 (define_expand "prologue"
10573 [(clobber (const_int 0))]
10576 arm_expand_prologue ();
10578 thumb1_expand_prologue ();
10583 (define_expand "epilogue"
10584 [(clobber (const_int 0))]
10587 if (crtl->calls_eh_return)
10588 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10591 thumb1_expand_epilogue ();
10592 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10593 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10595 else if (HAVE_return)
10597 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10598 no need for explicit testing again. */
10599 emit_jump_insn (gen_return ());
10601 else if (TARGET_32BIT)
10603 arm_expand_epilogue (true);
10609 ;; Note - although unspec_volatile's USE all hard registers,
10610 ;; USEs are ignored after relaod has completed. Thus we need
10611 ;; to add an unspec of the link register to ensure that flow
10612 ;; does not think that it is unused by the sibcall branch that
10613 ;; will replace the standard function epilogue.
10614 (define_expand "sibcall_epilogue"
10615 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10616 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10619 arm_expand_epilogue (false);
10624 (define_expand "eh_epilogue"
10625 [(use (match_operand:SI 0 "register_operand" ""))
10626 (use (match_operand:SI 1 "register_operand" ""))
10627 (use (match_operand:SI 2 "register_operand" ""))]
10631 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10632 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10634 rtx ra = gen_rtx_REG (Pmode, 2);
10636 emit_move_insn (ra, operands[2]);
10639 /* This is a hack -- we may have crystalized the function type too
10641 cfun->machine->func_type = 0;
10645 ;; This split is only used during output to reduce the number of patterns
10646 ;; that need assembler instructions adding to them. We allowed the setting
10647 ;; of the conditions to be implicit during rtl generation so that
10648 ;; the conditional compare patterns would work. However this conflicts to
10649 ;; some extent with the conditional data operations, so we have to split them
10652 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10653 ;; conditional execution sufficient?
10656 [(set (match_operand:SI 0 "s_register_operand" "")
10657 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10658 [(match_operand 2 "" "") (match_operand 3 "" "")])
10660 (match_operand 4 "" "")))
10661 (clobber (reg:CC CC_REGNUM))]
10662 "TARGET_ARM && reload_completed"
10663 [(set (match_dup 5) (match_dup 6))
10664 (cond_exec (match_dup 7)
10665 (set (match_dup 0) (match_dup 4)))]
10668 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10669 operands[2], operands[3]);
10670 enum rtx_code rc = GET_CODE (operands[1]);
10672 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10673 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10674 if (mode == CCFPmode || mode == CCFPEmode)
10675 rc = reverse_condition_maybe_unordered (rc);
10677 rc = reverse_condition (rc);
10679 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10684 [(set (match_operand:SI 0 "s_register_operand" "")
10685 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10686 [(match_operand 2 "" "") (match_operand 3 "" "")])
10687 (match_operand 4 "" "")
10689 (clobber (reg:CC CC_REGNUM))]
10690 "TARGET_ARM && reload_completed"
10691 [(set (match_dup 5) (match_dup 6))
10692 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10693 (set (match_dup 0) (match_dup 4)))]
10696 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10697 operands[2], operands[3]);
10699 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10700 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10705 [(set (match_operand:SI 0 "s_register_operand" "")
10706 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10707 [(match_operand 2 "" "") (match_operand 3 "" "")])
10708 (match_operand 4 "" "")
10709 (match_operand 5 "" "")))
10710 (clobber (reg:CC CC_REGNUM))]
10711 "TARGET_ARM && reload_completed"
10712 [(set (match_dup 6) (match_dup 7))
10713 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10714 (set (match_dup 0) (match_dup 4)))
10715 (cond_exec (match_dup 8)
10716 (set (match_dup 0) (match_dup 5)))]
10719 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10720 operands[2], operands[3]);
10721 enum rtx_code rc = GET_CODE (operands[1]);
10723 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10724 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10725 if (mode == CCFPmode || mode == CCFPEmode)
10726 rc = reverse_condition_maybe_unordered (rc);
10728 rc = reverse_condition (rc);
10730 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10735 [(set (match_operand:SI 0 "s_register_operand" "")
10736 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10737 [(match_operand:SI 2 "s_register_operand" "")
10738 (match_operand:SI 3 "arm_add_operand" "")])
10739 (match_operand:SI 4 "arm_rhs_operand" "")
10741 (match_operand:SI 5 "s_register_operand" ""))))
10742 (clobber (reg:CC CC_REGNUM))]
10743 "TARGET_ARM && reload_completed"
10744 [(set (match_dup 6) (match_dup 7))
10745 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10746 (set (match_dup 0) (match_dup 4)))
10747 (cond_exec (match_dup 8)
10748 (set (match_dup 0) (not:SI (match_dup 5))))]
10751 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10752 operands[2], operands[3]);
10753 enum rtx_code rc = GET_CODE (operands[1]);
10755 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10756 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10757 if (mode == CCFPmode || mode == CCFPEmode)
10758 rc = reverse_condition_maybe_unordered (rc);
10760 rc = reverse_condition (rc);
10762 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10766 (define_insn "*cond_move_not"
10767 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10768 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10769 [(match_operand 3 "cc_register" "") (const_int 0)])
10770 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10772 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10776 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10777 [(set_attr "conds" "use")
10778 (set_attr "type" "mvn_reg,multiple")
10779 (set_attr "length" "4,8")]
10782 ;; The next two patterns occur when an AND operation is followed by a
10783 ;; scc insn sequence
10785 (define_insn "*sign_extract_onebit"
10786 [(set (match_operand:SI 0 "s_register_operand" "=r")
10787 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10789 (match_operand:SI 2 "const_int_operand" "n")))
10790 (clobber (reg:CC CC_REGNUM))]
10793 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10794 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10795 return \"mvnne\\t%0, #0\";
10797 [(set_attr "conds" "clob")
10798 (set_attr "length" "8")
10799 (set_attr "type" "multiple")]
10802 (define_insn "*not_signextract_onebit"
10803 [(set (match_operand:SI 0 "s_register_operand" "=r")
10805 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10807 (match_operand:SI 2 "const_int_operand" "n"))))
10808 (clobber (reg:CC CC_REGNUM))]
10811 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10812 output_asm_insn (\"tst\\t%1, %2\", operands);
10813 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10814 return \"movne\\t%0, #0\";
10816 [(set_attr "conds" "clob")
10817 (set_attr "length" "12")
10818 (set_attr "type" "multiple")]
10820 ;; ??? The above patterns need auditing for Thumb-2
10822 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10823 ;; expressions. For simplicity, the first register is also in the unspec
10825 ;; To avoid the usage of GNU extension, the length attribute is computed
10826 ;; in a C function arm_attr_length_push_multi.
10827 (define_insn "*push_multi"
10828 [(match_parallel 2 "multi_register_push"
10829 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10830 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10831 UNSPEC_PUSH_MULT))])]
10835 int num_saves = XVECLEN (operands[2], 0);
10837 /* For the StrongARM at least it is faster to
10838 use STR to store only a single register.
10839 In Thumb mode always use push, and the assembler will pick
10840 something appropriate. */
10841 if (num_saves == 1 && TARGET_ARM)
10842 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10849 strcpy (pattern, \"push%?\\t{%1\");
10851 strcpy (pattern, \"push\\t{%1\");
10853 for (i = 1; i < num_saves; i++)
10855 strcat (pattern, \", %|\");
10857 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10860 strcat (pattern, \"}\");
10861 output_asm_insn (pattern, operands);
10866 [(set_attr "type" "store4")
10867 (set (attr "length")
10868 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10871 (define_insn "stack_tie"
10872 [(set (mem:BLK (scratch))
10873 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10874 (match_operand:SI 1 "s_register_operand" "rk")]
10878 [(set_attr "length" "0")
10879 (set_attr "type" "block")]
10882 ;; Pop (as used in epilogue RTL)
10884 (define_insn "*load_multiple_with_writeback"
10885 [(match_parallel 0 "load_multiple_operation"
10886 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10887 (plus:SI (match_dup 1)
10888 (match_operand:SI 2 "const_int_I_operand" "I")))
10889 (set (match_operand:SI 3 "s_register_operand" "=rk")
10890 (mem:SI (match_dup 1)))
10892 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10895 arm_output_multireg_pop (operands, /*return_pc=*/false,
10896 /*cond=*/const_true_rtx,
10902 [(set_attr "type" "load4")
10903 (set_attr "predicable" "yes")
10904 (set (attr "length")
10905 (symbol_ref "arm_attr_length_pop_multi (operands,
10906 /*return_pc=*/false,
10907 /*write_back_p=*/true)"))]
10910 ;; Pop with return (as used in epilogue RTL)
10912 ;; This instruction is generated when the registers are popped at the end of
10913 ;; epilogue. Here, instead of popping the value into LR and then generating
10914 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10916 (define_insn "*pop_multiple_with_writeback_and_return"
10917 [(match_parallel 0 "pop_multiple_return"
10919 (set (match_operand:SI 1 "s_register_operand" "+rk")
10920 (plus:SI (match_dup 1)
10921 (match_operand:SI 2 "const_int_I_operand" "I")))
10922 (set (match_operand:SI 3 "s_register_operand" "=rk")
10923 (mem:SI (match_dup 1)))
10925 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10928 arm_output_multireg_pop (operands, /*return_pc=*/true,
10929 /*cond=*/const_true_rtx,
10935 [(set_attr "type" "load4")
10936 (set_attr "predicable" "yes")
10937 (set (attr "length")
10938 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10939 /*write_back_p=*/true)"))]
10942 (define_insn "*pop_multiple_with_return"
10943 [(match_parallel 0 "pop_multiple_return"
10945 (set (match_operand:SI 2 "s_register_operand" "=rk")
10946 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10948 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10951 arm_output_multireg_pop (operands, /*return_pc=*/true,
10952 /*cond=*/const_true_rtx,
10958 [(set_attr "type" "load4")
10959 (set_attr "predicable" "yes")
10960 (set (attr "length")
10961 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10962 /*write_back_p=*/false)"))]
10965 ;; Load into PC and return
10966 (define_insn "*ldr_with_return"
10968 (set (reg:SI PC_REGNUM)
10969 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10970 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10971 "ldr%?\t%|pc, [%0], #4"
10972 [(set_attr "type" "load1")
10973 (set_attr "predicable" "yes")]
10975 ;; Pop for floating point registers (as used in epilogue RTL)
10976 (define_insn "*vfp_pop_multiple_with_writeback"
10977 [(match_parallel 0 "pop_multiple_fp"
10978 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10979 (plus:SI (match_dup 1)
10980 (match_operand:SI 2 "const_int_I_operand" "I")))
10981 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10982 (mem:DF (match_dup 1)))])]
10983 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10986 int num_regs = XVECLEN (operands[0], 0);
10989 strcpy (pattern, \"vldm\\t\");
10990 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10991 strcat (pattern, \"!, {\");
10992 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10993 strcat (pattern, \"%P0\");
10994 if ((num_regs - 1) > 1)
10996 strcat (pattern, \"-%P1\");
10997 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11000 strcat (pattern, \"}\");
11001 output_asm_insn (pattern, op_list);
11005 [(set_attr "type" "load4")
11006 (set_attr "conds" "unconditional")
11007 (set_attr "predicable" "no")]
11010 ;; Special patterns for dealing with the constant pool
11012 (define_insn "align_4"
11013 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11016 assemble_align (32);
11019 [(set_attr "type" "no_insn")]
11022 (define_insn "align_8"
11023 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11026 assemble_align (64);
11029 [(set_attr "type" "no_insn")]
11032 (define_insn "consttable_end"
11033 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11036 making_const_table = FALSE;
11039 [(set_attr "type" "no_insn")]
11042 (define_insn "consttable_1"
11043 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11046 making_const_table = TRUE;
11047 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11048 assemble_zeros (3);
11051 [(set_attr "length" "4")
11052 (set_attr "type" "no_insn")]
11055 (define_insn "consttable_2"
11056 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11060 rtx x = operands[0];
11061 making_const_table = TRUE;
11062 switch (GET_MODE_CLASS (GET_MODE (x)))
11065 arm_emit_fp16_const (x);
11068 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11069 assemble_zeros (2);
11074 [(set_attr "length" "4")
11075 (set_attr "type" "no_insn")]
11078 (define_insn "consttable_4"
11079 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11083 rtx x = operands[0];
11084 making_const_table = TRUE;
11085 switch (GET_MODE_CLASS (GET_MODE (x)))
11088 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
11092 /* XXX: Sometimes gcc does something really dumb and ends up with
11093 a HIGH in a constant pool entry, usually because it's trying to
11094 load into a VFP register. We know this will always be used in
11095 combination with a LO_SUM which ignores the high bits, so just
11096 strip off the HIGH. */
11097 if (GET_CODE (x) == HIGH)
11099 assemble_integer (x, 4, BITS_PER_WORD, 1);
11100 mark_symbol_refs_as_used (x);
11105 [(set_attr "length" "4")
11106 (set_attr "type" "no_insn")]
11109 (define_insn "consttable_8"
11110 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11114 making_const_table = TRUE;
11115 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11118 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11119 GET_MODE (operands[0]), BITS_PER_WORD);
11122 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11127 [(set_attr "length" "8")
11128 (set_attr "type" "no_insn")]
11131 (define_insn "consttable_16"
11132 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11136 making_const_table = TRUE;
11137 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11140 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11141 GET_MODE (operands[0]), BITS_PER_WORD);
11144 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11149 [(set_attr "length" "16")
11150 (set_attr "type" "no_insn")]
11153 ;; V5 Instructions,
11155 (define_insn "clzsi2"
11156 [(set (match_operand:SI 0 "s_register_operand" "=r")
11157 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11158 "TARGET_32BIT && arm_arch5"
11160 [(set_attr "predicable" "yes")
11161 (set_attr "predicable_short_it" "no")
11162 (set_attr "type" "clz")])
11164 (define_insn "rbitsi2"
11165 [(set (match_operand:SI 0 "s_register_operand" "=r")
11166 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11167 "TARGET_32BIT && arm_arch_thumb2"
11169 [(set_attr "predicable" "yes")
11170 (set_attr "predicable_short_it" "no")
11171 (set_attr "type" "clz")])
11173 ;; Keep this as a CTZ expression until after reload and then split
11174 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11175 ;; to fold with any other expression.
11177 (define_insn_and_split "ctzsi2"
11178 [(set (match_operand:SI 0 "s_register_operand" "=r")
11179 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11180 "TARGET_32BIT && arm_arch_thumb2"
11182 "&& reload_completed"
11185 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11186 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11190 ;; V5E instructions.
11192 (define_insn "prefetch"
11193 [(prefetch (match_operand:SI 0 "address_operand" "p")
11194 (match_operand:SI 1 "" "")
11195 (match_operand:SI 2 "" ""))]
11196 "TARGET_32BIT && arm_arch5e"
11198 [(set_attr "type" "load1")]
11201 ;; General predication pattern
11204 [(match_operator 0 "arm_comparison_operator"
11205 [(match_operand 1 "cc_register" "")
11208 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11210 [(set_attr "predicated" "yes")]
11213 (define_insn "force_register_use"
11214 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11217 [(set_attr "length" "0")
11218 (set_attr "type" "no_insn")]
11222 ;; Patterns for exception handling
11224 (define_expand "eh_return"
11225 [(use (match_operand 0 "general_operand" ""))]
11230 emit_insn (gen_arm_eh_return (operands[0]));
11232 emit_insn (gen_thumb_eh_return (operands[0]));
11237 ;; We can't expand this before we know where the link register is stored.
11238 (define_insn_and_split "arm_eh_return"
11239 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11241 (clobber (match_scratch:SI 1 "=&r"))]
11244 "&& reload_completed"
11248 arm_set_return_address (operands[0], operands[1]);
11256 (define_insn "load_tp_hard"
11257 [(set (match_operand:SI 0 "register_operand" "=r")
11258 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11260 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11261 [(set_attr "predicable" "yes")
11262 (set_attr "type" "mrs")]
11265 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11266 (define_insn "load_tp_soft"
11267 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11268 (clobber (reg:SI LR_REGNUM))
11269 (clobber (reg:SI IP_REGNUM))
11270 (clobber (reg:CC CC_REGNUM))]
11272 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11273 [(set_attr "conds" "clob")
11274 (set_attr "type" "branch")]
11277 ;; tls descriptor call
11278 (define_insn "tlscall"
11279 [(set (reg:SI R0_REGNUM)
11280 (unspec:SI [(reg:SI R0_REGNUM)
11281 (match_operand:SI 0 "" "X")
11282 (match_operand 1 "" "")] UNSPEC_TLS))
11283 (clobber (reg:SI R1_REGNUM))
11284 (clobber (reg:SI LR_REGNUM))
11285 (clobber (reg:SI CC_REGNUM))]
11288 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11289 INTVAL (operands[1]));
11290 return "bl\\t%c0(tlscall)";
11292 [(set_attr "conds" "clob")
11293 (set_attr "length" "4")
11294 (set_attr "type" "branch")]
11297 ;; For thread pointer builtin
11298 (define_expand "get_thread_pointersi"
11299 [(match_operand:SI 0 "s_register_operand" "=r")]
11303 arm_load_tp (operands[0]);
11309 ;; We only care about the lower 16 bits of the constant
11310 ;; being inserted into the upper 16 bits of the register.
11311 (define_insn "*arm_movtas_ze"
11312 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11315 (match_operand:SI 1 "const_int_operand" ""))]
11320 [(set_attr "arch" "32,v8mb")
11321 (set_attr "predicable" "yes")
11322 (set_attr "predicable_short_it" "no")
11323 (set_attr "length" "4")
11324 (set_attr "type" "alu_sreg")]
11327 (define_insn "*arm_rev"
11328 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11329 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11335 [(set_attr "arch" "t1,t2,32")
11336 (set_attr "length" "2,2,4")
11337 (set_attr "predicable" "no,yes,yes")
11338 (set_attr "predicable_short_it" "no")
11339 (set_attr "type" "rev")]
11342 (define_expand "arm_legacy_rev"
11343 [(set (match_operand:SI 2 "s_register_operand" "")
11344 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11348 (lshiftrt:SI (match_dup 2)
11350 (set (match_operand:SI 3 "s_register_operand" "")
11351 (rotatert:SI (match_dup 1)
11354 (and:SI (match_dup 2)
11355 (const_int -65281)))
11356 (set (match_operand:SI 0 "s_register_operand" "")
11357 (xor:SI (match_dup 3)
11363 ;; Reuse temporaries to keep register pressure down.
11364 (define_expand "thumb_legacy_rev"
11365 [(set (match_operand:SI 2 "s_register_operand" "")
11366 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11368 (set (match_operand:SI 3 "s_register_operand" "")
11369 (lshiftrt:SI (match_dup 1)
11372 (ior:SI (match_dup 3)
11374 (set (match_operand:SI 4 "s_register_operand" "")
11376 (set (match_operand:SI 5 "s_register_operand" "")
11377 (rotatert:SI (match_dup 1)
11380 (ashift:SI (match_dup 5)
11383 (lshiftrt:SI (match_dup 5)
11386 (ior:SI (match_dup 5)
11389 (rotatert:SI (match_dup 5)
11391 (set (match_operand:SI 0 "s_register_operand" "")
11392 (ior:SI (match_dup 5)
11398 ;; ARM-specific expansion of signed mod by power of 2
11399 ;; using conditional negate.
11400 ;; For r0 % n where n is a power of 2 produce:
11402 ;; and r0, r0, #(n - 1)
11403 ;; and r1, r1, #(n - 1)
11404 ;; rsbpl r0, r1, #0
11406 (define_expand "modsi3"
11407 [(match_operand:SI 0 "register_operand" "")
11408 (match_operand:SI 1 "register_operand" "")
11409 (match_operand:SI 2 "const_int_operand" "")]
11412 HOST_WIDE_INT val = INTVAL (operands[2]);
11415 || exact_log2 (val) <= 0)
11418 rtx mask = GEN_INT (val - 1);
11420 /* In the special case of x0 % 2 we can do the even shorter:
11423 rsblt r0, r0, #0. */
11427 rtx cc_reg = arm_gen_compare_reg (LT,
11428 operands[1], const0_rtx, NULL_RTX);
11429 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11430 rtx masked = gen_reg_rtx (SImode);
11432 emit_insn (gen_andsi3 (masked, operands[1], mask));
11433 emit_move_insn (operands[0],
11434 gen_rtx_IF_THEN_ELSE (SImode, cond,
11435 gen_rtx_NEG (SImode,
11441 rtx neg_op = gen_reg_rtx (SImode);
11442 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11445 /* Extract the condition register and mode. */
11446 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11447 rtx cc_reg = SET_DEST (cmp);
11448 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11450 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11452 rtx masked_neg = gen_reg_rtx (SImode);
11453 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11455 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11456 during expand does not always work. Do an IF_THEN_ELSE instead. */
11457 emit_move_insn (operands[0],
11458 gen_rtx_IF_THEN_ELSE (SImode, cond,
11459 gen_rtx_NEG (SImode, masked_neg),
11467 (define_expand "bswapsi2"
11468 [(set (match_operand:SI 0 "s_register_operand" "=r")
11469 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11470 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11474 rtx op2 = gen_reg_rtx (SImode);
11475 rtx op3 = gen_reg_rtx (SImode);
11479 rtx op4 = gen_reg_rtx (SImode);
11480 rtx op5 = gen_reg_rtx (SImode);
11482 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11483 op2, op3, op4, op5));
11487 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11496 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11497 ;; and unsigned variants, respectively. For rev16, expose
11498 ;; byte-swapping in the lower 16 bits only.
11499 (define_insn "*arm_revsh"
11500 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11501 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11507 [(set_attr "arch" "t1,t2,32")
11508 (set_attr "length" "2,2,4")
11509 (set_attr "type" "rev")]
11512 (define_insn "*arm_rev16"
11513 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11514 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11520 [(set_attr "arch" "t1,t2,32")
11521 (set_attr "length" "2,2,4")
11522 (set_attr "type" "rev")]
11525 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11526 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11527 ;; each valid permutation.
11529 (define_insn "arm_rev16si2"
11530 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11531 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11533 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11534 (and:SI (lshiftrt:SI (match_dup 1)
11536 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11538 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11539 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11541 [(set_attr "arch" "t1,t2,32")
11542 (set_attr "length" "2,2,4")
11543 (set_attr "type" "rev")]
11546 (define_insn "arm_rev16si2_alt"
11547 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11548 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11550 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11551 (and:SI (ashift:SI (match_dup 1)
11553 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11555 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11556 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11558 [(set_attr "arch" "t1,t2,32")
11559 (set_attr "length" "2,2,4")
11560 (set_attr "type" "rev")]
11563 (define_expand "bswaphi2"
11564 [(set (match_operand:HI 0 "s_register_operand" "=r")
11565 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11570 ;; Patterns for LDRD/STRD in Thumb2 mode
11572 (define_insn "*thumb2_ldrd"
11573 [(set (match_operand:SI 0 "s_register_operand" "=r")
11574 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11575 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11576 (set (match_operand:SI 3 "s_register_operand" "=r")
11577 (mem:SI (plus:SI (match_dup 1)
11578 (match_operand:SI 4 "const_int_operand" ""))))]
11579 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11580 && current_tune->prefer_ldrd_strd
11581 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11582 && (operands_ok_ldrd_strd (operands[0], operands[3],
11583 operands[1], INTVAL (operands[2]),
11585 "ldrd%?\t%0, %3, [%1, %2]"
11586 [(set_attr "type" "load2")
11587 (set_attr "predicable" "yes")
11588 (set_attr "predicable_short_it" "no")])
11590 (define_insn "*thumb2_ldrd_base"
11591 [(set (match_operand:SI 0 "s_register_operand" "=r")
11592 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11593 (set (match_operand:SI 2 "s_register_operand" "=r")
11594 (mem:SI (plus:SI (match_dup 1)
11596 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11597 && current_tune->prefer_ldrd_strd
11598 && (operands_ok_ldrd_strd (operands[0], operands[2],
11599 operands[1], 0, false, true))"
11600 "ldrd%?\t%0, %2, [%1]"
11601 [(set_attr "type" "load2")
11602 (set_attr "predicable" "yes")
11603 (set_attr "predicable_short_it" "no")])
11605 (define_insn "*thumb2_ldrd_base_neg"
11606 [(set (match_operand:SI 0 "s_register_operand" "=r")
11607 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11609 (set (match_operand:SI 2 "s_register_operand" "=r")
11610 (mem:SI (match_dup 1)))]
11611 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11612 && current_tune->prefer_ldrd_strd
11613 && (operands_ok_ldrd_strd (operands[0], operands[2],
11614 operands[1], -4, false, true))"
11615 "ldrd%?\t%0, %2, [%1, #-4]"
11616 [(set_attr "type" "load2")
11617 (set_attr "predicable" "yes")
11618 (set_attr "predicable_short_it" "no")])
11620 (define_insn "*thumb2_strd"
11621 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11622 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11623 (match_operand:SI 2 "s_register_operand" "r"))
11624 (set (mem:SI (plus:SI (match_dup 0)
11625 (match_operand:SI 3 "const_int_operand" "")))
11626 (match_operand:SI 4 "s_register_operand" "r"))]
11627 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11628 && current_tune->prefer_ldrd_strd
11629 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11630 && (operands_ok_ldrd_strd (operands[2], operands[4],
11631 operands[0], INTVAL (operands[1]),
11633 "strd%?\t%2, %4, [%0, %1]"
11634 [(set_attr "type" "store2")
11635 (set_attr "predicable" "yes")
11636 (set_attr "predicable_short_it" "no")])
11638 (define_insn "*thumb2_strd_base"
11639 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11640 (match_operand:SI 1 "s_register_operand" "r"))
11641 (set (mem:SI (plus:SI (match_dup 0)
11643 (match_operand:SI 2 "s_register_operand" "r"))]
11644 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11645 && current_tune->prefer_ldrd_strd
11646 && (operands_ok_ldrd_strd (operands[1], operands[2],
11647 operands[0], 0, false, false))"
11648 "strd%?\t%1, %2, [%0]"
11649 [(set_attr "type" "store2")
11650 (set_attr "predicable" "yes")
11651 (set_attr "predicable_short_it" "no")])
11653 (define_insn "*thumb2_strd_base_neg"
11654 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11656 (match_operand:SI 1 "s_register_operand" "r"))
11657 (set (mem:SI (match_dup 0))
11658 (match_operand:SI 2 "s_register_operand" "r"))]
11659 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11660 && current_tune->prefer_ldrd_strd
11661 && (operands_ok_ldrd_strd (operands[1], operands[2],
11662 operands[0], -4, false, false))"
11663 "strd%?\t%1, %2, [%0, #-4]"
11664 [(set_attr "type" "store2")
11665 (set_attr "predicable" "yes")
11666 (set_attr "predicable_short_it" "no")])
11668 ;; ARMv8 CRC32 instructions.
11669 (define_insn "<crc_variant>"
11670 [(set (match_operand:SI 0 "s_register_operand" "=r")
11671 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11672 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11675 "<crc_variant>\\t%0, %1, %2"
11676 [(set_attr "type" "crc")
11677 (set_attr "conds" "unconditional")]
11680 ;; Load the load/store double peephole optimizations.
11681 (include "ldrdstrd.md")
11683 ;; Load the load/store multiple patterns
11684 (include "ldmstm.md")
11686 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11687 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11688 (define_insn "*load_multiple"
11689 [(match_parallel 0 "load_multiple_operation"
11690 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11691 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11696 arm_output_multireg_pop (operands, /*return_pc=*/false,
11697 /*cond=*/const_true_rtx,
11703 [(set_attr "predicable" "yes")]
11706 (define_expand "copysignsf3"
11707 [(match_operand:SF 0 "register_operand")
11708 (match_operand:SF 1 "register_operand")
11709 (match_operand:SF 2 "register_operand")]
11710 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11712 emit_move_insn (operands[0], operands[2]);
11713 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11714 GEN_INT (31), GEN_INT (0),
11715 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11720 (define_expand "copysigndf3"
11721 [(match_operand:DF 0 "register_operand")
11722 (match_operand:DF 1 "register_operand")
11723 (match_operand:DF 2 "register_operand")]
11724 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11726 rtx op0_low = gen_lowpart (SImode, operands[0]);
11727 rtx op0_high = gen_highpart (SImode, operands[0]);
11728 rtx op1_low = gen_lowpart (SImode, operands[1]);
11729 rtx op1_high = gen_highpart (SImode, operands[1]);
11730 rtx op2_high = gen_highpart (SImode, operands[2]);
11732 rtx scratch1 = gen_reg_rtx (SImode);
11733 rtx scratch2 = gen_reg_rtx (SImode);
11734 emit_move_insn (scratch1, op2_high);
11735 emit_move_insn (scratch2, op1_high);
11737 emit_insn(gen_rtx_SET(scratch1,
11738 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11739 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11740 emit_move_insn (op0_low, op1_low);
11741 emit_move_insn (op0_high, scratch2);
11747 ;; movmisalign patterns for HImode and SImode.
11748 (define_expand "movmisalign<mode>"
11749 [(match_operand:HSI 0 "general_operand")
11750 (match_operand:HSI 1 "general_operand")]
11753 /* This pattern is not permitted to fail during expansion: if both arguments
11754 are non-registers (e.g. memory := constant), force operand 1 into a
11756 rtx (* gen_unaligned_load)(rtx, rtx);
11757 rtx tmp_dest = operands[0];
11758 if (!s_register_operand (operands[0], <MODE>mode)
11759 && !s_register_operand (operands[1], <MODE>mode))
11760 operands[1] = force_reg (<MODE>mode, operands[1]);
11762 if (<MODE>mode == HImode)
11764 gen_unaligned_load = gen_unaligned_loadhiu;
11765 tmp_dest = gen_reg_rtx (SImode);
11768 gen_unaligned_load = gen_unaligned_loadsi;
11770 if (MEM_P (operands[1]))
11772 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11773 if (<MODE>mode == HImode)
11774 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11777 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11782 ;; Vector bits common to IWMMXT and Neon
11783 (include "vec-common.md")
11784 ;; Load the Intel Wireless Multimedia Extension patterns
11785 (include "iwmmxt.md")
11786 ;; Load the VFP co-processor patterns
11788 ;; Thumb-1 patterns
11789 (include "thumb1.md")
11790 ;; Thumb-2 patterns
11791 (include "thumb2.md")
11793 (include "neon.md")
11795 (include "crypto.md")
11796 ;; Synchronization Primitives
11797 (include "sync.md")
11798 ;; Fixed-point patterns
11799 (include "arm-fixed.md")