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 (eq_attr "arch_enabled" "no")
238 (const_string "yes")))
240 ; POOL_RANGE is how far away from a constant pool entry that this insn
241 ; can be placed. If the distance is zero, then this insn will never
242 ; reference the pool.
243 ; Note that for Thumb constant pools the PC value is rounded down to the
244 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
245 ; Thumb insns) should be set to <max_range> - 2.
246 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
247 ; before its address. It is set to <max_range> - (8 + <data_size>).
248 (define_attr "arm_pool_range" "" (const_int 0))
249 (define_attr "thumb2_pool_range" "" (const_int 0))
250 (define_attr "arm_neg_pool_range" "" (const_int 0))
251 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
253 (define_attr "pool_range" ""
254 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
255 (attr "arm_pool_range")))
256 (define_attr "neg_pool_range" ""
257 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
258 (attr "arm_neg_pool_range")))
260 ; An assembler sequence may clobber the condition codes without us knowing.
261 ; If such an insn references the pool, then we have no way of knowing how,
262 ; so use the most conservative value for pool_range.
263 (define_asm_attributes
264 [(set_attr "conds" "clob")
265 (set_attr "length" "4")
266 (set_attr "pool_range" "250")])
268 ; Load scheduling, set from the arm_ld_sched variable
269 ; initialized by arm_option_override()
270 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
272 ; condition codes: this one is used by final_prescan_insn to speed up
273 ; conditionalizing instructions. It saves having to scan the rtl to see if
274 ; it uses or alters the condition codes.
276 ; USE means that the condition codes are used by the insn in the process of
277 ; outputting code, this means (at present) that we can't use the insn in
280 ; SET means that the purpose of the insn is to set the condition codes in a
281 ; well defined manner.
283 ; CLOB means that the condition codes are altered in an undefined manner, if
284 ; they are altered at all
286 ; UNCONDITIONAL means the instruction can not be conditionally executed and
287 ; that the instruction does not use or alter the condition codes.
289 ; NOCOND means that the instruction does not use or alter the condition
290 ; codes but can be converted into a conditionally exectuted instruction.
292 (define_attr "conds" "use,set,clob,unconditional,nocond"
294 (ior (eq_attr "is_thumb1" "yes")
295 (eq_attr "type" "call"))
296 (const_string "clob")
297 (if_then_else (eq_attr "is_neon_type" "no")
298 (const_string "nocond")
299 (const_string "unconditional"))))
301 ; Predicable means that the insn can be conditionally executed based on
302 ; an automatically added predicate (additional patterns are generated by
303 ; gen...). We default to 'no' because no Thumb patterns match this rule
304 ; and not all ARM patterns do.
305 (define_attr "predicable" "no,yes" (const_string "no"))
307 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
308 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
309 ; suffer blockages enough to warrant modelling this (and it can adversely
310 ; affect the schedule).
311 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
313 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
314 ; to stall the processor. Used with model_wbuf above.
315 (define_attr "write_conflict" "no,yes"
316 (if_then_else (eq_attr "type"
319 (const_string "no")))
321 ; Classify the insns into those that take one cycle and those that take more
322 ; than one on the main cpu execution unit.
323 (define_attr "core_cycles" "single,multi"
324 (if_then_else (eq_attr "type"
325 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
326 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
327 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
328 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
329 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
330 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
331 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
332 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
333 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
334 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
335 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
336 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
337 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
338 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
339 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
340 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
341 (const_string "single")
342 (const_string "multi")))
344 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
345 ;; distant label. Only applicable to Thumb code.
346 (define_attr "far_jump" "yes,no" (const_string "no"))
349 ;; The number of machine instructions this pattern expands to.
350 ;; Used for Thumb-2 conditional execution.
351 (define_attr "ce_count" "" (const_int 1))
353 ;;---------------------------------------------------------------------------
356 (include "unspecs.md")
358 ;;---------------------------------------------------------------------------
361 (include "iterators.md")
363 ;;---------------------------------------------------------------------------
366 (include "predicates.md")
367 (include "constraints.md")
369 ;;---------------------------------------------------------------------------
370 ;; Pipeline descriptions
372 (define_attr "tune_cortexr4" "yes,no"
374 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
376 (const_string "no"))))
378 ;; True if the generic scheduling description should be used.
380 (define_attr "generic_sched" "yes,no"
382 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
383 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
384 arm1136jfs,cortexa5,cortexa7,cortexa8,\
385 cortexa9,cortexa12,cortexa15,cortexa17,\
386 cortexa53,cortexa57,cortexm4,cortexm7,\
387 exynosm1,marvell_pj4,xgene1")
388 (eq_attr "tune_cortexr4" "yes"))
390 (const_string "yes"))))
392 (define_attr "generic_vfp" "yes,no"
394 (and (eq_attr "fpu" "vfp")
395 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
396 cortexa8,cortexa9,cortexa53,cortexm4,\
397 cortexm7,marvell_pj4,xgene1")
398 (eq_attr "tune_cortexr4" "no"))
400 (const_string "no"))))
402 (include "marvell-f-iwmmxt.md")
403 (include "arm-generic.md")
404 (include "arm926ejs.md")
405 (include "arm1020e.md")
406 (include "arm1026ejs.md")
407 (include "arm1136jfs.md")
409 (include "fa606te.md")
410 (include "fa626te.md")
411 (include "fmp626.md")
412 (include "fa726te.md")
413 (include "cortex-a5.md")
414 (include "cortex-a7.md")
415 (include "cortex-a8.md")
416 (include "cortex-a9.md")
417 (include "cortex-a15.md")
418 (include "cortex-a17.md")
419 (include "cortex-a53.md")
420 (include "cortex-a57.md")
421 (include "cortex-r4.md")
422 (include "cortex-r4f.md")
423 (include "cortex-m7.md")
424 (include "cortex-m4.md")
425 (include "cortex-m4-fpu.md")
426 (include "exynos-m1.md")
428 (include "marvell-pj4.md")
429 (include "xgene1.md")
432 ;;---------------------------------------------------------------------------
437 ;; Note: For DImode insns, there is normally no reason why operands should
438 ;; not be in the same register, what we don't want is for something being
439 ;; written to partially overlap something that is an input.
441 (define_expand "adddi3"
443 [(set (match_operand:DI 0 "s_register_operand" "")
444 (plus:DI (match_operand:DI 1 "s_register_operand" "")
445 (match_operand:DI 2 "arm_adddi_operand" "")))
446 (clobber (reg:CC CC_REGNUM))])]
451 if (!REG_P (operands[1]))
452 operands[1] = force_reg (DImode, operands[1]);
453 if (!REG_P (operands[2]))
454 operands[2] = force_reg (DImode, operands[2]);
459 (define_insn_and_split "*arm_adddi3"
460 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r,&r,&r")
461 (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r")
462 (match_operand:DI 2 "arm_general_adddi_operand" "r, 0, r, Dd, Dd")))
463 (clobber (reg:CC CC_REGNUM))]
464 "TARGET_32BIT && !TARGET_NEON"
466 "TARGET_32BIT && ((!TARGET_NEON && !TARGET_IWMMXT) || reload_completed)"
467 [(parallel [(set (reg:CC_C CC_REGNUM)
468 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
470 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
471 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
472 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
475 operands[3] = gen_highpart (SImode, operands[0]);
476 operands[0] = gen_lowpart (SImode, operands[0]);
477 operands[4] = gen_highpart (SImode, operands[1]);
478 operands[1] = gen_lowpart (SImode, operands[1]);
479 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
480 operands[2] = gen_lowpart (SImode, operands[2]);
482 [(set_attr "conds" "clob")
483 (set_attr "length" "8")
484 (set_attr "type" "multiple")]
487 (define_insn_and_split "*adddi_sesidi_di"
488 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
489 (plus:DI (sign_extend:DI
490 (match_operand:SI 2 "s_register_operand" "r,r"))
491 (match_operand:DI 1 "s_register_operand" "0,r")))
492 (clobber (reg:CC CC_REGNUM))]
495 "TARGET_32BIT && reload_completed"
496 [(parallel [(set (reg:CC_C CC_REGNUM)
497 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
499 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
500 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
503 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
506 operands[3] = gen_highpart (SImode, operands[0]);
507 operands[0] = gen_lowpart (SImode, operands[0]);
508 operands[4] = gen_highpart (SImode, operands[1]);
509 operands[1] = gen_lowpart (SImode, operands[1]);
510 operands[2] = gen_lowpart (SImode, operands[2]);
512 [(set_attr "conds" "clob")
513 (set_attr "length" "8")
514 (set_attr "type" "multiple")]
517 (define_insn_and_split "*adddi_zesidi_di"
518 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
519 (plus:DI (zero_extend:DI
520 (match_operand:SI 2 "s_register_operand" "r,r"))
521 (match_operand:DI 1 "s_register_operand" "0,r")))
522 (clobber (reg:CC CC_REGNUM))]
525 "TARGET_32BIT && reload_completed"
526 [(parallel [(set (reg:CC_C CC_REGNUM)
527 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
529 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
530 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
531 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
534 operands[3] = gen_highpart (SImode, operands[0]);
535 operands[0] = gen_lowpart (SImode, operands[0]);
536 operands[4] = gen_highpart (SImode, operands[1]);
537 operands[1] = gen_lowpart (SImode, operands[1]);
538 operands[2] = gen_lowpart (SImode, operands[2]);
540 [(set_attr "conds" "clob")
541 (set_attr "length" "8")
542 (set_attr "type" "multiple")]
545 (define_expand "addv<mode>4"
546 [(match_operand:SIDI 0 "register_operand")
547 (match_operand:SIDI 1 "register_operand")
548 (match_operand:SIDI 2 "register_operand")
549 (match_operand 3 "")]
552 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
553 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
558 (define_expand "uaddv<mode>4"
559 [(match_operand:SIDI 0 "register_operand")
560 (match_operand:SIDI 1 "register_operand")
561 (match_operand:SIDI 2 "register_operand")
562 (match_operand 3 "")]
565 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
566 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
571 (define_expand "addsi3"
572 [(set (match_operand:SI 0 "s_register_operand" "")
573 (plus:SI (match_operand:SI 1 "s_register_operand" "")
574 (match_operand:SI 2 "reg_or_int_operand" "")))]
577 if (TARGET_32BIT && CONST_INT_P (operands[2]))
579 arm_split_constant (PLUS, SImode, NULL_RTX,
580 INTVAL (operands[2]), operands[0], operands[1],
581 optimize && can_create_pseudo_p ());
587 ; If there is a scratch available, this will be faster than synthesizing the
590 [(match_scratch:SI 3 "r")
591 (set (match_operand:SI 0 "arm_general_register_operand" "")
592 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
593 (match_operand:SI 2 "const_int_operand" "")))]
595 !(const_ok_for_arm (INTVAL (operands[2]))
596 || const_ok_for_arm (-INTVAL (operands[2])))
597 && const_ok_for_arm (~INTVAL (operands[2]))"
598 [(set (match_dup 3) (match_dup 2))
599 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
603 ;; The r/r/k alternative is required when reloading the address
604 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
605 ;; put the duplicated register first, and not try the commutative version.
606 (define_insn_and_split "*arm_addsi3"
607 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
608 (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")
609 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
625 subw%?\\t%0, %1, #%n2
626 subw%?\\t%0, %1, #%n2
629 && CONST_INT_P (operands[2])
630 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
631 && (reload_completed || !arm_eliminable_register (operands[1]))"
632 [(clobber (const_int 0))]
634 arm_split_constant (PLUS, SImode, curr_insn,
635 INTVAL (operands[2]), operands[0],
639 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
640 (set_attr "predicable" "yes")
641 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
642 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
643 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
644 (const_string "alu_imm")
645 (const_string "alu_sreg")))
649 (define_insn_and_split "adddi3_compareV"
650 [(set (reg:CC_V CC_REGNUM)
653 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
654 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
655 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
656 (set (match_operand:DI 0 "register_operand" "=&r")
657 (plus:DI (match_dup 1) (match_dup 2)))]
660 "&& reload_completed"
661 [(parallel [(set (reg:CC_C CC_REGNUM)
662 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
664 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
665 (parallel [(set (reg:CC_V CC_REGNUM)
668 (sign_extend:DI (match_dup 4))
669 (sign_extend:DI (match_dup 5)))
670 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
671 (plus:DI (sign_extend:DI
672 (plus:SI (match_dup 4) (match_dup 5)))
673 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
674 (set (match_dup 3) (plus:SI (plus:SI
675 (match_dup 4) (match_dup 5))
676 (ltu:SI (reg:CC_C CC_REGNUM)
680 operands[3] = gen_highpart (SImode, operands[0]);
681 operands[0] = gen_lowpart (SImode, operands[0]);
682 operands[4] = gen_highpart (SImode, operands[1]);
683 operands[1] = gen_lowpart (SImode, operands[1]);
684 operands[5] = gen_highpart (SImode, operands[2]);
685 operands[2] = gen_lowpart (SImode, operands[2]);
687 [(set_attr "conds" "set")
688 (set_attr "length" "8")
689 (set_attr "type" "multiple")]
692 (define_insn "addsi3_compareV"
693 [(set (reg:CC_V CC_REGNUM)
696 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
697 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
698 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
699 (set (match_operand:SI 0 "register_operand" "=r")
700 (plus:SI (match_dup 1) (match_dup 2)))]
702 "adds%?\\t%0, %1, %2"
703 [(set_attr "conds" "set")
704 (set_attr "type" "alus_sreg")]
707 (define_insn "*addsi3_compareV_upper"
708 [(set (reg:CC_V CC_REGNUM)
712 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
713 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
714 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
715 (plus:DI (sign_extend:DI
716 (plus:SI (match_dup 1) (match_dup 2)))
717 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
718 (set (match_operand:SI 0 "register_operand" "=r")
720 (plus:SI (match_dup 1) (match_dup 2))
721 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
723 "adcs%?\\t%0, %1, %2"
724 [(set_attr "conds" "set")
725 (set_attr "type" "adcs_reg")]
728 (define_insn_and_split "adddi3_compareC"
729 [(set (reg:CC_C CC_REGNUM)
732 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
733 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
734 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
735 (set (match_operand:DI 0 "register_operand" "=&r")
736 (plus:DI (match_dup 1) (match_dup 2)))]
739 "&& reload_completed"
740 [(parallel [(set (reg:CC_C CC_REGNUM)
741 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
743 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
744 (parallel [(set (reg:CC_C CC_REGNUM)
747 (zero_extend:DI (match_dup 4))
748 (zero_extend:DI (match_dup 5)))
749 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
750 (plus:DI (zero_extend:DI
751 (plus:SI (match_dup 4) (match_dup 5)))
752 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
753 (set (match_dup 3) (plus:SI
754 (plus:SI (match_dup 4) (match_dup 5))
755 (ltu:SI (reg:CC_C CC_REGNUM)
759 operands[3] = gen_highpart (SImode, operands[0]);
760 operands[0] = gen_lowpart (SImode, operands[0]);
761 operands[4] = gen_highpart (SImode, operands[1]);
762 operands[5] = gen_highpart (SImode, operands[2]);
763 operands[1] = gen_lowpart (SImode, operands[1]);
764 operands[2] = gen_lowpart (SImode, operands[2]);
766 [(set_attr "conds" "set")
767 (set_attr "length" "8")
768 (set_attr "type" "multiple")]
771 (define_insn "*addsi3_compareC_upper"
772 [(set (reg:CC_C CC_REGNUM)
776 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
777 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
778 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
779 (plus:DI (zero_extend:DI
780 (plus:SI (match_dup 1) (match_dup 2)))
781 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
782 (set (match_operand:SI 0 "register_operand" "=r")
784 (plus:SI (match_dup 1) (match_dup 2))
785 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
787 "adcs%?\\t%0, %1, %2"
788 [(set_attr "conds" "set")
789 (set_attr "type" "adcs_reg")]
792 (define_insn "addsi3_compareC"
793 [(set (reg:CC_C CC_REGNUM)
796 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
797 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
799 (plus:SI (match_dup 1) (match_dup 2)))))
800 (set (match_operand:SI 0 "register_operand" "=r")
801 (plus:SI (match_dup 1) (match_dup 2)))]
803 "adds%?\\t%0, %1, %2"
804 [(set_attr "conds" "set")
805 (set_attr "type" "alus_sreg")]
808 (define_insn "addsi3_compare0"
809 [(set (reg:CC_NOOV CC_REGNUM)
811 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
812 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
814 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
815 (plus:SI (match_dup 1) (match_dup 2)))]
819 subs%?\\t%0, %1, #%n2
821 [(set_attr "conds" "set")
822 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
825 (define_insn "*addsi3_compare0_scratch"
826 [(set (reg:CC_NOOV CC_REGNUM)
828 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
829 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
836 [(set_attr "conds" "set")
837 (set_attr "predicable" "yes")
838 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
841 (define_insn "*compare_negsi_si"
842 [(set (reg:CC_Z CC_REGNUM)
844 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
845 (match_operand:SI 1 "s_register_operand" "l,r")))]
848 [(set_attr "conds" "set")
849 (set_attr "predicable" "yes")
850 (set_attr "arch" "t2,*")
851 (set_attr "length" "2,4")
852 (set_attr "predicable_short_it" "yes,no")
853 (set_attr "type" "alus_sreg")]
856 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
857 ;; addend is a constant.
858 (define_insn "cmpsi2_addneg"
859 [(set (reg:CC CC_REGNUM)
861 (match_operand:SI 1 "s_register_operand" "r,r")
862 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
863 (set (match_operand:SI 0 "s_register_operand" "=r,r")
864 (plus:SI (match_dup 1)
865 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
866 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
869 subs%?\\t%0, %1, #%n3"
870 [(set_attr "conds" "set")
871 (set_attr "type" "alus_sreg")]
874 ;; Convert the sequence
876 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
880 ;; bcs dest ((unsigned)rn >= 1)
881 ;; similarly for the beq variant using bcc.
882 ;; This is a common looping idiom (while (n--))
884 [(set (match_operand:SI 0 "arm_general_register_operand" "")
885 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
887 (set (match_operand 2 "cc_register" "")
888 (compare (match_dup 0) (const_int -1)))
890 (if_then_else (match_operator 3 "equality_operator"
891 [(match_dup 2) (const_int 0)])
892 (match_operand 4 "" "")
893 (match_operand 5 "" "")))]
894 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
898 (match_dup 1) (const_int 1)))
899 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
901 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
904 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
905 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
908 operands[2], const0_rtx);"
911 ;; The next four insns work because they compare the result with one of
912 ;; the operands, and we know that the use of the condition code is
913 ;; either GEU or LTU, so we can use the carry flag from the addition
914 ;; instead of doing the compare a second time.
915 (define_insn "*addsi3_compare_op1"
916 [(set (reg:CC_C CC_REGNUM)
918 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
919 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
921 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
922 (plus:SI (match_dup 1) (match_dup 2)))]
926 subs%?\\t%0, %1, #%n2
928 [(set_attr "conds" "set")
929 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
932 (define_insn "*addsi3_compare_op2"
933 [(set (reg:CC_C CC_REGNUM)
935 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
936 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
938 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
939 (plus:SI (match_dup 1) (match_dup 2)))]
943 subs%?\\t%0, %1, #%n2
945 [(set_attr "conds" "set")
946 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
949 (define_insn "*compare_addsi2_op0"
950 [(set (reg:CC_C CC_REGNUM)
952 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
953 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
962 [(set_attr "conds" "set")
963 (set_attr "predicable" "yes")
964 (set_attr "arch" "t2,t2,*,*,*")
965 (set_attr "predicable_short_it" "yes,yes,no,no,no")
966 (set_attr "length" "2,2,4,4,4")
967 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
970 (define_insn "*compare_addsi2_op1"
971 [(set (reg:CC_C CC_REGNUM)
973 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
974 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
983 [(set_attr "conds" "set")
984 (set_attr "predicable" "yes")
985 (set_attr "arch" "t2,t2,*,*,*")
986 (set_attr "predicable_short_it" "yes,yes,no,no,no")
987 (set_attr "length" "2,2,4,4,4")
988 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
991 (define_insn "*addsi3_carryin_<optab>"
992 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
993 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
994 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
995 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1000 sbc%?\\t%0, %1, #%B2"
1001 [(set_attr "conds" "use")
1002 (set_attr "predicable" "yes")
1003 (set_attr "arch" "t2,*,*")
1004 (set_attr "length" "4")
1005 (set_attr "predicable_short_it" "yes,no,no")
1006 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1009 (define_insn "*addsi3_carryin_alt2_<optab>"
1010 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1011 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1012 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1013 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1018 sbc%?\\t%0, %1, #%B2"
1019 [(set_attr "conds" "use")
1020 (set_attr "predicable" "yes")
1021 (set_attr "arch" "t2,*,*")
1022 (set_attr "length" "4")
1023 (set_attr "predicable_short_it" "yes,no,no")
1024 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1027 (define_insn "*addsi3_carryin_shift_<optab>"
1028 [(set (match_operand:SI 0 "s_register_operand" "=r")
1030 (match_operator:SI 2 "shift_operator"
1031 [(match_operand:SI 3 "s_register_operand" "r")
1032 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1033 (match_operand:SI 1 "s_register_operand" "r"))
1034 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1036 "adc%?\\t%0, %1, %3%S2"
1037 [(set_attr "conds" "use")
1038 (set_attr "predicable" "yes")
1039 (set_attr "predicable_short_it" "no")
1040 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1041 (const_string "alu_shift_imm")
1042 (const_string "alu_shift_reg")))]
1045 (define_insn "*addsi3_carryin_clobercc_<optab>"
1046 [(set (match_operand:SI 0 "s_register_operand" "=r")
1047 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1048 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1049 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1050 (clobber (reg:CC CC_REGNUM))]
1052 "adcs%?\\t%0, %1, %2"
1053 [(set_attr "conds" "set")
1054 (set_attr "type" "adcs_reg")]
1057 (define_expand "subv<mode>4"
1058 [(match_operand:SIDI 0 "register_operand")
1059 (match_operand:SIDI 1 "register_operand")
1060 (match_operand:SIDI 2 "register_operand")
1061 (match_operand 3 "")]
1064 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1065 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1070 (define_expand "usubv<mode>4"
1071 [(match_operand:SIDI 0 "register_operand")
1072 (match_operand:SIDI 1 "register_operand")
1073 (match_operand:SIDI 2 "register_operand")
1074 (match_operand 3 "")]
1077 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1078 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1083 (define_insn_and_split "subdi3_compare1"
1084 [(set (reg:CC CC_REGNUM)
1086 (match_operand:DI 1 "register_operand" "r")
1087 (match_operand:DI 2 "register_operand" "r")))
1088 (set (match_operand:DI 0 "register_operand" "=&r")
1089 (minus:DI (match_dup 1) (match_dup 2)))]
1092 "&& reload_completed"
1093 [(parallel [(set (reg:CC CC_REGNUM)
1094 (compare:CC (match_dup 1) (match_dup 2)))
1095 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1096 (parallel [(set (reg:CC CC_REGNUM)
1097 (compare:CC (match_dup 4) (match_dup 5)))
1098 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1099 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1101 operands[3] = gen_highpart (SImode, operands[0]);
1102 operands[0] = gen_lowpart (SImode, operands[0]);
1103 operands[4] = gen_highpart (SImode, operands[1]);
1104 operands[1] = gen_lowpart (SImode, operands[1]);
1105 operands[5] = gen_highpart (SImode, operands[2]);
1106 operands[2] = gen_lowpart (SImode, operands[2]);
1108 [(set_attr "conds" "set")
1109 (set_attr "length" "8")
1110 (set_attr "type" "multiple")]
1113 (define_insn "subsi3_compare1"
1114 [(set (reg:CC CC_REGNUM)
1116 (match_operand:SI 1 "register_operand" "r")
1117 (match_operand:SI 2 "register_operand" "r")))
1118 (set (match_operand:SI 0 "register_operand" "=r")
1119 (minus:SI (match_dup 1) (match_dup 2)))]
1121 "subs%?\\t%0, %1, %2"
1122 [(set_attr "conds" "set")
1123 (set_attr "type" "alus_sreg")]
1126 (define_insn "*subsi3_carryin"
1127 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1128 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1129 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1130 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1135 sbc%?\\t%0, %2, %2, lsl #1"
1136 [(set_attr "conds" "use")
1137 (set_attr "arch" "*,a,t2")
1138 (set_attr "predicable" "yes")
1139 (set_attr "predicable_short_it" "no")
1140 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1143 (define_insn "*subsi3_carryin_const"
1144 [(set (match_operand:SI 0 "s_register_operand" "=r")
1145 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1146 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1147 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1149 "sbc\\t%0, %1, #%B2"
1150 [(set_attr "conds" "use")
1151 (set_attr "type" "adc_imm")]
1154 (define_insn "*subsi3_carryin_compare"
1155 [(set (reg:CC CC_REGNUM)
1156 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1157 (match_operand:SI 2 "s_register_operand" "r")))
1158 (set (match_operand:SI 0 "s_register_operand" "=r")
1159 (minus:SI (minus:SI (match_dup 1)
1161 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1164 [(set_attr "conds" "set")
1165 (set_attr "type" "adcs_reg")]
1168 (define_insn "*subsi3_carryin_compare_const"
1169 [(set (reg:CC CC_REGNUM)
1170 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1171 (match_operand:SI 2 "arm_not_operand" "K")))
1172 (set (match_operand:SI 0 "s_register_operand" "=r")
1173 (minus:SI (plus:SI (match_dup 1)
1175 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1177 "sbcs\\t%0, %1, #%B2"
1178 [(set_attr "conds" "set")
1179 (set_attr "type" "adcs_imm")]
1182 (define_insn "*subsi3_carryin_shift"
1183 [(set (match_operand:SI 0 "s_register_operand" "=r")
1185 (match_operand:SI 1 "s_register_operand" "r")
1186 (match_operator:SI 2 "shift_operator"
1187 [(match_operand:SI 3 "s_register_operand" "r")
1188 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1189 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1191 "sbc%?\\t%0, %1, %3%S2"
1192 [(set_attr "conds" "use")
1193 (set_attr "predicable" "yes")
1194 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1195 (const_string "alu_shift_imm")
1196 (const_string "alu_shift_reg")))]
1199 (define_insn "*rsbsi3_carryin_shift"
1200 [(set (match_operand:SI 0 "s_register_operand" "=r")
1202 (match_operator:SI 2 "shift_operator"
1203 [(match_operand:SI 3 "s_register_operand" "r")
1204 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1205 (match_operand:SI 1 "s_register_operand" "r"))
1206 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1208 "rsc%?\\t%0, %1, %3%S2"
1209 [(set_attr "conds" "use")
1210 (set_attr "predicable" "yes")
1211 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1212 (const_string "alu_shift_imm")
1213 (const_string "alu_shift_reg")))]
1216 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1218 [(set (match_operand:SI 0 "s_register_operand" "")
1219 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1220 (match_operand:SI 2 "s_register_operand" ""))
1222 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1224 [(set (match_dup 3) (match_dup 1))
1225 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1227 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1230 (define_expand "addsf3"
1231 [(set (match_operand:SF 0 "s_register_operand" "")
1232 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1233 (match_operand:SF 2 "s_register_operand" "")))]
1234 "TARGET_32BIT && TARGET_HARD_FLOAT"
1238 (define_expand "adddf3"
1239 [(set (match_operand:DF 0 "s_register_operand" "")
1240 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1241 (match_operand:DF 2 "s_register_operand" "")))]
1242 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1246 (define_expand "subdi3"
1248 [(set (match_operand:DI 0 "s_register_operand" "")
1249 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1250 (match_operand:DI 2 "s_register_operand" "")))
1251 (clobber (reg:CC CC_REGNUM))])]
1256 if (!REG_P (operands[1]))
1257 operands[1] = force_reg (DImode, operands[1]);
1258 if (!REG_P (operands[2]))
1259 operands[2] = force_reg (DImode, operands[2]);
1264 (define_insn_and_split "*arm_subdi3"
1265 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
1266 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1267 (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1268 (clobber (reg:CC CC_REGNUM))]
1269 "TARGET_32BIT && !TARGET_NEON"
1270 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1271 "&& (!TARGET_IWMMXT || reload_completed)"
1272 [(parallel [(set (reg:CC CC_REGNUM)
1273 (compare:CC (match_dup 1) (match_dup 2)))
1274 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1275 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1276 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1278 operands[3] = gen_highpart (SImode, operands[0]);
1279 operands[0] = gen_lowpart (SImode, operands[0]);
1280 operands[4] = gen_highpart (SImode, operands[1]);
1281 operands[1] = gen_lowpart (SImode, operands[1]);
1282 operands[5] = gen_highpart (SImode, operands[2]);
1283 operands[2] = gen_lowpart (SImode, operands[2]);
1285 [(set_attr "conds" "clob")
1286 (set_attr "length" "8")
1287 (set_attr "type" "multiple")]
1290 (define_insn_and_split "*subdi_di_zesidi"
1291 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1292 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1294 (match_operand:SI 2 "s_register_operand" "r,r"))))
1295 (clobber (reg:CC CC_REGNUM))]
1297 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1298 "&& reload_completed"
1299 [(parallel [(set (reg:CC CC_REGNUM)
1300 (compare:CC (match_dup 1) (match_dup 2)))
1301 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1302 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1303 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1305 operands[3] = gen_highpart (SImode, operands[0]);
1306 operands[0] = gen_lowpart (SImode, operands[0]);
1307 operands[4] = gen_highpart (SImode, operands[1]);
1308 operands[1] = gen_lowpart (SImode, operands[1]);
1309 operands[5] = GEN_INT (~0);
1311 [(set_attr "conds" "clob")
1312 (set_attr "length" "8")
1313 (set_attr "type" "multiple")]
1316 (define_insn_and_split "*subdi_di_sesidi"
1317 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1318 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1320 (match_operand:SI 2 "s_register_operand" "r,r"))))
1321 (clobber (reg:CC CC_REGNUM))]
1323 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1324 "&& reload_completed"
1325 [(parallel [(set (reg:CC CC_REGNUM)
1326 (compare:CC (match_dup 1) (match_dup 2)))
1327 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1328 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1329 (ashiftrt:SI (match_dup 2)
1331 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1333 operands[3] = gen_highpart (SImode, operands[0]);
1334 operands[0] = gen_lowpart (SImode, operands[0]);
1335 operands[4] = gen_highpart (SImode, operands[1]);
1336 operands[1] = gen_lowpart (SImode, operands[1]);
1338 [(set_attr "conds" "clob")
1339 (set_attr "length" "8")
1340 (set_attr "type" "multiple")]
1343 (define_insn_and_split "*subdi_zesidi_di"
1344 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1345 (minus:DI (zero_extend:DI
1346 (match_operand:SI 2 "s_register_operand" "r,r"))
1347 (match_operand:DI 1 "s_register_operand" "0,r")))
1348 (clobber (reg:CC CC_REGNUM))]
1350 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1352 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1353 "&& reload_completed"
1354 [(parallel [(set (reg:CC CC_REGNUM)
1355 (compare:CC (match_dup 2) (match_dup 1)))
1356 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1357 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1358 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1360 operands[3] = gen_highpart (SImode, operands[0]);
1361 operands[0] = gen_lowpart (SImode, operands[0]);
1362 operands[4] = gen_highpart (SImode, operands[1]);
1363 operands[1] = gen_lowpart (SImode, operands[1]);
1365 [(set_attr "conds" "clob")
1366 (set_attr "length" "8")
1367 (set_attr "type" "multiple")]
1370 (define_insn_and_split "*subdi_sesidi_di"
1371 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1372 (minus:DI (sign_extend:DI
1373 (match_operand:SI 2 "s_register_operand" "r,r"))
1374 (match_operand:DI 1 "s_register_operand" "0,r")))
1375 (clobber (reg:CC CC_REGNUM))]
1377 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1379 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1380 "&& reload_completed"
1381 [(parallel [(set (reg:CC CC_REGNUM)
1382 (compare:CC (match_dup 2) (match_dup 1)))
1383 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1384 (set (match_dup 3) (minus:SI (minus:SI
1385 (ashiftrt:SI (match_dup 2)
1388 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1390 operands[3] = gen_highpart (SImode, operands[0]);
1391 operands[0] = gen_lowpart (SImode, operands[0]);
1392 operands[4] = gen_highpart (SImode, operands[1]);
1393 operands[1] = gen_lowpart (SImode, operands[1]);
1395 [(set_attr "conds" "clob")
1396 (set_attr "length" "8")
1397 (set_attr "type" "multiple")]
1400 (define_insn_and_split "*subdi_zesidi_zesidi"
1401 [(set (match_operand:DI 0 "s_register_operand" "=r")
1402 (minus:DI (zero_extend:DI
1403 (match_operand:SI 1 "s_register_operand" "r"))
1405 (match_operand:SI 2 "s_register_operand" "r"))))
1406 (clobber (reg:CC CC_REGNUM))]
1408 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1409 "&& reload_completed"
1410 [(parallel [(set (reg:CC CC_REGNUM)
1411 (compare:CC (match_dup 1) (match_dup 2)))
1412 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1413 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1414 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1416 operands[3] = gen_highpart (SImode, operands[0]);
1417 operands[0] = gen_lowpart (SImode, operands[0]);
1419 [(set_attr "conds" "clob")
1420 (set_attr "length" "8")
1421 (set_attr "type" "multiple")]
1424 (define_expand "subsi3"
1425 [(set (match_operand:SI 0 "s_register_operand" "")
1426 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1427 (match_operand:SI 2 "s_register_operand" "")))]
1430 if (CONST_INT_P (operands[1]))
1434 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1435 operands[1] = force_reg (SImode, operands[1]);
1438 arm_split_constant (MINUS, SImode, NULL_RTX,
1439 INTVAL (operands[1]), operands[0],
1441 optimize && can_create_pseudo_p ());
1445 else /* TARGET_THUMB1 */
1446 operands[1] = force_reg (SImode, operands[1]);
1451 ; ??? Check Thumb-2 split length
1452 (define_insn_and_split "*arm_subsi3_insn"
1453 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1454 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1455 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1467 "&& (CONST_INT_P (operands[1])
1468 && !const_ok_for_arm (INTVAL (operands[1])))"
1469 [(clobber (const_int 0))]
1471 arm_split_constant (MINUS, SImode, curr_insn,
1472 INTVAL (operands[1]), operands[0], operands[2], 0);
1475 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1476 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1477 (set_attr "predicable" "yes")
1478 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1479 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1483 [(match_scratch:SI 3 "r")
1484 (set (match_operand:SI 0 "arm_general_register_operand" "")
1485 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1486 (match_operand:SI 2 "arm_general_register_operand" "")))]
1488 && !const_ok_for_arm (INTVAL (operands[1]))
1489 && const_ok_for_arm (~INTVAL (operands[1]))"
1490 [(set (match_dup 3) (match_dup 1))
1491 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1495 (define_insn "subsi3_compare0"
1496 [(set (reg:CC_NOOV CC_REGNUM)
1498 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1499 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1501 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1502 (minus:SI (match_dup 1) (match_dup 2)))]
1507 rsbs%?\\t%0, %2, %1"
1508 [(set_attr "conds" "set")
1509 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1512 (define_insn "subsi3_compare"
1513 [(set (reg:CC CC_REGNUM)
1514 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1515 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1516 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1517 (minus:SI (match_dup 1) (match_dup 2)))]
1522 rsbs%?\\t%0, %2, %1"
1523 [(set_attr "conds" "set")
1524 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1527 (define_expand "subsf3"
1528 [(set (match_operand:SF 0 "s_register_operand" "")
1529 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1530 (match_operand:SF 2 "s_register_operand" "")))]
1531 "TARGET_32BIT && TARGET_HARD_FLOAT"
1535 (define_expand "subdf3"
1536 [(set (match_operand:DF 0 "s_register_operand" "")
1537 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1538 (match_operand:DF 2 "s_register_operand" "")))]
1539 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1544 ;; Multiplication insns
1546 (define_expand "mulhi3"
1547 [(set (match_operand:HI 0 "s_register_operand" "")
1548 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1549 (match_operand:HI 2 "s_register_operand" "")))]
1550 "TARGET_DSP_MULTIPLY"
1553 rtx result = gen_reg_rtx (SImode);
1554 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1555 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1560 (define_expand "mulsi3"
1561 [(set (match_operand:SI 0 "s_register_operand" "")
1562 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1563 (match_operand:SI 1 "s_register_operand" "")))]
1568 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1569 (define_insn "*arm_mulsi3"
1570 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1571 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1572 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1573 "TARGET_32BIT && !arm_arch6"
1574 "mul%?\\t%0, %2, %1"
1575 [(set_attr "type" "mul")
1576 (set_attr "predicable" "yes")]
1579 (define_insn "*arm_mulsi3_v6"
1580 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1581 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1582 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1583 "TARGET_32BIT && arm_arch6"
1584 "mul%?\\t%0, %1, %2"
1585 [(set_attr "type" "mul")
1586 (set_attr "predicable" "yes")
1587 (set_attr "arch" "t2,t2,*")
1588 (set_attr "length" "4")
1589 (set_attr "predicable_short_it" "yes,yes,no")]
1592 (define_insn "*mulsi3_compare0"
1593 [(set (reg:CC_NOOV CC_REGNUM)
1594 (compare:CC_NOOV (mult:SI
1595 (match_operand:SI 2 "s_register_operand" "r,r")
1596 (match_operand:SI 1 "s_register_operand" "%0,r"))
1598 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1599 (mult:SI (match_dup 2) (match_dup 1)))]
1600 "TARGET_ARM && !arm_arch6"
1601 "muls%?\\t%0, %2, %1"
1602 [(set_attr "conds" "set")
1603 (set_attr "type" "muls")]
1606 (define_insn "*mulsi3_compare0_v6"
1607 [(set (reg:CC_NOOV CC_REGNUM)
1608 (compare:CC_NOOV (mult:SI
1609 (match_operand:SI 2 "s_register_operand" "r")
1610 (match_operand:SI 1 "s_register_operand" "r"))
1612 (set (match_operand:SI 0 "s_register_operand" "=r")
1613 (mult:SI (match_dup 2) (match_dup 1)))]
1614 "TARGET_ARM && arm_arch6 && optimize_size"
1615 "muls%?\\t%0, %2, %1"
1616 [(set_attr "conds" "set")
1617 (set_attr "type" "muls")]
1620 (define_insn "*mulsi_compare0_scratch"
1621 [(set (reg:CC_NOOV CC_REGNUM)
1622 (compare:CC_NOOV (mult:SI
1623 (match_operand:SI 2 "s_register_operand" "r,r")
1624 (match_operand:SI 1 "s_register_operand" "%0,r"))
1626 (clobber (match_scratch:SI 0 "=&r,&r"))]
1627 "TARGET_ARM && !arm_arch6"
1628 "muls%?\\t%0, %2, %1"
1629 [(set_attr "conds" "set")
1630 (set_attr "type" "muls")]
1633 (define_insn "*mulsi_compare0_scratch_v6"
1634 [(set (reg:CC_NOOV CC_REGNUM)
1635 (compare:CC_NOOV (mult:SI
1636 (match_operand:SI 2 "s_register_operand" "r")
1637 (match_operand:SI 1 "s_register_operand" "r"))
1639 (clobber (match_scratch:SI 0 "=r"))]
1640 "TARGET_ARM && arm_arch6 && optimize_size"
1641 "muls%?\\t%0, %2, %1"
1642 [(set_attr "conds" "set")
1643 (set_attr "type" "muls")]
1646 ;; Unnamed templates to match MLA instruction.
1648 (define_insn "*mulsi3addsi"
1649 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1651 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1652 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1653 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1654 "TARGET_32BIT && !arm_arch6"
1655 "mla%?\\t%0, %2, %1, %3"
1656 [(set_attr "type" "mla")
1657 (set_attr "predicable" "yes")]
1660 (define_insn "*mulsi3addsi_v6"
1661 [(set (match_operand:SI 0 "s_register_operand" "=r")
1663 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1664 (match_operand:SI 1 "s_register_operand" "r"))
1665 (match_operand:SI 3 "s_register_operand" "r")))]
1666 "TARGET_32BIT && arm_arch6"
1667 "mla%?\\t%0, %2, %1, %3"
1668 [(set_attr "type" "mla")
1669 (set_attr "predicable" "yes")
1670 (set_attr "predicable_short_it" "no")]
1673 (define_insn "*mulsi3addsi_compare0"
1674 [(set (reg:CC_NOOV CC_REGNUM)
1677 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1678 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1679 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1681 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1682 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1684 "TARGET_ARM && arm_arch6"
1685 "mlas%?\\t%0, %2, %1, %3"
1686 [(set_attr "conds" "set")
1687 (set_attr "type" "mlas")]
1690 (define_insn "*mulsi3addsi_compare0_v6"
1691 [(set (reg:CC_NOOV CC_REGNUM)
1694 (match_operand:SI 2 "s_register_operand" "r")
1695 (match_operand:SI 1 "s_register_operand" "r"))
1696 (match_operand:SI 3 "s_register_operand" "r"))
1698 (set (match_operand:SI 0 "s_register_operand" "=r")
1699 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1701 "TARGET_ARM && arm_arch6 && optimize_size"
1702 "mlas%?\\t%0, %2, %1, %3"
1703 [(set_attr "conds" "set")
1704 (set_attr "type" "mlas")]
1707 (define_insn "*mulsi3addsi_compare0_scratch"
1708 [(set (reg:CC_NOOV CC_REGNUM)
1711 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1712 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1713 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1715 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1716 "TARGET_ARM && !arm_arch6"
1717 "mlas%?\\t%0, %2, %1, %3"
1718 [(set_attr "conds" "set")
1719 (set_attr "type" "mlas")]
1722 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1723 [(set (reg:CC_NOOV CC_REGNUM)
1726 (match_operand:SI 2 "s_register_operand" "r")
1727 (match_operand:SI 1 "s_register_operand" "r"))
1728 (match_operand:SI 3 "s_register_operand" "r"))
1730 (clobber (match_scratch:SI 0 "=r"))]
1731 "TARGET_ARM && arm_arch6 && optimize_size"
1732 "mlas%?\\t%0, %2, %1, %3"
1733 [(set_attr "conds" "set")
1734 (set_attr "type" "mlas")]
1737 (define_insn "*mulsi3subsi"
1738 [(set (match_operand:SI 0 "s_register_operand" "=r")
1740 (match_operand:SI 3 "s_register_operand" "r")
1741 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1742 (match_operand:SI 1 "s_register_operand" "r"))))]
1743 "TARGET_32BIT && arm_arch_thumb2"
1744 "mls%?\\t%0, %2, %1, %3"
1745 [(set_attr "type" "mla")
1746 (set_attr "predicable" "yes")
1747 (set_attr "predicable_short_it" "no")]
1750 (define_expand "maddsidi4"
1751 [(set (match_operand:DI 0 "s_register_operand" "")
1754 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1755 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1756 (match_operand:DI 3 "s_register_operand" "")))]
1757 "TARGET_32BIT && arm_arch3m"
1760 (define_insn "*mulsidi3adddi"
1761 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1764 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1765 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1766 (match_operand:DI 1 "s_register_operand" "0")))]
1767 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1768 "smlal%?\\t%Q0, %R0, %3, %2"
1769 [(set_attr "type" "smlal")
1770 (set_attr "predicable" "yes")]
1773 (define_insn "*mulsidi3adddi_v6"
1774 [(set (match_operand:DI 0 "s_register_operand" "=r")
1777 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1778 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1779 (match_operand:DI 1 "s_register_operand" "0")))]
1780 "TARGET_32BIT && arm_arch6"
1781 "smlal%?\\t%Q0, %R0, %3, %2"
1782 [(set_attr "type" "smlal")
1783 (set_attr "predicable" "yes")
1784 (set_attr "predicable_short_it" "no")]
1787 ;; 32x32->64 widening multiply.
1788 ;; As with mulsi3, the only difference between the v3-5 and v6+
1789 ;; versions of these patterns is the requirement that the output not
1790 ;; overlap the inputs, but that still means we have to have a named
1791 ;; expander and two different starred insns.
1793 (define_expand "mulsidi3"
1794 [(set (match_operand:DI 0 "s_register_operand" "")
1796 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1797 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1798 "TARGET_32BIT && arm_arch3m"
1802 (define_insn "*mulsidi3_nov6"
1803 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1805 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1806 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1807 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1808 "smull%?\\t%Q0, %R0, %1, %2"
1809 [(set_attr "type" "smull")
1810 (set_attr "predicable" "yes")]
1813 (define_insn "*mulsidi3_v6"
1814 [(set (match_operand:DI 0 "s_register_operand" "=r")
1816 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1817 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1818 "TARGET_32BIT && arm_arch6"
1819 "smull%?\\t%Q0, %R0, %1, %2"
1820 [(set_attr "type" "smull")
1821 (set_attr "predicable" "yes")
1822 (set_attr "predicable_short_it" "no")]
1825 (define_expand "umulsidi3"
1826 [(set (match_operand:DI 0 "s_register_operand" "")
1828 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1829 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1830 "TARGET_32BIT && arm_arch3m"
1834 (define_insn "*umulsidi3_nov6"
1835 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1837 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1838 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1839 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1840 "umull%?\\t%Q0, %R0, %1, %2"
1841 [(set_attr "type" "umull")
1842 (set_attr "predicable" "yes")]
1845 (define_insn "*umulsidi3_v6"
1846 [(set (match_operand:DI 0 "s_register_operand" "=r")
1848 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1849 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1850 "TARGET_32BIT && arm_arch6"
1851 "umull%?\\t%Q0, %R0, %1, %2"
1852 [(set_attr "type" "umull")
1853 (set_attr "predicable" "yes")
1854 (set_attr "predicable_short_it" "no")]
1857 (define_expand "umaddsidi4"
1858 [(set (match_operand:DI 0 "s_register_operand" "")
1861 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1862 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1863 (match_operand:DI 3 "s_register_operand" "")))]
1864 "TARGET_32BIT && arm_arch3m"
1867 (define_insn "*umulsidi3adddi"
1868 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1871 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1872 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1873 (match_operand:DI 1 "s_register_operand" "0")))]
1874 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1875 "umlal%?\\t%Q0, %R0, %3, %2"
1876 [(set_attr "type" "umlal")
1877 (set_attr "predicable" "yes")]
1880 (define_insn "*umulsidi3adddi_v6"
1881 [(set (match_operand:DI 0 "s_register_operand" "=r")
1884 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1885 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1886 (match_operand:DI 1 "s_register_operand" "0")))]
1887 "TARGET_32BIT && arm_arch6"
1888 "umlal%?\\t%Q0, %R0, %3, %2"
1889 [(set_attr "type" "umlal")
1890 (set_attr "predicable" "yes")
1891 (set_attr "predicable_short_it" "no")]
1894 (define_expand "smulsi3_highpart"
1896 [(set (match_operand:SI 0 "s_register_operand" "")
1900 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1901 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1903 (clobber (match_scratch:SI 3 ""))])]
1904 "TARGET_32BIT && arm_arch3m"
1908 (define_insn "*smulsi3_highpart_nov6"
1909 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1913 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1914 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1916 (clobber (match_scratch:SI 3 "=&r,&r"))]
1917 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1918 "smull%?\\t%3, %0, %2, %1"
1919 [(set_attr "type" "smull")
1920 (set_attr "predicable" "yes")]
1923 (define_insn "*smulsi3_highpart_v6"
1924 [(set (match_operand:SI 0 "s_register_operand" "=r")
1928 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1929 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1931 (clobber (match_scratch:SI 3 "=r"))]
1932 "TARGET_32BIT && arm_arch6"
1933 "smull%?\\t%3, %0, %2, %1"
1934 [(set_attr "type" "smull")
1935 (set_attr "predicable" "yes")
1936 (set_attr "predicable_short_it" "no")]
1939 (define_expand "umulsi3_highpart"
1941 [(set (match_operand:SI 0 "s_register_operand" "")
1945 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1946 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1948 (clobber (match_scratch:SI 3 ""))])]
1949 "TARGET_32BIT && arm_arch3m"
1953 (define_insn "*umulsi3_highpart_nov6"
1954 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1958 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1959 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1961 (clobber (match_scratch:SI 3 "=&r,&r"))]
1962 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1963 "umull%?\\t%3, %0, %2, %1"
1964 [(set_attr "type" "umull")
1965 (set_attr "predicable" "yes")]
1968 (define_insn "*umulsi3_highpart_v6"
1969 [(set (match_operand:SI 0 "s_register_operand" "=r")
1973 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1974 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1976 (clobber (match_scratch:SI 3 "=r"))]
1977 "TARGET_32BIT && arm_arch6"
1978 "umull%?\\t%3, %0, %2, %1"
1979 [(set_attr "type" "umull")
1980 (set_attr "predicable" "yes")
1981 (set_attr "predicable_short_it" "no")]
1984 (define_insn "mulhisi3"
1985 [(set (match_operand:SI 0 "s_register_operand" "=r")
1986 (mult:SI (sign_extend:SI
1987 (match_operand:HI 1 "s_register_operand" "%r"))
1989 (match_operand:HI 2 "s_register_operand" "r"))))]
1990 "TARGET_DSP_MULTIPLY"
1991 "smulbb%?\\t%0, %1, %2"
1992 [(set_attr "type" "smulxy")
1993 (set_attr "predicable" "yes")]
1996 (define_insn "*mulhisi3tb"
1997 [(set (match_operand:SI 0 "s_register_operand" "=r")
1998 (mult:SI (ashiftrt:SI
1999 (match_operand:SI 1 "s_register_operand" "r")
2002 (match_operand:HI 2 "s_register_operand" "r"))))]
2003 "TARGET_DSP_MULTIPLY"
2004 "smultb%?\\t%0, %1, %2"
2005 [(set_attr "type" "smulxy")
2006 (set_attr "predicable" "yes")
2007 (set_attr "predicable_short_it" "no")]
2010 (define_insn "*mulhisi3bt"
2011 [(set (match_operand:SI 0 "s_register_operand" "=r")
2012 (mult:SI (sign_extend:SI
2013 (match_operand:HI 1 "s_register_operand" "r"))
2015 (match_operand:SI 2 "s_register_operand" "r")
2017 "TARGET_DSP_MULTIPLY"
2018 "smulbt%?\\t%0, %1, %2"
2019 [(set_attr "type" "smulxy")
2020 (set_attr "predicable" "yes")
2021 (set_attr "predicable_short_it" "no")]
2024 (define_insn "*mulhisi3tt"
2025 [(set (match_operand:SI 0 "s_register_operand" "=r")
2026 (mult:SI (ashiftrt:SI
2027 (match_operand:SI 1 "s_register_operand" "r")
2030 (match_operand:SI 2 "s_register_operand" "r")
2032 "TARGET_DSP_MULTIPLY"
2033 "smultt%?\\t%0, %1, %2"
2034 [(set_attr "type" "smulxy")
2035 (set_attr "predicable" "yes")
2036 (set_attr "predicable_short_it" "no")]
2039 (define_insn "maddhisi4"
2040 [(set (match_operand:SI 0 "s_register_operand" "=r")
2041 (plus:SI (mult:SI (sign_extend:SI
2042 (match_operand:HI 1 "s_register_operand" "r"))
2044 (match_operand:HI 2 "s_register_operand" "r")))
2045 (match_operand:SI 3 "s_register_operand" "r")))]
2046 "TARGET_DSP_MULTIPLY"
2047 "smlabb%?\\t%0, %1, %2, %3"
2048 [(set_attr "type" "smlaxy")
2049 (set_attr "predicable" "yes")
2050 (set_attr "predicable_short_it" "no")]
2053 ;; Note: there is no maddhisi4ibt because this one is canonical form
2054 (define_insn "*maddhisi4tb"
2055 [(set (match_operand:SI 0 "s_register_operand" "=r")
2056 (plus:SI (mult:SI (ashiftrt:SI
2057 (match_operand:SI 1 "s_register_operand" "r")
2060 (match_operand:HI 2 "s_register_operand" "r")))
2061 (match_operand:SI 3 "s_register_operand" "r")))]
2062 "TARGET_DSP_MULTIPLY"
2063 "smlatb%?\\t%0, %1, %2, %3"
2064 [(set_attr "type" "smlaxy")
2065 (set_attr "predicable" "yes")
2066 (set_attr "predicable_short_it" "no")]
2069 (define_insn "*maddhisi4tt"
2070 [(set (match_operand:SI 0 "s_register_operand" "=r")
2071 (plus:SI (mult:SI (ashiftrt:SI
2072 (match_operand:SI 1 "s_register_operand" "r")
2075 (match_operand:SI 2 "s_register_operand" "r")
2077 (match_operand:SI 3 "s_register_operand" "r")))]
2078 "TARGET_DSP_MULTIPLY"
2079 "smlatt%?\\t%0, %1, %2, %3"
2080 [(set_attr "type" "smlaxy")
2081 (set_attr "predicable" "yes")
2082 (set_attr "predicable_short_it" "no")]
2085 (define_insn "maddhidi4"
2086 [(set (match_operand:DI 0 "s_register_operand" "=r")
2088 (mult:DI (sign_extend:DI
2089 (match_operand:HI 1 "s_register_operand" "r"))
2091 (match_operand:HI 2 "s_register_operand" "r")))
2092 (match_operand:DI 3 "s_register_operand" "0")))]
2093 "TARGET_DSP_MULTIPLY"
2094 "smlalbb%?\\t%Q0, %R0, %1, %2"
2095 [(set_attr "type" "smlalxy")
2096 (set_attr "predicable" "yes")
2097 (set_attr "predicable_short_it" "no")])
2099 ;; Note: there is no maddhidi4ibt because this one is canonical form
2100 (define_insn "*maddhidi4tb"
2101 [(set (match_operand:DI 0 "s_register_operand" "=r")
2103 (mult:DI (sign_extend:DI
2105 (match_operand:SI 1 "s_register_operand" "r")
2108 (match_operand:HI 2 "s_register_operand" "r")))
2109 (match_operand:DI 3 "s_register_operand" "0")))]
2110 "TARGET_DSP_MULTIPLY"
2111 "smlaltb%?\\t%Q0, %R0, %1, %2"
2112 [(set_attr "type" "smlalxy")
2113 (set_attr "predicable" "yes")
2114 (set_attr "predicable_short_it" "no")])
2116 (define_insn "*maddhidi4tt"
2117 [(set (match_operand:DI 0 "s_register_operand" "=r")
2119 (mult:DI (sign_extend:DI
2121 (match_operand:SI 1 "s_register_operand" "r")
2125 (match_operand:SI 2 "s_register_operand" "r")
2127 (match_operand:DI 3 "s_register_operand" "0")))]
2128 "TARGET_DSP_MULTIPLY"
2129 "smlaltt%?\\t%Q0, %R0, %1, %2"
2130 [(set_attr "type" "smlalxy")
2131 (set_attr "predicable" "yes")
2132 (set_attr "predicable_short_it" "no")])
2134 (define_expand "mulsf3"
2135 [(set (match_operand:SF 0 "s_register_operand" "")
2136 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2137 (match_operand:SF 2 "s_register_operand" "")))]
2138 "TARGET_32BIT && TARGET_HARD_FLOAT"
2142 (define_expand "muldf3"
2143 [(set (match_operand:DF 0 "s_register_operand" "")
2144 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2145 (match_operand:DF 2 "s_register_operand" "")))]
2146 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2152 (define_expand "divsf3"
2153 [(set (match_operand:SF 0 "s_register_operand" "")
2154 (div:SF (match_operand:SF 1 "s_register_operand" "")
2155 (match_operand:SF 2 "s_register_operand" "")))]
2156 "TARGET_32BIT && TARGET_HARD_FLOAT"
2159 (define_expand "divdf3"
2160 [(set (match_operand:DF 0 "s_register_operand" "")
2161 (div:DF (match_operand:DF 1 "s_register_operand" "")
2162 (match_operand:DF 2 "s_register_operand" "")))]
2163 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2166 ;; Boolean and,ior,xor insns
2168 ;; Split up double word logical operations
2170 ;; Split up simple DImode logical operations. Simply perform the logical
2171 ;; operation on the upper and lower halves of the registers.
2173 [(set (match_operand:DI 0 "s_register_operand" "")
2174 (match_operator:DI 6 "logical_binary_operator"
2175 [(match_operand:DI 1 "s_register_operand" "")
2176 (match_operand:DI 2 "s_register_operand" "")]))]
2177 "TARGET_32BIT && reload_completed
2178 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2179 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2180 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2181 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2184 operands[3] = gen_highpart (SImode, operands[0]);
2185 operands[0] = gen_lowpart (SImode, operands[0]);
2186 operands[4] = gen_highpart (SImode, operands[1]);
2187 operands[1] = gen_lowpart (SImode, operands[1]);
2188 operands[5] = gen_highpart (SImode, operands[2]);
2189 operands[2] = gen_lowpart (SImode, operands[2]);
2194 [(set (match_operand:DI 0 "s_register_operand" "")
2195 (match_operator:DI 6 "logical_binary_operator"
2196 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2197 (match_operand:DI 1 "s_register_operand" "")]))]
2198 "TARGET_32BIT && reload_completed"
2199 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2200 (set (match_dup 3) (match_op_dup:SI 6
2201 [(ashiftrt:SI (match_dup 2) (const_int 31))
2205 operands[3] = gen_highpart (SImode, operands[0]);
2206 operands[0] = gen_lowpart (SImode, operands[0]);
2207 operands[4] = gen_highpart (SImode, operands[1]);
2208 operands[1] = gen_lowpart (SImode, operands[1]);
2209 operands[5] = gen_highpart (SImode, operands[2]);
2210 operands[2] = gen_lowpart (SImode, operands[2]);
2214 ;; The zero extend of operand 2 means we can just copy the high part of
2215 ;; operand1 into operand0.
2217 [(set (match_operand:DI 0 "s_register_operand" "")
2219 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2220 (match_operand:DI 1 "s_register_operand" "")))]
2221 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2222 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2223 (set (match_dup 3) (match_dup 4))]
2226 operands[4] = gen_highpart (SImode, operands[1]);
2227 operands[3] = gen_highpart (SImode, operands[0]);
2228 operands[0] = gen_lowpart (SImode, operands[0]);
2229 operands[1] = gen_lowpart (SImode, operands[1]);
2233 ;; The zero extend of operand 2 means we can just copy the high part of
2234 ;; operand1 into operand0.
2236 [(set (match_operand:DI 0 "s_register_operand" "")
2238 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2239 (match_operand:DI 1 "s_register_operand" "")))]
2240 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2241 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2242 (set (match_dup 3) (match_dup 4))]
2245 operands[4] = gen_highpart (SImode, operands[1]);
2246 operands[3] = gen_highpart (SImode, operands[0]);
2247 operands[0] = gen_lowpart (SImode, operands[0]);
2248 operands[1] = gen_lowpart (SImode, operands[1]);
2252 (define_expand "anddi3"
2253 [(set (match_operand:DI 0 "s_register_operand" "")
2254 (and:DI (match_operand:DI 1 "s_register_operand" "")
2255 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2258 if (!TARGET_NEON && !TARGET_IWMMXT)
2260 rtx low = simplify_gen_binary (AND, SImode,
2261 gen_lowpart (SImode, operands[1]),
2262 gen_lowpart (SImode, operands[2]));
2263 rtx high = simplify_gen_binary (AND, SImode,
2264 gen_highpart (SImode, operands[1]),
2265 gen_highpart_mode (SImode, DImode,
2268 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2269 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2273 /* Otherwise expand pattern as above. */
2277 (define_insn_and_split "*anddi3_insn"
2278 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2279 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2280 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2281 "TARGET_32BIT && !TARGET_IWMMXT"
2283 switch (which_alternative)
2285 case 0: /* fall through */
2286 case 6: return "vand\t%P0, %P1, %P2";
2287 case 1: /* fall through */
2288 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2289 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2293 case 5: /* fall through */
2295 default: gcc_unreachable ();
2298 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2299 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2300 [(set (match_dup 3) (match_dup 4))
2301 (set (match_dup 5) (match_dup 6))]
2304 operands[3] = gen_lowpart (SImode, operands[0]);
2305 operands[5] = gen_highpart (SImode, operands[0]);
2307 operands[4] = simplify_gen_binary (AND, SImode,
2308 gen_lowpart (SImode, operands[1]),
2309 gen_lowpart (SImode, operands[2]));
2310 operands[6] = simplify_gen_binary (AND, SImode,
2311 gen_highpart (SImode, operands[1]),
2312 gen_highpart_mode (SImode, DImode, operands[2]));
2315 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2316 multiple,multiple,neon_logic,neon_logic")
2317 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2318 avoid_neon_for_64bits,avoid_neon_for_64bits")
2319 (set_attr "length" "*,*,8,8,8,8,*,*")
2323 (define_insn_and_split "*anddi_zesidi_di"
2324 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2325 (and:DI (zero_extend:DI
2326 (match_operand:SI 2 "s_register_operand" "r,r"))
2327 (match_operand:DI 1 "s_register_operand" "0,r")))]
2330 "TARGET_32BIT && reload_completed"
2331 ; The zero extend of operand 2 clears the high word of the output
2333 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2334 (set (match_dup 3) (const_int 0))]
2337 operands[3] = gen_highpart (SImode, operands[0]);
2338 operands[0] = gen_lowpart (SImode, operands[0]);
2339 operands[1] = gen_lowpart (SImode, operands[1]);
2341 [(set_attr "length" "8")
2342 (set_attr "type" "multiple")]
2345 (define_insn "*anddi_sesdi_di"
2346 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2347 (and:DI (sign_extend:DI
2348 (match_operand:SI 2 "s_register_operand" "r,r"))
2349 (match_operand:DI 1 "s_register_operand" "0,r")))]
2352 [(set_attr "length" "8")
2353 (set_attr "type" "multiple")]
2356 (define_expand "andsi3"
2357 [(set (match_operand:SI 0 "s_register_operand" "")
2358 (and:SI (match_operand:SI 1 "s_register_operand" "")
2359 (match_operand:SI 2 "reg_or_int_operand" "")))]
2364 if (CONST_INT_P (operands[2]))
2366 if (INTVAL (operands[2]) == 255 && arm_arch6)
2368 operands[1] = convert_to_mode (QImode, operands[1], 1);
2369 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2373 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2374 operands[2] = force_reg (SImode, operands[2]);
2377 arm_split_constant (AND, SImode, NULL_RTX,
2378 INTVAL (operands[2]), operands[0],
2380 optimize && can_create_pseudo_p ());
2386 else /* TARGET_THUMB1 */
2388 if (!CONST_INT_P (operands[2]))
2390 rtx tmp = force_reg (SImode, operands[2]);
2391 if (rtx_equal_p (operands[0], operands[1]))
2395 operands[2] = operands[1];
2403 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2405 operands[2] = force_reg (SImode,
2406 GEN_INT (~INTVAL (operands[2])));
2408 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2413 for (i = 9; i <= 31; i++)
2415 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2417 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2421 else if ((HOST_WIDE_INT_1 << i) - 1
2422 == ~INTVAL (operands[2]))
2424 rtx shift = GEN_INT (i);
2425 rtx reg = gen_reg_rtx (SImode);
2427 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2428 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2434 operands[2] = force_reg (SImode, operands[2]);
2440 ; ??? Check split length for Thumb-2
2441 (define_insn_and_split "*arm_andsi3_insn"
2442 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2443 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2444 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2449 bic%?\\t%0, %1, #%B2
2453 && CONST_INT_P (operands[2])
2454 && !(const_ok_for_arm (INTVAL (operands[2]))
2455 || const_ok_for_arm (~INTVAL (operands[2])))"
2456 [(clobber (const_int 0))]
2458 arm_split_constant (AND, SImode, curr_insn,
2459 INTVAL (operands[2]), operands[0], operands[1], 0);
2462 [(set_attr "length" "4,4,4,4,16")
2463 (set_attr "predicable" "yes")
2464 (set_attr "predicable_short_it" "no,yes,no,no,no")
2465 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2468 (define_insn "*andsi3_compare0"
2469 [(set (reg:CC_NOOV CC_REGNUM)
2471 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2472 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2474 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2475 (and:SI (match_dup 1) (match_dup 2)))]
2479 bics%?\\t%0, %1, #%B2
2480 ands%?\\t%0, %1, %2"
2481 [(set_attr "conds" "set")
2482 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2485 (define_insn "*andsi3_compare0_scratch"
2486 [(set (reg:CC_NOOV CC_REGNUM)
2488 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2489 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2491 (clobber (match_scratch:SI 2 "=X,r,X"))]
2495 bics%?\\t%2, %0, #%B1
2497 [(set_attr "conds" "set")
2498 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2501 (define_insn "*zeroextractsi_compare0_scratch"
2502 [(set (reg:CC_NOOV CC_REGNUM)
2503 (compare:CC_NOOV (zero_extract:SI
2504 (match_operand:SI 0 "s_register_operand" "r")
2505 (match_operand 1 "const_int_operand" "n")
2506 (match_operand 2 "const_int_operand" "n"))
2509 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2510 && INTVAL (operands[1]) > 0
2511 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2512 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2514 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2515 << INTVAL (operands[2]));
2516 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2519 [(set_attr "conds" "set")
2520 (set_attr "predicable" "yes")
2521 (set_attr "predicable_short_it" "no")
2522 (set_attr "type" "logics_imm")]
2525 (define_insn_and_split "*ne_zeroextractsi"
2526 [(set (match_operand:SI 0 "s_register_operand" "=r")
2527 (ne:SI (zero_extract:SI
2528 (match_operand:SI 1 "s_register_operand" "r")
2529 (match_operand:SI 2 "const_int_operand" "n")
2530 (match_operand:SI 3 "const_int_operand" "n"))
2532 (clobber (reg:CC CC_REGNUM))]
2534 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2535 && INTVAL (operands[2]) > 0
2536 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2537 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2540 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2541 && INTVAL (operands[2]) > 0
2542 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2543 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2544 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2545 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2547 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2549 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2550 (match_dup 0) (const_int 1)))]
2552 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2553 << INTVAL (operands[3]));
2555 [(set_attr "conds" "clob")
2556 (set (attr "length")
2557 (if_then_else (eq_attr "is_thumb" "yes")
2560 (set_attr "type" "multiple")]
2563 (define_insn_and_split "*ne_zeroextractsi_shifted"
2564 [(set (match_operand:SI 0 "s_register_operand" "=r")
2565 (ne:SI (zero_extract:SI
2566 (match_operand:SI 1 "s_register_operand" "r")
2567 (match_operand:SI 2 "const_int_operand" "n")
2570 (clobber (reg:CC CC_REGNUM))]
2574 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2575 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2577 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2579 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2580 (match_dup 0) (const_int 1)))]
2582 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2584 [(set_attr "conds" "clob")
2585 (set_attr "length" "8")
2586 (set_attr "type" "multiple")]
2589 (define_insn_and_split "*ite_ne_zeroextractsi"
2590 [(set (match_operand:SI 0 "s_register_operand" "=r")
2591 (if_then_else:SI (ne (zero_extract:SI
2592 (match_operand:SI 1 "s_register_operand" "r")
2593 (match_operand:SI 2 "const_int_operand" "n")
2594 (match_operand:SI 3 "const_int_operand" "n"))
2596 (match_operand:SI 4 "arm_not_operand" "rIK")
2598 (clobber (reg:CC CC_REGNUM))]
2600 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2601 && INTVAL (operands[2]) > 0
2602 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2603 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2604 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2607 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2608 && INTVAL (operands[2]) > 0
2609 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2610 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2611 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2612 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2613 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2615 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2617 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2618 (match_dup 0) (match_dup 4)))]
2620 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2621 << INTVAL (operands[3]));
2623 [(set_attr "conds" "clob")
2624 (set_attr "length" "8")
2625 (set_attr "type" "multiple")]
2628 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2629 [(set (match_operand:SI 0 "s_register_operand" "=r")
2630 (if_then_else:SI (ne (zero_extract:SI
2631 (match_operand:SI 1 "s_register_operand" "r")
2632 (match_operand:SI 2 "const_int_operand" "n")
2635 (match_operand:SI 3 "arm_not_operand" "rIK")
2637 (clobber (reg:CC CC_REGNUM))]
2638 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2640 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2641 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2642 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2644 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2646 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2647 (match_dup 0) (match_dup 3)))]
2649 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2651 [(set_attr "conds" "clob")
2652 (set_attr "length" "8")
2653 (set_attr "type" "multiple")]
2656 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2658 [(set (match_operand:SI 0 "s_register_operand" "")
2659 (match_operator:SI 1 "shiftable_operator"
2660 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2661 (match_operand:SI 3 "const_int_operand" "")
2662 (match_operand:SI 4 "const_int_operand" ""))
2663 (match_operand:SI 5 "s_register_operand" "")]))
2664 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2666 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2669 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2672 HOST_WIDE_INT temp = INTVAL (operands[3]);
2674 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2675 operands[4] = GEN_INT (32 - temp);
2680 [(set (match_operand:SI 0 "s_register_operand" "")
2681 (match_operator:SI 1 "shiftable_operator"
2682 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2683 (match_operand:SI 3 "const_int_operand" "")
2684 (match_operand:SI 4 "const_int_operand" ""))
2685 (match_operand:SI 5 "s_register_operand" "")]))
2686 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2688 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2691 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2694 HOST_WIDE_INT temp = INTVAL (operands[3]);
2696 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2697 operands[4] = GEN_INT (32 - temp);
2701 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2702 ;;; represented by the bitfield, then this will produce incorrect results.
2703 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2704 ;;; which have a real bit-field insert instruction, the truncation happens
2705 ;;; in the bit-field insert instruction itself. Since arm does not have a
2706 ;;; bit-field insert instruction, we would have to emit code here to truncate
2707 ;;; the value before we insert. This loses some of the advantage of having
2708 ;;; this insv pattern, so this pattern needs to be reevalutated.
2710 (define_expand "insv"
2711 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2712 (match_operand 1 "general_operand" "")
2713 (match_operand 2 "general_operand" ""))
2714 (match_operand 3 "reg_or_int_operand" ""))]
2715 "TARGET_ARM || arm_arch_thumb2"
2718 int start_bit = INTVAL (operands[2]);
2719 int width = INTVAL (operands[1]);
2720 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2721 rtx target, subtarget;
2723 if (arm_arch_thumb2)
2725 if (unaligned_access && MEM_P (operands[0])
2726 && s_register_operand (operands[3], GET_MODE (operands[3]))
2727 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2731 if (BYTES_BIG_ENDIAN)
2732 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2737 base_addr = adjust_address (operands[0], SImode,
2738 start_bit / BITS_PER_UNIT);
2739 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2743 rtx tmp = gen_reg_rtx (HImode);
2745 base_addr = adjust_address (operands[0], HImode,
2746 start_bit / BITS_PER_UNIT);
2747 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2748 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2752 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2754 bool use_bfi = TRUE;
2756 if (CONST_INT_P (operands[3]))
2758 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2762 emit_insn (gen_insv_zero (operands[0], operands[1],
2767 /* See if the set can be done with a single orr instruction. */
2768 if (val == mask && const_ok_for_arm (val << start_bit))
2774 if (!REG_P (operands[3]))
2775 operands[3] = force_reg (SImode, operands[3]);
2777 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2786 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2789 target = copy_rtx (operands[0]);
2790 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2791 subreg as the final target. */
2792 if (GET_CODE (target) == SUBREG)
2794 subtarget = gen_reg_rtx (SImode);
2795 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2796 < GET_MODE_SIZE (SImode))
2797 target = SUBREG_REG (target);
2802 if (CONST_INT_P (operands[3]))
2804 /* Since we are inserting a known constant, we may be able to
2805 reduce the number of bits that we have to clear so that
2806 the mask becomes simple. */
2807 /* ??? This code does not check to see if the new mask is actually
2808 simpler. It may not be. */
2809 rtx op1 = gen_reg_rtx (SImode);
2810 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2811 start of this pattern. */
2812 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2813 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2815 emit_insn (gen_andsi3 (op1, operands[0],
2816 gen_int_mode (~mask2, SImode)));
2817 emit_insn (gen_iorsi3 (subtarget, op1,
2818 gen_int_mode (op3_value << start_bit, SImode)));
2820 else if (start_bit == 0
2821 && !(const_ok_for_arm (mask)
2822 || const_ok_for_arm (~mask)))
2824 /* A Trick, since we are setting the bottom bits in the word,
2825 we can shift operand[3] up, operand[0] down, OR them together
2826 and rotate the result back again. This takes 3 insns, and
2827 the third might be mergeable into another op. */
2828 /* The shift up copes with the possibility that operand[3] is
2829 wider than the bitfield. */
2830 rtx op0 = gen_reg_rtx (SImode);
2831 rtx op1 = gen_reg_rtx (SImode);
2833 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2834 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2835 emit_insn (gen_iorsi3 (op1, op1, op0));
2836 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2838 else if ((width + start_bit == 32)
2839 && !(const_ok_for_arm (mask)
2840 || const_ok_for_arm (~mask)))
2842 /* Similar trick, but slightly less efficient. */
2844 rtx op0 = gen_reg_rtx (SImode);
2845 rtx op1 = gen_reg_rtx (SImode);
2847 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2848 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2849 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2850 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2854 rtx op0 = gen_int_mode (mask, SImode);
2855 rtx op1 = gen_reg_rtx (SImode);
2856 rtx op2 = gen_reg_rtx (SImode);
2858 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2860 rtx tmp = gen_reg_rtx (SImode);
2862 emit_insn (gen_movsi (tmp, op0));
2866 /* Mask out any bits in operand[3] that are not needed. */
2867 emit_insn (gen_andsi3 (op1, operands[3], op0));
2869 if (CONST_INT_P (op0)
2870 && (const_ok_for_arm (mask << start_bit)
2871 || const_ok_for_arm (~(mask << start_bit))))
2873 op0 = gen_int_mode (~(mask << start_bit), SImode);
2874 emit_insn (gen_andsi3 (op2, operands[0], op0));
2878 if (CONST_INT_P (op0))
2880 rtx tmp = gen_reg_rtx (SImode);
2882 emit_insn (gen_movsi (tmp, op0));
2887 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2889 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2893 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2895 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2898 if (subtarget != target)
2900 /* If TARGET is still a SUBREG, then it must be wider than a word,
2901 so we must be careful only to set the subword we were asked to. */
2902 if (GET_CODE (target) == SUBREG)
2903 emit_move_insn (target, subtarget);
2905 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2912 (define_insn "insv_zero"
2913 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2914 (match_operand:SI 1 "const_int_M_operand" "M")
2915 (match_operand:SI 2 "const_int_M_operand" "M"))
2919 [(set_attr "length" "4")
2920 (set_attr "predicable" "yes")
2921 (set_attr "predicable_short_it" "no")
2922 (set_attr "type" "bfm")]
2925 (define_insn "insv_t2"
2926 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2927 (match_operand:SI 1 "const_int_M_operand" "M")
2928 (match_operand:SI 2 "const_int_M_operand" "M"))
2929 (match_operand:SI 3 "s_register_operand" "r"))]
2931 "bfi%?\t%0, %3, %2, %1"
2932 [(set_attr "length" "4")
2933 (set_attr "predicable" "yes")
2934 (set_attr "predicable_short_it" "no")
2935 (set_attr "type" "bfm")]
2938 ; constants for op 2 will never be given to these patterns.
2939 (define_insn_and_split "*anddi_notdi_di"
2940 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2941 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2942 (match_operand:DI 2 "s_register_operand" "r,0")))]
2945 "TARGET_32BIT && reload_completed
2946 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2947 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2948 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2949 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2952 operands[3] = gen_highpart (SImode, operands[0]);
2953 operands[0] = gen_lowpart (SImode, operands[0]);
2954 operands[4] = gen_highpart (SImode, operands[1]);
2955 operands[1] = gen_lowpart (SImode, operands[1]);
2956 operands[5] = gen_highpart (SImode, operands[2]);
2957 operands[2] = gen_lowpart (SImode, operands[2]);
2959 [(set_attr "length" "8")
2960 (set_attr "predicable" "yes")
2961 (set_attr "type" "multiple")]
2964 (define_insn_and_split "*anddi_notzesidi_di"
2965 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2966 (and:DI (not:DI (zero_extend:DI
2967 (match_operand:SI 2 "s_register_operand" "r,r")))
2968 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2971 bic%?\\t%Q0, %Q1, %2
2973 ; (not (zero_extend ...)) allows us to just copy the high word from
2974 ; operand1 to operand0.
2977 && operands[0] != operands[1]"
2978 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2979 (set (match_dup 3) (match_dup 4))]
2982 operands[3] = gen_highpart (SImode, operands[0]);
2983 operands[0] = gen_lowpart (SImode, operands[0]);
2984 operands[4] = gen_highpart (SImode, operands[1]);
2985 operands[1] = gen_lowpart (SImode, operands[1]);
2987 [(set_attr "length" "4,8")
2988 (set_attr "predicable" "yes")
2989 (set_attr "predicable_short_it" "no")
2990 (set_attr "type" "multiple")]
2993 (define_insn_and_split "*anddi_notdi_zesidi"
2994 [(set (match_operand:DI 0 "s_register_operand" "=r")
2995 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2997 (match_operand:SI 1 "s_register_operand" "r"))))]
3000 "TARGET_32BIT && reload_completed"
3001 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3002 (set (match_dup 3) (const_int 0))]
3005 operands[3] = gen_highpart (SImode, operands[0]);
3006 operands[0] = gen_lowpart (SImode, operands[0]);
3007 operands[2] = gen_lowpart (SImode, operands[2]);
3009 [(set_attr "length" "8")
3010 (set_attr "predicable" "yes")
3011 (set_attr "predicable_short_it" "no")
3012 (set_attr "type" "multiple")]
3015 (define_insn_and_split "*anddi_notsesidi_di"
3016 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3017 (and:DI (not:DI (sign_extend:DI
3018 (match_operand:SI 2 "s_register_operand" "r,r")))
3019 (match_operand:DI 1 "s_register_operand" "0,r")))]
3022 "TARGET_32BIT && reload_completed"
3023 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3024 (set (match_dup 3) (and:SI (not:SI
3025 (ashiftrt:SI (match_dup 2) (const_int 31)))
3029 operands[3] = gen_highpart (SImode, operands[0]);
3030 operands[0] = gen_lowpart (SImode, operands[0]);
3031 operands[4] = gen_highpart (SImode, operands[1]);
3032 operands[1] = gen_lowpart (SImode, operands[1]);
3034 [(set_attr "length" "8")
3035 (set_attr "predicable" "yes")
3036 (set_attr "predicable_short_it" "no")
3037 (set_attr "type" "multiple")]
3040 (define_insn "andsi_notsi_si"
3041 [(set (match_operand:SI 0 "s_register_operand" "=r")
3042 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3043 (match_operand:SI 1 "s_register_operand" "r")))]
3045 "bic%?\\t%0, %1, %2"
3046 [(set_attr "predicable" "yes")
3047 (set_attr "predicable_short_it" "no")
3048 (set_attr "type" "logic_reg")]
3051 (define_insn "andsi_not_shiftsi_si"
3052 [(set (match_operand:SI 0 "s_register_operand" "=r")
3053 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3054 [(match_operand:SI 2 "s_register_operand" "r")
3055 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3056 (match_operand:SI 1 "s_register_operand" "r")))]
3058 "bic%?\\t%0, %1, %2%S4"
3059 [(set_attr "predicable" "yes")
3060 (set_attr "shift" "2")
3061 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3062 (const_string "logic_shift_imm")
3063 (const_string "logic_shift_reg")))]
3066 ;; Shifted bics pattern used to set up CC status register and not reusing
3067 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3068 ;; does not support shift by register.
3069 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3070 [(set (reg:CC_NOOV CC_REGNUM)
3072 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3073 [(match_operand:SI 1 "s_register_operand" "r")
3074 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3075 (match_operand:SI 3 "s_register_operand" "r"))
3077 (clobber (match_scratch:SI 4 "=r"))]
3078 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3079 "bics%?\\t%4, %3, %1%S0"
3080 [(set_attr "predicable" "yes")
3081 (set_attr "predicable_short_it" "no")
3082 (set_attr "conds" "set")
3083 (set_attr "shift" "1")
3084 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3085 (const_string "logic_shift_imm")
3086 (const_string "logic_shift_reg")))]
3089 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3090 ;; getting reused later.
3091 (define_insn "andsi_not_shiftsi_si_scc"
3092 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3094 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3095 [(match_operand:SI 1 "s_register_operand" "r")
3096 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3097 (match_operand:SI 3 "s_register_operand" "r"))
3099 (set (match_operand:SI 4 "s_register_operand" "=r")
3100 (and:SI (not:SI (match_op_dup 0
3104 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3105 "bics%?\\t%4, %3, %1%S0"
3106 [(set_attr "predicable" "yes")
3107 (set_attr "predicable_short_it" "no")
3108 (set_attr "conds" "set")
3109 (set_attr "shift" "1")
3110 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3111 (const_string "logic_shift_imm")
3112 (const_string "logic_shift_reg")))]
3115 (define_insn "*andsi_notsi_si_compare0"
3116 [(set (reg:CC_NOOV CC_REGNUM)
3118 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3119 (match_operand:SI 1 "s_register_operand" "r"))
3121 (set (match_operand:SI 0 "s_register_operand" "=r")
3122 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3125 [(set_attr "conds" "set")
3126 (set_attr "type" "logics_shift_reg")]
3129 (define_insn "*andsi_notsi_si_compare0_scratch"
3130 [(set (reg:CC_NOOV CC_REGNUM)
3132 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3133 (match_operand:SI 1 "s_register_operand" "r"))
3135 (clobber (match_scratch:SI 0 "=r"))]
3138 [(set_attr "conds" "set")
3139 (set_attr "type" "logics_shift_reg")]
3142 (define_expand "iordi3"
3143 [(set (match_operand:DI 0 "s_register_operand" "")
3144 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3145 (match_operand:DI 2 "neon_logic_op2" "")))]
3148 if (!TARGET_NEON && !TARGET_IWMMXT)
3150 rtx low = simplify_gen_binary (IOR, SImode,
3151 gen_lowpart (SImode, operands[1]),
3152 gen_lowpart (SImode, operands[2]));
3153 rtx high = simplify_gen_binary (IOR, SImode,
3154 gen_highpart (SImode, operands[1]),
3155 gen_highpart_mode (SImode, DImode,
3158 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3159 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3163 /* Otherwise expand pattern as above. */
3167 (define_insn_and_split "*iordi3_insn"
3168 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3169 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3170 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3171 "TARGET_32BIT && !TARGET_IWMMXT"
3173 switch (which_alternative)
3175 case 0: /* fall through */
3176 case 6: return "vorr\t%P0, %P1, %P2";
3177 case 1: /* fall through */
3178 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3179 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3185 default: gcc_unreachable ();
3188 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3189 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3190 [(set (match_dup 3) (match_dup 4))
3191 (set (match_dup 5) (match_dup 6))]
3194 operands[3] = gen_lowpart (SImode, operands[0]);
3195 operands[5] = gen_highpart (SImode, operands[0]);
3197 operands[4] = simplify_gen_binary (IOR, SImode,
3198 gen_lowpart (SImode, operands[1]),
3199 gen_lowpart (SImode, operands[2]));
3200 operands[6] = simplify_gen_binary (IOR, SImode,
3201 gen_highpart (SImode, operands[1]),
3202 gen_highpart_mode (SImode, DImode, operands[2]));
3205 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3206 multiple,neon_logic,neon_logic")
3207 (set_attr "length" "*,*,8,8,8,8,*,*")
3208 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3211 (define_insn "*iordi_zesidi_di"
3212 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3213 (ior:DI (zero_extend:DI
3214 (match_operand:SI 2 "s_register_operand" "r,r"))
3215 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3218 orr%?\\t%Q0, %Q1, %2
3220 [(set_attr "length" "4,8")
3221 (set_attr "predicable" "yes")
3222 (set_attr "predicable_short_it" "no")
3223 (set_attr "type" "logic_reg,multiple")]
3226 (define_insn "*iordi_sesidi_di"
3227 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3228 (ior:DI (sign_extend:DI
3229 (match_operand:SI 2 "s_register_operand" "r,r"))
3230 (match_operand:DI 1 "s_register_operand" "0,r")))]
3233 [(set_attr "length" "8")
3234 (set_attr "predicable" "yes")
3235 (set_attr "type" "multiple")]
3238 (define_expand "iorsi3"
3239 [(set (match_operand:SI 0 "s_register_operand" "")
3240 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3241 (match_operand:SI 2 "reg_or_int_operand" "")))]
3244 if (CONST_INT_P (operands[2]))
3248 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3249 operands[2] = force_reg (SImode, operands[2]);
3252 arm_split_constant (IOR, SImode, NULL_RTX,
3253 INTVAL (operands[2]), operands[0],
3255 optimize && can_create_pseudo_p ());
3259 else /* TARGET_THUMB1 */
3261 rtx tmp = force_reg (SImode, operands[2]);
3262 if (rtx_equal_p (operands[0], operands[1]))
3266 operands[2] = operands[1];
3274 (define_insn_and_split "*iorsi3_insn"
3275 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3276 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3277 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3282 orn%?\\t%0, %1, #%B2
3286 && CONST_INT_P (operands[2])
3287 && !(const_ok_for_arm (INTVAL (operands[2]))
3288 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3289 [(clobber (const_int 0))]
3291 arm_split_constant (IOR, SImode, curr_insn,
3292 INTVAL (operands[2]), operands[0], operands[1], 0);
3295 [(set_attr "length" "4,4,4,4,16")
3296 (set_attr "arch" "32,t2,t2,32,32")
3297 (set_attr "predicable" "yes")
3298 (set_attr "predicable_short_it" "no,yes,no,no,no")
3299 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3303 [(match_scratch:SI 3 "r")
3304 (set (match_operand:SI 0 "arm_general_register_operand" "")
3305 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3306 (match_operand:SI 2 "const_int_operand" "")))]
3308 && !const_ok_for_arm (INTVAL (operands[2]))
3309 && const_ok_for_arm (~INTVAL (operands[2]))"
3310 [(set (match_dup 3) (match_dup 2))
3311 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3315 (define_insn "*iorsi3_compare0"
3316 [(set (reg:CC_NOOV CC_REGNUM)
3317 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3318 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3320 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3321 (ior:SI (match_dup 1) (match_dup 2)))]
3323 "orrs%?\\t%0, %1, %2"
3324 [(set_attr "conds" "set")
3325 (set_attr "type" "logics_imm,logics_reg")]
3328 (define_insn "*iorsi3_compare0_scratch"
3329 [(set (reg:CC_NOOV CC_REGNUM)
3330 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3331 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3333 (clobber (match_scratch:SI 0 "=r,r"))]
3335 "orrs%?\\t%0, %1, %2"
3336 [(set_attr "conds" "set")
3337 (set_attr "type" "logics_imm,logics_reg")]
3340 (define_expand "xordi3"
3341 [(set (match_operand:DI 0 "s_register_operand" "")
3342 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3343 (match_operand:DI 2 "arm_xordi_operand" "")))]
3346 /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3347 to reuse this expander for all TARGET_32BIT targets so just force the
3348 constants into a register. Unlike for the anddi3 and iordi3 there are
3349 no NEON instructions that take an immediate. */
3350 if (TARGET_IWMMXT && !REG_P (operands[2]))
3351 operands[2] = force_reg (DImode, operands[2]);
3352 if (!TARGET_NEON && !TARGET_IWMMXT)
3354 rtx low = simplify_gen_binary (XOR, SImode,
3355 gen_lowpart (SImode, operands[1]),
3356 gen_lowpart (SImode, operands[2]));
3357 rtx high = simplify_gen_binary (XOR, SImode,
3358 gen_highpart (SImode, operands[1]),
3359 gen_highpart_mode (SImode, DImode,
3362 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3363 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3367 /* Otherwise expand pattern as above. */
3371 (define_insn_and_split "*xordi3_insn"
3372 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3373 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3374 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3375 "TARGET_32BIT && !TARGET_IWMMXT"
3377 switch (which_alternative)
3382 case 4: /* fall through */
3384 case 0: /* fall through */
3385 case 5: return "veor\t%P0, %P1, %P2";
3386 default: gcc_unreachable ();
3389 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3390 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3391 [(set (match_dup 3) (match_dup 4))
3392 (set (match_dup 5) (match_dup 6))]
3395 operands[3] = gen_lowpart (SImode, operands[0]);
3396 operands[5] = gen_highpart (SImode, operands[0]);
3398 operands[4] = simplify_gen_binary (XOR, SImode,
3399 gen_lowpart (SImode, operands[1]),
3400 gen_lowpart (SImode, operands[2]));
3401 operands[6] = simplify_gen_binary (XOR, SImode,
3402 gen_highpart (SImode, operands[1]),
3403 gen_highpart_mode (SImode, DImode, operands[2]));
3406 [(set_attr "length" "*,8,8,8,8,*")
3407 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3408 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3411 (define_insn "*xordi_zesidi_di"
3412 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3413 (xor:DI (zero_extend:DI
3414 (match_operand:SI 2 "s_register_operand" "r,r"))
3415 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3418 eor%?\\t%Q0, %Q1, %2
3420 [(set_attr "length" "4,8")
3421 (set_attr "predicable" "yes")
3422 (set_attr "predicable_short_it" "no")
3423 (set_attr "type" "logic_reg")]
3426 (define_insn "*xordi_sesidi_di"
3427 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3428 (xor:DI (sign_extend:DI
3429 (match_operand:SI 2 "s_register_operand" "r,r"))
3430 (match_operand:DI 1 "s_register_operand" "0,r")))]
3433 [(set_attr "length" "8")
3434 (set_attr "predicable" "yes")
3435 (set_attr "type" "multiple")]
3438 (define_expand "xorsi3"
3439 [(set (match_operand:SI 0 "s_register_operand" "")
3440 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3441 (match_operand:SI 2 "reg_or_int_operand" "")))]
3443 "if (CONST_INT_P (operands[2]))
3447 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3448 operands[2] = force_reg (SImode, operands[2]);
3451 arm_split_constant (XOR, SImode, NULL_RTX,
3452 INTVAL (operands[2]), operands[0],
3454 optimize && can_create_pseudo_p ());
3458 else /* TARGET_THUMB1 */
3460 rtx tmp = force_reg (SImode, operands[2]);
3461 if (rtx_equal_p (operands[0], operands[1]))
3465 operands[2] = operands[1];
3472 (define_insn_and_split "*arm_xorsi3"
3473 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3474 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3475 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3483 && CONST_INT_P (operands[2])
3484 && !const_ok_for_arm (INTVAL (operands[2]))"
3485 [(clobber (const_int 0))]
3487 arm_split_constant (XOR, SImode, curr_insn,
3488 INTVAL (operands[2]), operands[0], operands[1], 0);
3491 [(set_attr "length" "4,4,4,16")
3492 (set_attr "predicable" "yes")
3493 (set_attr "predicable_short_it" "no,yes,no,no")
3494 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3497 (define_insn "*xorsi3_compare0"
3498 [(set (reg:CC_NOOV CC_REGNUM)
3499 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3500 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3502 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3503 (xor:SI (match_dup 1) (match_dup 2)))]
3505 "eors%?\\t%0, %1, %2"
3506 [(set_attr "conds" "set")
3507 (set_attr "type" "logics_imm,logics_reg")]
3510 (define_insn "*xorsi3_compare0_scratch"
3511 [(set (reg:CC_NOOV CC_REGNUM)
3512 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3513 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3517 [(set_attr "conds" "set")
3518 (set_attr "type" "logics_imm,logics_reg")]
3521 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3522 ; (NOT D) we can sometimes merge the final NOT into one of the following
3526 [(set (match_operand:SI 0 "s_register_operand" "")
3527 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3528 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3529 (match_operand:SI 3 "arm_rhs_operand" "")))
3530 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3532 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3533 (not:SI (match_dup 3))))
3534 (set (match_dup 0) (not:SI (match_dup 4)))]
3538 (define_insn_and_split "*andsi_iorsi3_notsi"
3539 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3540 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3541 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3542 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3544 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3545 "&& reload_completed"
3546 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3547 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3549 /* If operands[3] is a constant make sure to fold the NOT into it
3550 to avoid creating a NOT of a CONST_INT. */
3551 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3552 if (CONST_INT_P (not_rtx))
3554 operands[4] = operands[0];
3555 operands[5] = not_rtx;
3559 operands[5] = operands[0];
3560 operands[4] = not_rtx;
3563 [(set_attr "length" "8")
3564 (set_attr "ce_count" "2")
3565 (set_attr "predicable" "yes")
3566 (set_attr "predicable_short_it" "no")
3567 (set_attr "type" "multiple")]
3570 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3571 ; insns are available?
3573 [(set (match_operand:SI 0 "s_register_operand" "")
3574 (match_operator:SI 1 "logical_binary_operator"
3575 [(zero_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 [(lshiftrt: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 [(lshiftrt: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 [(lshiftrt: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 (zero_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 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3621 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3625 [(set (match_operand:SI 0 "s_register_operand" "")
3626 (match_operator:SI 1 "logical_binary_operator"
3627 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3628 (match_operand:SI 3 "const_int_operand" "")
3629 (match_operand:SI 4 "const_int_operand" ""))
3630 (match_operator:SI 9 "logical_binary_operator"
3631 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3632 (match_operand:SI 6 "const_int_operand" ""))
3633 (match_operand:SI 7 "s_register_operand" "")])]))
3634 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3636 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3637 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3640 [(ashift:SI (match_dup 2) (match_dup 4))
3644 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3647 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3651 [(set (match_operand:SI 0 "s_register_operand" "")
3652 (match_operator:SI 1 "logical_binary_operator"
3653 [(match_operator:SI 9 "logical_binary_operator"
3654 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3655 (match_operand:SI 6 "const_int_operand" ""))
3656 (match_operand:SI 7 "s_register_operand" "")])
3657 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3658 (match_operand:SI 3 "const_int_operand" "")
3659 (match_operand:SI 4 "const_int_operand" ""))]))
3660 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3662 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3663 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3666 [(ashift:SI (match_dup 2) (match_dup 4))
3670 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3673 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3677 ;; Minimum and maximum insns
3679 (define_expand "smaxsi3"
3681 (set (match_operand:SI 0 "s_register_operand" "")
3682 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3683 (match_operand:SI 2 "arm_rhs_operand" "")))
3684 (clobber (reg:CC CC_REGNUM))])]
3687 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3689 /* No need for a clobber of the condition code register here. */
3690 emit_insn (gen_rtx_SET (operands[0],
3691 gen_rtx_SMAX (SImode, operands[1],
3697 (define_insn "*smax_0"
3698 [(set (match_operand:SI 0 "s_register_operand" "=r")
3699 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3702 "bic%?\\t%0, %1, %1, asr #31"
3703 [(set_attr "predicable" "yes")
3704 (set_attr "predicable_short_it" "no")
3705 (set_attr "type" "logic_shift_reg")]
3708 (define_insn "*smax_m1"
3709 [(set (match_operand:SI 0 "s_register_operand" "=r")
3710 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3713 "orr%?\\t%0, %1, %1, asr #31"
3714 [(set_attr "predicable" "yes")
3715 (set_attr "predicable_short_it" "no")
3716 (set_attr "type" "logic_shift_reg")]
3719 (define_insn_and_split "*arm_smax_insn"
3720 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3721 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3722 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3723 (clobber (reg:CC CC_REGNUM))]
3726 ; cmp\\t%1, %2\;movlt\\t%0, %2
3727 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3729 [(set (reg:CC CC_REGNUM)
3730 (compare:CC (match_dup 1) (match_dup 2)))
3732 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3736 [(set_attr "conds" "clob")
3737 (set_attr "length" "8,12")
3738 (set_attr "type" "multiple")]
3741 (define_expand "sminsi3"
3743 (set (match_operand:SI 0 "s_register_operand" "")
3744 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3745 (match_operand:SI 2 "arm_rhs_operand" "")))
3746 (clobber (reg:CC CC_REGNUM))])]
3749 if (operands[2] == const0_rtx)
3751 /* No need for a clobber of the condition code register here. */
3752 emit_insn (gen_rtx_SET (operands[0],
3753 gen_rtx_SMIN (SImode, operands[1],
3759 (define_insn "*smin_0"
3760 [(set (match_operand:SI 0 "s_register_operand" "=r")
3761 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3764 "and%?\\t%0, %1, %1, asr #31"
3765 [(set_attr "predicable" "yes")
3766 (set_attr "predicable_short_it" "no")
3767 (set_attr "type" "logic_shift_reg")]
3770 (define_insn_and_split "*arm_smin_insn"
3771 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3772 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3773 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3774 (clobber (reg:CC CC_REGNUM))]
3777 ; cmp\\t%1, %2\;movge\\t%0, %2
3778 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3780 [(set (reg:CC CC_REGNUM)
3781 (compare:CC (match_dup 1) (match_dup 2)))
3783 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3787 [(set_attr "conds" "clob")
3788 (set_attr "length" "8,12")
3789 (set_attr "type" "multiple,multiple")]
3792 (define_expand "umaxsi3"
3794 (set (match_operand:SI 0 "s_register_operand" "")
3795 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3796 (match_operand:SI 2 "arm_rhs_operand" "")))
3797 (clobber (reg:CC CC_REGNUM))])]
3802 (define_insn_and_split "*arm_umaxsi3"
3803 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3804 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3805 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3806 (clobber (reg:CC CC_REGNUM))]
3809 ; cmp\\t%1, %2\;movcc\\t%0, %2
3810 ; cmp\\t%1, %2\;movcs\\t%0, %1
3811 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3813 [(set (reg:CC CC_REGNUM)
3814 (compare:CC (match_dup 1) (match_dup 2)))
3816 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3820 [(set_attr "conds" "clob")
3821 (set_attr "length" "8,8,12")
3822 (set_attr "type" "store_4")]
3825 (define_expand "uminsi3"
3827 (set (match_operand:SI 0 "s_register_operand" "")
3828 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3829 (match_operand:SI 2 "arm_rhs_operand" "")))
3830 (clobber (reg:CC CC_REGNUM))])]
3835 (define_insn_and_split "*arm_uminsi3"
3836 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3837 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3838 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3839 (clobber (reg:CC CC_REGNUM))]
3842 ; cmp\\t%1, %2\;movcs\\t%0, %2
3843 ; cmp\\t%1, %2\;movcc\\t%0, %1
3844 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3846 [(set (reg:CC CC_REGNUM)
3847 (compare:CC (match_dup 1) (match_dup 2)))
3849 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3853 [(set_attr "conds" "clob")
3854 (set_attr "length" "8,8,12")
3855 (set_attr "type" "store_4")]
3858 (define_insn "*store_minmaxsi"
3859 [(set (match_operand:SI 0 "memory_operand" "=m")
3860 (match_operator:SI 3 "minmax_operator"
3861 [(match_operand:SI 1 "s_register_operand" "r")
3862 (match_operand:SI 2 "s_register_operand" "r")]))
3863 (clobber (reg:CC CC_REGNUM))]
3864 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3866 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3867 operands[1], operands[2]);
3868 output_asm_insn (\"cmp\\t%1, %2\", operands);
3870 output_asm_insn (\"ite\t%d3\", operands);
3871 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3872 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3875 [(set_attr "conds" "clob")
3876 (set (attr "length")
3877 (if_then_else (eq_attr "is_thumb" "yes")
3880 (set_attr "type" "store_4")]
3883 ; Reject the frame pointer in operand[1], since reloading this after
3884 ; it has been eliminated can cause carnage.
3885 (define_insn "*minmax_arithsi"
3886 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3887 (match_operator:SI 4 "shiftable_operator"
3888 [(match_operator:SI 5 "minmax_operator"
3889 [(match_operand:SI 2 "s_register_operand" "r,r")
3890 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3891 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3892 (clobber (reg:CC CC_REGNUM))]
3893 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3896 enum rtx_code code = GET_CODE (operands[4]);
3899 if (which_alternative != 0 || operands[3] != const0_rtx
3900 || (code != PLUS && code != IOR && code != XOR))
3905 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3906 operands[2], operands[3]);
3907 output_asm_insn (\"cmp\\t%2, %3\", operands);
3911 output_asm_insn (\"ite\\t%d5\", operands);
3913 output_asm_insn (\"it\\t%d5\", operands);
3915 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3917 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3920 [(set_attr "conds" "clob")
3921 (set (attr "length")
3922 (if_then_else (eq_attr "is_thumb" "yes")
3925 (set_attr "type" "multiple")]
3928 ; Reject the frame pointer in operand[1], since reloading this after
3929 ; it has been eliminated can cause carnage.
3930 (define_insn_and_split "*minmax_arithsi_non_canon"
3931 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3933 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3934 (match_operator:SI 4 "minmax_operator"
3935 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3936 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3937 (clobber (reg:CC CC_REGNUM))]
3938 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3939 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3941 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3942 [(set (reg:CC CC_REGNUM)
3943 (compare:CC (match_dup 2) (match_dup 3)))
3945 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3947 (minus:SI (match_dup 1)
3949 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3953 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3954 operands[2], operands[3]);
3955 enum rtx_code rc = minmax_code (operands[4]);
3956 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3957 operands[2], operands[3]);
3959 if (mode == CCFPmode || mode == CCFPEmode)
3960 rc = reverse_condition_maybe_unordered (rc);
3962 rc = reverse_condition (rc);
3963 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3964 if (CONST_INT_P (operands[3]))
3965 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3967 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3969 [(set_attr "conds" "clob")
3970 (set (attr "length")
3971 (if_then_else (eq_attr "is_thumb" "yes")
3974 (set_attr "type" "multiple")]
3977 (define_code_iterator SAT [smin smax])
3978 (define_code_iterator SATrev [smin smax])
3979 (define_code_attr SATlo [(smin "1") (smax "2")])
3980 (define_code_attr SAThi [(smin "2") (smax "1")])
3982 (define_insn "*satsi_<SAT:code>"
3983 [(set (match_operand:SI 0 "s_register_operand" "=r")
3984 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3985 (match_operand:SI 1 "const_int_operand" "i"))
3986 (match_operand:SI 2 "const_int_operand" "i")))]
3987 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3988 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3992 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3993 &mask, &signed_sat))
3996 operands[1] = GEN_INT (mask);
3998 return "ssat%?\t%0, %1, %3";
4000 return "usat%?\t%0, %1, %3";
4002 [(set_attr "predicable" "yes")
4003 (set_attr "predicable_short_it" "no")
4004 (set_attr "type" "alus_imm")]
4007 (define_insn "*satsi_<SAT:code>_shift"
4008 [(set (match_operand:SI 0 "s_register_operand" "=r")
4009 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
4010 [(match_operand:SI 4 "s_register_operand" "r")
4011 (match_operand:SI 5 "const_int_operand" "i")])
4012 (match_operand:SI 1 "const_int_operand" "i"))
4013 (match_operand:SI 2 "const_int_operand" "i")))]
4014 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
4015 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
4019 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
4020 &mask, &signed_sat))
4023 operands[1] = GEN_INT (mask);
4025 return "ssat%?\t%0, %1, %4%S3";
4027 return "usat%?\t%0, %1, %4%S3";
4029 [(set_attr "predicable" "yes")
4030 (set_attr "predicable_short_it" "no")
4031 (set_attr "shift" "3")
4032 (set_attr "type" "logic_shift_reg")])
4034 ;; Shift and rotation insns
4036 (define_expand "ashldi3"
4037 [(set (match_operand:DI 0 "s_register_operand" "")
4038 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
4039 (match_operand:SI 2 "general_operand" "")))]
4044 /* Delay the decision whether to use NEON or core-regs until
4045 register allocation. */
4046 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4051 /* Only the NEON case can handle in-memory shift counts. */
4052 if (!reg_or_int_operand (operands[2], SImode))
4053 operands[2] = force_reg (SImode, operands[2]);
4056 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4057 ; /* No special preparation statements; expand pattern as above. */
4060 rtx scratch1, scratch2;
4062 if (operands[2] == CONST1_RTX (SImode))
4064 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
4068 /* Ideally we should use iwmmxt here if we could know that operands[1]
4069 ends up already living in an iwmmxt register. Otherwise it's
4070 cheaper to have the alternate code being generated than moving
4071 values to iwmmxt regs and back. */
4073 /* Expand operation using core-registers.
4074 'FAIL' would achieve the same thing, but this is a bit smarter. */
4075 scratch1 = gen_reg_rtx (SImode);
4076 scratch2 = gen_reg_rtx (SImode);
4077 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4078 operands[2], scratch1, scratch2);
4084 (define_insn "arm_ashldi3_1bit"
4085 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4086 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4088 (clobber (reg:CC CC_REGNUM))]
4090 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4091 [(set_attr "conds" "clob")
4092 (set_attr "length" "8")
4093 (set_attr "type" "multiple")]
4096 (define_expand "ashlsi3"
4097 [(set (match_operand:SI 0 "s_register_operand" "")
4098 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4099 (match_operand:SI 2 "arm_rhs_operand" "")))]
4102 if (CONST_INT_P (operands[2])
4103 && (UINTVAL (operands[2])) > 31)
4105 emit_insn (gen_movsi (operands[0], const0_rtx));
4111 (define_expand "ashrdi3"
4112 [(set (match_operand:DI 0 "s_register_operand" "")
4113 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4114 (match_operand:SI 2 "reg_or_int_operand" "")))]
4119 /* Delay the decision whether to use NEON or core-regs until
4120 register allocation. */
4121 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4125 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4126 ; /* No special preparation statements; expand pattern as above. */
4129 rtx scratch1, scratch2;
4131 if (operands[2] == CONST1_RTX (SImode))
4133 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4137 /* Ideally we should use iwmmxt here if we could know that operands[1]
4138 ends up already living in an iwmmxt register. Otherwise it's
4139 cheaper to have the alternate code being generated than moving
4140 values to iwmmxt regs and back. */
4142 /* Expand operation using core-registers.
4143 'FAIL' would achieve the same thing, but this is a bit smarter. */
4144 scratch1 = gen_reg_rtx (SImode);
4145 scratch2 = gen_reg_rtx (SImode);
4146 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4147 operands[2], scratch1, scratch2);
4153 (define_insn "arm_ashrdi3_1bit"
4154 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4155 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4157 (clobber (reg:CC CC_REGNUM))]
4159 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4160 [(set_attr "conds" "clob")
4161 (set_attr "length" "8")
4162 (set_attr "type" "multiple")]
4165 (define_expand "ashrsi3"
4166 [(set (match_operand:SI 0 "s_register_operand" "")
4167 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4168 (match_operand:SI 2 "arm_rhs_operand" "")))]
4171 if (CONST_INT_P (operands[2])
4172 && UINTVAL (operands[2]) > 31)
4173 operands[2] = GEN_INT (31);
4177 (define_expand "lshrdi3"
4178 [(set (match_operand:DI 0 "s_register_operand" "")
4179 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4180 (match_operand:SI 2 "reg_or_int_operand" "")))]
4185 /* Delay the decision whether to use NEON or core-regs until
4186 register allocation. */
4187 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4191 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4192 ; /* No special preparation statements; expand pattern as above. */
4195 rtx scratch1, scratch2;
4197 if (operands[2] == CONST1_RTX (SImode))
4199 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4203 /* Ideally we should use iwmmxt here if we could know that operands[1]
4204 ends up already living in an iwmmxt register. Otherwise it's
4205 cheaper to have the alternate code being generated than moving
4206 values to iwmmxt regs and back. */
4208 /* Expand operation using core-registers.
4209 'FAIL' would achieve the same thing, but this is a bit smarter. */
4210 scratch1 = gen_reg_rtx (SImode);
4211 scratch2 = gen_reg_rtx (SImode);
4212 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4213 operands[2], scratch1, scratch2);
4219 (define_insn "arm_lshrdi3_1bit"
4220 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4221 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4223 (clobber (reg:CC CC_REGNUM))]
4225 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4226 [(set_attr "conds" "clob")
4227 (set_attr "length" "8")
4228 (set_attr "type" "multiple")]
4231 (define_expand "lshrsi3"
4232 [(set (match_operand:SI 0 "s_register_operand" "")
4233 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4234 (match_operand:SI 2 "arm_rhs_operand" "")))]
4237 if (CONST_INT_P (operands[2])
4238 && (UINTVAL (operands[2])) > 31)
4240 emit_insn (gen_movsi (operands[0], const0_rtx));
4246 (define_expand "rotlsi3"
4247 [(set (match_operand:SI 0 "s_register_operand" "")
4248 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4249 (match_operand:SI 2 "reg_or_int_operand" "")))]
4252 if (CONST_INT_P (operands[2]))
4253 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4256 rtx reg = gen_reg_rtx (SImode);
4257 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4263 (define_expand "rotrsi3"
4264 [(set (match_operand:SI 0 "s_register_operand" "")
4265 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4266 (match_operand:SI 2 "arm_rhs_operand" "")))]
4271 if (CONST_INT_P (operands[2])
4272 && UINTVAL (operands[2]) > 31)
4273 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4275 else /* TARGET_THUMB1 */
4277 if (CONST_INT_P (operands [2]))
4278 operands [2] = force_reg (SImode, operands[2]);
4283 (define_insn "*arm_shiftsi3"
4284 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4285 (match_operator:SI 3 "shift_operator"
4286 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4287 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4289 "* return arm_output_shift(operands, 0);"
4290 [(set_attr "predicable" "yes")
4291 (set_attr "arch" "t2,t2,*,*")
4292 (set_attr "predicable_short_it" "yes,yes,no,no")
4293 (set_attr "length" "4")
4294 (set_attr "shift" "1")
4295 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4298 (define_insn "*shiftsi3_compare0"
4299 [(set (reg:CC_NOOV CC_REGNUM)
4300 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4301 [(match_operand:SI 1 "s_register_operand" "r,r")
4302 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4304 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4305 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4307 "* return arm_output_shift(operands, 1);"
4308 [(set_attr "conds" "set")
4309 (set_attr "shift" "1")
4310 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4313 (define_insn "*shiftsi3_compare0_scratch"
4314 [(set (reg:CC_NOOV CC_REGNUM)
4315 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4316 [(match_operand:SI 1 "s_register_operand" "r,r")
4317 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4319 (clobber (match_scratch:SI 0 "=r,r"))]
4321 "* return arm_output_shift(operands, 1);"
4322 [(set_attr "conds" "set")
4323 (set_attr "shift" "1")
4324 (set_attr "type" "shift_imm,shift_reg")]
4327 (define_insn "*not_shiftsi"
4328 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4329 (not:SI (match_operator:SI 3 "shift_operator"
4330 [(match_operand:SI 1 "s_register_operand" "r,r")
4331 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4334 [(set_attr "predicable" "yes")
4335 (set_attr "predicable_short_it" "no")
4336 (set_attr "shift" "1")
4337 (set_attr "arch" "32,a")
4338 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4340 (define_insn "*not_shiftsi_compare0"
4341 [(set (reg:CC_NOOV CC_REGNUM)
4343 (not:SI (match_operator:SI 3 "shift_operator"
4344 [(match_operand:SI 1 "s_register_operand" "r,r")
4345 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4347 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4348 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4350 "mvns%?\\t%0, %1%S3"
4351 [(set_attr "conds" "set")
4352 (set_attr "shift" "1")
4353 (set_attr "arch" "32,a")
4354 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4356 (define_insn "*not_shiftsi_compare0_scratch"
4357 [(set (reg:CC_NOOV CC_REGNUM)
4359 (not:SI (match_operator:SI 3 "shift_operator"
4360 [(match_operand:SI 1 "s_register_operand" "r,r")
4361 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4363 (clobber (match_scratch:SI 0 "=r,r"))]
4365 "mvns%?\\t%0, %1%S3"
4366 [(set_attr "conds" "set")
4367 (set_attr "shift" "1")
4368 (set_attr "arch" "32,a")
4369 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4371 ;; We don't really have extzv, but defining this using shifts helps
4372 ;; to reduce register pressure later on.
4374 (define_expand "extzv"
4375 [(set (match_operand 0 "s_register_operand" "")
4376 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4377 (match_operand 2 "const_int_operand" "")
4378 (match_operand 3 "const_int_operand" "")))]
4379 "TARGET_THUMB1 || arm_arch_thumb2"
4382 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4383 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4385 if (arm_arch_thumb2)
4387 HOST_WIDE_INT width = INTVAL (operands[2]);
4388 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4390 if (unaligned_access && MEM_P (operands[1])
4391 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4395 if (BYTES_BIG_ENDIAN)
4396 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4401 base_addr = adjust_address (operands[1], SImode,
4402 bitpos / BITS_PER_UNIT);
4403 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4407 rtx dest = operands[0];
4408 rtx tmp = gen_reg_rtx (SImode);
4410 /* We may get a paradoxical subreg here. Strip it off. */
4411 if (GET_CODE (dest) == SUBREG
4412 && GET_MODE (dest) == SImode
4413 && GET_MODE (SUBREG_REG (dest)) == HImode)
4414 dest = SUBREG_REG (dest);
4416 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4419 base_addr = adjust_address (operands[1], HImode,
4420 bitpos / BITS_PER_UNIT);
4421 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4422 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4426 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4428 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4436 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4439 operands[3] = GEN_INT (rshift);
4443 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4447 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4448 operands[3], gen_reg_rtx (SImode)));
4453 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4455 (define_expand "extzv_t1"
4456 [(set (match_operand:SI 4 "s_register_operand" "")
4457 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4458 (match_operand:SI 2 "const_int_operand" "")))
4459 (set (match_operand:SI 0 "s_register_operand" "")
4460 (lshiftrt:SI (match_dup 4)
4461 (match_operand:SI 3 "const_int_operand" "")))]
4465 (define_expand "extv"
4466 [(set (match_operand 0 "s_register_operand" "")
4467 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4468 (match_operand 2 "const_int_operand" "")
4469 (match_operand 3 "const_int_operand" "")))]
4472 HOST_WIDE_INT width = INTVAL (operands[2]);
4473 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4475 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4476 && (bitpos % BITS_PER_UNIT) == 0)
4480 if (BYTES_BIG_ENDIAN)
4481 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4485 base_addr = adjust_address (operands[1], SImode,
4486 bitpos / BITS_PER_UNIT);
4487 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4491 rtx dest = operands[0];
4492 rtx tmp = gen_reg_rtx (SImode);
4494 /* We may get a paradoxical subreg here. Strip it off. */
4495 if (GET_CODE (dest) == SUBREG
4496 && GET_MODE (dest) == SImode
4497 && GET_MODE (SUBREG_REG (dest)) == HImode)
4498 dest = SUBREG_REG (dest);
4500 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4503 base_addr = adjust_address (operands[1], HImode,
4504 bitpos / BITS_PER_UNIT);
4505 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4506 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4511 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4513 else if (GET_MODE (operands[0]) == SImode
4514 && GET_MODE (operands[1]) == SImode)
4516 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4524 ; Helper to expand register forms of extv with the proper modes.
4526 (define_expand "extv_regsi"
4527 [(set (match_operand:SI 0 "s_register_operand" "")
4528 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4529 (match_operand 2 "const_int_operand" "")
4530 (match_operand 3 "const_int_operand" "")))]
4535 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4537 (define_insn "unaligned_loadsi"
4538 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4539 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4540 UNSPEC_UNALIGNED_LOAD))]
4542 "ldr%?\t%0, %1\t@ unaligned"
4543 [(set_attr "arch" "t2,any")
4544 (set_attr "length" "2,4")
4545 (set_attr "predicable" "yes")
4546 (set_attr "predicable_short_it" "yes,no")
4547 (set_attr "type" "load_4")])
4549 (define_insn "unaligned_loadhis"
4550 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4552 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4553 UNSPEC_UNALIGNED_LOAD)))]
4555 "ldrsh%?\t%0, %1\t@ unaligned"
4556 [(set_attr "arch" "t2,any")
4557 (set_attr "length" "2,4")
4558 (set_attr "predicable" "yes")
4559 (set_attr "predicable_short_it" "yes,no")
4560 (set_attr "type" "load_byte")])
4562 (define_insn "unaligned_loadhiu"
4563 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4565 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4566 UNSPEC_UNALIGNED_LOAD)))]
4568 "ldrh%?\t%0, %1\t@ unaligned"
4569 [(set_attr "arch" "t2,any")
4570 (set_attr "length" "2,4")
4571 (set_attr "predicable" "yes")
4572 (set_attr "predicable_short_it" "yes,no")
4573 (set_attr "type" "load_byte")])
4575 (define_insn "unaligned_storesi"
4576 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4577 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4578 UNSPEC_UNALIGNED_STORE))]
4580 "str%?\t%1, %0\t@ unaligned"
4581 [(set_attr "arch" "t2,any")
4582 (set_attr "length" "2,4")
4583 (set_attr "predicable" "yes")
4584 (set_attr "predicable_short_it" "yes,no")
4585 (set_attr "type" "store_4")])
4587 (define_insn "unaligned_storehi"
4588 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4589 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4590 UNSPEC_UNALIGNED_STORE))]
4592 "strh%?\t%1, %0\t@ unaligned"
4593 [(set_attr "arch" "t2,any")
4594 (set_attr "length" "2,4")
4595 (set_attr "predicable" "yes")
4596 (set_attr "predicable_short_it" "yes,no")
4597 (set_attr "type" "store_4")])
4600 (define_insn "*extv_reg"
4601 [(set (match_operand:SI 0 "s_register_operand" "=r")
4602 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4603 (match_operand:SI 2 "const_int_operand" "n")
4604 (match_operand:SI 3 "const_int_operand" "n")))]
4606 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4607 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4608 "sbfx%?\t%0, %1, %3, %2"
4609 [(set_attr "length" "4")
4610 (set_attr "predicable" "yes")
4611 (set_attr "predicable_short_it" "no")
4612 (set_attr "type" "bfm")]
4615 (define_insn "extzv_t2"
4616 [(set (match_operand:SI 0 "s_register_operand" "=r")
4617 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4618 (match_operand:SI 2 "const_int_operand" "n")
4619 (match_operand:SI 3 "const_int_operand" "n")))]
4621 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4622 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4623 "ubfx%?\t%0, %1, %3, %2"
4624 [(set_attr "length" "4")
4625 (set_attr "predicable" "yes")
4626 (set_attr "predicable_short_it" "no")
4627 (set_attr "type" "bfm")]
4631 ;; Division instructions
4632 (define_insn "divsi3"
4633 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4634 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4635 (match_operand:SI 2 "s_register_operand" "r,r")))]
4640 [(set_attr "arch" "32,v8mb")
4641 (set_attr "predicable" "yes")
4642 (set_attr "predicable_short_it" "no")
4643 (set_attr "type" "sdiv")]
4646 (define_insn "udivsi3"
4647 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4648 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4649 (match_operand:SI 2 "s_register_operand" "r,r")))]
4654 [(set_attr "arch" "32,v8mb")
4655 (set_attr "predicable" "yes")
4656 (set_attr "predicable_short_it" "no")
4657 (set_attr "type" "udiv")]
4661 ;; Unary arithmetic insns
4663 (define_expand "negvsi3"
4664 [(match_operand:SI 0 "register_operand")
4665 (match_operand:SI 1 "register_operand")
4666 (match_operand 2 "")]
4669 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4670 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4675 (define_expand "negvdi3"
4676 [(match_operand:DI 0 "register_operand")
4677 (match_operand:DI 1 "register_operand")
4678 (match_operand 2 "")]
4681 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4682 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4688 (define_insn_and_split "negdi2_compare"
4689 [(set (reg:CC CC_REGNUM)
4692 (match_operand:DI 1 "register_operand" "0,r")))
4693 (set (match_operand:DI 0 "register_operand" "=r,&r")
4694 (minus:DI (const_int 0) (match_dup 1)))]
4697 "&& reload_completed"
4698 [(parallel [(set (reg:CC CC_REGNUM)
4699 (compare:CC (const_int 0) (match_dup 1)))
4700 (set (match_dup 0) (minus:SI (const_int 0)
4702 (parallel [(set (reg:CC CC_REGNUM)
4703 (compare:CC (const_int 0) (match_dup 3)))
4706 (minus:SI (const_int 0) (match_dup 3))
4707 (ltu:SI (reg:CC_C CC_REGNUM)
4710 operands[2] = gen_highpart (SImode, operands[0]);
4711 operands[0] = gen_lowpart (SImode, operands[0]);
4712 operands[3] = gen_highpart (SImode, operands[1]);
4713 operands[1] = gen_lowpart (SImode, operands[1]);
4715 [(set_attr "conds" "set")
4716 (set_attr "length" "8")
4717 (set_attr "type" "multiple")]
4720 (define_expand "negdi2"
4722 [(set (match_operand:DI 0 "s_register_operand" "")
4723 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4724 (clobber (reg:CC CC_REGNUM))])]
4729 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4735 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4736 ;; The first alternative allows the common case of a *full* overlap.
4737 (define_insn_and_split "*negdi2_insn"
4738 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4739 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4740 (clobber (reg:CC CC_REGNUM))]
4742 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4743 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4744 "&& reload_completed"
4745 [(parallel [(set (reg:CC CC_REGNUM)
4746 (compare:CC (const_int 0) (match_dup 1)))
4747 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4748 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4749 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4751 operands[2] = gen_highpart (SImode, operands[0]);
4752 operands[0] = gen_lowpart (SImode, operands[0]);
4753 operands[3] = gen_highpart (SImode, operands[1]);
4754 operands[1] = gen_lowpart (SImode, operands[1]);
4756 [(set_attr "conds" "clob")
4757 (set_attr "length" "8")
4758 (set_attr "type" "multiple")]
4761 (define_insn "*negsi2_carryin_compare"
4762 [(set (reg:CC CC_REGNUM)
4763 (compare:CC (const_int 0)
4764 (match_operand:SI 1 "s_register_operand" "r")))
4765 (set (match_operand:SI 0 "s_register_operand" "=r")
4766 (minus:SI (minus:SI (const_int 0)
4768 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4771 [(set_attr "conds" "set")
4772 (set_attr "type" "alus_imm")]
4775 (define_expand "negsi2"
4776 [(set (match_operand:SI 0 "s_register_operand" "")
4777 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4782 (define_insn "*arm_negsi2"
4783 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4784 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4786 "rsb%?\\t%0, %1, #0"
4787 [(set_attr "predicable" "yes")
4788 (set_attr "predicable_short_it" "yes,no")
4789 (set_attr "arch" "t2,*")
4790 (set_attr "length" "4")
4791 (set_attr "type" "alu_sreg")]
4794 (define_expand "negsf2"
4795 [(set (match_operand:SF 0 "s_register_operand" "")
4796 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4797 "TARGET_32BIT && TARGET_HARD_FLOAT"
4801 (define_expand "negdf2"
4802 [(set (match_operand:DF 0 "s_register_operand" "")
4803 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4804 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4807 (define_insn_and_split "*zextendsidi_negsi"
4808 [(set (match_operand:DI 0 "s_register_operand" "=r")
4809 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4814 (neg:SI (match_dup 1)))
4818 operands[2] = gen_lowpart (SImode, operands[0]);
4819 operands[3] = gen_highpart (SImode, operands[0]);
4821 [(set_attr "length" "8")
4822 (set_attr "type" "multiple")]
4825 ;; Negate an extended 32-bit value.
4826 (define_insn_and_split "*negdi_extendsidi"
4827 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4828 (neg:DI (sign_extend:DI
4829 (match_operand:SI 1 "s_register_operand" "l,r"))))
4830 (clobber (reg:CC CC_REGNUM))]
4833 "&& reload_completed"
4836 rtx low = gen_lowpart (SImode, operands[0]);
4837 rtx high = gen_highpart (SImode, operands[0]);
4839 if (reg_overlap_mentioned_p (low, operands[1]))
4841 /* Input overlaps the low word of the output. Use:
4844 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4845 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4847 emit_insn (gen_rtx_SET (high,
4848 gen_rtx_ASHIFTRT (SImode, operands[1],
4851 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4853 emit_insn (gen_rtx_SET (high,
4854 gen_rtx_MINUS (SImode,
4855 gen_rtx_MINUS (SImode,
4858 gen_rtx_LTU (SImode,
4863 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4864 emit_insn (gen_rtx_SET (high,
4865 gen_rtx_MINUS (SImode,
4866 gen_rtx_MINUS (SImode,
4869 gen_rtx_LTU (SImode,
4876 /* No overlap, or overlap on high word. Use:
4880 Flags not needed for this sequence. */
4881 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4882 emit_insn (gen_rtx_SET (high,
4883 gen_rtx_AND (SImode,
4884 gen_rtx_NOT (SImode, operands[1]),
4886 emit_insn (gen_rtx_SET (high,
4887 gen_rtx_ASHIFTRT (SImode, high,
4892 [(set_attr "length" "12")
4893 (set_attr "arch" "t2,*")
4894 (set_attr "type" "multiple")]
4897 (define_insn_and_split "*negdi_zero_extendsidi"
4898 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4899 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4900 (clobber (reg:CC CC_REGNUM))]
4902 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4903 ;; Don't care what register is input to sbc,
4904 ;; since we just need to propagate the carry.
4905 "&& reload_completed"
4906 [(parallel [(set (reg:CC CC_REGNUM)
4907 (compare:CC (const_int 0) (match_dup 1)))
4908 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4909 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4910 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4912 operands[2] = gen_highpart (SImode, operands[0]);
4913 operands[0] = gen_lowpart (SImode, operands[0]);
4915 [(set_attr "conds" "clob")
4916 (set_attr "length" "8")
4917 (set_attr "type" "multiple")] ;; length in thumb is 4
4920 ;; abssi2 doesn't really clobber the condition codes if a different register
4921 ;; is being set. To keep things simple, assume during rtl manipulations that
4922 ;; it does, but tell the final scan operator the truth. Similarly for
4925 (define_expand "abssi2"
4927 [(set (match_operand:SI 0 "s_register_operand" "")
4928 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4929 (clobber (match_dup 2))])]
4933 operands[2] = gen_rtx_SCRATCH (SImode);
4935 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4938 (define_insn_and_split "*arm_abssi2"
4939 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4940 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4941 (clobber (reg:CC CC_REGNUM))]
4944 "&& reload_completed"
4947 /* if (which_alternative == 0) */
4948 if (REGNO(operands[0]) == REGNO(operands[1]))
4950 /* Emit the pattern:
4951 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4952 [(set (reg:CC CC_REGNUM)
4953 (compare:CC (match_dup 0) (const_int 0)))
4954 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4955 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4957 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4958 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4959 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4960 (gen_rtx_LT (SImode,
4961 gen_rtx_REG (CCmode, CC_REGNUM),
4963 (gen_rtx_SET (operands[0],
4964 (gen_rtx_MINUS (SImode,
4971 /* Emit the pattern:
4972 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4974 (xor:SI (match_dup 1)
4975 (ashiftrt:SI (match_dup 1) (const_int 31))))
4977 (minus:SI (match_dup 0)
4978 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4980 emit_insn (gen_rtx_SET (operands[0],
4981 gen_rtx_XOR (SImode,
4982 gen_rtx_ASHIFTRT (SImode,
4986 emit_insn (gen_rtx_SET (operands[0],
4987 gen_rtx_MINUS (SImode,
4989 gen_rtx_ASHIFTRT (SImode,
4995 [(set_attr "conds" "clob,*")
4996 (set_attr "shift" "1")
4997 (set_attr "predicable" "no, yes")
4998 (set_attr "length" "8")
4999 (set_attr "type" "multiple")]
5002 (define_insn_and_split "*arm_neg_abssi2"
5003 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
5004 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
5005 (clobber (reg:CC CC_REGNUM))]
5008 "&& reload_completed"
5011 /* if (which_alternative == 0) */
5012 if (REGNO (operands[0]) == REGNO (operands[1]))
5014 /* Emit the pattern:
5015 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
5017 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
5018 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
5019 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
5021 gen_rtx_REG (CCmode, CC_REGNUM),
5023 gen_rtx_SET (operands[0],
5024 (gen_rtx_MINUS (SImode,
5030 /* Emit the pattern:
5031 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
5033 emit_insn (gen_rtx_SET (operands[0],
5034 gen_rtx_XOR (SImode,
5035 gen_rtx_ASHIFTRT (SImode,
5039 emit_insn (gen_rtx_SET (operands[0],
5040 gen_rtx_MINUS (SImode,
5041 gen_rtx_ASHIFTRT (SImode,
5048 [(set_attr "conds" "clob,*")
5049 (set_attr "shift" "1")
5050 (set_attr "predicable" "no, yes")
5051 (set_attr "length" "8")
5052 (set_attr "type" "multiple")]
5055 (define_expand "abssf2"
5056 [(set (match_operand:SF 0 "s_register_operand" "")
5057 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5058 "TARGET_32BIT && TARGET_HARD_FLOAT"
5061 (define_expand "absdf2"
5062 [(set (match_operand:DF 0 "s_register_operand" "")
5063 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5064 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5067 (define_expand "sqrtsf2"
5068 [(set (match_operand:SF 0 "s_register_operand" "")
5069 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5070 "TARGET_32BIT && TARGET_HARD_FLOAT"
5073 (define_expand "sqrtdf2"
5074 [(set (match_operand:DF 0 "s_register_operand" "")
5075 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5076 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5079 (define_expand "one_cmpldi2"
5080 [(set (match_operand:DI 0 "s_register_operand" "")
5081 (not:DI (match_operand:DI 1 "s_register_operand" "")))]
5084 if (!TARGET_NEON && !TARGET_IWMMXT)
5086 rtx low = simplify_gen_unary (NOT, SImode,
5087 gen_lowpart (SImode, operands[1]),
5089 rtx high = simplify_gen_unary (NOT, SImode,
5090 gen_highpart_mode (SImode, DImode,
5094 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5095 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5099 /* Otherwise expand pattern as above. */
5103 (define_insn_and_split "*one_cmpldi2_insn"
5104 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5105 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5112 "TARGET_32BIT && reload_completed
5113 && arm_general_register_operand (operands[0], DImode)"
5114 [(set (match_dup 0) (not:SI (match_dup 1)))
5115 (set (match_dup 2) (not:SI (match_dup 3)))]
5118 operands[2] = gen_highpart (SImode, operands[0]);
5119 operands[0] = gen_lowpart (SImode, operands[0]);
5120 operands[3] = gen_highpart (SImode, operands[1]);
5121 operands[1] = gen_lowpart (SImode, operands[1]);
5123 [(set_attr "length" "*,8,8,*")
5124 (set_attr "predicable" "no,yes,yes,no")
5125 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5126 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5129 (define_expand "one_cmplsi2"
5130 [(set (match_operand:SI 0 "s_register_operand" "")
5131 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5136 (define_insn "*arm_one_cmplsi2"
5137 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5138 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5141 [(set_attr "predicable" "yes")
5142 (set_attr "predicable_short_it" "yes,no")
5143 (set_attr "arch" "t2,*")
5144 (set_attr "length" "4")
5145 (set_attr "type" "mvn_reg")]
5148 (define_insn "*notsi_compare0"
5149 [(set (reg:CC_NOOV CC_REGNUM)
5150 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5152 (set (match_operand:SI 0 "s_register_operand" "=r")
5153 (not:SI (match_dup 1)))]
5156 [(set_attr "conds" "set")
5157 (set_attr "type" "mvn_reg")]
5160 (define_insn "*notsi_compare0_scratch"
5161 [(set (reg:CC_NOOV CC_REGNUM)
5162 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5164 (clobber (match_scratch:SI 0 "=r"))]
5167 [(set_attr "conds" "set")
5168 (set_attr "type" "mvn_reg")]
5171 ;; Fixed <--> Floating conversion insns
5173 (define_expand "floatsihf2"
5174 [(set (match_operand:HF 0 "general_operand" "")
5175 (float:HF (match_operand:SI 1 "general_operand" "")))]
5179 rtx op1 = gen_reg_rtx (SFmode);
5180 expand_float (op1, operands[1], 0);
5181 op1 = convert_to_mode (HFmode, op1, 0);
5182 emit_move_insn (operands[0], op1);
5187 (define_expand "floatdihf2"
5188 [(set (match_operand:HF 0 "general_operand" "")
5189 (float:HF (match_operand:DI 1 "general_operand" "")))]
5193 rtx op1 = gen_reg_rtx (SFmode);
5194 expand_float (op1, operands[1], 0);
5195 op1 = convert_to_mode (HFmode, op1, 0);
5196 emit_move_insn (operands[0], op1);
5201 (define_expand "floatsisf2"
5202 [(set (match_operand:SF 0 "s_register_operand" "")
5203 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5204 "TARGET_32BIT && TARGET_HARD_FLOAT"
5208 (define_expand "floatsidf2"
5209 [(set (match_operand:DF 0 "s_register_operand" "")
5210 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5211 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5215 (define_expand "fix_trunchfsi2"
5216 [(set (match_operand:SI 0 "general_operand" "")
5217 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5221 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5222 expand_fix (operands[0], op1, 0);
5227 (define_expand "fix_trunchfdi2"
5228 [(set (match_operand:DI 0 "general_operand" "")
5229 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5233 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5234 expand_fix (operands[0], op1, 0);
5239 (define_expand "fix_truncsfsi2"
5240 [(set (match_operand:SI 0 "s_register_operand" "")
5241 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5242 "TARGET_32BIT && TARGET_HARD_FLOAT"
5246 (define_expand "fix_truncdfsi2"
5247 [(set (match_operand:SI 0 "s_register_operand" "")
5248 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5249 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5255 (define_expand "truncdfsf2"
5256 [(set (match_operand:SF 0 "s_register_operand" "")
5258 (match_operand:DF 1 "s_register_operand" "")))]
5259 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5263 ;; DFmode to HFmode conversions on targets without a single-step hardware
5264 ;; instruction for it would have to go through SFmode. This is dangerous
5265 ;; as it introduces double rounding.
5267 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5268 ;; a single-step instruction.
5270 (define_expand "truncdfhf2"
5271 [(set (match_operand:HF 0 "s_register_operand" "")
5273 (match_operand:DF 1 "s_register_operand" "")))]
5274 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5275 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5277 /* We don't have a direct instruction for this, so we must be in
5278 an unsafe math mode, and going via SFmode. */
5280 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5283 op1 = convert_to_mode (SFmode, operands[1], 0);
5284 op1 = convert_to_mode (HFmode, op1, 0);
5285 emit_move_insn (operands[0], op1);
5288 /* Otherwise, we will pick this up as a single instruction with
5289 no intermediary rounding. */
5293 ;; Zero and sign extension instructions.
5295 (define_insn "zero_extend<mode>di2"
5296 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5297 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5298 "<qhs_zextenddi_cstr>")))]
5299 "TARGET_32BIT <qhs_zextenddi_cond>"
5301 [(set_attr "length" "8,4,8,8")
5302 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5303 (set_attr "ce_count" "2")
5304 (set_attr "predicable" "yes")
5305 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5308 (define_insn "extend<mode>di2"
5309 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5310 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5311 "<qhs_extenddi_cstr>")))]
5312 "TARGET_32BIT <qhs_sextenddi_cond>"
5314 [(set_attr "length" "8,4,8,8,8")
5315 (set_attr "ce_count" "2")
5316 (set_attr "shift" "1")
5317 (set_attr "predicable" "yes")
5318 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5319 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5322 ;; Splits for all extensions to DImode
5324 [(set (match_operand:DI 0 "s_register_operand" "")
5325 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5326 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5327 [(set (match_dup 0) (match_dup 1))]
5329 rtx lo_part = gen_lowpart (SImode, operands[0]);
5330 machine_mode src_mode = GET_MODE (operands[1]);
5332 if (REG_P (operands[0])
5333 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5334 emit_clobber (operands[0]);
5335 if (!REG_P (lo_part) || src_mode != SImode
5336 || !rtx_equal_p (lo_part, operands[1]))
5338 if (src_mode == SImode)
5339 emit_move_insn (lo_part, operands[1]);
5341 emit_insn (gen_rtx_SET (lo_part,
5342 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5343 operands[1] = lo_part;
5345 operands[0] = gen_highpart (SImode, operands[0]);
5346 operands[1] = const0_rtx;
5350 [(set (match_operand:DI 0 "s_register_operand" "")
5351 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5352 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5353 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5355 rtx lo_part = gen_lowpart (SImode, operands[0]);
5356 machine_mode src_mode = GET_MODE (operands[1]);
5358 if (REG_P (operands[0])
5359 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5360 emit_clobber (operands[0]);
5362 if (!REG_P (lo_part) || src_mode != SImode
5363 || !rtx_equal_p (lo_part, operands[1]))
5365 if (src_mode == SImode)
5366 emit_move_insn (lo_part, operands[1]);
5368 emit_insn (gen_rtx_SET (lo_part,
5369 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5370 operands[1] = lo_part;
5372 operands[0] = gen_highpart (SImode, operands[0]);
5375 (define_expand "zero_extendhisi2"
5376 [(set (match_operand:SI 0 "s_register_operand" "")
5377 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5380 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5382 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5385 if (!arm_arch6 && !MEM_P (operands[1]))
5387 rtx t = gen_lowpart (SImode, operands[1]);
5388 rtx tmp = gen_reg_rtx (SImode);
5389 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5390 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5396 [(set (match_operand:SI 0 "s_register_operand" "")
5397 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5398 "!TARGET_THUMB2 && !arm_arch6"
5399 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5400 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5402 operands[2] = gen_lowpart (SImode, operands[1]);
5405 (define_insn "*arm_zero_extendhisi2"
5406 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5407 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5408 "TARGET_ARM && arm_arch4 && !arm_arch6"
5412 [(set_attr "type" "alu_shift_reg,load_byte")
5413 (set_attr "predicable" "yes")]
5416 (define_insn "*arm_zero_extendhisi2_v6"
5417 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5418 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5419 "TARGET_ARM && arm_arch6"
5423 [(set_attr "predicable" "yes")
5424 (set_attr "type" "extend,load_byte")]
5427 (define_insn "*arm_zero_extendhisi2addsi"
5428 [(set (match_operand:SI 0 "s_register_operand" "=r")
5429 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5430 (match_operand:SI 2 "s_register_operand" "r")))]
5432 "uxtah%?\\t%0, %2, %1"
5433 [(set_attr "type" "alu_shift_reg")
5434 (set_attr "predicable" "yes")
5435 (set_attr "predicable_short_it" "no")]
5438 (define_expand "zero_extendqisi2"
5439 [(set (match_operand:SI 0 "s_register_operand" "")
5440 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5443 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5445 emit_insn (gen_andsi3 (operands[0],
5446 gen_lowpart (SImode, operands[1]),
5450 if (!arm_arch6 && !MEM_P (operands[1]))
5452 rtx t = gen_lowpart (SImode, operands[1]);
5453 rtx tmp = gen_reg_rtx (SImode);
5454 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5455 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5461 [(set (match_operand:SI 0 "s_register_operand" "")
5462 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5464 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5465 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5467 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5470 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5475 (define_insn "*arm_zero_extendqisi2"
5476 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5477 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5478 "TARGET_ARM && !arm_arch6"
5481 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5482 [(set_attr "length" "8,4")
5483 (set_attr "type" "alu_shift_reg,load_byte")
5484 (set_attr "predicable" "yes")]
5487 (define_insn "*arm_zero_extendqisi2_v6"
5488 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5489 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5490 "TARGET_ARM && arm_arch6"
5493 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5494 [(set_attr "type" "extend,load_byte")
5495 (set_attr "predicable" "yes")]
5498 (define_insn "*arm_zero_extendqisi2addsi"
5499 [(set (match_operand:SI 0 "s_register_operand" "=r")
5500 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5501 (match_operand:SI 2 "s_register_operand" "r")))]
5503 "uxtab%?\\t%0, %2, %1"
5504 [(set_attr "predicable" "yes")
5505 (set_attr "predicable_short_it" "no")
5506 (set_attr "type" "alu_shift_reg")]
5510 [(set (match_operand:SI 0 "s_register_operand" "")
5511 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5512 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5513 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5514 [(set (match_dup 2) (match_dup 1))
5515 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5520 [(set (match_operand:SI 0 "s_register_operand" "")
5521 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5522 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5523 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5524 [(set (match_dup 2) (match_dup 1))
5525 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5531 [(set (match_operand:SI 0 "s_register_operand" "")
5532 (IOR_XOR:SI (and:SI (ashift:SI
5533 (match_operand:SI 1 "s_register_operand" "")
5534 (match_operand:SI 2 "const_int_operand" ""))
5535 (match_operand:SI 3 "const_int_operand" ""))
5537 (match_operator 5 "subreg_lowpart_operator"
5538 [(match_operand:SI 4 "s_register_operand" "")]))))]
5540 && (UINTVAL (operands[3])
5541 == (GET_MODE_MASK (GET_MODE (operands[5]))
5542 & (GET_MODE_MASK (GET_MODE (operands[5]))
5543 << (INTVAL (operands[2])))))"
5544 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5546 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5547 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5550 (define_insn "*compareqi_eq0"
5551 [(set (reg:CC_Z CC_REGNUM)
5552 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5556 [(set_attr "conds" "set")
5557 (set_attr "predicable" "yes")
5558 (set_attr "predicable_short_it" "no")
5559 (set_attr "type" "logic_imm")]
5562 (define_expand "extendhisi2"
5563 [(set (match_operand:SI 0 "s_register_operand" "")
5564 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5569 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5572 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5574 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5578 if (!arm_arch6 && !MEM_P (operands[1]))
5580 rtx t = gen_lowpart (SImode, operands[1]);
5581 rtx tmp = gen_reg_rtx (SImode);
5582 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5583 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5590 [(set (match_operand:SI 0 "register_operand" "")
5591 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5592 (clobber (match_scratch:SI 2 ""))])]
5594 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5595 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5597 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5600 ;; This pattern will only be used when ldsh is not available
5601 (define_expand "extendhisi2_mem"
5602 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5604 (zero_extend:SI (match_dup 7)))
5605 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5606 (set (match_operand:SI 0 "" "")
5607 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5612 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5614 mem1 = change_address (operands[1], QImode, addr);
5615 mem2 = change_address (operands[1], QImode,
5616 plus_constant (Pmode, addr, 1));
5617 operands[0] = gen_lowpart (SImode, operands[0]);
5619 operands[2] = gen_reg_rtx (SImode);
5620 operands[3] = gen_reg_rtx (SImode);
5621 operands[6] = gen_reg_rtx (SImode);
5624 if (BYTES_BIG_ENDIAN)
5626 operands[4] = operands[2];
5627 operands[5] = operands[3];
5631 operands[4] = operands[3];
5632 operands[5] = operands[2];
5638 [(set (match_operand:SI 0 "register_operand" "")
5639 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5641 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5642 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5644 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5647 (define_insn "*arm_extendhisi2"
5648 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5649 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5650 "TARGET_ARM && arm_arch4 && !arm_arch6"
5654 [(set_attr "length" "8,4")
5655 (set_attr "type" "alu_shift_reg,load_byte")
5656 (set_attr "predicable" "yes")]
5659 ;; ??? Check Thumb-2 pool range
5660 (define_insn "*arm_extendhisi2_v6"
5661 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5662 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5663 "TARGET_32BIT && arm_arch6"
5667 [(set_attr "type" "extend,load_byte")
5668 (set_attr "predicable" "yes")
5669 (set_attr "predicable_short_it" "no")]
5672 (define_insn "*arm_extendhisi2addsi"
5673 [(set (match_operand:SI 0 "s_register_operand" "=r")
5674 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5675 (match_operand:SI 2 "s_register_operand" "r")))]
5677 "sxtah%?\\t%0, %2, %1"
5678 [(set_attr "type" "alu_shift_reg")]
5681 (define_expand "extendqihi2"
5683 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5685 (set (match_operand:HI 0 "s_register_operand" "")
5686 (ashiftrt:SI (match_dup 2)
5691 if (arm_arch4 && MEM_P (operands[1]))
5693 emit_insn (gen_rtx_SET (operands[0],
5694 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5697 if (!s_register_operand (operands[1], QImode))
5698 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5699 operands[0] = gen_lowpart (SImode, operands[0]);
5700 operands[1] = gen_lowpart (SImode, operands[1]);
5701 operands[2] = gen_reg_rtx (SImode);
5705 (define_insn "*arm_extendqihi_insn"
5706 [(set (match_operand:HI 0 "s_register_operand" "=r")
5707 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5708 "TARGET_ARM && arm_arch4"
5710 [(set_attr "type" "load_byte")
5711 (set_attr "predicable" "yes")]
5714 (define_expand "extendqisi2"
5715 [(set (match_operand:SI 0 "s_register_operand" "")
5716 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5719 if (!arm_arch4 && MEM_P (operands[1]))
5720 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5722 if (!arm_arch6 && !MEM_P (operands[1]))
5724 rtx t = gen_lowpart (SImode, operands[1]);
5725 rtx tmp = gen_reg_rtx (SImode);
5726 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5727 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5733 [(set (match_operand:SI 0 "register_operand" "")
5734 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5736 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5737 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5739 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5742 (define_insn "*arm_extendqisi"
5743 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5744 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5745 "TARGET_ARM && arm_arch4 && !arm_arch6"
5749 [(set_attr "length" "8,4")
5750 (set_attr "type" "alu_shift_reg,load_byte")
5751 (set_attr "predicable" "yes")]
5754 (define_insn "*arm_extendqisi_v6"
5755 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5757 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5758 "TARGET_ARM && arm_arch6"
5762 [(set_attr "type" "extend,load_byte")
5763 (set_attr "predicable" "yes")]
5766 (define_insn "*arm_extendqisi2addsi"
5767 [(set (match_operand:SI 0 "s_register_operand" "=r")
5768 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5769 (match_operand:SI 2 "s_register_operand" "r")))]
5771 "sxtab%?\\t%0, %2, %1"
5772 [(set_attr "type" "alu_shift_reg")
5773 (set_attr "predicable" "yes")
5774 (set_attr "predicable_short_it" "no")]
5777 (define_expand "extendsfdf2"
5778 [(set (match_operand:DF 0 "s_register_operand" "")
5779 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5780 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5784 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5785 ;; must go through SFmode.
5787 ;; This is always safe for an extend.
5789 (define_expand "extendhfdf2"
5790 [(set (match_operand:DF 0 "s_register_operand" "")
5791 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5794 /* We don't have a direct instruction for this, so go via SFmode. */
5795 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5798 op1 = convert_to_mode (SFmode, operands[1], 0);
5799 op1 = convert_to_mode (DFmode, op1, 0);
5800 emit_insn (gen_movdf (operands[0], op1));
5803 /* Otherwise, we're done producing RTL and will pick up the correct
5804 pattern to do this with one rounding-step in a single instruction. */
5808 ;; Move insns (including loads and stores)
5810 ;; XXX Just some ideas about movti.
5811 ;; I don't think these are a good idea on the arm, there just aren't enough
5813 ;;(define_expand "loadti"
5814 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5815 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5818 ;;(define_expand "storeti"
5819 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5820 ;; (match_operand:TI 1 "s_register_operand" ""))]
5823 ;;(define_expand "movti"
5824 ;; [(set (match_operand:TI 0 "general_operand" "")
5825 ;; (match_operand:TI 1 "general_operand" ""))]
5831 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5832 ;; operands[1] = copy_to_reg (operands[1]);
5833 ;; if (MEM_P (operands[0]))
5834 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5835 ;; else if (MEM_P (operands[1]))
5836 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5840 ;; emit_insn (insn);
5844 ;; Recognize garbage generated above.
5847 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5848 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5852 ;; register mem = (which_alternative < 3);
5853 ;; register const char *template;
5855 ;; operands[mem] = XEXP (operands[mem], 0);
5856 ;; switch (which_alternative)
5858 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5859 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5860 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5861 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5862 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5863 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5865 ;; output_asm_insn (template, operands);
5869 (define_expand "movdi"
5870 [(set (match_operand:DI 0 "general_operand" "")
5871 (match_operand:DI 1 "general_operand" ""))]
5874 if (can_create_pseudo_p ())
5876 if (!REG_P (operands[0]))
5877 operands[1] = force_reg (DImode, operands[1]);
5879 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5880 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5882 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5883 when expanding function calls. */
5884 gcc_assert (can_create_pseudo_p ());
5885 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5887 /* Perform load into legal reg pair first, then move. */
5888 rtx reg = gen_reg_rtx (DImode);
5889 emit_insn (gen_movdi (reg, operands[1]));
5892 emit_move_insn (gen_lowpart (SImode, operands[0]),
5893 gen_lowpart (SImode, operands[1]));
5894 emit_move_insn (gen_highpart (SImode, operands[0]),
5895 gen_highpart (SImode, operands[1]));
5898 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5899 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5901 /* Avoid STRD's from an odd-numbered register pair in ARM state
5902 when expanding function prologue. */
5903 gcc_assert (can_create_pseudo_p ());
5904 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5905 ? gen_reg_rtx (DImode)
5907 emit_move_insn (gen_lowpart (SImode, split_dest),
5908 gen_lowpart (SImode, operands[1]));
5909 emit_move_insn (gen_highpart (SImode, split_dest),
5910 gen_highpart (SImode, operands[1]));
5911 if (split_dest != operands[0])
5912 emit_insn (gen_movdi (operands[0], split_dest));
5918 (define_insn "*arm_movdi"
5919 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5920 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5922 && !(TARGET_HARD_FLOAT)
5924 && ( register_operand (operands[0], DImode)
5925 || register_operand (operands[1], DImode))"
5927 switch (which_alternative)
5934 return output_move_double (operands, true, NULL);
5937 [(set_attr "length" "8,12,16,8,8")
5938 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5939 (set_attr "arm_pool_range" "*,*,*,1020,*")
5940 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5941 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5942 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5946 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5947 (match_operand:ANY64 1 "immediate_operand" ""))]
5950 && (arm_disable_literal_pool
5951 || (arm_const_double_inline_cost (operands[1])
5952 <= arm_max_const_double_inline_cost ()))"
5955 arm_split_constant (SET, SImode, curr_insn,
5956 INTVAL (gen_lowpart (SImode, operands[1])),
5957 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5958 arm_split_constant (SET, SImode, curr_insn,
5959 INTVAL (gen_highpart_mode (SImode,
5960 GET_MODE (operands[0]),
5962 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5967 ; If optimizing for size, or if we have load delay slots, then
5968 ; we want to split the constant into two separate operations.
5969 ; In both cases this may split a trivial part into a single data op
5970 ; leaving a single complex constant to load. We can also get longer
5971 ; offsets in a LDR which means we get better chances of sharing the pool
5972 ; entries. Finally, we can normally do a better job of scheduling
5973 ; LDR instructions than we can with LDM.
5974 ; This pattern will only match if the one above did not.
5976 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5977 (match_operand:ANY64 1 "const_double_operand" ""))]
5978 "TARGET_ARM && reload_completed
5979 && arm_const_double_by_parts (operands[1])"
5980 [(set (match_dup 0) (match_dup 1))
5981 (set (match_dup 2) (match_dup 3))]
5983 operands[2] = gen_highpart (SImode, operands[0]);
5984 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5986 operands[0] = gen_lowpart (SImode, operands[0]);
5987 operands[1] = gen_lowpart (SImode, operands[1]);
5992 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5993 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5994 "TARGET_EITHER && reload_completed"
5995 [(set (match_dup 0) (match_dup 1))
5996 (set (match_dup 2) (match_dup 3))]
5998 operands[2] = gen_highpart (SImode, operands[0]);
5999 operands[3] = gen_highpart (SImode, operands[1]);
6000 operands[0] = gen_lowpart (SImode, operands[0]);
6001 operands[1] = gen_lowpart (SImode, operands[1]);
6003 /* Handle a partial overlap. */
6004 if (rtx_equal_p (operands[0], operands[3]))
6006 rtx tmp0 = operands[0];
6007 rtx tmp1 = operands[1];
6009 operands[0] = operands[2];
6010 operands[1] = operands[3];
6017 ;; We can't actually do base+index doubleword loads if the index and
6018 ;; destination overlap. Split here so that we at least have chance to
6021 [(set (match_operand:DI 0 "s_register_operand" "")
6022 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
6023 (match_operand:SI 2 "s_register_operand" ""))))]
6025 && reg_overlap_mentioned_p (operands[0], operands[1])
6026 && reg_overlap_mentioned_p (operands[0], operands[2])"
6028 (plus:SI (match_dup 1)
6031 (mem:DI (match_dup 4)))]
6033 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
6037 (define_expand "movsi"
6038 [(set (match_operand:SI 0 "general_operand" "")
6039 (match_operand:SI 1 "general_operand" ""))]
6043 rtx base, offset, tmp;
6045 if (TARGET_32BIT || TARGET_HAVE_MOVT)
6047 /* Everything except mem = const or mem = mem can be done easily. */
6048 if (MEM_P (operands[0]))
6049 operands[1] = force_reg (SImode, operands[1]);
6050 if (arm_general_register_operand (operands[0], SImode)
6051 && CONST_INT_P (operands[1])
6052 && !(const_ok_for_arm (INTVAL (operands[1]))
6053 || const_ok_for_arm (~INTVAL (operands[1]))))
6055 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
6057 emit_insn (gen_rtx_SET (operands[0], operands[1]));
6062 arm_split_constant (SET, SImode, NULL_RTX,
6063 INTVAL (operands[1]), operands[0], NULL_RTX,
6064 optimize && can_create_pseudo_p ());
6069 else /* Target doesn't have MOVT... */
6071 if (can_create_pseudo_p ())
6073 if (!REG_P (operands[0]))
6074 operands[1] = force_reg (SImode, operands[1]);
6078 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6080 split_const (operands[1], &base, &offset);
6081 if (GET_CODE (base) == SYMBOL_REF
6082 && !offset_within_block_p (base, INTVAL (offset)))
6084 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6085 emit_move_insn (tmp, base);
6086 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6091 /* Recognize the case where operand[1] is a reference to thread-local
6092 data and load its address to a register. */
6093 if (arm_tls_referenced_p (operands[1]))
6095 rtx tmp = operands[1];
6098 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6100 addend = XEXP (XEXP (tmp, 0), 1);
6101 tmp = XEXP (XEXP (tmp, 0), 0);
6104 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6105 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6107 tmp = legitimize_tls_address (tmp,
6108 !can_create_pseudo_p () ? operands[0] : 0);
6111 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6112 tmp = force_operand (tmp, operands[0]);
6117 && (CONSTANT_P (operands[1])
6118 || symbol_mentioned_p (operands[1])
6119 || label_mentioned_p (operands[1])))
6120 operands[1] = legitimize_pic_address (operands[1], SImode,
6121 (!can_create_pseudo_p ()
6128 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6129 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6130 ;; so this does not matter.
6131 (define_insn "*arm_movt"
6132 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6133 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6134 (match_operand:SI 2 "general_operand" "i,i")))]
6135 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6137 movt%?\t%0, #:upper16:%c2
6138 movt\t%0, #:upper16:%c2"
6139 [(set_attr "arch" "32,v8mb")
6140 (set_attr "predicable" "yes")
6141 (set_attr "predicable_short_it" "no")
6142 (set_attr "length" "4")
6143 (set_attr "type" "alu_sreg")]
6146 (define_insn "*arm_movsi_insn"
6147 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6148 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6149 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6150 && ( register_operand (operands[0], SImode)
6151 || register_operand (operands[1], SImode))"
6159 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6160 (set_attr "predicable" "yes")
6161 (set_attr "arch" "*,*,*,v6t2,*,*")
6162 (set_attr "pool_range" "*,*,*,*,4096,*")
6163 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6167 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6168 (match_operand:SI 1 "const_int_operand" ""))]
6169 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6170 && (!(const_ok_for_arm (INTVAL (operands[1]))
6171 || const_ok_for_arm (~INTVAL (operands[1]))))"
6172 [(clobber (const_int 0))]
6174 arm_split_constant (SET, SImode, NULL_RTX,
6175 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6180 ;; A normal way to do (symbol + offset) requires three instructions at least
6181 ;; (depends on how big the offset is) as below:
6182 ;; movw r0, #:lower16:g
6183 ;; movw r0, #:upper16:g
6186 ;; A better way would be:
6187 ;; movw r0, #:lower16:g+4
6188 ;; movw r0, #:upper16:g+4
6190 ;; The limitation of this way is that the length of offset should be a 16-bit
6191 ;; signed value, because current assembler only supports REL type relocation for
6192 ;; such case. If the more powerful RELA type is supported in future, we should
6193 ;; update this pattern to go with better way.
6195 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6196 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6197 (match_operand:SI 2 "const_int_operand" ""))))]
6200 && arm_disable_literal_pool
6202 && GET_CODE (operands[1]) == SYMBOL_REF"
6203 [(clobber (const_int 0))]
6205 int offset = INTVAL (operands[2]);
6207 if (offset < -0x8000 || offset > 0x7fff)
6209 arm_emit_movpair (operands[0], operands[1]);
6210 emit_insn (gen_rtx_SET (operands[0],
6211 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6215 rtx op = gen_rtx_CONST (SImode,
6216 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6217 arm_emit_movpair (operands[0], op);
6222 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6223 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6224 ;; and lo_sum would be merged back into memory load at cprop. However,
6225 ;; if the default is to prefer movt/movw rather than a load from the constant
6226 ;; pool, the performance is better.
6228 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6229 (match_operand:SI 1 "general_operand" ""))]
6230 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6231 && !flag_pic && !target_word_relocations
6232 && !arm_tls_referenced_p (operands[1])"
6233 [(clobber (const_int 0))]
6235 arm_emit_movpair (operands[0], operands[1]);
6239 ;; When generating pic, we need to load the symbol offset into a register.
6240 ;; So that the optimizer does not confuse this with a normal symbol load
6241 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6242 ;; since that is the only type of relocation we can use.
6244 ;; Wrap calculation of the whole PIC address in a single pattern for the
6245 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6246 ;; a PIC address involves two loads from memory, so we want to CSE it
6247 ;; as often as possible.
6248 ;; This pattern will be split into one of the pic_load_addr_* patterns
6249 ;; and a move after GCSE optimizations.
6251 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6252 (define_expand "calculate_pic_address"
6253 [(set (match_operand:SI 0 "register_operand" "")
6254 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6255 (unspec:SI [(match_operand:SI 2 "" "")]
6260 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6262 [(set (match_operand:SI 0 "register_operand" "")
6263 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6264 (unspec:SI [(match_operand:SI 2 "" "")]
6267 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6268 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6269 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6272 ;; operand1 is the memory address to go into
6273 ;; pic_load_addr_32bit.
6274 ;; operand2 is the PIC label to be emitted
6275 ;; from pic_add_dot_plus_eight.
6276 ;; We do this to allow hoisting of the entire insn.
6277 (define_insn_and_split "pic_load_addr_unified"
6278 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6279 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6280 (match_operand:SI 2 "" "")]
6281 UNSPEC_PIC_UNIFIED))]
6284 "&& reload_completed"
6285 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6286 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6287 (match_dup 2)] UNSPEC_PIC_BASE))]
6288 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6289 [(set_attr "type" "load_4,load_4,load_4")
6290 (set_attr "pool_range" "4096,4094,1022")
6291 (set_attr "neg_pool_range" "4084,0,0")
6292 (set_attr "arch" "a,t2,t1")
6293 (set_attr "length" "8,6,4")]
6296 ;; The rather odd constraints on the following are to force reload to leave
6297 ;; the insn alone, and to force the minipool generation pass to then move
6298 ;; the GOT symbol to memory.
6300 (define_insn "pic_load_addr_32bit"
6301 [(set (match_operand:SI 0 "s_register_operand" "=r")
6302 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6303 "TARGET_32BIT && flag_pic"
6305 [(set_attr "type" "load_4")
6306 (set (attr "pool_range")
6307 (if_then_else (eq_attr "is_thumb" "no")
6310 (set (attr "neg_pool_range")
6311 (if_then_else (eq_attr "is_thumb" "no")
6316 (define_insn "pic_load_addr_thumb1"
6317 [(set (match_operand:SI 0 "s_register_operand" "=l")
6318 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6319 "TARGET_THUMB1 && flag_pic"
6321 [(set_attr "type" "load_4")
6322 (set (attr "pool_range") (const_int 1018))]
6325 (define_insn "pic_add_dot_plus_four"
6326 [(set (match_operand:SI 0 "register_operand" "=r")
6327 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6329 (match_operand 2 "" "")]
6333 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6334 INTVAL (operands[2]));
6335 return \"add\\t%0, %|pc\";
6337 [(set_attr "length" "2")
6338 (set_attr "type" "alu_sreg")]
6341 (define_insn "pic_add_dot_plus_eight"
6342 [(set (match_operand:SI 0 "register_operand" "=r")
6343 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6345 (match_operand 2 "" "")]
6349 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6350 INTVAL (operands[2]));
6351 return \"add%?\\t%0, %|pc, %1\";
6353 [(set_attr "predicable" "yes")
6354 (set_attr "type" "alu_sreg")]
6357 (define_insn "tls_load_dot_plus_eight"
6358 [(set (match_operand:SI 0 "register_operand" "=r")
6359 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6361 (match_operand 2 "" "")]
6365 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6366 INTVAL (operands[2]));
6367 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6369 [(set_attr "predicable" "yes")
6370 (set_attr "type" "load_4")]
6373 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6374 ;; followed by a load. These sequences can be crunched down to
6375 ;; tls_load_dot_plus_eight by a peephole.
6378 [(set (match_operand:SI 0 "register_operand" "")
6379 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6381 (match_operand 1 "" "")]
6383 (set (match_operand:SI 2 "arm_general_register_operand" "")
6384 (mem:SI (match_dup 0)))]
6385 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6387 (mem:SI (unspec:SI [(match_dup 3)
6394 (define_insn "pic_offset_arm"
6395 [(set (match_operand:SI 0 "register_operand" "=r")
6396 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6397 (unspec:SI [(match_operand:SI 2 "" "X")]
6398 UNSPEC_PIC_OFFSET))))]
6399 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6400 "ldr%?\\t%0, [%1,%2]"
6401 [(set_attr "type" "load_4")]
6404 (define_expand "builtin_setjmp_receiver"
6405 [(label_ref (match_operand 0 "" ""))]
6409 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6411 if (arm_pic_register != INVALID_REGNUM)
6412 arm_load_pic_register (1UL << 3);
6416 ;; If copying one reg to another we can set the condition codes according to
6417 ;; its value. Such a move is common after a return from subroutine and the
6418 ;; result is being tested against zero.
6420 (define_insn "*movsi_compare0"
6421 [(set (reg:CC CC_REGNUM)
6422 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6424 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6429 subs%?\\t%0, %1, #0"
6430 [(set_attr "conds" "set")
6431 (set_attr "type" "alus_imm,alus_imm")]
6434 ;; Subroutine to store a half word from a register into memory.
6435 ;; Operand 0 is the source register (HImode)
6436 ;; Operand 1 is the destination address in a register (SImode)
6438 ;; In both this routine and the next, we must be careful not to spill
6439 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6440 ;; can generate unrecognizable rtl.
6442 (define_expand "storehi"
6443 [;; store the low byte
6444 (set (match_operand 1 "" "") (match_dup 3))
6445 ;; extract the high byte
6447 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6448 ;; store the high byte
6449 (set (match_dup 4) (match_dup 5))]
6453 rtx op1 = operands[1];
6454 rtx addr = XEXP (op1, 0);
6455 enum rtx_code code = GET_CODE (addr);
6457 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6459 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6461 operands[4] = adjust_address (op1, QImode, 1);
6462 operands[1] = adjust_address (operands[1], QImode, 0);
6463 operands[3] = gen_lowpart (QImode, operands[0]);
6464 operands[0] = gen_lowpart (SImode, operands[0]);
6465 operands[2] = gen_reg_rtx (SImode);
6466 operands[5] = gen_lowpart (QImode, operands[2]);
6470 (define_expand "storehi_bigend"
6471 [(set (match_dup 4) (match_dup 3))
6473 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6474 (set (match_operand 1 "" "") (match_dup 5))]
6478 rtx op1 = operands[1];
6479 rtx addr = XEXP (op1, 0);
6480 enum rtx_code code = GET_CODE (addr);
6482 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6484 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6486 operands[4] = adjust_address (op1, QImode, 1);
6487 operands[1] = adjust_address (operands[1], QImode, 0);
6488 operands[3] = gen_lowpart (QImode, operands[0]);
6489 operands[0] = gen_lowpart (SImode, operands[0]);
6490 operands[2] = gen_reg_rtx (SImode);
6491 operands[5] = gen_lowpart (QImode, operands[2]);
6495 ;; Subroutine to store a half word integer constant into memory.
6496 (define_expand "storeinthi"
6497 [(set (match_operand 0 "" "")
6498 (match_operand 1 "" ""))
6499 (set (match_dup 3) (match_dup 2))]
6503 HOST_WIDE_INT value = INTVAL (operands[1]);
6504 rtx addr = XEXP (operands[0], 0);
6505 rtx op0 = operands[0];
6506 enum rtx_code code = GET_CODE (addr);
6508 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6510 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6512 operands[1] = gen_reg_rtx (SImode);
6513 if (BYTES_BIG_ENDIAN)
6515 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6516 if ((value & 255) == ((value >> 8) & 255))
6517 operands[2] = operands[1];
6520 operands[2] = gen_reg_rtx (SImode);
6521 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6526 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6527 if ((value & 255) == ((value >> 8) & 255))
6528 operands[2] = operands[1];
6531 operands[2] = gen_reg_rtx (SImode);
6532 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6536 operands[3] = adjust_address (op0, QImode, 1);
6537 operands[0] = adjust_address (operands[0], QImode, 0);
6538 operands[2] = gen_lowpart (QImode, operands[2]);
6539 operands[1] = gen_lowpart (QImode, operands[1]);
6543 (define_expand "storehi_single_op"
6544 [(set (match_operand:HI 0 "memory_operand" "")
6545 (match_operand:HI 1 "general_operand" ""))]
6546 "TARGET_32BIT && arm_arch4"
6548 if (!s_register_operand (operands[1], HImode))
6549 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6553 (define_expand "movhi"
6554 [(set (match_operand:HI 0 "general_operand" "")
6555 (match_operand:HI 1 "general_operand" ""))]
6560 if (can_create_pseudo_p ())
6562 if (MEM_P (operands[0]))
6566 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6569 if (CONST_INT_P (operands[1]))
6570 emit_insn (gen_storeinthi (operands[0], operands[1]));
6573 if (MEM_P (operands[1]))
6574 operands[1] = force_reg (HImode, operands[1]);
6575 if (BYTES_BIG_ENDIAN)
6576 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6578 emit_insn (gen_storehi (operands[1], operands[0]));
6582 /* Sign extend a constant, and keep it in an SImode reg. */
6583 else if (CONST_INT_P (operands[1]))
6585 rtx reg = gen_reg_rtx (SImode);
6586 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6588 /* If the constant is already valid, leave it alone. */
6589 if (!const_ok_for_arm (val))
6591 /* If setting all the top bits will make the constant
6592 loadable in a single instruction, then set them.
6593 Otherwise, sign extend the number. */
6595 if (const_ok_for_arm (~(val | ~0xffff)))
6597 else if (val & 0x8000)
6601 emit_insn (gen_movsi (reg, GEN_INT (val)));
6602 operands[1] = gen_lowpart (HImode, reg);
6604 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6605 && MEM_P (operands[1]))
6607 rtx reg = gen_reg_rtx (SImode);
6609 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6610 operands[1] = gen_lowpart (HImode, reg);
6612 else if (!arm_arch4)
6614 if (MEM_P (operands[1]))
6617 rtx offset = const0_rtx;
6618 rtx reg = gen_reg_rtx (SImode);
6620 if ((REG_P (base = XEXP (operands[1], 0))
6621 || (GET_CODE (base) == PLUS
6622 && (CONST_INT_P (offset = XEXP (base, 1)))
6623 && ((INTVAL(offset) & 1) != 1)
6624 && REG_P (base = XEXP (base, 0))))
6625 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6629 new_rtx = widen_memory_access (operands[1], SImode,
6630 ((INTVAL (offset) & ~3)
6631 - INTVAL (offset)));
6632 emit_insn (gen_movsi (reg, new_rtx));
6633 if (((INTVAL (offset) & 2) != 0)
6634 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6636 rtx reg2 = gen_reg_rtx (SImode);
6638 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6643 emit_insn (gen_movhi_bytes (reg, operands[1]));
6645 operands[1] = gen_lowpart (HImode, reg);
6649 /* Handle loading a large integer during reload. */
6650 else if (CONST_INT_P (operands[1])
6651 && !const_ok_for_arm (INTVAL (operands[1]))
6652 && !const_ok_for_arm (~INTVAL (operands[1])))
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]));
6663 else if (TARGET_THUMB2)
6665 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6666 if (can_create_pseudo_p ())
6668 if (!REG_P (operands[0]))
6669 operands[1] = force_reg (HImode, operands[1]);
6670 /* Zero extend a constant, and keep it in an SImode reg. */
6671 else if (CONST_INT_P (operands[1]))
6673 rtx reg = gen_reg_rtx (SImode);
6674 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6676 emit_insn (gen_movsi (reg, GEN_INT (val)));
6677 operands[1] = gen_lowpart (HImode, reg);
6681 else /* TARGET_THUMB1 */
6683 if (can_create_pseudo_p ())
6685 if (CONST_INT_P (operands[1]))
6687 rtx reg = gen_reg_rtx (SImode);
6689 emit_insn (gen_movsi (reg, operands[1]));
6690 operands[1] = gen_lowpart (HImode, reg);
6693 /* ??? We shouldn't really get invalid addresses here, but this can
6694 happen if we are passed a SP (never OK for HImode/QImode) or
6695 virtual register (also rejected as illegitimate for HImode/QImode)
6696 relative address. */
6697 /* ??? This should perhaps be fixed elsewhere, for instance, in
6698 fixup_stack_1, by checking for other kinds of invalid addresses,
6699 e.g. a bare reference to a virtual register. This may confuse the
6700 alpha though, which must handle this case differently. */
6701 if (MEM_P (operands[0])
6702 && !memory_address_p (GET_MODE (operands[0]),
6703 XEXP (operands[0], 0)))
6705 = replace_equiv_address (operands[0],
6706 copy_to_reg (XEXP (operands[0], 0)));
6708 if (MEM_P (operands[1])
6709 && !memory_address_p (GET_MODE (operands[1]),
6710 XEXP (operands[1], 0)))
6712 = replace_equiv_address (operands[1],
6713 copy_to_reg (XEXP (operands[1], 0)));
6715 if (MEM_P (operands[1]) && optimize > 0)
6717 rtx reg = gen_reg_rtx (SImode);
6719 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6720 operands[1] = gen_lowpart (HImode, reg);
6723 if (MEM_P (operands[0]))
6724 operands[1] = force_reg (HImode, operands[1]);
6726 else if (CONST_INT_P (operands[1])
6727 && !satisfies_constraint_I (operands[1]))
6729 /* Handle loading a large integer during reload. */
6731 /* Writing a constant to memory needs a scratch, which should
6732 be handled with SECONDARY_RELOADs. */
6733 gcc_assert (REG_P (operands[0]));
6735 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6736 emit_insn (gen_movsi (operands[0], operands[1]));
6743 (define_expand "movhi_bytes"
6744 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6746 (zero_extend:SI (match_dup 6)))
6747 (set (match_operand:SI 0 "" "")
6748 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6753 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6755 mem1 = change_address (operands[1], QImode, addr);
6756 mem2 = change_address (operands[1], QImode,
6757 plus_constant (Pmode, addr, 1));
6758 operands[0] = gen_lowpart (SImode, operands[0]);
6760 operands[2] = gen_reg_rtx (SImode);
6761 operands[3] = gen_reg_rtx (SImode);
6764 if (BYTES_BIG_ENDIAN)
6766 operands[4] = operands[2];
6767 operands[5] = operands[3];
6771 operands[4] = operands[3];
6772 operands[5] = operands[2];
6777 (define_expand "movhi_bigend"
6779 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6782 (ashiftrt:SI (match_dup 2) (const_int 16)))
6783 (set (match_operand:HI 0 "s_register_operand" "")
6787 operands[2] = gen_reg_rtx (SImode);
6788 operands[3] = gen_reg_rtx (SImode);
6789 operands[4] = gen_lowpart (HImode, operands[3]);
6793 ;; Pattern to recognize insn generated default case above
6794 (define_insn "*movhi_insn_arch4"
6795 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6796 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6798 && arm_arch4 && !TARGET_HARD_FLOAT
6799 && (register_operand (operands[0], HImode)
6800 || register_operand (operands[1], HImode))"
6802 mov%?\\t%0, %1\\t%@ movhi
6803 mvn%?\\t%0, #%B1\\t%@ movhi
6804 movw%?\\t%0, %L1\\t%@ movhi
6805 strh%?\\t%1, %0\\t%@ movhi
6806 ldrh%?\\t%0, %1\\t%@ movhi"
6807 [(set_attr "predicable" "yes")
6808 (set_attr "pool_range" "*,*,*,*,256")
6809 (set_attr "neg_pool_range" "*,*,*,*,244")
6810 (set_attr "arch" "*,*,v6t2,*,*")
6811 (set_attr_alternative "type"
6812 [(if_then_else (match_operand 1 "const_int_operand" "")
6813 (const_string "mov_imm" )
6814 (const_string "mov_reg"))
6815 (const_string "mvn_imm")
6816 (const_string "mov_imm")
6817 (const_string "store_4")
6818 (const_string "load_4")])]
6821 (define_insn "*movhi_bytes"
6822 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6823 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6824 "TARGET_ARM && !TARGET_HARD_FLOAT"
6826 mov%?\\t%0, %1\\t%@ movhi
6827 mov%?\\t%0, %1\\t%@ movhi
6828 mvn%?\\t%0, #%B1\\t%@ movhi"
6829 [(set_attr "predicable" "yes")
6830 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6833 ;; We use a DImode scratch because we may occasionally need an additional
6834 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6835 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6836 (define_expand "reload_outhi"
6837 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6838 (match_operand:HI 1 "s_register_operand" "r")
6839 (match_operand:DI 2 "s_register_operand" "=&l")])]
6842 arm_reload_out_hi (operands);
6844 thumb_reload_out_hi (operands);
6849 (define_expand "reload_inhi"
6850 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6851 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6852 (match_operand:DI 2 "s_register_operand" "=&r")])]
6856 arm_reload_in_hi (operands);
6858 thumb_reload_out_hi (operands);
6862 (define_expand "movqi"
6863 [(set (match_operand:QI 0 "general_operand" "")
6864 (match_operand:QI 1 "general_operand" ""))]
6867 /* Everything except mem = const or mem = mem can be done easily */
6869 if (can_create_pseudo_p ())
6871 if (CONST_INT_P (operands[1]))
6873 rtx reg = gen_reg_rtx (SImode);
6875 /* For thumb we want an unsigned immediate, then we are more likely
6876 to be able to use a movs insn. */
6878 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6880 emit_insn (gen_movsi (reg, operands[1]));
6881 operands[1] = gen_lowpart (QImode, reg);
6886 /* ??? We shouldn't really get invalid addresses here, but this can
6887 happen if we are passed a SP (never OK for HImode/QImode) or
6888 virtual register (also rejected as illegitimate for HImode/QImode)
6889 relative address. */
6890 /* ??? This should perhaps be fixed elsewhere, for instance, in
6891 fixup_stack_1, by checking for other kinds of invalid addresses,
6892 e.g. a bare reference to a virtual register. This may confuse the
6893 alpha though, which must handle this case differently. */
6894 if (MEM_P (operands[0])
6895 && !memory_address_p (GET_MODE (operands[0]),
6896 XEXP (operands[0], 0)))
6898 = replace_equiv_address (operands[0],
6899 copy_to_reg (XEXP (operands[0], 0)));
6900 if (MEM_P (operands[1])
6901 && !memory_address_p (GET_MODE (operands[1]),
6902 XEXP (operands[1], 0)))
6904 = replace_equiv_address (operands[1],
6905 copy_to_reg (XEXP (operands[1], 0)));
6908 if (MEM_P (operands[1]) && optimize > 0)
6910 rtx reg = gen_reg_rtx (SImode);
6912 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6913 operands[1] = gen_lowpart (QImode, reg);
6916 if (MEM_P (operands[0]))
6917 operands[1] = force_reg (QImode, operands[1]);
6919 else if (TARGET_THUMB
6920 && CONST_INT_P (operands[1])
6921 && !satisfies_constraint_I (operands[1]))
6923 /* Handle loading a large integer during reload. */
6925 /* Writing a constant to memory needs a scratch, which should
6926 be handled with SECONDARY_RELOADs. */
6927 gcc_assert (REG_P (operands[0]));
6929 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6930 emit_insn (gen_movsi (operands[0], operands[1]));
6936 (define_insn "*arm_movqi_insn"
6937 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6938 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6940 && ( register_operand (operands[0], QImode)
6941 || register_operand (operands[1], QImode))"
6952 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6953 (set_attr "predicable" "yes")
6954 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6955 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6956 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6960 (define_expand "movhf"
6961 [(set (match_operand:HF 0 "general_operand" "")
6962 (match_operand:HF 1 "general_operand" ""))]
6967 if (MEM_P (operands[0]))
6968 operands[1] = force_reg (HFmode, operands[1]);
6970 else /* TARGET_THUMB1 */
6972 if (can_create_pseudo_p ())
6974 if (!REG_P (operands[0]))
6975 operands[1] = force_reg (HFmode, operands[1]);
6981 (define_insn "*arm32_movhf"
6982 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6983 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6984 "TARGET_32BIT && !TARGET_HARD_FLOAT
6985 && ( s_register_operand (operands[0], HFmode)
6986 || s_register_operand (operands[1], HFmode))"
6988 switch (which_alternative)
6990 case 0: /* ARM register from memory */
6991 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6992 case 1: /* memory from ARM register */
6993 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6994 case 2: /* ARM register from ARM register */
6995 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6996 case 3: /* ARM register from constant */
7001 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
7003 ops[0] = operands[0];
7004 ops[1] = GEN_INT (bits);
7005 ops[2] = GEN_INT (bits & 0xff00);
7006 ops[3] = GEN_INT (bits & 0x00ff);
7008 if (arm_arch_thumb2)
7009 output_asm_insn (\"movw%?\\t%0, %1\", ops);
7011 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
7018 [(set_attr "conds" "unconditional")
7019 (set_attr "type" "load_4,store_4,mov_reg,multiple")
7020 (set_attr "length" "4,4,4,8")
7021 (set_attr "predicable" "yes")
7022 (set_attr "predicable_short_it" "no")]
7025 (define_expand "movsf"
7026 [(set (match_operand:SF 0 "general_operand" "")
7027 (match_operand:SF 1 "general_operand" ""))]
7032 if (MEM_P (operands[0]))
7033 operands[1] = force_reg (SFmode, operands[1]);
7035 else /* TARGET_THUMB1 */
7037 if (can_create_pseudo_p ())
7039 if (!REG_P (operands[0]))
7040 operands[1] = force_reg (SFmode, operands[1]);
7046 ;; Transform a floating-point move of a constant into a core register into
7047 ;; an SImode operation.
7049 [(set (match_operand:SF 0 "arm_general_register_operand" "")
7050 (match_operand:SF 1 "immediate_operand" ""))]
7053 && CONST_DOUBLE_P (operands[1])"
7054 [(set (match_dup 2) (match_dup 3))]
7056 operands[2] = gen_lowpart (SImode, operands[0]);
7057 operands[3] = gen_lowpart (SImode, operands[1]);
7058 if (operands[2] == 0 || operands[3] == 0)
7063 (define_insn "*arm_movsf_soft_insn"
7064 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7065 (match_operand:SF 1 "general_operand" "r,mE,r"))]
7067 && TARGET_SOFT_FLOAT
7068 && (!MEM_P (operands[0])
7069 || register_operand (operands[1], SFmode))"
7072 ldr%?\\t%0, %1\\t%@ float
7073 str%?\\t%1, %0\\t%@ float"
7074 [(set_attr "predicable" "yes")
7075 (set_attr "predicable_short_it" "no")
7076 (set_attr "type" "mov_reg,load_4,store_4")
7077 (set_attr "arm_pool_range" "*,4096,*")
7078 (set_attr "thumb2_pool_range" "*,4094,*")
7079 (set_attr "arm_neg_pool_range" "*,4084,*")
7080 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7083 (define_expand "movdf"
7084 [(set (match_operand:DF 0 "general_operand" "")
7085 (match_operand:DF 1 "general_operand" ""))]
7090 if (MEM_P (operands[0]))
7091 operands[1] = force_reg (DFmode, operands[1]);
7093 else /* TARGET_THUMB */
7095 if (can_create_pseudo_p ())
7097 if (!REG_P (operands[0]))
7098 operands[1] = force_reg (DFmode, operands[1]);
7104 ;; Reloading a df mode value stored in integer regs to memory can require a
7106 (define_expand "reload_outdf"
7107 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7108 (match_operand:DF 1 "s_register_operand" "r")
7109 (match_operand:SI 2 "s_register_operand" "=&r")]
7113 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7116 operands[2] = XEXP (operands[0], 0);
7117 else if (code == POST_INC || code == PRE_DEC)
7119 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7120 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7121 emit_insn (gen_movdi (operands[0], operands[1]));
7124 else if (code == PRE_INC)
7126 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7128 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7131 else if (code == POST_DEC)
7132 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7134 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7135 XEXP (XEXP (operands[0], 0), 1)));
7137 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7140 if (code == POST_DEC)
7141 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7147 (define_insn "*movdf_soft_insn"
7148 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7149 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7150 "TARGET_32BIT && TARGET_SOFT_FLOAT
7151 && ( register_operand (operands[0], DFmode)
7152 || register_operand (operands[1], DFmode))"
7154 switch (which_alternative)
7161 return output_move_double (operands, true, NULL);
7164 [(set_attr "length" "8,12,16,8,8")
7165 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7166 (set_attr "arm_pool_range" "*,*,*,1020,*")
7167 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7168 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7169 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7173 ;; load- and store-multiple insns
7174 ;; The arm can load/store any set of registers, provided that they are in
7175 ;; ascending order, but these expanders assume a contiguous set.
7177 (define_expand "load_multiple"
7178 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7179 (match_operand:SI 1 "" ""))
7180 (use (match_operand:SI 2 "" ""))])]
7183 HOST_WIDE_INT offset = 0;
7185 /* Support only fixed point registers. */
7186 if (!CONST_INT_P (operands[2])
7187 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7188 || INTVAL (operands[2]) < 2
7189 || !MEM_P (operands[1])
7190 || !REG_P (operands[0])
7191 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7192 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7196 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7197 INTVAL (operands[2]),
7198 force_reg (SImode, XEXP (operands[1], 0)),
7199 FALSE, operands[1], &offset);
7202 (define_expand "store_multiple"
7203 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7204 (match_operand:SI 1 "" ""))
7205 (use (match_operand:SI 2 "" ""))])]
7208 HOST_WIDE_INT offset = 0;
7210 /* Support only fixed point registers. */
7211 if (!CONST_INT_P (operands[2])
7212 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7213 || INTVAL (operands[2]) < 2
7214 || !REG_P (operands[1])
7215 || !MEM_P (operands[0])
7216 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7217 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7221 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7222 INTVAL (operands[2]),
7223 force_reg (SImode, XEXP (operands[0], 0)),
7224 FALSE, operands[0], &offset);
7228 (define_expand "setmemsi"
7229 [(match_operand:BLK 0 "general_operand" "")
7230 (match_operand:SI 1 "const_int_operand" "")
7231 (match_operand:SI 2 "const_int_operand" "")
7232 (match_operand:SI 3 "const_int_operand" "")]
7235 if (arm_gen_setmem (operands))
7242 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7243 ;; We could let this apply for blocks of less than this, but it clobbers so
7244 ;; many registers that there is then probably a better way.
7246 (define_expand "movmemqi"
7247 [(match_operand:BLK 0 "general_operand" "")
7248 (match_operand:BLK 1 "general_operand" "")
7249 (match_operand:SI 2 "const_int_operand" "")
7250 (match_operand:SI 3 "const_int_operand" "")]
7255 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7256 && !optimize_function_for_size_p (cfun))
7258 if (gen_movmem_ldrd_strd (operands))
7263 if (arm_gen_movmemqi (operands))
7267 else /* TARGET_THUMB1 */
7269 if ( INTVAL (operands[3]) != 4
7270 || INTVAL (operands[2]) > 48)
7273 thumb_expand_movmemqi (operands);
7280 ;; Compare & branch insns
7281 ;; The range calculations are based as follows:
7282 ;; For forward branches, the address calculation returns the address of
7283 ;; the next instruction. This is 2 beyond the branch instruction.
7284 ;; For backward branches, the address calculation returns the address of
7285 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7286 ;; instruction for the shortest sequence, and 4 before the branch instruction
7287 ;; if we have to jump around an unconditional branch.
7288 ;; To the basic branch range the PC offset must be added (this is +4).
7289 ;; So for forward branches we have
7290 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7291 ;; And for backward branches we have
7292 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7294 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7295 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7297 (define_expand "cbranchsi4"
7298 [(set (pc) (if_then_else
7299 (match_operator 0 "expandable_comparison_operator"
7300 [(match_operand:SI 1 "s_register_operand" "")
7301 (match_operand:SI 2 "nonmemory_operand" "")])
7302 (label_ref (match_operand 3 "" ""))
7308 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7310 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7314 if (thumb1_cmpneg_operand (operands[2], SImode))
7316 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7317 operands[3], operands[0]));
7320 if (!thumb1_cmp_operand (operands[2], SImode))
7321 operands[2] = force_reg (SImode, operands[2]);
7324 (define_expand "cbranchsf4"
7325 [(set (pc) (if_then_else
7326 (match_operator 0 "expandable_comparison_operator"
7327 [(match_operand:SF 1 "s_register_operand" "")
7328 (match_operand:SF 2 "vfp_compare_operand" "")])
7329 (label_ref (match_operand 3 "" ""))
7331 "TARGET_32BIT && TARGET_HARD_FLOAT"
7332 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7333 operands[3])); DONE;"
7336 (define_expand "cbranchdf4"
7337 [(set (pc) (if_then_else
7338 (match_operator 0 "expandable_comparison_operator"
7339 [(match_operand:DF 1 "s_register_operand" "")
7340 (match_operand:DF 2 "vfp_compare_operand" "")])
7341 (label_ref (match_operand 3 "" ""))
7343 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7344 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7345 operands[3])); DONE;"
7348 (define_expand "cbranchdi4"
7349 [(set (pc) (if_then_else
7350 (match_operator 0 "expandable_comparison_operator"
7351 [(match_operand:DI 1 "s_register_operand" "")
7352 (match_operand:DI 2 "cmpdi_operand" "")])
7353 (label_ref (match_operand 3 "" ""))
7357 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7359 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7365 ;; Comparison and test insns
7367 (define_insn "*arm_cmpsi_insn"
7368 [(set (reg:CC CC_REGNUM)
7369 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7370 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7378 [(set_attr "conds" "set")
7379 (set_attr "arch" "t2,t2,any,any,any")
7380 (set_attr "length" "2,2,4,4,4")
7381 (set_attr "predicable" "yes")
7382 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7383 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7386 (define_insn "*cmpsi_shiftsi"
7387 [(set (reg:CC CC_REGNUM)
7388 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7389 (match_operator:SI 3 "shift_operator"
7390 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7391 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7394 [(set_attr "conds" "set")
7395 (set_attr "shift" "1")
7396 (set_attr "arch" "32,a,a")
7397 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7399 (define_insn "*cmpsi_shiftsi_swp"
7400 [(set (reg:CC_SWP CC_REGNUM)
7401 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7402 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7403 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7404 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7407 [(set_attr "conds" "set")
7408 (set_attr "shift" "1")
7409 (set_attr "arch" "32,a,a")
7410 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7412 (define_insn "*arm_cmpsi_negshiftsi_si"
7413 [(set (reg:CC_Z CC_REGNUM)
7415 (neg:SI (match_operator:SI 1 "shift_operator"
7416 [(match_operand:SI 2 "s_register_operand" "r")
7417 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7418 (match_operand:SI 0 "s_register_operand" "r")))]
7421 [(set_attr "conds" "set")
7422 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7423 (const_string "alus_shift_imm")
7424 (const_string "alus_shift_reg")))
7425 (set_attr "predicable" "yes")]
7428 ;; DImode comparisons. The generic code generates branches that
7429 ;; if-conversion can not reduce to a conditional compare, so we do
7432 (define_insn_and_split "*arm_cmpdi_insn"
7433 [(set (reg:CC_NCV CC_REGNUM)
7434 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7435 (match_operand:DI 1 "arm_di_operand" "rDi")))
7436 (clobber (match_scratch:SI 2 "=r"))]
7438 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7439 "&& reload_completed"
7440 [(set (reg:CC CC_REGNUM)
7441 (compare:CC (match_dup 0) (match_dup 1)))
7442 (parallel [(set (reg:CC CC_REGNUM)
7443 (compare:CC (match_dup 3) (match_dup 4)))
7445 (minus:SI (match_dup 5)
7446 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7448 operands[3] = gen_highpart (SImode, operands[0]);
7449 operands[0] = gen_lowpart (SImode, operands[0]);
7450 if (CONST_INT_P (operands[1]))
7452 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7455 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7459 operands[4] = gen_highpart (SImode, operands[1]);
7460 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7462 operands[1] = gen_lowpart (SImode, operands[1]);
7463 operands[2] = gen_lowpart (SImode, operands[2]);
7465 [(set_attr "conds" "set")
7466 (set_attr "length" "8")
7467 (set_attr "type" "multiple")]
7470 (define_insn_and_split "*arm_cmpdi_unsigned"
7471 [(set (reg:CC_CZ CC_REGNUM)
7472 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7473 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7476 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7477 "&& reload_completed"
7478 [(set (reg:CC CC_REGNUM)
7479 (compare:CC (match_dup 2) (match_dup 3)))
7480 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7481 (set (reg:CC CC_REGNUM)
7482 (compare:CC (match_dup 0) (match_dup 1))))]
7484 operands[2] = gen_highpart (SImode, operands[0]);
7485 operands[0] = gen_lowpart (SImode, operands[0]);
7486 if (CONST_INT_P (operands[1]))
7487 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7489 operands[3] = gen_highpart (SImode, operands[1]);
7490 operands[1] = gen_lowpart (SImode, operands[1]);
7492 [(set_attr "conds" "set")
7493 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7494 (set_attr "arch" "t2,t2,t2,a")
7495 (set_attr "length" "6,6,10,8")
7496 (set_attr "type" "multiple")]
7499 (define_insn "*arm_cmpdi_zero"
7500 [(set (reg:CC_Z CC_REGNUM)
7501 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7503 (clobber (match_scratch:SI 1 "=r"))]
7505 "orrs%?\\t%1, %Q0, %R0"
7506 [(set_attr "conds" "set")
7507 (set_attr "type" "logics_reg")]
7510 ; This insn allows redundant compares to be removed by cse, nothing should
7511 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7512 ; is deleted later on. The match_dup will match the mode here, so that
7513 ; mode changes of the condition codes aren't lost by this even though we don't
7514 ; specify what they are.
7516 (define_insn "*deleted_compare"
7517 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7519 "\\t%@ deleted compare"
7520 [(set_attr "conds" "set")
7521 (set_attr "length" "0")
7522 (set_attr "type" "no_insn")]
7526 ;; Conditional branch insns
7528 (define_expand "cbranch_cc"
7530 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7531 (match_operand 2 "" "")])
7532 (label_ref (match_operand 3 "" ""))
7535 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7536 operands[1], operands[2], NULL_RTX);
7537 operands[2] = const0_rtx;"
7541 ;; Patterns to match conditional branch insns.
7544 (define_insn "arm_cond_branch"
7546 (if_then_else (match_operator 1 "arm_comparison_operator"
7547 [(match_operand 2 "cc_register" "") (const_int 0)])
7548 (label_ref (match_operand 0 "" ""))
7552 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7554 arm_ccfsm_state += 2;
7557 return \"b%d1\\t%l0\";
7559 [(set_attr "conds" "use")
7560 (set_attr "type" "branch")
7561 (set (attr "length")
7563 (and (match_test "TARGET_THUMB2")
7564 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7565 (le (minus (match_dup 0) (pc)) (const_int 256))))
7570 (define_insn "*arm_cond_branch_reversed"
7572 (if_then_else (match_operator 1 "arm_comparison_operator"
7573 [(match_operand 2 "cc_register" "") (const_int 0)])
7575 (label_ref (match_operand 0 "" ""))))]
7578 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7580 arm_ccfsm_state += 2;
7583 return \"b%D1\\t%l0\";
7585 [(set_attr "conds" "use")
7586 (set_attr "type" "branch")
7587 (set (attr "length")
7589 (and (match_test "TARGET_THUMB2")
7590 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7591 (le (minus (match_dup 0) (pc)) (const_int 256))))
7600 (define_expand "cstore_cc"
7601 [(set (match_operand:SI 0 "s_register_operand" "")
7602 (match_operator:SI 1 "" [(match_operand 2 "" "")
7603 (match_operand 3 "" "")]))]
7605 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7606 operands[2], operands[3], NULL_RTX);
7607 operands[3] = const0_rtx;"
7610 (define_insn_and_split "*mov_scc"
7611 [(set (match_operand:SI 0 "s_register_operand" "=r")
7612 (match_operator:SI 1 "arm_comparison_operator_mode"
7613 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7615 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7618 (if_then_else:SI (match_dup 1)
7622 [(set_attr "conds" "use")
7623 (set_attr "length" "8")
7624 (set_attr "type" "multiple")]
7627 (define_insn_and_split "*mov_negscc"
7628 [(set (match_operand:SI 0 "s_register_operand" "=r")
7629 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7630 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7632 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7635 (if_then_else:SI (match_dup 1)
7639 operands[3] = GEN_INT (~0);
7641 [(set_attr "conds" "use")
7642 (set_attr "length" "8")
7643 (set_attr "type" "multiple")]
7646 (define_insn_and_split "*mov_notscc"
7647 [(set (match_operand:SI 0 "s_register_operand" "=r")
7648 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7649 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7651 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7654 (if_then_else:SI (match_dup 1)
7658 operands[3] = GEN_INT (~1);
7659 operands[4] = GEN_INT (~0);
7661 [(set_attr "conds" "use")
7662 (set_attr "length" "8")
7663 (set_attr "type" "multiple")]
7666 (define_expand "cstoresi4"
7667 [(set (match_operand:SI 0 "s_register_operand" "")
7668 (match_operator:SI 1 "expandable_comparison_operator"
7669 [(match_operand:SI 2 "s_register_operand" "")
7670 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7671 "TARGET_32BIT || TARGET_THUMB1"
7673 rtx op3, scratch, scratch2;
7677 if (!arm_add_operand (operands[3], SImode))
7678 operands[3] = force_reg (SImode, operands[3]);
7679 emit_insn (gen_cstore_cc (operands[0], operands[1],
7680 operands[2], operands[3]));
7684 if (operands[3] == const0_rtx)
7686 switch (GET_CODE (operands[1]))
7689 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7693 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7697 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7698 NULL_RTX, 0, OPTAB_WIDEN);
7699 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7700 NULL_RTX, 0, OPTAB_WIDEN);
7701 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7702 operands[0], 1, OPTAB_WIDEN);
7706 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7708 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7709 NULL_RTX, 1, OPTAB_WIDEN);
7713 scratch = expand_binop (SImode, ashr_optab, operands[2],
7714 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7715 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7716 NULL_RTX, 0, OPTAB_WIDEN);
7717 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7721 /* LT is handled by generic code. No need for unsigned with 0. */
7728 switch (GET_CODE (operands[1]))
7731 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7732 NULL_RTX, 0, OPTAB_WIDEN);
7733 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7737 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7738 NULL_RTX, 0, OPTAB_WIDEN);
7739 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7743 op3 = force_reg (SImode, operands[3]);
7745 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7746 NULL_RTX, 1, OPTAB_WIDEN);
7747 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7748 NULL_RTX, 0, OPTAB_WIDEN);
7749 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7755 if (!thumb1_cmp_operand (op3, SImode))
7756 op3 = force_reg (SImode, op3);
7757 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7758 NULL_RTX, 0, OPTAB_WIDEN);
7759 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7760 NULL_RTX, 1, OPTAB_WIDEN);
7761 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7766 op3 = force_reg (SImode, operands[3]);
7767 scratch = force_reg (SImode, const0_rtx);
7768 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7774 if (!thumb1_cmp_operand (op3, SImode))
7775 op3 = force_reg (SImode, op3);
7776 scratch = force_reg (SImode, const0_rtx);
7777 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7783 if (!thumb1_cmp_operand (op3, SImode))
7784 op3 = force_reg (SImode, op3);
7785 scratch = gen_reg_rtx (SImode);
7786 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7790 op3 = force_reg (SImode, operands[3]);
7791 scratch = gen_reg_rtx (SImode);
7792 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7795 /* No good sequences for GT, LT. */
7802 (define_expand "cstorehf4"
7803 [(set (match_operand:SI 0 "s_register_operand")
7804 (match_operator:SI 1 "expandable_comparison_operator"
7805 [(match_operand:HF 2 "s_register_operand")
7806 (match_operand:HF 3 "vfp_compare_operand")]))]
7807 "TARGET_VFP_FP16INST"
7809 if (!arm_validize_comparison (&operands[1],
7814 emit_insn (gen_cstore_cc (operands[0], operands[1],
7815 operands[2], operands[3]));
7820 (define_expand "cstoresf4"
7821 [(set (match_operand:SI 0 "s_register_operand" "")
7822 (match_operator:SI 1 "expandable_comparison_operator"
7823 [(match_operand:SF 2 "s_register_operand" "")
7824 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7825 "TARGET_32BIT && TARGET_HARD_FLOAT"
7826 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7827 operands[2], operands[3])); DONE;"
7830 (define_expand "cstoredf4"
7831 [(set (match_operand:SI 0 "s_register_operand" "")
7832 (match_operator:SI 1 "expandable_comparison_operator"
7833 [(match_operand:DF 2 "s_register_operand" "")
7834 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7835 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7836 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7837 operands[2], operands[3])); DONE;"
7840 (define_expand "cstoredi4"
7841 [(set (match_operand:SI 0 "s_register_operand" "")
7842 (match_operator:SI 1 "expandable_comparison_operator"
7843 [(match_operand:DI 2 "s_register_operand" "")
7844 (match_operand:DI 3 "cmpdi_operand" "")]))]
7847 if (!arm_validize_comparison (&operands[1],
7851 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7858 ;; Conditional move insns
7860 (define_expand "movsicc"
7861 [(set (match_operand:SI 0 "s_register_operand" "")
7862 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7863 (match_operand:SI 2 "arm_not_operand" "")
7864 (match_operand:SI 3 "arm_not_operand" "")))]
7871 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7872 &XEXP (operands[1], 1)))
7875 code = GET_CODE (operands[1]);
7876 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7877 XEXP (operands[1], 1), NULL_RTX);
7878 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7882 (define_expand "movhfcc"
7883 [(set (match_operand:HF 0 "s_register_operand")
7884 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7885 (match_operand:HF 2 "s_register_operand")
7886 (match_operand:HF 3 "s_register_operand")))]
7887 "TARGET_VFP_FP16INST"
7890 enum rtx_code code = GET_CODE (operands[1]);
7893 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7894 &XEXP (operands[1], 1)))
7897 code = GET_CODE (operands[1]);
7898 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7899 XEXP (operands[1], 1), NULL_RTX);
7900 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7904 (define_expand "movsfcc"
7905 [(set (match_operand:SF 0 "s_register_operand" "")
7906 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7907 (match_operand:SF 2 "s_register_operand" "")
7908 (match_operand:SF 3 "s_register_operand" "")))]
7909 "TARGET_32BIT && TARGET_HARD_FLOAT"
7912 enum rtx_code code = GET_CODE (operands[1]);
7915 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7916 &XEXP (operands[1], 1)))
7919 code = GET_CODE (operands[1]);
7920 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7921 XEXP (operands[1], 1), NULL_RTX);
7922 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7926 (define_expand "movdfcc"
7927 [(set (match_operand:DF 0 "s_register_operand" "")
7928 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7929 (match_operand:DF 2 "s_register_operand" "")
7930 (match_operand:DF 3 "s_register_operand" "")))]
7931 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7934 enum rtx_code code = GET_CODE (operands[1]);
7937 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7938 &XEXP (operands[1], 1)))
7940 code = GET_CODE (operands[1]);
7941 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7942 XEXP (operands[1], 1), NULL_RTX);
7943 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7947 (define_insn "*cmov<mode>"
7948 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7949 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7950 [(match_operand 2 "cc_register" "") (const_int 0)])
7951 (match_operand:SDF 3 "s_register_operand"
7953 (match_operand:SDF 4 "s_register_operand"
7954 "<F_constraint>")))]
7955 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7958 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7965 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7970 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7976 [(set_attr "conds" "use")
7977 (set_attr "type" "fcsel")]
7980 (define_insn "*cmovhf"
7981 [(set (match_operand:HF 0 "s_register_operand" "=t")
7982 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7983 [(match_operand 2 "cc_register" "") (const_int 0)])
7984 (match_operand:HF 3 "s_register_operand" "t")
7985 (match_operand:HF 4 "s_register_operand" "t")))]
7986 "TARGET_VFP_FP16INST"
7989 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7996 return \"vsel%d1.f16\\t%0, %3, %4\";
8001 return \"vsel%D1.f16\\t%0, %4, %3\";
8007 [(set_attr "conds" "use")
8008 (set_attr "type" "fcsel")]
8011 (define_insn_and_split "*movsicc_insn"
8012 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8014 (match_operator 3 "arm_comparison_operator"
8015 [(match_operand 4 "cc_register" "") (const_int 0)])
8016 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8017 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8028 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8029 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8030 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8031 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8032 "&& reload_completed"
8035 enum rtx_code rev_code;
8039 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8041 gen_rtx_SET (operands[0], operands[1])));
8043 rev_code = GET_CODE (operands[3]);
8044 mode = GET_MODE (operands[4]);
8045 if (mode == CCFPmode || mode == CCFPEmode)
8046 rev_code = reverse_condition_maybe_unordered (rev_code);
8048 rev_code = reverse_condition (rev_code);
8050 rev_cond = gen_rtx_fmt_ee (rev_code,
8054 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8056 gen_rtx_SET (operands[0], operands[2])));
8059 [(set_attr "length" "4,4,4,4,8,8,8,8")
8060 (set_attr "conds" "use")
8061 (set_attr_alternative "type"
8062 [(if_then_else (match_operand 2 "const_int_operand" "")
8063 (const_string "mov_imm")
8064 (const_string "mov_reg"))
8065 (const_string "mvn_imm")
8066 (if_then_else (match_operand 1 "const_int_operand" "")
8067 (const_string "mov_imm")
8068 (const_string "mov_reg"))
8069 (const_string "mvn_imm")
8070 (const_string "multiple")
8071 (const_string "multiple")
8072 (const_string "multiple")
8073 (const_string "multiple")])]
8076 (define_insn "*movsfcc_soft_insn"
8077 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8078 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8079 [(match_operand 4 "cc_register" "") (const_int 0)])
8080 (match_operand:SF 1 "s_register_operand" "0,r")
8081 (match_operand:SF 2 "s_register_operand" "r,0")))]
8082 "TARGET_ARM && TARGET_SOFT_FLOAT"
8086 [(set_attr "conds" "use")
8087 (set_attr "type" "mov_reg")]
8091 ;; Jump and linkage insns
8093 (define_expand "jump"
8095 (label_ref (match_operand 0 "" "")))]
8100 (define_insn "*arm_jump"
8102 (label_ref (match_operand 0 "" "")))]
8106 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8108 arm_ccfsm_state += 2;
8111 return \"b%?\\t%l0\";
8114 [(set_attr "predicable" "yes")
8115 (set (attr "length")
8117 (and (match_test "TARGET_THUMB2")
8118 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8119 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8122 (set_attr "type" "branch")]
8125 (define_expand "call"
8126 [(parallel [(call (match_operand 0 "memory_operand" "")
8127 (match_operand 1 "general_operand" ""))
8128 (use (match_operand 2 "" ""))
8129 (clobber (reg:SI LR_REGNUM))])]
8134 tree addr = MEM_EXPR (operands[0]);
8136 /* In an untyped call, we can get NULL for operand 2. */
8137 if (operands[2] == NULL_RTX)
8138 operands[2] = const0_rtx;
8140 /* Decide if we should generate indirect calls by loading the
8141 32-bit address of the callee into a register before performing the
8143 callee = XEXP (operands[0], 0);
8144 if (GET_CODE (callee) == SYMBOL_REF
8145 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8147 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8149 if (detect_cmse_nonsecure_call (addr))
8151 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8153 emit_call_insn (pat);
8157 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8158 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8164 (define_expand "call_internal"
8165 [(parallel [(call (match_operand 0 "memory_operand" "")
8166 (match_operand 1 "general_operand" ""))
8167 (use (match_operand 2 "" ""))
8168 (clobber (reg:SI LR_REGNUM))])])
8170 (define_expand "nonsecure_call_internal"
8171 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8172 UNSPEC_NONSECURE_MEM)
8173 (match_operand 1 "general_operand" ""))
8174 (use (match_operand 2 "" ""))
8175 (clobber (reg:SI LR_REGNUM))
8176 (clobber (reg:SI 4))])]
8181 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8182 gen_rtx_REG (SImode, 4),
8185 operands[0] = replace_equiv_address (operands[0], tmp);
8188 (define_insn "*call_reg_armv5"
8189 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8190 (match_operand 1 "" ""))
8191 (use (match_operand 2 "" ""))
8192 (clobber (reg:SI LR_REGNUM))]
8193 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8195 [(set_attr "type" "call")]
8198 (define_insn "*call_reg_arm"
8199 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8200 (match_operand 1 "" ""))
8201 (use (match_operand 2 "" ""))
8202 (clobber (reg:SI LR_REGNUM))]
8203 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8205 return output_call (operands);
8207 ;; length is worst case, normally it is only two
8208 [(set_attr "length" "12")
8209 (set_attr "type" "call")]
8213 (define_expand "call_value"
8214 [(parallel [(set (match_operand 0 "" "")
8215 (call (match_operand 1 "memory_operand" "")
8216 (match_operand 2 "general_operand" "")))
8217 (use (match_operand 3 "" ""))
8218 (clobber (reg:SI LR_REGNUM))])]
8223 tree addr = MEM_EXPR (operands[1]);
8225 /* In an untyped call, we can get NULL for operand 2. */
8226 if (operands[3] == 0)
8227 operands[3] = const0_rtx;
8229 /* Decide if we should generate indirect calls by loading the
8230 32-bit address of the callee into a register before performing the
8232 callee = XEXP (operands[1], 0);
8233 if (GET_CODE (callee) == SYMBOL_REF
8234 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8236 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8238 if (detect_cmse_nonsecure_call (addr))
8240 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8241 operands[2], operands[3]);
8242 emit_call_insn (pat);
8246 pat = gen_call_value_internal (operands[0], operands[1],
8247 operands[2], operands[3]);
8248 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8254 (define_expand "call_value_internal"
8255 [(parallel [(set (match_operand 0 "" "")
8256 (call (match_operand 1 "memory_operand" "")
8257 (match_operand 2 "general_operand" "")))
8258 (use (match_operand 3 "" ""))
8259 (clobber (reg:SI LR_REGNUM))])])
8261 (define_expand "nonsecure_call_value_internal"
8262 [(parallel [(set (match_operand 0 "" "")
8263 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8264 UNSPEC_NONSECURE_MEM)
8265 (match_operand 2 "general_operand" "")))
8266 (use (match_operand 3 "" ""))
8267 (clobber (reg:SI LR_REGNUM))
8268 (clobber (reg:SI 4))])]
8273 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8274 gen_rtx_REG (SImode, 4),
8277 operands[1] = replace_equiv_address (operands[1], tmp);
8280 (define_insn "*call_value_reg_armv5"
8281 [(set (match_operand 0 "" "")
8282 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8283 (match_operand 2 "" "")))
8284 (use (match_operand 3 "" ""))
8285 (clobber (reg:SI LR_REGNUM))]
8286 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8288 [(set_attr "type" "call")]
8291 (define_insn "*call_value_reg_arm"
8292 [(set (match_operand 0 "" "")
8293 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8294 (match_operand 2 "" "")))
8295 (use (match_operand 3 "" ""))
8296 (clobber (reg:SI LR_REGNUM))]
8297 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8299 return output_call (&operands[1]);
8301 [(set_attr "length" "12")
8302 (set_attr "type" "call")]
8305 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8306 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8308 (define_insn "*call_symbol"
8309 [(call (mem:SI (match_operand:SI 0 "" ""))
8310 (match_operand 1 "" ""))
8311 (use (match_operand 2 "" ""))
8312 (clobber (reg:SI LR_REGNUM))]
8314 && !SIBLING_CALL_P (insn)
8315 && (GET_CODE (operands[0]) == SYMBOL_REF)
8316 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8319 rtx op = operands[0];
8321 /* Switch mode now when possible. */
8322 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8323 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8324 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8326 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8328 [(set_attr "type" "call")]
8331 (define_insn "*call_value_symbol"
8332 [(set (match_operand 0 "" "")
8333 (call (mem:SI (match_operand:SI 1 "" ""))
8334 (match_operand:SI 2 "" "")))
8335 (use (match_operand 3 "" ""))
8336 (clobber (reg:SI LR_REGNUM))]
8338 && !SIBLING_CALL_P (insn)
8339 && (GET_CODE (operands[1]) == SYMBOL_REF)
8340 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8343 rtx op = operands[1];
8345 /* Switch mode now when possible. */
8346 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8347 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8348 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8350 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8352 [(set_attr "type" "call")]
8355 (define_expand "sibcall_internal"
8356 [(parallel [(call (match_operand 0 "memory_operand" "")
8357 (match_operand 1 "general_operand" ""))
8359 (use (match_operand 2 "" ""))])])
8361 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8362 (define_expand "sibcall"
8363 [(parallel [(call (match_operand 0 "memory_operand" "")
8364 (match_operand 1 "general_operand" ""))
8366 (use (match_operand 2 "" ""))])]
8372 if ((!REG_P (XEXP (operands[0], 0))
8373 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8374 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8375 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8376 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8378 if (operands[2] == NULL_RTX)
8379 operands[2] = const0_rtx;
8381 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8382 arm_emit_call_insn (pat, operands[0], true);
8387 (define_expand "sibcall_value_internal"
8388 [(parallel [(set (match_operand 0 "" "")
8389 (call (match_operand 1 "memory_operand" "")
8390 (match_operand 2 "general_operand" "")))
8392 (use (match_operand 3 "" ""))])])
8394 (define_expand "sibcall_value"
8395 [(parallel [(set (match_operand 0 "" "")
8396 (call (match_operand 1 "memory_operand" "")
8397 (match_operand 2 "general_operand" "")))
8399 (use (match_operand 3 "" ""))])]
8405 if ((!REG_P (XEXP (operands[1], 0))
8406 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8407 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8408 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8409 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8411 if (operands[3] == NULL_RTX)
8412 operands[3] = const0_rtx;
8414 pat = gen_sibcall_value_internal (operands[0], operands[1],
8415 operands[2], operands[3]);
8416 arm_emit_call_insn (pat, operands[1], true);
8421 (define_insn "*sibcall_insn"
8422 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8423 (match_operand 1 "" ""))
8425 (use (match_operand 2 "" ""))]
8426 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8428 if (which_alternative == 1)
8429 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8432 if (arm_arch5 || arm_arch4t)
8433 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8435 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8438 [(set_attr "type" "call")]
8441 (define_insn "*sibcall_value_insn"
8442 [(set (match_operand 0 "" "")
8443 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8444 (match_operand 2 "" "")))
8446 (use (match_operand 3 "" ""))]
8447 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8449 if (which_alternative == 1)
8450 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8453 if (arm_arch5 || arm_arch4t)
8454 return \"bx%?\\t%1\";
8456 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8459 [(set_attr "type" "call")]
8462 (define_expand "<return_str>return"
8464 "(TARGET_ARM || (TARGET_THUMB2
8465 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8466 && !IS_STACKALIGN (arm_current_func_type ())))
8467 <return_cond_false>"
8472 thumb2_expand_return (<return_simple_p>);
8479 ;; Often the return insn will be the same as loading from memory, so set attr
8480 (define_insn "*arm_return"
8482 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8485 if (arm_ccfsm_state == 2)
8487 arm_ccfsm_state += 2;
8490 return output_return_instruction (const_true_rtx, true, false, false);
8492 [(set_attr "type" "load_4")
8493 (set_attr "length" "12")
8494 (set_attr "predicable" "yes")]
8497 (define_insn "*cond_<return_str>return"
8499 (if_then_else (match_operator 0 "arm_comparison_operator"
8500 [(match_operand 1 "cc_register" "") (const_int 0)])
8503 "TARGET_ARM <return_cond_true>"
8506 if (arm_ccfsm_state == 2)
8508 arm_ccfsm_state += 2;
8511 return output_return_instruction (operands[0], true, false,
8514 [(set_attr "conds" "use")
8515 (set_attr "length" "12")
8516 (set_attr "type" "load_4")]
8519 (define_insn "*cond_<return_str>return_inverted"
8521 (if_then_else (match_operator 0 "arm_comparison_operator"
8522 [(match_operand 1 "cc_register" "") (const_int 0)])
8525 "TARGET_ARM <return_cond_true>"
8528 if (arm_ccfsm_state == 2)
8530 arm_ccfsm_state += 2;
8533 return output_return_instruction (operands[0], true, true,
8536 [(set_attr "conds" "use")
8537 (set_attr "length" "12")
8538 (set_attr "type" "load_4")]
8541 (define_insn "*arm_simple_return"
8546 if (arm_ccfsm_state == 2)
8548 arm_ccfsm_state += 2;
8551 return output_return_instruction (const_true_rtx, true, false, true);
8553 [(set_attr "type" "branch")
8554 (set_attr "length" "4")
8555 (set_attr "predicable" "yes")]
8558 ;; Generate a sequence of instructions to determine if the processor is
8559 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8562 (define_expand "return_addr_mask"
8564 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8566 (set (match_operand:SI 0 "s_register_operand" "")
8567 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8569 (const_int 67108860)))] ; 0x03fffffc
8572 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8575 (define_insn "*check_arch2"
8576 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8577 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8580 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8581 [(set_attr "length" "8")
8582 (set_attr "conds" "set")
8583 (set_attr "type" "multiple")]
8586 ;; Call subroutine returning any type.
8588 (define_expand "untyped_call"
8589 [(parallel [(call (match_operand 0 "" "")
8591 (match_operand 1 "" "")
8592 (match_operand 2 "" "")])]
8597 rtx par = gen_rtx_PARALLEL (VOIDmode,
8598 rtvec_alloc (XVECLEN (operands[2], 0)));
8599 rtx addr = gen_reg_rtx (Pmode);
8603 emit_move_insn (addr, XEXP (operands[1], 0));
8604 mem = change_address (operands[1], BLKmode, addr);
8606 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8608 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8610 /* Default code only uses r0 as a return value, but we could
8611 be using anything up to 4 registers. */
8612 if (REGNO (src) == R0_REGNUM)
8613 src = gen_rtx_REG (TImode, R0_REGNUM);
8615 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8617 size += GET_MODE_SIZE (GET_MODE (src));
8620 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8624 for (i = 0; i < XVECLEN (par, 0); i++)
8626 HOST_WIDE_INT offset = 0;
8627 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8630 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8632 mem = change_address (mem, GET_MODE (reg), NULL);
8633 if (REGNO (reg) == R0_REGNUM)
8635 /* On thumb we have to use a write-back instruction. */
8636 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8637 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8638 size = TARGET_ARM ? 16 : 0;
8642 emit_move_insn (mem, reg);
8643 size = GET_MODE_SIZE (GET_MODE (reg));
8647 /* The optimizer does not know that the call sets the function value
8648 registers we stored in the result block. We avoid problems by
8649 claiming that all hard registers are used and clobbered at this
8651 emit_insn (gen_blockage ());
8657 (define_expand "untyped_return"
8658 [(match_operand:BLK 0 "memory_operand" "")
8659 (match_operand 1 "" "")]
8664 rtx addr = gen_reg_rtx (Pmode);
8668 emit_move_insn (addr, XEXP (operands[0], 0));
8669 mem = change_address (operands[0], BLKmode, addr);
8671 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8673 HOST_WIDE_INT offset = 0;
8674 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8677 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8679 mem = change_address (mem, GET_MODE (reg), NULL);
8680 if (REGNO (reg) == R0_REGNUM)
8682 /* On thumb we have to use a write-back instruction. */
8683 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8684 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8685 size = TARGET_ARM ? 16 : 0;
8689 emit_move_insn (reg, mem);
8690 size = GET_MODE_SIZE (GET_MODE (reg));
8694 /* Emit USE insns before the return. */
8695 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8696 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8698 /* Construct the return. */
8699 expand_naked_return ();
8705 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8706 ;; all of memory. This blocks insns from being moved across this point.
8708 (define_insn "blockage"
8709 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8712 [(set_attr "length" "0")
8713 (set_attr "type" "block")]
8716 (define_insn "probe_stack"
8717 [(set (match_operand:SI 0 "memory_operand" "=m")
8718 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8721 [(set_attr "type" "store_4")
8722 (set_attr "predicable" "yes")]
8725 (define_insn "probe_stack_range"
8726 [(set (match_operand:SI 0 "register_operand" "=r")
8727 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8728 (match_operand:SI 2 "register_operand" "r")]
8729 VUNSPEC_PROBE_STACK_RANGE))]
8732 return output_probe_stack_range (operands[0], operands[2]);
8734 [(set_attr "type" "multiple")
8735 (set_attr "conds" "clob")]
8738 (define_expand "casesi"
8739 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8740 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8741 (match_operand:SI 2 "const_int_operand" "") ; total range
8742 (match_operand:SI 3 "" "") ; table label
8743 (match_operand:SI 4 "" "")] ; Out of range label
8744 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8747 enum insn_code code;
8748 if (operands[1] != const0_rtx)
8750 rtx reg = gen_reg_rtx (SImode);
8752 emit_insn (gen_addsi3 (reg, operands[0],
8753 gen_int_mode (-INTVAL (operands[1]),
8759 code = CODE_FOR_arm_casesi_internal;
8760 else if (TARGET_THUMB1)
8761 code = CODE_FOR_thumb1_casesi_internal_pic;
8763 code = CODE_FOR_thumb2_casesi_internal_pic;
8765 code = CODE_FOR_thumb2_casesi_internal;
8767 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8768 operands[2] = force_reg (SImode, operands[2]);
8770 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8771 operands[3], operands[4]));
8776 ;; The USE in this pattern is needed to tell flow analysis that this is
8777 ;; a CASESI insn. It has no other purpose.
8778 (define_insn "arm_casesi_internal"
8779 [(parallel [(set (pc)
8781 (leu (match_operand:SI 0 "s_register_operand" "r")
8782 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8783 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8784 (label_ref (match_operand 2 "" ""))))
8785 (label_ref (match_operand 3 "" ""))))
8786 (clobber (reg:CC CC_REGNUM))
8787 (use (label_ref (match_dup 2)))])]
8791 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8792 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8794 [(set_attr "conds" "clob")
8795 (set_attr "length" "12")
8796 (set_attr "type" "multiple")]
8799 (define_expand "indirect_jump"
8801 (match_operand:SI 0 "s_register_operand" ""))]
8804 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8805 address and use bx. */
8809 tmp = gen_reg_rtx (SImode);
8810 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8816 ;; NB Never uses BX.
8817 (define_insn "*arm_indirect_jump"
8819 (match_operand:SI 0 "s_register_operand" "r"))]
8821 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8822 [(set_attr "predicable" "yes")
8823 (set_attr "type" "branch")]
8826 (define_insn "*load_indirect_jump"
8828 (match_operand:SI 0 "memory_operand" "m"))]
8830 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8831 [(set_attr "type" "load_4")
8832 (set_attr "pool_range" "4096")
8833 (set_attr "neg_pool_range" "4084")
8834 (set_attr "predicable" "yes")]
8844 [(set (attr "length")
8845 (if_then_else (eq_attr "is_thumb" "yes")
8848 (set_attr "type" "mov_reg")]
8852 [(trap_if (const_int 1) (const_int 0))]
8856 return \".inst\\t0xe7f000f0\";
8858 return \".inst\\t0xdeff\";
8860 [(set (attr "length")
8861 (if_then_else (eq_attr "is_thumb" "yes")
8864 (set_attr "type" "trap")
8865 (set_attr "conds" "unconditional")]
8869 ;; Patterns to allow combination of arithmetic, cond code and shifts
8871 (define_insn "*<arith_shift_insn>_multsi"
8872 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8874 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8875 (match_operand:SI 3 "power_of_two_operand" ""))
8876 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8878 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8879 [(set_attr "predicable" "yes")
8880 (set_attr "predicable_short_it" "no")
8881 (set_attr "shift" "2")
8882 (set_attr "arch" "a,t2")
8883 (set_attr "type" "alu_shift_imm")])
8885 (define_insn "*<arith_shift_insn>_shiftsi"
8886 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8888 (match_operator:SI 2 "shift_nomul_operator"
8889 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8890 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8891 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8892 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8893 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8894 [(set_attr "predicable" "yes")
8895 (set_attr "predicable_short_it" "no")
8896 (set_attr "shift" "3")
8897 (set_attr "arch" "a,t2,a")
8898 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8901 [(set (match_operand:SI 0 "s_register_operand" "")
8902 (match_operator:SI 1 "shiftable_operator"
8903 [(match_operator:SI 2 "shiftable_operator"
8904 [(match_operator:SI 3 "shift_operator"
8905 [(match_operand:SI 4 "s_register_operand" "")
8906 (match_operand:SI 5 "reg_or_int_operand" "")])
8907 (match_operand:SI 6 "s_register_operand" "")])
8908 (match_operand:SI 7 "arm_rhs_operand" "")]))
8909 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8912 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8915 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8918 (define_insn "*arith_shiftsi_compare0"
8919 [(set (reg:CC_NOOV CC_REGNUM)
8921 (match_operator:SI 1 "shiftable_operator"
8922 [(match_operator:SI 3 "shift_operator"
8923 [(match_operand:SI 4 "s_register_operand" "r,r")
8924 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8925 (match_operand:SI 2 "s_register_operand" "r,r")])
8927 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8928 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8931 "%i1s%?\\t%0, %2, %4%S3"
8932 [(set_attr "conds" "set")
8933 (set_attr "shift" "4")
8934 (set_attr "arch" "32,a")
8935 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8937 (define_insn "*arith_shiftsi_compare0_scratch"
8938 [(set (reg:CC_NOOV CC_REGNUM)
8940 (match_operator:SI 1 "shiftable_operator"
8941 [(match_operator:SI 3 "shift_operator"
8942 [(match_operand:SI 4 "s_register_operand" "r,r")
8943 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8944 (match_operand:SI 2 "s_register_operand" "r,r")])
8946 (clobber (match_scratch:SI 0 "=r,r"))]
8948 "%i1s%?\\t%0, %2, %4%S3"
8949 [(set_attr "conds" "set")
8950 (set_attr "shift" "4")
8951 (set_attr "arch" "32,a")
8952 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8954 (define_insn "*sub_shiftsi"
8955 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8956 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8957 (match_operator:SI 2 "shift_operator"
8958 [(match_operand:SI 3 "s_register_operand" "r,r")
8959 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8961 "sub%?\\t%0, %1, %3%S2"
8962 [(set_attr "predicable" "yes")
8963 (set_attr "shift" "3")
8964 (set_attr "arch" "32,a")
8965 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8967 (define_insn "*sub_shiftsi_compare0"
8968 [(set (reg:CC_NOOV CC_REGNUM)
8970 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8971 (match_operator:SI 2 "shift_operator"
8972 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8973 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8975 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8976 (minus:SI (match_dup 1)
8977 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8979 "subs%?\\t%0, %1, %3%S2"
8980 [(set_attr "conds" "set")
8981 (set_attr "shift" "3")
8982 (set_attr "arch" "32,a,a")
8983 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8985 (define_insn "*sub_shiftsi_compare0_scratch"
8986 [(set (reg:CC_NOOV CC_REGNUM)
8988 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8989 (match_operator:SI 2 "shift_operator"
8990 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8991 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8993 (clobber (match_scratch:SI 0 "=r,r,r"))]
8995 "subs%?\\t%0, %1, %3%S2"
8996 [(set_attr "conds" "set")
8997 (set_attr "shift" "3")
8998 (set_attr "arch" "32,a,a")
8999 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9002 (define_insn_and_split "*and_scc"
9003 [(set (match_operand:SI 0 "s_register_operand" "=r")
9004 (and:SI (match_operator:SI 1 "arm_comparison_operator"
9005 [(match_operand 2 "cc_register" "") (const_int 0)])
9006 (match_operand:SI 3 "s_register_operand" "r")))]
9008 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
9009 "&& reload_completed"
9010 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
9011 (cond_exec (match_dup 4) (set (match_dup 0)
9012 (and:SI (match_dup 3) (const_int 1))))]
9014 machine_mode mode = GET_MODE (operands[2]);
9015 enum rtx_code rc = GET_CODE (operands[1]);
9017 /* Note that operands[4] is the same as operands[1],
9018 but with VOIDmode as the result. */
9019 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9020 if (mode == CCFPmode || mode == CCFPEmode)
9021 rc = reverse_condition_maybe_unordered (rc);
9023 rc = reverse_condition (rc);
9024 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9026 [(set_attr "conds" "use")
9027 (set_attr "type" "multiple")
9028 (set_attr "length" "8")]
9031 (define_insn_and_split "*ior_scc"
9032 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9033 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
9034 [(match_operand 2 "cc_register" "") (const_int 0)])
9035 (match_operand:SI 3 "s_register_operand" "0,?r")))]
9040 "&& reload_completed
9041 && REGNO (operands [0]) != REGNO (operands[3])"
9042 ;; && which_alternative == 1
9043 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
9044 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
9045 (cond_exec (match_dup 4) (set (match_dup 0)
9046 (ior:SI (match_dup 3) (const_int 1))))]
9048 machine_mode mode = GET_MODE (operands[2]);
9049 enum rtx_code rc = GET_CODE (operands[1]);
9051 /* Note that operands[4] is the same as operands[1],
9052 but with VOIDmode as the result. */
9053 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9054 if (mode == CCFPmode || mode == CCFPEmode)
9055 rc = reverse_condition_maybe_unordered (rc);
9057 rc = reverse_condition (rc);
9058 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9060 [(set_attr "conds" "use")
9061 (set_attr "length" "4,8")
9062 (set_attr "type" "logic_imm,multiple")]
9065 ; A series of splitters for the compare_scc pattern below. Note that
9066 ; order is important.
9068 [(set (match_operand:SI 0 "s_register_operand" "")
9069 (lt:SI (match_operand:SI 1 "s_register_operand" "")
9071 (clobber (reg:CC CC_REGNUM))]
9072 "TARGET_32BIT && reload_completed"
9073 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9076 [(set (match_operand:SI 0 "s_register_operand" "")
9077 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9079 (clobber (reg:CC CC_REGNUM))]
9080 "TARGET_32BIT && reload_completed"
9081 [(set (match_dup 0) (not:SI (match_dup 1)))
9082 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9085 [(set (match_operand:SI 0 "s_register_operand" "")
9086 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9088 (clobber (reg:CC CC_REGNUM))]
9089 "arm_arch5 && TARGET_32BIT"
9090 [(set (match_dup 0) (clz:SI (match_dup 1)))
9091 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9095 [(set (match_operand:SI 0 "s_register_operand" "")
9096 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9098 (clobber (reg:CC CC_REGNUM))]
9099 "TARGET_32BIT && reload_completed"
9101 [(set (reg:CC CC_REGNUM)
9102 (compare:CC (const_int 1) (match_dup 1)))
9104 (minus:SI (const_int 1) (match_dup 1)))])
9105 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9106 (set (match_dup 0) (const_int 0)))])
9109 [(set (match_operand:SI 0 "s_register_operand" "")
9110 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9111 (match_operand:SI 2 "const_int_operand" "")))
9112 (clobber (reg:CC CC_REGNUM))]
9113 "TARGET_32BIT && reload_completed"
9115 [(set (reg:CC CC_REGNUM)
9116 (compare:CC (match_dup 1) (match_dup 2)))
9117 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9118 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9119 (set (match_dup 0) (const_int 1)))]
9121 operands[3] = GEN_INT (-INTVAL (operands[2]));
9125 [(set (match_operand:SI 0 "s_register_operand" "")
9126 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9127 (match_operand:SI 2 "arm_add_operand" "")))
9128 (clobber (reg:CC CC_REGNUM))]
9129 "TARGET_32BIT && reload_completed"
9131 [(set (reg:CC_NOOV CC_REGNUM)
9132 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9134 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9135 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9136 (set (match_dup 0) (const_int 1)))])
9138 (define_insn_and_split "*compare_scc"
9139 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9140 (match_operator:SI 1 "arm_comparison_operator"
9141 [(match_operand:SI 2 "s_register_operand" "r,r")
9142 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9143 (clobber (reg:CC CC_REGNUM))]
9146 "&& reload_completed"
9147 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9148 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9149 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9152 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9153 operands[2], operands[3]);
9154 enum rtx_code rc = GET_CODE (operands[1]);
9156 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9158 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9159 if (mode == CCFPmode || mode == CCFPEmode)
9160 rc = reverse_condition_maybe_unordered (rc);
9162 rc = reverse_condition (rc);
9163 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9165 [(set_attr "type" "multiple")]
9168 ;; Attempt to improve the sequence generated by the compare_scc splitters
9169 ;; not to use conditional execution.
9171 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9175 [(set (reg:CC CC_REGNUM)
9176 (compare:CC (match_operand:SI 1 "register_operand" "")
9178 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9179 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9180 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9181 (set (match_dup 0) (const_int 1)))]
9182 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9183 [(set (match_dup 0) (clz:SI (match_dup 1)))
9184 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9187 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9191 [(set (reg:CC CC_REGNUM)
9192 (compare:CC (match_operand:SI 1 "register_operand" "")
9194 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9195 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9196 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9197 (set (match_dup 0) (const_int 1)))
9198 (match_scratch:SI 2 "r")]
9199 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9201 [(set (reg:CC CC_REGNUM)
9202 (compare:CC (const_int 0) (match_dup 1)))
9203 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9205 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9206 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9209 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9210 ;; sub Rd, Reg1, reg2
9214 [(set (reg:CC CC_REGNUM)
9215 (compare:CC (match_operand:SI 1 "register_operand" "")
9216 (match_operand:SI 2 "arm_rhs_operand" "")))
9217 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9218 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9219 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9220 (set (match_dup 0) (const_int 1)))]
9221 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9222 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9223 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9224 (set (match_dup 0) (clz:SI (match_dup 0)))
9225 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9229 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9230 ;; sub T1, Reg1, reg2
9234 [(set (reg:CC CC_REGNUM)
9235 (compare:CC (match_operand:SI 1 "register_operand" "")
9236 (match_operand:SI 2 "arm_rhs_operand" "")))
9237 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9238 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9239 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9240 (set (match_dup 0) (const_int 1)))
9241 (match_scratch:SI 3 "r")]
9242 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9243 [(set (match_dup 3) (match_dup 4))
9245 [(set (reg:CC CC_REGNUM)
9246 (compare:CC (const_int 0) (match_dup 3)))
9247 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9249 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9250 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9252 if (CONST_INT_P (operands[2]))
9253 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9255 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9258 (define_insn "*cond_move"
9259 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9260 (if_then_else:SI (match_operator 3 "equality_operator"
9261 [(match_operator 4 "arm_comparison_operator"
9262 [(match_operand 5 "cc_register" "") (const_int 0)])
9264 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9265 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9268 if (GET_CODE (operands[3]) == NE)
9270 if (which_alternative != 1)
9271 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9272 if (which_alternative != 0)
9273 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9276 if (which_alternative != 0)
9277 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9278 if (which_alternative != 1)
9279 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9282 [(set_attr "conds" "use")
9283 (set_attr_alternative "type"
9284 [(if_then_else (match_operand 2 "const_int_operand" "")
9285 (const_string "mov_imm")
9286 (const_string "mov_reg"))
9287 (if_then_else (match_operand 1 "const_int_operand" "")
9288 (const_string "mov_imm")
9289 (const_string "mov_reg"))
9290 (const_string "multiple")])
9291 (set_attr "length" "4,4,8")]
9294 (define_insn "*cond_arith"
9295 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9296 (match_operator:SI 5 "shiftable_operator"
9297 [(match_operator:SI 4 "arm_comparison_operator"
9298 [(match_operand:SI 2 "s_register_operand" "r,r")
9299 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9300 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9301 (clobber (reg:CC CC_REGNUM))]
9304 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9305 return \"%i5\\t%0, %1, %2, lsr #31\";
9307 output_asm_insn (\"cmp\\t%2, %3\", operands);
9308 if (GET_CODE (operands[5]) == AND)
9309 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9310 else if (GET_CODE (operands[5]) == MINUS)
9311 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9312 else if (which_alternative != 0)
9313 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9314 return \"%i5%d4\\t%0, %1, #1\";
9316 [(set_attr "conds" "clob")
9317 (set_attr "length" "12")
9318 (set_attr "type" "multiple")]
9321 (define_insn "*cond_sub"
9322 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9323 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9324 (match_operator:SI 4 "arm_comparison_operator"
9325 [(match_operand:SI 2 "s_register_operand" "r,r")
9326 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9327 (clobber (reg:CC CC_REGNUM))]
9330 output_asm_insn (\"cmp\\t%2, %3\", operands);
9331 if (which_alternative != 0)
9332 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9333 return \"sub%d4\\t%0, %1, #1\";
9335 [(set_attr "conds" "clob")
9336 (set_attr "length" "8,12")
9337 (set_attr "type" "multiple")]
9340 (define_insn "*cmp_ite0"
9341 [(set (match_operand 6 "dominant_cc_register" "")
9344 (match_operator 4 "arm_comparison_operator"
9345 [(match_operand:SI 0 "s_register_operand"
9346 "l,l,l,r,r,r,r,r,r")
9347 (match_operand:SI 1 "arm_add_operand"
9348 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9349 (match_operator:SI 5 "arm_comparison_operator"
9350 [(match_operand:SI 2 "s_register_operand"
9351 "l,r,r,l,l,r,r,r,r")
9352 (match_operand:SI 3 "arm_add_operand"
9353 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9359 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9361 {\"cmp%d5\\t%0, %1\",
9362 \"cmp%d4\\t%2, %3\"},
9363 {\"cmn%d5\\t%0, #%n1\",
9364 \"cmp%d4\\t%2, %3\"},
9365 {\"cmp%d5\\t%0, %1\",
9366 \"cmn%d4\\t%2, #%n3\"},
9367 {\"cmn%d5\\t%0, #%n1\",
9368 \"cmn%d4\\t%2, #%n3\"}
9370 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9375 \"cmn\\t%0, #%n1\"},
9376 {\"cmn\\t%2, #%n3\",
9378 {\"cmn\\t%2, #%n3\",
9381 static const char * const ite[2] =
9386 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9387 CMP_CMP, CMN_CMP, CMP_CMP,
9388 CMN_CMP, CMP_CMN, CMN_CMN};
9390 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9392 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9393 if (TARGET_THUMB2) {
9394 output_asm_insn (ite[swap], operands);
9396 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9399 [(set_attr "conds" "set")
9400 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9401 (set_attr "type" "multiple")
9402 (set_attr_alternative "length"
9408 (if_then_else (eq_attr "is_thumb" "no")
9411 (if_then_else (eq_attr "is_thumb" "no")
9414 (if_then_else (eq_attr "is_thumb" "no")
9417 (if_then_else (eq_attr "is_thumb" "no")
9422 (define_insn "*cmp_ite1"
9423 [(set (match_operand 6 "dominant_cc_register" "")
9426 (match_operator 4 "arm_comparison_operator"
9427 [(match_operand:SI 0 "s_register_operand"
9428 "l,l,l,r,r,r,r,r,r")
9429 (match_operand:SI 1 "arm_add_operand"
9430 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9431 (match_operator:SI 5 "arm_comparison_operator"
9432 [(match_operand:SI 2 "s_register_operand"
9433 "l,r,r,l,l,r,r,r,r")
9434 (match_operand:SI 3 "arm_add_operand"
9435 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9441 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9445 {\"cmn\\t%0, #%n1\",
9448 \"cmn\\t%2, #%n3\"},
9449 {\"cmn\\t%0, #%n1\",
9452 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9454 {\"cmp%d4\\t%2, %3\",
9455 \"cmp%D5\\t%0, %1\"},
9456 {\"cmp%d4\\t%2, %3\",
9457 \"cmn%D5\\t%0, #%n1\"},
9458 {\"cmn%d4\\t%2, #%n3\",
9459 \"cmp%D5\\t%0, %1\"},
9460 {\"cmn%d4\\t%2, #%n3\",
9461 \"cmn%D5\\t%0, #%n1\"}
9463 static const char * const ite[2] =
9468 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9469 CMP_CMP, CMN_CMP, CMP_CMP,
9470 CMN_CMP, CMP_CMN, CMN_CMN};
9472 comparison_dominates_p (GET_CODE (operands[5]),
9473 reverse_condition (GET_CODE (operands[4])));
9475 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9476 if (TARGET_THUMB2) {
9477 output_asm_insn (ite[swap], operands);
9479 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9482 [(set_attr "conds" "set")
9483 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9484 (set_attr_alternative "length"
9490 (if_then_else (eq_attr "is_thumb" "no")
9493 (if_then_else (eq_attr "is_thumb" "no")
9496 (if_then_else (eq_attr "is_thumb" "no")
9499 (if_then_else (eq_attr "is_thumb" "no")
9502 (set_attr "type" "multiple")]
9505 (define_insn "*cmp_and"
9506 [(set (match_operand 6 "dominant_cc_register" "")
9509 (match_operator 4 "arm_comparison_operator"
9510 [(match_operand:SI 0 "s_register_operand"
9511 "l,l,l,r,r,r,r,r,r")
9512 (match_operand:SI 1 "arm_add_operand"
9513 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9514 (match_operator:SI 5 "arm_comparison_operator"
9515 [(match_operand:SI 2 "s_register_operand"
9516 "l,r,r,l,l,r,r,r,r")
9517 (match_operand:SI 3 "arm_add_operand"
9518 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9523 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9525 {\"cmp%d5\\t%0, %1\",
9526 \"cmp%d4\\t%2, %3\"},
9527 {\"cmn%d5\\t%0, #%n1\",
9528 \"cmp%d4\\t%2, %3\"},
9529 {\"cmp%d5\\t%0, %1\",
9530 \"cmn%d4\\t%2, #%n3\"},
9531 {\"cmn%d5\\t%0, #%n1\",
9532 \"cmn%d4\\t%2, #%n3\"}
9534 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9539 \"cmn\\t%0, #%n1\"},
9540 {\"cmn\\t%2, #%n3\",
9542 {\"cmn\\t%2, #%n3\",
9545 static const char *const ite[2] =
9550 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9551 CMP_CMP, CMN_CMP, CMP_CMP,
9552 CMN_CMP, CMP_CMN, CMN_CMN};
9554 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9556 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9557 if (TARGET_THUMB2) {
9558 output_asm_insn (ite[swap], operands);
9560 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9563 [(set_attr "conds" "set")
9564 (set_attr "predicable" "no")
9565 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9566 (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9567 (set_attr_alternative "length"
9573 (if_then_else (eq_attr "is_thumb" "no")
9576 (if_then_else (eq_attr "is_thumb" "no")
9579 (if_then_else (eq_attr "is_thumb" "no")
9582 (if_then_else (eq_attr "is_thumb" "no")
9585 (set_attr "type" "multiple")]
9588 (define_insn "*cmp_ior"
9589 [(set (match_operand 6 "dominant_cc_register" "")
9592 (match_operator 4 "arm_comparison_operator"
9593 [(match_operand:SI 0 "s_register_operand"
9594 "l,l,l,r,r,r,r,r,r")
9595 (match_operand:SI 1 "arm_add_operand"
9596 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9597 (match_operator:SI 5 "arm_comparison_operator"
9598 [(match_operand:SI 2 "s_register_operand"
9599 "l,r,r,l,l,r,r,r,r")
9600 (match_operand:SI 3 "arm_add_operand"
9601 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9606 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9610 {\"cmn\\t%0, #%n1\",
9613 \"cmn\\t%2, #%n3\"},
9614 {\"cmn\\t%0, #%n1\",
9617 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9619 {\"cmp%D4\\t%2, %3\",
9620 \"cmp%D5\\t%0, %1\"},
9621 {\"cmp%D4\\t%2, %3\",
9622 \"cmn%D5\\t%0, #%n1\"},
9623 {\"cmn%D4\\t%2, #%n3\",
9624 \"cmp%D5\\t%0, %1\"},
9625 {\"cmn%D4\\t%2, #%n3\",
9626 \"cmn%D5\\t%0, #%n1\"}
9628 static const char *const ite[2] =
9633 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9634 CMP_CMP, CMN_CMP, CMP_CMP,
9635 CMN_CMP, CMP_CMN, CMN_CMN};
9637 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9639 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9640 if (TARGET_THUMB2) {
9641 output_asm_insn (ite[swap], operands);
9643 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9647 [(set_attr "conds" "set")
9648 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9649 (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9650 (set_attr_alternative "length"
9656 (if_then_else (eq_attr "is_thumb" "no")
9659 (if_then_else (eq_attr "is_thumb" "no")
9662 (if_then_else (eq_attr "is_thumb" "no")
9665 (if_then_else (eq_attr "is_thumb" "no")
9668 (set_attr "type" "multiple")]
9671 (define_insn_and_split "*ior_scc_scc"
9672 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9673 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9674 [(match_operand:SI 1 "s_register_operand" "l,r")
9675 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9676 (match_operator:SI 6 "arm_comparison_operator"
9677 [(match_operand:SI 4 "s_register_operand" "l,r")
9678 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9679 (clobber (reg:CC CC_REGNUM))]
9681 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9684 "TARGET_32BIT && reload_completed"
9688 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9689 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9691 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9693 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9696 [(set_attr "conds" "clob")
9697 (set_attr "enabled_for_depr_it" "yes,no")
9698 (set_attr "length" "16")
9699 (set_attr "type" "multiple")]
9702 ; If the above pattern is followed by a CMP insn, then the compare is
9703 ; redundant, since we can rework the conditional instruction that follows.
9704 (define_insn_and_split "*ior_scc_scc_cmp"
9705 [(set (match_operand 0 "dominant_cc_register" "")
9706 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9707 [(match_operand:SI 1 "s_register_operand" "l,r")
9708 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9709 (match_operator:SI 6 "arm_comparison_operator"
9710 [(match_operand:SI 4 "s_register_operand" "l,r")
9711 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9713 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9714 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9715 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9718 "TARGET_32BIT && reload_completed"
9722 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9723 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9725 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9727 [(set_attr "conds" "set")
9728 (set_attr "enabled_for_depr_it" "yes,no")
9729 (set_attr "length" "16")
9730 (set_attr "type" "multiple")]
9733 (define_insn_and_split "*and_scc_scc"
9734 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9735 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9736 [(match_operand:SI 1 "s_register_operand" "l,r")
9737 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9738 (match_operator:SI 6 "arm_comparison_operator"
9739 [(match_operand:SI 4 "s_register_operand" "l,r")
9740 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9741 (clobber (reg:CC CC_REGNUM))]
9743 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9746 "TARGET_32BIT && reload_completed
9747 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9752 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9753 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9755 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9757 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9760 [(set_attr "conds" "clob")
9761 (set_attr "enabled_for_depr_it" "yes,no")
9762 (set_attr "length" "16")
9763 (set_attr "type" "multiple")]
9766 ; If the above pattern is followed by a CMP insn, then the compare is
9767 ; redundant, since we can rework the conditional instruction that follows.
9768 (define_insn_and_split "*and_scc_scc_cmp"
9769 [(set (match_operand 0 "dominant_cc_register" "")
9770 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9771 [(match_operand:SI 1 "s_register_operand" "l,r")
9772 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9773 (match_operator:SI 6 "arm_comparison_operator"
9774 [(match_operand:SI 4 "s_register_operand" "l,r")
9775 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9777 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9778 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9779 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9782 "TARGET_32BIT && reload_completed"
9786 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9787 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9789 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9791 [(set_attr "conds" "set")
9792 (set_attr "enabled_for_depr_it" "yes,no")
9793 (set_attr "length" "16")
9794 (set_attr "type" "multiple")]
9797 ;; If there is no dominance in the comparison, then we can still save an
9798 ;; instruction in the AND case, since we can know that the second compare
9799 ;; need only zero the value if false (if true, then the value is already
9801 (define_insn_and_split "*and_scc_scc_nodom"
9802 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9803 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9804 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9805 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9806 (match_operator:SI 6 "arm_comparison_operator"
9807 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9808 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9809 (clobber (reg:CC CC_REGNUM))]
9811 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9814 "TARGET_32BIT && reload_completed"
9815 [(parallel [(set (match_dup 0)
9816 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9817 (clobber (reg:CC CC_REGNUM))])
9818 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9820 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9823 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9824 operands[4], operands[5]),
9826 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9828 [(set_attr "conds" "clob")
9829 (set_attr "length" "20")
9830 (set_attr "type" "multiple")]
9834 [(set (reg:CC_NOOV CC_REGNUM)
9835 (compare:CC_NOOV (ior:SI
9836 (and:SI (match_operand:SI 0 "s_register_operand" "")
9838 (match_operator:SI 1 "arm_comparison_operator"
9839 [(match_operand:SI 2 "s_register_operand" "")
9840 (match_operand:SI 3 "arm_add_operand" "")]))
9842 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9845 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9847 (set (reg:CC_NOOV CC_REGNUM)
9848 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9853 [(set (reg:CC_NOOV CC_REGNUM)
9854 (compare:CC_NOOV (ior:SI
9855 (match_operator:SI 1 "arm_comparison_operator"
9856 [(match_operand:SI 2 "s_register_operand" "")
9857 (match_operand:SI 3 "arm_add_operand" "")])
9858 (and:SI (match_operand:SI 0 "s_register_operand" "")
9861 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9864 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9866 (set (reg:CC_NOOV CC_REGNUM)
9867 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9870 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9872 (define_insn_and_split "*negscc"
9873 [(set (match_operand:SI 0 "s_register_operand" "=r")
9874 (neg:SI (match_operator 3 "arm_comparison_operator"
9875 [(match_operand:SI 1 "s_register_operand" "r")
9876 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9877 (clobber (reg:CC CC_REGNUM))]
9880 "&& reload_completed"
9883 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9885 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9887 /* Emit mov\\t%0, %1, asr #31 */
9888 emit_insn (gen_rtx_SET (operands[0],
9889 gen_rtx_ASHIFTRT (SImode,
9894 else if (GET_CODE (operands[3]) == NE)
9896 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9897 if (CONST_INT_P (operands[2]))
9898 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9899 GEN_INT (- INTVAL (operands[2]))));
9901 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9903 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9907 gen_rtx_SET (operands[0],
9913 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9914 emit_insn (gen_rtx_SET (cc_reg,
9915 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9916 enum rtx_code rc = GET_CODE (operands[3]);
9918 rc = reverse_condition (rc);
9919 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9924 gen_rtx_SET (operands[0], const0_rtx)));
9925 rc = GET_CODE (operands[3]);
9926 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9931 gen_rtx_SET (operands[0],
9937 [(set_attr "conds" "clob")
9938 (set_attr "length" "12")
9939 (set_attr "type" "multiple")]
9942 (define_insn_and_split "movcond_addsi"
9943 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9945 (match_operator 5 "comparison_operator"
9946 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9947 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9949 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9950 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9951 (clobber (reg:CC CC_REGNUM))]
9954 "&& reload_completed"
9955 [(set (reg:CC_NOOV CC_REGNUM)
9957 (plus:SI (match_dup 3)
9960 (set (match_dup 0) (match_dup 1))
9961 (cond_exec (match_dup 6)
9962 (set (match_dup 0) (match_dup 2)))]
9965 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9966 operands[3], operands[4]);
9967 enum rtx_code rc = GET_CODE (operands[5]);
9968 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9969 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9970 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9971 rc = reverse_condition (rc);
9973 std::swap (operands[1], operands[2]);
9975 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9978 [(set_attr "conds" "clob")
9979 (set_attr "enabled_for_depr_it" "no,yes,yes")
9980 (set_attr "type" "multiple")]
9983 (define_insn "movcond"
9984 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9986 (match_operator 5 "arm_comparison_operator"
9987 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9988 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9989 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9990 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9991 (clobber (reg:CC CC_REGNUM))]
9994 if (GET_CODE (operands[5]) == LT
9995 && (operands[4] == const0_rtx))
9997 if (which_alternative != 1 && REG_P (operands[1]))
9999 if (operands[2] == const0_rtx)
10000 return \"and\\t%0, %1, %3, asr #31\";
10001 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
10003 else if (which_alternative != 0 && REG_P (operands[2]))
10005 if (operands[1] == const0_rtx)
10006 return \"bic\\t%0, %2, %3, asr #31\";
10007 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
10009 /* The only case that falls through to here is when both ops 1 & 2
10013 if (GET_CODE (operands[5]) == GE
10014 && (operands[4] == const0_rtx))
10016 if (which_alternative != 1 && REG_P (operands[1]))
10018 if (operands[2] == const0_rtx)
10019 return \"bic\\t%0, %1, %3, asr #31\";
10020 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
10022 else if (which_alternative != 0 && REG_P (operands[2]))
10024 if (operands[1] == const0_rtx)
10025 return \"and\\t%0, %2, %3, asr #31\";
10026 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
10028 /* The only case that falls through to here is when both ops 1 & 2
10031 if (CONST_INT_P (operands[4])
10032 && !const_ok_for_arm (INTVAL (operands[4])))
10033 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
10035 output_asm_insn (\"cmp\\t%3, %4\", operands);
10036 if (which_alternative != 0)
10037 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
10038 if (which_alternative != 1)
10039 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
10042 [(set_attr "conds" "clob")
10043 (set_attr "length" "8,8,12")
10044 (set_attr "type" "multiple")]
10047 ;; ??? The patterns below need checking for Thumb-2 usefulness.
10049 (define_insn "*ifcompare_plus_move"
10050 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10051 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10052 [(match_operand:SI 4 "s_register_operand" "r,r")
10053 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10055 (match_operand:SI 2 "s_register_operand" "r,r")
10056 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10057 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10058 (clobber (reg:CC CC_REGNUM))]
10061 [(set_attr "conds" "clob")
10062 (set_attr "length" "8,12")
10063 (set_attr "type" "multiple")]
10066 (define_insn "*if_plus_move"
10067 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10069 (match_operator 4 "arm_comparison_operator"
10070 [(match_operand 5 "cc_register" "") (const_int 0)])
10072 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10073 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10074 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10077 add%d4\\t%0, %2, %3
10078 sub%d4\\t%0, %2, #%n3
10079 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10080 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10081 [(set_attr "conds" "use")
10082 (set_attr "length" "4,4,8,8")
10083 (set_attr_alternative "type"
10084 [(if_then_else (match_operand 3 "const_int_operand" "")
10085 (const_string "alu_imm" )
10086 (const_string "alu_sreg"))
10087 (const_string "alu_imm")
10088 (const_string "multiple")
10089 (const_string "multiple")])]
10092 (define_insn "*ifcompare_move_plus"
10093 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10094 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10095 [(match_operand:SI 4 "s_register_operand" "r,r")
10096 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10097 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10099 (match_operand:SI 2 "s_register_operand" "r,r")
10100 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10101 (clobber (reg:CC CC_REGNUM))]
10104 [(set_attr "conds" "clob")
10105 (set_attr "length" "8,12")
10106 (set_attr "type" "multiple")]
10109 (define_insn "*if_move_plus"
10110 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10112 (match_operator 4 "arm_comparison_operator"
10113 [(match_operand 5 "cc_register" "") (const_int 0)])
10114 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10116 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10117 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10120 add%D4\\t%0, %2, %3
10121 sub%D4\\t%0, %2, #%n3
10122 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10123 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10124 [(set_attr "conds" "use")
10125 (set_attr "length" "4,4,8,8")
10126 (set_attr_alternative "type"
10127 [(if_then_else (match_operand 3 "const_int_operand" "")
10128 (const_string "alu_imm" )
10129 (const_string "alu_sreg"))
10130 (const_string "alu_imm")
10131 (const_string "multiple")
10132 (const_string "multiple")])]
10135 (define_insn "*ifcompare_arith_arith"
10136 [(set (match_operand:SI 0 "s_register_operand" "=r")
10137 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10138 [(match_operand:SI 5 "s_register_operand" "r")
10139 (match_operand:SI 6 "arm_add_operand" "rIL")])
10140 (match_operator:SI 8 "shiftable_operator"
10141 [(match_operand:SI 1 "s_register_operand" "r")
10142 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10143 (match_operator:SI 7 "shiftable_operator"
10144 [(match_operand:SI 3 "s_register_operand" "r")
10145 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10146 (clobber (reg:CC CC_REGNUM))]
10149 [(set_attr "conds" "clob")
10150 (set_attr "length" "12")
10151 (set_attr "type" "multiple")]
10154 (define_insn "*if_arith_arith"
10155 [(set (match_operand:SI 0 "s_register_operand" "=r")
10156 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10157 [(match_operand 8 "cc_register" "") (const_int 0)])
10158 (match_operator:SI 6 "shiftable_operator"
10159 [(match_operand:SI 1 "s_register_operand" "r")
10160 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10161 (match_operator:SI 7 "shiftable_operator"
10162 [(match_operand:SI 3 "s_register_operand" "r")
10163 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10165 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10166 [(set_attr "conds" "use")
10167 (set_attr "length" "8")
10168 (set_attr "type" "multiple")]
10171 (define_insn "*ifcompare_arith_move"
10172 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10173 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10174 [(match_operand:SI 2 "s_register_operand" "r,r")
10175 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10176 (match_operator:SI 7 "shiftable_operator"
10177 [(match_operand:SI 4 "s_register_operand" "r,r")
10178 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10179 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10180 (clobber (reg:CC CC_REGNUM))]
10183 /* If we have an operation where (op x 0) is the identity operation and
10184 the conditional operator is LT or GE and we are comparing against zero and
10185 everything is in registers then we can do this in two instructions. */
10186 if (operands[3] == const0_rtx
10187 && GET_CODE (operands[7]) != AND
10188 && REG_P (operands[5])
10189 && REG_P (operands[1])
10190 && REGNO (operands[1]) == REGNO (operands[4])
10191 && REGNO (operands[4]) != REGNO (operands[0]))
10193 if (GET_CODE (operands[6]) == LT)
10194 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10195 else if (GET_CODE (operands[6]) == GE)
10196 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10198 if (CONST_INT_P (operands[3])
10199 && !const_ok_for_arm (INTVAL (operands[3])))
10200 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10202 output_asm_insn (\"cmp\\t%2, %3\", operands);
10203 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10204 if (which_alternative != 0)
10205 return \"mov%D6\\t%0, %1\";
10208 [(set_attr "conds" "clob")
10209 (set_attr "length" "8,12")
10210 (set_attr "type" "multiple")]
10213 (define_insn "*if_arith_move"
10214 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10215 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10216 [(match_operand 6 "cc_register" "") (const_int 0)])
10217 (match_operator:SI 5 "shiftable_operator"
10218 [(match_operand:SI 2 "s_register_operand" "r,r")
10219 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10220 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10223 %I5%d4\\t%0, %2, %3
10224 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10225 [(set_attr "conds" "use")
10226 (set_attr "length" "4,8")
10227 (set_attr_alternative "type"
10228 [(if_then_else (match_operand 3 "const_int_operand" "")
10229 (const_string "alu_shift_imm" )
10230 (const_string "alu_shift_reg"))
10231 (const_string "multiple")])]
10234 (define_insn "*ifcompare_move_arith"
10235 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10236 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10237 [(match_operand:SI 4 "s_register_operand" "r,r")
10238 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10239 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10240 (match_operator:SI 7 "shiftable_operator"
10241 [(match_operand:SI 2 "s_register_operand" "r,r")
10242 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10243 (clobber (reg:CC CC_REGNUM))]
10246 /* If we have an operation where (op x 0) is the identity operation and
10247 the conditional operator is LT or GE and we are comparing against zero and
10248 everything is in registers then we can do this in two instructions */
10249 if (operands[5] == const0_rtx
10250 && GET_CODE (operands[7]) != AND
10251 && REG_P (operands[3])
10252 && REG_P (operands[1])
10253 && REGNO (operands[1]) == REGNO (operands[2])
10254 && REGNO (operands[2]) != REGNO (operands[0]))
10256 if (GET_CODE (operands[6]) == GE)
10257 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10258 else if (GET_CODE (operands[6]) == LT)
10259 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10262 if (CONST_INT_P (operands[5])
10263 && !const_ok_for_arm (INTVAL (operands[5])))
10264 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10266 output_asm_insn (\"cmp\\t%4, %5\", operands);
10268 if (which_alternative != 0)
10269 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10270 return \"%I7%D6\\t%0, %2, %3\";
10272 [(set_attr "conds" "clob")
10273 (set_attr "length" "8,12")
10274 (set_attr "type" "multiple")]
10277 (define_insn "*if_move_arith"
10278 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10280 (match_operator 4 "arm_comparison_operator"
10281 [(match_operand 6 "cc_register" "") (const_int 0)])
10282 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10283 (match_operator:SI 5 "shiftable_operator"
10284 [(match_operand:SI 2 "s_register_operand" "r,r")
10285 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10288 %I5%D4\\t%0, %2, %3
10289 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10290 [(set_attr "conds" "use")
10291 (set_attr "length" "4,8")
10292 (set_attr_alternative "type"
10293 [(if_then_else (match_operand 3 "const_int_operand" "")
10294 (const_string "alu_shift_imm" )
10295 (const_string "alu_shift_reg"))
10296 (const_string "multiple")])]
10299 (define_insn "*ifcompare_move_not"
10300 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10302 (match_operator 5 "arm_comparison_operator"
10303 [(match_operand:SI 3 "s_register_operand" "r,r")
10304 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10305 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10307 (match_operand:SI 2 "s_register_operand" "r,r"))))
10308 (clobber (reg:CC CC_REGNUM))]
10311 [(set_attr "conds" "clob")
10312 (set_attr "length" "8,12")
10313 (set_attr "type" "multiple")]
10316 (define_insn "*if_move_not"
10317 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10319 (match_operator 4 "arm_comparison_operator"
10320 [(match_operand 3 "cc_register" "") (const_int 0)])
10321 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10322 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10326 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10327 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10328 [(set_attr "conds" "use")
10329 (set_attr "type" "mvn_reg")
10330 (set_attr "length" "4,8,8")
10331 (set_attr "type" "mvn_reg,multiple,multiple")]
10334 (define_insn "*ifcompare_not_move"
10335 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10337 (match_operator 5 "arm_comparison_operator"
10338 [(match_operand:SI 3 "s_register_operand" "r,r")
10339 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10341 (match_operand:SI 2 "s_register_operand" "r,r"))
10342 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10343 (clobber (reg:CC CC_REGNUM))]
10346 [(set_attr "conds" "clob")
10347 (set_attr "length" "8,12")
10348 (set_attr "type" "multiple")]
10351 (define_insn "*if_not_move"
10352 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10354 (match_operator 4 "arm_comparison_operator"
10355 [(match_operand 3 "cc_register" "") (const_int 0)])
10356 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10357 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10361 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10362 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10363 [(set_attr "conds" "use")
10364 (set_attr "type" "mvn_reg,multiple,multiple")
10365 (set_attr "length" "4,8,8")]
10368 (define_insn "*ifcompare_shift_move"
10369 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10371 (match_operator 6 "arm_comparison_operator"
10372 [(match_operand:SI 4 "s_register_operand" "r,r")
10373 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10374 (match_operator:SI 7 "shift_operator"
10375 [(match_operand:SI 2 "s_register_operand" "r,r")
10376 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10377 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10378 (clobber (reg:CC CC_REGNUM))]
10381 [(set_attr "conds" "clob")
10382 (set_attr "length" "8,12")
10383 (set_attr "type" "multiple")]
10386 (define_insn "*if_shift_move"
10387 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10389 (match_operator 5 "arm_comparison_operator"
10390 [(match_operand 6 "cc_register" "") (const_int 0)])
10391 (match_operator:SI 4 "shift_operator"
10392 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10393 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10394 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10398 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10399 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10400 [(set_attr "conds" "use")
10401 (set_attr "shift" "2")
10402 (set_attr "length" "4,8,8")
10403 (set_attr_alternative "type"
10404 [(if_then_else (match_operand 3 "const_int_operand" "")
10405 (const_string "mov_shift" )
10406 (const_string "mov_shift_reg"))
10407 (const_string "multiple")
10408 (const_string "multiple")])]
10411 (define_insn "*ifcompare_move_shift"
10412 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10414 (match_operator 6 "arm_comparison_operator"
10415 [(match_operand:SI 4 "s_register_operand" "r,r")
10416 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10417 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10418 (match_operator:SI 7 "shift_operator"
10419 [(match_operand:SI 2 "s_register_operand" "r,r")
10420 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10421 (clobber (reg:CC CC_REGNUM))]
10424 [(set_attr "conds" "clob")
10425 (set_attr "length" "8,12")
10426 (set_attr "type" "multiple")]
10429 (define_insn "*if_move_shift"
10430 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10432 (match_operator 5 "arm_comparison_operator"
10433 [(match_operand 6 "cc_register" "") (const_int 0)])
10434 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10435 (match_operator:SI 4 "shift_operator"
10436 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10437 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10441 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10442 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10443 [(set_attr "conds" "use")
10444 (set_attr "shift" "2")
10445 (set_attr "length" "4,8,8")
10446 (set_attr_alternative "type"
10447 [(if_then_else (match_operand 3 "const_int_operand" "")
10448 (const_string "mov_shift" )
10449 (const_string "mov_shift_reg"))
10450 (const_string "multiple")
10451 (const_string "multiple")])]
10454 (define_insn "*ifcompare_shift_shift"
10455 [(set (match_operand:SI 0 "s_register_operand" "=r")
10457 (match_operator 7 "arm_comparison_operator"
10458 [(match_operand:SI 5 "s_register_operand" "r")
10459 (match_operand:SI 6 "arm_add_operand" "rIL")])
10460 (match_operator:SI 8 "shift_operator"
10461 [(match_operand:SI 1 "s_register_operand" "r")
10462 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10463 (match_operator:SI 9 "shift_operator"
10464 [(match_operand:SI 3 "s_register_operand" "r")
10465 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10466 (clobber (reg:CC CC_REGNUM))]
10469 [(set_attr "conds" "clob")
10470 (set_attr "length" "12")
10471 (set_attr "type" "multiple")]
10474 (define_insn "*if_shift_shift"
10475 [(set (match_operand:SI 0 "s_register_operand" "=r")
10477 (match_operator 5 "arm_comparison_operator"
10478 [(match_operand 8 "cc_register" "") (const_int 0)])
10479 (match_operator:SI 6 "shift_operator"
10480 [(match_operand:SI 1 "s_register_operand" "r")
10481 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10482 (match_operator:SI 7 "shift_operator"
10483 [(match_operand:SI 3 "s_register_operand" "r")
10484 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10486 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10487 [(set_attr "conds" "use")
10488 (set_attr "shift" "1")
10489 (set_attr "length" "8")
10490 (set (attr "type") (if_then_else
10491 (and (match_operand 2 "const_int_operand" "")
10492 (match_operand 4 "const_int_operand" ""))
10493 (const_string "mov_shift")
10494 (const_string "mov_shift_reg")))]
10497 (define_insn "*ifcompare_not_arith"
10498 [(set (match_operand:SI 0 "s_register_operand" "=r")
10500 (match_operator 6 "arm_comparison_operator"
10501 [(match_operand:SI 4 "s_register_operand" "r")
10502 (match_operand:SI 5 "arm_add_operand" "rIL")])
10503 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10504 (match_operator:SI 7 "shiftable_operator"
10505 [(match_operand:SI 2 "s_register_operand" "r")
10506 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10507 (clobber (reg:CC CC_REGNUM))]
10510 [(set_attr "conds" "clob")
10511 (set_attr "length" "12")
10512 (set_attr "type" "multiple")]
10515 (define_insn "*if_not_arith"
10516 [(set (match_operand:SI 0 "s_register_operand" "=r")
10518 (match_operator 5 "arm_comparison_operator"
10519 [(match_operand 4 "cc_register" "") (const_int 0)])
10520 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10521 (match_operator:SI 6 "shiftable_operator"
10522 [(match_operand:SI 2 "s_register_operand" "r")
10523 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10525 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10526 [(set_attr "conds" "use")
10527 (set_attr "type" "mvn_reg")
10528 (set_attr "length" "8")]
10531 (define_insn "*ifcompare_arith_not"
10532 [(set (match_operand:SI 0 "s_register_operand" "=r")
10534 (match_operator 6 "arm_comparison_operator"
10535 [(match_operand:SI 4 "s_register_operand" "r")
10536 (match_operand:SI 5 "arm_add_operand" "rIL")])
10537 (match_operator:SI 7 "shiftable_operator"
10538 [(match_operand:SI 2 "s_register_operand" "r")
10539 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10540 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10541 (clobber (reg:CC CC_REGNUM))]
10544 [(set_attr "conds" "clob")
10545 (set_attr "length" "12")
10546 (set_attr "type" "multiple")]
10549 (define_insn "*if_arith_not"
10550 [(set (match_operand:SI 0 "s_register_operand" "=r")
10552 (match_operator 5 "arm_comparison_operator"
10553 [(match_operand 4 "cc_register" "") (const_int 0)])
10554 (match_operator:SI 6 "shiftable_operator"
10555 [(match_operand:SI 2 "s_register_operand" "r")
10556 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10557 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10559 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10560 [(set_attr "conds" "use")
10561 (set_attr "type" "multiple")
10562 (set_attr "length" "8")]
10565 (define_insn "*ifcompare_neg_move"
10566 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10568 (match_operator 5 "arm_comparison_operator"
10569 [(match_operand:SI 3 "s_register_operand" "r,r")
10570 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10571 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10572 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10573 (clobber (reg:CC CC_REGNUM))]
10576 [(set_attr "conds" "clob")
10577 (set_attr "length" "8,12")
10578 (set_attr "type" "multiple")]
10581 (define_insn_and_split "*if_neg_move"
10582 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10584 (match_operator 4 "arm_comparison_operator"
10585 [(match_operand 3 "cc_register" "") (const_int 0)])
10586 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10587 (match_operand:SI 1 "s_register_operand" "0,0")))]
10590 "&& reload_completed"
10591 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10592 (set (match_dup 0) (neg:SI (match_dup 2))))]
10594 [(set_attr "conds" "use")
10595 (set_attr "length" "4")
10596 (set_attr "arch" "t2,32")
10597 (set_attr "enabled_for_depr_it" "yes,no")
10598 (set_attr "type" "logic_shift_imm")]
10601 (define_insn "*ifcompare_move_neg"
10602 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10604 (match_operator 5 "arm_comparison_operator"
10605 [(match_operand:SI 3 "s_register_operand" "r,r")
10606 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10607 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10608 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10609 (clobber (reg:CC CC_REGNUM))]
10612 [(set_attr "conds" "clob")
10613 (set_attr "length" "8,12")
10614 (set_attr "type" "multiple")]
10617 (define_insn_and_split "*if_move_neg"
10618 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10620 (match_operator 4 "arm_comparison_operator"
10621 [(match_operand 3 "cc_register" "") (const_int 0)])
10622 (match_operand:SI 1 "s_register_operand" "0,0")
10623 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10626 "&& reload_completed"
10627 [(cond_exec (match_dup 5)
10628 (set (match_dup 0) (neg:SI (match_dup 2))))]
10630 machine_mode mode = GET_MODE (operands[3]);
10631 rtx_code rc = GET_CODE (operands[4]);
10633 if (mode == CCFPmode || mode == CCFPEmode)
10634 rc = reverse_condition_maybe_unordered (rc);
10636 rc = reverse_condition (rc);
10638 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10640 [(set_attr "conds" "use")
10641 (set_attr "length" "4")
10642 (set_attr "arch" "t2,32")
10643 (set_attr "enabled_for_depr_it" "yes,no")
10644 (set_attr "type" "logic_shift_imm")]
10647 (define_insn "*arith_adjacentmem"
10648 [(set (match_operand:SI 0 "s_register_operand" "=r")
10649 (match_operator:SI 1 "shiftable_operator"
10650 [(match_operand:SI 2 "memory_operand" "m")
10651 (match_operand:SI 3 "memory_operand" "m")]))
10652 (clobber (match_scratch:SI 4 "=r"))]
10653 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10659 HOST_WIDE_INT val1 = 0, val2 = 0;
10661 if (REGNO (operands[0]) > REGNO (operands[4]))
10663 ldm[1] = operands[4];
10664 ldm[2] = operands[0];
10668 ldm[1] = operands[0];
10669 ldm[2] = operands[4];
10672 base_reg = XEXP (operands[2], 0);
10674 if (!REG_P (base_reg))
10676 val1 = INTVAL (XEXP (base_reg, 1));
10677 base_reg = XEXP (base_reg, 0);
10680 if (!REG_P (XEXP (operands[3], 0)))
10681 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10683 arith[0] = operands[0];
10684 arith[3] = operands[1];
10698 if (val1 !=0 && val2 != 0)
10702 if (val1 == 4 || val2 == 4)
10703 /* Other val must be 8, since we know they are adjacent and neither
10705 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10706 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10708 ldm[0] = ops[0] = operands[4];
10710 ops[2] = GEN_INT (val1);
10711 output_add_immediate (ops);
10713 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10715 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10719 /* Offset is out of range for a single add, so use two ldr. */
10722 ops[2] = GEN_INT (val1);
10723 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10725 ops[2] = GEN_INT (val2);
10726 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10729 else if (val1 != 0)
10732 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10734 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10739 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10741 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10743 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10746 [(set_attr "length" "12")
10747 (set_attr "predicable" "yes")
10748 (set_attr "type" "load_4")]
10751 ; This pattern is never tried by combine, so do it as a peephole
10754 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10755 (match_operand:SI 1 "arm_general_register_operand" ""))
10756 (set (reg:CC CC_REGNUM)
10757 (compare:CC (match_dup 1) (const_int 0)))]
10759 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10760 (set (match_dup 0) (match_dup 1))])]
10765 [(set (match_operand:SI 0 "s_register_operand" "")
10766 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10768 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10769 [(match_operand:SI 3 "s_register_operand" "")
10770 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10771 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10773 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10774 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10779 ;; This split can be used because CC_Z mode implies that the following
10780 ;; branch will be an equality, or an unsigned inequality, so the sign
10781 ;; extension is not needed.
10784 [(set (reg:CC_Z CC_REGNUM)
10786 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10788 (match_operand 1 "const_int_operand" "")))
10789 (clobber (match_scratch:SI 2 ""))]
10791 && ((UINTVAL (operands[1]))
10792 == ((UINTVAL (operands[1])) >> 24) << 24)"
10793 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10794 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10796 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10799 ;; ??? Check the patterns above for Thumb-2 usefulness
10801 (define_expand "prologue"
10802 [(clobber (const_int 0))]
10805 arm_expand_prologue ();
10807 thumb1_expand_prologue ();
10812 (define_expand "epilogue"
10813 [(clobber (const_int 0))]
10816 if (crtl->calls_eh_return)
10817 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10820 thumb1_expand_epilogue ();
10821 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10822 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10824 else if (HAVE_return)
10826 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10827 no need for explicit testing again. */
10828 emit_jump_insn (gen_return ());
10830 else if (TARGET_32BIT)
10832 arm_expand_epilogue (true);
10838 ;; Note - although unspec_volatile's USE all hard registers,
10839 ;; USEs are ignored after relaod has completed. Thus we need
10840 ;; to add an unspec of the link register to ensure that flow
10841 ;; does not think that it is unused by the sibcall branch that
10842 ;; will replace the standard function epilogue.
10843 (define_expand "sibcall_epilogue"
10844 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10845 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10848 arm_expand_epilogue (false);
10853 (define_expand "eh_epilogue"
10854 [(use (match_operand:SI 0 "register_operand" ""))
10855 (use (match_operand:SI 1 "register_operand" ""))
10856 (use (match_operand:SI 2 "register_operand" ""))]
10860 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10861 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10863 rtx ra = gen_rtx_REG (Pmode, 2);
10865 emit_move_insn (ra, operands[2]);
10868 /* This is a hack -- we may have crystalized the function type too
10870 cfun->machine->func_type = 0;
10874 ;; This split is only used during output to reduce the number of patterns
10875 ;; that need assembler instructions adding to them. We allowed the setting
10876 ;; of the conditions to be implicit during rtl generation so that
10877 ;; the conditional compare patterns would work. However this conflicts to
10878 ;; some extent with the conditional data operations, so we have to split them
10881 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10882 ;; conditional execution sufficient?
10885 [(set (match_operand:SI 0 "s_register_operand" "")
10886 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10887 [(match_operand 2 "" "") (match_operand 3 "" "")])
10889 (match_operand 4 "" "")))
10890 (clobber (reg:CC CC_REGNUM))]
10891 "TARGET_ARM && reload_completed"
10892 [(set (match_dup 5) (match_dup 6))
10893 (cond_exec (match_dup 7)
10894 (set (match_dup 0) (match_dup 4)))]
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[5] = gen_rtx_REG (mode, CC_REGNUM);
10902 operands[6] = 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[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10913 [(set (match_operand:SI 0 "s_register_operand" "")
10914 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10915 [(match_operand 2 "" "") (match_operand 3 "" "")])
10916 (match_operand 4 "" "")
10918 (clobber (reg:CC CC_REGNUM))]
10919 "TARGET_ARM && reload_completed"
10920 [(set (match_dup 5) (match_dup 6))
10921 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10922 (set (match_dup 0) (match_dup 4)))]
10925 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10926 operands[2], operands[3]);
10928 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10929 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10934 [(set (match_operand:SI 0 "s_register_operand" "")
10935 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10936 [(match_operand 2 "" "") (match_operand 3 "" "")])
10937 (match_operand 4 "" "")
10938 (match_operand 5 "" "")))
10939 (clobber (reg:CC CC_REGNUM))]
10940 "TARGET_ARM && reload_completed"
10941 [(set (match_dup 6) (match_dup 7))
10942 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10943 (set (match_dup 0) (match_dup 4)))
10944 (cond_exec (match_dup 8)
10945 (set (match_dup 0) (match_dup 5)))]
10948 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10949 operands[2], operands[3]);
10950 enum rtx_code rc = GET_CODE (operands[1]);
10952 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10953 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10954 if (mode == CCFPmode || mode == CCFPEmode)
10955 rc = reverse_condition_maybe_unordered (rc);
10957 rc = reverse_condition (rc);
10959 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10964 [(set (match_operand:SI 0 "s_register_operand" "")
10965 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10966 [(match_operand:SI 2 "s_register_operand" "")
10967 (match_operand:SI 3 "arm_add_operand" "")])
10968 (match_operand:SI 4 "arm_rhs_operand" "")
10970 (match_operand:SI 5 "s_register_operand" ""))))
10971 (clobber (reg:CC CC_REGNUM))]
10972 "TARGET_ARM && reload_completed"
10973 [(set (match_dup 6) (match_dup 7))
10974 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10975 (set (match_dup 0) (match_dup 4)))
10976 (cond_exec (match_dup 8)
10977 (set (match_dup 0) (not:SI (match_dup 5))))]
10980 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10981 operands[2], operands[3]);
10982 enum rtx_code rc = GET_CODE (operands[1]);
10984 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10985 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10986 if (mode == CCFPmode || mode == CCFPEmode)
10987 rc = reverse_condition_maybe_unordered (rc);
10989 rc = reverse_condition (rc);
10991 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10995 (define_insn "*cond_move_not"
10996 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10997 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10998 [(match_operand 3 "cc_register" "") (const_int 0)])
10999 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11001 (match_operand:SI 2 "s_register_operand" "r,r"))))]
11005 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11006 [(set_attr "conds" "use")
11007 (set_attr "type" "mvn_reg,multiple")
11008 (set_attr "length" "4,8")]
11011 ;; The next two patterns occur when an AND operation is followed by a
11012 ;; scc insn sequence
11014 (define_insn "*sign_extract_onebit"
11015 [(set (match_operand:SI 0 "s_register_operand" "=r")
11016 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11018 (match_operand:SI 2 "const_int_operand" "n")))
11019 (clobber (reg:CC CC_REGNUM))]
11022 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11023 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
11024 return \"mvnne\\t%0, #0\";
11026 [(set_attr "conds" "clob")
11027 (set_attr "length" "8")
11028 (set_attr "type" "multiple")]
11031 (define_insn "*not_signextract_onebit"
11032 [(set (match_operand:SI 0 "s_register_operand" "=r")
11034 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11036 (match_operand:SI 2 "const_int_operand" "n"))))
11037 (clobber (reg:CC CC_REGNUM))]
11040 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11041 output_asm_insn (\"tst\\t%1, %2\", operands);
11042 output_asm_insn (\"mvneq\\t%0, #0\", operands);
11043 return \"movne\\t%0, #0\";
11045 [(set_attr "conds" "clob")
11046 (set_attr "length" "12")
11047 (set_attr "type" "multiple")]
11049 ;; ??? The above patterns need auditing for Thumb-2
11051 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
11052 ;; expressions. For simplicity, the first register is also in the unspec
11054 ;; To avoid the usage of GNU extension, the length attribute is computed
11055 ;; in a C function arm_attr_length_push_multi.
11056 (define_insn "*push_multi"
11057 [(match_parallel 2 "multi_register_push"
11058 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11059 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11060 UNSPEC_PUSH_MULT))])]
11064 int num_saves = XVECLEN (operands[2], 0);
11066 /* For the StrongARM at least it is faster to
11067 use STR to store only a single register.
11068 In Thumb mode always use push, and the assembler will pick
11069 something appropriate. */
11070 if (num_saves == 1 && TARGET_ARM)
11071 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11078 strcpy (pattern, \"push%?\\t{%1\");
11080 strcpy (pattern, \"push\\t{%1\");
11082 for (i = 1; i < num_saves; i++)
11084 strcat (pattern, \", %|\");
11086 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11089 strcat (pattern, \"}\");
11090 output_asm_insn (pattern, operands);
11095 [(set_attr "type" "store_16")
11096 (set (attr "length")
11097 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11100 (define_insn "stack_tie"
11101 [(set (mem:BLK (scratch))
11102 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11103 (match_operand:SI 1 "s_register_operand" "rk")]
11107 [(set_attr "length" "0")
11108 (set_attr "type" "block")]
11111 ;; Pop (as used in epilogue RTL)
11113 (define_insn "*load_multiple_with_writeback"
11114 [(match_parallel 0 "load_multiple_operation"
11115 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11116 (plus:SI (match_dup 1)
11117 (match_operand:SI 2 "const_int_I_operand" "I")))
11118 (set (match_operand:SI 3 "s_register_operand" "=rk")
11119 (mem:SI (match_dup 1)))
11121 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11124 arm_output_multireg_pop (operands, /*return_pc=*/false,
11125 /*cond=*/const_true_rtx,
11131 [(set_attr "type" "load_16")
11132 (set_attr "predicable" "yes")
11133 (set (attr "length")
11134 (symbol_ref "arm_attr_length_pop_multi (operands,
11135 /*return_pc=*/false,
11136 /*write_back_p=*/true)"))]
11139 ;; Pop with return (as used in epilogue RTL)
11141 ;; This instruction is generated when the registers are popped at the end of
11142 ;; epilogue. Here, instead of popping the value into LR and then generating
11143 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11145 (define_insn "*pop_multiple_with_writeback_and_return"
11146 [(match_parallel 0 "pop_multiple_return"
11148 (set (match_operand:SI 1 "s_register_operand" "+rk")
11149 (plus:SI (match_dup 1)
11150 (match_operand:SI 2 "const_int_I_operand" "I")))
11151 (set (match_operand:SI 3 "s_register_operand" "=rk")
11152 (mem:SI (match_dup 1)))
11154 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11157 arm_output_multireg_pop (operands, /*return_pc=*/true,
11158 /*cond=*/const_true_rtx,
11164 [(set_attr "type" "load_16")
11165 (set_attr "predicable" "yes")
11166 (set (attr "length")
11167 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11168 /*write_back_p=*/true)"))]
11171 (define_insn "*pop_multiple_with_return"
11172 [(match_parallel 0 "pop_multiple_return"
11174 (set (match_operand:SI 2 "s_register_operand" "=rk")
11175 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11177 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11180 arm_output_multireg_pop (operands, /*return_pc=*/true,
11181 /*cond=*/const_true_rtx,
11187 [(set_attr "type" "load_16")
11188 (set_attr "predicable" "yes")
11189 (set (attr "length")
11190 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11191 /*write_back_p=*/false)"))]
11194 ;; Load into PC and return
11195 (define_insn "*ldr_with_return"
11197 (set (reg:SI PC_REGNUM)
11198 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11199 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11200 "ldr%?\t%|pc, [%0], #4"
11201 [(set_attr "type" "load_4")
11202 (set_attr "predicable" "yes")]
11204 ;; Pop for floating point registers (as used in epilogue RTL)
11205 (define_insn "*vfp_pop_multiple_with_writeback"
11206 [(match_parallel 0 "pop_multiple_fp"
11207 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11208 (plus:SI (match_dup 1)
11209 (match_operand:SI 2 "const_int_I_operand" "I")))
11210 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11211 (mem:DF (match_dup 1)))])]
11212 "TARGET_32BIT && TARGET_HARD_FLOAT"
11215 int num_regs = XVECLEN (operands[0], 0);
11218 strcpy (pattern, \"vldm\\t\");
11219 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11220 strcat (pattern, \"!, {\");
11221 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11222 strcat (pattern, \"%P0\");
11223 if ((num_regs - 1) > 1)
11225 strcat (pattern, \"-%P1\");
11226 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11229 strcat (pattern, \"}\");
11230 output_asm_insn (pattern, op_list);
11234 [(set_attr "type" "load_16")
11235 (set_attr "conds" "unconditional")
11236 (set_attr "predicable" "no")]
11239 ;; Special patterns for dealing with the constant pool
11241 (define_insn "align_4"
11242 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11245 assemble_align (32);
11248 [(set_attr "type" "no_insn")]
11251 (define_insn "align_8"
11252 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11255 assemble_align (64);
11258 [(set_attr "type" "no_insn")]
11261 (define_insn "consttable_end"
11262 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11265 making_const_table = FALSE;
11268 [(set_attr "type" "no_insn")]
11271 (define_insn "consttable_1"
11272 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11275 making_const_table = TRUE;
11276 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11277 assemble_zeros (3);
11280 [(set_attr "length" "4")
11281 (set_attr "type" "no_insn")]
11284 (define_insn "consttable_2"
11285 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11289 rtx x = operands[0];
11290 making_const_table = TRUE;
11291 switch (GET_MODE_CLASS (GET_MODE (x)))
11294 arm_emit_fp16_const (x);
11297 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11298 assemble_zeros (2);
11303 [(set_attr "length" "4")
11304 (set_attr "type" "no_insn")]
11307 (define_insn "consttable_4"
11308 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11312 rtx x = operands[0];
11313 making_const_table = TRUE;
11314 scalar_float_mode float_mode;
11315 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11316 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11319 /* XXX: Sometimes gcc does something really dumb and ends up with
11320 a HIGH in a constant pool entry, usually because it's trying to
11321 load into a VFP register. We know this will always be used in
11322 combination with a LO_SUM which ignores the high bits, so just
11323 strip off the HIGH. */
11324 if (GET_CODE (x) == HIGH)
11326 assemble_integer (x, 4, BITS_PER_WORD, 1);
11327 mark_symbol_refs_as_used (x);
11331 [(set_attr "length" "4")
11332 (set_attr "type" "no_insn")]
11335 (define_insn "consttable_8"
11336 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11340 making_const_table = TRUE;
11341 scalar_float_mode float_mode;
11342 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11343 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11344 float_mode, BITS_PER_WORD);
11346 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11349 [(set_attr "length" "8")
11350 (set_attr "type" "no_insn")]
11353 (define_insn "consttable_16"
11354 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11358 making_const_table = TRUE;
11359 scalar_float_mode float_mode;
11360 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11361 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11362 float_mode, BITS_PER_WORD);
11364 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11367 [(set_attr "length" "16")
11368 (set_attr "type" "no_insn")]
11371 ;; V5 Instructions,
11373 (define_insn "clzsi2"
11374 [(set (match_operand:SI 0 "s_register_operand" "=r")
11375 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11376 "TARGET_32BIT && arm_arch5"
11378 [(set_attr "predicable" "yes")
11379 (set_attr "predicable_short_it" "no")
11380 (set_attr "type" "clz")])
11382 (define_insn "rbitsi2"
11383 [(set (match_operand:SI 0 "s_register_operand" "=r")
11384 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11385 "TARGET_32BIT && arm_arch_thumb2"
11387 [(set_attr "predicable" "yes")
11388 (set_attr "predicable_short_it" "no")
11389 (set_attr "type" "clz")])
11391 ;; Keep this as a CTZ expression until after reload and then split
11392 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11393 ;; to fold with any other expression.
11395 (define_insn_and_split "ctzsi2"
11396 [(set (match_operand:SI 0 "s_register_operand" "=r")
11397 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11398 "TARGET_32BIT && arm_arch_thumb2"
11400 "&& reload_completed"
11403 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11404 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11408 ;; V5E instructions.
11410 (define_insn "prefetch"
11411 [(prefetch (match_operand:SI 0 "address_operand" "p")
11412 (match_operand:SI 1 "" "")
11413 (match_operand:SI 2 "" ""))]
11414 "TARGET_32BIT && arm_arch5e"
11416 [(set_attr "type" "load_4")]
11419 ;; General predication pattern
11422 [(match_operator 0 "arm_comparison_operator"
11423 [(match_operand 1 "cc_register" "")
11426 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11428 [(set_attr "predicated" "yes")]
11431 (define_insn "force_register_use"
11432 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11435 [(set_attr "length" "0")
11436 (set_attr "type" "no_insn")]
11440 ;; Patterns for exception handling
11442 (define_expand "eh_return"
11443 [(use (match_operand 0 "general_operand" ""))]
11448 emit_insn (gen_arm_eh_return (operands[0]));
11450 emit_insn (gen_thumb_eh_return (operands[0]));
11455 ;; We can't expand this before we know where the link register is stored.
11456 (define_insn_and_split "arm_eh_return"
11457 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11459 (clobber (match_scratch:SI 1 "=&r"))]
11462 "&& reload_completed"
11466 arm_set_return_address (operands[0], operands[1]);
11474 (define_insn "load_tp_hard"
11475 [(set (match_operand:SI 0 "register_operand" "=r")
11476 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11478 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11479 [(set_attr "predicable" "yes")
11480 (set_attr "type" "mrs")]
11483 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11484 (define_insn "load_tp_soft"
11485 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11486 (clobber (reg:SI LR_REGNUM))
11487 (clobber (reg:SI IP_REGNUM))
11488 (clobber (reg:CC CC_REGNUM))]
11490 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11491 [(set_attr "conds" "clob")
11492 (set_attr "type" "branch")]
11495 ;; tls descriptor call
11496 (define_insn "tlscall"
11497 [(set (reg:SI R0_REGNUM)
11498 (unspec:SI [(reg:SI R0_REGNUM)
11499 (match_operand:SI 0 "" "X")
11500 (match_operand 1 "" "")] UNSPEC_TLS))
11501 (clobber (reg:SI R1_REGNUM))
11502 (clobber (reg:SI LR_REGNUM))
11503 (clobber (reg:SI CC_REGNUM))]
11506 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11507 INTVAL (operands[1]));
11508 return "bl\\t%c0(tlscall)";
11510 [(set_attr "conds" "clob")
11511 (set_attr "length" "4")
11512 (set_attr "type" "branch")]
11515 ;; For thread pointer builtin
11516 (define_expand "get_thread_pointersi"
11517 [(match_operand:SI 0 "s_register_operand" "=r")]
11521 arm_load_tp (operands[0]);
11527 ;; We only care about the lower 16 bits of the constant
11528 ;; being inserted into the upper 16 bits of the register.
11529 (define_insn "*arm_movtas_ze"
11530 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11533 (match_operand:SI 1 "const_int_operand" ""))]
11538 [(set_attr "arch" "32,v8mb")
11539 (set_attr "predicable" "yes")
11540 (set_attr "predicable_short_it" "no")
11541 (set_attr "length" "4")
11542 (set_attr "type" "alu_sreg")]
11545 (define_insn "*arm_rev"
11546 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11547 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11553 [(set_attr "arch" "t1,t2,32")
11554 (set_attr "length" "2,2,4")
11555 (set_attr "predicable" "no,yes,yes")
11556 (set_attr "predicable_short_it" "no")
11557 (set_attr "type" "rev")]
11560 (define_expand "arm_legacy_rev"
11561 [(set (match_operand:SI 2 "s_register_operand" "")
11562 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11566 (lshiftrt:SI (match_dup 2)
11568 (set (match_operand:SI 3 "s_register_operand" "")
11569 (rotatert:SI (match_dup 1)
11572 (and:SI (match_dup 2)
11573 (const_int -65281)))
11574 (set (match_operand:SI 0 "s_register_operand" "")
11575 (xor:SI (match_dup 3)
11581 ;; Reuse temporaries to keep register pressure down.
11582 (define_expand "thumb_legacy_rev"
11583 [(set (match_operand:SI 2 "s_register_operand" "")
11584 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11586 (set (match_operand:SI 3 "s_register_operand" "")
11587 (lshiftrt:SI (match_dup 1)
11590 (ior:SI (match_dup 3)
11592 (set (match_operand:SI 4 "s_register_operand" "")
11594 (set (match_operand:SI 5 "s_register_operand" "")
11595 (rotatert:SI (match_dup 1)
11598 (ashift:SI (match_dup 5)
11601 (lshiftrt:SI (match_dup 5)
11604 (ior:SI (match_dup 5)
11607 (rotatert:SI (match_dup 5)
11609 (set (match_operand:SI 0 "s_register_operand" "")
11610 (ior:SI (match_dup 5)
11616 ;; ARM-specific expansion of signed mod by power of 2
11617 ;; using conditional negate.
11618 ;; For r0 % n where n is a power of 2 produce:
11620 ;; and r0, r0, #(n - 1)
11621 ;; and r1, r1, #(n - 1)
11622 ;; rsbpl r0, r1, #0
11624 (define_expand "modsi3"
11625 [(match_operand:SI 0 "register_operand" "")
11626 (match_operand:SI 1 "register_operand" "")
11627 (match_operand:SI 2 "const_int_operand" "")]
11630 HOST_WIDE_INT val = INTVAL (operands[2]);
11633 || exact_log2 (val) <= 0)
11636 rtx mask = GEN_INT (val - 1);
11638 /* In the special case of x0 % 2 we can do the even shorter:
11641 rsblt r0, r0, #0. */
11645 rtx cc_reg = arm_gen_compare_reg (LT,
11646 operands[1], const0_rtx, NULL_RTX);
11647 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11648 rtx masked = gen_reg_rtx (SImode);
11650 emit_insn (gen_andsi3 (masked, operands[1], mask));
11651 emit_move_insn (operands[0],
11652 gen_rtx_IF_THEN_ELSE (SImode, cond,
11653 gen_rtx_NEG (SImode,
11659 rtx neg_op = gen_reg_rtx (SImode);
11660 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11663 /* Extract the condition register and mode. */
11664 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11665 rtx cc_reg = SET_DEST (cmp);
11666 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11668 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11670 rtx masked_neg = gen_reg_rtx (SImode);
11671 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11673 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11674 during expand does not always work. Do an IF_THEN_ELSE instead. */
11675 emit_move_insn (operands[0],
11676 gen_rtx_IF_THEN_ELSE (SImode, cond,
11677 gen_rtx_NEG (SImode, masked_neg),
11685 (define_expand "bswapsi2"
11686 [(set (match_operand:SI 0 "s_register_operand" "=r")
11687 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11688 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11692 rtx op2 = gen_reg_rtx (SImode);
11693 rtx op3 = gen_reg_rtx (SImode);
11697 rtx op4 = gen_reg_rtx (SImode);
11698 rtx op5 = gen_reg_rtx (SImode);
11700 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11701 op2, op3, op4, op5));
11705 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11714 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11715 ;; and unsigned variants, respectively. For rev16, expose
11716 ;; byte-swapping in the lower 16 bits only.
11717 (define_insn "*arm_revsh"
11718 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11719 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11725 [(set_attr "arch" "t1,t2,32")
11726 (set_attr "length" "2,2,4")
11727 (set_attr "type" "rev")]
11730 (define_insn "*arm_rev16"
11731 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11732 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11738 [(set_attr "arch" "t1,t2,32")
11739 (set_attr "length" "2,2,4")
11740 (set_attr "type" "rev")]
11743 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11744 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11745 ;; each valid permutation.
11747 (define_insn "arm_rev16si2"
11748 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11749 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11751 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11752 (and:SI (lshiftrt:SI (match_dup 1)
11754 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11756 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11757 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11759 [(set_attr "arch" "t1,t2,32")
11760 (set_attr "length" "2,2,4")
11761 (set_attr "type" "rev")]
11764 (define_insn "arm_rev16si2_alt"
11765 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11766 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11768 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11769 (and:SI (ashift:SI (match_dup 1)
11771 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11773 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11774 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11776 [(set_attr "arch" "t1,t2,32")
11777 (set_attr "length" "2,2,4")
11778 (set_attr "type" "rev")]
11781 (define_expand "bswaphi2"
11782 [(set (match_operand:HI 0 "s_register_operand" "=r")
11783 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11788 ;; Patterns for LDRD/STRD in Thumb2 mode
11790 (define_insn "*thumb2_ldrd"
11791 [(set (match_operand:SI 0 "s_register_operand" "=r")
11792 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11793 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11794 (set (match_operand:SI 3 "s_register_operand" "=r")
11795 (mem:SI (plus:SI (match_dup 1)
11796 (match_operand:SI 4 "const_int_operand" ""))))]
11797 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11798 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11799 && (operands_ok_ldrd_strd (operands[0], operands[3],
11800 operands[1], INTVAL (operands[2]),
11802 "ldrd%?\t%0, %3, [%1, %2]"
11803 [(set_attr "type" "load_8")
11804 (set_attr "predicable" "yes")
11805 (set_attr "predicable_short_it" "no")])
11807 (define_insn "*thumb2_ldrd_base"
11808 [(set (match_operand:SI 0 "s_register_operand" "=r")
11809 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11810 (set (match_operand:SI 2 "s_register_operand" "=r")
11811 (mem:SI (plus:SI (match_dup 1)
11813 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11814 && (operands_ok_ldrd_strd (operands[0], operands[2],
11815 operands[1], 0, false, true))"
11816 "ldrd%?\t%0, %2, [%1]"
11817 [(set_attr "type" "load_8")
11818 (set_attr "predicable" "yes")
11819 (set_attr "predicable_short_it" "no")])
11821 (define_insn "*thumb2_ldrd_base_neg"
11822 [(set (match_operand:SI 0 "s_register_operand" "=r")
11823 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11825 (set (match_operand:SI 2 "s_register_operand" "=r")
11826 (mem:SI (match_dup 1)))]
11827 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11828 && (operands_ok_ldrd_strd (operands[0], operands[2],
11829 operands[1], -4, false, true))"
11830 "ldrd%?\t%0, %2, [%1, #-4]"
11831 [(set_attr "type" "load_8")
11832 (set_attr "predicable" "yes")
11833 (set_attr "predicable_short_it" "no")])
11835 (define_insn "*thumb2_strd"
11836 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11837 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11838 (match_operand:SI 2 "s_register_operand" "r"))
11839 (set (mem:SI (plus:SI (match_dup 0)
11840 (match_operand:SI 3 "const_int_operand" "")))
11841 (match_operand:SI 4 "s_register_operand" "r"))]
11842 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11843 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11844 && (operands_ok_ldrd_strd (operands[2], operands[4],
11845 operands[0], INTVAL (operands[1]),
11847 "strd%?\t%2, %4, [%0, %1]"
11848 [(set_attr "type" "store_8")
11849 (set_attr "predicable" "yes")
11850 (set_attr "predicable_short_it" "no")])
11852 (define_insn "*thumb2_strd_base"
11853 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11854 (match_operand:SI 1 "s_register_operand" "r"))
11855 (set (mem:SI (plus:SI (match_dup 0)
11857 (match_operand:SI 2 "s_register_operand" "r"))]
11858 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11859 && (operands_ok_ldrd_strd (operands[1], operands[2],
11860 operands[0], 0, false, false))"
11861 "strd%?\t%1, %2, [%0]"
11862 [(set_attr "type" "store_8")
11863 (set_attr "predicable" "yes")
11864 (set_attr "predicable_short_it" "no")])
11866 (define_insn "*thumb2_strd_base_neg"
11867 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11869 (match_operand:SI 1 "s_register_operand" "r"))
11870 (set (mem:SI (match_dup 0))
11871 (match_operand:SI 2 "s_register_operand" "r"))]
11872 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11873 && (operands_ok_ldrd_strd (operands[1], operands[2],
11874 operands[0], -4, false, false))"
11875 "strd%?\t%1, %2, [%0, #-4]"
11876 [(set_attr "type" "store_8")
11877 (set_attr "predicable" "yes")
11878 (set_attr "predicable_short_it" "no")])
11880 ;; ARMv8 CRC32 instructions.
11881 (define_insn "<crc_variant>"
11882 [(set (match_operand:SI 0 "s_register_operand" "=r")
11883 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11884 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11887 "<crc_variant>\\t%0, %1, %2"
11888 [(set_attr "type" "crc")
11889 (set_attr "conds" "unconditional")]
11892 ;; Load the load/store double peephole optimizations.
11893 (include "ldrdstrd.md")
11895 ;; Load the load/store multiple patterns
11896 (include "ldmstm.md")
11898 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11899 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11900 ;; The operands are validated through the load_multiple_operation
11901 ;; match_parallel predicate rather than through constraints so enable it only
11903 (define_insn "*load_multiple"
11904 [(match_parallel 0 "load_multiple_operation"
11905 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11906 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11908 "TARGET_32BIT && reload_completed"
11911 arm_output_multireg_pop (operands, /*return_pc=*/false,
11912 /*cond=*/const_true_rtx,
11918 [(set_attr "predicable" "yes")]
11921 (define_expand "copysignsf3"
11922 [(match_operand:SF 0 "register_operand")
11923 (match_operand:SF 1 "register_operand")
11924 (match_operand:SF 2 "register_operand")]
11925 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11927 emit_move_insn (operands[0], operands[2]);
11928 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11929 GEN_INT (31), GEN_INT (0),
11930 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11935 (define_expand "copysigndf3"
11936 [(match_operand:DF 0 "register_operand")
11937 (match_operand:DF 1 "register_operand")
11938 (match_operand:DF 2 "register_operand")]
11939 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11941 rtx op0_low = gen_lowpart (SImode, operands[0]);
11942 rtx op0_high = gen_highpart (SImode, operands[0]);
11943 rtx op1_low = gen_lowpart (SImode, operands[1]);
11944 rtx op1_high = gen_highpart (SImode, operands[1]);
11945 rtx op2_high = gen_highpart (SImode, operands[2]);
11947 rtx scratch1 = gen_reg_rtx (SImode);
11948 rtx scratch2 = gen_reg_rtx (SImode);
11949 emit_move_insn (scratch1, op2_high);
11950 emit_move_insn (scratch2, op1_high);
11952 emit_insn(gen_rtx_SET(scratch1,
11953 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11954 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11955 emit_move_insn (op0_low, op1_low);
11956 emit_move_insn (op0_high, scratch2);
11962 ;; movmisalign patterns for HImode and SImode.
11963 (define_expand "movmisalign<mode>"
11964 [(match_operand:HSI 0 "general_operand")
11965 (match_operand:HSI 1 "general_operand")]
11968 /* This pattern is not permitted to fail during expansion: if both arguments
11969 are non-registers (e.g. memory := constant), force operand 1 into a
11971 rtx (* gen_unaligned_load)(rtx, rtx);
11972 rtx tmp_dest = operands[0];
11973 if (!s_register_operand (operands[0], <MODE>mode)
11974 && !s_register_operand (operands[1], <MODE>mode))
11975 operands[1] = force_reg (<MODE>mode, operands[1]);
11977 if (<MODE>mode == HImode)
11979 gen_unaligned_load = gen_unaligned_loadhiu;
11980 tmp_dest = gen_reg_rtx (SImode);
11983 gen_unaligned_load = gen_unaligned_loadsi;
11985 if (MEM_P (operands[1]))
11987 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11988 if (<MODE>mode == HImode)
11989 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11992 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11997 (define_insn "<cdp>"
11998 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11999 (match_operand:SI 1 "immediate_operand" "n")
12000 (match_operand:SI 2 "immediate_operand" "n")
12001 (match_operand:SI 3 "immediate_operand" "n")
12002 (match_operand:SI 4 "immediate_operand" "n")
12003 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
12004 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
12006 arm_const_bounds (operands[0], 0, 16);
12007 arm_const_bounds (operands[1], 0, 16);
12008 arm_const_bounds (operands[2], 0, (1 << 5));
12009 arm_const_bounds (operands[3], 0, (1 << 5));
12010 arm_const_bounds (operands[4], 0, (1 << 5));
12011 arm_const_bounds (operands[5], 0, 8);
12012 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
12014 [(set_attr "length" "4")
12015 (set_attr "type" "coproc")])
12017 (define_insn "*ldc"
12018 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12019 (match_operand:SI 1 "immediate_operand" "n")
12020 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
12021 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
12023 arm_const_bounds (operands[0], 0, 16);
12024 arm_const_bounds (operands[1], 0, (1 << 5));
12025 return "<ldc>\\tp%c0, CR%c1, %2";
12027 [(set_attr "length" "4")
12028 (set_attr "type" "coproc")])
12030 (define_insn "*stc"
12031 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12032 (match_operand:SI 1 "immediate_operand" "n")
12033 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
12034 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
12036 arm_const_bounds (operands[0], 0, 16);
12037 arm_const_bounds (operands[1], 0, (1 << 5));
12038 return "<stc>\\tp%c0, CR%c1, %2";
12040 [(set_attr "length" "4")
12041 (set_attr "type" "coproc")])
12043 (define_expand "<ldc>"
12044 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12045 (match_operand:SI 1 "immediate_operand")
12046 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
12047 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
12049 (define_expand "<stc>"
12050 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12051 (match_operand:SI 1 "immediate_operand")
12052 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12053 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12055 (define_insn "<mcr>"
12056 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12057 (match_operand:SI 1 "immediate_operand" "n")
12058 (match_operand:SI 2 "s_register_operand" "r")
12059 (match_operand:SI 3 "immediate_operand" "n")
12060 (match_operand:SI 4 "immediate_operand" "n")
12061 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12062 (use (match_dup 2))]
12063 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12065 arm_const_bounds (operands[0], 0, 16);
12066 arm_const_bounds (operands[1], 0, 8);
12067 arm_const_bounds (operands[3], 0, (1 << 5));
12068 arm_const_bounds (operands[4], 0, (1 << 5));
12069 arm_const_bounds (operands[5], 0, 8);
12070 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12072 [(set_attr "length" "4")
12073 (set_attr "type" "coproc")])
12075 (define_insn "<mrc>"
12076 [(set (match_operand:SI 0 "s_register_operand" "=r")
12077 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12078 (match_operand:SI 2 "immediate_operand" "n")
12079 (match_operand:SI 3 "immediate_operand" "n")
12080 (match_operand:SI 4 "immediate_operand" "n")
12081 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12082 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12084 arm_const_bounds (operands[1], 0, 16);
12085 arm_const_bounds (operands[2], 0, 8);
12086 arm_const_bounds (operands[3], 0, (1 << 5));
12087 arm_const_bounds (operands[4], 0, (1 << 5));
12088 arm_const_bounds (operands[5], 0, 8);
12089 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12091 [(set_attr "length" "4")
12092 (set_attr "type" "coproc")])
12094 (define_insn "<mcrr>"
12095 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12096 (match_operand:SI 1 "immediate_operand" "n")
12097 (match_operand:DI 2 "s_register_operand" "r")
12098 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12099 (use (match_dup 2))]
12100 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12102 arm_const_bounds (operands[0], 0, 16);
12103 arm_const_bounds (operands[1], 0, 8);
12104 arm_const_bounds (operands[3], 0, (1 << 5));
12105 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12107 [(set_attr "length" "4")
12108 (set_attr "type" "coproc")])
12110 (define_insn "<mrrc>"
12111 [(set (match_operand:DI 0 "s_register_operand" "=r")
12112 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12113 (match_operand:SI 2 "immediate_operand" "n")
12114 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12115 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12117 arm_const_bounds (operands[1], 0, 16);
12118 arm_const_bounds (operands[2], 0, 8);
12119 arm_const_bounds (operands[3], 0, (1 << 5));
12120 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12122 [(set_attr "length" "4")
12123 (set_attr "type" "coproc")])
12125 ;; Vector bits common to IWMMXT and Neon
12126 (include "vec-common.md")
12127 ;; Load the Intel Wireless Multimedia Extension patterns
12128 (include "iwmmxt.md")
12129 ;; Load the VFP co-processor patterns
12131 ;; Thumb-1 patterns
12132 (include "thumb1.md")
12133 ;; Thumb-2 patterns
12134 (include "thumb2.md")
12136 (include "neon.md")
12138 (include "crypto.md")
12139 ;; Synchronization Primitives
12140 (include "sync.md")
12141 ;; Fixed-point patterns
12142 (include "arm-fixed.md")