1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2017 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;---------------------------------------------------------------------------
29 ;; Register numbers -- All machine registers should be defined here
31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (IP_REGNUM 12) ; Scratch register
34 (SP_REGNUM 13) ; Stack pointer
35 (LR_REGNUM 14) ; Return address register
36 (PC_REGNUM 15) ; Program counter
37 (LAST_ARM_REGNUM 15) ;
38 (CC_REGNUM 100) ; Condition code pseudo register
39 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
42 ;; 3rd operand to select_dominance_cc_mode
49 ;; conditional compare combination
60 ;;---------------------------------------------------------------------------
63 ;; Processor type. This is created automatically from arm-cores.def.
64 (include "arm-tune.md")
66 ;; Instruction classification types
69 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70 ; generating ARM code. This is used to control the length of some insn
71 ; patterns that share the same RTL in both ARM and Thumb code.
72 (define_attr "is_thumb" "yes,no"
73 (const (if_then_else (symbol_ref "TARGET_THUMB")
74 (const_string "yes") (const_string "no"))))
76 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
79 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
80 (define_attr "is_thumb1" "yes,no"
81 (const (if_then_else (symbol_ref "TARGET_THUMB1")
82 (const_string "yes") (const_string "no"))))
84 ; We use this attribute to disable alternatives that can produce 32-bit
85 ; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
86 ; that contain 32-bit instructions.
87 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
89 ; This attribute is used to disable a predicated alternative when we have
91 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
93 ;; Operand number of an input operand that is shifted. Zero if the
94 ;; given instruction does not shift one of its input operands.
95 (define_attr "shift" "" (const_int 0))
97 ;; [For compatibility with AArch64 in pipeline models]
98 ;; Attribute that specifies whether or not the instruction touches fp
100 (define_attr "fp" "no,yes" (const_string "no"))
102 ; Floating Point Unit. If we only have floating point emulation, then there
103 ; is no point in scheduling the floating point insns. (Well, for best
104 ; performance we should try and group them together).
105 (define_attr "fpu" "none,vfp"
106 (const (symbol_ref "arm_fpu_attr")))
108 ; Predicated means that the insn form is conditionally executed based on a
109 ; predicate. We default to 'no' because no Thumb patterns match this rule
110 ; and not all ARM insns do.
111 (define_attr "predicated" "yes,no" (const_string "no"))
113 ; LENGTH of an instruction (in bytes)
114 (define_attr "length" ""
117 ; The architecture which supports the instruction (or alternative).
118 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
119 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
120 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
121 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
122 ; Baseline. This attribute is used to compute attribute "enabled",
123 ; use type "any" to enable an alternative in all cases.
124 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
125 (const_string "any"))
127 (define_attr "arch_enabled" "no,yes"
128 (cond [(eq_attr "arch" "any")
131 (and (eq_attr "arch" "a")
132 (match_test "TARGET_ARM"))
135 (and (eq_attr "arch" "t")
136 (match_test "TARGET_THUMB"))
139 (and (eq_attr "arch" "t1")
140 (match_test "TARGET_THUMB1"))
143 (and (eq_attr "arch" "t2")
144 (match_test "TARGET_THUMB2"))
147 (and (eq_attr "arch" "32")
148 (match_test "TARGET_32BIT"))
151 (and (eq_attr "arch" "v6")
152 (match_test "TARGET_32BIT && arm_arch6"))
155 (and (eq_attr "arch" "nov6")
156 (match_test "TARGET_32BIT && !arm_arch6"))
159 (and (eq_attr "arch" "v6t2")
160 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
163 (and (eq_attr "arch" "v8mb")
164 (match_test "TARGET_THUMB1 && arm_arch8"))
167 (and (eq_attr "arch" "avoid_neon_for_64bits")
168 (match_test "TARGET_NEON")
169 (not (match_test "TARGET_PREFER_NEON_64BITS")))
172 (and (eq_attr "arch" "neon_for_64bits")
173 (match_test "TARGET_NEON")
174 (match_test "TARGET_PREFER_NEON_64BITS"))
177 (and (eq_attr "arch" "iwmmxt2")
178 (match_test "TARGET_REALLY_IWMMXT2"))
181 (and (eq_attr "arch" "armv6_or_vfpv3")
182 (match_test "arm_arch6 || TARGET_VFP3"))
185 (and (eq_attr "arch" "neon")
186 (match_test "TARGET_NEON"))
190 (const_string "no")))
192 (define_attr "opt" "any,speed,size"
193 (const_string "any"))
195 (define_attr "opt_enabled" "no,yes"
196 (cond [(eq_attr "opt" "any")
199 (and (eq_attr "opt" "speed")
200 (match_test "optimize_function_for_speed_p (cfun)"))
203 (and (eq_attr "opt" "size")
204 (match_test "optimize_function_for_size_p (cfun)"))
205 (const_string "yes")]
206 (const_string "no")))
208 (define_attr "use_literal_pool" "no,yes"
209 (cond [(and (eq_attr "type" "f_loads,f_loadd")
210 (match_test "CONSTANT_P (operands[1])"))
211 (const_string "yes")]
212 (const_string "no")))
214 ; Enable all alternatives that are both arch_enabled and insn_enabled.
215 ; FIXME:: opt_enabled has been temporarily removed till the time we have
216 ; an attribute that allows the use of such alternatives.
217 ; This depends on caching of speed_p, size_p on a per
218 ; alternative basis. The problem is that the enabled attribute
219 ; cannot depend on any state that is not cached or is not constant
220 ; for a compilation unit. We probably need a generic "hot/cold"
221 ; alternative which if implemented can help with this. We disable this
222 ; until such a time as this is implemented and / or the improvements or
223 ; regressions with removing this attribute are double checked.
224 ; See ashldi3_neon and <shift>di3_neon in neon.md.
226 (define_attr "enabled" "no,yes"
227 (cond [(and (eq_attr "predicable_short_it" "no")
228 (and (eq_attr "predicated" "yes")
229 (match_test "arm_restrict_it")))
232 (and (eq_attr "enabled_for_depr_it" "no")
233 (match_test "arm_restrict_it"))
236 (and (eq_attr "use_literal_pool" "yes")
237 (match_test "arm_disable_literal_pool"))
240 (eq_attr "arch_enabled" "no")
242 (const_string "yes")))
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed. If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address. It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
257 (define_attr "pool_range" ""
258 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259 (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262 (attr "arm_neg_pool_range")))
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268 [(set_attr "conds" "clob")
269 (set_attr "length" "4")
270 (set_attr "pool_range" "250")])
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions. It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
280 ; USE means that the condition codes are used by the insn in the process of
281 ; outputting code, this means (at present) that we can't use the insn in
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ; well defined manner.
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ; they are altered at all
290 ; UNCONDITIONAL means the instruction can not be conditionally executed and
291 ; that the instruction does not use or alter the condition codes.
293 ; NOCOND means that the instruction does not use or alter the condition
294 ; codes but can be converted into a conditionally exectuted instruction.
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
298 (ior (eq_attr "is_thumb1" "yes")
299 (eq_attr "type" "call"))
300 (const_string "clob")
301 (if_then_else (eq_attr "is_neon_type" "no")
302 (const_string "nocond")
303 (const_string "unconditional"))))
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by
307 ; gen...). We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
311 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
312 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor. Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320 (if_then_else (eq_attr "type"
323 (const_string "no")))
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328 (if_then_else (eq_attr "type"
329 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345 (const_string "single")
346 (const_string "multi")))
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label. Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
357 ;;---------------------------------------------------------------------------
360 (include "unspecs.md")
362 ;;---------------------------------------------------------------------------
365 (include "iterators.md")
367 ;;---------------------------------------------------------------------------
370 (include "predicates.md")
371 (include "constraints.md")
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
376 (define_attr "tune_cortexr4" "yes,no"
378 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
380 (const_string "no"))))
382 ;; True if the generic scheduling description should be used.
384 (define_attr "generic_sched" "yes,no"
386 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
388 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389 cortexa9,cortexa12,cortexa15,cortexa17,\
390 cortexa53,cortexa57,cortexm4,cortexm7,\
391 exynosm1,marvell_pj4,xgene1")
392 (eq_attr "tune_cortexr4" "yes"))
394 (const_string "yes"))))
396 (define_attr "generic_vfp" "yes,no"
398 (and (eq_attr "fpu" "vfp")
399 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
400 cortexa8,cortexa9,cortexa53,cortexm4,\
401 cortexm7,marvell_pj4,xgene1")
402 (eq_attr "tune_cortexr4" "no"))
404 (const_string "no"))))
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
436 ;;---------------------------------------------------------------------------
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
445 (define_expand "adddi3"
447 [(set (match_operand:DI 0 "s_register_operand" "")
448 (plus:DI (match_operand:DI 1 "s_register_operand" "")
449 (match_operand:DI 2 "arm_adddi_operand" "")))
450 (clobber (reg:CC CC_REGNUM))])]
455 if (!REG_P (operands[1]))
456 operands[1] = force_reg (DImode, operands[1]);
457 if (!REG_P (operands[2]))
458 operands[2] = force_reg (DImode, operands[2]);
463 (define_insn_and_split "*arm_adddi3"
464 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
465 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
466 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
467 (clobber (reg:CC CC_REGNUM))]
468 "TARGET_32BIT && !TARGET_NEON"
470 "TARGET_32BIT && reload_completed
471 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
472 [(parallel [(set (reg:CC_C CC_REGNUM)
473 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
475 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
476 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
477 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
480 operands[3] = gen_highpart (SImode, operands[0]);
481 operands[0] = gen_lowpart (SImode, operands[0]);
482 operands[4] = gen_highpart (SImode, operands[1]);
483 operands[1] = gen_lowpart (SImode, operands[1]);
484 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
485 operands[2] = gen_lowpart (SImode, operands[2]);
487 [(set_attr "conds" "clob")
488 (set_attr "length" "8")
489 (set_attr "type" "multiple")]
492 (define_insn_and_split "*adddi_sesidi_di"
493 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
494 (plus:DI (sign_extend:DI
495 (match_operand:SI 2 "s_register_operand" "r,r"))
496 (match_operand:DI 1 "s_register_operand" "0,r")))
497 (clobber (reg:CC CC_REGNUM))]
500 "TARGET_32BIT && reload_completed"
501 [(parallel [(set (reg:CC_C CC_REGNUM)
502 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
504 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
505 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
508 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
511 operands[3] = gen_highpart (SImode, operands[0]);
512 operands[0] = gen_lowpart (SImode, operands[0]);
513 operands[4] = gen_highpart (SImode, operands[1]);
514 operands[1] = gen_lowpart (SImode, operands[1]);
515 operands[2] = gen_lowpart (SImode, operands[2]);
517 [(set_attr "conds" "clob")
518 (set_attr "length" "8")
519 (set_attr "type" "multiple")]
522 (define_insn_and_split "*adddi_zesidi_di"
523 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
524 (plus:DI (zero_extend:DI
525 (match_operand:SI 2 "s_register_operand" "r,r"))
526 (match_operand:DI 1 "s_register_operand" "0,r")))
527 (clobber (reg:CC CC_REGNUM))]
530 "TARGET_32BIT && reload_completed"
531 [(parallel [(set (reg:CC_C CC_REGNUM)
532 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
534 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
535 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
536 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
539 operands[3] = gen_highpart (SImode, operands[0]);
540 operands[0] = gen_lowpart (SImode, operands[0]);
541 operands[4] = gen_highpart (SImode, operands[1]);
542 operands[1] = gen_lowpart (SImode, operands[1]);
543 operands[2] = gen_lowpart (SImode, operands[2]);
545 [(set_attr "conds" "clob")
546 (set_attr "length" "8")
547 (set_attr "type" "multiple")]
550 (define_expand "addv<mode>4"
551 [(match_operand:SIDI 0 "register_operand")
552 (match_operand:SIDI 1 "register_operand")
553 (match_operand:SIDI 2 "register_operand")
554 (match_operand 3 "")]
557 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
558 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
563 (define_expand "uaddv<mode>4"
564 [(match_operand:SIDI 0 "register_operand")
565 (match_operand:SIDI 1 "register_operand")
566 (match_operand:SIDI 2 "register_operand")
567 (match_operand 3 "")]
570 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
571 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
576 (define_expand "addsi3"
577 [(set (match_operand:SI 0 "s_register_operand" "")
578 (plus:SI (match_operand:SI 1 "s_register_operand" "")
579 (match_operand:SI 2 "reg_or_int_operand" "")))]
582 if (TARGET_32BIT && CONST_INT_P (operands[2]))
584 arm_split_constant (PLUS, SImode, NULL_RTX,
585 INTVAL (operands[2]), operands[0], operands[1],
586 optimize && can_create_pseudo_p ());
592 ; If there is a scratch available, this will be faster than synthesizing the
595 [(match_scratch:SI 3 "r")
596 (set (match_operand:SI 0 "arm_general_register_operand" "")
597 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
598 (match_operand:SI 2 "const_int_operand" "")))]
600 !(const_ok_for_arm (INTVAL (operands[2]))
601 || const_ok_for_arm (-INTVAL (operands[2])))
602 && const_ok_for_arm (~INTVAL (operands[2]))"
603 [(set (match_dup 3) (match_dup 2))
604 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
608 ;; The r/r/k alternative is required when reloading the address
609 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
610 ;; put the duplicated register first, and not try the commutative version.
611 (define_insn_and_split "*arm_addsi3"
612 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
613 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,r ,rk,k ,rk,k,r,rk,k ,rk")
614 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
630 subw%?\\t%0, %1, #%n2
631 subw%?\\t%0, %1, #%n2
634 && CONST_INT_P (operands[2])
635 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
636 && (reload_completed || !arm_eliminable_register (operands[1]))"
637 [(clobber (const_int 0))]
639 arm_split_constant (PLUS, SImode, curr_insn,
640 INTVAL (operands[2]), operands[0],
644 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
645 (set_attr "predicable" "yes")
646 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
647 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
648 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
649 (const_string "alu_imm")
650 (const_string "alu_sreg")))
654 (define_insn_and_split "adddi3_compareV"
655 [(set (reg:CC_V CC_REGNUM)
658 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
659 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
660 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
661 (set (match_operand:DI 0 "register_operand" "=&r")
662 (plus:DI (match_dup 1) (match_dup 2)))]
665 "&& reload_completed"
666 [(parallel [(set (reg:CC_C CC_REGNUM)
667 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
669 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
670 (parallel [(set (reg:CC_V CC_REGNUM)
673 (sign_extend:DI (match_dup 4))
674 (sign_extend:DI (match_dup 5)))
675 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
676 (plus:DI (sign_extend:DI
677 (plus:SI (match_dup 4) (match_dup 5)))
678 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
679 (set (match_dup 3) (plus:SI (plus:SI
680 (match_dup 4) (match_dup 5))
681 (ltu:SI (reg:CC_C CC_REGNUM)
685 operands[3] = gen_highpart (SImode, operands[0]);
686 operands[0] = gen_lowpart (SImode, operands[0]);
687 operands[4] = gen_highpart (SImode, operands[1]);
688 operands[1] = gen_lowpart (SImode, operands[1]);
689 operands[5] = gen_highpart (SImode, operands[2]);
690 operands[2] = gen_lowpart (SImode, operands[2]);
692 [(set_attr "conds" "set")
693 (set_attr "length" "8")
694 (set_attr "type" "multiple")]
697 (define_insn "addsi3_compareV"
698 [(set (reg:CC_V CC_REGNUM)
701 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
702 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
703 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
704 (set (match_operand:SI 0 "register_operand" "=r")
705 (plus:SI (match_dup 1) (match_dup 2)))]
707 "adds%?\\t%0, %1, %2"
708 [(set_attr "conds" "set")
709 (set_attr "type" "alus_sreg")]
712 (define_insn "*addsi3_compareV_upper"
713 [(set (reg:CC_V CC_REGNUM)
717 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
718 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
719 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
720 (plus:DI (sign_extend:DI
721 (plus:SI (match_dup 1) (match_dup 2)))
722 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
723 (set (match_operand:SI 0 "register_operand" "=r")
725 (plus:SI (match_dup 1) (match_dup 2))
726 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
728 "adcs%?\\t%0, %1, %2"
729 [(set_attr "conds" "set")
730 (set_attr "type" "adcs_reg")]
733 (define_insn_and_split "adddi3_compareC"
734 [(set (reg:CC_C CC_REGNUM)
737 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
738 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
739 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
740 (set (match_operand:DI 0 "register_operand" "=&r")
741 (plus:DI (match_dup 1) (match_dup 2)))]
744 "&& reload_completed"
745 [(parallel [(set (reg:CC_C CC_REGNUM)
746 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
748 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
749 (parallel [(set (reg:CC_C CC_REGNUM)
752 (zero_extend:DI (match_dup 4))
753 (zero_extend:DI (match_dup 5)))
754 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
755 (plus:DI (zero_extend:DI
756 (plus:SI (match_dup 4) (match_dup 5)))
757 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
758 (set (match_dup 3) (plus:SI
759 (plus:SI (match_dup 4) (match_dup 5))
760 (ltu:SI (reg:CC_C CC_REGNUM)
764 operands[3] = gen_highpart (SImode, operands[0]);
765 operands[0] = gen_lowpart (SImode, operands[0]);
766 operands[4] = gen_highpart (SImode, operands[1]);
767 operands[5] = gen_highpart (SImode, operands[2]);
768 operands[1] = gen_lowpart (SImode, operands[1]);
769 operands[2] = gen_lowpart (SImode, operands[2]);
771 [(set_attr "conds" "set")
772 (set_attr "length" "8")
773 (set_attr "type" "multiple")]
776 (define_insn "*addsi3_compareC_upper"
777 [(set (reg:CC_C CC_REGNUM)
781 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
782 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
783 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
784 (plus:DI (zero_extend:DI
785 (plus:SI (match_dup 1) (match_dup 2)))
786 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
787 (set (match_operand:SI 0 "register_operand" "=r")
789 (plus:SI (match_dup 1) (match_dup 2))
790 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
792 "adcs%?\\t%0, %1, %2"
793 [(set_attr "conds" "set")
794 (set_attr "type" "adcs_reg")]
797 (define_insn "addsi3_compareC"
798 [(set (reg:CC_C CC_REGNUM)
801 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
802 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
804 (plus:SI (match_dup 1) (match_dup 2)))))
805 (set (match_operand:SI 0 "register_operand" "=r")
806 (plus:SI (match_dup 1) (match_dup 2)))]
808 "adds%?\\t%0, %1, %2"
809 [(set_attr "conds" "set")
810 (set_attr "type" "alus_sreg")]
813 (define_insn "addsi3_compare0"
814 [(set (reg:CC_NOOV CC_REGNUM)
816 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
817 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
819 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
820 (plus:SI (match_dup 1) (match_dup 2)))]
824 subs%?\\t%0, %1, #%n2
826 [(set_attr "conds" "set")
827 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
830 (define_insn "*addsi3_compare0_scratch"
831 [(set (reg:CC_NOOV CC_REGNUM)
833 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
834 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
841 [(set_attr "conds" "set")
842 (set_attr "predicable" "yes")
843 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
846 (define_insn "*compare_negsi_si"
847 [(set (reg:CC_Z CC_REGNUM)
849 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
850 (match_operand:SI 1 "s_register_operand" "l,r")))]
853 [(set_attr "conds" "set")
854 (set_attr "predicable" "yes")
855 (set_attr "arch" "t2,*")
856 (set_attr "length" "2,4")
857 (set_attr "predicable_short_it" "yes,no")
858 (set_attr "type" "alus_sreg")]
861 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
862 ;; addend is a constant.
863 (define_insn "cmpsi2_addneg"
864 [(set (reg:CC CC_REGNUM)
866 (match_operand:SI 1 "s_register_operand" "r,r")
867 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
868 (set (match_operand:SI 0 "s_register_operand" "=r,r")
869 (plus:SI (match_dup 1)
870 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
871 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
874 subs%?\\t%0, %1, #%n3"
875 [(set_attr "conds" "set")
876 (set_attr "type" "alus_sreg")]
879 ;; Convert the sequence
881 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
885 ;; bcs dest ((unsigned)rn >= 1)
886 ;; similarly for the beq variant using bcc.
887 ;; This is a common looping idiom (while (n--))
889 [(set (match_operand:SI 0 "arm_general_register_operand" "")
890 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
892 (set (match_operand 2 "cc_register" "")
893 (compare (match_dup 0) (const_int -1)))
895 (if_then_else (match_operator 3 "equality_operator"
896 [(match_dup 2) (const_int 0)])
897 (match_operand 4 "" "")
898 (match_operand 5 "" "")))]
899 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
903 (match_dup 1) (const_int 1)))
904 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
906 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
909 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
910 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
913 operands[2], const0_rtx);"
916 ;; The next four insns work because they compare the result with one of
917 ;; the operands, and we know that the use of the condition code is
918 ;; either GEU or LTU, so we can use the carry flag from the addition
919 ;; instead of doing the compare a second time.
920 (define_insn "*addsi3_compare_op1"
921 [(set (reg:CC_C CC_REGNUM)
923 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
924 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
926 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
927 (plus:SI (match_dup 1) (match_dup 2)))]
931 subs%?\\t%0, %1, #%n2
933 [(set_attr "conds" "set")
934 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
937 (define_insn "*addsi3_compare_op2"
938 [(set (reg:CC_C CC_REGNUM)
940 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
941 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
943 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
944 (plus:SI (match_dup 1) (match_dup 2)))]
948 subs%?\\t%0, %1, #%n2
950 [(set_attr "conds" "set")
951 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
954 (define_insn "*compare_addsi2_op0"
955 [(set (reg:CC_C CC_REGNUM)
957 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
958 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
967 [(set_attr "conds" "set")
968 (set_attr "predicable" "yes")
969 (set_attr "arch" "t2,t2,*,*,*")
970 (set_attr "predicable_short_it" "yes,yes,no,no,no")
971 (set_attr "length" "2,2,4,4,4")
972 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
975 (define_insn "*compare_addsi2_op1"
976 [(set (reg:CC_C CC_REGNUM)
978 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
979 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
988 [(set_attr "conds" "set")
989 (set_attr "predicable" "yes")
990 (set_attr "arch" "t2,t2,*,*,*")
991 (set_attr "predicable_short_it" "yes,yes,no,no,no")
992 (set_attr "length" "2,2,4,4,4")
993 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
996 (define_insn "*addsi3_carryin_<optab>"
997 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
998 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
999 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
1000 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1005 sbc%?\\t%0, %1, #%B2"
1006 [(set_attr "conds" "use")
1007 (set_attr "predicable" "yes")
1008 (set_attr "arch" "t2,*,*")
1009 (set_attr "length" "4")
1010 (set_attr "predicable_short_it" "yes,no,no")
1011 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1014 (define_insn "*addsi3_carryin_alt2_<optab>"
1015 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1016 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1017 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1018 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1023 sbc%?\\t%0, %1, #%B2"
1024 [(set_attr "conds" "use")
1025 (set_attr "predicable" "yes")
1026 (set_attr "arch" "t2,*,*")
1027 (set_attr "length" "4")
1028 (set_attr "predicable_short_it" "yes,no,no")
1029 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1032 (define_insn "*addsi3_carryin_shift_<optab>"
1033 [(set (match_operand:SI 0 "s_register_operand" "=r")
1035 (match_operator:SI 2 "shift_operator"
1036 [(match_operand:SI 3 "s_register_operand" "r")
1037 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1038 (match_operand:SI 1 "s_register_operand" "r"))
1039 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1041 "adc%?\\t%0, %1, %3%S2"
1042 [(set_attr "conds" "use")
1043 (set_attr "predicable" "yes")
1044 (set_attr "predicable_short_it" "no")
1045 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1046 (const_string "alu_shift_imm")
1047 (const_string "alu_shift_reg")))]
1050 (define_insn "*addsi3_carryin_clobercc_<optab>"
1051 [(set (match_operand:SI 0 "s_register_operand" "=r")
1052 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1053 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1054 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1055 (clobber (reg:CC CC_REGNUM))]
1057 "adcs%?\\t%0, %1, %2"
1058 [(set_attr "conds" "set")
1059 (set_attr "type" "adcs_reg")]
1062 (define_expand "subv<mode>4"
1063 [(match_operand:SIDI 0 "register_operand")
1064 (match_operand:SIDI 1 "register_operand")
1065 (match_operand:SIDI 2 "register_operand")
1066 (match_operand 3 "")]
1069 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1070 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1075 (define_expand "usubv<mode>4"
1076 [(match_operand:SIDI 0 "register_operand")
1077 (match_operand:SIDI 1 "register_operand")
1078 (match_operand:SIDI 2 "register_operand")
1079 (match_operand 3 "")]
1082 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1083 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1088 (define_insn_and_split "subdi3_compare1"
1089 [(set (reg:CC CC_REGNUM)
1091 (match_operand:DI 1 "register_operand" "r")
1092 (match_operand:DI 2 "register_operand" "r")))
1093 (set (match_operand:DI 0 "register_operand" "=&r")
1094 (minus:DI (match_dup 1) (match_dup 2)))]
1097 "&& reload_completed"
1098 [(parallel [(set (reg:CC CC_REGNUM)
1099 (compare:CC (match_dup 1) (match_dup 2)))
1100 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1101 (parallel [(set (reg:CC CC_REGNUM)
1102 (compare:CC (match_dup 4) (match_dup 5)))
1103 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1104 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1106 operands[3] = gen_highpart (SImode, operands[0]);
1107 operands[0] = gen_lowpart (SImode, operands[0]);
1108 operands[4] = gen_highpart (SImode, operands[1]);
1109 operands[1] = gen_lowpart (SImode, operands[1]);
1110 operands[5] = gen_highpart (SImode, operands[2]);
1111 operands[2] = gen_lowpart (SImode, operands[2]);
1113 [(set_attr "conds" "set")
1114 (set_attr "length" "8")
1115 (set_attr "type" "multiple")]
1118 (define_insn "subsi3_compare1"
1119 [(set (reg:CC CC_REGNUM)
1121 (match_operand:SI 1 "register_operand" "r")
1122 (match_operand:SI 2 "register_operand" "r")))
1123 (set (match_operand:SI 0 "register_operand" "=r")
1124 (minus:SI (match_dup 1) (match_dup 2)))]
1126 "subs%?\\t%0, %1, %2"
1127 [(set_attr "conds" "set")
1128 (set_attr "type" "alus_sreg")]
1131 (define_insn "*subsi3_carryin"
1132 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1133 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1134 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1135 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1140 sbc%?\\t%0, %2, %2, lsl #1"
1141 [(set_attr "conds" "use")
1142 (set_attr "arch" "*,a,t2")
1143 (set_attr "predicable" "yes")
1144 (set_attr "predicable_short_it" "no")
1145 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1148 (define_insn "*subsi3_carryin_const"
1149 [(set (match_operand:SI 0 "s_register_operand" "=r")
1150 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1151 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1152 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1154 "sbc\\t%0, %1, #%B2"
1155 [(set_attr "conds" "use")
1156 (set_attr "type" "adc_imm")]
1159 (define_insn "*subsi3_carryin_compare"
1160 [(set (reg:CC CC_REGNUM)
1161 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1162 (match_operand:SI 2 "s_register_operand" "r")))
1163 (set (match_operand:SI 0 "s_register_operand" "=r")
1164 (minus:SI (minus:SI (match_dup 1)
1166 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1169 [(set_attr "conds" "set")
1170 (set_attr "type" "adcs_reg")]
1173 (define_insn "*subsi3_carryin_compare_const"
1174 [(set (reg:CC CC_REGNUM)
1175 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1176 (match_operand:SI 2 "arm_not_operand" "K")))
1177 (set (match_operand:SI 0 "s_register_operand" "=r")
1178 (minus:SI (plus:SI (match_dup 1)
1180 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1182 "sbcs\\t%0, %1, #%B2"
1183 [(set_attr "conds" "set")
1184 (set_attr "type" "adcs_imm")]
1187 (define_insn "*subsi3_carryin_shift"
1188 [(set (match_operand:SI 0 "s_register_operand" "=r")
1190 (match_operand:SI 1 "s_register_operand" "r")
1191 (match_operator:SI 2 "shift_operator"
1192 [(match_operand:SI 3 "s_register_operand" "r")
1193 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1194 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1196 "sbc%?\\t%0, %1, %3%S2"
1197 [(set_attr "conds" "use")
1198 (set_attr "predicable" "yes")
1199 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1200 (const_string "alu_shift_imm")
1201 (const_string "alu_shift_reg")))]
1204 (define_insn "*rsbsi3_carryin_shift"
1205 [(set (match_operand:SI 0 "s_register_operand" "=r")
1207 (match_operator:SI 2 "shift_operator"
1208 [(match_operand:SI 3 "s_register_operand" "r")
1209 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1210 (match_operand:SI 1 "s_register_operand" "r"))
1211 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1213 "rsc%?\\t%0, %1, %3%S2"
1214 [(set_attr "conds" "use")
1215 (set_attr "predicable" "yes")
1216 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1217 (const_string "alu_shift_imm")
1218 (const_string "alu_shift_reg")))]
1221 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1223 [(set (match_operand:SI 0 "s_register_operand" "")
1224 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1225 (match_operand:SI 2 "s_register_operand" ""))
1227 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1229 [(set (match_dup 3) (match_dup 1))
1230 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1232 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1235 (define_expand "addsf3"
1236 [(set (match_operand:SF 0 "s_register_operand" "")
1237 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1238 (match_operand:SF 2 "s_register_operand" "")))]
1239 "TARGET_32BIT && TARGET_HARD_FLOAT"
1243 (define_expand "adddf3"
1244 [(set (match_operand:DF 0 "s_register_operand" "")
1245 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1246 (match_operand:DF 2 "s_register_operand" "")))]
1247 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1251 (define_expand "subdi3"
1253 [(set (match_operand:DI 0 "s_register_operand" "")
1254 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1255 (match_operand:DI 2 "s_register_operand" "")))
1256 (clobber (reg:CC CC_REGNUM))])]
1261 if (!REG_P (operands[1]))
1262 operands[1] = force_reg (DImode, operands[1]);
1263 if (!REG_P (operands[2]))
1264 operands[2] = force_reg (DImode, operands[2]);
1269 (define_insn_and_split "*arm_subdi3"
1270 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1271 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1272 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1273 (clobber (reg:CC CC_REGNUM))]
1274 "TARGET_32BIT && !TARGET_NEON"
1275 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1276 "&& reload_completed"
1277 [(parallel [(set (reg:CC CC_REGNUM)
1278 (compare:CC (match_dup 1) (match_dup 2)))
1279 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1280 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1281 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1283 operands[3] = gen_highpart (SImode, operands[0]);
1284 operands[0] = gen_lowpart (SImode, operands[0]);
1285 operands[4] = gen_highpart (SImode, operands[1]);
1286 operands[1] = gen_lowpart (SImode, operands[1]);
1287 operands[5] = gen_highpart (SImode, operands[2]);
1288 operands[2] = gen_lowpart (SImode, operands[2]);
1290 [(set_attr "conds" "clob")
1291 (set_attr "length" "8")
1292 (set_attr "type" "multiple")]
1295 (define_insn_and_split "*subdi_di_zesidi"
1296 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1297 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1299 (match_operand:SI 2 "s_register_operand" "r,r"))))
1300 (clobber (reg:CC CC_REGNUM))]
1302 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1303 "&& reload_completed"
1304 [(parallel [(set (reg:CC CC_REGNUM)
1305 (compare:CC (match_dup 1) (match_dup 2)))
1306 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1307 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1308 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1310 operands[3] = gen_highpart (SImode, operands[0]);
1311 operands[0] = gen_lowpart (SImode, operands[0]);
1312 operands[4] = gen_highpart (SImode, operands[1]);
1313 operands[1] = gen_lowpart (SImode, operands[1]);
1314 operands[5] = GEN_INT (~0);
1316 [(set_attr "conds" "clob")
1317 (set_attr "length" "8")
1318 (set_attr "type" "multiple")]
1321 (define_insn_and_split "*subdi_di_sesidi"
1322 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1323 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1325 (match_operand:SI 2 "s_register_operand" "r,r"))))
1326 (clobber (reg:CC CC_REGNUM))]
1328 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1329 "&& reload_completed"
1330 [(parallel [(set (reg:CC CC_REGNUM)
1331 (compare:CC (match_dup 1) (match_dup 2)))
1332 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1333 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1334 (ashiftrt:SI (match_dup 2)
1336 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1338 operands[3] = gen_highpart (SImode, operands[0]);
1339 operands[0] = gen_lowpart (SImode, operands[0]);
1340 operands[4] = gen_highpart (SImode, operands[1]);
1341 operands[1] = gen_lowpart (SImode, operands[1]);
1343 [(set_attr "conds" "clob")
1344 (set_attr "length" "8")
1345 (set_attr "type" "multiple")]
1348 (define_insn_and_split "*subdi_zesidi_di"
1349 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1350 (minus:DI (zero_extend:DI
1351 (match_operand:SI 2 "s_register_operand" "r,r"))
1352 (match_operand:DI 1 "s_register_operand" "0,r")))
1353 (clobber (reg:CC CC_REGNUM))]
1355 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1357 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1358 "&& reload_completed"
1359 [(parallel [(set (reg:CC CC_REGNUM)
1360 (compare:CC (match_dup 2) (match_dup 1)))
1361 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1362 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1363 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1365 operands[3] = gen_highpart (SImode, operands[0]);
1366 operands[0] = gen_lowpart (SImode, operands[0]);
1367 operands[4] = gen_highpart (SImode, operands[1]);
1368 operands[1] = gen_lowpart (SImode, operands[1]);
1370 [(set_attr "conds" "clob")
1371 (set_attr "length" "8")
1372 (set_attr "type" "multiple")]
1375 (define_insn_and_split "*subdi_sesidi_di"
1376 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1377 (minus:DI (sign_extend:DI
1378 (match_operand:SI 2 "s_register_operand" "r,r"))
1379 (match_operand:DI 1 "s_register_operand" "0,r")))
1380 (clobber (reg:CC CC_REGNUM))]
1382 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1384 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1385 "&& reload_completed"
1386 [(parallel [(set (reg:CC CC_REGNUM)
1387 (compare:CC (match_dup 2) (match_dup 1)))
1388 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1389 (set (match_dup 3) (minus:SI (minus:SI
1390 (ashiftrt:SI (match_dup 2)
1393 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1395 operands[3] = gen_highpart (SImode, operands[0]);
1396 operands[0] = gen_lowpart (SImode, operands[0]);
1397 operands[4] = gen_highpart (SImode, operands[1]);
1398 operands[1] = gen_lowpart (SImode, operands[1]);
1400 [(set_attr "conds" "clob")
1401 (set_attr "length" "8")
1402 (set_attr "type" "multiple")]
1405 (define_insn_and_split "*subdi_zesidi_zesidi"
1406 [(set (match_operand:DI 0 "s_register_operand" "=r")
1407 (minus:DI (zero_extend:DI
1408 (match_operand:SI 1 "s_register_operand" "r"))
1410 (match_operand:SI 2 "s_register_operand" "r"))))
1411 (clobber (reg:CC CC_REGNUM))]
1413 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1414 "&& reload_completed"
1415 [(parallel [(set (reg:CC CC_REGNUM)
1416 (compare:CC (match_dup 1) (match_dup 2)))
1417 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1418 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1419 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1421 operands[3] = gen_highpart (SImode, operands[0]);
1422 operands[0] = gen_lowpart (SImode, operands[0]);
1424 [(set_attr "conds" "clob")
1425 (set_attr "length" "8")
1426 (set_attr "type" "multiple")]
1429 (define_expand "subsi3"
1430 [(set (match_operand:SI 0 "s_register_operand" "")
1431 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1432 (match_operand:SI 2 "s_register_operand" "")))]
1435 if (CONST_INT_P (operands[1]))
1439 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1440 operands[1] = force_reg (SImode, operands[1]);
1443 arm_split_constant (MINUS, SImode, NULL_RTX,
1444 INTVAL (operands[1]), operands[0],
1446 optimize && can_create_pseudo_p ());
1450 else /* TARGET_THUMB1 */
1451 operands[1] = force_reg (SImode, operands[1]);
1456 ; ??? Check Thumb-2 split length
1457 (define_insn_and_split "*arm_subsi3_insn"
1458 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1459 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1460 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1472 "&& (CONST_INT_P (operands[1])
1473 && !const_ok_for_arm (INTVAL (operands[1])))"
1474 [(clobber (const_int 0))]
1476 arm_split_constant (MINUS, SImode, curr_insn,
1477 INTVAL (operands[1]), operands[0], operands[2], 0);
1480 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1481 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1482 (set_attr "predicable" "yes")
1483 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1484 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1488 [(match_scratch:SI 3 "r")
1489 (set (match_operand:SI 0 "arm_general_register_operand" "")
1490 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1491 (match_operand:SI 2 "arm_general_register_operand" "")))]
1493 && !const_ok_for_arm (INTVAL (operands[1]))
1494 && const_ok_for_arm (~INTVAL (operands[1]))"
1495 [(set (match_dup 3) (match_dup 1))
1496 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1500 (define_insn "subsi3_compare0"
1501 [(set (reg:CC_NOOV CC_REGNUM)
1503 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1504 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1506 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1507 (minus:SI (match_dup 1) (match_dup 2)))]
1512 rsbs%?\\t%0, %2, %1"
1513 [(set_attr "conds" "set")
1514 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1517 (define_insn "subsi3_compare"
1518 [(set (reg:CC CC_REGNUM)
1519 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1520 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1521 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1522 (minus:SI (match_dup 1) (match_dup 2)))]
1527 rsbs%?\\t%0, %2, %1"
1528 [(set_attr "conds" "set")
1529 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1532 (define_expand "subsf3"
1533 [(set (match_operand:SF 0 "s_register_operand" "")
1534 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1535 (match_operand:SF 2 "s_register_operand" "")))]
1536 "TARGET_32BIT && TARGET_HARD_FLOAT"
1540 (define_expand "subdf3"
1541 [(set (match_operand:DF 0 "s_register_operand" "")
1542 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1543 (match_operand:DF 2 "s_register_operand" "")))]
1544 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1549 ;; Multiplication insns
1551 (define_expand "mulhi3"
1552 [(set (match_operand:HI 0 "s_register_operand" "")
1553 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1554 (match_operand:HI 2 "s_register_operand" "")))]
1555 "TARGET_DSP_MULTIPLY"
1558 rtx result = gen_reg_rtx (SImode);
1559 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1560 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1565 (define_expand "mulsi3"
1566 [(set (match_operand:SI 0 "s_register_operand" "")
1567 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1568 (match_operand:SI 1 "s_register_operand" "")))]
1573 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1574 (define_insn "*arm_mulsi3"
1575 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1576 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1577 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1578 "TARGET_32BIT && !arm_arch6"
1579 "mul%?\\t%0, %2, %1"
1580 [(set_attr "type" "mul")
1581 (set_attr "predicable" "yes")]
1584 (define_insn "*arm_mulsi3_v6"
1585 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1586 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1587 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1588 "TARGET_32BIT && arm_arch6"
1589 "mul%?\\t%0, %1, %2"
1590 [(set_attr "type" "mul")
1591 (set_attr "predicable" "yes")
1592 (set_attr "arch" "t2,t2,*")
1593 (set_attr "length" "4")
1594 (set_attr "predicable_short_it" "yes,yes,no")]
1597 (define_insn "*mulsi3_compare0"
1598 [(set (reg:CC_NOOV CC_REGNUM)
1599 (compare:CC_NOOV (mult:SI
1600 (match_operand:SI 2 "s_register_operand" "r,r")
1601 (match_operand:SI 1 "s_register_operand" "%0,r"))
1603 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1604 (mult:SI (match_dup 2) (match_dup 1)))]
1605 "TARGET_ARM && !arm_arch6"
1606 "muls%?\\t%0, %2, %1"
1607 [(set_attr "conds" "set")
1608 (set_attr "type" "muls")]
1611 (define_insn "*mulsi3_compare0_v6"
1612 [(set (reg:CC_NOOV CC_REGNUM)
1613 (compare:CC_NOOV (mult:SI
1614 (match_operand:SI 2 "s_register_operand" "r")
1615 (match_operand:SI 1 "s_register_operand" "r"))
1617 (set (match_operand:SI 0 "s_register_operand" "=r")
1618 (mult:SI (match_dup 2) (match_dup 1)))]
1619 "TARGET_ARM && arm_arch6 && optimize_size"
1620 "muls%?\\t%0, %2, %1"
1621 [(set_attr "conds" "set")
1622 (set_attr "type" "muls")]
1625 (define_insn "*mulsi_compare0_scratch"
1626 [(set (reg:CC_NOOV CC_REGNUM)
1627 (compare:CC_NOOV (mult:SI
1628 (match_operand:SI 2 "s_register_operand" "r,r")
1629 (match_operand:SI 1 "s_register_operand" "%0,r"))
1631 (clobber (match_scratch:SI 0 "=&r,&r"))]
1632 "TARGET_ARM && !arm_arch6"
1633 "muls%?\\t%0, %2, %1"
1634 [(set_attr "conds" "set")
1635 (set_attr "type" "muls")]
1638 (define_insn "*mulsi_compare0_scratch_v6"
1639 [(set (reg:CC_NOOV CC_REGNUM)
1640 (compare:CC_NOOV (mult:SI
1641 (match_operand:SI 2 "s_register_operand" "r")
1642 (match_operand:SI 1 "s_register_operand" "r"))
1644 (clobber (match_scratch:SI 0 "=r"))]
1645 "TARGET_ARM && arm_arch6 && optimize_size"
1646 "muls%?\\t%0, %2, %1"
1647 [(set_attr "conds" "set")
1648 (set_attr "type" "muls")]
1651 ;; Unnamed templates to match MLA instruction.
1653 (define_insn "*mulsi3addsi"
1654 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1656 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1657 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1658 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1659 "TARGET_32BIT && !arm_arch6"
1660 "mla%?\\t%0, %2, %1, %3"
1661 [(set_attr "type" "mla")
1662 (set_attr "predicable" "yes")]
1665 (define_insn "*mulsi3addsi_v6"
1666 [(set (match_operand:SI 0 "s_register_operand" "=r")
1668 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1669 (match_operand:SI 1 "s_register_operand" "r"))
1670 (match_operand:SI 3 "s_register_operand" "r")))]
1671 "TARGET_32BIT && arm_arch6"
1672 "mla%?\\t%0, %2, %1, %3"
1673 [(set_attr "type" "mla")
1674 (set_attr "predicable" "yes")
1675 (set_attr "predicable_short_it" "no")]
1678 (define_insn "*mulsi3addsi_compare0"
1679 [(set (reg:CC_NOOV CC_REGNUM)
1682 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1683 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1684 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1686 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1687 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1689 "TARGET_ARM && arm_arch6"
1690 "mlas%?\\t%0, %2, %1, %3"
1691 [(set_attr "conds" "set")
1692 (set_attr "type" "mlas")]
1695 (define_insn "*mulsi3addsi_compare0_v6"
1696 [(set (reg:CC_NOOV CC_REGNUM)
1699 (match_operand:SI 2 "s_register_operand" "r")
1700 (match_operand:SI 1 "s_register_operand" "r"))
1701 (match_operand:SI 3 "s_register_operand" "r"))
1703 (set (match_operand:SI 0 "s_register_operand" "=r")
1704 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1706 "TARGET_ARM && arm_arch6 && optimize_size"
1707 "mlas%?\\t%0, %2, %1, %3"
1708 [(set_attr "conds" "set")
1709 (set_attr "type" "mlas")]
1712 (define_insn "*mulsi3addsi_compare0_scratch"
1713 [(set (reg:CC_NOOV CC_REGNUM)
1716 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1717 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1718 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1720 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1721 "TARGET_ARM && !arm_arch6"
1722 "mlas%?\\t%0, %2, %1, %3"
1723 [(set_attr "conds" "set")
1724 (set_attr "type" "mlas")]
1727 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1728 [(set (reg:CC_NOOV CC_REGNUM)
1731 (match_operand:SI 2 "s_register_operand" "r")
1732 (match_operand:SI 1 "s_register_operand" "r"))
1733 (match_operand:SI 3 "s_register_operand" "r"))
1735 (clobber (match_scratch:SI 0 "=r"))]
1736 "TARGET_ARM && arm_arch6 && optimize_size"
1737 "mlas%?\\t%0, %2, %1, %3"
1738 [(set_attr "conds" "set")
1739 (set_attr "type" "mlas")]
1742 (define_insn "*mulsi3subsi"
1743 [(set (match_operand:SI 0 "s_register_operand" "=r")
1745 (match_operand:SI 3 "s_register_operand" "r")
1746 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1747 (match_operand:SI 1 "s_register_operand" "r"))))]
1748 "TARGET_32BIT && arm_arch_thumb2"
1749 "mls%?\\t%0, %2, %1, %3"
1750 [(set_attr "type" "mla")
1751 (set_attr "predicable" "yes")
1752 (set_attr "predicable_short_it" "no")]
1755 (define_expand "maddsidi4"
1756 [(set (match_operand:DI 0 "s_register_operand" "")
1759 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1760 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1761 (match_operand:DI 3 "s_register_operand" "")))]
1762 "TARGET_32BIT && arm_arch3m"
1765 (define_insn "*mulsidi3adddi"
1766 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1769 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1770 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1771 (match_operand:DI 1 "s_register_operand" "0")))]
1772 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1773 "smlal%?\\t%Q0, %R0, %3, %2"
1774 [(set_attr "type" "smlal")
1775 (set_attr "predicable" "yes")]
1778 (define_insn "*mulsidi3adddi_v6"
1779 [(set (match_operand:DI 0 "s_register_operand" "=r")
1782 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1783 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1784 (match_operand:DI 1 "s_register_operand" "0")))]
1785 "TARGET_32BIT && arm_arch6"
1786 "smlal%?\\t%Q0, %R0, %3, %2"
1787 [(set_attr "type" "smlal")
1788 (set_attr "predicable" "yes")
1789 (set_attr "predicable_short_it" "no")]
1792 ;; 32x32->64 widening multiply.
1793 ;; As with mulsi3, the only difference between the v3-5 and v6+
1794 ;; versions of these patterns is the requirement that the output not
1795 ;; overlap the inputs, but that still means we have to have a named
1796 ;; expander and two different starred insns.
1798 (define_expand "mulsidi3"
1799 [(set (match_operand:DI 0 "s_register_operand" "")
1801 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1802 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1803 "TARGET_32BIT && arm_arch3m"
1807 (define_insn "*mulsidi3_nov6"
1808 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1810 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1811 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1812 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1813 "smull%?\\t%Q0, %R0, %1, %2"
1814 [(set_attr "type" "smull")
1815 (set_attr "predicable" "yes")]
1818 (define_insn "*mulsidi3_v6"
1819 [(set (match_operand:DI 0 "s_register_operand" "=r")
1821 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1822 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1823 "TARGET_32BIT && arm_arch6"
1824 "smull%?\\t%Q0, %R0, %1, %2"
1825 [(set_attr "type" "smull")
1826 (set_attr "predicable" "yes")
1827 (set_attr "predicable_short_it" "no")]
1830 (define_expand "umulsidi3"
1831 [(set (match_operand:DI 0 "s_register_operand" "")
1833 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1834 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1835 "TARGET_32BIT && arm_arch3m"
1839 (define_insn "*umulsidi3_nov6"
1840 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1842 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1843 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1844 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1845 "umull%?\\t%Q0, %R0, %1, %2"
1846 [(set_attr "type" "umull")
1847 (set_attr "predicable" "yes")]
1850 (define_insn "*umulsidi3_v6"
1851 [(set (match_operand:DI 0 "s_register_operand" "=r")
1853 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1854 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1855 "TARGET_32BIT && arm_arch6"
1856 "umull%?\\t%Q0, %R0, %1, %2"
1857 [(set_attr "type" "umull")
1858 (set_attr "predicable" "yes")
1859 (set_attr "predicable_short_it" "no")]
1862 (define_expand "umaddsidi4"
1863 [(set (match_operand:DI 0 "s_register_operand" "")
1866 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1867 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1868 (match_operand:DI 3 "s_register_operand" "")))]
1869 "TARGET_32BIT && arm_arch3m"
1872 (define_insn "*umulsidi3adddi"
1873 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1876 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1877 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1878 (match_operand:DI 1 "s_register_operand" "0")))]
1879 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1880 "umlal%?\\t%Q0, %R0, %3, %2"
1881 [(set_attr "type" "umlal")
1882 (set_attr "predicable" "yes")]
1885 (define_insn "*umulsidi3adddi_v6"
1886 [(set (match_operand:DI 0 "s_register_operand" "=r")
1889 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1890 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1891 (match_operand:DI 1 "s_register_operand" "0")))]
1892 "TARGET_32BIT && arm_arch6"
1893 "umlal%?\\t%Q0, %R0, %3, %2"
1894 [(set_attr "type" "umlal")
1895 (set_attr "predicable" "yes")
1896 (set_attr "predicable_short_it" "no")]
1899 (define_expand "smulsi3_highpart"
1901 [(set (match_operand:SI 0 "s_register_operand" "")
1905 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1906 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1908 (clobber (match_scratch:SI 3 ""))])]
1909 "TARGET_32BIT && arm_arch3m"
1913 (define_insn "*smulsi3_highpart_nov6"
1914 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1918 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1919 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1921 (clobber (match_scratch:SI 3 "=&r,&r"))]
1922 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1923 "smull%?\\t%3, %0, %2, %1"
1924 [(set_attr "type" "smull")
1925 (set_attr "predicable" "yes")]
1928 (define_insn "*smulsi3_highpart_v6"
1929 [(set (match_operand:SI 0 "s_register_operand" "=r")
1933 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1934 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1936 (clobber (match_scratch:SI 3 "=r"))]
1937 "TARGET_32BIT && arm_arch6"
1938 "smull%?\\t%3, %0, %2, %1"
1939 [(set_attr "type" "smull")
1940 (set_attr "predicable" "yes")
1941 (set_attr "predicable_short_it" "no")]
1944 (define_expand "umulsi3_highpart"
1946 [(set (match_operand:SI 0 "s_register_operand" "")
1950 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1951 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1953 (clobber (match_scratch:SI 3 ""))])]
1954 "TARGET_32BIT && arm_arch3m"
1958 (define_insn "*umulsi3_highpart_nov6"
1959 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1963 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1964 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1966 (clobber (match_scratch:SI 3 "=&r,&r"))]
1967 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1968 "umull%?\\t%3, %0, %2, %1"
1969 [(set_attr "type" "umull")
1970 (set_attr "predicable" "yes")]
1973 (define_insn "*umulsi3_highpart_v6"
1974 [(set (match_operand:SI 0 "s_register_operand" "=r")
1978 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1979 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1981 (clobber (match_scratch:SI 3 "=r"))]
1982 "TARGET_32BIT && arm_arch6"
1983 "umull%?\\t%3, %0, %2, %1"
1984 [(set_attr "type" "umull")
1985 (set_attr "predicable" "yes")
1986 (set_attr "predicable_short_it" "no")]
1989 (define_insn "mulhisi3"
1990 [(set (match_operand:SI 0 "s_register_operand" "=r")
1991 (mult:SI (sign_extend:SI
1992 (match_operand:HI 1 "s_register_operand" "%r"))
1994 (match_operand:HI 2 "s_register_operand" "r"))))]
1995 "TARGET_DSP_MULTIPLY"
1996 "smulbb%?\\t%0, %1, %2"
1997 [(set_attr "type" "smulxy")
1998 (set_attr "predicable" "yes")]
2001 (define_insn "*mulhisi3tb"
2002 [(set (match_operand:SI 0 "s_register_operand" "=r")
2003 (mult:SI (ashiftrt:SI
2004 (match_operand:SI 1 "s_register_operand" "r")
2007 (match_operand:HI 2 "s_register_operand" "r"))))]
2008 "TARGET_DSP_MULTIPLY"
2009 "smultb%?\\t%0, %1, %2"
2010 [(set_attr "type" "smulxy")
2011 (set_attr "predicable" "yes")
2012 (set_attr "predicable_short_it" "no")]
2015 (define_insn "*mulhisi3bt"
2016 [(set (match_operand:SI 0 "s_register_operand" "=r")
2017 (mult:SI (sign_extend:SI
2018 (match_operand:HI 1 "s_register_operand" "r"))
2020 (match_operand:SI 2 "s_register_operand" "r")
2022 "TARGET_DSP_MULTIPLY"
2023 "smulbt%?\\t%0, %1, %2"
2024 [(set_attr "type" "smulxy")
2025 (set_attr "predicable" "yes")
2026 (set_attr "predicable_short_it" "no")]
2029 (define_insn "*mulhisi3tt"
2030 [(set (match_operand:SI 0 "s_register_operand" "=r")
2031 (mult:SI (ashiftrt:SI
2032 (match_operand:SI 1 "s_register_operand" "r")
2035 (match_operand:SI 2 "s_register_operand" "r")
2037 "TARGET_DSP_MULTIPLY"
2038 "smultt%?\\t%0, %1, %2"
2039 [(set_attr "type" "smulxy")
2040 (set_attr "predicable" "yes")
2041 (set_attr "predicable_short_it" "no")]
2044 (define_insn "maddhisi4"
2045 [(set (match_operand:SI 0 "s_register_operand" "=r")
2046 (plus:SI (mult:SI (sign_extend:SI
2047 (match_operand:HI 1 "s_register_operand" "r"))
2049 (match_operand:HI 2 "s_register_operand" "r")))
2050 (match_operand:SI 3 "s_register_operand" "r")))]
2051 "TARGET_DSP_MULTIPLY"
2052 "smlabb%?\\t%0, %1, %2, %3"
2053 [(set_attr "type" "smlaxy")
2054 (set_attr "predicable" "yes")
2055 (set_attr "predicable_short_it" "no")]
2058 ;; Note: there is no maddhisi4ibt because this one is canonical form
2059 (define_insn "*maddhisi4tb"
2060 [(set (match_operand:SI 0 "s_register_operand" "=r")
2061 (plus:SI (mult:SI (ashiftrt:SI
2062 (match_operand:SI 1 "s_register_operand" "r")
2065 (match_operand:HI 2 "s_register_operand" "r")))
2066 (match_operand:SI 3 "s_register_operand" "r")))]
2067 "TARGET_DSP_MULTIPLY"
2068 "smlatb%?\\t%0, %1, %2, %3"
2069 [(set_attr "type" "smlaxy")
2070 (set_attr "predicable" "yes")
2071 (set_attr "predicable_short_it" "no")]
2074 (define_insn "*maddhisi4tt"
2075 [(set (match_operand:SI 0 "s_register_operand" "=r")
2076 (plus:SI (mult:SI (ashiftrt:SI
2077 (match_operand:SI 1 "s_register_operand" "r")
2080 (match_operand:SI 2 "s_register_operand" "r")
2082 (match_operand:SI 3 "s_register_operand" "r")))]
2083 "TARGET_DSP_MULTIPLY"
2084 "smlatt%?\\t%0, %1, %2, %3"
2085 [(set_attr "type" "smlaxy")
2086 (set_attr "predicable" "yes")
2087 (set_attr "predicable_short_it" "no")]
2090 (define_insn "maddhidi4"
2091 [(set (match_operand:DI 0 "s_register_operand" "=r")
2093 (mult:DI (sign_extend:DI
2094 (match_operand:HI 1 "s_register_operand" "r"))
2096 (match_operand:HI 2 "s_register_operand" "r")))
2097 (match_operand:DI 3 "s_register_operand" "0")))]
2098 "TARGET_DSP_MULTIPLY"
2099 "smlalbb%?\\t%Q0, %R0, %1, %2"
2100 [(set_attr "type" "smlalxy")
2101 (set_attr "predicable" "yes")
2102 (set_attr "predicable_short_it" "no")])
2104 ;; Note: there is no maddhidi4ibt because this one is canonical form
2105 (define_insn "*maddhidi4tb"
2106 [(set (match_operand:DI 0 "s_register_operand" "=r")
2108 (mult:DI (sign_extend:DI
2110 (match_operand:SI 1 "s_register_operand" "r")
2113 (match_operand:HI 2 "s_register_operand" "r")))
2114 (match_operand:DI 3 "s_register_operand" "0")))]
2115 "TARGET_DSP_MULTIPLY"
2116 "smlaltb%?\\t%Q0, %R0, %1, %2"
2117 [(set_attr "type" "smlalxy")
2118 (set_attr "predicable" "yes")
2119 (set_attr "predicable_short_it" "no")])
2121 (define_insn "*maddhidi4tt"
2122 [(set (match_operand:DI 0 "s_register_operand" "=r")
2124 (mult:DI (sign_extend:DI
2126 (match_operand:SI 1 "s_register_operand" "r")
2130 (match_operand:SI 2 "s_register_operand" "r")
2132 (match_operand:DI 3 "s_register_operand" "0")))]
2133 "TARGET_DSP_MULTIPLY"
2134 "smlaltt%?\\t%Q0, %R0, %1, %2"
2135 [(set_attr "type" "smlalxy")
2136 (set_attr "predicable" "yes")
2137 (set_attr "predicable_short_it" "no")])
2139 (define_expand "mulsf3"
2140 [(set (match_operand:SF 0 "s_register_operand" "")
2141 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2142 (match_operand:SF 2 "s_register_operand" "")))]
2143 "TARGET_32BIT && TARGET_HARD_FLOAT"
2147 (define_expand "muldf3"
2148 [(set (match_operand:DF 0 "s_register_operand" "")
2149 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2150 (match_operand:DF 2 "s_register_operand" "")))]
2151 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2157 (define_expand "divsf3"
2158 [(set (match_operand:SF 0 "s_register_operand" "")
2159 (div:SF (match_operand:SF 1 "s_register_operand" "")
2160 (match_operand:SF 2 "s_register_operand" "")))]
2161 "TARGET_32BIT && TARGET_HARD_FLOAT"
2164 (define_expand "divdf3"
2165 [(set (match_operand:DF 0 "s_register_operand" "")
2166 (div:DF (match_operand:DF 1 "s_register_operand" "")
2167 (match_operand:DF 2 "s_register_operand" "")))]
2168 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2171 ;; Boolean and,ior,xor insns
2173 ;; Split up double word logical operations
2175 ;; Split up simple DImode logical operations. Simply perform the logical
2176 ;; operation on the upper and lower halves of the registers.
2178 [(set (match_operand:DI 0 "s_register_operand" "")
2179 (match_operator:DI 6 "logical_binary_operator"
2180 [(match_operand:DI 1 "s_register_operand" "")
2181 (match_operand:DI 2 "s_register_operand" "")]))]
2182 "TARGET_32BIT && reload_completed
2183 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2184 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2185 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2186 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2189 operands[3] = gen_highpart (SImode, operands[0]);
2190 operands[0] = gen_lowpart (SImode, operands[0]);
2191 operands[4] = gen_highpart (SImode, operands[1]);
2192 operands[1] = gen_lowpart (SImode, operands[1]);
2193 operands[5] = gen_highpart (SImode, operands[2]);
2194 operands[2] = gen_lowpart (SImode, operands[2]);
2199 [(set (match_operand:DI 0 "s_register_operand" "")
2200 (match_operator:DI 6 "logical_binary_operator"
2201 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2202 (match_operand:DI 1 "s_register_operand" "")]))]
2203 "TARGET_32BIT && reload_completed"
2204 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2205 (set (match_dup 3) (match_op_dup:SI 6
2206 [(ashiftrt:SI (match_dup 2) (const_int 31))
2210 operands[3] = gen_highpart (SImode, operands[0]);
2211 operands[0] = gen_lowpart (SImode, operands[0]);
2212 operands[4] = gen_highpart (SImode, operands[1]);
2213 operands[1] = gen_lowpart (SImode, operands[1]);
2214 operands[5] = gen_highpart (SImode, operands[2]);
2215 operands[2] = gen_lowpart (SImode, operands[2]);
2219 ;; The zero extend of operand 2 means we can just copy the high part of
2220 ;; operand1 into operand0.
2222 [(set (match_operand:DI 0 "s_register_operand" "")
2224 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2225 (match_operand:DI 1 "s_register_operand" "")))]
2226 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2227 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2228 (set (match_dup 3) (match_dup 4))]
2231 operands[4] = gen_highpart (SImode, operands[1]);
2232 operands[3] = gen_highpart (SImode, operands[0]);
2233 operands[0] = gen_lowpart (SImode, operands[0]);
2234 operands[1] = gen_lowpart (SImode, operands[1]);
2238 ;; The zero extend of operand 2 means we can just copy the high part of
2239 ;; operand1 into operand0.
2241 [(set (match_operand:DI 0 "s_register_operand" "")
2243 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2244 (match_operand:DI 1 "s_register_operand" "")))]
2245 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2246 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2247 (set (match_dup 3) (match_dup 4))]
2250 operands[4] = gen_highpart (SImode, operands[1]);
2251 operands[3] = gen_highpart (SImode, operands[0]);
2252 operands[0] = gen_lowpart (SImode, operands[0]);
2253 operands[1] = gen_lowpart (SImode, operands[1]);
2257 (define_expand "anddi3"
2258 [(set (match_operand:DI 0 "s_register_operand" "")
2259 (and:DI (match_operand:DI 1 "s_register_operand" "")
2260 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2265 (define_insn_and_split "*anddi3_insn"
2266 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2267 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2268 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2269 "TARGET_32BIT && !TARGET_IWMMXT"
2271 switch (which_alternative)
2273 case 0: /* fall through */
2274 case 6: return "vand\t%P0, %P1, %P2";
2275 case 1: /* fall through */
2276 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2277 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2281 case 5: /* fall through */
2283 default: gcc_unreachable ();
2286 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2287 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2288 [(set (match_dup 3) (match_dup 4))
2289 (set (match_dup 5) (match_dup 6))]
2292 operands[3] = gen_lowpart (SImode, operands[0]);
2293 operands[5] = gen_highpart (SImode, operands[0]);
2295 operands[4] = simplify_gen_binary (AND, SImode,
2296 gen_lowpart (SImode, operands[1]),
2297 gen_lowpart (SImode, operands[2]));
2298 operands[6] = simplify_gen_binary (AND, SImode,
2299 gen_highpart (SImode, operands[1]),
2300 gen_highpart_mode (SImode, DImode, operands[2]));
2303 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2304 multiple,multiple,neon_logic,neon_logic")
2305 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2306 avoid_neon_for_64bits,avoid_neon_for_64bits")
2307 (set_attr "length" "*,*,8,8,8,8,*,*")
2311 (define_insn_and_split "*anddi_zesidi_di"
2312 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2313 (and:DI (zero_extend:DI
2314 (match_operand:SI 2 "s_register_operand" "r,r"))
2315 (match_operand:DI 1 "s_register_operand" "0,r")))]
2318 "TARGET_32BIT && reload_completed"
2319 ; The zero extend of operand 2 clears the high word of the output
2321 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2322 (set (match_dup 3) (const_int 0))]
2325 operands[3] = gen_highpart (SImode, operands[0]);
2326 operands[0] = gen_lowpart (SImode, operands[0]);
2327 operands[1] = gen_lowpart (SImode, operands[1]);
2329 [(set_attr "length" "8")
2330 (set_attr "type" "multiple")]
2333 (define_insn "*anddi_sesdi_di"
2334 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2335 (and:DI (sign_extend:DI
2336 (match_operand:SI 2 "s_register_operand" "r,r"))
2337 (match_operand:DI 1 "s_register_operand" "0,r")))]
2340 [(set_attr "length" "8")
2341 (set_attr "type" "multiple")]
2344 (define_expand "andsi3"
2345 [(set (match_operand:SI 0 "s_register_operand" "")
2346 (and:SI (match_operand:SI 1 "s_register_operand" "")
2347 (match_operand:SI 2 "reg_or_int_operand" "")))]
2352 if (CONST_INT_P (operands[2]))
2354 if (INTVAL (operands[2]) == 255 && arm_arch6)
2356 operands[1] = convert_to_mode (QImode, operands[1], 1);
2357 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2361 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2362 operands[2] = force_reg (SImode, operands[2]);
2365 arm_split_constant (AND, SImode, NULL_RTX,
2366 INTVAL (operands[2]), operands[0],
2368 optimize && can_create_pseudo_p ());
2374 else /* TARGET_THUMB1 */
2376 if (!CONST_INT_P (operands[2]))
2378 rtx tmp = force_reg (SImode, operands[2]);
2379 if (rtx_equal_p (operands[0], operands[1]))
2383 operands[2] = operands[1];
2391 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2393 operands[2] = force_reg (SImode,
2394 GEN_INT (~INTVAL (operands[2])));
2396 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2401 for (i = 9; i <= 31; i++)
2403 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2405 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2409 else if ((HOST_WIDE_INT_1 << i) - 1
2410 == ~INTVAL (operands[2]))
2412 rtx shift = GEN_INT (i);
2413 rtx reg = gen_reg_rtx (SImode);
2415 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2416 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2422 operands[2] = force_reg (SImode, operands[2]);
2428 ; ??? Check split length for Thumb-2
2429 (define_insn_and_split "*arm_andsi3_insn"
2430 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2431 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2432 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2437 bic%?\\t%0, %1, #%B2
2441 && CONST_INT_P (operands[2])
2442 && !(const_ok_for_arm (INTVAL (operands[2]))
2443 || const_ok_for_arm (~INTVAL (operands[2])))"
2444 [(clobber (const_int 0))]
2446 arm_split_constant (AND, SImode, curr_insn,
2447 INTVAL (operands[2]), operands[0], operands[1], 0);
2450 [(set_attr "length" "4,4,4,4,16")
2451 (set_attr "predicable" "yes")
2452 (set_attr "predicable_short_it" "no,yes,no,no,no")
2453 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2456 (define_insn "*andsi3_compare0"
2457 [(set (reg:CC_NOOV CC_REGNUM)
2459 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2460 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2462 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2463 (and:SI (match_dup 1) (match_dup 2)))]
2467 bics%?\\t%0, %1, #%B2
2468 ands%?\\t%0, %1, %2"
2469 [(set_attr "conds" "set")
2470 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2473 (define_insn "*andsi3_compare0_scratch"
2474 [(set (reg:CC_NOOV CC_REGNUM)
2476 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2477 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2479 (clobber (match_scratch:SI 2 "=X,r,X"))]
2483 bics%?\\t%2, %0, #%B1
2485 [(set_attr "conds" "set")
2486 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2489 (define_insn "*zeroextractsi_compare0_scratch"
2490 [(set (reg:CC_NOOV CC_REGNUM)
2491 (compare:CC_NOOV (zero_extract:SI
2492 (match_operand:SI 0 "s_register_operand" "r")
2493 (match_operand 1 "const_int_operand" "n")
2494 (match_operand 2 "const_int_operand" "n"))
2497 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2498 && INTVAL (operands[1]) > 0
2499 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2500 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2502 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2503 << INTVAL (operands[2]));
2504 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2507 [(set_attr "conds" "set")
2508 (set_attr "predicable" "yes")
2509 (set_attr "predicable_short_it" "no")
2510 (set_attr "type" "logics_imm")]
2513 (define_insn_and_split "*ne_zeroextractsi"
2514 [(set (match_operand:SI 0 "s_register_operand" "=r")
2515 (ne:SI (zero_extract:SI
2516 (match_operand:SI 1 "s_register_operand" "r")
2517 (match_operand:SI 2 "const_int_operand" "n")
2518 (match_operand:SI 3 "const_int_operand" "n"))
2520 (clobber (reg:CC CC_REGNUM))]
2522 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2523 && INTVAL (operands[2]) > 0
2524 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2525 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2528 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2529 && INTVAL (operands[2]) > 0
2530 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2531 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2532 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2533 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2535 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2537 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2538 (match_dup 0) (const_int 1)))]
2540 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2541 << INTVAL (operands[3]));
2543 [(set_attr "conds" "clob")
2544 (set (attr "length")
2545 (if_then_else (eq_attr "is_thumb" "yes")
2548 (set_attr "type" "multiple")]
2551 (define_insn_and_split "*ne_zeroextractsi_shifted"
2552 [(set (match_operand:SI 0 "s_register_operand" "=r")
2553 (ne:SI (zero_extract:SI
2554 (match_operand:SI 1 "s_register_operand" "r")
2555 (match_operand:SI 2 "const_int_operand" "n")
2558 (clobber (reg:CC CC_REGNUM))]
2562 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2563 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2565 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2567 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2568 (match_dup 0) (const_int 1)))]
2570 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2572 [(set_attr "conds" "clob")
2573 (set_attr "length" "8")
2574 (set_attr "type" "multiple")]
2577 (define_insn_and_split "*ite_ne_zeroextractsi"
2578 [(set (match_operand:SI 0 "s_register_operand" "=r")
2579 (if_then_else:SI (ne (zero_extract:SI
2580 (match_operand:SI 1 "s_register_operand" "r")
2581 (match_operand:SI 2 "const_int_operand" "n")
2582 (match_operand:SI 3 "const_int_operand" "n"))
2584 (match_operand:SI 4 "arm_not_operand" "rIK")
2586 (clobber (reg:CC CC_REGNUM))]
2588 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2589 && INTVAL (operands[2]) > 0
2590 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2591 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2592 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2595 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2596 && INTVAL (operands[2]) > 0
2597 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2598 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2599 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2600 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2601 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2603 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2605 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2606 (match_dup 0) (match_dup 4)))]
2608 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2609 << INTVAL (operands[3]));
2611 [(set_attr "conds" "clob")
2612 (set_attr "length" "8")
2613 (set_attr "type" "multiple")]
2616 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2617 [(set (match_operand:SI 0 "s_register_operand" "=r")
2618 (if_then_else:SI (ne (zero_extract:SI
2619 (match_operand:SI 1 "s_register_operand" "r")
2620 (match_operand:SI 2 "const_int_operand" "n")
2623 (match_operand:SI 3 "arm_not_operand" "rIK")
2625 (clobber (reg:CC CC_REGNUM))]
2626 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2628 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2629 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2630 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2632 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2634 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2635 (match_dup 0) (match_dup 3)))]
2637 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2639 [(set_attr "conds" "clob")
2640 (set_attr "length" "8")
2641 (set_attr "type" "multiple")]
2644 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2646 [(set (match_operand:SI 0 "s_register_operand" "")
2647 (match_operator:SI 1 "shiftable_operator"
2648 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2649 (match_operand:SI 3 "const_int_operand" "")
2650 (match_operand:SI 4 "const_int_operand" ""))
2651 (match_operand:SI 5 "s_register_operand" "")]))
2652 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2654 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2657 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2660 HOST_WIDE_INT temp = INTVAL (operands[3]);
2662 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2663 operands[4] = GEN_INT (32 - temp);
2668 [(set (match_operand:SI 0 "s_register_operand" "")
2669 (match_operator:SI 1 "shiftable_operator"
2670 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2671 (match_operand:SI 3 "const_int_operand" "")
2672 (match_operand:SI 4 "const_int_operand" ""))
2673 (match_operand:SI 5 "s_register_operand" "")]))
2674 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2676 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2679 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2682 HOST_WIDE_INT temp = INTVAL (operands[3]);
2684 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2685 operands[4] = GEN_INT (32 - temp);
2689 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2690 ;;; represented by the bitfield, then this will produce incorrect results.
2691 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2692 ;;; which have a real bit-field insert instruction, the truncation happens
2693 ;;; in the bit-field insert instruction itself. Since arm does not have a
2694 ;;; bit-field insert instruction, we would have to emit code here to truncate
2695 ;;; the value before we insert. This loses some of the advantage of having
2696 ;;; this insv pattern, so this pattern needs to be reevalutated.
2698 (define_expand "insv"
2699 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2700 (match_operand 1 "general_operand" "")
2701 (match_operand 2 "general_operand" ""))
2702 (match_operand 3 "reg_or_int_operand" ""))]
2703 "TARGET_ARM || arm_arch_thumb2"
2706 int start_bit = INTVAL (operands[2]);
2707 int width = INTVAL (operands[1]);
2708 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2709 rtx target, subtarget;
2711 if (arm_arch_thumb2)
2713 if (unaligned_access && MEM_P (operands[0])
2714 && s_register_operand (operands[3], GET_MODE (operands[3]))
2715 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2719 if (BYTES_BIG_ENDIAN)
2720 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2725 base_addr = adjust_address (operands[0], SImode,
2726 start_bit / BITS_PER_UNIT);
2727 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2731 rtx tmp = gen_reg_rtx (HImode);
2733 base_addr = adjust_address (operands[0], HImode,
2734 start_bit / BITS_PER_UNIT);
2735 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2736 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2740 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2742 bool use_bfi = TRUE;
2744 if (CONST_INT_P (operands[3]))
2746 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2750 emit_insn (gen_insv_zero (operands[0], operands[1],
2755 /* See if the set can be done with a single orr instruction. */
2756 if (val == mask && const_ok_for_arm (val << start_bit))
2762 if (!REG_P (operands[3]))
2763 operands[3] = force_reg (SImode, operands[3]);
2765 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2774 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2777 target = copy_rtx (operands[0]);
2778 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2779 subreg as the final target. */
2780 if (GET_CODE (target) == SUBREG)
2782 subtarget = gen_reg_rtx (SImode);
2783 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2784 < GET_MODE_SIZE (SImode))
2785 target = SUBREG_REG (target);
2790 if (CONST_INT_P (operands[3]))
2792 /* Since we are inserting a known constant, we may be able to
2793 reduce the number of bits that we have to clear so that
2794 the mask becomes simple. */
2795 /* ??? This code does not check to see if the new mask is actually
2796 simpler. It may not be. */
2797 rtx op1 = gen_reg_rtx (SImode);
2798 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2799 start of this pattern. */
2800 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2801 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2803 emit_insn (gen_andsi3 (op1, operands[0],
2804 gen_int_mode (~mask2, SImode)));
2805 emit_insn (gen_iorsi3 (subtarget, op1,
2806 gen_int_mode (op3_value << start_bit, SImode)));
2808 else if (start_bit == 0
2809 && !(const_ok_for_arm (mask)
2810 || const_ok_for_arm (~mask)))
2812 /* A Trick, since we are setting the bottom bits in the word,
2813 we can shift operand[3] up, operand[0] down, OR them together
2814 and rotate the result back again. This takes 3 insns, and
2815 the third might be mergeable into another op. */
2816 /* The shift up copes with the possibility that operand[3] is
2817 wider than the bitfield. */
2818 rtx op0 = gen_reg_rtx (SImode);
2819 rtx op1 = gen_reg_rtx (SImode);
2821 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2822 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2823 emit_insn (gen_iorsi3 (op1, op1, op0));
2824 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2826 else if ((width + start_bit == 32)
2827 && !(const_ok_for_arm (mask)
2828 || const_ok_for_arm (~mask)))
2830 /* Similar trick, but slightly less efficient. */
2832 rtx op0 = gen_reg_rtx (SImode);
2833 rtx op1 = gen_reg_rtx (SImode);
2835 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2836 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2837 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2838 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2842 rtx op0 = gen_int_mode (mask, SImode);
2843 rtx op1 = gen_reg_rtx (SImode);
2844 rtx op2 = gen_reg_rtx (SImode);
2846 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2848 rtx tmp = gen_reg_rtx (SImode);
2850 emit_insn (gen_movsi (tmp, op0));
2854 /* Mask out any bits in operand[3] that are not needed. */
2855 emit_insn (gen_andsi3 (op1, operands[3], op0));
2857 if (CONST_INT_P (op0)
2858 && (const_ok_for_arm (mask << start_bit)
2859 || const_ok_for_arm (~(mask << start_bit))))
2861 op0 = gen_int_mode (~(mask << start_bit), SImode);
2862 emit_insn (gen_andsi3 (op2, operands[0], op0));
2866 if (CONST_INT_P (op0))
2868 rtx tmp = gen_reg_rtx (SImode);
2870 emit_insn (gen_movsi (tmp, op0));
2875 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2877 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2881 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2883 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2886 if (subtarget != target)
2888 /* If TARGET is still a SUBREG, then it must be wider than a word,
2889 so we must be careful only to set the subword we were asked to. */
2890 if (GET_CODE (target) == SUBREG)
2891 emit_move_insn (target, subtarget);
2893 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2900 (define_insn "insv_zero"
2901 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2902 (match_operand:SI 1 "const_int_M_operand" "M")
2903 (match_operand:SI 2 "const_int_M_operand" "M"))
2907 [(set_attr "length" "4")
2908 (set_attr "predicable" "yes")
2909 (set_attr "predicable_short_it" "no")
2910 (set_attr "type" "bfm")]
2913 (define_insn "insv_t2"
2914 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2915 (match_operand:SI 1 "const_int_M_operand" "M")
2916 (match_operand:SI 2 "const_int_M_operand" "M"))
2917 (match_operand:SI 3 "s_register_operand" "r"))]
2919 "bfi%?\t%0, %3, %2, %1"
2920 [(set_attr "length" "4")
2921 (set_attr "predicable" "yes")
2922 (set_attr "predicable_short_it" "no")
2923 (set_attr "type" "bfm")]
2926 ; constants for op 2 will never be given to these patterns.
2927 (define_insn_and_split "*anddi_notdi_di"
2928 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2929 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2930 (match_operand:DI 2 "s_register_operand" "r,0")))]
2933 "TARGET_32BIT && reload_completed
2934 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2935 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2936 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2937 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2940 operands[3] = gen_highpart (SImode, operands[0]);
2941 operands[0] = gen_lowpart (SImode, operands[0]);
2942 operands[4] = gen_highpart (SImode, operands[1]);
2943 operands[1] = gen_lowpart (SImode, operands[1]);
2944 operands[5] = gen_highpart (SImode, operands[2]);
2945 operands[2] = gen_lowpart (SImode, operands[2]);
2947 [(set_attr "length" "8")
2948 (set_attr "predicable" "yes")
2949 (set_attr "type" "multiple")]
2952 (define_insn_and_split "*anddi_notzesidi_di"
2953 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2954 (and:DI (not:DI (zero_extend:DI
2955 (match_operand:SI 2 "s_register_operand" "r,r")))
2956 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2959 bic%?\\t%Q0, %Q1, %2
2961 ; (not (zero_extend ...)) allows us to just copy the high word from
2962 ; operand1 to operand0.
2965 && operands[0] != operands[1]"
2966 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2967 (set (match_dup 3) (match_dup 4))]
2970 operands[3] = gen_highpart (SImode, operands[0]);
2971 operands[0] = gen_lowpart (SImode, operands[0]);
2972 operands[4] = gen_highpart (SImode, operands[1]);
2973 operands[1] = gen_lowpart (SImode, operands[1]);
2975 [(set_attr "length" "4,8")
2976 (set_attr "predicable" "yes")
2977 (set_attr "predicable_short_it" "no")
2978 (set_attr "type" "multiple")]
2981 (define_insn_and_split "*anddi_notdi_zesidi"
2982 [(set (match_operand:DI 0 "s_register_operand" "=r")
2983 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2985 (match_operand:SI 1 "s_register_operand" "r"))))]
2988 "TARGET_32BIT && reload_completed"
2989 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2990 (set (match_dup 3) (const_int 0))]
2993 operands[3] = gen_highpart (SImode, operands[0]);
2994 operands[0] = gen_lowpart (SImode, operands[0]);
2995 operands[2] = gen_lowpart (SImode, operands[2]);
2997 [(set_attr "length" "8")
2998 (set_attr "predicable" "yes")
2999 (set_attr "predicable_short_it" "no")
3000 (set_attr "type" "multiple")]
3003 (define_insn_and_split "*anddi_notsesidi_di"
3004 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3005 (and:DI (not:DI (sign_extend:DI
3006 (match_operand:SI 2 "s_register_operand" "r,r")))
3007 (match_operand:DI 1 "s_register_operand" "0,r")))]
3010 "TARGET_32BIT && reload_completed"
3011 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3012 (set (match_dup 3) (and:SI (not:SI
3013 (ashiftrt:SI (match_dup 2) (const_int 31)))
3017 operands[3] = gen_highpart (SImode, operands[0]);
3018 operands[0] = gen_lowpart (SImode, operands[0]);
3019 operands[4] = gen_highpart (SImode, operands[1]);
3020 operands[1] = gen_lowpart (SImode, operands[1]);
3022 [(set_attr "length" "8")
3023 (set_attr "predicable" "yes")
3024 (set_attr "predicable_short_it" "no")
3025 (set_attr "type" "multiple")]
3028 (define_insn "andsi_notsi_si"
3029 [(set (match_operand:SI 0 "s_register_operand" "=r")
3030 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3031 (match_operand:SI 1 "s_register_operand" "r")))]
3033 "bic%?\\t%0, %1, %2"
3034 [(set_attr "predicable" "yes")
3035 (set_attr "predicable_short_it" "no")
3036 (set_attr "type" "logic_reg")]
3039 (define_insn "andsi_not_shiftsi_si"
3040 [(set (match_operand:SI 0 "s_register_operand" "=r")
3041 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3042 [(match_operand:SI 2 "s_register_operand" "r")
3043 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3044 (match_operand:SI 1 "s_register_operand" "r")))]
3046 "bic%?\\t%0, %1, %2%S4"
3047 [(set_attr "predicable" "yes")
3048 (set_attr "shift" "2")
3049 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3050 (const_string "logic_shift_imm")
3051 (const_string "logic_shift_reg")))]
3054 ;; Shifted bics pattern used to set up CC status register and not reusing
3055 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3056 ;; does not support shift by register.
3057 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3058 [(set (reg:CC_NOOV CC_REGNUM)
3060 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3061 [(match_operand:SI 1 "s_register_operand" "r")
3062 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3063 (match_operand:SI 3 "s_register_operand" "r"))
3065 (clobber (match_scratch:SI 4 "=r"))]
3066 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3067 "bics%?\\t%4, %3, %1%S0"
3068 [(set_attr "predicable" "yes")
3069 (set_attr "predicable_short_it" "no")
3070 (set_attr "conds" "set")
3071 (set_attr "shift" "1")
3072 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3073 (const_string "logic_shift_imm")
3074 (const_string "logic_shift_reg")))]
3077 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3078 ;; getting reused later.
3079 (define_insn "andsi_not_shiftsi_si_scc"
3080 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3082 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3083 [(match_operand:SI 1 "s_register_operand" "r")
3084 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3085 (match_operand:SI 3 "s_register_operand" "r"))
3087 (set (match_operand:SI 4 "s_register_operand" "=r")
3088 (and:SI (not:SI (match_op_dup 0
3092 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3093 "bics%?\\t%4, %3, %1%S0"
3094 [(set_attr "predicable" "yes")
3095 (set_attr "predicable_short_it" "no")
3096 (set_attr "conds" "set")
3097 (set_attr "shift" "1")
3098 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3099 (const_string "logic_shift_imm")
3100 (const_string "logic_shift_reg")))]
3103 (define_insn "*andsi_notsi_si_compare0"
3104 [(set (reg:CC_NOOV CC_REGNUM)
3106 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3107 (match_operand:SI 1 "s_register_operand" "r"))
3109 (set (match_operand:SI 0 "s_register_operand" "=r")
3110 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3113 [(set_attr "conds" "set")
3114 (set_attr "type" "logics_shift_reg")]
3117 (define_insn "*andsi_notsi_si_compare0_scratch"
3118 [(set (reg:CC_NOOV CC_REGNUM)
3120 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3121 (match_operand:SI 1 "s_register_operand" "r"))
3123 (clobber (match_scratch:SI 0 "=r"))]
3126 [(set_attr "conds" "set")
3127 (set_attr "type" "logics_shift_reg")]
3130 (define_expand "iordi3"
3131 [(set (match_operand:DI 0 "s_register_operand" "")
3132 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3133 (match_operand:DI 2 "neon_logic_op2" "")))]
3138 (define_insn_and_split "*iordi3_insn"
3139 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3140 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3141 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3142 "TARGET_32BIT && !TARGET_IWMMXT"
3144 switch (which_alternative)
3146 case 0: /* fall through */
3147 case 6: return "vorr\t%P0, %P1, %P2";
3148 case 1: /* fall through */
3149 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3150 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3156 default: gcc_unreachable ();
3159 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3160 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3161 [(set (match_dup 3) (match_dup 4))
3162 (set (match_dup 5) (match_dup 6))]
3165 operands[3] = gen_lowpart (SImode, operands[0]);
3166 operands[5] = gen_highpart (SImode, operands[0]);
3168 operands[4] = simplify_gen_binary (IOR, SImode,
3169 gen_lowpart (SImode, operands[1]),
3170 gen_lowpart (SImode, operands[2]));
3171 operands[6] = simplify_gen_binary (IOR, SImode,
3172 gen_highpart (SImode, operands[1]),
3173 gen_highpart_mode (SImode, DImode, operands[2]));
3176 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3177 multiple,neon_logic,neon_logic")
3178 (set_attr "length" "*,*,8,8,8,8,*,*")
3179 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3182 (define_insn "*iordi_zesidi_di"
3183 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3184 (ior:DI (zero_extend:DI
3185 (match_operand:SI 2 "s_register_operand" "r,r"))
3186 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3189 orr%?\\t%Q0, %Q1, %2
3191 [(set_attr "length" "4,8")
3192 (set_attr "predicable" "yes")
3193 (set_attr "predicable_short_it" "no")
3194 (set_attr "type" "logic_reg,multiple")]
3197 (define_insn "*iordi_sesidi_di"
3198 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3199 (ior:DI (sign_extend:DI
3200 (match_operand:SI 2 "s_register_operand" "r,r"))
3201 (match_operand:DI 1 "s_register_operand" "0,r")))]
3204 [(set_attr "length" "8")
3205 (set_attr "predicable" "yes")
3206 (set_attr "type" "multiple")]
3209 (define_expand "iorsi3"
3210 [(set (match_operand:SI 0 "s_register_operand" "")
3211 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3212 (match_operand:SI 2 "reg_or_int_operand" "")))]
3215 if (CONST_INT_P (operands[2]))
3219 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3220 operands[2] = force_reg (SImode, operands[2]);
3223 arm_split_constant (IOR, SImode, NULL_RTX,
3224 INTVAL (operands[2]), operands[0],
3226 optimize && can_create_pseudo_p ());
3230 else /* TARGET_THUMB1 */
3232 rtx tmp = force_reg (SImode, operands[2]);
3233 if (rtx_equal_p (operands[0], operands[1]))
3237 operands[2] = operands[1];
3245 (define_insn_and_split "*iorsi3_insn"
3246 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3247 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3248 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3253 orn%?\\t%0, %1, #%B2
3257 && CONST_INT_P (operands[2])
3258 && !(const_ok_for_arm (INTVAL (operands[2]))
3259 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3260 [(clobber (const_int 0))]
3262 arm_split_constant (IOR, SImode, curr_insn,
3263 INTVAL (operands[2]), operands[0], operands[1], 0);
3266 [(set_attr "length" "4,4,4,4,16")
3267 (set_attr "arch" "32,t2,t2,32,32")
3268 (set_attr "predicable" "yes")
3269 (set_attr "predicable_short_it" "no,yes,no,no,no")
3270 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3274 [(match_scratch:SI 3 "r")
3275 (set (match_operand:SI 0 "arm_general_register_operand" "")
3276 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3277 (match_operand:SI 2 "const_int_operand" "")))]
3279 && !const_ok_for_arm (INTVAL (operands[2]))
3280 && const_ok_for_arm (~INTVAL (operands[2]))"
3281 [(set (match_dup 3) (match_dup 2))
3282 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3286 (define_insn "*iorsi3_compare0"
3287 [(set (reg:CC_NOOV CC_REGNUM)
3288 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3289 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3291 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3292 (ior:SI (match_dup 1) (match_dup 2)))]
3294 "orrs%?\\t%0, %1, %2"
3295 [(set_attr "conds" "set")
3296 (set_attr "type" "logics_imm,logics_reg")]
3299 (define_insn "*iorsi3_compare0_scratch"
3300 [(set (reg:CC_NOOV CC_REGNUM)
3301 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3302 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3304 (clobber (match_scratch:SI 0 "=r,r"))]
3306 "orrs%?\\t%0, %1, %2"
3307 [(set_attr "conds" "set")
3308 (set_attr "type" "logics_imm,logics_reg")]
3311 (define_expand "xordi3"
3312 [(set (match_operand:DI 0 "s_register_operand" "")
3313 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3314 (match_operand:DI 2 "arm_xordi_operand" "")))]
3319 (define_insn_and_split "*xordi3_insn"
3320 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3321 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3322 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3323 "TARGET_32BIT && !TARGET_IWMMXT"
3325 switch (which_alternative)
3330 case 4: /* fall through */
3332 case 0: /* fall through */
3333 case 5: return "veor\t%P0, %P1, %P2";
3334 default: gcc_unreachable ();
3337 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3338 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3339 [(set (match_dup 3) (match_dup 4))
3340 (set (match_dup 5) (match_dup 6))]
3343 operands[3] = gen_lowpart (SImode, operands[0]);
3344 operands[5] = gen_highpart (SImode, operands[0]);
3346 operands[4] = simplify_gen_binary (XOR, SImode,
3347 gen_lowpart (SImode, operands[1]),
3348 gen_lowpart (SImode, operands[2]));
3349 operands[6] = simplify_gen_binary (XOR, SImode,
3350 gen_highpart (SImode, operands[1]),
3351 gen_highpart_mode (SImode, DImode, operands[2]));
3354 [(set_attr "length" "*,8,8,8,8,*")
3355 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3356 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3359 (define_insn "*xordi_zesidi_di"
3360 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3361 (xor:DI (zero_extend:DI
3362 (match_operand:SI 2 "s_register_operand" "r,r"))
3363 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3366 eor%?\\t%Q0, %Q1, %2
3368 [(set_attr "length" "4,8")
3369 (set_attr "predicable" "yes")
3370 (set_attr "predicable_short_it" "no")
3371 (set_attr "type" "logic_reg")]
3374 (define_insn "*xordi_sesidi_di"
3375 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3376 (xor:DI (sign_extend:DI
3377 (match_operand:SI 2 "s_register_operand" "r,r"))
3378 (match_operand:DI 1 "s_register_operand" "0,r")))]
3381 [(set_attr "length" "8")
3382 (set_attr "predicable" "yes")
3383 (set_attr "type" "multiple")]
3386 (define_expand "xorsi3"
3387 [(set (match_operand:SI 0 "s_register_operand" "")
3388 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3389 (match_operand:SI 2 "reg_or_int_operand" "")))]
3391 "if (CONST_INT_P (operands[2]))
3395 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3396 operands[2] = force_reg (SImode, operands[2]);
3399 arm_split_constant (XOR, SImode, NULL_RTX,
3400 INTVAL (operands[2]), operands[0],
3402 optimize && can_create_pseudo_p ());
3406 else /* TARGET_THUMB1 */
3408 rtx tmp = force_reg (SImode, operands[2]);
3409 if (rtx_equal_p (operands[0], operands[1]))
3413 operands[2] = operands[1];
3420 (define_insn_and_split "*arm_xorsi3"
3421 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3422 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3423 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3431 && CONST_INT_P (operands[2])
3432 && !const_ok_for_arm (INTVAL (operands[2]))"
3433 [(clobber (const_int 0))]
3435 arm_split_constant (XOR, SImode, curr_insn,
3436 INTVAL (operands[2]), operands[0], operands[1], 0);
3439 [(set_attr "length" "4,4,4,16")
3440 (set_attr "predicable" "yes")
3441 (set_attr "predicable_short_it" "no,yes,no,no")
3442 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3445 (define_insn "*xorsi3_compare0"
3446 [(set (reg:CC_NOOV CC_REGNUM)
3447 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3448 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3450 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3451 (xor:SI (match_dup 1) (match_dup 2)))]
3453 "eors%?\\t%0, %1, %2"
3454 [(set_attr "conds" "set")
3455 (set_attr "type" "logics_imm,logics_reg")]
3458 (define_insn "*xorsi3_compare0_scratch"
3459 [(set (reg:CC_NOOV CC_REGNUM)
3460 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3461 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3465 [(set_attr "conds" "set")
3466 (set_attr "type" "logics_imm,logics_reg")]
3469 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3470 ; (NOT D) we can sometimes merge the final NOT into one of the following
3474 [(set (match_operand:SI 0 "s_register_operand" "")
3475 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3476 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3477 (match_operand:SI 3 "arm_rhs_operand" "")))
3478 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3480 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3481 (not:SI (match_dup 3))))
3482 (set (match_dup 0) (not:SI (match_dup 4)))]
3486 (define_insn_and_split "*andsi_iorsi3_notsi"
3487 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3488 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3489 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3490 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3492 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3493 "&& reload_completed"
3494 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3495 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3497 /* If operands[3] is a constant make sure to fold the NOT into it
3498 to avoid creating a NOT of a CONST_INT. */
3499 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3500 if (CONST_INT_P (not_rtx))
3502 operands[4] = operands[0];
3503 operands[5] = not_rtx;
3507 operands[5] = operands[0];
3508 operands[4] = not_rtx;
3511 [(set_attr "length" "8")
3512 (set_attr "ce_count" "2")
3513 (set_attr "predicable" "yes")
3514 (set_attr "predicable_short_it" "no")
3515 (set_attr "type" "multiple")]
3518 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3519 ; insns are available?
3521 [(set (match_operand:SI 0 "s_register_operand" "")
3522 (match_operator:SI 1 "logical_binary_operator"
3523 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3524 (match_operand:SI 3 "const_int_operand" "")
3525 (match_operand:SI 4 "const_int_operand" ""))
3526 (match_operator:SI 9 "logical_binary_operator"
3527 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3528 (match_operand:SI 6 "const_int_operand" ""))
3529 (match_operand:SI 7 "s_register_operand" "")])]))
3530 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3532 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3533 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3536 [(ashift:SI (match_dup 2) (match_dup 4))
3540 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3543 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3547 [(set (match_operand:SI 0 "s_register_operand" "")
3548 (match_operator:SI 1 "logical_binary_operator"
3549 [(match_operator:SI 9 "logical_binary_operator"
3550 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3551 (match_operand:SI 6 "const_int_operand" ""))
3552 (match_operand:SI 7 "s_register_operand" "")])
3553 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3554 (match_operand:SI 3 "const_int_operand" "")
3555 (match_operand:SI 4 "const_int_operand" ""))]))
3556 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3558 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3559 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3562 [(ashift:SI (match_dup 2) (match_dup 4))
3566 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3569 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3573 [(set (match_operand:SI 0 "s_register_operand" "")
3574 (match_operator:SI 1 "logical_binary_operator"
3575 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3576 (match_operand:SI 3 "const_int_operand" "")
3577 (match_operand:SI 4 "const_int_operand" ""))
3578 (match_operator:SI 9 "logical_binary_operator"
3579 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3580 (match_operand:SI 6 "const_int_operand" ""))
3581 (match_operand:SI 7 "s_register_operand" "")])]))
3582 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3584 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3585 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3588 [(ashift:SI (match_dup 2) (match_dup 4))
3592 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3595 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3599 [(set (match_operand:SI 0 "s_register_operand" "")
3600 (match_operator:SI 1 "logical_binary_operator"
3601 [(match_operator:SI 9 "logical_binary_operator"
3602 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3603 (match_operand:SI 6 "const_int_operand" ""))
3604 (match_operand:SI 7 "s_register_operand" "")])
3605 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3606 (match_operand:SI 3 "const_int_operand" "")
3607 (match_operand:SI 4 "const_int_operand" ""))]))
3608 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3610 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3611 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3614 [(ashift:SI (match_dup 2) (match_dup 4))
3618 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3621 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3625 ;; Minimum and maximum insns
3627 (define_expand "smaxsi3"
3629 (set (match_operand:SI 0 "s_register_operand" "")
3630 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3631 (match_operand:SI 2 "arm_rhs_operand" "")))
3632 (clobber (reg:CC CC_REGNUM))])]
3635 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3637 /* No need for a clobber of the condition code register here. */
3638 emit_insn (gen_rtx_SET (operands[0],
3639 gen_rtx_SMAX (SImode, operands[1],
3645 (define_insn "*smax_0"
3646 [(set (match_operand:SI 0 "s_register_operand" "=r")
3647 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3650 "bic%?\\t%0, %1, %1, asr #31"
3651 [(set_attr "predicable" "yes")
3652 (set_attr "predicable_short_it" "no")
3653 (set_attr "type" "logic_shift_reg")]
3656 (define_insn "*smax_m1"
3657 [(set (match_operand:SI 0 "s_register_operand" "=r")
3658 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3661 "orr%?\\t%0, %1, %1, asr #31"
3662 [(set_attr "predicable" "yes")
3663 (set_attr "predicable_short_it" "no")
3664 (set_attr "type" "logic_shift_reg")]
3667 (define_insn_and_split "*arm_smax_insn"
3668 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3669 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3670 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3671 (clobber (reg:CC CC_REGNUM))]
3674 ; cmp\\t%1, %2\;movlt\\t%0, %2
3675 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3677 [(set (reg:CC CC_REGNUM)
3678 (compare:CC (match_dup 1) (match_dup 2)))
3680 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3684 [(set_attr "conds" "clob")
3685 (set_attr "length" "8,12")
3686 (set_attr "type" "multiple")]
3689 (define_expand "sminsi3"
3691 (set (match_operand:SI 0 "s_register_operand" "")
3692 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3693 (match_operand:SI 2 "arm_rhs_operand" "")))
3694 (clobber (reg:CC CC_REGNUM))])]
3697 if (operands[2] == const0_rtx)
3699 /* No need for a clobber of the condition code register here. */
3700 emit_insn (gen_rtx_SET (operands[0],
3701 gen_rtx_SMIN (SImode, operands[1],
3707 (define_insn "*smin_0"
3708 [(set (match_operand:SI 0 "s_register_operand" "=r")
3709 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3712 "and%?\\t%0, %1, %1, asr #31"
3713 [(set_attr "predicable" "yes")
3714 (set_attr "predicable_short_it" "no")
3715 (set_attr "type" "logic_shift_reg")]
3718 (define_insn_and_split "*arm_smin_insn"
3719 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3720 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3721 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3722 (clobber (reg:CC CC_REGNUM))]
3725 ; cmp\\t%1, %2\;movge\\t%0, %2
3726 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3728 [(set (reg:CC CC_REGNUM)
3729 (compare:CC (match_dup 1) (match_dup 2)))
3731 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3735 [(set_attr "conds" "clob")
3736 (set_attr "length" "8,12")
3737 (set_attr "type" "multiple,multiple")]
3740 (define_expand "umaxsi3"
3742 (set (match_operand:SI 0 "s_register_operand" "")
3743 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3744 (match_operand:SI 2 "arm_rhs_operand" "")))
3745 (clobber (reg:CC CC_REGNUM))])]
3750 (define_insn_and_split "*arm_umaxsi3"
3751 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3752 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3753 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3754 (clobber (reg:CC CC_REGNUM))]
3757 ; cmp\\t%1, %2\;movcc\\t%0, %2
3758 ; cmp\\t%1, %2\;movcs\\t%0, %1
3759 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3761 [(set (reg:CC CC_REGNUM)
3762 (compare:CC (match_dup 1) (match_dup 2)))
3764 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3768 [(set_attr "conds" "clob")
3769 (set_attr "length" "8,8,12")
3770 (set_attr "type" "store1")]
3773 (define_expand "uminsi3"
3775 (set (match_operand:SI 0 "s_register_operand" "")
3776 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3777 (match_operand:SI 2 "arm_rhs_operand" "")))
3778 (clobber (reg:CC CC_REGNUM))])]
3783 (define_insn_and_split "*arm_uminsi3"
3784 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3785 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3786 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3787 (clobber (reg:CC CC_REGNUM))]
3790 ; cmp\\t%1, %2\;movcs\\t%0, %2
3791 ; cmp\\t%1, %2\;movcc\\t%0, %1
3792 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3794 [(set (reg:CC CC_REGNUM)
3795 (compare:CC (match_dup 1) (match_dup 2)))
3797 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3801 [(set_attr "conds" "clob")
3802 (set_attr "length" "8,8,12")
3803 (set_attr "type" "store1")]
3806 (define_insn "*store_minmaxsi"
3807 [(set (match_operand:SI 0 "memory_operand" "=m")
3808 (match_operator:SI 3 "minmax_operator"
3809 [(match_operand:SI 1 "s_register_operand" "r")
3810 (match_operand:SI 2 "s_register_operand" "r")]))
3811 (clobber (reg:CC CC_REGNUM))]
3812 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3814 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3815 operands[1], operands[2]);
3816 output_asm_insn (\"cmp\\t%1, %2\", operands);
3818 output_asm_insn (\"ite\t%d3\", operands);
3819 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3820 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3823 [(set_attr "conds" "clob")
3824 (set (attr "length")
3825 (if_then_else (eq_attr "is_thumb" "yes")
3828 (set_attr "type" "store1")]
3831 ; Reject the frame pointer in operand[1], since reloading this after
3832 ; it has been eliminated can cause carnage.
3833 (define_insn "*minmax_arithsi"
3834 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3835 (match_operator:SI 4 "shiftable_operator"
3836 [(match_operator:SI 5 "minmax_operator"
3837 [(match_operand:SI 2 "s_register_operand" "r,r")
3838 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3839 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3840 (clobber (reg:CC CC_REGNUM))]
3841 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3844 enum rtx_code code = GET_CODE (operands[4]);
3847 if (which_alternative != 0 || operands[3] != const0_rtx
3848 || (code != PLUS && code != IOR && code != XOR))
3853 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3854 operands[2], operands[3]);
3855 output_asm_insn (\"cmp\\t%2, %3\", operands);
3859 output_asm_insn (\"ite\\t%d5\", operands);
3861 output_asm_insn (\"it\\t%d5\", operands);
3863 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3865 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3868 [(set_attr "conds" "clob")
3869 (set (attr "length")
3870 (if_then_else (eq_attr "is_thumb" "yes")
3873 (set_attr "type" "multiple")]
3876 ; Reject the frame pointer in operand[1], since reloading this after
3877 ; it has been eliminated can cause carnage.
3878 (define_insn_and_split "*minmax_arithsi_non_canon"
3879 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3881 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3882 (match_operator:SI 4 "minmax_operator"
3883 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3884 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3885 (clobber (reg:CC CC_REGNUM))]
3886 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3887 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3889 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3890 [(set (reg:CC CC_REGNUM)
3891 (compare:CC (match_dup 2) (match_dup 3)))
3893 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3895 (minus:SI (match_dup 1)
3897 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3901 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3902 operands[2], operands[3]);
3903 enum rtx_code rc = minmax_code (operands[4]);
3904 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3905 operands[2], operands[3]);
3907 if (mode == CCFPmode || mode == CCFPEmode)
3908 rc = reverse_condition_maybe_unordered (rc);
3910 rc = reverse_condition (rc);
3911 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3912 if (CONST_INT_P (operands[3]))
3913 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3915 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3917 [(set_attr "conds" "clob")
3918 (set (attr "length")
3919 (if_then_else (eq_attr "is_thumb" "yes")
3922 (set_attr "type" "multiple")]
3925 (define_code_iterator SAT [smin smax])
3926 (define_code_iterator SATrev [smin smax])
3927 (define_code_attr SATlo [(smin "1") (smax "2")])
3928 (define_code_attr SAThi [(smin "2") (smax "1")])
3930 (define_insn "*satsi_<SAT:code>"
3931 [(set (match_operand:SI 0 "s_register_operand" "=r")
3932 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3933 (match_operand:SI 1 "const_int_operand" "i"))
3934 (match_operand:SI 2 "const_int_operand" "i")))]
3935 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3936 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3940 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3941 &mask, &signed_sat))
3944 operands[1] = GEN_INT (mask);
3946 return "ssat%?\t%0, %1, %3";
3948 return "usat%?\t%0, %1, %3";
3950 [(set_attr "predicable" "yes")
3951 (set_attr "predicable_short_it" "no")
3952 (set_attr "type" "alus_imm")]
3955 (define_insn "*satsi_<SAT:code>_shift"
3956 [(set (match_operand:SI 0 "s_register_operand" "=r")
3957 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3958 [(match_operand:SI 4 "s_register_operand" "r")
3959 (match_operand:SI 5 "const_int_operand" "i")])
3960 (match_operand:SI 1 "const_int_operand" "i"))
3961 (match_operand:SI 2 "const_int_operand" "i")))]
3962 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3963 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3967 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3968 &mask, &signed_sat))
3971 operands[1] = GEN_INT (mask);
3973 return "ssat%?\t%0, %1, %4%S3";
3975 return "usat%?\t%0, %1, %4%S3";
3977 [(set_attr "predicable" "yes")
3978 (set_attr "predicable_short_it" "no")
3979 (set_attr "shift" "3")
3980 (set_attr "type" "logic_shift_reg")])
3982 ;; Shift and rotation insns
3984 (define_expand "ashldi3"
3985 [(set (match_operand:DI 0 "s_register_operand" "")
3986 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3987 (match_operand:SI 2 "general_operand" "")))]
3992 /* Delay the decision whether to use NEON or core-regs until
3993 register allocation. */
3994 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3999 /* Only the NEON case can handle in-memory shift counts. */
4000 if (!reg_or_int_operand (operands[2], SImode))
4001 operands[2] = force_reg (SImode, operands[2]);
4004 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4005 ; /* No special preparation statements; expand pattern as above. */
4008 rtx scratch1, scratch2;
4010 if (operands[2] == CONST1_RTX (SImode))
4012 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
4016 /* Ideally we should use iwmmxt here if we could know that operands[1]
4017 ends up already living in an iwmmxt register. Otherwise it's
4018 cheaper to have the alternate code being generated than moving
4019 values to iwmmxt regs and back. */
4021 /* Expand operation using core-registers.
4022 'FAIL' would achieve the same thing, but this is a bit smarter. */
4023 scratch1 = gen_reg_rtx (SImode);
4024 scratch2 = gen_reg_rtx (SImode);
4025 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4026 operands[2], scratch1, scratch2);
4032 (define_insn "arm_ashldi3_1bit"
4033 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4034 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4036 (clobber (reg:CC CC_REGNUM))]
4038 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4039 [(set_attr "conds" "clob")
4040 (set_attr "length" "8")
4041 (set_attr "type" "multiple")]
4044 (define_expand "ashlsi3"
4045 [(set (match_operand:SI 0 "s_register_operand" "")
4046 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4047 (match_operand:SI 2 "arm_rhs_operand" "")))]
4050 if (CONST_INT_P (operands[2])
4051 && (UINTVAL (operands[2])) > 31)
4053 emit_insn (gen_movsi (operands[0], const0_rtx));
4059 (define_expand "ashrdi3"
4060 [(set (match_operand:DI 0 "s_register_operand" "")
4061 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4062 (match_operand:SI 2 "reg_or_int_operand" "")))]
4067 /* Delay the decision whether to use NEON or core-regs until
4068 register allocation. */
4069 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4073 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4074 ; /* No special preparation statements; expand pattern as above. */
4077 rtx scratch1, scratch2;
4079 if (operands[2] == CONST1_RTX (SImode))
4081 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4085 /* Ideally we should use iwmmxt here if we could know that operands[1]
4086 ends up already living in an iwmmxt register. Otherwise it's
4087 cheaper to have the alternate code being generated than moving
4088 values to iwmmxt regs and back. */
4090 /* Expand operation using core-registers.
4091 'FAIL' would achieve the same thing, but this is a bit smarter. */
4092 scratch1 = gen_reg_rtx (SImode);
4093 scratch2 = gen_reg_rtx (SImode);
4094 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4095 operands[2], scratch1, scratch2);
4101 (define_insn "arm_ashrdi3_1bit"
4102 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4103 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4105 (clobber (reg:CC CC_REGNUM))]
4107 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4108 [(set_attr "conds" "clob")
4109 (set_attr "length" "8")
4110 (set_attr "type" "multiple")]
4113 (define_expand "ashrsi3"
4114 [(set (match_operand:SI 0 "s_register_operand" "")
4115 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4116 (match_operand:SI 2 "arm_rhs_operand" "")))]
4119 if (CONST_INT_P (operands[2])
4120 && UINTVAL (operands[2]) > 31)
4121 operands[2] = GEN_INT (31);
4125 (define_expand "lshrdi3"
4126 [(set (match_operand:DI 0 "s_register_operand" "")
4127 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4128 (match_operand:SI 2 "reg_or_int_operand" "")))]
4133 /* Delay the decision whether to use NEON or core-regs until
4134 register allocation. */
4135 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4139 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4140 ; /* No special preparation statements; expand pattern as above. */
4143 rtx scratch1, scratch2;
4145 if (operands[2] == CONST1_RTX (SImode))
4147 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4151 /* Ideally we should use iwmmxt here if we could know that operands[1]
4152 ends up already living in an iwmmxt register. Otherwise it's
4153 cheaper to have the alternate code being generated than moving
4154 values to iwmmxt regs and back. */
4156 /* Expand operation using core-registers.
4157 'FAIL' would achieve the same thing, but this is a bit smarter. */
4158 scratch1 = gen_reg_rtx (SImode);
4159 scratch2 = gen_reg_rtx (SImode);
4160 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4161 operands[2], scratch1, scratch2);
4167 (define_insn "arm_lshrdi3_1bit"
4168 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4169 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4171 (clobber (reg:CC CC_REGNUM))]
4173 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4174 [(set_attr "conds" "clob")
4175 (set_attr "length" "8")
4176 (set_attr "type" "multiple")]
4179 (define_expand "lshrsi3"
4180 [(set (match_operand:SI 0 "s_register_operand" "")
4181 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4182 (match_operand:SI 2 "arm_rhs_operand" "")))]
4185 if (CONST_INT_P (operands[2])
4186 && (UINTVAL (operands[2])) > 31)
4188 emit_insn (gen_movsi (operands[0], const0_rtx));
4194 (define_expand "rotlsi3"
4195 [(set (match_operand:SI 0 "s_register_operand" "")
4196 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4197 (match_operand:SI 2 "reg_or_int_operand" "")))]
4200 if (CONST_INT_P (operands[2]))
4201 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4204 rtx reg = gen_reg_rtx (SImode);
4205 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4211 (define_expand "rotrsi3"
4212 [(set (match_operand:SI 0 "s_register_operand" "")
4213 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4214 (match_operand:SI 2 "arm_rhs_operand" "")))]
4219 if (CONST_INT_P (operands[2])
4220 && UINTVAL (operands[2]) > 31)
4221 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4223 else /* TARGET_THUMB1 */
4225 if (CONST_INT_P (operands [2]))
4226 operands [2] = force_reg (SImode, operands[2]);
4231 (define_insn "*arm_shiftsi3"
4232 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4233 (match_operator:SI 3 "shift_operator"
4234 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4235 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4237 "* return arm_output_shift(operands, 0);"
4238 [(set_attr "predicable" "yes")
4239 (set_attr "arch" "t2,t2,*,*")
4240 (set_attr "predicable_short_it" "yes,yes,no,no")
4241 (set_attr "length" "4")
4242 (set_attr "shift" "1")
4243 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4246 (define_insn "*shiftsi3_compare0"
4247 [(set (reg:CC_NOOV CC_REGNUM)
4248 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4249 [(match_operand:SI 1 "s_register_operand" "r,r")
4250 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4252 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4253 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4255 "* return arm_output_shift(operands, 1);"
4256 [(set_attr "conds" "set")
4257 (set_attr "shift" "1")
4258 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4261 (define_insn "*shiftsi3_compare0_scratch"
4262 [(set (reg:CC_NOOV CC_REGNUM)
4263 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4264 [(match_operand:SI 1 "s_register_operand" "r,r")
4265 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4267 (clobber (match_scratch:SI 0 "=r,r"))]
4269 "* return arm_output_shift(operands, 1);"
4270 [(set_attr "conds" "set")
4271 (set_attr "shift" "1")
4272 (set_attr "type" "shift_imm,shift_reg")]
4275 (define_insn "*not_shiftsi"
4276 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4277 (not:SI (match_operator:SI 3 "shift_operator"
4278 [(match_operand:SI 1 "s_register_operand" "r,r")
4279 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4282 [(set_attr "predicable" "yes")
4283 (set_attr "predicable_short_it" "no")
4284 (set_attr "shift" "1")
4285 (set_attr "arch" "32,a")
4286 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4288 (define_insn "*not_shiftsi_compare0"
4289 [(set (reg:CC_NOOV CC_REGNUM)
4291 (not:SI (match_operator:SI 3 "shift_operator"
4292 [(match_operand:SI 1 "s_register_operand" "r,r")
4293 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4295 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4296 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4298 "mvns%?\\t%0, %1%S3"
4299 [(set_attr "conds" "set")
4300 (set_attr "shift" "1")
4301 (set_attr "arch" "32,a")
4302 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4304 (define_insn "*not_shiftsi_compare0_scratch"
4305 [(set (reg:CC_NOOV CC_REGNUM)
4307 (not:SI (match_operator:SI 3 "shift_operator"
4308 [(match_operand:SI 1 "s_register_operand" "r,r")
4309 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4311 (clobber (match_scratch:SI 0 "=r,r"))]
4313 "mvns%?\\t%0, %1%S3"
4314 [(set_attr "conds" "set")
4315 (set_attr "shift" "1")
4316 (set_attr "arch" "32,a")
4317 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4319 ;; We don't really have extzv, but defining this using shifts helps
4320 ;; to reduce register pressure later on.
4322 (define_expand "extzv"
4323 [(set (match_operand 0 "s_register_operand" "")
4324 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4325 (match_operand 2 "const_int_operand" "")
4326 (match_operand 3 "const_int_operand" "")))]
4327 "TARGET_THUMB1 || arm_arch_thumb2"
4330 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4331 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4333 if (arm_arch_thumb2)
4335 HOST_WIDE_INT width = INTVAL (operands[2]);
4336 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4338 if (unaligned_access && MEM_P (operands[1])
4339 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4343 if (BYTES_BIG_ENDIAN)
4344 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4349 base_addr = adjust_address (operands[1], SImode,
4350 bitpos / BITS_PER_UNIT);
4351 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4355 rtx dest = operands[0];
4356 rtx tmp = gen_reg_rtx (SImode);
4358 /* We may get a paradoxical subreg here. Strip it off. */
4359 if (GET_CODE (dest) == SUBREG
4360 && GET_MODE (dest) == SImode
4361 && GET_MODE (SUBREG_REG (dest)) == HImode)
4362 dest = SUBREG_REG (dest);
4364 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4367 base_addr = adjust_address (operands[1], HImode,
4368 bitpos / BITS_PER_UNIT);
4369 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4370 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4374 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4376 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4384 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4387 operands[3] = GEN_INT (rshift);
4391 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4395 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4396 operands[3], gen_reg_rtx (SImode)));
4401 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4403 (define_expand "extzv_t1"
4404 [(set (match_operand:SI 4 "s_register_operand" "")
4405 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4406 (match_operand:SI 2 "const_int_operand" "")))
4407 (set (match_operand:SI 0 "s_register_operand" "")
4408 (lshiftrt:SI (match_dup 4)
4409 (match_operand:SI 3 "const_int_operand" "")))]
4413 (define_expand "extv"
4414 [(set (match_operand 0 "s_register_operand" "")
4415 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4416 (match_operand 2 "const_int_operand" "")
4417 (match_operand 3 "const_int_operand" "")))]
4420 HOST_WIDE_INT width = INTVAL (operands[2]);
4421 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4423 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4424 && (bitpos % BITS_PER_UNIT) == 0)
4428 if (BYTES_BIG_ENDIAN)
4429 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4433 base_addr = adjust_address (operands[1], SImode,
4434 bitpos / BITS_PER_UNIT);
4435 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4439 rtx dest = operands[0];
4440 rtx tmp = gen_reg_rtx (SImode);
4442 /* We may get a paradoxical subreg here. Strip it off. */
4443 if (GET_CODE (dest) == SUBREG
4444 && GET_MODE (dest) == SImode
4445 && GET_MODE (SUBREG_REG (dest)) == HImode)
4446 dest = SUBREG_REG (dest);
4448 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4451 base_addr = adjust_address (operands[1], HImode,
4452 bitpos / BITS_PER_UNIT);
4453 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4454 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4459 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4461 else if (GET_MODE (operands[0]) == SImode
4462 && GET_MODE (operands[1]) == SImode)
4464 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4472 ; Helper to expand register forms of extv with the proper modes.
4474 (define_expand "extv_regsi"
4475 [(set (match_operand:SI 0 "s_register_operand" "")
4476 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4477 (match_operand 2 "const_int_operand" "")
4478 (match_operand 3 "const_int_operand" "")))]
4483 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4485 (define_insn "unaligned_loadsi"
4486 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4487 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4488 UNSPEC_UNALIGNED_LOAD))]
4490 "ldr%?\t%0, %1\t@ unaligned"
4491 [(set_attr "arch" "t2,any")
4492 (set_attr "length" "2,4")
4493 (set_attr "predicable" "yes")
4494 (set_attr "predicable_short_it" "yes,no")
4495 (set_attr "type" "load1")])
4497 (define_insn "unaligned_loadhis"
4498 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4500 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4501 UNSPEC_UNALIGNED_LOAD)))]
4503 "ldrsh%?\t%0, %1\t@ unaligned"
4504 [(set_attr "arch" "t2,any")
4505 (set_attr "length" "2,4")
4506 (set_attr "predicable" "yes")
4507 (set_attr "predicable_short_it" "yes,no")
4508 (set_attr "type" "load_byte")])
4510 (define_insn "unaligned_loadhiu"
4511 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4513 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4514 UNSPEC_UNALIGNED_LOAD)))]
4516 "ldrh%?\t%0, %1\t@ unaligned"
4517 [(set_attr "arch" "t2,any")
4518 (set_attr "length" "2,4")
4519 (set_attr "predicable" "yes")
4520 (set_attr "predicable_short_it" "yes,no")
4521 (set_attr "type" "load_byte")])
4523 (define_insn "unaligned_storesi"
4524 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4525 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4526 UNSPEC_UNALIGNED_STORE))]
4528 "str%?\t%1, %0\t@ unaligned"
4529 [(set_attr "arch" "t2,any")
4530 (set_attr "length" "2,4")
4531 (set_attr "predicable" "yes")
4532 (set_attr "predicable_short_it" "yes,no")
4533 (set_attr "type" "store1")])
4535 (define_insn "unaligned_storehi"
4536 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4537 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4538 UNSPEC_UNALIGNED_STORE))]
4540 "strh%?\t%1, %0\t@ unaligned"
4541 [(set_attr "arch" "t2,any")
4542 (set_attr "length" "2,4")
4543 (set_attr "predicable" "yes")
4544 (set_attr "predicable_short_it" "yes,no")
4545 (set_attr "type" "store1")])
4548 (define_insn "*extv_reg"
4549 [(set (match_operand:SI 0 "s_register_operand" "=r")
4550 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4551 (match_operand:SI 2 "const_int_operand" "n")
4552 (match_operand:SI 3 "const_int_operand" "n")))]
4554 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4555 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4556 "sbfx%?\t%0, %1, %3, %2"
4557 [(set_attr "length" "4")
4558 (set_attr "predicable" "yes")
4559 (set_attr "predicable_short_it" "no")
4560 (set_attr "type" "bfm")]
4563 (define_insn "extzv_t2"
4564 [(set (match_operand:SI 0 "s_register_operand" "=r")
4565 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4566 (match_operand:SI 2 "const_int_operand" "n")
4567 (match_operand:SI 3 "const_int_operand" "n")))]
4569 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4570 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4571 "ubfx%?\t%0, %1, %3, %2"
4572 [(set_attr "length" "4")
4573 (set_attr "predicable" "yes")
4574 (set_attr "predicable_short_it" "no")
4575 (set_attr "type" "bfm")]
4579 ;; Division instructions
4580 (define_insn "divsi3"
4581 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4582 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4583 (match_operand:SI 2 "s_register_operand" "r,r")))]
4588 [(set_attr "arch" "32,v8mb")
4589 (set_attr "predicable" "yes")
4590 (set_attr "predicable_short_it" "no")
4591 (set_attr "type" "sdiv")]
4594 (define_insn "udivsi3"
4595 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4596 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4597 (match_operand:SI 2 "s_register_operand" "r,r")))]
4602 [(set_attr "arch" "32,v8mb")
4603 (set_attr "predicable" "yes")
4604 (set_attr "predicable_short_it" "no")
4605 (set_attr "type" "udiv")]
4609 ;; Unary arithmetic insns
4611 (define_expand "negvsi3"
4612 [(match_operand:SI 0 "register_operand")
4613 (match_operand:SI 1 "register_operand")
4614 (match_operand 2 "")]
4617 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4618 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4623 (define_expand "negvdi3"
4624 [(match_operand:DI 0 "register_operand")
4625 (match_operand:DI 1 "register_operand")
4626 (match_operand 2 "")]
4629 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4630 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4636 (define_insn_and_split "negdi2_compare"
4637 [(set (reg:CC CC_REGNUM)
4640 (match_operand:DI 1 "register_operand" "0,r")))
4641 (set (match_operand:DI 0 "register_operand" "=r,&r")
4642 (minus:DI (const_int 0) (match_dup 1)))]
4645 "&& reload_completed"
4646 [(parallel [(set (reg:CC CC_REGNUM)
4647 (compare:CC (const_int 0) (match_dup 1)))
4648 (set (match_dup 0) (minus:SI (const_int 0)
4650 (parallel [(set (reg:CC CC_REGNUM)
4651 (compare:CC (const_int 0) (match_dup 3)))
4654 (minus:SI (const_int 0) (match_dup 3))
4655 (ltu:SI (reg:CC_C CC_REGNUM)
4658 operands[2] = gen_highpart (SImode, operands[0]);
4659 operands[0] = gen_lowpart (SImode, operands[0]);
4660 operands[3] = gen_highpart (SImode, operands[1]);
4661 operands[1] = gen_lowpart (SImode, operands[1]);
4663 [(set_attr "conds" "set")
4664 (set_attr "length" "8")
4665 (set_attr "type" "multiple")]
4668 (define_expand "negdi2"
4670 [(set (match_operand:DI 0 "s_register_operand" "")
4671 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4672 (clobber (reg:CC CC_REGNUM))])]
4677 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4683 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4684 ;; The first alternative allows the common case of a *full* overlap.
4685 (define_insn_and_split "*negdi2_insn"
4686 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4687 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4688 (clobber (reg:CC CC_REGNUM))]
4690 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4691 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4692 "&& reload_completed"
4693 [(parallel [(set (reg:CC CC_REGNUM)
4694 (compare:CC (const_int 0) (match_dup 1)))
4695 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4696 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4697 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4699 operands[2] = gen_highpart (SImode, operands[0]);
4700 operands[0] = gen_lowpart (SImode, operands[0]);
4701 operands[3] = gen_highpart (SImode, operands[1]);
4702 operands[1] = gen_lowpart (SImode, operands[1]);
4704 [(set_attr "conds" "clob")
4705 (set_attr "length" "8")
4706 (set_attr "type" "multiple")]
4709 (define_insn "*negsi2_carryin_compare"
4710 [(set (reg:CC CC_REGNUM)
4711 (compare:CC (const_int 0)
4712 (match_operand:SI 1 "s_register_operand" "r")))
4713 (set (match_operand:SI 0 "s_register_operand" "=r")
4714 (minus:SI (minus:SI (const_int 0)
4716 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4719 [(set_attr "conds" "set")
4720 (set_attr "type" "alus_imm")]
4723 (define_expand "negsi2"
4724 [(set (match_operand:SI 0 "s_register_operand" "")
4725 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4730 (define_insn "*arm_negsi2"
4731 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4732 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4734 "rsb%?\\t%0, %1, #0"
4735 [(set_attr "predicable" "yes")
4736 (set_attr "predicable_short_it" "yes,no")
4737 (set_attr "arch" "t2,*")
4738 (set_attr "length" "4")
4739 (set_attr "type" "alu_sreg")]
4742 (define_expand "negsf2"
4743 [(set (match_operand:SF 0 "s_register_operand" "")
4744 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4745 "TARGET_32BIT && TARGET_HARD_FLOAT"
4749 (define_expand "negdf2"
4750 [(set (match_operand:DF 0 "s_register_operand" "")
4751 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4752 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4755 (define_insn_and_split "*zextendsidi_negsi"
4756 [(set (match_operand:DI 0 "s_register_operand" "=r")
4757 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4762 (neg:SI (match_dup 1)))
4766 operands[2] = gen_lowpart (SImode, operands[0]);
4767 operands[3] = gen_highpart (SImode, operands[0]);
4769 [(set_attr "length" "8")
4770 (set_attr "type" "multiple")]
4773 ;; Negate an extended 32-bit value.
4774 (define_insn_and_split "*negdi_extendsidi"
4775 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4776 (neg:DI (sign_extend:DI
4777 (match_operand:SI 1 "s_register_operand" "l,r"))))
4778 (clobber (reg:CC CC_REGNUM))]
4781 "&& reload_completed"
4784 rtx low = gen_lowpart (SImode, operands[0]);
4785 rtx high = gen_highpart (SImode, operands[0]);
4787 if (reg_overlap_mentioned_p (low, operands[1]))
4789 /* Input overlaps the low word of the output. Use:
4792 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4793 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4795 emit_insn (gen_rtx_SET (high,
4796 gen_rtx_ASHIFTRT (SImode, operands[1],
4799 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4801 emit_insn (gen_rtx_SET (high,
4802 gen_rtx_MINUS (SImode,
4803 gen_rtx_MINUS (SImode,
4806 gen_rtx_LTU (SImode,
4811 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4812 emit_insn (gen_rtx_SET (high,
4813 gen_rtx_MINUS (SImode,
4814 gen_rtx_MINUS (SImode,
4817 gen_rtx_LTU (SImode,
4824 /* No overlap, or overlap on high word. Use:
4828 Flags not needed for this sequence. */
4829 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4830 emit_insn (gen_rtx_SET (high,
4831 gen_rtx_AND (SImode,
4832 gen_rtx_NOT (SImode, operands[1]),
4834 emit_insn (gen_rtx_SET (high,
4835 gen_rtx_ASHIFTRT (SImode, high,
4840 [(set_attr "length" "12")
4841 (set_attr "arch" "t2,*")
4842 (set_attr "type" "multiple")]
4845 (define_insn_and_split "*negdi_zero_extendsidi"
4846 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4847 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4848 (clobber (reg:CC CC_REGNUM))]
4850 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4851 ;; Don't care what register is input to sbc,
4852 ;; since we just need to propagate the carry.
4853 "&& reload_completed"
4854 [(parallel [(set (reg:CC CC_REGNUM)
4855 (compare:CC (const_int 0) (match_dup 1)))
4856 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4857 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4858 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4860 operands[2] = gen_highpart (SImode, operands[0]);
4861 operands[0] = gen_lowpart (SImode, operands[0]);
4863 [(set_attr "conds" "clob")
4864 (set_attr "length" "8")
4865 (set_attr "type" "multiple")] ;; length in thumb is 4
4868 ;; abssi2 doesn't really clobber the condition codes if a different register
4869 ;; is being set. To keep things simple, assume during rtl manipulations that
4870 ;; it does, but tell the final scan operator the truth. Similarly for
4873 (define_expand "abssi2"
4875 [(set (match_operand:SI 0 "s_register_operand" "")
4876 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4877 (clobber (match_dup 2))])]
4881 operands[2] = gen_rtx_SCRATCH (SImode);
4883 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4886 (define_insn_and_split "*arm_abssi2"
4887 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4888 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4889 (clobber (reg:CC CC_REGNUM))]
4892 "&& reload_completed"
4895 /* if (which_alternative == 0) */
4896 if (REGNO(operands[0]) == REGNO(operands[1]))
4898 /* Emit the pattern:
4899 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4900 [(set (reg:CC CC_REGNUM)
4901 (compare:CC (match_dup 0) (const_int 0)))
4902 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4903 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4905 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4906 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4907 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4908 (gen_rtx_LT (SImode,
4909 gen_rtx_REG (CCmode, CC_REGNUM),
4911 (gen_rtx_SET (operands[0],
4912 (gen_rtx_MINUS (SImode,
4919 /* Emit the pattern:
4920 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4922 (xor:SI (match_dup 1)
4923 (ashiftrt:SI (match_dup 1) (const_int 31))))
4925 (minus:SI (match_dup 0)
4926 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4928 emit_insn (gen_rtx_SET (operands[0],
4929 gen_rtx_XOR (SImode,
4930 gen_rtx_ASHIFTRT (SImode,
4934 emit_insn (gen_rtx_SET (operands[0],
4935 gen_rtx_MINUS (SImode,
4937 gen_rtx_ASHIFTRT (SImode,
4943 [(set_attr "conds" "clob,*")
4944 (set_attr "shift" "1")
4945 (set_attr "predicable" "no, yes")
4946 (set_attr "length" "8")
4947 (set_attr "type" "multiple")]
4950 (define_insn_and_split "*arm_neg_abssi2"
4951 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4952 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4953 (clobber (reg:CC CC_REGNUM))]
4956 "&& reload_completed"
4959 /* if (which_alternative == 0) */
4960 if (REGNO (operands[0]) == REGNO (operands[1]))
4962 /* Emit the pattern:
4963 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4965 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4966 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4967 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4969 gen_rtx_REG (CCmode, CC_REGNUM),
4971 gen_rtx_SET (operands[0],
4972 (gen_rtx_MINUS (SImode,
4978 /* Emit the pattern:
4979 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4981 emit_insn (gen_rtx_SET (operands[0],
4982 gen_rtx_XOR (SImode,
4983 gen_rtx_ASHIFTRT (SImode,
4987 emit_insn (gen_rtx_SET (operands[0],
4988 gen_rtx_MINUS (SImode,
4989 gen_rtx_ASHIFTRT (SImode,
4996 [(set_attr "conds" "clob,*")
4997 (set_attr "shift" "1")
4998 (set_attr "predicable" "no, yes")
4999 (set_attr "length" "8")
5000 (set_attr "type" "multiple")]
5003 (define_expand "abssf2"
5004 [(set (match_operand:SF 0 "s_register_operand" "")
5005 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5006 "TARGET_32BIT && TARGET_HARD_FLOAT"
5009 (define_expand "absdf2"
5010 [(set (match_operand:DF 0 "s_register_operand" "")
5011 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5012 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5015 (define_expand "sqrtsf2"
5016 [(set (match_operand:SF 0 "s_register_operand" "")
5017 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5018 "TARGET_32BIT && TARGET_HARD_FLOAT"
5021 (define_expand "sqrtdf2"
5022 [(set (match_operand:DF 0 "s_register_operand" "")
5023 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5024 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5027 (define_insn_and_split "one_cmpldi2"
5028 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5029 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5036 "TARGET_32BIT && reload_completed
5037 && arm_general_register_operand (operands[0], DImode)"
5038 [(set (match_dup 0) (not:SI (match_dup 1)))
5039 (set (match_dup 2) (not:SI (match_dup 3)))]
5042 operands[2] = gen_highpart (SImode, operands[0]);
5043 operands[0] = gen_lowpart (SImode, operands[0]);
5044 operands[3] = gen_highpart (SImode, operands[1]);
5045 operands[1] = gen_lowpart (SImode, operands[1]);
5047 [(set_attr "length" "*,8,8,*")
5048 (set_attr "predicable" "no,yes,yes,no")
5049 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5050 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5053 (define_expand "one_cmplsi2"
5054 [(set (match_operand:SI 0 "s_register_operand" "")
5055 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5060 (define_insn "*arm_one_cmplsi2"
5061 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5062 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5065 [(set_attr "predicable" "yes")
5066 (set_attr "predicable_short_it" "yes,no")
5067 (set_attr "arch" "t2,*")
5068 (set_attr "length" "4")
5069 (set_attr "type" "mvn_reg")]
5072 (define_insn "*notsi_compare0"
5073 [(set (reg:CC_NOOV CC_REGNUM)
5074 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5076 (set (match_operand:SI 0 "s_register_operand" "=r")
5077 (not:SI (match_dup 1)))]
5080 [(set_attr "conds" "set")
5081 (set_attr "type" "mvn_reg")]
5084 (define_insn "*notsi_compare0_scratch"
5085 [(set (reg:CC_NOOV CC_REGNUM)
5086 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5088 (clobber (match_scratch:SI 0 "=r"))]
5091 [(set_attr "conds" "set")
5092 (set_attr "type" "mvn_reg")]
5095 ;; Fixed <--> Floating conversion insns
5097 (define_expand "floatsihf2"
5098 [(set (match_operand:HF 0 "general_operand" "")
5099 (float:HF (match_operand:SI 1 "general_operand" "")))]
5103 rtx op1 = gen_reg_rtx (SFmode);
5104 expand_float (op1, operands[1], 0);
5105 op1 = convert_to_mode (HFmode, op1, 0);
5106 emit_move_insn (operands[0], op1);
5111 (define_expand "floatdihf2"
5112 [(set (match_operand:HF 0 "general_operand" "")
5113 (float:HF (match_operand:DI 1 "general_operand" "")))]
5117 rtx op1 = gen_reg_rtx (SFmode);
5118 expand_float (op1, operands[1], 0);
5119 op1 = convert_to_mode (HFmode, op1, 0);
5120 emit_move_insn (operands[0], op1);
5125 (define_expand "floatsisf2"
5126 [(set (match_operand:SF 0 "s_register_operand" "")
5127 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5128 "TARGET_32BIT && TARGET_HARD_FLOAT"
5132 (define_expand "floatsidf2"
5133 [(set (match_operand:DF 0 "s_register_operand" "")
5134 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5135 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5139 (define_expand "fix_trunchfsi2"
5140 [(set (match_operand:SI 0 "general_operand" "")
5141 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5145 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5146 expand_fix (operands[0], op1, 0);
5151 (define_expand "fix_trunchfdi2"
5152 [(set (match_operand:DI 0 "general_operand" "")
5153 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5157 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5158 expand_fix (operands[0], op1, 0);
5163 (define_expand "fix_truncsfsi2"
5164 [(set (match_operand:SI 0 "s_register_operand" "")
5165 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5166 "TARGET_32BIT && TARGET_HARD_FLOAT"
5170 (define_expand "fix_truncdfsi2"
5171 [(set (match_operand:SI 0 "s_register_operand" "")
5172 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5173 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5179 (define_expand "truncdfsf2"
5180 [(set (match_operand:SF 0 "s_register_operand" "")
5182 (match_operand:DF 1 "s_register_operand" "")))]
5183 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5187 ;; DFmode to HFmode conversions on targets without a single-step hardware
5188 ;; instruction for it would have to go through SFmode. This is dangerous
5189 ;; as it introduces double rounding.
5191 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5192 ;; a single-step instruction.
5194 (define_expand "truncdfhf2"
5195 [(set (match_operand:HF 0 "s_register_operand" "")
5197 (match_operand:DF 1 "s_register_operand" "")))]
5198 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5199 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5201 /* We don't have a direct instruction for this, so we must be in
5202 an unsafe math mode, and going via SFmode. */
5204 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5207 op1 = convert_to_mode (SFmode, operands[1], 0);
5208 op1 = convert_to_mode (HFmode, op1, 0);
5209 emit_move_insn (operands[0], op1);
5212 /* Otherwise, we will pick this up as a single instruction with
5213 no intermediary rounding. */
5217 ;; Zero and sign extension instructions.
5219 (define_insn "zero_extend<mode>di2"
5220 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5221 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5222 "<qhs_zextenddi_cstr>")))]
5223 "TARGET_32BIT <qhs_zextenddi_cond>"
5225 [(set_attr "length" "8,4,8,8")
5226 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5227 (set_attr "ce_count" "2")
5228 (set_attr "predicable" "yes")
5229 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5232 (define_insn "extend<mode>di2"
5233 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5234 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5235 "<qhs_extenddi_cstr>")))]
5236 "TARGET_32BIT <qhs_sextenddi_cond>"
5238 [(set_attr "length" "8,4,8,8,8")
5239 (set_attr "ce_count" "2")
5240 (set_attr "shift" "1")
5241 (set_attr "predicable" "yes")
5242 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5243 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5246 ;; Splits for all extensions to DImode
5248 [(set (match_operand:DI 0 "s_register_operand" "")
5249 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5250 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5251 [(set (match_dup 0) (match_dup 1))]
5253 rtx lo_part = gen_lowpart (SImode, operands[0]);
5254 machine_mode src_mode = GET_MODE (operands[1]);
5256 if (REG_P (operands[0])
5257 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5258 emit_clobber (operands[0]);
5259 if (!REG_P (lo_part) || src_mode != SImode
5260 || !rtx_equal_p (lo_part, operands[1]))
5262 if (src_mode == SImode)
5263 emit_move_insn (lo_part, operands[1]);
5265 emit_insn (gen_rtx_SET (lo_part,
5266 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5267 operands[1] = lo_part;
5269 operands[0] = gen_highpart (SImode, operands[0]);
5270 operands[1] = const0_rtx;
5274 [(set (match_operand:DI 0 "s_register_operand" "")
5275 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5276 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5277 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5279 rtx lo_part = gen_lowpart (SImode, operands[0]);
5280 machine_mode src_mode = GET_MODE (operands[1]);
5282 if (REG_P (operands[0])
5283 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5284 emit_clobber (operands[0]);
5286 if (!REG_P (lo_part) || src_mode != SImode
5287 || !rtx_equal_p (lo_part, operands[1]))
5289 if (src_mode == SImode)
5290 emit_move_insn (lo_part, operands[1]);
5292 emit_insn (gen_rtx_SET (lo_part,
5293 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5294 operands[1] = lo_part;
5296 operands[0] = gen_highpart (SImode, operands[0]);
5299 (define_expand "zero_extendhisi2"
5300 [(set (match_operand:SI 0 "s_register_operand" "")
5301 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5304 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5306 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5309 if (!arm_arch6 && !MEM_P (operands[1]))
5311 rtx t = gen_lowpart (SImode, operands[1]);
5312 rtx tmp = gen_reg_rtx (SImode);
5313 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5314 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5320 [(set (match_operand:SI 0 "s_register_operand" "")
5321 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5322 "!TARGET_THUMB2 && !arm_arch6"
5323 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5324 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5326 operands[2] = gen_lowpart (SImode, operands[1]);
5329 (define_insn "*arm_zero_extendhisi2"
5330 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5331 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5332 "TARGET_ARM && arm_arch4 && !arm_arch6"
5336 [(set_attr "type" "alu_shift_reg,load_byte")
5337 (set_attr "predicable" "yes")]
5340 (define_insn "*arm_zero_extendhisi2_v6"
5341 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5342 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5343 "TARGET_ARM && arm_arch6"
5347 [(set_attr "predicable" "yes")
5348 (set_attr "type" "extend,load_byte")]
5351 (define_insn "*arm_zero_extendhisi2addsi"
5352 [(set (match_operand:SI 0 "s_register_operand" "=r")
5353 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5354 (match_operand:SI 2 "s_register_operand" "r")))]
5356 "uxtah%?\\t%0, %2, %1"
5357 [(set_attr "type" "alu_shift_reg")
5358 (set_attr "predicable" "yes")
5359 (set_attr "predicable_short_it" "no")]
5362 (define_expand "zero_extendqisi2"
5363 [(set (match_operand:SI 0 "s_register_operand" "")
5364 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5367 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5369 emit_insn (gen_andsi3 (operands[0],
5370 gen_lowpart (SImode, operands[1]),
5374 if (!arm_arch6 && !MEM_P (operands[1]))
5376 rtx t = gen_lowpart (SImode, operands[1]);
5377 rtx tmp = gen_reg_rtx (SImode);
5378 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5379 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5385 [(set (match_operand:SI 0 "s_register_operand" "")
5386 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5388 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5389 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5391 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5394 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5399 (define_insn "*arm_zero_extendqisi2"
5400 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5401 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5402 "TARGET_ARM && !arm_arch6"
5405 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5406 [(set_attr "length" "8,4")
5407 (set_attr "type" "alu_shift_reg,load_byte")
5408 (set_attr "predicable" "yes")]
5411 (define_insn "*arm_zero_extendqisi2_v6"
5412 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5413 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5414 "TARGET_ARM && arm_arch6"
5417 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5418 [(set_attr "type" "extend,load_byte")
5419 (set_attr "predicable" "yes")]
5422 (define_insn "*arm_zero_extendqisi2addsi"
5423 [(set (match_operand:SI 0 "s_register_operand" "=r")
5424 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5425 (match_operand:SI 2 "s_register_operand" "r")))]
5427 "uxtab%?\\t%0, %2, %1"
5428 [(set_attr "predicable" "yes")
5429 (set_attr "predicable_short_it" "no")
5430 (set_attr "type" "alu_shift_reg")]
5434 [(set (match_operand:SI 0 "s_register_operand" "")
5435 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5436 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5437 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5438 [(set (match_dup 2) (match_dup 1))
5439 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5444 [(set (match_operand:SI 0 "s_register_operand" "")
5445 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5446 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5447 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5448 [(set (match_dup 2) (match_dup 1))
5449 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5455 [(set (match_operand:SI 0 "s_register_operand" "")
5456 (IOR_XOR:SI (and:SI (ashift:SI
5457 (match_operand:SI 1 "s_register_operand" "")
5458 (match_operand:SI 2 "const_int_operand" ""))
5459 (match_operand:SI 3 "const_int_operand" ""))
5461 (match_operator 5 "subreg_lowpart_operator"
5462 [(match_operand:SI 4 "s_register_operand" "")]))))]
5464 && (UINTVAL (operands[3])
5465 == (GET_MODE_MASK (GET_MODE (operands[5]))
5466 & (GET_MODE_MASK (GET_MODE (operands[5]))
5467 << (INTVAL (operands[2])))))"
5468 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5470 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5471 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5474 (define_insn "*compareqi_eq0"
5475 [(set (reg:CC_Z CC_REGNUM)
5476 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5480 [(set_attr "conds" "set")
5481 (set_attr "predicable" "yes")
5482 (set_attr "predicable_short_it" "no")
5483 (set_attr "type" "logic_imm")]
5486 (define_expand "extendhisi2"
5487 [(set (match_operand:SI 0 "s_register_operand" "")
5488 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5493 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5496 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5498 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5502 if (!arm_arch6 && !MEM_P (operands[1]))
5504 rtx t = gen_lowpart (SImode, operands[1]);
5505 rtx tmp = gen_reg_rtx (SImode);
5506 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5507 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5514 [(set (match_operand:SI 0 "register_operand" "")
5515 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5516 (clobber (match_scratch:SI 2 ""))])]
5518 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5519 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5521 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5524 ;; This pattern will only be used when ldsh is not available
5525 (define_expand "extendhisi2_mem"
5526 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5528 (zero_extend:SI (match_dup 7)))
5529 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5530 (set (match_operand:SI 0 "" "")
5531 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5536 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5538 mem1 = change_address (operands[1], QImode, addr);
5539 mem2 = change_address (operands[1], QImode,
5540 plus_constant (Pmode, addr, 1));
5541 operands[0] = gen_lowpart (SImode, operands[0]);
5543 operands[2] = gen_reg_rtx (SImode);
5544 operands[3] = gen_reg_rtx (SImode);
5545 operands[6] = gen_reg_rtx (SImode);
5548 if (BYTES_BIG_ENDIAN)
5550 operands[4] = operands[2];
5551 operands[5] = operands[3];
5555 operands[4] = operands[3];
5556 operands[5] = operands[2];
5562 [(set (match_operand:SI 0 "register_operand" "")
5563 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5565 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5566 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5568 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5571 (define_insn "*arm_extendhisi2"
5572 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5573 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5574 "TARGET_ARM && arm_arch4 && !arm_arch6"
5578 [(set_attr "length" "8,4")
5579 (set_attr "type" "alu_shift_reg,load_byte")
5580 (set_attr "predicable" "yes")]
5583 ;; ??? Check Thumb-2 pool range
5584 (define_insn "*arm_extendhisi2_v6"
5585 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5586 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5587 "TARGET_32BIT && arm_arch6"
5591 [(set_attr "type" "extend,load_byte")
5592 (set_attr "predicable" "yes")
5593 (set_attr "predicable_short_it" "no")]
5596 (define_insn "*arm_extendhisi2addsi"
5597 [(set (match_operand:SI 0 "s_register_operand" "=r")
5598 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5599 (match_operand:SI 2 "s_register_operand" "r")))]
5601 "sxtah%?\\t%0, %2, %1"
5602 [(set_attr "type" "alu_shift_reg")]
5605 (define_expand "extendqihi2"
5607 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5609 (set (match_operand:HI 0 "s_register_operand" "")
5610 (ashiftrt:SI (match_dup 2)
5615 if (arm_arch4 && MEM_P (operands[1]))
5617 emit_insn (gen_rtx_SET (operands[0],
5618 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5621 if (!s_register_operand (operands[1], QImode))
5622 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5623 operands[0] = gen_lowpart (SImode, operands[0]);
5624 operands[1] = gen_lowpart (SImode, operands[1]);
5625 operands[2] = gen_reg_rtx (SImode);
5629 (define_insn "*arm_extendqihi_insn"
5630 [(set (match_operand:HI 0 "s_register_operand" "=r")
5631 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5632 "TARGET_ARM && arm_arch4"
5634 [(set_attr "type" "load_byte")
5635 (set_attr "predicable" "yes")]
5638 (define_expand "extendqisi2"
5639 [(set (match_operand:SI 0 "s_register_operand" "")
5640 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5643 if (!arm_arch4 && MEM_P (operands[1]))
5644 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5646 if (!arm_arch6 && !MEM_P (operands[1]))
5648 rtx t = gen_lowpart (SImode, operands[1]);
5649 rtx tmp = gen_reg_rtx (SImode);
5650 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5651 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5657 [(set (match_operand:SI 0 "register_operand" "")
5658 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5660 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5661 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5663 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5666 (define_insn "*arm_extendqisi"
5667 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5668 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5669 "TARGET_ARM && arm_arch4 && !arm_arch6"
5673 [(set_attr "length" "8,4")
5674 (set_attr "type" "alu_shift_reg,load_byte")
5675 (set_attr "predicable" "yes")]
5678 (define_insn "*arm_extendqisi_v6"
5679 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5681 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5682 "TARGET_ARM && arm_arch6"
5686 [(set_attr "type" "extend,load_byte")
5687 (set_attr "predicable" "yes")]
5690 (define_insn "*arm_extendqisi2addsi"
5691 [(set (match_operand:SI 0 "s_register_operand" "=r")
5692 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5693 (match_operand:SI 2 "s_register_operand" "r")))]
5695 "sxtab%?\\t%0, %2, %1"
5696 [(set_attr "type" "alu_shift_reg")
5697 (set_attr "predicable" "yes")
5698 (set_attr "predicable_short_it" "no")]
5701 (define_expand "extendsfdf2"
5702 [(set (match_operand:DF 0 "s_register_operand" "")
5703 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5704 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5708 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5709 ;; must go through SFmode.
5711 ;; This is always safe for an extend.
5713 (define_expand "extendhfdf2"
5714 [(set (match_operand:DF 0 "s_register_operand" "")
5715 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5718 /* We don't have a direct instruction for this, so go via SFmode. */
5719 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5722 op1 = convert_to_mode (SFmode, operands[1], 0);
5723 op1 = convert_to_mode (DFmode, op1, 0);
5724 emit_insn (gen_movdf (operands[0], op1));
5727 /* Otherwise, we're done producing RTL and will pick up the correct
5728 pattern to do this with one rounding-step in a single instruction. */
5732 ;; Move insns (including loads and stores)
5734 ;; XXX Just some ideas about movti.
5735 ;; I don't think these are a good idea on the arm, there just aren't enough
5737 ;;(define_expand "loadti"
5738 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5739 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5742 ;;(define_expand "storeti"
5743 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5744 ;; (match_operand:TI 1 "s_register_operand" ""))]
5747 ;;(define_expand "movti"
5748 ;; [(set (match_operand:TI 0 "general_operand" "")
5749 ;; (match_operand:TI 1 "general_operand" ""))]
5755 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5756 ;; operands[1] = copy_to_reg (operands[1]);
5757 ;; if (MEM_P (operands[0]))
5758 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5759 ;; else if (MEM_P (operands[1]))
5760 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5764 ;; emit_insn (insn);
5768 ;; Recognize garbage generated above.
5771 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5772 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5776 ;; register mem = (which_alternative < 3);
5777 ;; register const char *template;
5779 ;; operands[mem] = XEXP (operands[mem], 0);
5780 ;; switch (which_alternative)
5782 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5783 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5784 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5785 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5786 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5787 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5789 ;; output_asm_insn (template, operands);
5793 (define_expand "movdi"
5794 [(set (match_operand:DI 0 "general_operand" "")
5795 (match_operand:DI 1 "general_operand" ""))]
5798 if (can_create_pseudo_p ())
5800 if (!REG_P (operands[0]))
5801 operands[1] = force_reg (DImode, operands[1]);
5803 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5804 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5806 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5807 when expanding function calls. */
5808 gcc_assert (can_create_pseudo_p ());
5809 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5811 /* Perform load into legal reg pair first, then move. */
5812 rtx reg = gen_reg_rtx (DImode);
5813 emit_insn (gen_movdi (reg, operands[1]));
5816 emit_move_insn (gen_lowpart (SImode, operands[0]),
5817 gen_lowpart (SImode, operands[1]));
5818 emit_move_insn (gen_highpart (SImode, operands[0]),
5819 gen_highpart (SImode, operands[1]));
5822 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5823 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5825 /* Avoid STRD's from an odd-numbered register pair in ARM state
5826 when expanding function prologue. */
5827 gcc_assert (can_create_pseudo_p ());
5828 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5829 ? gen_reg_rtx (DImode)
5831 emit_move_insn (gen_lowpart (SImode, split_dest),
5832 gen_lowpart (SImode, operands[1]));
5833 emit_move_insn (gen_highpart (SImode, split_dest),
5834 gen_highpart (SImode, operands[1]));
5835 if (split_dest != operands[0])
5836 emit_insn (gen_movdi (operands[0], split_dest));
5842 (define_insn "*arm_movdi"
5843 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5844 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5846 && !(TARGET_HARD_FLOAT)
5848 && ( register_operand (operands[0], DImode)
5849 || register_operand (operands[1], DImode))"
5851 switch (which_alternative)
5858 return output_move_double (operands, true, NULL);
5861 [(set_attr "length" "8,12,16,8,8")
5862 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5863 (set_attr "arm_pool_range" "*,*,*,1020,*")
5864 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5865 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5866 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5870 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5871 (match_operand:ANY64 1 "immediate_operand" ""))]
5874 && (arm_const_double_inline_cost (operands[1])
5875 <= arm_max_const_double_inline_cost ())"
5878 arm_split_constant (SET, SImode, curr_insn,
5879 INTVAL (gen_lowpart (SImode, operands[1])),
5880 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5881 arm_split_constant (SET, SImode, curr_insn,
5882 INTVAL (gen_highpart_mode (SImode,
5883 GET_MODE (operands[0]),
5885 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5890 ; If optimizing for size, or if we have load delay slots, then
5891 ; we want to split the constant into two separate operations.
5892 ; In both cases this may split a trivial part into a single data op
5893 ; leaving a single complex constant to load. We can also get longer
5894 ; offsets in a LDR which means we get better chances of sharing the pool
5895 ; entries. Finally, we can normally do a better job of scheduling
5896 ; LDR instructions than we can with LDM.
5897 ; This pattern will only match if the one above did not.
5899 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5900 (match_operand:ANY64 1 "const_double_operand" ""))]
5901 "TARGET_ARM && reload_completed
5902 && arm_const_double_by_parts (operands[1])"
5903 [(set (match_dup 0) (match_dup 1))
5904 (set (match_dup 2) (match_dup 3))]
5906 operands[2] = gen_highpart (SImode, operands[0]);
5907 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5909 operands[0] = gen_lowpart (SImode, operands[0]);
5910 operands[1] = gen_lowpart (SImode, operands[1]);
5915 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5916 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5917 "TARGET_EITHER && reload_completed"
5918 [(set (match_dup 0) (match_dup 1))
5919 (set (match_dup 2) (match_dup 3))]
5921 operands[2] = gen_highpart (SImode, operands[0]);
5922 operands[3] = gen_highpart (SImode, operands[1]);
5923 operands[0] = gen_lowpart (SImode, operands[0]);
5924 operands[1] = gen_lowpart (SImode, operands[1]);
5926 /* Handle a partial overlap. */
5927 if (rtx_equal_p (operands[0], operands[3]))
5929 rtx tmp0 = operands[0];
5930 rtx tmp1 = operands[1];
5932 operands[0] = operands[2];
5933 operands[1] = operands[3];
5940 ;; We can't actually do base+index doubleword loads if the index and
5941 ;; destination overlap. Split here so that we at least have chance to
5944 [(set (match_operand:DI 0 "s_register_operand" "")
5945 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5946 (match_operand:SI 2 "s_register_operand" ""))))]
5948 && reg_overlap_mentioned_p (operands[0], operands[1])
5949 && reg_overlap_mentioned_p (operands[0], operands[2])"
5951 (plus:SI (match_dup 1)
5954 (mem:DI (match_dup 4)))]
5956 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5960 (define_expand "movsi"
5961 [(set (match_operand:SI 0 "general_operand" "")
5962 (match_operand:SI 1 "general_operand" ""))]
5966 rtx base, offset, tmp;
5970 /* Everything except mem = const or mem = mem can be done easily. */
5971 if (MEM_P (operands[0]))
5972 operands[1] = force_reg (SImode, operands[1]);
5973 if (arm_general_register_operand (operands[0], SImode)
5974 && CONST_INT_P (operands[1])
5975 && !(const_ok_for_arm (INTVAL (operands[1]))
5976 || const_ok_for_arm (~INTVAL (operands[1]))))
5978 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5980 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5985 arm_split_constant (SET, SImode, NULL_RTX,
5986 INTVAL (operands[1]), operands[0], NULL_RTX,
5987 optimize && can_create_pseudo_p ());
5992 else /* TARGET_THUMB1... */
5994 if (can_create_pseudo_p ())
5996 if (!REG_P (operands[0]))
5997 operands[1] = force_reg (SImode, operands[1]);
6001 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6003 split_const (operands[1], &base, &offset);
6004 if (GET_CODE (base) == SYMBOL_REF
6005 && !offset_within_block_p (base, INTVAL (offset)))
6007 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6008 emit_move_insn (tmp, base);
6009 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6014 /* Recognize the case where operand[1] is a reference to thread-local
6015 data and load its address to a register. */
6016 if (arm_tls_referenced_p (operands[1]))
6018 rtx tmp = operands[1];
6021 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6023 addend = XEXP (XEXP (tmp, 0), 1);
6024 tmp = XEXP (XEXP (tmp, 0), 0);
6027 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6028 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6030 tmp = legitimize_tls_address (tmp,
6031 !can_create_pseudo_p () ? operands[0] : 0);
6034 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6035 tmp = force_operand (tmp, operands[0]);
6040 && (CONSTANT_P (operands[1])
6041 || symbol_mentioned_p (operands[1])
6042 || label_mentioned_p (operands[1])))
6043 operands[1] = legitimize_pic_address (operands[1], SImode,
6044 (!can_create_pseudo_p ()
6051 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6052 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6053 ;; so this does not matter.
6054 (define_insn "*arm_movt"
6055 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6056 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6057 (match_operand:SI 2 "general_operand" "i,i")))]
6058 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6060 movt%?\t%0, #:upper16:%c2
6061 movt\t%0, #:upper16:%c2"
6062 [(set_attr "arch" "32,v8mb")
6063 (set_attr "predicable" "yes")
6064 (set_attr "predicable_short_it" "no")
6065 (set_attr "length" "4")
6066 (set_attr "type" "alu_sreg")]
6069 (define_insn "*arm_movsi_insn"
6070 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6071 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6072 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6073 && ( register_operand (operands[0], SImode)
6074 || register_operand (operands[1], SImode))"
6082 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6083 (set_attr "predicable" "yes")
6084 (set_attr "arch" "*,*,*,v6t2,*,*")
6085 (set_attr "pool_range" "*,*,*,*,4096,*")
6086 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6090 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6091 (match_operand:SI 1 "const_int_operand" ""))]
6093 && (!(const_ok_for_arm (INTVAL (operands[1]))
6094 || const_ok_for_arm (~INTVAL (operands[1]))))"
6095 [(clobber (const_int 0))]
6097 arm_split_constant (SET, SImode, NULL_RTX,
6098 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6103 ;; A normal way to do (symbol + offset) requires three instructions at least
6104 ;; (depends on how big the offset is) as below:
6105 ;; movw r0, #:lower16:g
6106 ;; movw r0, #:upper16:g
6109 ;; A better way would be:
6110 ;; movw r0, #:lower16:g+4
6111 ;; movw r0, #:upper16:g+4
6113 ;; The limitation of this way is that the length of offset should be a 16-bit
6114 ;; signed value, because current assembler only supports REL type relocation for
6115 ;; such case. If the more powerful RELA type is supported in future, we should
6116 ;; update this pattern to go with better way.
6118 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6119 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6120 (match_operand:SI 2 "const_int_operand" ""))))]
6123 && arm_disable_literal_pool
6125 && GET_CODE (operands[1]) == SYMBOL_REF"
6126 [(clobber (const_int 0))]
6128 int offset = INTVAL (operands[2]);
6130 if (offset < -0x8000 || offset > 0x7fff)
6132 arm_emit_movpair (operands[0], operands[1]);
6133 emit_insn (gen_rtx_SET (operands[0],
6134 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6138 rtx op = gen_rtx_CONST (SImode,
6139 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6140 arm_emit_movpair (operands[0], op);
6145 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6146 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6147 ;; and lo_sum would be merged back into memory load at cprop. However,
6148 ;; if the default is to prefer movt/movw rather than a load from the constant
6149 ;; pool, the performance is better.
6151 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6152 (match_operand:SI 1 "general_operand" ""))]
6153 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6154 && !flag_pic && !target_word_relocations
6155 && !arm_tls_referenced_p (operands[1])"
6156 [(clobber (const_int 0))]
6158 arm_emit_movpair (operands[0], operands[1]);
6162 ;; When generating pic, we need to load the symbol offset into a register.
6163 ;; So that the optimizer does not confuse this with a normal symbol load
6164 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6165 ;; since that is the only type of relocation we can use.
6167 ;; Wrap calculation of the whole PIC address in a single pattern for the
6168 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6169 ;; a PIC address involves two loads from memory, so we want to CSE it
6170 ;; as often as possible.
6171 ;; This pattern will be split into one of the pic_load_addr_* patterns
6172 ;; and a move after GCSE optimizations.
6174 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6175 (define_expand "calculate_pic_address"
6176 [(set (match_operand:SI 0 "register_operand" "")
6177 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6178 (unspec:SI [(match_operand:SI 2 "" "")]
6183 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6185 [(set (match_operand:SI 0 "register_operand" "")
6186 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6187 (unspec:SI [(match_operand:SI 2 "" "")]
6190 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6191 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6192 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6195 ;; operand1 is the memory address to go into
6196 ;; pic_load_addr_32bit.
6197 ;; operand2 is the PIC label to be emitted
6198 ;; from pic_add_dot_plus_eight.
6199 ;; We do this to allow hoisting of the entire insn.
6200 (define_insn_and_split "pic_load_addr_unified"
6201 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6202 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6203 (match_operand:SI 2 "" "")]
6204 UNSPEC_PIC_UNIFIED))]
6207 "&& reload_completed"
6208 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6209 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6210 (match_dup 2)] UNSPEC_PIC_BASE))]
6211 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6212 [(set_attr "type" "load1,load1,load1")
6213 (set_attr "pool_range" "4096,4094,1022")
6214 (set_attr "neg_pool_range" "4084,0,0")
6215 (set_attr "arch" "a,t2,t1")
6216 (set_attr "length" "8,6,4")]
6219 ;; The rather odd constraints on the following are to force reload to leave
6220 ;; the insn alone, and to force the minipool generation pass to then move
6221 ;; the GOT symbol to memory.
6223 (define_insn "pic_load_addr_32bit"
6224 [(set (match_operand:SI 0 "s_register_operand" "=r")
6225 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6226 "TARGET_32BIT && flag_pic"
6228 [(set_attr "type" "load1")
6229 (set (attr "pool_range")
6230 (if_then_else (eq_attr "is_thumb" "no")
6233 (set (attr "neg_pool_range")
6234 (if_then_else (eq_attr "is_thumb" "no")
6239 (define_insn "pic_load_addr_thumb1"
6240 [(set (match_operand:SI 0 "s_register_operand" "=l")
6241 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6242 "TARGET_THUMB1 && flag_pic"
6244 [(set_attr "type" "load1")
6245 (set (attr "pool_range") (const_int 1018))]
6248 (define_insn "pic_add_dot_plus_four"
6249 [(set (match_operand:SI 0 "register_operand" "=r")
6250 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6252 (match_operand 2 "" "")]
6256 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6257 INTVAL (operands[2]));
6258 return \"add\\t%0, %|pc\";
6260 [(set_attr "length" "2")
6261 (set_attr "type" "alu_sreg")]
6264 (define_insn "pic_add_dot_plus_eight"
6265 [(set (match_operand:SI 0 "register_operand" "=r")
6266 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6268 (match_operand 2 "" "")]
6272 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6273 INTVAL (operands[2]));
6274 return \"add%?\\t%0, %|pc, %1\";
6276 [(set_attr "predicable" "yes")
6277 (set_attr "type" "alu_sreg")]
6280 (define_insn "tls_load_dot_plus_eight"
6281 [(set (match_operand:SI 0 "register_operand" "=r")
6282 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6284 (match_operand 2 "" "")]
6288 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6289 INTVAL (operands[2]));
6290 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6292 [(set_attr "predicable" "yes")
6293 (set_attr "type" "load1")]
6296 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6297 ;; followed by a load. These sequences can be crunched down to
6298 ;; tls_load_dot_plus_eight by a peephole.
6301 [(set (match_operand:SI 0 "register_operand" "")
6302 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6304 (match_operand 1 "" "")]
6306 (set (match_operand:SI 2 "arm_general_register_operand" "")
6307 (mem:SI (match_dup 0)))]
6308 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6310 (mem:SI (unspec:SI [(match_dup 3)
6317 (define_insn "pic_offset_arm"
6318 [(set (match_operand:SI 0 "register_operand" "=r")
6319 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6320 (unspec:SI [(match_operand:SI 2 "" "X")]
6321 UNSPEC_PIC_OFFSET))))]
6322 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6323 "ldr%?\\t%0, [%1,%2]"
6324 [(set_attr "type" "load1")]
6327 (define_expand "builtin_setjmp_receiver"
6328 [(label_ref (match_operand 0 "" ""))]
6332 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6334 if (arm_pic_register != INVALID_REGNUM)
6335 arm_load_pic_register (1UL << 3);
6339 ;; If copying one reg to another we can set the condition codes according to
6340 ;; its value. Such a move is common after a return from subroutine and the
6341 ;; result is being tested against zero.
6343 (define_insn "*movsi_compare0"
6344 [(set (reg:CC CC_REGNUM)
6345 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6347 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6352 subs%?\\t%0, %1, #0"
6353 [(set_attr "conds" "set")
6354 (set_attr "type" "alus_imm,alus_imm")]
6357 ;; Subroutine to store a half word from a register into memory.
6358 ;; Operand 0 is the source register (HImode)
6359 ;; Operand 1 is the destination address in a register (SImode)
6361 ;; In both this routine and the next, we must be careful not to spill
6362 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6363 ;; can generate unrecognizable rtl.
6365 (define_expand "storehi"
6366 [;; store the low byte
6367 (set (match_operand 1 "" "") (match_dup 3))
6368 ;; extract the high byte
6370 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6371 ;; store the high byte
6372 (set (match_dup 4) (match_dup 5))]
6376 rtx op1 = operands[1];
6377 rtx addr = XEXP (op1, 0);
6378 enum rtx_code code = GET_CODE (addr);
6380 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6382 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6384 operands[4] = adjust_address (op1, QImode, 1);
6385 operands[1] = adjust_address (operands[1], QImode, 0);
6386 operands[3] = gen_lowpart (QImode, operands[0]);
6387 operands[0] = gen_lowpart (SImode, operands[0]);
6388 operands[2] = gen_reg_rtx (SImode);
6389 operands[5] = gen_lowpart (QImode, operands[2]);
6393 (define_expand "storehi_bigend"
6394 [(set (match_dup 4) (match_dup 3))
6396 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6397 (set (match_operand 1 "" "") (match_dup 5))]
6401 rtx op1 = operands[1];
6402 rtx addr = XEXP (op1, 0);
6403 enum rtx_code code = GET_CODE (addr);
6405 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6407 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6409 operands[4] = adjust_address (op1, QImode, 1);
6410 operands[1] = adjust_address (operands[1], QImode, 0);
6411 operands[3] = gen_lowpart (QImode, operands[0]);
6412 operands[0] = gen_lowpart (SImode, operands[0]);
6413 operands[2] = gen_reg_rtx (SImode);
6414 operands[5] = gen_lowpart (QImode, operands[2]);
6418 ;; Subroutine to store a half word integer constant into memory.
6419 (define_expand "storeinthi"
6420 [(set (match_operand 0 "" "")
6421 (match_operand 1 "" ""))
6422 (set (match_dup 3) (match_dup 2))]
6426 HOST_WIDE_INT value = INTVAL (operands[1]);
6427 rtx addr = XEXP (operands[0], 0);
6428 rtx op0 = operands[0];
6429 enum rtx_code code = GET_CODE (addr);
6431 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6433 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6435 operands[1] = gen_reg_rtx (SImode);
6436 if (BYTES_BIG_ENDIAN)
6438 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6439 if ((value & 255) == ((value >> 8) & 255))
6440 operands[2] = operands[1];
6443 operands[2] = gen_reg_rtx (SImode);
6444 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6449 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6450 if ((value & 255) == ((value >> 8) & 255))
6451 operands[2] = operands[1];
6454 operands[2] = gen_reg_rtx (SImode);
6455 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6459 operands[3] = adjust_address (op0, QImode, 1);
6460 operands[0] = adjust_address (operands[0], QImode, 0);
6461 operands[2] = gen_lowpart (QImode, operands[2]);
6462 operands[1] = gen_lowpart (QImode, operands[1]);
6466 (define_expand "storehi_single_op"
6467 [(set (match_operand:HI 0 "memory_operand" "")
6468 (match_operand:HI 1 "general_operand" ""))]
6469 "TARGET_32BIT && arm_arch4"
6471 if (!s_register_operand (operands[1], HImode))
6472 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6476 (define_expand "movhi"
6477 [(set (match_operand:HI 0 "general_operand" "")
6478 (match_operand:HI 1 "general_operand" ""))]
6483 if (can_create_pseudo_p ())
6485 if (MEM_P (operands[0]))
6489 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6492 if (CONST_INT_P (operands[1]))
6493 emit_insn (gen_storeinthi (operands[0], operands[1]));
6496 if (MEM_P (operands[1]))
6497 operands[1] = force_reg (HImode, operands[1]);
6498 if (BYTES_BIG_ENDIAN)
6499 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6501 emit_insn (gen_storehi (operands[1], operands[0]));
6505 /* Sign extend a constant, and keep it in an SImode reg. */
6506 else if (CONST_INT_P (operands[1]))
6508 rtx reg = gen_reg_rtx (SImode);
6509 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6511 /* If the constant is already valid, leave it alone. */
6512 if (!const_ok_for_arm (val))
6514 /* If setting all the top bits will make the constant
6515 loadable in a single instruction, then set them.
6516 Otherwise, sign extend the number. */
6518 if (const_ok_for_arm (~(val | ~0xffff)))
6520 else if (val & 0x8000)
6524 emit_insn (gen_movsi (reg, GEN_INT (val)));
6525 operands[1] = gen_lowpart (HImode, reg);
6527 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6528 && MEM_P (operands[1]))
6530 rtx reg = gen_reg_rtx (SImode);
6532 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6533 operands[1] = gen_lowpart (HImode, reg);
6535 else if (!arm_arch4)
6537 if (MEM_P (operands[1]))
6540 rtx offset = const0_rtx;
6541 rtx reg = gen_reg_rtx (SImode);
6543 if ((REG_P (base = XEXP (operands[1], 0))
6544 || (GET_CODE (base) == PLUS
6545 && (CONST_INT_P (offset = XEXP (base, 1)))
6546 && ((INTVAL(offset) & 1) != 1)
6547 && REG_P (base = XEXP (base, 0))))
6548 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6552 new_rtx = widen_memory_access (operands[1], SImode,
6553 ((INTVAL (offset) & ~3)
6554 - INTVAL (offset)));
6555 emit_insn (gen_movsi (reg, new_rtx));
6556 if (((INTVAL (offset) & 2) != 0)
6557 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6559 rtx reg2 = gen_reg_rtx (SImode);
6561 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6566 emit_insn (gen_movhi_bytes (reg, operands[1]));
6568 operands[1] = gen_lowpart (HImode, reg);
6572 /* Handle loading a large integer during reload. */
6573 else if (CONST_INT_P (operands[1])
6574 && !const_ok_for_arm (INTVAL (operands[1]))
6575 && !const_ok_for_arm (~INTVAL (operands[1])))
6577 /* Writing a constant to memory needs a scratch, which should
6578 be handled with SECONDARY_RELOADs. */
6579 gcc_assert (REG_P (operands[0]));
6581 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6582 emit_insn (gen_movsi (operands[0], operands[1]));
6586 else if (TARGET_THUMB2)
6588 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6589 if (can_create_pseudo_p ())
6591 if (!REG_P (operands[0]))
6592 operands[1] = force_reg (HImode, operands[1]);
6593 /* Zero extend a constant, and keep it in an SImode reg. */
6594 else if (CONST_INT_P (operands[1]))
6596 rtx reg = gen_reg_rtx (SImode);
6597 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6599 emit_insn (gen_movsi (reg, GEN_INT (val)));
6600 operands[1] = gen_lowpart (HImode, reg);
6604 else /* TARGET_THUMB1 */
6606 if (can_create_pseudo_p ())
6608 if (CONST_INT_P (operands[1]))
6610 rtx reg = gen_reg_rtx (SImode);
6612 emit_insn (gen_movsi (reg, operands[1]));
6613 operands[1] = gen_lowpart (HImode, reg);
6616 /* ??? We shouldn't really get invalid addresses here, but this can
6617 happen if we are passed a SP (never OK for HImode/QImode) or
6618 virtual register (also rejected as illegitimate for HImode/QImode)
6619 relative address. */
6620 /* ??? This should perhaps be fixed elsewhere, for instance, in
6621 fixup_stack_1, by checking for other kinds of invalid addresses,
6622 e.g. a bare reference to a virtual register. This may confuse the
6623 alpha though, which must handle this case differently. */
6624 if (MEM_P (operands[0])
6625 && !memory_address_p (GET_MODE (operands[0]),
6626 XEXP (operands[0], 0)))
6628 = replace_equiv_address (operands[0],
6629 copy_to_reg (XEXP (operands[0], 0)));
6631 if (MEM_P (operands[1])
6632 && !memory_address_p (GET_MODE (operands[1]),
6633 XEXP (operands[1], 0)))
6635 = replace_equiv_address (operands[1],
6636 copy_to_reg (XEXP (operands[1], 0)));
6638 if (MEM_P (operands[1]) && optimize > 0)
6640 rtx reg = gen_reg_rtx (SImode);
6642 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6643 operands[1] = gen_lowpart (HImode, reg);
6646 if (MEM_P (operands[0]))
6647 operands[1] = force_reg (HImode, operands[1]);
6649 else if (CONST_INT_P (operands[1])
6650 && !satisfies_constraint_I (operands[1]))
6652 /* Handle loading a large integer during reload. */
6654 /* Writing a constant to memory needs a scratch, which should
6655 be handled with SECONDARY_RELOADs. */
6656 gcc_assert (REG_P (operands[0]));
6658 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6659 emit_insn (gen_movsi (operands[0], operands[1]));
6666 (define_expand "movhi_bytes"
6667 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6669 (zero_extend:SI (match_dup 6)))
6670 (set (match_operand:SI 0 "" "")
6671 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6676 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6678 mem1 = change_address (operands[1], QImode, addr);
6679 mem2 = change_address (operands[1], QImode,
6680 plus_constant (Pmode, addr, 1));
6681 operands[0] = gen_lowpart (SImode, operands[0]);
6683 operands[2] = gen_reg_rtx (SImode);
6684 operands[3] = gen_reg_rtx (SImode);
6687 if (BYTES_BIG_ENDIAN)
6689 operands[4] = operands[2];
6690 operands[5] = operands[3];
6694 operands[4] = operands[3];
6695 operands[5] = operands[2];
6700 (define_expand "movhi_bigend"
6702 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6705 (ashiftrt:SI (match_dup 2) (const_int 16)))
6706 (set (match_operand:HI 0 "s_register_operand" "")
6710 operands[2] = gen_reg_rtx (SImode);
6711 operands[3] = gen_reg_rtx (SImode);
6712 operands[4] = gen_lowpart (HImode, operands[3]);
6716 ;; Pattern to recognize insn generated default case above
6717 (define_insn "*movhi_insn_arch4"
6718 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6719 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6721 && arm_arch4 && !TARGET_HARD_FLOAT
6722 && (register_operand (operands[0], HImode)
6723 || register_operand (operands[1], HImode))"
6725 mov%?\\t%0, %1\\t%@ movhi
6726 mvn%?\\t%0, #%B1\\t%@ movhi
6727 movw%?\\t%0, %L1\\t%@ movhi
6728 strh%?\\t%1, %0\\t%@ movhi
6729 ldrh%?\\t%0, %1\\t%@ movhi"
6730 [(set_attr "predicable" "yes")
6731 (set_attr "pool_range" "*,*,*,*,256")
6732 (set_attr "neg_pool_range" "*,*,*,*,244")
6733 (set_attr "arch" "*,*,v6t2,*,*")
6734 (set_attr_alternative "type"
6735 [(if_then_else (match_operand 1 "const_int_operand" "")
6736 (const_string "mov_imm" )
6737 (const_string "mov_reg"))
6738 (const_string "mvn_imm")
6739 (const_string "mov_imm")
6740 (const_string "store1")
6741 (const_string "load1")])]
6744 (define_insn "*movhi_bytes"
6745 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6746 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6747 "TARGET_ARM && !TARGET_HARD_FLOAT"
6749 mov%?\\t%0, %1\\t%@ movhi
6750 mov%?\\t%0, %1\\t%@ movhi
6751 mvn%?\\t%0, #%B1\\t%@ movhi"
6752 [(set_attr "predicable" "yes")
6753 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6756 ;; We use a DImode scratch because we may occasionally need an additional
6757 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6758 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6759 (define_expand "reload_outhi"
6760 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6761 (match_operand:HI 1 "s_register_operand" "r")
6762 (match_operand:DI 2 "s_register_operand" "=&l")])]
6765 arm_reload_out_hi (operands);
6767 thumb_reload_out_hi (operands);
6772 (define_expand "reload_inhi"
6773 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6774 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6775 (match_operand:DI 2 "s_register_operand" "=&r")])]
6779 arm_reload_in_hi (operands);
6781 thumb_reload_out_hi (operands);
6785 (define_expand "movqi"
6786 [(set (match_operand:QI 0 "general_operand" "")
6787 (match_operand:QI 1 "general_operand" ""))]
6790 /* Everything except mem = const or mem = mem can be done easily */
6792 if (can_create_pseudo_p ())
6794 if (CONST_INT_P (operands[1]))
6796 rtx reg = gen_reg_rtx (SImode);
6798 /* For thumb we want an unsigned immediate, then we are more likely
6799 to be able to use a movs insn. */
6801 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6803 emit_insn (gen_movsi (reg, operands[1]));
6804 operands[1] = gen_lowpart (QImode, reg);
6809 /* ??? We shouldn't really get invalid addresses here, but this can
6810 happen if we are passed a SP (never OK for HImode/QImode) or
6811 virtual register (also rejected as illegitimate for HImode/QImode)
6812 relative address. */
6813 /* ??? This should perhaps be fixed elsewhere, for instance, in
6814 fixup_stack_1, by checking for other kinds of invalid addresses,
6815 e.g. a bare reference to a virtual register. This may confuse the
6816 alpha though, which must handle this case differently. */
6817 if (MEM_P (operands[0])
6818 && !memory_address_p (GET_MODE (operands[0]),
6819 XEXP (operands[0], 0)))
6821 = replace_equiv_address (operands[0],
6822 copy_to_reg (XEXP (operands[0], 0)));
6823 if (MEM_P (operands[1])
6824 && !memory_address_p (GET_MODE (operands[1]),
6825 XEXP (operands[1], 0)))
6827 = replace_equiv_address (operands[1],
6828 copy_to_reg (XEXP (operands[1], 0)));
6831 if (MEM_P (operands[1]) && optimize > 0)
6833 rtx reg = gen_reg_rtx (SImode);
6835 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6836 operands[1] = gen_lowpart (QImode, reg);
6839 if (MEM_P (operands[0]))
6840 operands[1] = force_reg (QImode, operands[1]);
6842 else if (TARGET_THUMB
6843 && CONST_INT_P (operands[1])
6844 && !satisfies_constraint_I (operands[1]))
6846 /* Handle loading a large integer during reload. */
6848 /* Writing a constant to memory needs a scratch, which should
6849 be handled with SECONDARY_RELOADs. */
6850 gcc_assert (REG_P (operands[0]));
6852 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6853 emit_insn (gen_movsi (operands[0], operands[1]));
6859 (define_insn "*arm_movqi_insn"
6860 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6861 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6863 && ( register_operand (operands[0], QImode)
6864 || register_operand (operands[1], QImode))"
6875 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6876 (set_attr "predicable" "yes")
6877 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6878 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6879 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6883 (define_expand "movhf"
6884 [(set (match_operand:HF 0 "general_operand" "")
6885 (match_operand:HF 1 "general_operand" ""))]
6890 if (MEM_P (operands[0]))
6891 operands[1] = force_reg (HFmode, operands[1]);
6893 else /* TARGET_THUMB1 */
6895 if (can_create_pseudo_p ())
6897 if (!REG_P (operands[0]))
6898 operands[1] = force_reg (HFmode, operands[1]);
6904 (define_insn "*arm32_movhf"
6905 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6906 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6907 "TARGET_32BIT && !TARGET_HARD_FLOAT
6908 && ( s_register_operand (operands[0], HFmode)
6909 || s_register_operand (operands[1], HFmode))"
6911 switch (which_alternative)
6913 case 0: /* ARM register from memory */
6914 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6915 case 1: /* memory from ARM register */
6916 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6917 case 2: /* ARM register from ARM register */
6918 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6919 case 3: /* ARM register from constant */
6924 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6926 ops[0] = operands[0];
6927 ops[1] = GEN_INT (bits);
6928 ops[2] = GEN_INT (bits & 0xff00);
6929 ops[3] = GEN_INT (bits & 0x00ff);
6931 if (arm_arch_thumb2)
6932 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6934 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6941 [(set_attr "conds" "unconditional")
6942 (set_attr "type" "load1,store1,mov_reg,multiple")
6943 (set_attr "length" "4,4,4,8")
6944 (set_attr "predicable" "yes")
6945 (set_attr "predicable_short_it" "no")]
6948 (define_expand "movsf"
6949 [(set (match_operand:SF 0 "general_operand" "")
6950 (match_operand:SF 1 "general_operand" ""))]
6955 if (MEM_P (operands[0]))
6956 operands[1] = force_reg (SFmode, operands[1]);
6958 else /* TARGET_THUMB1 */
6960 if (can_create_pseudo_p ())
6962 if (!REG_P (operands[0]))
6963 operands[1] = force_reg (SFmode, operands[1]);
6969 ;; Transform a floating-point move of a constant into a core register into
6970 ;; an SImode operation.
6972 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6973 (match_operand:SF 1 "immediate_operand" ""))]
6976 && CONST_DOUBLE_P (operands[1])"
6977 [(set (match_dup 2) (match_dup 3))]
6979 operands[2] = gen_lowpart (SImode, operands[0]);
6980 operands[3] = gen_lowpart (SImode, operands[1]);
6981 if (operands[2] == 0 || operands[3] == 0)
6986 (define_insn "*arm_movsf_soft_insn"
6987 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6988 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6990 && TARGET_SOFT_FLOAT
6991 && (!MEM_P (operands[0])
6992 || register_operand (operands[1], SFmode))"
6995 ldr%?\\t%0, %1\\t%@ float
6996 str%?\\t%1, %0\\t%@ float"
6997 [(set_attr "predicable" "yes")
6998 (set_attr "predicable_short_it" "no")
6999 (set_attr "type" "mov_reg,load1,store1")
7000 (set_attr "arm_pool_range" "*,4096,*")
7001 (set_attr "thumb2_pool_range" "*,4094,*")
7002 (set_attr "arm_neg_pool_range" "*,4084,*")
7003 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7006 (define_expand "movdf"
7007 [(set (match_operand:DF 0 "general_operand" "")
7008 (match_operand:DF 1 "general_operand" ""))]
7013 if (MEM_P (operands[0]))
7014 operands[1] = force_reg (DFmode, operands[1]);
7016 else /* TARGET_THUMB */
7018 if (can_create_pseudo_p ())
7020 if (!REG_P (operands[0]))
7021 operands[1] = force_reg (DFmode, operands[1]);
7027 ;; Reloading a df mode value stored in integer regs to memory can require a
7029 (define_expand "reload_outdf"
7030 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7031 (match_operand:DF 1 "s_register_operand" "r")
7032 (match_operand:SI 2 "s_register_operand" "=&r")]
7036 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7039 operands[2] = XEXP (operands[0], 0);
7040 else if (code == POST_INC || code == PRE_DEC)
7042 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7043 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7044 emit_insn (gen_movdi (operands[0], operands[1]));
7047 else if (code == PRE_INC)
7049 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7051 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7054 else if (code == POST_DEC)
7055 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7057 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7058 XEXP (XEXP (operands[0], 0), 1)));
7060 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7063 if (code == POST_DEC)
7064 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7070 (define_insn "*movdf_soft_insn"
7071 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7072 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7073 "TARGET_32BIT && TARGET_SOFT_FLOAT
7074 && ( register_operand (operands[0], DFmode)
7075 || register_operand (operands[1], DFmode))"
7077 switch (which_alternative)
7084 return output_move_double (operands, true, NULL);
7087 [(set_attr "length" "8,12,16,8,8")
7088 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7089 (set_attr "arm_pool_range" "*,*,*,1020,*")
7090 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7091 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7092 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7096 ;; load- and store-multiple insns
7097 ;; The arm can load/store any set of registers, provided that they are in
7098 ;; ascending order, but these expanders assume a contiguous set.
7100 (define_expand "load_multiple"
7101 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7102 (match_operand:SI 1 "" ""))
7103 (use (match_operand:SI 2 "" ""))])]
7106 HOST_WIDE_INT offset = 0;
7108 /* Support only fixed point registers. */
7109 if (!CONST_INT_P (operands[2])
7110 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7111 || INTVAL (operands[2]) < 2
7112 || !MEM_P (operands[1])
7113 || !REG_P (operands[0])
7114 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7115 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7119 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7120 INTVAL (operands[2]),
7121 force_reg (SImode, XEXP (operands[1], 0)),
7122 FALSE, operands[1], &offset);
7125 (define_expand "store_multiple"
7126 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7127 (match_operand:SI 1 "" ""))
7128 (use (match_operand:SI 2 "" ""))])]
7131 HOST_WIDE_INT offset = 0;
7133 /* Support only fixed point registers. */
7134 if (!CONST_INT_P (operands[2])
7135 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7136 || INTVAL (operands[2]) < 2
7137 || !REG_P (operands[1])
7138 || !MEM_P (operands[0])
7139 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7140 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7144 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7145 INTVAL (operands[2]),
7146 force_reg (SImode, XEXP (operands[0], 0)),
7147 FALSE, operands[0], &offset);
7151 (define_expand "setmemsi"
7152 [(match_operand:BLK 0 "general_operand" "")
7153 (match_operand:SI 1 "const_int_operand" "")
7154 (match_operand:SI 2 "const_int_operand" "")
7155 (match_operand:SI 3 "const_int_operand" "")]
7158 if (arm_gen_setmem (operands))
7165 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7166 ;; We could let this apply for blocks of less than this, but it clobbers so
7167 ;; many registers that there is then probably a better way.
7169 (define_expand "movmemqi"
7170 [(match_operand:BLK 0 "general_operand" "")
7171 (match_operand:BLK 1 "general_operand" "")
7172 (match_operand:SI 2 "const_int_operand" "")
7173 (match_operand:SI 3 "const_int_operand" "")]
7178 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7179 && !optimize_function_for_size_p (cfun))
7181 if (gen_movmem_ldrd_strd (operands))
7186 if (arm_gen_movmemqi (operands))
7190 else /* TARGET_THUMB1 */
7192 if ( INTVAL (operands[3]) != 4
7193 || INTVAL (operands[2]) > 48)
7196 thumb_expand_movmemqi (operands);
7203 ;; Compare & branch insns
7204 ;; The range calculations are based as follows:
7205 ;; For forward branches, the address calculation returns the address of
7206 ;; the next instruction. This is 2 beyond the branch instruction.
7207 ;; For backward branches, the address calculation returns the address of
7208 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7209 ;; instruction for the shortest sequence, and 4 before the branch instruction
7210 ;; if we have to jump around an unconditional branch.
7211 ;; To the basic branch range the PC offset must be added (this is +4).
7212 ;; So for forward branches we have
7213 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7214 ;; And for backward branches we have
7215 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7217 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7218 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7220 (define_expand "cbranchsi4"
7221 [(set (pc) (if_then_else
7222 (match_operator 0 "expandable_comparison_operator"
7223 [(match_operand:SI 1 "s_register_operand" "")
7224 (match_operand:SI 2 "nonmemory_operand" "")])
7225 (label_ref (match_operand 3 "" ""))
7231 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7233 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7237 if (thumb1_cmpneg_operand (operands[2], SImode))
7239 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7240 operands[3], operands[0]));
7243 if (!thumb1_cmp_operand (operands[2], SImode))
7244 operands[2] = force_reg (SImode, operands[2]);
7247 (define_expand "cbranchsf4"
7248 [(set (pc) (if_then_else
7249 (match_operator 0 "expandable_comparison_operator"
7250 [(match_operand:SF 1 "s_register_operand" "")
7251 (match_operand:SF 2 "vfp_compare_operand" "")])
7252 (label_ref (match_operand 3 "" ""))
7254 "TARGET_32BIT && TARGET_HARD_FLOAT"
7255 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7256 operands[3])); DONE;"
7259 (define_expand "cbranchdf4"
7260 [(set (pc) (if_then_else
7261 (match_operator 0 "expandable_comparison_operator"
7262 [(match_operand:DF 1 "s_register_operand" "")
7263 (match_operand:DF 2 "vfp_compare_operand" "")])
7264 (label_ref (match_operand 3 "" ""))
7266 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7267 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7268 operands[3])); DONE;"
7271 (define_expand "cbranchdi4"
7272 [(set (pc) (if_then_else
7273 (match_operator 0 "expandable_comparison_operator"
7274 [(match_operand:DI 1 "s_register_operand" "")
7275 (match_operand:DI 2 "cmpdi_operand" "")])
7276 (label_ref (match_operand 3 "" ""))
7280 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7282 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7288 ;; Comparison and test insns
7290 (define_insn "*arm_cmpsi_insn"
7291 [(set (reg:CC CC_REGNUM)
7292 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7293 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7301 [(set_attr "conds" "set")
7302 (set_attr "arch" "t2,t2,any,any,any")
7303 (set_attr "length" "2,2,4,4,4")
7304 (set_attr "predicable" "yes")
7305 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7306 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7309 (define_insn "*cmpsi_shiftsi"
7310 [(set (reg:CC CC_REGNUM)
7311 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7312 (match_operator:SI 3 "shift_operator"
7313 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7314 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7317 [(set_attr "conds" "set")
7318 (set_attr "shift" "1")
7319 (set_attr "arch" "32,a,a")
7320 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7322 (define_insn "*cmpsi_shiftsi_swp"
7323 [(set (reg:CC_SWP CC_REGNUM)
7324 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7325 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7326 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7327 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7330 [(set_attr "conds" "set")
7331 (set_attr "shift" "1")
7332 (set_attr "arch" "32,a,a")
7333 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7335 (define_insn "*arm_cmpsi_negshiftsi_si"
7336 [(set (reg:CC_Z CC_REGNUM)
7338 (neg:SI (match_operator:SI 1 "shift_operator"
7339 [(match_operand:SI 2 "s_register_operand" "r")
7340 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7341 (match_operand:SI 0 "s_register_operand" "r")))]
7344 [(set_attr "conds" "set")
7345 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7346 (const_string "alus_shift_imm")
7347 (const_string "alus_shift_reg")))
7348 (set_attr "predicable" "yes")]
7351 ;; DImode comparisons. The generic code generates branches that
7352 ;; if-conversion can not reduce to a conditional compare, so we do
7355 (define_insn_and_split "*arm_cmpdi_insn"
7356 [(set (reg:CC_NCV CC_REGNUM)
7357 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7358 (match_operand:DI 1 "arm_di_operand" "rDi")))
7359 (clobber (match_scratch:SI 2 "=r"))]
7361 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7362 "&& reload_completed"
7363 [(set (reg:CC CC_REGNUM)
7364 (compare:CC (match_dup 0) (match_dup 1)))
7365 (parallel [(set (reg:CC CC_REGNUM)
7366 (compare:CC (match_dup 3) (match_dup 4)))
7368 (minus:SI (match_dup 5)
7369 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7371 operands[3] = gen_highpart (SImode, operands[0]);
7372 operands[0] = gen_lowpart (SImode, operands[0]);
7373 if (CONST_INT_P (operands[1]))
7375 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7378 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7382 operands[4] = gen_highpart (SImode, operands[1]);
7383 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7385 operands[1] = gen_lowpart (SImode, operands[1]);
7386 operands[2] = gen_lowpart (SImode, operands[2]);
7388 [(set_attr "conds" "set")
7389 (set_attr "length" "8")
7390 (set_attr "type" "multiple")]
7393 (define_insn_and_split "*arm_cmpdi_unsigned"
7394 [(set (reg:CC_CZ CC_REGNUM)
7395 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7396 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7399 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7400 "&& reload_completed"
7401 [(set (reg:CC CC_REGNUM)
7402 (compare:CC (match_dup 2) (match_dup 3)))
7403 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7404 (set (reg:CC CC_REGNUM)
7405 (compare:CC (match_dup 0) (match_dup 1))))]
7407 operands[2] = gen_highpart (SImode, operands[0]);
7408 operands[0] = gen_lowpart (SImode, operands[0]);
7409 if (CONST_INT_P (operands[1]))
7410 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7412 operands[3] = gen_highpart (SImode, operands[1]);
7413 operands[1] = gen_lowpart (SImode, operands[1]);
7415 [(set_attr "conds" "set")
7416 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7417 (set_attr "arch" "t2,t2,t2,a")
7418 (set_attr "length" "6,6,10,8")
7419 (set_attr "type" "multiple")]
7422 (define_insn "*arm_cmpdi_zero"
7423 [(set (reg:CC_Z CC_REGNUM)
7424 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7426 (clobber (match_scratch:SI 1 "=r"))]
7428 "orrs%?\\t%1, %Q0, %R0"
7429 [(set_attr "conds" "set")
7430 (set_attr "type" "logics_reg")]
7433 ; This insn allows redundant compares to be removed by cse, nothing should
7434 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7435 ; is deleted later on. The match_dup will match the mode here, so that
7436 ; mode changes of the condition codes aren't lost by this even though we don't
7437 ; specify what they are.
7439 (define_insn "*deleted_compare"
7440 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7442 "\\t%@ deleted compare"
7443 [(set_attr "conds" "set")
7444 (set_attr "length" "0")
7445 (set_attr "type" "no_insn")]
7449 ;; Conditional branch insns
7451 (define_expand "cbranch_cc"
7453 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7454 (match_operand 2 "" "")])
7455 (label_ref (match_operand 3 "" ""))
7458 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7459 operands[1], operands[2], NULL_RTX);
7460 operands[2] = const0_rtx;"
7464 ;; Patterns to match conditional branch insns.
7467 (define_insn "arm_cond_branch"
7469 (if_then_else (match_operator 1 "arm_comparison_operator"
7470 [(match_operand 2 "cc_register" "") (const_int 0)])
7471 (label_ref (match_operand 0 "" ""))
7475 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7477 arm_ccfsm_state += 2;
7480 return \"b%d1\\t%l0\";
7482 [(set_attr "conds" "use")
7483 (set_attr "type" "branch")
7484 (set (attr "length")
7486 (and (match_test "TARGET_THUMB2")
7487 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7488 (le (minus (match_dup 0) (pc)) (const_int 256))))
7493 (define_insn "*arm_cond_branch_reversed"
7495 (if_then_else (match_operator 1 "arm_comparison_operator"
7496 [(match_operand 2 "cc_register" "") (const_int 0)])
7498 (label_ref (match_operand 0 "" ""))))]
7501 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7503 arm_ccfsm_state += 2;
7506 return \"b%D1\\t%l0\";
7508 [(set_attr "conds" "use")
7509 (set_attr "type" "branch")
7510 (set (attr "length")
7512 (and (match_test "TARGET_THUMB2")
7513 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7514 (le (minus (match_dup 0) (pc)) (const_int 256))))
7523 (define_expand "cstore_cc"
7524 [(set (match_operand:SI 0 "s_register_operand" "")
7525 (match_operator:SI 1 "" [(match_operand 2 "" "")
7526 (match_operand 3 "" "")]))]
7528 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7529 operands[2], operands[3], NULL_RTX);
7530 operands[3] = const0_rtx;"
7533 (define_insn_and_split "*mov_scc"
7534 [(set (match_operand:SI 0 "s_register_operand" "=r")
7535 (match_operator:SI 1 "arm_comparison_operator_mode"
7536 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7538 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7541 (if_then_else:SI (match_dup 1)
7545 [(set_attr "conds" "use")
7546 (set_attr "length" "8")
7547 (set_attr "type" "multiple")]
7550 (define_insn_and_split "*mov_negscc"
7551 [(set (match_operand:SI 0 "s_register_operand" "=r")
7552 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7553 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7555 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7558 (if_then_else:SI (match_dup 1)
7562 operands[3] = GEN_INT (~0);
7564 [(set_attr "conds" "use")
7565 (set_attr "length" "8")
7566 (set_attr "type" "multiple")]
7569 (define_insn_and_split "*mov_notscc"
7570 [(set (match_operand:SI 0 "s_register_operand" "=r")
7571 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7572 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7574 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7577 (if_then_else:SI (match_dup 1)
7581 operands[3] = GEN_INT (~1);
7582 operands[4] = GEN_INT (~0);
7584 [(set_attr "conds" "use")
7585 (set_attr "length" "8")
7586 (set_attr "type" "multiple")]
7589 (define_expand "cstoresi4"
7590 [(set (match_operand:SI 0 "s_register_operand" "")
7591 (match_operator:SI 1 "expandable_comparison_operator"
7592 [(match_operand:SI 2 "s_register_operand" "")
7593 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7594 "TARGET_32BIT || TARGET_THUMB1"
7596 rtx op3, scratch, scratch2;
7600 if (!arm_add_operand (operands[3], SImode))
7601 operands[3] = force_reg (SImode, operands[3]);
7602 emit_insn (gen_cstore_cc (operands[0], operands[1],
7603 operands[2], operands[3]));
7607 if (operands[3] == const0_rtx)
7609 switch (GET_CODE (operands[1]))
7612 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7616 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7620 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7621 NULL_RTX, 0, OPTAB_WIDEN);
7622 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7623 NULL_RTX, 0, OPTAB_WIDEN);
7624 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7625 operands[0], 1, OPTAB_WIDEN);
7629 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7631 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7632 NULL_RTX, 1, OPTAB_WIDEN);
7636 scratch = expand_binop (SImode, ashr_optab, operands[2],
7637 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7638 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7639 NULL_RTX, 0, OPTAB_WIDEN);
7640 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7644 /* LT is handled by generic code. No need for unsigned with 0. */
7651 switch (GET_CODE (operands[1]))
7654 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7655 NULL_RTX, 0, OPTAB_WIDEN);
7656 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7660 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7661 NULL_RTX, 0, OPTAB_WIDEN);
7662 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7666 op3 = force_reg (SImode, operands[3]);
7668 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7669 NULL_RTX, 1, OPTAB_WIDEN);
7670 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7671 NULL_RTX, 0, OPTAB_WIDEN);
7672 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7678 if (!thumb1_cmp_operand (op3, SImode))
7679 op3 = force_reg (SImode, op3);
7680 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7681 NULL_RTX, 0, OPTAB_WIDEN);
7682 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7683 NULL_RTX, 1, OPTAB_WIDEN);
7684 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7689 op3 = force_reg (SImode, operands[3]);
7690 scratch = force_reg (SImode, const0_rtx);
7691 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7697 if (!thumb1_cmp_operand (op3, SImode))
7698 op3 = force_reg (SImode, op3);
7699 scratch = force_reg (SImode, const0_rtx);
7700 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7706 if (!thumb1_cmp_operand (op3, SImode))
7707 op3 = force_reg (SImode, op3);
7708 scratch = gen_reg_rtx (SImode);
7709 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7713 op3 = force_reg (SImode, operands[3]);
7714 scratch = gen_reg_rtx (SImode);
7715 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7718 /* No good sequences for GT, LT. */
7725 (define_expand "cstorehf4"
7726 [(set (match_operand:SI 0 "s_register_operand")
7727 (match_operator:SI 1 "expandable_comparison_operator"
7728 [(match_operand:HF 2 "s_register_operand")
7729 (match_operand:HF 3 "vfp_compare_operand")]))]
7730 "TARGET_VFP_FP16INST"
7732 if (!arm_validize_comparison (&operands[1],
7737 emit_insn (gen_cstore_cc (operands[0], operands[1],
7738 operands[2], operands[3]));
7743 (define_expand "cstoresf4"
7744 [(set (match_operand:SI 0 "s_register_operand" "")
7745 (match_operator:SI 1 "expandable_comparison_operator"
7746 [(match_operand:SF 2 "s_register_operand" "")
7747 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7748 "TARGET_32BIT && TARGET_HARD_FLOAT"
7749 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7750 operands[2], operands[3])); DONE;"
7753 (define_expand "cstoredf4"
7754 [(set (match_operand:SI 0 "s_register_operand" "")
7755 (match_operator:SI 1 "expandable_comparison_operator"
7756 [(match_operand:DF 2 "s_register_operand" "")
7757 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7758 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7759 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7760 operands[2], operands[3])); DONE;"
7763 (define_expand "cstoredi4"
7764 [(set (match_operand:SI 0 "s_register_operand" "")
7765 (match_operator:SI 1 "expandable_comparison_operator"
7766 [(match_operand:DI 2 "s_register_operand" "")
7767 (match_operand:DI 3 "cmpdi_operand" "")]))]
7770 if (!arm_validize_comparison (&operands[1],
7774 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7781 ;; Conditional move insns
7783 (define_expand "movsicc"
7784 [(set (match_operand:SI 0 "s_register_operand" "")
7785 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7786 (match_operand:SI 2 "arm_not_operand" "")
7787 (match_operand:SI 3 "arm_not_operand" "")))]
7794 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7795 &XEXP (operands[1], 1)))
7798 code = GET_CODE (operands[1]);
7799 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7800 XEXP (operands[1], 1), NULL_RTX);
7801 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7805 (define_expand "movhfcc"
7806 [(set (match_operand:HF 0 "s_register_operand")
7807 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7808 (match_operand:HF 2 "s_register_operand")
7809 (match_operand:HF 3 "s_register_operand")))]
7810 "TARGET_VFP_FP16INST"
7813 enum rtx_code code = GET_CODE (operands[1]);
7816 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7817 &XEXP (operands[1], 1)))
7820 code = GET_CODE (operands[1]);
7821 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7822 XEXP (operands[1], 1), NULL_RTX);
7823 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7827 (define_expand "movsfcc"
7828 [(set (match_operand:SF 0 "s_register_operand" "")
7829 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7830 (match_operand:SF 2 "s_register_operand" "")
7831 (match_operand:SF 3 "s_register_operand" "")))]
7832 "TARGET_32BIT && TARGET_HARD_FLOAT"
7835 enum rtx_code code = GET_CODE (operands[1]);
7838 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7839 &XEXP (operands[1], 1)))
7842 code = GET_CODE (operands[1]);
7843 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7844 XEXP (operands[1], 1), NULL_RTX);
7845 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7849 (define_expand "movdfcc"
7850 [(set (match_operand:DF 0 "s_register_operand" "")
7851 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7852 (match_operand:DF 2 "s_register_operand" "")
7853 (match_operand:DF 3 "s_register_operand" "")))]
7854 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7857 enum rtx_code code = GET_CODE (operands[1]);
7860 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7861 &XEXP (operands[1], 1)))
7863 code = GET_CODE (operands[1]);
7864 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7865 XEXP (operands[1], 1), NULL_RTX);
7866 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7870 (define_insn "*cmov<mode>"
7871 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7872 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7873 [(match_operand 2 "cc_register" "") (const_int 0)])
7874 (match_operand:SDF 3 "s_register_operand"
7876 (match_operand:SDF 4 "s_register_operand"
7877 "<F_constraint>")))]
7878 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7881 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7888 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7893 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7899 [(set_attr "conds" "use")
7900 (set_attr "type" "fcsel")]
7903 (define_insn "*cmovhf"
7904 [(set (match_operand:HF 0 "s_register_operand" "=t")
7905 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7906 [(match_operand 2 "cc_register" "") (const_int 0)])
7907 (match_operand:HF 3 "s_register_operand" "t")
7908 (match_operand:HF 4 "s_register_operand" "t")))]
7909 "TARGET_VFP_FP16INST"
7912 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7919 return \"vsel%d1.f16\\t%0, %3, %4\";
7924 return \"vsel%D1.f16\\t%0, %4, %3\";
7930 [(set_attr "conds" "use")
7931 (set_attr "type" "fcsel")]
7934 (define_insn_and_split "*movsicc_insn"
7935 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7937 (match_operator 3 "arm_comparison_operator"
7938 [(match_operand 4 "cc_register" "") (const_int 0)])
7939 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7940 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7951 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7952 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7953 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7954 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7955 "&& reload_completed"
7958 enum rtx_code rev_code;
7962 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7964 gen_rtx_SET (operands[0], operands[1])));
7966 rev_code = GET_CODE (operands[3]);
7967 mode = GET_MODE (operands[4]);
7968 if (mode == CCFPmode || mode == CCFPEmode)
7969 rev_code = reverse_condition_maybe_unordered (rev_code);
7971 rev_code = reverse_condition (rev_code);
7973 rev_cond = gen_rtx_fmt_ee (rev_code,
7977 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7979 gen_rtx_SET (operands[0], operands[2])));
7982 [(set_attr "length" "4,4,4,4,8,8,8,8")
7983 (set_attr "conds" "use")
7984 (set_attr_alternative "type"
7985 [(if_then_else (match_operand 2 "const_int_operand" "")
7986 (const_string "mov_imm")
7987 (const_string "mov_reg"))
7988 (const_string "mvn_imm")
7989 (if_then_else (match_operand 1 "const_int_operand" "")
7990 (const_string "mov_imm")
7991 (const_string "mov_reg"))
7992 (const_string "mvn_imm")
7993 (const_string "multiple")
7994 (const_string "multiple")
7995 (const_string "multiple")
7996 (const_string "multiple")])]
7999 (define_insn "*movsfcc_soft_insn"
8000 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8001 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8002 [(match_operand 4 "cc_register" "") (const_int 0)])
8003 (match_operand:SF 1 "s_register_operand" "0,r")
8004 (match_operand:SF 2 "s_register_operand" "r,0")))]
8005 "TARGET_ARM && TARGET_SOFT_FLOAT"
8009 [(set_attr "conds" "use")
8010 (set_attr "type" "mov_reg")]
8014 ;; Jump and linkage insns
8016 (define_expand "jump"
8018 (label_ref (match_operand 0 "" "")))]
8023 (define_insn "*arm_jump"
8025 (label_ref (match_operand 0 "" "")))]
8029 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8031 arm_ccfsm_state += 2;
8034 return \"b%?\\t%l0\";
8037 [(set_attr "predicable" "yes")
8038 (set (attr "length")
8040 (and (match_test "TARGET_THUMB2")
8041 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8042 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8045 (set_attr "type" "branch")]
8048 (define_expand "call"
8049 [(parallel [(call (match_operand 0 "memory_operand" "")
8050 (match_operand 1 "general_operand" ""))
8051 (use (match_operand 2 "" ""))
8052 (clobber (reg:SI LR_REGNUM))])]
8057 tree addr = MEM_EXPR (operands[0]);
8059 /* In an untyped call, we can get NULL for operand 2. */
8060 if (operands[2] == NULL_RTX)
8061 operands[2] = const0_rtx;
8063 /* Decide if we should generate indirect calls by loading the
8064 32-bit address of the callee into a register before performing the
8066 callee = XEXP (operands[0], 0);
8067 if (GET_CODE (callee) == SYMBOL_REF
8068 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8070 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8072 if (detect_cmse_nonsecure_call (addr))
8074 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8076 emit_call_insn (pat);
8080 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8081 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8087 (define_expand "call_internal"
8088 [(parallel [(call (match_operand 0 "memory_operand" "")
8089 (match_operand 1 "general_operand" ""))
8090 (use (match_operand 2 "" ""))
8091 (clobber (reg:SI LR_REGNUM))])])
8093 (define_expand "nonsecure_call_internal"
8094 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8095 UNSPEC_NONSECURE_MEM)
8096 (match_operand 1 "general_operand" ""))
8097 (use (match_operand 2 "" ""))
8098 (clobber (reg:SI LR_REGNUM))
8099 (clobber (reg:SI 4))])]
8104 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8105 gen_rtx_REG (SImode, 4),
8108 operands[0] = replace_equiv_address (operands[0], tmp);
8111 (define_insn "*call_reg_armv5"
8112 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8113 (match_operand 1 "" ""))
8114 (use (match_operand 2 "" ""))
8115 (clobber (reg:SI LR_REGNUM))]
8116 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8118 [(set_attr "type" "call")]
8121 (define_insn "*call_reg_arm"
8122 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8123 (match_operand 1 "" ""))
8124 (use (match_operand 2 "" ""))
8125 (clobber (reg:SI LR_REGNUM))]
8126 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8128 return output_call (operands);
8130 ;; length is worst case, normally it is only two
8131 [(set_attr "length" "12")
8132 (set_attr "type" "call")]
8136 (define_expand "call_value"
8137 [(parallel [(set (match_operand 0 "" "")
8138 (call (match_operand 1 "memory_operand" "")
8139 (match_operand 2 "general_operand" "")))
8140 (use (match_operand 3 "" ""))
8141 (clobber (reg:SI LR_REGNUM))])]
8146 tree addr = MEM_EXPR (operands[1]);
8148 /* In an untyped call, we can get NULL for operand 2. */
8149 if (operands[3] == 0)
8150 operands[3] = const0_rtx;
8152 /* Decide if we should generate indirect calls by loading the
8153 32-bit address of the callee into a register before performing the
8155 callee = XEXP (operands[1], 0);
8156 if (GET_CODE (callee) == SYMBOL_REF
8157 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8159 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8161 if (detect_cmse_nonsecure_call (addr))
8163 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8164 operands[2], operands[3]);
8165 emit_call_insn (pat);
8169 pat = gen_call_value_internal (operands[0], operands[1],
8170 operands[2], operands[3]);
8171 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8177 (define_expand "call_value_internal"
8178 [(parallel [(set (match_operand 0 "" "")
8179 (call (match_operand 1 "memory_operand" "")
8180 (match_operand 2 "general_operand" "")))
8181 (use (match_operand 3 "" ""))
8182 (clobber (reg:SI LR_REGNUM))])])
8184 (define_expand "nonsecure_call_value_internal"
8185 [(parallel [(set (match_operand 0 "" "")
8186 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8187 UNSPEC_NONSECURE_MEM)
8188 (match_operand 2 "general_operand" "")))
8189 (use (match_operand 3 "" ""))
8190 (clobber (reg:SI LR_REGNUM))
8191 (clobber (reg:SI 4))])]
8196 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8197 gen_rtx_REG (SImode, 4),
8200 operands[1] = replace_equiv_address (operands[1], tmp);
8203 (define_insn "*call_value_reg_armv5"
8204 [(set (match_operand 0 "" "")
8205 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8206 (match_operand 2 "" "")))
8207 (use (match_operand 3 "" ""))
8208 (clobber (reg:SI LR_REGNUM))]
8209 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8211 [(set_attr "type" "call")]
8214 (define_insn "*call_value_reg_arm"
8215 [(set (match_operand 0 "" "")
8216 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8217 (match_operand 2 "" "")))
8218 (use (match_operand 3 "" ""))
8219 (clobber (reg:SI LR_REGNUM))]
8220 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8222 return output_call (&operands[1]);
8224 [(set_attr "length" "12")
8225 (set_attr "type" "call")]
8228 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8229 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8231 (define_insn "*call_symbol"
8232 [(call (mem:SI (match_operand:SI 0 "" ""))
8233 (match_operand 1 "" ""))
8234 (use (match_operand 2 "" ""))
8235 (clobber (reg:SI LR_REGNUM))]
8237 && !SIBLING_CALL_P (insn)
8238 && (GET_CODE (operands[0]) == SYMBOL_REF)
8239 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8242 rtx op = operands[0];
8244 /* Switch mode now when possible. */
8245 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8246 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8247 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8249 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8251 [(set_attr "type" "call")]
8254 (define_insn "*call_value_symbol"
8255 [(set (match_operand 0 "" "")
8256 (call (mem:SI (match_operand:SI 1 "" ""))
8257 (match_operand:SI 2 "" "")))
8258 (use (match_operand 3 "" ""))
8259 (clobber (reg:SI LR_REGNUM))]
8261 && !SIBLING_CALL_P (insn)
8262 && (GET_CODE (operands[1]) == SYMBOL_REF)
8263 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8266 rtx op = operands[1];
8268 /* Switch mode now when possible. */
8269 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8270 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8271 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8273 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8275 [(set_attr "type" "call")]
8278 (define_expand "sibcall_internal"
8279 [(parallel [(call (match_operand 0 "memory_operand" "")
8280 (match_operand 1 "general_operand" ""))
8282 (use (match_operand 2 "" ""))])])
8284 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8285 (define_expand "sibcall"
8286 [(parallel [(call (match_operand 0 "memory_operand" "")
8287 (match_operand 1 "general_operand" ""))
8289 (use (match_operand 2 "" ""))])]
8295 if ((!REG_P (XEXP (operands[0], 0))
8296 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8297 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8298 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8299 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8301 if (operands[2] == NULL_RTX)
8302 operands[2] = const0_rtx;
8304 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8305 arm_emit_call_insn (pat, operands[0], true);
8310 (define_expand "sibcall_value_internal"
8311 [(parallel [(set (match_operand 0 "" "")
8312 (call (match_operand 1 "memory_operand" "")
8313 (match_operand 2 "general_operand" "")))
8315 (use (match_operand 3 "" ""))])])
8317 (define_expand "sibcall_value"
8318 [(parallel [(set (match_operand 0 "" "")
8319 (call (match_operand 1 "memory_operand" "")
8320 (match_operand 2 "general_operand" "")))
8322 (use (match_operand 3 "" ""))])]
8328 if ((!REG_P (XEXP (operands[1], 0))
8329 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8330 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8331 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8332 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8334 if (operands[3] == NULL_RTX)
8335 operands[3] = const0_rtx;
8337 pat = gen_sibcall_value_internal (operands[0], operands[1],
8338 operands[2], operands[3]);
8339 arm_emit_call_insn (pat, operands[1], true);
8344 (define_insn "*sibcall_insn"
8345 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8346 (match_operand 1 "" ""))
8348 (use (match_operand 2 "" ""))]
8349 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8351 if (which_alternative == 1)
8352 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8355 if (arm_arch5 || arm_arch4t)
8356 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8358 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8361 [(set_attr "type" "call")]
8364 (define_insn "*sibcall_value_insn"
8365 [(set (match_operand 0 "" "")
8366 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8367 (match_operand 2 "" "")))
8369 (use (match_operand 3 "" ""))]
8370 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8372 if (which_alternative == 1)
8373 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8376 if (arm_arch5 || arm_arch4t)
8377 return \"bx%?\\t%1\";
8379 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8382 [(set_attr "type" "call")]
8385 (define_expand "<return_str>return"
8387 "(TARGET_ARM || (TARGET_THUMB2
8388 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8389 && !IS_STACKALIGN (arm_current_func_type ())))
8390 <return_cond_false>"
8395 thumb2_expand_return (<return_simple_p>);
8402 ;; Often the return insn will be the same as loading from memory, so set attr
8403 (define_insn "*arm_return"
8405 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8408 if (arm_ccfsm_state == 2)
8410 arm_ccfsm_state += 2;
8413 return output_return_instruction (const_true_rtx, true, false, false);
8415 [(set_attr "type" "load1")
8416 (set_attr "length" "12")
8417 (set_attr "predicable" "yes")]
8420 (define_insn "*cond_<return_str>return"
8422 (if_then_else (match_operator 0 "arm_comparison_operator"
8423 [(match_operand 1 "cc_register" "") (const_int 0)])
8426 "TARGET_ARM <return_cond_true>"
8429 if (arm_ccfsm_state == 2)
8431 arm_ccfsm_state += 2;
8434 return output_return_instruction (operands[0], true, false,
8437 [(set_attr "conds" "use")
8438 (set_attr "length" "12")
8439 (set_attr "type" "load1")]
8442 (define_insn "*cond_<return_str>return_inverted"
8444 (if_then_else (match_operator 0 "arm_comparison_operator"
8445 [(match_operand 1 "cc_register" "") (const_int 0)])
8448 "TARGET_ARM <return_cond_true>"
8451 if (arm_ccfsm_state == 2)
8453 arm_ccfsm_state += 2;
8456 return output_return_instruction (operands[0], true, true,
8459 [(set_attr "conds" "use")
8460 (set_attr "length" "12")
8461 (set_attr "type" "load1")]
8464 (define_insn "*arm_simple_return"
8469 if (arm_ccfsm_state == 2)
8471 arm_ccfsm_state += 2;
8474 return output_return_instruction (const_true_rtx, true, false, true);
8476 [(set_attr "type" "branch")
8477 (set_attr "length" "4")
8478 (set_attr "predicable" "yes")]
8481 ;; Generate a sequence of instructions to determine if the processor is
8482 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8485 (define_expand "return_addr_mask"
8487 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8489 (set (match_operand:SI 0 "s_register_operand" "")
8490 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8492 (const_int 67108860)))] ; 0x03fffffc
8495 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8498 (define_insn "*check_arch2"
8499 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8500 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8503 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8504 [(set_attr "length" "8")
8505 (set_attr "conds" "set")
8506 (set_attr "type" "multiple")]
8509 ;; Call subroutine returning any type.
8511 (define_expand "untyped_call"
8512 [(parallel [(call (match_operand 0 "" "")
8514 (match_operand 1 "" "")
8515 (match_operand 2 "" "")])]
8520 rtx par = gen_rtx_PARALLEL (VOIDmode,
8521 rtvec_alloc (XVECLEN (operands[2], 0)));
8522 rtx addr = gen_reg_rtx (Pmode);
8526 emit_move_insn (addr, XEXP (operands[1], 0));
8527 mem = change_address (operands[1], BLKmode, addr);
8529 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8531 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8533 /* Default code only uses r0 as a return value, but we could
8534 be using anything up to 4 registers. */
8535 if (REGNO (src) == R0_REGNUM)
8536 src = gen_rtx_REG (TImode, R0_REGNUM);
8538 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8540 size += GET_MODE_SIZE (GET_MODE (src));
8543 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8547 for (i = 0; i < XVECLEN (par, 0); i++)
8549 HOST_WIDE_INT offset = 0;
8550 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8553 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8555 mem = change_address (mem, GET_MODE (reg), NULL);
8556 if (REGNO (reg) == R0_REGNUM)
8558 /* On thumb we have to use a write-back instruction. */
8559 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8560 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8561 size = TARGET_ARM ? 16 : 0;
8565 emit_move_insn (mem, reg);
8566 size = GET_MODE_SIZE (GET_MODE (reg));
8570 /* The optimizer does not know that the call sets the function value
8571 registers we stored in the result block. We avoid problems by
8572 claiming that all hard registers are used and clobbered at this
8574 emit_insn (gen_blockage ());
8580 (define_expand "untyped_return"
8581 [(match_operand:BLK 0 "memory_operand" "")
8582 (match_operand 1 "" "")]
8587 rtx addr = gen_reg_rtx (Pmode);
8591 emit_move_insn (addr, XEXP (operands[0], 0));
8592 mem = change_address (operands[0], BLKmode, addr);
8594 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8596 HOST_WIDE_INT offset = 0;
8597 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8600 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8602 mem = change_address (mem, GET_MODE (reg), NULL);
8603 if (REGNO (reg) == R0_REGNUM)
8605 /* On thumb we have to use a write-back instruction. */
8606 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8607 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8608 size = TARGET_ARM ? 16 : 0;
8612 emit_move_insn (reg, mem);
8613 size = GET_MODE_SIZE (GET_MODE (reg));
8617 /* Emit USE insns before the return. */
8618 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8619 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8621 /* Construct the return. */
8622 expand_naked_return ();
8628 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8629 ;; all of memory. This blocks insns from being moved across this point.
8631 (define_insn "blockage"
8632 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8635 [(set_attr "length" "0")
8636 (set_attr "type" "block")]
8639 (define_insn "probe_stack"
8640 [(set (match_operand:SI 0 "memory_operand" "=m")
8641 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8644 [(set_attr "type" "store1")
8645 (set_attr "predicable" "yes")]
8648 (define_insn "probe_stack_range"
8649 [(set (match_operand:SI 0 "register_operand" "=r")
8650 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8651 (match_operand:SI 2 "register_operand" "r")]
8652 VUNSPEC_PROBE_STACK_RANGE))]
8655 return output_probe_stack_range (operands[0], operands[2]);
8657 [(set_attr "type" "multiple")
8658 (set_attr "conds" "clob")]
8661 (define_expand "casesi"
8662 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8663 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8664 (match_operand:SI 2 "const_int_operand" "") ; total range
8665 (match_operand:SI 3 "" "") ; table label
8666 (match_operand:SI 4 "" "")] ; Out of range label
8667 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8670 enum insn_code code;
8671 if (operands[1] != const0_rtx)
8673 rtx reg = gen_reg_rtx (SImode);
8675 emit_insn (gen_addsi3 (reg, operands[0],
8676 gen_int_mode (-INTVAL (operands[1]),
8682 code = CODE_FOR_arm_casesi_internal;
8683 else if (TARGET_THUMB1)
8684 code = CODE_FOR_thumb1_casesi_internal_pic;
8686 code = CODE_FOR_thumb2_casesi_internal_pic;
8688 code = CODE_FOR_thumb2_casesi_internal;
8690 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8691 operands[2] = force_reg (SImode, operands[2]);
8693 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8694 operands[3], operands[4]));
8699 ;; The USE in this pattern is needed to tell flow analysis that this is
8700 ;; a CASESI insn. It has no other purpose.
8701 (define_insn "arm_casesi_internal"
8702 [(parallel [(set (pc)
8704 (leu (match_operand:SI 0 "s_register_operand" "r")
8705 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8706 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8707 (label_ref (match_operand 2 "" ""))))
8708 (label_ref (match_operand 3 "" ""))))
8709 (clobber (reg:CC CC_REGNUM))
8710 (use (label_ref (match_dup 2)))])]
8714 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8715 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8717 [(set_attr "conds" "clob")
8718 (set_attr "length" "12")
8719 (set_attr "type" "multiple")]
8722 (define_expand "indirect_jump"
8724 (match_operand:SI 0 "s_register_operand" ""))]
8727 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8728 address and use bx. */
8732 tmp = gen_reg_rtx (SImode);
8733 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8739 ;; NB Never uses BX.
8740 (define_insn "*arm_indirect_jump"
8742 (match_operand:SI 0 "s_register_operand" "r"))]
8744 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8745 [(set_attr "predicable" "yes")
8746 (set_attr "type" "branch")]
8749 (define_insn "*load_indirect_jump"
8751 (match_operand:SI 0 "memory_operand" "m"))]
8753 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8754 [(set_attr "type" "load1")
8755 (set_attr "pool_range" "4096")
8756 (set_attr "neg_pool_range" "4084")
8757 (set_attr "predicable" "yes")]
8767 [(set (attr "length")
8768 (if_then_else (eq_attr "is_thumb" "yes")
8771 (set_attr "type" "mov_reg")]
8775 [(trap_if (const_int 1) (const_int 0))]
8779 return \".inst\\t0xe7f000f0\";
8781 return \".inst\\t0xdeff\";
8783 [(set (attr "length")
8784 (if_then_else (eq_attr "is_thumb" "yes")
8787 (set_attr "type" "trap")
8788 (set_attr "conds" "unconditional")]
8792 ;; Patterns to allow combination of arithmetic, cond code and shifts
8794 (define_insn "*<arith_shift_insn>_multsi"
8795 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8797 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8798 (match_operand:SI 3 "power_of_two_operand" ""))
8799 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8801 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8802 [(set_attr "predicable" "yes")
8803 (set_attr "predicable_short_it" "no")
8804 (set_attr "shift" "2")
8805 (set_attr "arch" "a,t2")
8806 (set_attr "type" "alu_shift_imm")])
8808 (define_insn "*<arith_shift_insn>_shiftsi"
8809 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8811 (match_operator:SI 2 "shift_nomul_operator"
8812 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8813 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8814 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8815 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8816 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8817 [(set_attr "predicable" "yes")
8818 (set_attr "predicable_short_it" "no")
8819 (set_attr "shift" "3")
8820 (set_attr "arch" "a,t2,a")
8821 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8824 [(set (match_operand:SI 0 "s_register_operand" "")
8825 (match_operator:SI 1 "shiftable_operator"
8826 [(match_operator:SI 2 "shiftable_operator"
8827 [(match_operator:SI 3 "shift_operator"
8828 [(match_operand:SI 4 "s_register_operand" "")
8829 (match_operand:SI 5 "reg_or_int_operand" "")])
8830 (match_operand:SI 6 "s_register_operand" "")])
8831 (match_operand:SI 7 "arm_rhs_operand" "")]))
8832 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8835 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8838 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8841 (define_insn "*arith_shiftsi_compare0"
8842 [(set (reg:CC_NOOV CC_REGNUM)
8844 (match_operator:SI 1 "shiftable_operator"
8845 [(match_operator:SI 3 "shift_operator"
8846 [(match_operand:SI 4 "s_register_operand" "r,r")
8847 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8848 (match_operand:SI 2 "s_register_operand" "r,r")])
8850 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8851 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8854 "%i1s%?\\t%0, %2, %4%S3"
8855 [(set_attr "conds" "set")
8856 (set_attr "shift" "4")
8857 (set_attr "arch" "32,a")
8858 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8860 (define_insn "*arith_shiftsi_compare0_scratch"
8861 [(set (reg:CC_NOOV CC_REGNUM)
8863 (match_operator:SI 1 "shiftable_operator"
8864 [(match_operator:SI 3 "shift_operator"
8865 [(match_operand:SI 4 "s_register_operand" "r,r")
8866 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8867 (match_operand:SI 2 "s_register_operand" "r,r")])
8869 (clobber (match_scratch:SI 0 "=r,r"))]
8871 "%i1s%?\\t%0, %2, %4%S3"
8872 [(set_attr "conds" "set")
8873 (set_attr "shift" "4")
8874 (set_attr "arch" "32,a")
8875 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8877 (define_insn "*sub_shiftsi"
8878 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8879 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8880 (match_operator:SI 2 "shift_operator"
8881 [(match_operand:SI 3 "s_register_operand" "r,r")
8882 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8884 "sub%?\\t%0, %1, %3%S2"
8885 [(set_attr "predicable" "yes")
8886 (set_attr "shift" "3")
8887 (set_attr "arch" "32,a")
8888 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8890 (define_insn "*sub_shiftsi_compare0"
8891 [(set (reg:CC_NOOV CC_REGNUM)
8893 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8894 (match_operator:SI 2 "shift_operator"
8895 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8896 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8898 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8899 (minus:SI (match_dup 1)
8900 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8902 "subs%?\\t%0, %1, %3%S2"
8903 [(set_attr "conds" "set")
8904 (set_attr "shift" "3")
8905 (set_attr "arch" "32,a,a")
8906 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8908 (define_insn "*sub_shiftsi_compare0_scratch"
8909 [(set (reg:CC_NOOV CC_REGNUM)
8911 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8912 (match_operator:SI 2 "shift_operator"
8913 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8914 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8916 (clobber (match_scratch:SI 0 "=r,r,r"))]
8918 "subs%?\\t%0, %1, %3%S2"
8919 [(set_attr "conds" "set")
8920 (set_attr "shift" "3")
8921 (set_attr "arch" "32,a,a")
8922 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8925 (define_insn_and_split "*and_scc"
8926 [(set (match_operand:SI 0 "s_register_operand" "=r")
8927 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8928 [(match_operand 2 "cc_register" "") (const_int 0)])
8929 (match_operand:SI 3 "s_register_operand" "r")))]
8931 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8932 "&& reload_completed"
8933 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8934 (cond_exec (match_dup 4) (set (match_dup 0)
8935 (and:SI (match_dup 3) (const_int 1))))]
8937 machine_mode mode = GET_MODE (operands[2]);
8938 enum rtx_code rc = GET_CODE (operands[1]);
8940 /* Note that operands[4] is the same as operands[1],
8941 but with VOIDmode as the result. */
8942 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8943 if (mode == CCFPmode || mode == CCFPEmode)
8944 rc = reverse_condition_maybe_unordered (rc);
8946 rc = reverse_condition (rc);
8947 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8949 [(set_attr "conds" "use")
8950 (set_attr "type" "multiple")
8951 (set_attr "length" "8")]
8954 (define_insn_and_split "*ior_scc"
8955 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8956 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8957 [(match_operand 2 "cc_register" "") (const_int 0)])
8958 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8963 "&& reload_completed
8964 && REGNO (operands [0]) != REGNO (operands[3])"
8965 ;; && which_alternative == 1
8966 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8967 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8968 (cond_exec (match_dup 4) (set (match_dup 0)
8969 (ior:SI (match_dup 3) (const_int 1))))]
8971 machine_mode mode = GET_MODE (operands[2]);
8972 enum rtx_code rc = GET_CODE (operands[1]);
8974 /* Note that operands[4] is the same as operands[1],
8975 but with VOIDmode as the result. */
8976 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8977 if (mode == CCFPmode || mode == CCFPEmode)
8978 rc = reverse_condition_maybe_unordered (rc);
8980 rc = reverse_condition (rc);
8981 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8983 [(set_attr "conds" "use")
8984 (set_attr "length" "4,8")
8985 (set_attr "type" "logic_imm,multiple")]
8988 ; A series of splitters for the compare_scc pattern below. Note that
8989 ; order is important.
8991 [(set (match_operand:SI 0 "s_register_operand" "")
8992 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8994 (clobber (reg:CC CC_REGNUM))]
8995 "TARGET_32BIT && reload_completed"
8996 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8999 [(set (match_operand:SI 0 "s_register_operand" "")
9000 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9002 (clobber (reg:CC CC_REGNUM))]
9003 "TARGET_32BIT && reload_completed"
9004 [(set (match_dup 0) (not:SI (match_dup 1)))
9005 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9008 [(set (match_operand:SI 0 "s_register_operand" "")
9009 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9011 (clobber (reg:CC CC_REGNUM))]
9012 "arm_arch5 && TARGET_32BIT"
9013 [(set (match_dup 0) (clz:SI (match_dup 1)))
9014 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9018 [(set (match_operand:SI 0 "s_register_operand" "")
9019 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9021 (clobber (reg:CC CC_REGNUM))]
9022 "TARGET_32BIT && reload_completed"
9024 [(set (reg:CC CC_REGNUM)
9025 (compare:CC (const_int 1) (match_dup 1)))
9027 (minus:SI (const_int 1) (match_dup 1)))])
9028 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9029 (set (match_dup 0) (const_int 0)))])
9032 [(set (match_operand:SI 0 "s_register_operand" "")
9033 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9034 (match_operand:SI 2 "const_int_operand" "")))
9035 (clobber (reg:CC CC_REGNUM))]
9036 "TARGET_32BIT && reload_completed"
9038 [(set (reg:CC CC_REGNUM)
9039 (compare:CC (match_dup 1) (match_dup 2)))
9040 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9041 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9042 (set (match_dup 0) (const_int 1)))]
9044 operands[3] = GEN_INT (-INTVAL (operands[2]));
9048 [(set (match_operand:SI 0 "s_register_operand" "")
9049 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9050 (match_operand:SI 2 "arm_add_operand" "")))
9051 (clobber (reg:CC CC_REGNUM))]
9052 "TARGET_32BIT && reload_completed"
9054 [(set (reg:CC_NOOV CC_REGNUM)
9055 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9057 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9058 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9059 (set (match_dup 0) (const_int 1)))])
9061 (define_insn_and_split "*compare_scc"
9062 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9063 (match_operator:SI 1 "arm_comparison_operator"
9064 [(match_operand:SI 2 "s_register_operand" "r,r")
9065 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9066 (clobber (reg:CC CC_REGNUM))]
9069 "&& reload_completed"
9070 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9071 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9072 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9075 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9076 operands[2], operands[3]);
9077 enum rtx_code rc = GET_CODE (operands[1]);
9079 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9081 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9082 if (mode == CCFPmode || mode == CCFPEmode)
9083 rc = reverse_condition_maybe_unordered (rc);
9085 rc = reverse_condition (rc);
9086 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9088 [(set_attr "type" "multiple")]
9091 ;; Attempt to improve the sequence generated by the compare_scc splitters
9092 ;; not to use conditional execution.
9094 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9098 [(set (reg:CC CC_REGNUM)
9099 (compare:CC (match_operand:SI 1 "register_operand" "")
9101 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9102 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9103 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9104 (set (match_dup 0) (const_int 1)))]
9105 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9106 [(set (match_dup 0) (clz:SI (match_dup 1)))
9107 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9110 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9114 [(set (reg:CC CC_REGNUM)
9115 (compare:CC (match_operand:SI 1 "register_operand" "")
9117 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9118 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9119 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9120 (set (match_dup 0) (const_int 1)))
9121 (match_scratch:SI 2 "r")]
9122 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9124 [(set (reg:CC CC_REGNUM)
9125 (compare:CC (const_int 0) (match_dup 1)))
9126 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9128 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9129 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9132 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9133 ;; sub Rd, Reg1, reg2
9137 [(set (reg:CC CC_REGNUM)
9138 (compare:CC (match_operand:SI 1 "register_operand" "")
9139 (match_operand:SI 2 "arm_rhs_operand" "")))
9140 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9141 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9142 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9143 (set (match_dup 0) (const_int 1)))]
9144 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9145 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9146 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9147 (set (match_dup 0) (clz:SI (match_dup 0)))
9148 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9152 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9153 ;; sub T1, Reg1, reg2
9157 [(set (reg:CC CC_REGNUM)
9158 (compare:CC (match_operand:SI 1 "register_operand" "")
9159 (match_operand:SI 2 "arm_rhs_operand" "")))
9160 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9161 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9162 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9163 (set (match_dup 0) (const_int 1)))
9164 (match_scratch:SI 3 "r")]
9165 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9166 [(set (match_dup 3) (match_dup 4))
9168 [(set (reg:CC CC_REGNUM)
9169 (compare:CC (const_int 0) (match_dup 3)))
9170 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9172 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9173 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9175 if (CONST_INT_P (operands[2]))
9176 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9178 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9181 (define_insn "*cond_move"
9182 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9183 (if_then_else:SI (match_operator 3 "equality_operator"
9184 [(match_operator 4 "arm_comparison_operator"
9185 [(match_operand 5 "cc_register" "") (const_int 0)])
9187 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9188 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9191 if (GET_CODE (operands[3]) == NE)
9193 if (which_alternative != 1)
9194 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9195 if (which_alternative != 0)
9196 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9199 if (which_alternative != 0)
9200 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9201 if (which_alternative != 1)
9202 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9205 [(set_attr "conds" "use")
9206 (set_attr_alternative "type"
9207 [(if_then_else (match_operand 2 "const_int_operand" "")
9208 (const_string "mov_imm")
9209 (const_string "mov_reg"))
9210 (if_then_else (match_operand 1 "const_int_operand" "")
9211 (const_string "mov_imm")
9212 (const_string "mov_reg"))
9213 (const_string "multiple")])
9214 (set_attr "length" "4,4,8")]
9217 (define_insn "*cond_arith"
9218 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9219 (match_operator:SI 5 "shiftable_operator"
9220 [(match_operator:SI 4 "arm_comparison_operator"
9221 [(match_operand:SI 2 "s_register_operand" "r,r")
9222 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9223 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9224 (clobber (reg:CC CC_REGNUM))]
9227 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9228 return \"%i5\\t%0, %1, %2, lsr #31\";
9230 output_asm_insn (\"cmp\\t%2, %3\", operands);
9231 if (GET_CODE (operands[5]) == AND)
9232 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9233 else if (GET_CODE (operands[5]) == MINUS)
9234 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9235 else if (which_alternative != 0)
9236 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9237 return \"%i5%d4\\t%0, %1, #1\";
9239 [(set_attr "conds" "clob")
9240 (set_attr "length" "12")
9241 (set_attr "type" "multiple")]
9244 (define_insn "*cond_sub"
9245 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9246 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9247 (match_operator:SI 4 "arm_comparison_operator"
9248 [(match_operand:SI 2 "s_register_operand" "r,r")
9249 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9250 (clobber (reg:CC CC_REGNUM))]
9253 output_asm_insn (\"cmp\\t%2, %3\", operands);
9254 if (which_alternative != 0)
9255 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9256 return \"sub%d4\\t%0, %1, #1\";
9258 [(set_attr "conds" "clob")
9259 (set_attr "length" "8,12")
9260 (set_attr "type" "multiple")]
9263 (define_insn "*cmp_ite0"
9264 [(set (match_operand 6 "dominant_cc_register" "")
9267 (match_operator 4 "arm_comparison_operator"
9268 [(match_operand:SI 0 "s_register_operand"
9269 "l,l,l,r,r,r,r,r,r")
9270 (match_operand:SI 1 "arm_add_operand"
9271 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9272 (match_operator:SI 5 "arm_comparison_operator"
9273 [(match_operand:SI 2 "s_register_operand"
9274 "l,r,r,l,l,r,r,r,r")
9275 (match_operand:SI 3 "arm_add_operand"
9276 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9282 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9284 {\"cmp%d5\\t%0, %1\",
9285 \"cmp%d4\\t%2, %3\"},
9286 {\"cmn%d5\\t%0, #%n1\",
9287 \"cmp%d4\\t%2, %3\"},
9288 {\"cmp%d5\\t%0, %1\",
9289 \"cmn%d4\\t%2, #%n3\"},
9290 {\"cmn%d5\\t%0, #%n1\",
9291 \"cmn%d4\\t%2, #%n3\"}
9293 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9298 \"cmn\\t%0, #%n1\"},
9299 {\"cmn\\t%2, #%n3\",
9301 {\"cmn\\t%2, #%n3\",
9304 static const char * const ite[2] =
9309 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9310 CMP_CMP, CMN_CMP, CMP_CMP,
9311 CMN_CMP, CMP_CMN, CMN_CMN};
9313 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9315 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9316 if (TARGET_THUMB2) {
9317 output_asm_insn (ite[swap], operands);
9319 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9322 [(set_attr "conds" "set")
9323 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9324 (set_attr "type" "multiple")
9325 (set_attr_alternative "length"
9331 (if_then_else (eq_attr "is_thumb" "no")
9334 (if_then_else (eq_attr "is_thumb" "no")
9337 (if_then_else (eq_attr "is_thumb" "no")
9340 (if_then_else (eq_attr "is_thumb" "no")
9345 (define_insn "*cmp_ite1"
9346 [(set (match_operand 6 "dominant_cc_register" "")
9349 (match_operator 4 "arm_comparison_operator"
9350 [(match_operand:SI 0 "s_register_operand"
9351 "l,l,l,r,r,r,r,r,r")
9352 (match_operand:SI 1 "arm_add_operand"
9353 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9354 (match_operator:SI 5 "arm_comparison_operator"
9355 [(match_operand:SI 2 "s_register_operand"
9356 "l,r,r,l,l,r,r,r,r")
9357 (match_operand:SI 3 "arm_add_operand"
9358 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9364 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9368 {\"cmn\\t%0, #%n1\",
9371 \"cmn\\t%2, #%n3\"},
9372 {\"cmn\\t%0, #%n1\",
9375 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9377 {\"cmp%d4\\t%2, %3\",
9378 \"cmp%D5\\t%0, %1\"},
9379 {\"cmp%d4\\t%2, %3\",
9380 \"cmn%D5\\t%0, #%n1\"},
9381 {\"cmn%d4\\t%2, #%n3\",
9382 \"cmp%D5\\t%0, %1\"},
9383 {\"cmn%d4\\t%2, #%n3\",
9384 \"cmn%D5\\t%0, #%n1\"}
9386 static const char * const ite[2] =
9391 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9392 CMP_CMP, CMN_CMP, CMP_CMP,
9393 CMN_CMP, CMP_CMN, CMN_CMN};
9395 comparison_dominates_p (GET_CODE (operands[5]),
9396 reverse_condition (GET_CODE (operands[4])));
9398 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9399 if (TARGET_THUMB2) {
9400 output_asm_insn (ite[swap], operands);
9402 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9405 [(set_attr "conds" "set")
9406 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9407 (set_attr_alternative "length"
9413 (if_then_else (eq_attr "is_thumb" "no")
9416 (if_then_else (eq_attr "is_thumb" "no")
9419 (if_then_else (eq_attr "is_thumb" "no")
9422 (if_then_else (eq_attr "is_thumb" "no")
9425 (set_attr "type" "multiple")]
9428 (define_insn "*cmp_and"
9429 [(set (match_operand 6 "dominant_cc_register" "")
9432 (match_operator 4 "arm_comparison_operator"
9433 [(match_operand:SI 0 "s_register_operand"
9434 "l,l,l,r,r,r,r,r,r")
9435 (match_operand:SI 1 "arm_add_operand"
9436 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9437 (match_operator:SI 5 "arm_comparison_operator"
9438 [(match_operand:SI 2 "s_register_operand"
9439 "l,r,r,l,l,r,r,r,r")
9440 (match_operand:SI 3 "arm_add_operand"
9441 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9446 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9448 {\"cmp%d5\\t%0, %1\",
9449 \"cmp%d4\\t%2, %3\"},
9450 {\"cmn%d5\\t%0, #%n1\",
9451 \"cmp%d4\\t%2, %3\"},
9452 {\"cmp%d5\\t%0, %1\",
9453 \"cmn%d4\\t%2, #%n3\"},
9454 {\"cmn%d5\\t%0, #%n1\",
9455 \"cmn%d4\\t%2, #%n3\"}
9457 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9462 \"cmn\\t%0, #%n1\"},
9463 {\"cmn\\t%2, #%n3\",
9465 {\"cmn\\t%2, #%n3\",
9468 static const char *const ite[2] =
9473 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9474 CMP_CMP, CMN_CMP, CMP_CMP,
9475 CMN_CMP, CMP_CMN, CMN_CMN};
9477 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9479 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9480 if (TARGET_THUMB2) {
9481 output_asm_insn (ite[swap], operands);
9483 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9486 [(set_attr "conds" "set")
9487 (set_attr "predicable" "no")
9488 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9489 (set_attr_alternative "length"
9495 (if_then_else (eq_attr "is_thumb" "no")
9498 (if_then_else (eq_attr "is_thumb" "no")
9501 (if_then_else (eq_attr "is_thumb" "no")
9504 (if_then_else (eq_attr "is_thumb" "no")
9507 (set_attr "type" "multiple")]
9510 (define_insn "*cmp_ior"
9511 [(set (match_operand 6 "dominant_cc_register" "")
9514 (match_operator 4 "arm_comparison_operator"
9515 [(match_operand:SI 0 "s_register_operand"
9516 "l,l,l,r,r,r,r,r,r")
9517 (match_operand:SI 1 "arm_add_operand"
9518 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9519 (match_operator:SI 5 "arm_comparison_operator"
9520 [(match_operand:SI 2 "s_register_operand"
9521 "l,r,r,l,l,r,r,r,r")
9522 (match_operand:SI 3 "arm_add_operand"
9523 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9528 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9532 {\"cmn\\t%0, #%n1\",
9535 \"cmn\\t%2, #%n3\"},
9536 {\"cmn\\t%0, #%n1\",
9539 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9541 {\"cmp%D4\\t%2, %3\",
9542 \"cmp%D5\\t%0, %1\"},
9543 {\"cmp%D4\\t%2, %3\",
9544 \"cmn%D5\\t%0, #%n1\"},
9545 {\"cmn%D4\\t%2, #%n3\",
9546 \"cmp%D5\\t%0, %1\"},
9547 {\"cmn%D4\\t%2, #%n3\",
9548 \"cmn%D5\\t%0, #%n1\"}
9550 static const char *const ite[2] =
9555 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9556 CMP_CMP, CMN_CMP, CMP_CMP,
9557 CMN_CMP, CMP_CMN, CMN_CMN};
9559 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9561 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9562 if (TARGET_THUMB2) {
9563 output_asm_insn (ite[swap], operands);
9565 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9569 [(set_attr "conds" "set")
9570 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9571 (set_attr_alternative "length"
9577 (if_then_else (eq_attr "is_thumb" "no")
9580 (if_then_else (eq_attr "is_thumb" "no")
9583 (if_then_else (eq_attr "is_thumb" "no")
9586 (if_then_else (eq_attr "is_thumb" "no")
9589 (set_attr "type" "multiple")]
9592 (define_insn_and_split "*ior_scc_scc"
9593 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9594 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9595 [(match_operand:SI 1 "s_register_operand" "r")
9596 (match_operand:SI 2 "arm_add_operand" "rIL")])
9597 (match_operator:SI 6 "arm_comparison_operator"
9598 [(match_operand:SI 4 "s_register_operand" "r")
9599 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9600 (clobber (reg:CC CC_REGNUM))]
9602 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9605 "TARGET_32BIT && reload_completed"
9609 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9610 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9612 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9614 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9617 [(set_attr "conds" "clob")
9618 (set_attr "length" "16")
9619 (set_attr "type" "multiple")]
9622 ; If the above pattern is followed by a CMP insn, then the compare is
9623 ; redundant, since we can rework the conditional instruction that follows.
9624 (define_insn_and_split "*ior_scc_scc_cmp"
9625 [(set (match_operand 0 "dominant_cc_register" "")
9626 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9627 [(match_operand:SI 1 "s_register_operand" "r")
9628 (match_operand:SI 2 "arm_add_operand" "rIL")])
9629 (match_operator:SI 6 "arm_comparison_operator"
9630 [(match_operand:SI 4 "s_register_operand" "r")
9631 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9633 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9634 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9635 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9638 "TARGET_32BIT && reload_completed"
9642 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9643 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9645 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9647 [(set_attr "conds" "set")
9648 (set_attr "length" "16")
9649 (set_attr "type" "multiple")]
9652 (define_insn_and_split "*and_scc_scc"
9653 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9654 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9655 [(match_operand:SI 1 "s_register_operand" "r")
9656 (match_operand:SI 2 "arm_add_operand" "rIL")])
9657 (match_operator:SI 6 "arm_comparison_operator"
9658 [(match_operand:SI 4 "s_register_operand" "r")
9659 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9660 (clobber (reg:CC CC_REGNUM))]
9662 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9665 "TARGET_32BIT && reload_completed
9666 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9671 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9672 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9674 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9676 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9679 [(set_attr "conds" "clob")
9680 (set_attr "length" "16")
9681 (set_attr "type" "multiple")]
9684 ; If the above pattern is followed by a CMP insn, then the compare is
9685 ; redundant, since we can rework the conditional instruction that follows.
9686 (define_insn_and_split "*and_scc_scc_cmp"
9687 [(set (match_operand 0 "dominant_cc_register" "")
9688 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9689 [(match_operand:SI 1 "s_register_operand" "r")
9690 (match_operand:SI 2 "arm_add_operand" "rIL")])
9691 (match_operator:SI 6 "arm_comparison_operator"
9692 [(match_operand:SI 4 "s_register_operand" "r")
9693 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9695 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9696 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9697 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9700 "TARGET_32BIT && reload_completed"
9704 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9705 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9707 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9709 [(set_attr "conds" "set")
9710 (set_attr "length" "16")
9711 (set_attr "type" "multiple")]
9714 ;; If there is no dominance in the comparison, then we can still save an
9715 ;; instruction in the AND case, since we can know that the second compare
9716 ;; need only zero the value if false (if true, then the value is already
9718 (define_insn_and_split "*and_scc_scc_nodom"
9719 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9720 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9721 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9722 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9723 (match_operator:SI 6 "arm_comparison_operator"
9724 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9725 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9726 (clobber (reg:CC CC_REGNUM))]
9728 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9731 "TARGET_32BIT && reload_completed"
9732 [(parallel [(set (match_dup 0)
9733 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9734 (clobber (reg:CC CC_REGNUM))])
9735 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9737 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9740 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9741 operands[4], operands[5]),
9743 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9745 [(set_attr "conds" "clob")
9746 (set_attr "length" "20")
9747 (set_attr "type" "multiple")]
9751 [(set (reg:CC_NOOV CC_REGNUM)
9752 (compare:CC_NOOV (ior:SI
9753 (and:SI (match_operand:SI 0 "s_register_operand" "")
9755 (match_operator:SI 1 "arm_comparison_operator"
9756 [(match_operand:SI 2 "s_register_operand" "")
9757 (match_operand:SI 3 "arm_add_operand" "")]))
9759 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9762 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9764 (set (reg:CC_NOOV CC_REGNUM)
9765 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9770 [(set (reg:CC_NOOV CC_REGNUM)
9771 (compare:CC_NOOV (ior:SI
9772 (match_operator:SI 1 "arm_comparison_operator"
9773 [(match_operand:SI 2 "s_register_operand" "")
9774 (match_operand:SI 3 "arm_add_operand" "")])
9775 (and:SI (match_operand:SI 0 "s_register_operand" "")
9778 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9781 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9783 (set (reg:CC_NOOV CC_REGNUM)
9784 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9787 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9789 (define_insn_and_split "*negscc"
9790 [(set (match_operand:SI 0 "s_register_operand" "=r")
9791 (neg:SI (match_operator 3 "arm_comparison_operator"
9792 [(match_operand:SI 1 "s_register_operand" "r")
9793 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9794 (clobber (reg:CC CC_REGNUM))]
9797 "&& reload_completed"
9800 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9802 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9804 /* Emit mov\\t%0, %1, asr #31 */
9805 emit_insn (gen_rtx_SET (operands[0],
9806 gen_rtx_ASHIFTRT (SImode,
9811 else if (GET_CODE (operands[3]) == NE)
9813 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9814 if (CONST_INT_P (operands[2]))
9815 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9816 GEN_INT (- INTVAL (operands[2]))));
9818 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9820 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9824 gen_rtx_SET (operands[0],
9830 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9831 emit_insn (gen_rtx_SET (cc_reg,
9832 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9833 enum rtx_code rc = GET_CODE (operands[3]);
9835 rc = reverse_condition (rc);
9836 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9841 gen_rtx_SET (operands[0], const0_rtx)));
9842 rc = GET_CODE (operands[3]);
9843 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9848 gen_rtx_SET (operands[0],
9854 [(set_attr "conds" "clob")
9855 (set_attr "length" "12")
9856 (set_attr "type" "multiple")]
9859 (define_insn_and_split "movcond_addsi"
9860 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9862 (match_operator 5 "comparison_operator"
9863 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9864 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9866 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9867 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9868 (clobber (reg:CC CC_REGNUM))]
9871 "&& reload_completed"
9872 [(set (reg:CC_NOOV CC_REGNUM)
9874 (plus:SI (match_dup 3)
9877 (set (match_dup 0) (match_dup 1))
9878 (cond_exec (match_dup 6)
9879 (set (match_dup 0) (match_dup 2)))]
9882 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9883 operands[3], operands[4]);
9884 enum rtx_code rc = GET_CODE (operands[5]);
9885 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9886 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9887 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9888 rc = reverse_condition (rc);
9890 std::swap (operands[1], operands[2]);
9892 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9895 [(set_attr "conds" "clob")
9896 (set_attr "enabled_for_depr_it" "no,yes,yes")
9897 (set_attr "type" "multiple")]
9900 (define_insn "movcond"
9901 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9903 (match_operator 5 "arm_comparison_operator"
9904 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9905 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9906 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9907 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9908 (clobber (reg:CC CC_REGNUM))]
9911 if (GET_CODE (operands[5]) == LT
9912 && (operands[4] == const0_rtx))
9914 if (which_alternative != 1 && REG_P (operands[1]))
9916 if (operands[2] == const0_rtx)
9917 return \"and\\t%0, %1, %3, asr #31\";
9918 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9920 else if (which_alternative != 0 && REG_P (operands[2]))
9922 if (operands[1] == const0_rtx)
9923 return \"bic\\t%0, %2, %3, asr #31\";
9924 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9926 /* The only case that falls through to here is when both ops 1 & 2
9930 if (GET_CODE (operands[5]) == GE
9931 && (operands[4] == const0_rtx))
9933 if (which_alternative != 1 && REG_P (operands[1]))
9935 if (operands[2] == const0_rtx)
9936 return \"bic\\t%0, %1, %3, asr #31\";
9937 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9939 else if (which_alternative != 0 && REG_P (operands[2]))
9941 if (operands[1] == const0_rtx)
9942 return \"and\\t%0, %2, %3, asr #31\";
9943 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9945 /* The only case that falls through to here is when both ops 1 & 2
9948 if (CONST_INT_P (operands[4])
9949 && !const_ok_for_arm (INTVAL (operands[4])))
9950 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9952 output_asm_insn (\"cmp\\t%3, %4\", operands);
9953 if (which_alternative != 0)
9954 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9955 if (which_alternative != 1)
9956 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9959 [(set_attr "conds" "clob")
9960 (set_attr "length" "8,8,12")
9961 (set_attr "type" "multiple")]
9964 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9966 (define_insn "*ifcompare_plus_move"
9967 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9968 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9969 [(match_operand:SI 4 "s_register_operand" "r,r")
9970 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9972 (match_operand:SI 2 "s_register_operand" "r,r")
9973 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9974 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9975 (clobber (reg:CC CC_REGNUM))]
9978 [(set_attr "conds" "clob")
9979 (set_attr "length" "8,12")
9980 (set_attr "type" "multiple")]
9983 (define_insn "*if_plus_move"
9984 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9986 (match_operator 4 "arm_comparison_operator"
9987 [(match_operand 5 "cc_register" "") (const_int 0)])
9989 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9990 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9991 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9995 sub%d4\\t%0, %2, #%n3
9996 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9997 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9998 [(set_attr "conds" "use")
9999 (set_attr "length" "4,4,8,8")
10000 (set_attr_alternative "type"
10001 [(if_then_else (match_operand 3 "const_int_operand" "")
10002 (const_string "alu_imm" )
10003 (const_string "alu_sreg"))
10004 (const_string "alu_imm")
10005 (const_string "multiple")
10006 (const_string "multiple")])]
10009 (define_insn "*ifcompare_move_plus"
10010 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10011 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10012 [(match_operand:SI 4 "s_register_operand" "r,r")
10013 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10014 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10016 (match_operand:SI 2 "s_register_operand" "r,r")
10017 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10018 (clobber (reg:CC CC_REGNUM))]
10021 [(set_attr "conds" "clob")
10022 (set_attr "length" "8,12")
10023 (set_attr "type" "multiple")]
10026 (define_insn "*if_move_plus"
10027 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10029 (match_operator 4 "arm_comparison_operator"
10030 [(match_operand 5 "cc_register" "") (const_int 0)])
10031 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10033 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10034 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10037 add%D4\\t%0, %2, %3
10038 sub%D4\\t%0, %2, #%n3
10039 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10040 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10041 [(set_attr "conds" "use")
10042 (set_attr "length" "4,4,8,8")
10043 (set_attr_alternative "type"
10044 [(if_then_else (match_operand 3 "const_int_operand" "")
10045 (const_string "alu_imm" )
10046 (const_string "alu_sreg"))
10047 (const_string "alu_imm")
10048 (const_string "multiple")
10049 (const_string "multiple")])]
10052 (define_insn "*ifcompare_arith_arith"
10053 [(set (match_operand:SI 0 "s_register_operand" "=r")
10054 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10055 [(match_operand:SI 5 "s_register_operand" "r")
10056 (match_operand:SI 6 "arm_add_operand" "rIL")])
10057 (match_operator:SI 8 "shiftable_operator"
10058 [(match_operand:SI 1 "s_register_operand" "r")
10059 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10060 (match_operator:SI 7 "shiftable_operator"
10061 [(match_operand:SI 3 "s_register_operand" "r")
10062 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10063 (clobber (reg:CC CC_REGNUM))]
10066 [(set_attr "conds" "clob")
10067 (set_attr "length" "12")
10068 (set_attr "type" "multiple")]
10071 (define_insn "*if_arith_arith"
10072 [(set (match_operand:SI 0 "s_register_operand" "=r")
10073 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10074 [(match_operand 8 "cc_register" "") (const_int 0)])
10075 (match_operator:SI 6 "shiftable_operator"
10076 [(match_operand:SI 1 "s_register_operand" "r")
10077 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10078 (match_operator:SI 7 "shiftable_operator"
10079 [(match_operand:SI 3 "s_register_operand" "r")
10080 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10082 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10083 [(set_attr "conds" "use")
10084 (set_attr "length" "8")
10085 (set_attr "type" "multiple")]
10088 (define_insn "*ifcompare_arith_move"
10089 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10090 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10091 [(match_operand:SI 2 "s_register_operand" "r,r")
10092 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10093 (match_operator:SI 7 "shiftable_operator"
10094 [(match_operand:SI 4 "s_register_operand" "r,r")
10095 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10096 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10097 (clobber (reg:CC CC_REGNUM))]
10100 /* If we have an operation where (op x 0) is the identity operation and
10101 the conditional operator is LT or GE and we are comparing against zero and
10102 everything is in registers then we can do this in two instructions. */
10103 if (operands[3] == const0_rtx
10104 && GET_CODE (operands[7]) != AND
10105 && REG_P (operands[5])
10106 && REG_P (operands[1])
10107 && REGNO (operands[1]) == REGNO (operands[4])
10108 && REGNO (operands[4]) != REGNO (operands[0]))
10110 if (GET_CODE (operands[6]) == LT)
10111 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10112 else if (GET_CODE (operands[6]) == GE)
10113 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10115 if (CONST_INT_P (operands[3])
10116 && !const_ok_for_arm (INTVAL (operands[3])))
10117 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10119 output_asm_insn (\"cmp\\t%2, %3\", operands);
10120 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10121 if (which_alternative != 0)
10122 return \"mov%D6\\t%0, %1\";
10125 [(set_attr "conds" "clob")
10126 (set_attr "length" "8,12")
10127 (set_attr "type" "multiple")]
10130 (define_insn "*if_arith_move"
10131 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10132 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10133 [(match_operand 6 "cc_register" "") (const_int 0)])
10134 (match_operator:SI 5 "shiftable_operator"
10135 [(match_operand:SI 2 "s_register_operand" "r,r")
10136 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10137 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10140 %I5%d4\\t%0, %2, %3
10141 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10142 [(set_attr "conds" "use")
10143 (set_attr "length" "4,8")
10144 (set_attr_alternative "type"
10145 [(if_then_else (match_operand 3 "const_int_operand" "")
10146 (const_string "alu_shift_imm" )
10147 (const_string "alu_shift_reg"))
10148 (const_string "multiple")])]
10151 (define_insn "*ifcompare_move_arith"
10152 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10153 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10154 [(match_operand:SI 4 "s_register_operand" "r,r")
10155 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10156 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10157 (match_operator:SI 7 "shiftable_operator"
10158 [(match_operand:SI 2 "s_register_operand" "r,r")
10159 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10160 (clobber (reg:CC CC_REGNUM))]
10163 /* If we have an operation where (op x 0) is the identity operation and
10164 the conditional operator is LT or GE and we are comparing against zero and
10165 everything is in registers then we can do this in two instructions */
10166 if (operands[5] == const0_rtx
10167 && GET_CODE (operands[7]) != AND
10168 && REG_P (operands[3])
10169 && REG_P (operands[1])
10170 && REGNO (operands[1]) == REGNO (operands[2])
10171 && REGNO (operands[2]) != REGNO (operands[0]))
10173 if (GET_CODE (operands[6]) == GE)
10174 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10175 else if (GET_CODE (operands[6]) == LT)
10176 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10179 if (CONST_INT_P (operands[5])
10180 && !const_ok_for_arm (INTVAL (operands[5])))
10181 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10183 output_asm_insn (\"cmp\\t%4, %5\", operands);
10185 if (which_alternative != 0)
10186 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10187 return \"%I7%D6\\t%0, %2, %3\";
10189 [(set_attr "conds" "clob")
10190 (set_attr "length" "8,12")
10191 (set_attr "type" "multiple")]
10194 (define_insn "*if_move_arith"
10195 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10197 (match_operator 4 "arm_comparison_operator"
10198 [(match_operand 6 "cc_register" "") (const_int 0)])
10199 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10200 (match_operator:SI 5 "shiftable_operator"
10201 [(match_operand:SI 2 "s_register_operand" "r,r")
10202 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10205 %I5%D4\\t%0, %2, %3
10206 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10207 [(set_attr "conds" "use")
10208 (set_attr "length" "4,8")
10209 (set_attr_alternative "type"
10210 [(if_then_else (match_operand 3 "const_int_operand" "")
10211 (const_string "alu_shift_imm" )
10212 (const_string "alu_shift_reg"))
10213 (const_string "multiple")])]
10216 (define_insn "*ifcompare_move_not"
10217 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10219 (match_operator 5 "arm_comparison_operator"
10220 [(match_operand:SI 3 "s_register_operand" "r,r")
10221 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10222 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10224 (match_operand:SI 2 "s_register_operand" "r,r"))))
10225 (clobber (reg:CC CC_REGNUM))]
10228 [(set_attr "conds" "clob")
10229 (set_attr "length" "8,12")
10230 (set_attr "type" "multiple")]
10233 (define_insn "*if_move_not"
10234 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10236 (match_operator 4 "arm_comparison_operator"
10237 [(match_operand 3 "cc_register" "") (const_int 0)])
10238 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10239 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10243 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10244 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10245 [(set_attr "conds" "use")
10246 (set_attr "type" "mvn_reg")
10247 (set_attr "length" "4,8,8")
10248 (set_attr "type" "mvn_reg,multiple,multiple")]
10251 (define_insn "*ifcompare_not_move"
10252 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10254 (match_operator 5 "arm_comparison_operator"
10255 [(match_operand:SI 3 "s_register_operand" "r,r")
10256 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10258 (match_operand:SI 2 "s_register_operand" "r,r"))
10259 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10260 (clobber (reg:CC CC_REGNUM))]
10263 [(set_attr "conds" "clob")
10264 (set_attr "length" "8,12")
10265 (set_attr "type" "multiple")]
10268 (define_insn "*if_not_move"
10269 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10271 (match_operator 4 "arm_comparison_operator"
10272 [(match_operand 3 "cc_register" "") (const_int 0)])
10273 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10274 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10278 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10279 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10280 [(set_attr "conds" "use")
10281 (set_attr "type" "mvn_reg,multiple,multiple")
10282 (set_attr "length" "4,8,8")]
10285 (define_insn "*ifcompare_shift_move"
10286 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10288 (match_operator 6 "arm_comparison_operator"
10289 [(match_operand:SI 4 "s_register_operand" "r,r")
10290 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10291 (match_operator:SI 7 "shift_operator"
10292 [(match_operand:SI 2 "s_register_operand" "r,r")
10293 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10294 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10295 (clobber (reg:CC CC_REGNUM))]
10298 [(set_attr "conds" "clob")
10299 (set_attr "length" "8,12")
10300 (set_attr "type" "multiple")]
10303 (define_insn "*if_shift_move"
10304 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10306 (match_operator 5 "arm_comparison_operator"
10307 [(match_operand 6 "cc_register" "") (const_int 0)])
10308 (match_operator:SI 4 "shift_operator"
10309 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10310 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10311 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10315 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10316 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10317 [(set_attr "conds" "use")
10318 (set_attr "shift" "2")
10319 (set_attr "length" "4,8,8")
10320 (set_attr_alternative "type"
10321 [(if_then_else (match_operand 3 "const_int_operand" "")
10322 (const_string "mov_shift" )
10323 (const_string "mov_shift_reg"))
10324 (const_string "multiple")
10325 (const_string "multiple")])]
10328 (define_insn "*ifcompare_move_shift"
10329 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10331 (match_operator 6 "arm_comparison_operator"
10332 [(match_operand:SI 4 "s_register_operand" "r,r")
10333 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10334 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10335 (match_operator:SI 7 "shift_operator"
10336 [(match_operand:SI 2 "s_register_operand" "r,r")
10337 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10338 (clobber (reg:CC CC_REGNUM))]
10341 [(set_attr "conds" "clob")
10342 (set_attr "length" "8,12")
10343 (set_attr "type" "multiple")]
10346 (define_insn "*if_move_shift"
10347 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10349 (match_operator 5 "arm_comparison_operator"
10350 [(match_operand 6 "cc_register" "") (const_int 0)])
10351 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10352 (match_operator:SI 4 "shift_operator"
10353 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10354 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10358 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10359 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10360 [(set_attr "conds" "use")
10361 (set_attr "shift" "2")
10362 (set_attr "length" "4,8,8")
10363 (set_attr_alternative "type"
10364 [(if_then_else (match_operand 3 "const_int_operand" "")
10365 (const_string "mov_shift" )
10366 (const_string "mov_shift_reg"))
10367 (const_string "multiple")
10368 (const_string "multiple")])]
10371 (define_insn "*ifcompare_shift_shift"
10372 [(set (match_operand:SI 0 "s_register_operand" "=r")
10374 (match_operator 7 "arm_comparison_operator"
10375 [(match_operand:SI 5 "s_register_operand" "r")
10376 (match_operand:SI 6 "arm_add_operand" "rIL")])
10377 (match_operator:SI 8 "shift_operator"
10378 [(match_operand:SI 1 "s_register_operand" "r")
10379 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10380 (match_operator:SI 9 "shift_operator"
10381 [(match_operand:SI 3 "s_register_operand" "r")
10382 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10383 (clobber (reg:CC CC_REGNUM))]
10386 [(set_attr "conds" "clob")
10387 (set_attr "length" "12")
10388 (set_attr "type" "multiple")]
10391 (define_insn "*if_shift_shift"
10392 [(set (match_operand:SI 0 "s_register_operand" "=r")
10394 (match_operator 5 "arm_comparison_operator"
10395 [(match_operand 8 "cc_register" "") (const_int 0)])
10396 (match_operator:SI 6 "shift_operator"
10397 [(match_operand:SI 1 "s_register_operand" "r")
10398 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10399 (match_operator:SI 7 "shift_operator"
10400 [(match_operand:SI 3 "s_register_operand" "r")
10401 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10403 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10404 [(set_attr "conds" "use")
10405 (set_attr "shift" "1")
10406 (set_attr "length" "8")
10407 (set (attr "type") (if_then_else
10408 (and (match_operand 2 "const_int_operand" "")
10409 (match_operand 4 "const_int_operand" ""))
10410 (const_string "mov_shift")
10411 (const_string "mov_shift_reg")))]
10414 (define_insn "*ifcompare_not_arith"
10415 [(set (match_operand:SI 0 "s_register_operand" "=r")
10417 (match_operator 6 "arm_comparison_operator"
10418 [(match_operand:SI 4 "s_register_operand" "r")
10419 (match_operand:SI 5 "arm_add_operand" "rIL")])
10420 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10421 (match_operator:SI 7 "shiftable_operator"
10422 [(match_operand:SI 2 "s_register_operand" "r")
10423 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10424 (clobber (reg:CC CC_REGNUM))]
10427 [(set_attr "conds" "clob")
10428 (set_attr "length" "12")
10429 (set_attr "type" "multiple")]
10432 (define_insn "*if_not_arith"
10433 [(set (match_operand:SI 0 "s_register_operand" "=r")
10435 (match_operator 5 "arm_comparison_operator"
10436 [(match_operand 4 "cc_register" "") (const_int 0)])
10437 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10438 (match_operator:SI 6 "shiftable_operator"
10439 [(match_operand:SI 2 "s_register_operand" "r")
10440 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10442 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10443 [(set_attr "conds" "use")
10444 (set_attr "type" "mvn_reg")
10445 (set_attr "length" "8")]
10448 (define_insn "*ifcompare_arith_not"
10449 [(set (match_operand:SI 0 "s_register_operand" "=r")
10451 (match_operator 6 "arm_comparison_operator"
10452 [(match_operand:SI 4 "s_register_operand" "r")
10453 (match_operand:SI 5 "arm_add_operand" "rIL")])
10454 (match_operator:SI 7 "shiftable_operator"
10455 [(match_operand:SI 2 "s_register_operand" "r")
10456 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10457 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10458 (clobber (reg:CC CC_REGNUM))]
10461 [(set_attr "conds" "clob")
10462 (set_attr "length" "12")
10463 (set_attr "type" "multiple")]
10466 (define_insn "*if_arith_not"
10467 [(set (match_operand:SI 0 "s_register_operand" "=r")
10469 (match_operator 5 "arm_comparison_operator"
10470 [(match_operand 4 "cc_register" "") (const_int 0)])
10471 (match_operator:SI 6 "shiftable_operator"
10472 [(match_operand:SI 2 "s_register_operand" "r")
10473 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10474 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10476 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10477 [(set_attr "conds" "use")
10478 (set_attr "type" "multiple")
10479 (set_attr "length" "8")]
10482 (define_insn "*ifcompare_neg_move"
10483 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10485 (match_operator 5 "arm_comparison_operator"
10486 [(match_operand:SI 3 "s_register_operand" "r,r")
10487 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10488 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10489 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10490 (clobber (reg:CC CC_REGNUM))]
10493 [(set_attr "conds" "clob")
10494 (set_attr "length" "8,12")
10495 (set_attr "type" "multiple")]
10498 (define_insn_and_split "*if_neg_move"
10499 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10501 (match_operator 4 "arm_comparison_operator"
10502 [(match_operand 3 "cc_register" "") (const_int 0)])
10503 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10504 (match_operand:SI 1 "s_register_operand" "0,0")))]
10507 "&& reload_completed"
10508 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10509 (set (match_dup 0) (neg:SI (match_dup 2))))]
10511 [(set_attr "conds" "use")
10512 (set_attr "length" "4")
10513 (set_attr "arch" "t2,32")
10514 (set_attr "enabled_for_depr_it" "yes,no")
10515 (set_attr "type" "logic_shift_imm")]
10518 (define_insn "*ifcompare_move_neg"
10519 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10521 (match_operator 5 "arm_comparison_operator"
10522 [(match_operand:SI 3 "s_register_operand" "r,r")
10523 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10524 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10525 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10526 (clobber (reg:CC CC_REGNUM))]
10529 [(set_attr "conds" "clob")
10530 (set_attr "length" "8,12")
10531 (set_attr "type" "multiple")]
10534 (define_insn_and_split "*if_move_neg"
10535 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10537 (match_operator 4 "arm_comparison_operator"
10538 [(match_operand 3 "cc_register" "") (const_int 0)])
10539 (match_operand:SI 1 "s_register_operand" "0,0")
10540 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10543 "&& reload_completed"
10544 [(cond_exec (match_dup 5)
10545 (set (match_dup 0) (neg:SI (match_dup 2))))]
10547 machine_mode mode = GET_MODE (operands[3]);
10548 rtx_code rc = GET_CODE (operands[4]);
10550 if (mode == CCFPmode || mode == CCFPEmode)
10551 rc = reverse_condition_maybe_unordered (rc);
10553 rc = reverse_condition (rc);
10555 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10557 [(set_attr "conds" "use")
10558 (set_attr "length" "4")
10559 (set_attr "arch" "t2,32")
10560 (set_attr "enabled_for_depr_it" "yes,no")
10561 (set_attr "type" "logic_shift_imm")]
10564 (define_insn "*arith_adjacentmem"
10565 [(set (match_operand:SI 0 "s_register_operand" "=r")
10566 (match_operator:SI 1 "shiftable_operator"
10567 [(match_operand:SI 2 "memory_operand" "m")
10568 (match_operand:SI 3 "memory_operand" "m")]))
10569 (clobber (match_scratch:SI 4 "=r"))]
10570 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10576 HOST_WIDE_INT val1 = 0, val2 = 0;
10578 if (REGNO (operands[0]) > REGNO (operands[4]))
10580 ldm[1] = operands[4];
10581 ldm[2] = operands[0];
10585 ldm[1] = operands[0];
10586 ldm[2] = operands[4];
10589 base_reg = XEXP (operands[2], 0);
10591 if (!REG_P (base_reg))
10593 val1 = INTVAL (XEXP (base_reg, 1));
10594 base_reg = XEXP (base_reg, 0);
10597 if (!REG_P (XEXP (operands[3], 0)))
10598 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10600 arith[0] = operands[0];
10601 arith[3] = operands[1];
10615 if (val1 !=0 && val2 != 0)
10619 if (val1 == 4 || val2 == 4)
10620 /* Other val must be 8, since we know they are adjacent and neither
10622 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10623 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10625 ldm[0] = ops[0] = operands[4];
10627 ops[2] = GEN_INT (val1);
10628 output_add_immediate (ops);
10630 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10632 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10636 /* Offset is out of range for a single add, so use two ldr. */
10639 ops[2] = GEN_INT (val1);
10640 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10642 ops[2] = GEN_INT (val2);
10643 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10646 else if (val1 != 0)
10649 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10651 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10656 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10658 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10660 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10663 [(set_attr "length" "12")
10664 (set_attr "predicable" "yes")
10665 (set_attr "type" "load1")]
10668 ; This pattern is never tried by combine, so do it as a peephole
10671 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10672 (match_operand:SI 1 "arm_general_register_operand" ""))
10673 (set (reg:CC CC_REGNUM)
10674 (compare:CC (match_dup 1) (const_int 0)))]
10676 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10677 (set (match_dup 0) (match_dup 1))])]
10682 [(set (match_operand:SI 0 "s_register_operand" "")
10683 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10685 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10686 [(match_operand:SI 3 "s_register_operand" "")
10687 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10688 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10690 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10691 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10696 ;; This split can be used because CC_Z mode implies that the following
10697 ;; branch will be an equality, or an unsigned inequality, so the sign
10698 ;; extension is not needed.
10701 [(set (reg:CC_Z CC_REGNUM)
10703 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10705 (match_operand 1 "const_int_operand" "")))
10706 (clobber (match_scratch:SI 2 ""))]
10708 && ((UINTVAL (operands[1]))
10709 == ((UINTVAL (operands[1])) >> 24) << 24)"
10710 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10711 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10713 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10716 ;; ??? Check the patterns above for Thumb-2 usefulness
10718 (define_expand "prologue"
10719 [(clobber (const_int 0))]
10722 arm_expand_prologue ();
10724 thumb1_expand_prologue ();
10729 (define_expand "epilogue"
10730 [(clobber (const_int 0))]
10733 if (crtl->calls_eh_return)
10734 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10737 thumb1_expand_epilogue ();
10738 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10739 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10741 else if (HAVE_return)
10743 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10744 no need for explicit testing again. */
10745 emit_jump_insn (gen_return ());
10747 else if (TARGET_32BIT)
10749 arm_expand_epilogue (true);
10755 ;; Note - although unspec_volatile's USE all hard registers,
10756 ;; USEs are ignored after relaod has completed. Thus we need
10757 ;; to add an unspec of the link register to ensure that flow
10758 ;; does not think that it is unused by the sibcall branch that
10759 ;; will replace the standard function epilogue.
10760 (define_expand "sibcall_epilogue"
10761 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10762 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10765 arm_expand_epilogue (false);
10770 (define_expand "eh_epilogue"
10771 [(use (match_operand:SI 0 "register_operand" ""))
10772 (use (match_operand:SI 1 "register_operand" ""))
10773 (use (match_operand:SI 2 "register_operand" ""))]
10777 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10778 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10780 rtx ra = gen_rtx_REG (Pmode, 2);
10782 emit_move_insn (ra, operands[2]);
10785 /* This is a hack -- we may have crystalized the function type too
10787 cfun->machine->func_type = 0;
10791 ;; This split is only used during output to reduce the number of patterns
10792 ;; that need assembler instructions adding to them. We allowed the setting
10793 ;; of the conditions to be implicit during rtl generation so that
10794 ;; the conditional compare patterns would work. However this conflicts to
10795 ;; some extent with the conditional data operations, so we have to split them
10798 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10799 ;; conditional execution sufficient?
10802 [(set (match_operand:SI 0 "s_register_operand" "")
10803 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10804 [(match_operand 2 "" "") (match_operand 3 "" "")])
10806 (match_operand 4 "" "")))
10807 (clobber (reg:CC CC_REGNUM))]
10808 "TARGET_ARM && reload_completed"
10809 [(set (match_dup 5) (match_dup 6))
10810 (cond_exec (match_dup 7)
10811 (set (match_dup 0) (match_dup 4)))]
10814 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10815 operands[2], operands[3]);
10816 enum rtx_code rc = GET_CODE (operands[1]);
10818 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10819 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10820 if (mode == CCFPmode || mode == CCFPEmode)
10821 rc = reverse_condition_maybe_unordered (rc);
10823 rc = reverse_condition (rc);
10825 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10830 [(set (match_operand:SI 0 "s_register_operand" "")
10831 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10832 [(match_operand 2 "" "") (match_operand 3 "" "")])
10833 (match_operand 4 "" "")
10835 (clobber (reg:CC CC_REGNUM))]
10836 "TARGET_ARM && reload_completed"
10837 [(set (match_dup 5) (match_dup 6))
10838 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10839 (set (match_dup 0) (match_dup 4)))]
10842 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10843 operands[2], operands[3]);
10845 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10846 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10851 [(set (match_operand:SI 0 "s_register_operand" "")
10852 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10853 [(match_operand 2 "" "") (match_operand 3 "" "")])
10854 (match_operand 4 "" "")
10855 (match_operand 5 "" "")))
10856 (clobber (reg:CC CC_REGNUM))]
10857 "TARGET_ARM && reload_completed"
10858 [(set (match_dup 6) (match_dup 7))
10859 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10860 (set (match_dup 0) (match_dup 4)))
10861 (cond_exec (match_dup 8)
10862 (set (match_dup 0) (match_dup 5)))]
10865 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10866 operands[2], operands[3]);
10867 enum rtx_code rc = GET_CODE (operands[1]);
10869 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10870 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10871 if (mode == CCFPmode || mode == CCFPEmode)
10872 rc = reverse_condition_maybe_unordered (rc);
10874 rc = reverse_condition (rc);
10876 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10881 [(set (match_operand:SI 0 "s_register_operand" "")
10882 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10883 [(match_operand:SI 2 "s_register_operand" "")
10884 (match_operand:SI 3 "arm_add_operand" "")])
10885 (match_operand:SI 4 "arm_rhs_operand" "")
10887 (match_operand:SI 5 "s_register_operand" ""))))
10888 (clobber (reg:CC CC_REGNUM))]
10889 "TARGET_ARM && reload_completed"
10890 [(set (match_dup 6) (match_dup 7))
10891 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10892 (set (match_dup 0) (match_dup 4)))
10893 (cond_exec (match_dup 8)
10894 (set (match_dup 0) (not:SI (match_dup 5))))]
10897 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10898 operands[2], operands[3]);
10899 enum rtx_code rc = GET_CODE (operands[1]);
10901 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10902 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10903 if (mode == CCFPmode || mode == CCFPEmode)
10904 rc = reverse_condition_maybe_unordered (rc);
10906 rc = reverse_condition (rc);
10908 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10912 (define_insn "*cond_move_not"
10913 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10914 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10915 [(match_operand 3 "cc_register" "") (const_int 0)])
10916 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10918 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10922 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10923 [(set_attr "conds" "use")
10924 (set_attr "type" "mvn_reg,multiple")
10925 (set_attr "length" "4,8")]
10928 ;; The next two patterns occur when an AND operation is followed by a
10929 ;; scc insn sequence
10931 (define_insn "*sign_extract_onebit"
10932 [(set (match_operand:SI 0 "s_register_operand" "=r")
10933 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10935 (match_operand:SI 2 "const_int_operand" "n")))
10936 (clobber (reg:CC CC_REGNUM))]
10939 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10940 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10941 return \"mvnne\\t%0, #0\";
10943 [(set_attr "conds" "clob")
10944 (set_attr "length" "8")
10945 (set_attr "type" "multiple")]
10948 (define_insn "*not_signextract_onebit"
10949 [(set (match_operand:SI 0 "s_register_operand" "=r")
10951 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10953 (match_operand:SI 2 "const_int_operand" "n"))))
10954 (clobber (reg:CC CC_REGNUM))]
10957 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10958 output_asm_insn (\"tst\\t%1, %2\", operands);
10959 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10960 return \"movne\\t%0, #0\";
10962 [(set_attr "conds" "clob")
10963 (set_attr "length" "12")
10964 (set_attr "type" "multiple")]
10966 ;; ??? The above patterns need auditing for Thumb-2
10968 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10969 ;; expressions. For simplicity, the first register is also in the unspec
10971 ;; To avoid the usage of GNU extension, the length attribute is computed
10972 ;; in a C function arm_attr_length_push_multi.
10973 (define_insn "*push_multi"
10974 [(match_parallel 2 "multi_register_push"
10975 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10976 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10977 UNSPEC_PUSH_MULT))])]
10981 int num_saves = XVECLEN (operands[2], 0);
10983 /* For the StrongARM at least it is faster to
10984 use STR to store only a single register.
10985 In Thumb mode always use push, and the assembler will pick
10986 something appropriate. */
10987 if (num_saves == 1 && TARGET_ARM)
10988 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10995 strcpy (pattern, \"push%?\\t{%1\");
10997 strcpy (pattern, \"push\\t{%1\");
10999 for (i = 1; i < num_saves; i++)
11001 strcat (pattern, \", %|\");
11003 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11006 strcat (pattern, \"}\");
11007 output_asm_insn (pattern, operands);
11012 [(set_attr "type" "store4")
11013 (set (attr "length")
11014 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11017 (define_insn "stack_tie"
11018 [(set (mem:BLK (scratch))
11019 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11020 (match_operand:SI 1 "s_register_operand" "rk")]
11024 [(set_attr "length" "0")
11025 (set_attr "type" "block")]
11028 ;; Pop (as used in epilogue RTL)
11030 (define_insn "*load_multiple_with_writeback"
11031 [(match_parallel 0 "load_multiple_operation"
11032 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11033 (plus:SI (match_dup 1)
11034 (match_operand:SI 2 "const_int_I_operand" "I")))
11035 (set (match_operand:SI 3 "s_register_operand" "=rk")
11036 (mem:SI (match_dup 1)))
11038 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11041 arm_output_multireg_pop (operands, /*return_pc=*/false,
11042 /*cond=*/const_true_rtx,
11048 [(set_attr "type" "load4")
11049 (set_attr "predicable" "yes")
11050 (set (attr "length")
11051 (symbol_ref "arm_attr_length_pop_multi (operands,
11052 /*return_pc=*/false,
11053 /*write_back_p=*/true)"))]
11056 ;; Pop with return (as used in epilogue RTL)
11058 ;; This instruction is generated when the registers are popped at the end of
11059 ;; epilogue. Here, instead of popping the value into LR and then generating
11060 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11062 (define_insn "*pop_multiple_with_writeback_and_return"
11063 [(match_parallel 0 "pop_multiple_return"
11065 (set (match_operand:SI 1 "s_register_operand" "+rk")
11066 (plus:SI (match_dup 1)
11067 (match_operand:SI 2 "const_int_I_operand" "I")))
11068 (set (match_operand:SI 3 "s_register_operand" "=rk")
11069 (mem:SI (match_dup 1)))
11071 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11074 arm_output_multireg_pop (operands, /*return_pc=*/true,
11075 /*cond=*/const_true_rtx,
11081 [(set_attr "type" "load4")
11082 (set_attr "predicable" "yes")
11083 (set (attr "length")
11084 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11085 /*write_back_p=*/true)"))]
11088 (define_insn "*pop_multiple_with_return"
11089 [(match_parallel 0 "pop_multiple_return"
11091 (set (match_operand:SI 2 "s_register_operand" "=rk")
11092 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11094 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11097 arm_output_multireg_pop (operands, /*return_pc=*/true,
11098 /*cond=*/const_true_rtx,
11104 [(set_attr "type" "load4")
11105 (set_attr "predicable" "yes")
11106 (set (attr "length")
11107 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11108 /*write_back_p=*/false)"))]
11111 ;; Load into PC and return
11112 (define_insn "*ldr_with_return"
11114 (set (reg:SI PC_REGNUM)
11115 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11116 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11117 "ldr%?\t%|pc, [%0], #4"
11118 [(set_attr "type" "load1")
11119 (set_attr "predicable" "yes")]
11121 ;; Pop for floating point registers (as used in epilogue RTL)
11122 (define_insn "*vfp_pop_multiple_with_writeback"
11123 [(match_parallel 0 "pop_multiple_fp"
11124 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11125 (plus:SI (match_dup 1)
11126 (match_operand:SI 2 "const_int_I_operand" "I")))
11127 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11128 (mem:DF (match_dup 1)))])]
11129 "TARGET_32BIT && TARGET_HARD_FLOAT"
11132 int num_regs = XVECLEN (operands[0], 0);
11135 strcpy (pattern, \"vldm\\t\");
11136 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11137 strcat (pattern, \"!, {\");
11138 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11139 strcat (pattern, \"%P0\");
11140 if ((num_regs - 1) > 1)
11142 strcat (pattern, \"-%P1\");
11143 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11146 strcat (pattern, \"}\");
11147 output_asm_insn (pattern, op_list);
11151 [(set_attr "type" "load4")
11152 (set_attr "conds" "unconditional")
11153 (set_attr "predicable" "no")]
11156 ;; Special patterns for dealing with the constant pool
11158 (define_insn "align_4"
11159 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11162 assemble_align (32);
11165 [(set_attr "type" "no_insn")]
11168 (define_insn "align_8"
11169 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11172 assemble_align (64);
11175 [(set_attr "type" "no_insn")]
11178 (define_insn "consttable_end"
11179 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11182 making_const_table = FALSE;
11185 [(set_attr "type" "no_insn")]
11188 (define_insn "consttable_1"
11189 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11192 making_const_table = TRUE;
11193 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11194 assemble_zeros (3);
11197 [(set_attr "length" "4")
11198 (set_attr "type" "no_insn")]
11201 (define_insn "consttable_2"
11202 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11206 rtx x = operands[0];
11207 making_const_table = TRUE;
11208 switch (GET_MODE_CLASS (GET_MODE (x)))
11211 arm_emit_fp16_const (x);
11214 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11215 assemble_zeros (2);
11220 [(set_attr "length" "4")
11221 (set_attr "type" "no_insn")]
11224 (define_insn "consttable_4"
11225 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11229 rtx x = operands[0];
11230 making_const_table = TRUE;
11231 switch (GET_MODE_CLASS (GET_MODE (x)))
11234 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
11238 /* XXX: Sometimes gcc does something really dumb and ends up with
11239 a HIGH in a constant pool entry, usually because it's trying to
11240 load into a VFP register. We know this will always be used in
11241 combination with a LO_SUM which ignores the high bits, so just
11242 strip off the HIGH. */
11243 if (GET_CODE (x) == HIGH)
11245 assemble_integer (x, 4, BITS_PER_WORD, 1);
11246 mark_symbol_refs_as_used (x);
11251 [(set_attr "length" "4")
11252 (set_attr "type" "no_insn")]
11255 (define_insn "consttable_8"
11256 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11260 making_const_table = TRUE;
11261 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11264 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11265 GET_MODE (operands[0]), BITS_PER_WORD);
11268 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11273 [(set_attr "length" "8")
11274 (set_attr "type" "no_insn")]
11277 (define_insn "consttable_16"
11278 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11282 making_const_table = TRUE;
11283 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11286 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11287 GET_MODE (operands[0]), BITS_PER_WORD);
11290 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11295 [(set_attr "length" "16")
11296 (set_attr "type" "no_insn")]
11299 ;; V5 Instructions,
11301 (define_insn "clzsi2"
11302 [(set (match_operand:SI 0 "s_register_operand" "=r")
11303 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11304 "TARGET_32BIT && arm_arch5"
11306 [(set_attr "predicable" "yes")
11307 (set_attr "predicable_short_it" "no")
11308 (set_attr "type" "clz")])
11310 (define_insn "rbitsi2"
11311 [(set (match_operand:SI 0 "s_register_operand" "=r")
11312 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11313 "TARGET_32BIT && arm_arch_thumb2"
11315 [(set_attr "predicable" "yes")
11316 (set_attr "predicable_short_it" "no")
11317 (set_attr "type" "clz")])
11319 ;; Keep this as a CTZ expression until after reload and then split
11320 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11321 ;; to fold with any other expression.
11323 (define_insn_and_split "ctzsi2"
11324 [(set (match_operand:SI 0 "s_register_operand" "=r")
11325 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11326 "TARGET_32BIT && arm_arch_thumb2"
11328 "&& reload_completed"
11331 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11332 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11336 ;; V5E instructions.
11338 (define_insn "prefetch"
11339 [(prefetch (match_operand:SI 0 "address_operand" "p")
11340 (match_operand:SI 1 "" "")
11341 (match_operand:SI 2 "" ""))]
11342 "TARGET_32BIT && arm_arch5e"
11344 [(set_attr "type" "load1")]
11347 ;; General predication pattern
11350 [(match_operator 0 "arm_comparison_operator"
11351 [(match_operand 1 "cc_register" "")
11354 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11356 [(set_attr "predicated" "yes")]
11359 (define_insn "force_register_use"
11360 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11363 [(set_attr "length" "0")
11364 (set_attr "type" "no_insn")]
11368 ;; Patterns for exception handling
11370 (define_expand "eh_return"
11371 [(use (match_operand 0 "general_operand" ""))]
11376 emit_insn (gen_arm_eh_return (operands[0]));
11378 emit_insn (gen_thumb_eh_return (operands[0]));
11383 ;; We can't expand this before we know where the link register is stored.
11384 (define_insn_and_split "arm_eh_return"
11385 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11387 (clobber (match_scratch:SI 1 "=&r"))]
11390 "&& reload_completed"
11394 arm_set_return_address (operands[0], operands[1]);
11402 (define_insn "load_tp_hard"
11403 [(set (match_operand:SI 0 "register_operand" "=r")
11404 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11406 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11407 [(set_attr "predicable" "yes")
11408 (set_attr "type" "mrs")]
11411 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11412 (define_insn "load_tp_soft"
11413 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11414 (clobber (reg:SI LR_REGNUM))
11415 (clobber (reg:SI IP_REGNUM))
11416 (clobber (reg:CC CC_REGNUM))]
11418 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11419 [(set_attr "conds" "clob")
11420 (set_attr "type" "branch")]
11423 ;; tls descriptor call
11424 (define_insn "tlscall"
11425 [(set (reg:SI R0_REGNUM)
11426 (unspec:SI [(reg:SI R0_REGNUM)
11427 (match_operand:SI 0 "" "X")
11428 (match_operand 1 "" "")] UNSPEC_TLS))
11429 (clobber (reg:SI R1_REGNUM))
11430 (clobber (reg:SI LR_REGNUM))
11431 (clobber (reg:SI CC_REGNUM))]
11434 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11435 INTVAL (operands[1]));
11436 return "bl\\t%c0(tlscall)";
11438 [(set_attr "conds" "clob")
11439 (set_attr "length" "4")
11440 (set_attr "type" "branch")]
11443 ;; For thread pointer builtin
11444 (define_expand "get_thread_pointersi"
11445 [(match_operand:SI 0 "s_register_operand" "=r")]
11449 arm_load_tp (operands[0]);
11455 ;; We only care about the lower 16 bits of the constant
11456 ;; being inserted into the upper 16 bits of the register.
11457 (define_insn "*arm_movtas_ze"
11458 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11461 (match_operand:SI 1 "const_int_operand" ""))]
11466 [(set_attr "arch" "32,v8mb")
11467 (set_attr "predicable" "yes")
11468 (set_attr "predicable_short_it" "no")
11469 (set_attr "length" "4")
11470 (set_attr "type" "alu_sreg")]
11473 (define_insn "*arm_rev"
11474 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11475 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11481 [(set_attr "arch" "t1,t2,32")
11482 (set_attr "length" "2,2,4")
11483 (set_attr "predicable" "no,yes,yes")
11484 (set_attr "predicable_short_it" "no")
11485 (set_attr "type" "rev")]
11488 (define_expand "arm_legacy_rev"
11489 [(set (match_operand:SI 2 "s_register_operand" "")
11490 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11494 (lshiftrt:SI (match_dup 2)
11496 (set (match_operand:SI 3 "s_register_operand" "")
11497 (rotatert:SI (match_dup 1)
11500 (and:SI (match_dup 2)
11501 (const_int -65281)))
11502 (set (match_operand:SI 0 "s_register_operand" "")
11503 (xor:SI (match_dup 3)
11509 ;; Reuse temporaries to keep register pressure down.
11510 (define_expand "thumb_legacy_rev"
11511 [(set (match_operand:SI 2 "s_register_operand" "")
11512 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11514 (set (match_operand:SI 3 "s_register_operand" "")
11515 (lshiftrt:SI (match_dup 1)
11518 (ior:SI (match_dup 3)
11520 (set (match_operand:SI 4 "s_register_operand" "")
11522 (set (match_operand:SI 5 "s_register_operand" "")
11523 (rotatert:SI (match_dup 1)
11526 (ashift:SI (match_dup 5)
11529 (lshiftrt:SI (match_dup 5)
11532 (ior:SI (match_dup 5)
11535 (rotatert:SI (match_dup 5)
11537 (set (match_operand:SI 0 "s_register_operand" "")
11538 (ior:SI (match_dup 5)
11544 ;; ARM-specific expansion of signed mod by power of 2
11545 ;; using conditional negate.
11546 ;; For r0 % n where n is a power of 2 produce:
11548 ;; and r0, r0, #(n - 1)
11549 ;; and r1, r1, #(n - 1)
11550 ;; rsbpl r0, r1, #0
11552 (define_expand "modsi3"
11553 [(match_operand:SI 0 "register_operand" "")
11554 (match_operand:SI 1 "register_operand" "")
11555 (match_operand:SI 2 "const_int_operand" "")]
11558 HOST_WIDE_INT val = INTVAL (operands[2]);
11561 || exact_log2 (val) <= 0)
11564 rtx mask = GEN_INT (val - 1);
11566 /* In the special case of x0 % 2 we can do the even shorter:
11569 rsblt r0, r0, #0. */
11573 rtx cc_reg = arm_gen_compare_reg (LT,
11574 operands[1], const0_rtx, NULL_RTX);
11575 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11576 rtx masked = gen_reg_rtx (SImode);
11578 emit_insn (gen_andsi3 (masked, operands[1], mask));
11579 emit_move_insn (operands[0],
11580 gen_rtx_IF_THEN_ELSE (SImode, cond,
11581 gen_rtx_NEG (SImode,
11587 rtx neg_op = gen_reg_rtx (SImode);
11588 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11591 /* Extract the condition register and mode. */
11592 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11593 rtx cc_reg = SET_DEST (cmp);
11594 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11596 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11598 rtx masked_neg = gen_reg_rtx (SImode);
11599 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11601 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11602 during expand does not always work. Do an IF_THEN_ELSE instead. */
11603 emit_move_insn (operands[0],
11604 gen_rtx_IF_THEN_ELSE (SImode, cond,
11605 gen_rtx_NEG (SImode, masked_neg),
11613 (define_expand "bswapsi2"
11614 [(set (match_operand:SI 0 "s_register_operand" "=r")
11615 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11616 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11620 rtx op2 = gen_reg_rtx (SImode);
11621 rtx op3 = gen_reg_rtx (SImode);
11625 rtx op4 = gen_reg_rtx (SImode);
11626 rtx op5 = gen_reg_rtx (SImode);
11628 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11629 op2, op3, op4, op5));
11633 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11642 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11643 ;; and unsigned variants, respectively. For rev16, expose
11644 ;; byte-swapping in the lower 16 bits only.
11645 (define_insn "*arm_revsh"
11646 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11647 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11653 [(set_attr "arch" "t1,t2,32")
11654 (set_attr "length" "2,2,4")
11655 (set_attr "type" "rev")]
11658 (define_insn "*arm_rev16"
11659 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11660 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11666 [(set_attr "arch" "t1,t2,32")
11667 (set_attr "length" "2,2,4")
11668 (set_attr "type" "rev")]
11671 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11672 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11673 ;; each valid permutation.
11675 (define_insn "arm_rev16si2"
11676 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11677 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11679 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11680 (and:SI (lshiftrt:SI (match_dup 1)
11682 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11684 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11685 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11687 [(set_attr "arch" "t1,t2,32")
11688 (set_attr "length" "2,2,4")
11689 (set_attr "type" "rev")]
11692 (define_insn "arm_rev16si2_alt"
11693 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11694 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11696 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11697 (and:SI (ashift:SI (match_dup 1)
11699 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11701 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11702 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11704 [(set_attr "arch" "t1,t2,32")
11705 (set_attr "length" "2,2,4")
11706 (set_attr "type" "rev")]
11709 (define_expand "bswaphi2"
11710 [(set (match_operand:HI 0 "s_register_operand" "=r")
11711 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11716 ;; Patterns for LDRD/STRD in Thumb2 mode
11718 (define_insn "*thumb2_ldrd"
11719 [(set (match_operand:SI 0 "s_register_operand" "=r")
11720 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11721 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11722 (set (match_operand:SI 3 "s_register_operand" "=r")
11723 (mem:SI (plus:SI (match_dup 1)
11724 (match_operand:SI 4 "const_int_operand" ""))))]
11725 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11726 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11727 && (operands_ok_ldrd_strd (operands[0], operands[3],
11728 operands[1], INTVAL (operands[2]),
11730 "ldrd%?\t%0, %3, [%1, %2]"
11731 [(set_attr "type" "load2")
11732 (set_attr "predicable" "yes")
11733 (set_attr "predicable_short_it" "no")])
11735 (define_insn "*thumb2_ldrd_base"
11736 [(set (match_operand:SI 0 "s_register_operand" "=r")
11737 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11738 (set (match_operand:SI 2 "s_register_operand" "=r")
11739 (mem:SI (plus:SI (match_dup 1)
11741 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11742 && (operands_ok_ldrd_strd (operands[0], operands[2],
11743 operands[1], 0, false, true))"
11744 "ldrd%?\t%0, %2, [%1]"
11745 [(set_attr "type" "load2")
11746 (set_attr "predicable" "yes")
11747 (set_attr "predicable_short_it" "no")])
11749 (define_insn "*thumb2_ldrd_base_neg"
11750 [(set (match_operand:SI 0 "s_register_operand" "=r")
11751 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11753 (set (match_operand:SI 2 "s_register_operand" "=r")
11754 (mem:SI (match_dup 1)))]
11755 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11756 && (operands_ok_ldrd_strd (operands[0], operands[2],
11757 operands[1], -4, false, true))"
11758 "ldrd%?\t%0, %2, [%1, #-4]"
11759 [(set_attr "type" "load2")
11760 (set_attr "predicable" "yes")
11761 (set_attr "predicable_short_it" "no")])
11763 (define_insn "*thumb2_strd"
11764 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11765 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11766 (match_operand:SI 2 "s_register_operand" "r"))
11767 (set (mem:SI (plus:SI (match_dup 0)
11768 (match_operand:SI 3 "const_int_operand" "")))
11769 (match_operand:SI 4 "s_register_operand" "r"))]
11770 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11771 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11772 && (operands_ok_ldrd_strd (operands[2], operands[4],
11773 operands[0], INTVAL (operands[1]),
11775 "strd%?\t%2, %4, [%0, %1]"
11776 [(set_attr "type" "store2")
11777 (set_attr "predicable" "yes")
11778 (set_attr "predicable_short_it" "no")])
11780 (define_insn "*thumb2_strd_base"
11781 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11782 (match_operand:SI 1 "s_register_operand" "r"))
11783 (set (mem:SI (plus:SI (match_dup 0)
11785 (match_operand:SI 2 "s_register_operand" "r"))]
11786 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11787 && (operands_ok_ldrd_strd (operands[1], operands[2],
11788 operands[0], 0, false, false))"
11789 "strd%?\t%1, %2, [%0]"
11790 [(set_attr "type" "store2")
11791 (set_attr "predicable" "yes")
11792 (set_attr "predicable_short_it" "no")])
11794 (define_insn "*thumb2_strd_base_neg"
11795 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11797 (match_operand:SI 1 "s_register_operand" "r"))
11798 (set (mem:SI (match_dup 0))
11799 (match_operand:SI 2 "s_register_operand" "r"))]
11800 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11801 && (operands_ok_ldrd_strd (operands[1], operands[2],
11802 operands[0], -4, false, false))"
11803 "strd%?\t%1, %2, [%0, #-4]"
11804 [(set_attr "type" "store2")
11805 (set_attr "predicable" "yes")
11806 (set_attr "predicable_short_it" "no")])
11808 ;; ARMv8 CRC32 instructions.
11809 (define_insn "<crc_variant>"
11810 [(set (match_operand:SI 0 "s_register_operand" "=r")
11811 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11812 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11815 "<crc_variant>\\t%0, %1, %2"
11816 [(set_attr "type" "crc")
11817 (set_attr "conds" "unconditional")]
11820 ;; Load the load/store double peephole optimizations.
11821 (include "ldrdstrd.md")
11823 ;; Load the load/store multiple patterns
11824 (include "ldmstm.md")
11826 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11827 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11828 (define_insn "*load_multiple"
11829 [(match_parallel 0 "load_multiple_operation"
11830 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11831 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11836 arm_output_multireg_pop (operands, /*return_pc=*/false,
11837 /*cond=*/const_true_rtx,
11843 [(set_attr "predicable" "yes")]
11846 (define_expand "copysignsf3"
11847 [(match_operand:SF 0 "register_operand")
11848 (match_operand:SF 1 "register_operand")
11849 (match_operand:SF 2 "register_operand")]
11850 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11852 emit_move_insn (operands[0], operands[2]);
11853 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11854 GEN_INT (31), GEN_INT (0),
11855 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11860 (define_expand "copysigndf3"
11861 [(match_operand:DF 0 "register_operand")
11862 (match_operand:DF 1 "register_operand")
11863 (match_operand:DF 2 "register_operand")]
11864 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11866 rtx op0_low = gen_lowpart (SImode, operands[0]);
11867 rtx op0_high = gen_highpart (SImode, operands[0]);
11868 rtx op1_low = gen_lowpart (SImode, operands[1]);
11869 rtx op1_high = gen_highpart (SImode, operands[1]);
11870 rtx op2_high = gen_highpart (SImode, operands[2]);
11872 rtx scratch1 = gen_reg_rtx (SImode);
11873 rtx scratch2 = gen_reg_rtx (SImode);
11874 emit_move_insn (scratch1, op2_high);
11875 emit_move_insn (scratch2, op1_high);
11877 emit_insn(gen_rtx_SET(scratch1,
11878 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11879 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11880 emit_move_insn (op0_low, op1_low);
11881 emit_move_insn (op0_high, scratch2);
11887 ;; movmisalign patterns for HImode and SImode.
11888 (define_expand "movmisalign<mode>"
11889 [(match_operand:HSI 0 "general_operand")
11890 (match_operand:HSI 1 "general_operand")]
11893 /* This pattern is not permitted to fail during expansion: if both arguments
11894 are non-registers (e.g. memory := constant), force operand 1 into a
11896 rtx (* gen_unaligned_load)(rtx, rtx);
11897 rtx tmp_dest = operands[0];
11898 if (!s_register_operand (operands[0], <MODE>mode)
11899 && !s_register_operand (operands[1], <MODE>mode))
11900 operands[1] = force_reg (<MODE>mode, operands[1]);
11902 if (<MODE>mode == HImode)
11904 gen_unaligned_load = gen_unaligned_loadhiu;
11905 tmp_dest = gen_reg_rtx (SImode);
11908 gen_unaligned_load = gen_unaligned_loadsi;
11910 if (MEM_P (operands[1]))
11912 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11913 if (<MODE>mode == HImode)
11914 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11917 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11922 (define_insn "<cdp>"
11923 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11924 (match_operand:SI 1 "immediate_operand" "n")
11925 (match_operand:SI 2 "immediate_operand" "n")
11926 (match_operand:SI 3 "immediate_operand" "n")
11927 (match_operand:SI 4 "immediate_operand" "n")
11928 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11929 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11931 arm_const_bounds (operands[0], 0, 16);
11932 arm_const_bounds (operands[1], 0, 16);
11933 arm_const_bounds (operands[2], 0, (1 << 5));
11934 arm_const_bounds (operands[3], 0, (1 << 5));
11935 arm_const_bounds (operands[4], 0, (1 << 5));
11936 arm_const_bounds (operands[5], 0, 8);
11937 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11939 [(set_attr "length" "4")
11940 (set_attr "type" "coproc")])
11942 (define_insn "*ldc"
11943 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11944 (match_operand:SI 1 "immediate_operand" "n")
11945 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11946 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11948 arm_const_bounds (operands[0], 0, 16);
11949 arm_const_bounds (operands[1], 0, (1 << 5));
11950 return "<ldc>\\tp%c0, CR%c1, %2";
11952 [(set_attr "length" "4")
11953 (set_attr "type" "coproc")])
11955 (define_insn "*stc"
11956 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11957 (match_operand:SI 1 "immediate_operand" "n")
11958 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11959 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11961 arm_const_bounds (operands[0], 0, 16);
11962 arm_const_bounds (operands[1], 0, (1 << 5));
11963 return "<stc>\\tp%c0, CR%c1, %2";
11965 [(set_attr "length" "4")
11966 (set_attr "type" "coproc")])
11968 (define_expand "<ldc>"
11969 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11970 (match_operand:SI 1 "immediate_operand")
11971 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11972 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11974 (define_expand "<stc>"
11975 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11976 (match_operand:SI 1 "immediate_operand")
11977 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11978 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
11980 (define_insn "<mcr>"
11981 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11982 (match_operand:SI 1 "immediate_operand" "n")
11983 (match_operand:SI 2 "s_register_operand" "r")
11984 (match_operand:SI 3 "immediate_operand" "n")
11985 (match_operand:SI 4 "immediate_operand" "n")
11986 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
11987 (use (match_dup 2))]
11988 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
11990 arm_const_bounds (operands[0], 0, 16);
11991 arm_const_bounds (operands[1], 0, 8);
11992 arm_const_bounds (operands[3], 0, (1 << 5));
11993 arm_const_bounds (operands[4], 0, (1 << 5));
11994 arm_const_bounds (operands[5], 0, 8);
11995 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
11997 [(set_attr "length" "4")
11998 (set_attr "type" "coproc")])
12000 (define_insn "<mrc>"
12001 [(set (match_operand:SI 0 "s_register_operand" "=r")
12002 (unspec_volatile [(match_operand:SI 1 "immediate_operand" "n")
12003 (match_operand:SI 2 "immediate_operand" "n")
12004 (match_operand:SI 3 "immediate_operand" "n")
12005 (match_operand:SI 4 "immediate_operand" "n")
12006 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12007 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12009 arm_const_bounds (operands[1], 0, 16);
12010 arm_const_bounds (operands[2], 0, 8);
12011 arm_const_bounds (operands[3], 0, (1 << 5));
12012 arm_const_bounds (operands[4], 0, (1 << 5));
12013 arm_const_bounds (operands[5], 0, 8);
12014 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12016 [(set_attr "length" "4")
12017 (set_attr "type" "coproc")])
12019 (define_insn "<mcrr>"
12020 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12021 (match_operand:SI 1 "immediate_operand" "n")
12022 (match_operand:DI 2 "s_register_operand" "r")
12023 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12024 (use (match_dup 2))]
12025 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12027 arm_const_bounds (operands[0], 0, 16);
12028 arm_const_bounds (operands[1], 0, 8);
12029 arm_const_bounds (operands[3], 0, (1 << 5));
12030 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12032 [(set_attr "length" "4")
12033 (set_attr "type" "coproc")])
12035 (define_insn "<mrrc>"
12036 [(set (match_operand:DI 0 "s_register_operand" "=r")
12037 (unspec_volatile [(match_operand:SI 1 "immediate_operand" "n")
12038 (match_operand:SI 2 "immediate_operand" "n")
12039 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12040 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12042 arm_const_bounds (operands[1], 0, 16);
12043 arm_const_bounds (operands[2], 0, 8);
12044 arm_const_bounds (operands[3], 0, (1 << 5));
12045 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12047 [(set_attr "length" "4")
12048 (set_attr "type" "coproc")])
12050 ;; Vector bits common to IWMMXT and Neon
12051 (include "vec-common.md")
12052 ;; Load the Intel Wireless Multimedia Extension patterns
12053 (include "iwmmxt.md")
12054 ;; Load the VFP co-processor patterns
12056 ;; Thumb-1 patterns
12057 (include "thumb1.md")
12058 ;; Thumb-2 patterns
12059 (include "thumb2.md")
12061 (include "neon.md")
12063 (include "crypto.md")
12064 ;; Synchronization Primitives
12065 (include "sync.md")
12066 ;; Fixed-point patterns
12067 (include "arm-fixed.md")