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 /* Ideally we should use iwmmxt here if we could know that operands[1]
4063 ends up already living in an iwmmxt register. Otherwise it's
4064 cheaper to have the alternate code being generated than moving
4065 values to iwmmxt regs and back. */
4067 /* Expand operation using core-registers.
4068 'FAIL' would achieve the same thing, but this is a bit smarter. */
4069 scratch1 = gen_reg_rtx (SImode);
4070 scratch2 = gen_reg_rtx (SImode);
4071 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4072 operands[2], scratch1, scratch2);
4078 (define_expand "ashlsi3"
4079 [(set (match_operand:SI 0 "s_register_operand" "")
4080 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4081 (match_operand:SI 2 "arm_rhs_operand" "")))]
4084 if (CONST_INT_P (operands[2])
4085 && (UINTVAL (operands[2])) > 31)
4087 emit_insn (gen_movsi (operands[0], const0_rtx));
4093 (define_expand "ashrdi3"
4094 [(set (match_operand:DI 0 "s_register_operand" "")
4095 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4096 (match_operand:SI 2 "reg_or_int_operand" "")))]
4101 /* Delay the decision whether to use NEON or core-regs until
4102 register allocation. */
4103 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4107 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4108 ; /* No special preparation statements; expand pattern as above. */
4111 rtx scratch1, scratch2;
4113 /* Ideally we should use iwmmxt here if we could know that operands[1]
4114 ends up already living in an iwmmxt register. Otherwise it's
4115 cheaper to have the alternate code being generated than moving
4116 values to iwmmxt regs and back. */
4118 /* Expand operation using core-registers.
4119 'FAIL' would achieve the same thing, but this is a bit smarter. */
4120 scratch1 = gen_reg_rtx (SImode);
4121 scratch2 = gen_reg_rtx (SImode);
4122 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4123 operands[2], scratch1, scratch2);
4129 (define_expand "ashrsi3"
4130 [(set (match_operand:SI 0 "s_register_operand" "")
4131 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4132 (match_operand:SI 2 "arm_rhs_operand" "")))]
4135 if (CONST_INT_P (operands[2])
4136 && UINTVAL (operands[2]) > 31)
4137 operands[2] = GEN_INT (31);
4141 (define_expand "lshrdi3"
4142 [(set (match_operand:DI 0 "s_register_operand" "")
4143 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4144 (match_operand:SI 2 "reg_or_int_operand" "")))]
4149 /* Delay the decision whether to use NEON or core-regs until
4150 register allocation. */
4151 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4155 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4156 ; /* No special preparation statements; expand pattern as above. */
4159 rtx scratch1, scratch2;
4161 /* Ideally we should use iwmmxt here if we could know that operands[1]
4162 ends up already living in an iwmmxt register. Otherwise it's
4163 cheaper to have the alternate code being generated than moving
4164 values to iwmmxt regs and back. */
4166 /* Expand operation using core-registers.
4167 'FAIL' would achieve the same thing, but this is a bit smarter. */
4168 scratch1 = gen_reg_rtx (SImode);
4169 scratch2 = gen_reg_rtx (SImode);
4170 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4171 operands[2], scratch1, scratch2);
4177 (define_expand "lshrsi3"
4178 [(set (match_operand:SI 0 "s_register_operand" "")
4179 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4180 (match_operand:SI 2 "arm_rhs_operand" "")))]
4183 if (CONST_INT_P (operands[2])
4184 && (UINTVAL (operands[2])) > 31)
4186 emit_insn (gen_movsi (operands[0], const0_rtx));
4192 (define_expand "rotlsi3"
4193 [(set (match_operand:SI 0 "s_register_operand" "")
4194 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4195 (match_operand:SI 2 "reg_or_int_operand" "")))]
4198 if (CONST_INT_P (operands[2]))
4199 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4202 rtx reg = gen_reg_rtx (SImode);
4203 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4209 (define_expand "rotrsi3"
4210 [(set (match_operand:SI 0 "s_register_operand" "")
4211 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4212 (match_operand:SI 2 "arm_rhs_operand" "")))]
4217 if (CONST_INT_P (operands[2])
4218 && UINTVAL (operands[2]) > 31)
4219 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4221 else /* TARGET_THUMB1 */
4223 if (CONST_INT_P (operands [2]))
4224 operands [2] = force_reg (SImode, operands[2]);
4229 (define_insn "*arm_shiftsi3"
4230 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4231 (match_operator:SI 3 "shift_operator"
4232 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4233 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4235 "* return arm_output_shift(operands, 0);"
4236 [(set_attr "predicable" "yes")
4237 (set_attr "arch" "t2,t2,*,*")
4238 (set_attr "predicable_short_it" "yes,yes,no,no")
4239 (set_attr "length" "4")
4240 (set_attr "shift" "1")
4241 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4244 (define_insn "*shiftsi3_compare0"
4245 [(set (reg:CC_NOOV CC_REGNUM)
4246 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4247 [(match_operand:SI 1 "s_register_operand" "r,r")
4248 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4250 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4251 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4253 "* return arm_output_shift(operands, 1);"
4254 [(set_attr "conds" "set")
4255 (set_attr "shift" "1")
4256 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4259 (define_insn "*shiftsi3_compare0_scratch"
4260 [(set (reg:CC_NOOV CC_REGNUM)
4261 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4262 [(match_operand:SI 1 "s_register_operand" "r,r")
4263 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4265 (clobber (match_scratch:SI 0 "=r,r"))]
4267 "* return arm_output_shift(operands, 1);"
4268 [(set_attr "conds" "set")
4269 (set_attr "shift" "1")
4270 (set_attr "type" "shift_imm,shift_reg")]
4273 (define_insn "*not_shiftsi"
4274 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4275 (not:SI (match_operator:SI 3 "shift_operator"
4276 [(match_operand:SI 1 "s_register_operand" "r,r")
4277 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4280 [(set_attr "predicable" "yes")
4281 (set_attr "predicable_short_it" "no")
4282 (set_attr "shift" "1")
4283 (set_attr "arch" "32,a")
4284 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4286 (define_insn "*not_shiftsi_compare0"
4287 [(set (reg:CC_NOOV CC_REGNUM)
4289 (not:SI (match_operator:SI 3 "shift_operator"
4290 [(match_operand:SI 1 "s_register_operand" "r,r")
4291 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4293 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4294 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4296 "mvns%?\\t%0, %1%S3"
4297 [(set_attr "conds" "set")
4298 (set_attr "shift" "1")
4299 (set_attr "arch" "32,a")
4300 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4302 (define_insn "*not_shiftsi_compare0_scratch"
4303 [(set (reg:CC_NOOV CC_REGNUM)
4305 (not:SI (match_operator:SI 3 "shift_operator"
4306 [(match_operand:SI 1 "s_register_operand" "r,r")
4307 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4309 (clobber (match_scratch:SI 0 "=r,r"))]
4311 "mvns%?\\t%0, %1%S3"
4312 [(set_attr "conds" "set")
4313 (set_attr "shift" "1")
4314 (set_attr "arch" "32,a")
4315 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4317 ;; We don't really have extzv, but defining this using shifts helps
4318 ;; to reduce register pressure later on.
4320 (define_expand "extzv"
4321 [(set (match_operand 0 "s_register_operand" "")
4322 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4323 (match_operand 2 "const_int_operand" "")
4324 (match_operand 3 "const_int_operand" "")))]
4325 "TARGET_THUMB1 || arm_arch_thumb2"
4328 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4329 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4331 if (arm_arch_thumb2)
4333 HOST_WIDE_INT width = INTVAL (operands[2]);
4334 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4336 if (unaligned_access && MEM_P (operands[1])
4337 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4341 if (BYTES_BIG_ENDIAN)
4342 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4347 base_addr = adjust_address (operands[1], SImode,
4348 bitpos / BITS_PER_UNIT);
4349 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4353 rtx dest = operands[0];
4354 rtx tmp = gen_reg_rtx (SImode);
4356 /* We may get a paradoxical subreg here. Strip it off. */
4357 if (GET_CODE (dest) == SUBREG
4358 && GET_MODE (dest) == SImode
4359 && GET_MODE (SUBREG_REG (dest)) == HImode)
4360 dest = SUBREG_REG (dest);
4362 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4365 base_addr = adjust_address (operands[1], HImode,
4366 bitpos / BITS_PER_UNIT);
4367 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4368 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4372 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4374 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4382 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4385 operands[3] = GEN_INT (rshift);
4389 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4393 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4394 operands[3], gen_reg_rtx (SImode)));
4399 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4401 (define_expand "extzv_t1"
4402 [(set (match_operand:SI 4 "s_register_operand" "")
4403 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4404 (match_operand:SI 2 "const_int_operand" "")))
4405 (set (match_operand:SI 0 "s_register_operand" "")
4406 (lshiftrt:SI (match_dup 4)
4407 (match_operand:SI 3 "const_int_operand" "")))]
4411 (define_expand "extv"
4412 [(set (match_operand 0 "s_register_operand" "")
4413 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4414 (match_operand 2 "const_int_operand" "")
4415 (match_operand 3 "const_int_operand" "")))]
4418 HOST_WIDE_INT width = INTVAL (operands[2]);
4419 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4421 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4422 && (bitpos % BITS_PER_UNIT) == 0)
4426 if (BYTES_BIG_ENDIAN)
4427 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4431 base_addr = adjust_address (operands[1], SImode,
4432 bitpos / BITS_PER_UNIT);
4433 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4437 rtx dest = operands[0];
4438 rtx tmp = gen_reg_rtx (SImode);
4440 /* We may get a paradoxical subreg here. Strip it off. */
4441 if (GET_CODE (dest) == SUBREG
4442 && GET_MODE (dest) == SImode
4443 && GET_MODE (SUBREG_REG (dest)) == HImode)
4444 dest = SUBREG_REG (dest);
4446 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4449 base_addr = adjust_address (operands[1], HImode,
4450 bitpos / BITS_PER_UNIT);
4451 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4452 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4457 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4459 else if (GET_MODE (operands[0]) == SImode
4460 && GET_MODE (operands[1]) == SImode)
4462 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4470 ; Helper to expand register forms of extv with the proper modes.
4472 (define_expand "extv_regsi"
4473 [(set (match_operand:SI 0 "s_register_operand" "")
4474 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4475 (match_operand 2 "const_int_operand" "")
4476 (match_operand 3 "const_int_operand" "")))]
4481 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4483 (define_insn "unaligned_loadsi"
4484 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4485 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4486 UNSPEC_UNALIGNED_LOAD))]
4488 "ldr%?\t%0, %1\t@ unaligned"
4489 [(set_attr "arch" "t2,any")
4490 (set_attr "length" "2,4")
4491 (set_attr "predicable" "yes")
4492 (set_attr "predicable_short_it" "yes,no")
4493 (set_attr "type" "load_4")])
4495 (define_insn "unaligned_loadhis"
4496 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4498 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4499 UNSPEC_UNALIGNED_LOAD)))]
4501 "ldrsh%?\t%0, %1\t@ unaligned"
4502 [(set_attr "arch" "t2,any")
4503 (set_attr "length" "2,4")
4504 (set_attr "predicable" "yes")
4505 (set_attr "predicable_short_it" "yes,no")
4506 (set_attr "type" "load_byte")])
4508 (define_insn "unaligned_loadhiu"
4509 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4511 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4512 UNSPEC_UNALIGNED_LOAD)))]
4514 "ldrh%?\t%0, %1\t@ unaligned"
4515 [(set_attr "arch" "t2,any")
4516 (set_attr "length" "2,4")
4517 (set_attr "predicable" "yes")
4518 (set_attr "predicable_short_it" "yes,no")
4519 (set_attr "type" "load_byte")])
4521 (define_insn "unaligned_storesi"
4522 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4523 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4524 UNSPEC_UNALIGNED_STORE))]
4526 "str%?\t%1, %0\t@ unaligned"
4527 [(set_attr "arch" "t2,any")
4528 (set_attr "length" "2,4")
4529 (set_attr "predicable" "yes")
4530 (set_attr "predicable_short_it" "yes,no")
4531 (set_attr "type" "store_4")])
4533 (define_insn "unaligned_storehi"
4534 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4535 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4536 UNSPEC_UNALIGNED_STORE))]
4538 "strh%?\t%1, %0\t@ unaligned"
4539 [(set_attr "arch" "t2,any")
4540 (set_attr "length" "2,4")
4541 (set_attr "predicable" "yes")
4542 (set_attr "predicable_short_it" "yes,no")
4543 (set_attr "type" "store_4")])
4546 (define_insn "*extv_reg"
4547 [(set (match_operand:SI 0 "s_register_operand" "=r")
4548 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4549 (match_operand:SI 2 "const_int_operand" "n")
4550 (match_operand:SI 3 "const_int_operand" "n")))]
4552 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4553 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4554 "sbfx%?\t%0, %1, %3, %2"
4555 [(set_attr "length" "4")
4556 (set_attr "predicable" "yes")
4557 (set_attr "predicable_short_it" "no")
4558 (set_attr "type" "bfm")]
4561 (define_insn "extzv_t2"
4562 [(set (match_operand:SI 0 "s_register_operand" "=r")
4563 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4564 (match_operand:SI 2 "const_int_operand" "n")
4565 (match_operand:SI 3 "const_int_operand" "n")))]
4567 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4568 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4569 "ubfx%?\t%0, %1, %3, %2"
4570 [(set_attr "length" "4")
4571 (set_attr "predicable" "yes")
4572 (set_attr "predicable_short_it" "no")
4573 (set_attr "type" "bfm")]
4577 ;; Division instructions
4578 (define_insn "divsi3"
4579 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4580 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4581 (match_operand:SI 2 "s_register_operand" "r,r")))]
4586 [(set_attr "arch" "32,v8mb")
4587 (set_attr "predicable" "yes")
4588 (set_attr "predicable_short_it" "no")
4589 (set_attr "type" "sdiv")]
4592 (define_insn "udivsi3"
4593 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4594 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4595 (match_operand:SI 2 "s_register_operand" "r,r")))]
4600 [(set_attr "arch" "32,v8mb")
4601 (set_attr "predicable" "yes")
4602 (set_attr "predicable_short_it" "no")
4603 (set_attr "type" "udiv")]
4607 ;; Unary arithmetic insns
4609 (define_expand "negvsi3"
4610 [(match_operand:SI 0 "register_operand")
4611 (match_operand:SI 1 "register_operand")
4612 (match_operand 2 "")]
4615 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4616 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4621 (define_expand "negvdi3"
4622 [(match_operand:DI 0 "register_operand")
4623 (match_operand:DI 1 "register_operand")
4624 (match_operand 2 "")]
4627 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4628 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4634 (define_insn_and_split "negdi2_compare"
4635 [(set (reg:CC CC_REGNUM)
4638 (match_operand:DI 1 "register_operand" "0,r")))
4639 (set (match_operand:DI 0 "register_operand" "=r,&r")
4640 (minus:DI (const_int 0) (match_dup 1)))]
4643 "&& reload_completed"
4644 [(parallel [(set (reg:CC CC_REGNUM)
4645 (compare:CC (const_int 0) (match_dup 1)))
4646 (set (match_dup 0) (minus:SI (const_int 0)
4648 (parallel [(set (reg:CC CC_REGNUM)
4649 (compare:CC (const_int 0) (match_dup 3)))
4652 (minus:SI (const_int 0) (match_dup 3))
4653 (ltu:SI (reg:CC_C CC_REGNUM)
4656 operands[2] = gen_highpart (SImode, operands[0]);
4657 operands[0] = gen_lowpart (SImode, operands[0]);
4658 operands[3] = gen_highpart (SImode, operands[1]);
4659 operands[1] = gen_lowpart (SImode, operands[1]);
4661 [(set_attr "conds" "set")
4662 (set_attr "length" "8")
4663 (set_attr "type" "multiple")]
4666 (define_expand "negdi2"
4668 [(set (match_operand:DI 0 "s_register_operand" "")
4669 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4670 (clobber (reg:CC CC_REGNUM))])]
4675 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4681 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4682 ;; The first alternative allows the common case of a *full* overlap.
4683 (define_insn_and_split "*negdi2_insn"
4684 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4685 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4686 (clobber (reg:CC CC_REGNUM))]
4688 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4689 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4690 "&& reload_completed"
4691 [(parallel [(set (reg:CC CC_REGNUM)
4692 (compare:CC (const_int 0) (match_dup 1)))
4693 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4694 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4695 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4697 operands[2] = gen_highpart (SImode, operands[0]);
4698 operands[0] = gen_lowpart (SImode, operands[0]);
4699 operands[3] = gen_highpart (SImode, operands[1]);
4700 operands[1] = gen_lowpart (SImode, operands[1]);
4702 [(set_attr "conds" "clob")
4703 (set_attr "length" "8")
4704 (set_attr "type" "multiple")]
4707 (define_insn "*negsi2_carryin_compare"
4708 [(set (reg:CC CC_REGNUM)
4709 (compare:CC (const_int 0)
4710 (match_operand:SI 1 "s_register_operand" "r")))
4711 (set (match_operand:SI 0 "s_register_operand" "=r")
4712 (minus:SI (minus:SI (const_int 0)
4714 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4717 [(set_attr "conds" "set")
4718 (set_attr "type" "alus_imm")]
4721 (define_expand "negsi2"
4722 [(set (match_operand:SI 0 "s_register_operand" "")
4723 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4728 (define_insn "*arm_negsi2"
4729 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4730 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4732 "rsb%?\\t%0, %1, #0"
4733 [(set_attr "predicable" "yes")
4734 (set_attr "predicable_short_it" "yes,no")
4735 (set_attr "arch" "t2,*")
4736 (set_attr "length" "4")
4737 (set_attr "type" "alu_sreg")]
4740 (define_expand "negsf2"
4741 [(set (match_operand:SF 0 "s_register_operand" "")
4742 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4743 "TARGET_32BIT && TARGET_HARD_FLOAT"
4747 (define_expand "negdf2"
4748 [(set (match_operand:DF 0 "s_register_operand" "")
4749 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4750 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4753 (define_insn_and_split "*zextendsidi_negsi"
4754 [(set (match_operand:DI 0 "s_register_operand" "=r")
4755 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4760 (neg:SI (match_dup 1)))
4764 operands[2] = gen_lowpart (SImode, operands[0]);
4765 operands[3] = gen_highpart (SImode, operands[0]);
4767 [(set_attr "length" "8")
4768 (set_attr "type" "multiple")]
4771 ;; Negate an extended 32-bit value.
4772 (define_insn_and_split "*negdi_extendsidi"
4773 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4774 (neg:DI (sign_extend:DI
4775 (match_operand:SI 1 "s_register_operand" "l,r"))))
4776 (clobber (reg:CC CC_REGNUM))]
4779 "&& reload_completed"
4782 rtx low = gen_lowpart (SImode, operands[0]);
4783 rtx high = gen_highpart (SImode, operands[0]);
4785 if (reg_overlap_mentioned_p (low, operands[1]))
4787 /* Input overlaps the low word of the output. Use:
4790 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4791 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4793 emit_insn (gen_rtx_SET (high,
4794 gen_rtx_ASHIFTRT (SImode, operands[1],
4797 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4799 emit_insn (gen_rtx_SET (high,
4800 gen_rtx_MINUS (SImode,
4801 gen_rtx_MINUS (SImode,
4804 gen_rtx_LTU (SImode,
4809 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4810 emit_insn (gen_rtx_SET (high,
4811 gen_rtx_MINUS (SImode,
4812 gen_rtx_MINUS (SImode,
4815 gen_rtx_LTU (SImode,
4822 /* No overlap, or overlap on high word. Use:
4826 Flags not needed for this sequence. */
4827 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4828 emit_insn (gen_rtx_SET (high,
4829 gen_rtx_AND (SImode,
4830 gen_rtx_NOT (SImode, operands[1]),
4832 emit_insn (gen_rtx_SET (high,
4833 gen_rtx_ASHIFTRT (SImode, high,
4838 [(set_attr "length" "12")
4839 (set_attr "arch" "t2,*")
4840 (set_attr "type" "multiple")]
4843 (define_insn_and_split "*negdi_zero_extendsidi"
4844 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4845 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4846 (clobber (reg:CC CC_REGNUM))]
4848 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4849 ;; Don't care what register is input to sbc,
4850 ;; since we just need to propagate the carry.
4851 "&& reload_completed"
4852 [(parallel [(set (reg:CC CC_REGNUM)
4853 (compare:CC (const_int 0) (match_dup 1)))
4854 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4855 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4856 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4858 operands[2] = gen_highpart (SImode, operands[0]);
4859 operands[0] = gen_lowpart (SImode, operands[0]);
4861 [(set_attr "conds" "clob")
4862 (set_attr "length" "8")
4863 (set_attr "type" "multiple")] ;; length in thumb is 4
4866 ;; abssi2 doesn't really clobber the condition codes if a different register
4867 ;; is being set. To keep things simple, assume during rtl manipulations that
4868 ;; it does, but tell the final scan operator the truth. Similarly for
4871 (define_expand "abssi2"
4873 [(set (match_operand:SI 0 "s_register_operand" "")
4874 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4875 (clobber (match_dup 2))])]
4879 operands[2] = gen_rtx_SCRATCH (SImode);
4881 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4884 (define_insn_and_split "*arm_abssi2"
4885 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4886 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4887 (clobber (reg:CC CC_REGNUM))]
4890 "&& reload_completed"
4893 /* if (which_alternative == 0) */
4894 if (REGNO(operands[0]) == REGNO(operands[1]))
4896 /* Emit the pattern:
4897 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4898 [(set (reg:CC CC_REGNUM)
4899 (compare:CC (match_dup 0) (const_int 0)))
4900 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4901 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4903 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4904 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4905 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4906 (gen_rtx_LT (SImode,
4907 gen_rtx_REG (CCmode, CC_REGNUM),
4909 (gen_rtx_SET (operands[0],
4910 (gen_rtx_MINUS (SImode,
4917 /* Emit the pattern:
4918 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4920 (xor:SI (match_dup 1)
4921 (ashiftrt:SI (match_dup 1) (const_int 31))))
4923 (minus:SI (match_dup 0)
4924 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4926 emit_insn (gen_rtx_SET (operands[0],
4927 gen_rtx_XOR (SImode,
4928 gen_rtx_ASHIFTRT (SImode,
4932 emit_insn (gen_rtx_SET (operands[0],
4933 gen_rtx_MINUS (SImode,
4935 gen_rtx_ASHIFTRT (SImode,
4941 [(set_attr "conds" "clob,*")
4942 (set_attr "shift" "1")
4943 (set_attr "predicable" "no, yes")
4944 (set_attr "length" "8")
4945 (set_attr "type" "multiple")]
4948 (define_insn_and_split "*arm_neg_abssi2"
4949 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4950 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4951 (clobber (reg:CC CC_REGNUM))]
4954 "&& reload_completed"
4957 /* if (which_alternative == 0) */
4958 if (REGNO (operands[0]) == REGNO (operands[1]))
4960 /* Emit the pattern:
4961 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4963 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4964 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4965 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4967 gen_rtx_REG (CCmode, CC_REGNUM),
4969 gen_rtx_SET (operands[0],
4970 (gen_rtx_MINUS (SImode,
4976 /* Emit the pattern:
4977 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4979 emit_insn (gen_rtx_SET (operands[0],
4980 gen_rtx_XOR (SImode,
4981 gen_rtx_ASHIFTRT (SImode,
4985 emit_insn (gen_rtx_SET (operands[0],
4986 gen_rtx_MINUS (SImode,
4987 gen_rtx_ASHIFTRT (SImode,
4994 [(set_attr "conds" "clob,*")
4995 (set_attr "shift" "1")
4996 (set_attr "predicable" "no, yes")
4997 (set_attr "length" "8")
4998 (set_attr "type" "multiple")]
5001 (define_expand "abssf2"
5002 [(set (match_operand:SF 0 "s_register_operand" "")
5003 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5004 "TARGET_32BIT && TARGET_HARD_FLOAT"
5007 (define_expand "absdf2"
5008 [(set (match_operand:DF 0 "s_register_operand" "")
5009 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5010 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5013 (define_expand "sqrtsf2"
5014 [(set (match_operand:SF 0 "s_register_operand" "")
5015 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5016 "TARGET_32BIT && TARGET_HARD_FLOAT"
5019 (define_expand "sqrtdf2"
5020 [(set (match_operand:DF 0 "s_register_operand" "")
5021 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5022 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5025 (define_expand "one_cmpldi2"
5026 [(set (match_operand:DI 0 "s_register_operand" "")
5027 (not:DI (match_operand:DI 1 "s_register_operand" "")))]
5030 if (!TARGET_NEON && !TARGET_IWMMXT)
5032 rtx low = simplify_gen_unary (NOT, SImode,
5033 gen_lowpart (SImode, operands[1]),
5035 rtx high = simplify_gen_unary (NOT, SImode,
5036 gen_highpart_mode (SImode, DImode,
5040 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5041 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5045 /* Otherwise expand pattern as above. */
5049 (define_insn_and_split "*one_cmpldi2_insn"
5050 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5051 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5058 "TARGET_32BIT && reload_completed
5059 && arm_general_register_operand (operands[0], DImode)"
5060 [(set (match_dup 0) (not:SI (match_dup 1)))
5061 (set (match_dup 2) (not:SI (match_dup 3)))]
5064 operands[2] = gen_highpart (SImode, operands[0]);
5065 operands[0] = gen_lowpart (SImode, operands[0]);
5066 operands[3] = gen_highpart (SImode, operands[1]);
5067 operands[1] = gen_lowpart (SImode, operands[1]);
5069 [(set_attr "length" "*,8,8,*")
5070 (set_attr "predicable" "no,yes,yes,no")
5071 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5072 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5075 (define_expand "one_cmplsi2"
5076 [(set (match_operand:SI 0 "s_register_operand" "")
5077 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5082 (define_insn "*arm_one_cmplsi2"
5083 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5084 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5087 [(set_attr "predicable" "yes")
5088 (set_attr "predicable_short_it" "yes,no")
5089 (set_attr "arch" "t2,*")
5090 (set_attr "length" "4")
5091 (set_attr "type" "mvn_reg")]
5094 (define_insn "*notsi_compare0"
5095 [(set (reg:CC_NOOV CC_REGNUM)
5096 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5098 (set (match_operand:SI 0 "s_register_operand" "=r")
5099 (not:SI (match_dup 1)))]
5102 [(set_attr "conds" "set")
5103 (set_attr "type" "mvn_reg")]
5106 (define_insn "*notsi_compare0_scratch"
5107 [(set (reg:CC_NOOV CC_REGNUM)
5108 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5110 (clobber (match_scratch:SI 0 "=r"))]
5113 [(set_attr "conds" "set")
5114 (set_attr "type" "mvn_reg")]
5117 ;; Fixed <--> Floating conversion insns
5119 (define_expand "floatsihf2"
5120 [(set (match_operand:HF 0 "general_operand" "")
5121 (float:HF (match_operand:SI 1 "general_operand" "")))]
5125 rtx op1 = gen_reg_rtx (SFmode);
5126 expand_float (op1, operands[1], 0);
5127 op1 = convert_to_mode (HFmode, op1, 0);
5128 emit_move_insn (operands[0], op1);
5133 (define_expand "floatdihf2"
5134 [(set (match_operand:HF 0 "general_operand" "")
5135 (float:HF (match_operand:DI 1 "general_operand" "")))]
5139 rtx op1 = gen_reg_rtx (SFmode);
5140 expand_float (op1, operands[1], 0);
5141 op1 = convert_to_mode (HFmode, op1, 0);
5142 emit_move_insn (operands[0], op1);
5147 (define_expand "floatsisf2"
5148 [(set (match_operand:SF 0 "s_register_operand" "")
5149 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5150 "TARGET_32BIT && TARGET_HARD_FLOAT"
5154 (define_expand "floatsidf2"
5155 [(set (match_operand:DF 0 "s_register_operand" "")
5156 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5157 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5161 (define_expand "fix_trunchfsi2"
5162 [(set (match_operand:SI 0 "general_operand" "")
5163 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5167 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5168 expand_fix (operands[0], op1, 0);
5173 (define_expand "fix_trunchfdi2"
5174 [(set (match_operand:DI 0 "general_operand" "")
5175 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5179 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5180 expand_fix (operands[0], op1, 0);
5185 (define_expand "fix_truncsfsi2"
5186 [(set (match_operand:SI 0 "s_register_operand" "")
5187 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5188 "TARGET_32BIT && TARGET_HARD_FLOAT"
5192 (define_expand "fix_truncdfsi2"
5193 [(set (match_operand:SI 0 "s_register_operand" "")
5194 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5195 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5201 (define_expand "truncdfsf2"
5202 [(set (match_operand:SF 0 "s_register_operand" "")
5204 (match_operand:DF 1 "s_register_operand" "")))]
5205 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5209 ;; DFmode to HFmode conversions on targets without a single-step hardware
5210 ;; instruction for it would have to go through SFmode. This is dangerous
5211 ;; as it introduces double rounding.
5213 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5214 ;; a single-step instruction.
5216 (define_expand "truncdfhf2"
5217 [(set (match_operand:HF 0 "s_register_operand" "")
5219 (match_operand:DF 1 "s_register_operand" "")))]
5220 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5221 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5223 /* We don't have a direct instruction for this, so we must be in
5224 an unsafe math mode, and going via SFmode. */
5226 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5229 op1 = convert_to_mode (SFmode, operands[1], 0);
5230 op1 = convert_to_mode (HFmode, op1, 0);
5231 emit_move_insn (operands[0], op1);
5234 /* Otherwise, we will pick this up as a single instruction with
5235 no intermediary rounding. */
5239 ;; Zero and sign extension instructions.
5241 (define_insn "zero_extend<mode>di2"
5242 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5243 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5244 "<qhs_zextenddi_cstr>")))]
5245 "TARGET_32BIT <qhs_zextenddi_cond>"
5247 [(set_attr "length" "8,4,8,8")
5248 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5249 (set_attr "ce_count" "2")
5250 (set_attr "predicable" "yes")
5251 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5254 (define_insn "extend<mode>di2"
5255 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5256 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5257 "<qhs_extenddi_cstr>")))]
5258 "TARGET_32BIT <qhs_sextenddi_cond>"
5260 [(set_attr "length" "8,4,8,8,8")
5261 (set_attr "ce_count" "2")
5262 (set_attr "shift" "1")
5263 (set_attr "predicable" "yes")
5264 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5265 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5268 ;; Splits for all extensions to DImode
5270 [(set (match_operand:DI 0 "s_register_operand" "")
5271 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5272 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5273 [(set (match_dup 0) (match_dup 1))]
5275 rtx lo_part = gen_lowpart (SImode, operands[0]);
5276 machine_mode src_mode = GET_MODE (operands[1]);
5278 if (REG_P (operands[0])
5279 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5280 emit_clobber (operands[0]);
5281 if (!REG_P (lo_part) || src_mode != SImode
5282 || !rtx_equal_p (lo_part, operands[1]))
5284 if (src_mode == SImode)
5285 emit_move_insn (lo_part, operands[1]);
5287 emit_insn (gen_rtx_SET (lo_part,
5288 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5289 operands[1] = lo_part;
5291 operands[0] = gen_highpart (SImode, operands[0]);
5292 operands[1] = const0_rtx;
5296 [(set (match_operand:DI 0 "s_register_operand" "")
5297 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5298 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5299 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5301 rtx lo_part = gen_lowpart (SImode, operands[0]);
5302 machine_mode src_mode = GET_MODE (operands[1]);
5304 if (REG_P (operands[0])
5305 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5306 emit_clobber (operands[0]);
5308 if (!REG_P (lo_part) || src_mode != SImode
5309 || !rtx_equal_p (lo_part, operands[1]))
5311 if (src_mode == SImode)
5312 emit_move_insn (lo_part, operands[1]);
5314 emit_insn (gen_rtx_SET (lo_part,
5315 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5316 operands[1] = lo_part;
5318 operands[0] = gen_highpart (SImode, operands[0]);
5321 (define_expand "zero_extendhisi2"
5322 [(set (match_operand:SI 0 "s_register_operand" "")
5323 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5326 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5328 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5331 if (!arm_arch6 && !MEM_P (operands[1]))
5333 rtx t = gen_lowpart (SImode, operands[1]);
5334 rtx tmp = gen_reg_rtx (SImode);
5335 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5336 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5342 [(set (match_operand:SI 0 "s_register_operand" "")
5343 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5344 "!TARGET_THUMB2 && !arm_arch6"
5345 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5346 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5348 operands[2] = gen_lowpart (SImode, operands[1]);
5351 (define_insn "*arm_zero_extendhisi2"
5352 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5353 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5354 "TARGET_ARM && arm_arch4 && !arm_arch6"
5358 [(set_attr "type" "alu_shift_reg,load_byte")
5359 (set_attr "predicable" "yes")]
5362 (define_insn "*arm_zero_extendhisi2_v6"
5363 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5364 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5365 "TARGET_ARM && arm_arch6"
5369 [(set_attr "predicable" "yes")
5370 (set_attr "type" "extend,load_byte")]
5373 (define_insn "*arm_zero_extendhisi2addsi"
5374 [(set (match_operand:SI 0 "s_register_operand" "=r")
5375 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5376 (match_operand:SI 2 "s_register_operand" "r")))]
5378 "uxtah%?\\t%0, %2, %1"
5379 [(set_attr "type" "alu_shift_reg")
5380 (set_attr "predicable" "yes")
5381 (set_attr "predicable_short_it" "no")]
5384 (define_expand "zero_extendqisi2"
5385 [(set (match_operand:SI 0 "s_register_operand" "")
5386 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5389 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5391 emit_insn (gen_andsi3 (operands[0],
5392 gen_lowpart (SImode, operands[1]),
5396 if (!arm_arch6 && !MEM_P (operands[1]))
5398 rtx t = gen_lowpart (SImode, operands[1]);
5399 rtx tmp = gen_reg_rtx (SImode);
5400 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5401 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5407 [(set (match_operand:SI 0 "s_register_operand" "")
5408 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5410 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5411 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5413 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5416 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5421 (define_insn "*arm_zero_extendqisi2"
5422 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5423 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5424 "TARGET_ARM && !arm_arch6"
5427 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5428 [(set_attr "length" "8,4")
5429 (set_attr "type" "alu_shift_reg,load_byte")
5430 (set_attr "predicable" "yes")]
5433 (define_insn "*arm_zero_extendqisi2_v6"
5434 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5435 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5436 "TARGET_ARM && arm_arch6"
5439 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5440 [(set_attr "type" "extend,load_byte")
5441 (set_attr "predicable" "yes")]
5444 (define_insn "*arm_zero_extendqisi2addsi"
5445 [(set (match_operand:SI 0 "s_register_operand" "=r")
5446 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5447 (match_operand:SI 2 "s_register_operand" "r")))]
5449 "uxtab%?\\t%0, %2, %1"
5450 [(set_attr "predicable" "yes")
5451 (set_attr "predicable_short_it" "no")
5452 (set_attr "type" "alu_shift_reg")]
5456 [(set (match_operand:SI 0 "s_register_operand" "")
5457 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5458 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5459 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5460 [(set (match_dup 2) (match_dup 1))
5461 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5466 [(set (match_operand:SI 0 "s_register_operand" "")
5467 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5468 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5469 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5470 [(set (match_dup 2) (match_dup 1))
5471 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5477 [(set (match_operand:SI 0 "s_register_operand" "")
5478 (IOR_XOR:SI (and:SI (ashift:SI
5479 (match_operand:SI 1 "s_register_operand" "")
5480 (match_operand:SI 2 "const_int_operand" ""))
5481 (match_operand:SI 3 "const_int_operand" ""))
5483 (match_operator 5 "subreg_lowpart_operator"
5484 [(match_operand:SI 4 "s_register_operand" "")]))))]
5486 && (UINTVAL (operands[3])
5487 == (GET_MODE_MASK (GET_MODE (operands[5]))
5488 & (GET_MODE_MASK (GET_MODE (operands[5]))
5489 << (INTVAL (operands[2])))))"
5490 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5492 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5493 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5496 (define_insn "*compareqi_eq0"
5497 [(set (reg:CC_Z CC_REGNUM)
5498 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5502 [(set_attr "conds" "set")
5503 (set_attr "predicable" "yes")
5504 (set_attr "predicable_short_it" "no")
5505 (set_attr "type" "logic_imm")]
5508 (define_expand "extendhisi2"
5509 [(set (match_operand:SI 0 "s_register_operand" "")
5510 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5515 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5518 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5520 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5524 if (!arm_arch6 && !MEM_P (operands[1]))
5526 rtx t = gen_lowpart (SImode, operands[1]);
5527 rtx tmp = gen_reg_rtx (SImode);
5528 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5529 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5536 [(set (match_operand:SI 0 "register_operand" "")
5537 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5538 (clobber (match_scratch:SI 2 ""))])]
5540 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5541 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5543 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5546 ;; This pattern will only be used when ldsh is not available
5547 (define_expand "extendhisi2_mem"
5548 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5550 (zero_extend:SI (match_dup 7)))
5551 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5552 (set (match_operand:SI 0 "" "")
5553 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5558 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5560 mem1 = change_address (operands[1], QImode, addr);
5561 mem2 = change_address (operands[1], QImode,
5562 plus_constant (Pmode, addr, 1));
5563 operands[0] = gen_lowpart (SImode, operands[0]);
5565 operands[2] = gen_reg_rtx (SImode);
5566 operands[3] = gen_reg_rtx (SImode);
5567 operands[6] = gen_reg_rtx (SImode);
5570 if (BYTES_BIG_ENDIAN)
5572 operands[4] = operands[2];
5573 operands[5] = operands[3];
5577 operands[4] = operands[3];
5578 operands[5] = operands[2];
5584 [(set (match_operand:SI 0 "register_operand" "")
5585 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5587 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5588 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5590 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5593 (define_insn "*arm_extendhisi2"
5594 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5595 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5596 "TARGET_ARM && arm_arch4 && !arm_arch6"
5600 [(set_attr "length" "8,4")
5601 (set_attr "type" "alu_shift_reg,load_byte")
5602 (set_attr "predicable" "yes")]
5605 ;; ??? Check Thumb-2 pool range
5606 (define_insn "*arm_extendhisi2_v6"
5607 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5608 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5609 "TARGET_32BIT && arm_arch6"
5613 [(set_attr "type" "extend,load_byte")
5614 (set_attr "predicable" "yes")
5615 (set_attr "predicable_short_it" "no")]
5618 (define_insn "*arm_extendhisi2addsi"
5619 [(set (match_operand:SI 0 "s_register_operand" "=r")
5620 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5621 (match_operand:SI 2 "s_register_operand" "r")))]
5623 "sxtah%?\\t%0, %2, %1"
5624 [(set_attr "type" "alu_shift_reg")]
5627 (define_expand "extendqihi2"
5629 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5631 (set (match_operand:HI 0 "s_register_operand" "")
5632 (ashiftrt:SI (match_dup 2)
5637 if (arm_arch4 && MEM_P (operands[1]))
5639 emit_insn (gen_rtx_SET (operands[0],
5640 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5643 if (!s_register_operand (operands[1], QImode))
5644 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5645 operands[0] = gen_lowpart (SImode, operands[0]);
5646 operands[1] = gen_lowpart (SImode, operands[1]);
5647 operands[2] = gen_reg_rtx (SImode);
5651 (define_insn "*arm_extendqihi_insn"
5652 [(set (match_operand:HI 0 "s_register_operand" "=r")
5653 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5654 "TARGET_ARM && arm_arch4"
5656 [(set_attr "type" "load_byte")
5657 (set_attr "predicable" "yes")]
5660 (define_expand "extendqisi2"
5661 [(set (match_operand:SI 0 "s_register_operand" "")
5662 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5665 if (!arm_arch4 && MEM_P (operands[1]))
5666 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5668 if (!arm_arch6 && !MEM_P (operands[1]))
5670 rtx t = gen_lowpart (SImode, operands[1]);
5671 rtx tmp = gen_reg_rtx (SImode);
5672 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5673 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5679 [(set (match_operand:SI 0 "register_operand" "")
5680 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5682 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5683 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5685 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5688 (define_insn "*arm_extendqisi"
5689 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5690 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5691 "TARGET_ARM && arm_arch4 && !arm_arch6"
5695 [(set_attr "length" "8,4")
5696 (set_attr "type" "alu_shift_reg,load_byte")
5697 (set_attr "predicable" "yes")]
5700 (define_insn "*arm_extendqisi_v6"
5701 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5703 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5704 "TARGET_ARM && arm_arch6"
5708 [(set_attr "type" "extend,load_byte")
5709 (set_attr "predicable" "yes")]
5712 (define_insn "*arm_extendqisi2addsi"
5713 [(set (match_operand:SI 0 "s_register_operand" "=r")
5714 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5715 (match_operand:SI 2 "s_register_operand" "r")))]
5717 "sxtab%?\\t%0, %2, %1"
5718 [(set_attr "type" "alu_shift_reg")
5719 (set_attr "predicable" "yes")
5720 (set_attr "predicable_short_it" "no")]
5723 (define_expand "extendsfdf2"
5724 [(set (match_operand:DF 0 "s_register_operand" "")
5725 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5726 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5730 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5731 ;; must go through SFmode.
5733 ;; This is always safe for an extend.
5735 (define_expand "extendhfdf2"
5736 [(set (match_operand:DF 0 "s_register_operand" "")
5737 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5740 /* We don't have a direct instruction for this, so go via SFmode. */
5741 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5744 op1 = convert_to_mode (SFmode, operands[1], 0);
5745 op1 = convert_to_mode (DFmode, op1, 0);
5746 emit_insn (gen_movdf (operands[0], op1));
5749 /* Otherwise, we're done producing RTL and will pick up the correct
5750 pattern to do this with one rounding-step in a single instruction. */
5754 ;; Move insns (including loads and stores)
5756 ;; XXX Just some ideas about movti.
5757 ;; I don't think these are a good idea on the arm, there just aren't enough
5759 ;;(define_expand "loadti"
5760 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5761 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5764 ;;(define_expand "storeti"
5765 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5766 ;; (match_operand:TI 1 "s_register_operand" ""))]
5769 ;;(define_expand "movti"
5770 ;; [(set (match_operand:TI 0 "general_operand" "")
5771 ;; (match_operand:TI 1 "general_operand" ""))]
5777 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5778 ;; operands[1] = copy_to_reg (operands[1]);
5779 ;; if (MEM_P (operands[0]))
5780 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5781 ;; else if (MEM_P (operands[1]))
5782 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5786 ;; emit_insn (insn);
5790 ;; Recognize garbage generated above.
5793 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5794 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5798 ;; register mem = (which_alternative < 3);
5799 ;; register const char *template;
5801 ;; operands[mem] = XEXP (operands[mem], 0);
5802 ;; switch (which_alternative)
5804 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5805 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5806 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5807 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5808 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5809 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5811 ;; output_asm_insn (template, operands);
5815 (define_expand "movdi"
5816 [(set (match_operand:DI 0 "general_operand" "")
5817 (match_operand:DI 1 "general_operand" ""))]
5820 if (can_create_pseudo_p ())
5822 if (!REG_P (operands[0]))
5823 operands[1] = force_reg (DImode, operands[1]);
5825 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5826 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5828 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5829 when expanding function calls. */
5830 gcc_assert (can_create_pseudo_p ());
5831 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5833 /* Perform load into legal reg pair first, then move. */
5834 rtx reg = gen_reg_rtx (DImode);
5835 emit_insn (gen_movdi (reg, operands[1]));
5838 emit_move_insn (gen_lowpart (SImode, operands[0]),
5839 gen_lowpart (SImode, operands[1]));
5840 emit_move_insn (gen_highpart (SImode, operands[0]),
5841 gen_highpart (SImode, operands[1]));
5844 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5845 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5847 /* Avoid STRD's from an odd-numbered register pair in ARM state
5848 when expanding function prologue. */
5849 gcc_assert (can_create_pseudo_p ());
5850 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5851 ? gen_reg_rtx (DImode)
5853 emit_move_insn (gen_lowpart (SImode, split_dest),
5854 gen_lowpart (SImode, operands[1]));
5855 emit_move_insn (gen_highpart (SImode, split_dest),
5856 gen_highpart (SImode, operands[1]));
5857 if (split_dest != operands[0])
5858 emit_insn (gen_movdi (operands[0], split_dest));
5864 (define_insn "*arm_movdi"
5865 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5866 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5868 && !(TARGET_HARD_FLOAT)
5870 && ( register_operand (operands[0], DImode)
5871 || register_operand (operands[1], DImode))"
5873 switch (which_alternative)
5880 return output_move_double (operands, true, NULL);
5883 [(set_attr "length" "8,12,16,8,8")
5884 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5885 (set_attr "arm_pool_range" "*,*,*,1020,*")
5886 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5887 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5888 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5892 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5893 (match_operand:ANY64 1 "immediate_operand" ""))]
5896 && (arm_disable_literal_pool
5897 || (arm_const_double_inline_cost (operands[1])
5898 <= arm_max_const_double_inline_cost ()))"
5901 arm_split_constant (SET, SImode, curr_insn,
5902 INTVAL (gen_lowpart (SImode, operands[1])),
5903 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5904 arm_split_constant (SET, SImode, curr_insn,
5905 INTVAL (gen_highpart_mode (SImode,
5906 GET_MODE (operands[0]),
5908 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5913 ; If optimizing for size, or if we have load delay slots, then
5914 ; we want to split the constant into two separate operations.
5915 ; In both cases this may split a trivial part into a single data op
5916 ; leaving a single complex constant to load. We can also get longer
5917 ; offsets in a LDR which means we get better chances of sharing the pool
5918 ; entries. Finally, we can normally do a better job of scheduling
5919 ; LDR instructions than we can with LDM.
5920 ; This pattern will only match if the one above did not.
5922 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5923 (match_operand:ANY64 1 "const_double_operand" ""))]
5924 "TARGET_ARM && reload_completed
5925 && arm_const_double_by_parts (operands[1])"
5926 [(set (match_dup 0) (match_dup 1))
5927 (set (match_dup 2) (match_dup 3))]
5929 operands[2] = gen_highpart (SImode, operands[0]);
5930 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5932 operands[0] = gen_lowpart (SImode, operands[0]);
5933 operands[1] = gen_lowpart (SImode, operands[1]);
5938 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5939 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5940 "TARGET_EITHER && reload_completed"
5941 [(set (match_dup 0) (match_dup 1))
5942 (set (match_dup 2) (match_dup 3))]
5944 operands[2] = gen_highpart (SImode, operands[0]);
5945 operands[3] = gen_highpart (SImode, operands[1]);
5946 operands[0] = gen_lowpart (SImode, operands[0]);
5947 operands[1] = gen_lowpart (SImode, operands[1]);
5949 /* Handle a partial overlap. */
5950 if (rtx_equal_p (operands[0], operands[3]))
5952 rtx tmp0 = operands[0];
5953 rtx tmp1 = operands[1];
5955 operands[0] = operands[2];
5956 operands[1] = operands[3];
5963 ;; We can't actually do base+index doubleword loads if the index and
5964 ;; destination overlap. Split here so that we at least have chance to
5967 [(set (match_operand:DI 0 "s_register_operand" "")
5968 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5969 (match_operand:SI 2 "s_register_operand" ""))))]
5971 && reg_overlap_mentioned_p (operands[0], operands[1])
5972 && reg_overlap_mentioned_p (operands[0], operands[2])"
5974 (plus:SI (match_dup 1)
5977 (mem:DI (match_dup 4)))]
5979 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5983 (define_expand "movsi"
5984 [(set (match_operand:SI 0 "general_operand" "")
5985 (match_operand:SI 1 "general_operand" ""))]
5989 rtx base, offset, tmp;
5991 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5993 /* Everything except mem = const or mem = mem can be done easily. */
5994 if (MEM_P (operands[0]))
5995 operands[1] = force_reg (SImode, operands[1]);
5996 if (arm_general_register_operand (operands[0], SImode)
5997 && CONST_INT_P (operands[1])
5998 && !(const_ok_for_arm (INTVAL (operands[1]))
5999 || const_ok_for_arm (~INTVAL (operands[1]))))
6001 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
6003 emit_insn (gen_rtx_SET (operands[0], operands[1]));
6008 arm_split_constant (SET, SImode, NULL_RTX,
6009 INTVAL (operands[1]), operands[0], NULL_RTX,
6010 optimize && can_create_pseudo_p ());
6015 else /* Target doesn't have MOVT... */
6017 if (can_create_pseudo_p ())
6019 if (!REG_P (operands[0]))
6020 operands[1] = force_reg (SImode, operands[1]);
6024 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6026 split_const (operands[1], &base, &offset);
6027 if (GET_CODE (base) == SYMBOL_REF
6028 && !offset_within_block_p (base, INTVAL (offset)))
6030 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6031 emit_move_insn (tmp, base);
6032 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6037 /* Recognize the case where operand[1] is a reference to thread-local
6038 data and load its address to a register. */
6039 if (arm_tls_referenced_p (operands[1]))
6041 rtx tmp = operands[1];
6044 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6046 addend = XEXP (XEXP (tmp, 0), 1);
6047 tmp = XEXP (XEXP (tmp, 0), 0);
6050 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6051 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6053 tmp = legitimize_tls_address (tmp,
6054 !can_create_pseudo_p () ? operands[0] : 0);
6057 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6058 tmp = force_operand (tmp, operands[0]);
6063 && (CONSTANT_P (operands[1])
6064 || symbol_mentioned_p (operands[1])
6065 || label_mentioned_p (operands[1])))
6066 operands[1] = legitimize_pic_address (operands[1], SImode,
6067 (!can_create_pseudo_p ()
6074 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6075 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6076 ;; so this does not matter.
6077 (define_insn "*arm_movt"
6078 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6079 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6080 (match_operand:SI 2 "general_operand" "i,i")))]
6081 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6083 movt%?\t%0, #:upper16:%c2
6084 movt\t%0, #:upper16:%c2"
6085 [(set_attr "arch" "32,v8mb")
6086 (set_attr "predicable" "yes")
6087 (set_attr "predicable_short_it" "no")
6088 (set_attr "length" "4")
6089 (set_attr "type" "alu_sreg")]
6092 (define_insn "*arm_movsi_insn"
6093 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6094 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6095 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6096 && ( register_operand (operands[0], SImode)
6097 || register_operand (operands[1], SImode))"
6105 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6106 (set_attr "predicable" "yes")
6107 (set_attr "arch" "*,*,*,v6t2,*,*")
6108 (set_attr "pool_range" "*,*,*,*,4096,*")
6109 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6113 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6114 (match_operand:SI 1 "const_int_operand" ""))]
6115 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6116 && (!(const_ok_for_arm (INTVAL (operands[1]))
6117 || const_ok_for_arm (~INTVAL (operands[1]))))"
6118 [(clobber (const_int 0))]
6120 arm_split_constant (SET, SImode, NULL_RTX,
6121 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6126 ;; A normal way to do (symbol + offset) requires three instructions at least
6127 ;; (depends on how big the offset is) as below:
6128 ;; movw r0, #:lower16:g
6129 ;; movw r0, #:upper16:g
6132 ;; A better way would be:
6133 ;; movw r0, #:lower16:g+4
6134 ;; movw r0, #:upper16:g+4
6136 ;; The limitation of this way is that the length of offset should be a 16-bit
6137 ;; signed value, because current assembler only supports REL type relocation for
6138 ;; such case. If the more powerful RELA type is supported in future, we should
6139 ;; update this pattern to go with better way.
6141 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6142 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6143 (match_operand:SI 2 "const_int_operand" ""))))]
6146 && arm_disable_literal_pool
6148 && GET_CODE (operands[1]) == SYMBOL_REF"
6149 [(clobber (const_int 0))]
6151 int offset = INTVAL (operands[2]);
6153 if (offset < -0x8000 || offset > 0x7fff)
6155 arm_emit_movpair (operands[0], operands[1]);
6156 emit_insn (gen_rtx_SET (operands[0],
6157 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6161 rtx op = gen_rtx_CONST (SImode,
6162 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6163 arm_emit_movpair (operands[0], op);
6168 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6169 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6170 ;; and lo_sum would be merged back into memory load at cprop. However,
6171 ;; if the default is to prefer movt/movw rather than a load from the constant
6172 ;; pool, the performance is better.
6174 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6175 (match_operand:SI 1 "general_operand" ""))]
6176 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6177 && !flag_pic && !target_word_relocations
6178 && !arm_tls_referenced_p (operands[1])"
6179 [(clobber (const_int 0))]
6181 arm_emit_movpair (operands[0], operands[1]);
6185 ;; When generating pic, we need to load the symbol offset into a register.
6186 ;; So that the optimizer does not confuse this with a normal symbol load
6187 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6188 ;; since that is the only type of relocation we can use.
6190 ;; Wrap calculation of the whole PIC address in a single pattern for the
6191 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6192 ;; a PIC address involves two loads from memory, so we want to CSE it
6193 ;; as often as possible.
6194 ;; This pattern will be split into one of the pic_load_addr_* patterns
6195 ;; and a move after GCSE optimizations.
6197 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6198 (define_expand "calculate_pic_address"
6199 [(set (match_operand:SI 0 "register_operand" "")
6200 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6201 (unspec:SI [(match_operand:SI 2 "" "")]
6206 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6208 [(set (match_operand:SI 0 "register_operand" "")
6209 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6210 (unspec:SI [(match_operand:SI 2 "" "")]
6213 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6214 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6215 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6218 ;; operand1 is the memory address to go into
6219 ;; pic_load_addr_32bit.
6220 ;; operand2 is the PIC label to be emitted
6221 ;; from pic_add_dot_plus_eight.
6222 ;; We do this to allow hoisting of the entire insn.
6223 (define_insn_and_split "pic_load_addr_unified"
6224 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6225 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6226 (match_operand:SI 2 "" "")]
6227 UNSPEC_PIC_UNIFIED))]
6230 "&& reload_completed"
6231 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6232 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6233 (match_dup 2)] UNSPEC_PIC_BASE))]
6234 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6235 [(set_attr "type" "load_4,load_4,load_4")
6236 (set_attr "pool_range" "4096,4094,1022")
6237 (set_attr "neg_pool_range" "4084,0,0")
6238 (set_attr "arch" "a,t2,t1")
6239 (set_attr "length" "8,6,4")]
6242 ;; The rather odd constraints on the following are to force reload to leave
6243 ;; the insn alone, and to force the minipool generation pass to then move
6244 ;; the GOT symbol to memory.
6246 (define_insn "pic_load_addr_32bit"
6247 [(set (match_operand:SI 0 "s_register_operand" "=r")
6248 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6249 "TARGET_32BIT && flag_pic"
6251 [(set_attr "type" "load_4")
6252 (set (attr "pool_range")
6253 (if_then_else (eq_attr "is_thumb" "no")
6256 (set (attr "neg_pool_range")
6257 (if_then_else (eq_attr "is_thumb" "no")
6262 (define_insn "pic_load_addr_thumb1"
6263 [(set (match_operand:SI 0 "s_register_operand" "=l")
6264 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6265 "TARGET_THUMB1 && flag_pic"
6267 [(set_attr "type" "load_4")
6268 (set (attr "pool_range") (const_int 1018))]
6271 (define_insn "pic_add_dot_plus_four"
6272 [(set (match_operand:SI 0 "register_operand" "=r")
6273 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6275 (match_operand 2 "" "")]
6279 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6280 INTVAL (operands[2]));
6281 return \"add\\t%0, %|pc\";
6283 [(set_attr "length" "2")
6284 (set_attr "type" "alu_sreg")]
6287 (define_insn "pic_add_dot_plus_eight"
6288 [(set (match_operand:SI 0 "register_operand" "=r")
6289 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6291 (match_operand 2 "" "")]
6295 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6296 INTVAL (operands[2]));
6297 return \"add%?\\t%0, %|pc, %1\";
6299 [(set_attr "predicable" "yes")
6300 (set_attr "type" "alu_sreg")]
6303 (define_insn "tls_load_dot_plus_eight"
6304 [(set (match_operand:SI 0 "register_operand" "=r")
6305 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6307 (match_operand 2 "" "")]
6311 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6312 INTVAL (operands[2]));
6313 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6315 [(set_attr "predicable" "yes")
6316 (set_attr "type" "load_4")]
6319 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6320 ;; followed by a load. These sequences can be crunched down to
6321 ;; tls_load_dot_plus_eight by a peephole.
6324 [(set (match_operand:SI 0 "register_operand" "")
6325 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6327 (match_operand 1 "" "")]
6329 (set (match_operand:SI 2 "arm_general_register_operand" "")
6330 (mem:SI (match_dup 0)))]
6331 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6333 (mem:SI (unspec:SI [(match_dup 3)
6340 (define_insn "pic_offset_arm"
6341 [(set (match_operand:SI 0 "register_operand" "=r")
6342 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6343 (unspec:SI [(match_operand:SI 2 "" "X")]
6344 UNSPEC_PIC_OFFSET))))]
6345 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6346 "ldr%?\\t%0, [%1,%2]"
6347 [(set_attr "type" "load_4")]
6350 (define_expand "builtin_setjmp_receiver"
6351 [(label_ref (match_operand 0 "" ""))]
6355 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6357 if (arm_pic_register != INVALID_REGNUM)
6358 arm_load_pic_register (1UL << 3);
6362 ;; If copying one reg to another we can set the condition codes according to
6363 ;; its value. Such a move is common after a return from subroutine and the
6364 ;; result is being tested against zero.
6366 (define_insn "*movsi_compare0"
6367 [(set (reg:CC CC_REGNUM)
6368 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6370 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6375 subs%?\\t%0, %1, #0"
6376 [(set_attr "conds" "set")
6377 (set_attr "type" "alus_imm,alus_imm")]
6380 ;; Subroutine to store a half word from a register into memory.
6381 ;; Operand 0 is the source register (HImode)
6382 ;; Operand 1 is the destination address in a register (SImode)
6384 ;; In both this routine and the next, we must be careful not to spill
6385 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6386 ;; can generate unrecognizable rtl.
6388 (define_expand "storehi"
6389 [;; store the low byte
6390 (set (match_operand 1 "" "") (match_dup 3))
6391 ;; extract the high byte
6393 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6394 ;; store the high byte
6395 (set (match_dup 4) (match_dup 5))]
6399 rtx op1 = operands[1];
6400 rtx addr = XEXP (op1, 0);
6401 enum rtx_code code = GET_CODE (addr);
6403 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6405 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6407 operands[4] = adjust_address (op1, QImode, 1);
6408 operands[1] = adjust_address (operands[1], QImode, 0);
6409 operands[3] = gen_lowpart (QImode, operands[0]);
6410 operands[0] = gen_lowpart (SImode, operands[0]);
6411 operands[2] = gen_reg_rtx (SImode);
6412 operands[5] = gen_lowpart (QImode, operands[2]);
6416 (define_expand "storehi_bigend"
6417 [(set (match_dup 4) (match_dup 3))
6419 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6420 (set (match_operand 1 "" "") (match_dup 5))]
6424 rtx op1 = operands[1];
6425 rtx addr = XEXP (op1, 0);
6426 enum rtx_code code = GET_CODE (addr);
6428 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6430 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6432 operands[4] = adjust_address (op1, QImode, 1);
6433 operands[1] = adjust_address (operands[1], QImode, 0);
6434 operands[3] = gen_lowpart (QImode, operands[0]);
6435 operands[0] = gen_lowpart (SImode, operands[0]);
6436 operands[2] = gen_reg_rtx (SImode);
6437 operands[5] = gen_lowpart (QImode, operands[2]);
6441 ;; Subroutine to store a half word integer constant into memory.
6442 (define_expand "storeinthi"
6443 [(set (match_operand 0 "" "")
6444 (match_operand 1 "" ""))
6445 (set (match_dup 3) (match_dup 2))]
6449 HOST_WIDE_INT value = INTVAL (operands[1]);
6450 rtx addr = XEXP (operands[0], 0);
6451 rtx op0 = operands[0];
6452 enum rtx_code code = GET_CODE (addr);
6454 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6456 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6458 operands[1] = gen_reg_rtx (SImode);
6459 if (BYTES_BIG_ENDIAN)
6461 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6462 if ((value & 255) == ((value >> 8) & 255))
6463 operands[2] = operands[1];
6466 operands[2] = gen_reg_rtx (SImode);
6467 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6472 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6473 if ((value & 255) == ((value >> 8) & 255))
6474 operands[2] = operands[1];
6477 operands[2] = gen_reg_rtx (SImode);
6478 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6482 operands[3] = adjust_address (op0, QImode, 1);
6483 operands[0] = adjust_address (operands[0], QImode, 0);
6484 operands[2] = gen_lowpart (QImode, operands[2]);
6485 operands[1] = gen_lowpart (QImode, operands[1]);
6489 (define_expand "storehi_single_op"
6490 [(set (match_operand:HI 0 "memory_operand" "")
6491 (match_operand:HI 1 "general_operand" ""))]
6492 "TARGET_32BIT && arm_arch4"
6494 if (!s_register_operand (operands[1], HImode))
6495 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6499 (define_expand "movhi"
6500 [(set (match_operand:HI 0 "general_operand" "")
6501 (match_operand:HI 1 "general_operand" ""))]
6506 if (can_create_pseudo_p ())
6508 if (MEM_P (operands[0]))
6512 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6515 if (CONST_INT_P (operands[1]))
6516 emit_insn (gen_storeinthi (operands[0], operands[1]));
6519 if (MEM_P (operands[1]))
6520 operands[1] = force_reg (HImode, operands[1]);
6521 if (BYTES_BIG_ENDIAN)
6522 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6524 emit_insn (gen_storehi (operands[1], operands[0]));
6528 /* Sign extend a constant, and keep it in an SImode reg. */
6529 else if (CONST_INT_P (operands[1]))
6531 rtx reg = gen_reg_rtx (SImode);
6532 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6534 /* If the constant is already valid, leave it alone. */
6535 if (!const_ok_for_arm (val))
6537 /* If setting all the top bits will make the constant
6538 loadable in a single instruction, then set them.
6539 Otherwise, sign extend the number. */
6541 if (const_ok_for_arm (~(val | ~0xffff)))
6543 else if (val & 0x8000)
6547 emit_insn (gen_movsi (reg, GEN_INT (val)));
6548 operands[1] = gen_lowpart (HImode, reg);
6550 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6551 && MEM_P (operands[1]))
6553 rtx reg = gen_reg_rtx (SImode);
6555 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6556 operands[1] = gen_lowpart (HImode, reg);
6558 else if (!arm_arch4)
6560 if (MEM_P (operands[1]))
6563 rtx offset = const0_rtx;
6564 rtx reg = gen_reg_rtx (SImode);
6566 if ((REG_P (base = XEXP (operands[1], 0))
6567 || (GET_CODE (base) == PLUS
6568 && (CONST_INT_P (offset = XEXP (base, 1)))
6569 && ((INTVAL(offset) & 1) != 1)
6570 && REG_P (base = XEXP (base, 0))))
6571 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6575 new_rtx = widen_memory_access (operands[1], SImode,
6576 ((INTVAL (offset) & ~3)
6577 - INTVAL (offset)));
6578 emit_insn (gen_movsi (reg, new_rtx));
6579 if (((INTVAL (offset) & 2) != 0)
6580 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6582 rtx reg2 = gen_reg_rtx (SImode);
6584 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6589 emit_insn (gen_movhi_bytes (reg, operands[1]));
6591 operands[1] = gen_lowpart (HImode, reg);
6595 /* Handle loading a large integer during reload. */
6596 else if (CONST_INT_P (operands[1])
6597 && !const_ok_for_arm (INTVAL (operands[1]))
6598 && !const_ok_for_arm (~INTVAL (operands[1])))
6600 /* Writing a constant to memory needs a scratch, which should
6601 be handled with SECONDARY_RELOADs. */
6602 gcc_assert (REG_P (operands[0]));
6604 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6605 emit_insn (gen_movsi (operands[0], operands[1]));
6609 else if (TARGET_THUMB2)
6611 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6612 if (can_create_pseudo_p ())
6614 if (!REG_P (operands[0]))
6615 operands[1] = force_reg (HImode, operands[1]);
6616 /* Zero extend a constant, and keep it in an SImode reg. */
6617 else if (CONST_INT_P (operands[1]))
6619 rtx reg = gen_reg_rtx (SImode);
6620 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6622 emit_insn (gen_movsi (reg, GEN_INT (val)));
6623 operands[1] = gen_lowpart (HImode, reg);
6627 else /* TARGET_THUMB1 */
6629 if (can_create_pseudo_p ())
6631 if (CONST_INT_P (operands[1]))
6633 rtx reg = gen_reg_rtx (SImode);
6635 emit_insn (gen_movsi (reg, operands[1]));
6636 operands[1] = gen_lowpart (HImode, reg);
6639 /* ??? We shouldn't really get invalid addresses here, but this can
6640 happen if we are passed a SP (never OK for HImode/QImode) or
6641 virtual register (also rejected as illegitimate for HImode/QImode)
6642 relative address. */
6643 /* ??? This should perhaps be fixed elsewhere, for instance, in
6644 fixup_stack_1, by checking for other kinds of invalid addresses,
6645 e.g. a bare reference to a virtual register. This may confuse the
6646 alpha though, which must handle this case differently. */
6647 if (MEM_P (operands[0])
6648 && !memory_address_p (GET_MODE (operands[0]),
6649 XEXP (operands[0], 0)))
6651 = replace_equiv_address (operands[0],
6652 copy_to_reg (XEXP (operands[0], 0)));
6654 if (MEM_P (operands[1])
6655 && !memory_address_p (GET_MODE (operands[1]),
6656 XEXP (operands[1], 0)))
6658 = replace_equiv_address (operands[1],
6659 copy_to_reg (XEXP (operands[1], 0)));
6661 if (MEM_P (operands[1]) && optimize > 0)
6663 rtx reg = gen_reg_rtx (SImode);
6665 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6666 operands[1] = gen_lowpart (HImode, reg);
6669 if (MEM_P (operands[0]))
6670 operands[1] = force_reg (HImode, operands[1]);
6672 else if (CONST_INT_P (operands[1])
6673 && !satisfies_constraint_I (operands[1]))
6675 /* Handle loading a large integer during reload. */
6677 /* Writing a constant to memory needs a scratch, which should
6678 be handled with SECONDARY_RELOADs. */
6679 gcc_assert (REG_P (operands[0]));
6681 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6682 emit_insn (gen_movsi (operands[0], operands[1]));
6689 (define_expand "movhi_bytes"
6690 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6692 (zero_extend:SI (match_dup 6)))
6693 (set (match_operand:SI 0 "" "")
6694 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6699 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6701 mem1 = change_address (operands[1], QImode, addr);
6702 mem2 = change_address (operands[1], QImode,
6703 plus_constant (Pmode, addr, 1));
6704 operands[0] = gen_lowpart (SImode, operands[0]);
6706 operands[2] = gen_reg_rtx (SImode);
6707 operands[3] = gen_reg_rtx (SImode);
6710 if (BYTES_BIG_ENDIAN)
6712 operands[4] = operands[2];
6713 operands[5] = operands[3];
6717 operands[4] = operands[3];
6718 operands[5] = operands[2];
6723 (define_expand "movhi_bigend"
6725 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6728 (ashiftrt:SI (match_dup 2) (const_int 16)))
6729 (set (match_operand:HI 0 "s_register_operand" "")
6733 operands[2] = gen_reg_rtx (SImode);
6734 operands[3] = gen_reg_rtx (SImode);
6735 operands[4] = gen_lowpart (HImode, operands[3]);
6739 ;; Pattern to recognize insn generated default case above
6740 (define_insn "*movhi_insn_arch4"
6741 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6742 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6744 && arm_arch4 && !TARGET_HARD_FLOAT
6745 && (register_operand (operands[0], HImode)
6746 || register_operand (operands[1], HImode))"
6748 mov%?\\t%0, %1\\t%@ movhi
6749 mvn%?\\t%0, #%B1\\t%@ movhi
6750 movw%?\\t%0, %L1\\t%@ movhi
6751 strh%?\\t%1, %0\\t%@ movhi
6752 ldrh%?\\t%0, %1\\t%@ movhi"
6753 [(set_attr "predicable" "yes")
6754 (set_attr "pool_range" "*,*,*,*,256")
6755 (set_attr "neg_pool_range" "*,*,*,*,244")
6756 (set_attr "arch" "*,*,v6t2,*,*")
6757 (set_attr_alternative "type"
6758 [(if_then_else (match_operand 1 "const_int_operand" "")
6759 (const_string "mov_imm" )
6760 (const_string "mov_reg"))
6761 (const_string "mvn_imm")
6762 (const_string "mov_imm")
6763 (const_string "store_4")
6764 (const_string "load_4")])]
6767 (define_insn "*movhi_bytes"
6768 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6769 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6770 "TARGET_ARM && !TARGET_HARD_FLOAT"
6772 mov%?\\t%0, %1\\t%@ movhi
6773 mov%?\\t%0, %1\\t%@ movhi
6774 mvn%?\\t%0, #%B1\\t%@ movhi"
6775 [(set_attr "predicable" "yes")
6776 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6779 ;; We use a DImode scratch because we may occasionally need an additional
6780 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6781 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6782 (define_expand "reload_outhi"
6783 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6784 (match_operand:HI 1 "s_register_operand" "r")
6785 (match_operand:DI 2 "s_register_operand" "=&l")])]
6788 arm_reload_out_hi (operands);
6790 thumb_reload_out_hi (operands);
6795 (define_expand "reload_inhi"
6796 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6797 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6798 (match_operand:DI 2 "s_register_operand" "=&r")])]
6802 arm_reload_in_hi (operands);
6804 thumb_reload_out_hi (operands);
6808 (define_expand "movqi"
6809 [(set (match_operand:QI 0 "general_operand" "")
6810 (match_operand:QI 1 "general_operand" ""))]
6813 /* Everything except mem = const or mem = mem can be done easily */
6815 if (can_create_pseudo_p ())
6817 if (CONST_INT_P (operands[1]))
6819 rtx reg = gen_reg_rtx (SImode);
6821 /* For thumb we want an unsigned immediate, then we are more likely
6822 to be able to use a movs insn. */
6824 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6826 emit_insn (gen_movsi (reg, operands[1]));
6827 operands[1] = gen_lowpart (QImode, reg);
6832 /* ??? We shouldn't really get invalid addresses here, but this can
6833 happen if we are passed a SP (never OK for HImode/QImode) or
6834 virtual register (also rejected as illegitimate for HImode/QImode)
6835 relative address. */
6836 /* ??? This should perhaps be fixed elsewhere, for instance, in
6837 fixup_stack_1, by checking for other kinds of invalid addresses,
6838 e.g. a bare reference to a virtual register. This may confuse the
6839 alpha though, which must handle this case differently. */
6840 if (MEM_P (operands[0])
6841 && !memory_address_p (GET_MODE (operands[0]),
6842 XEXP (operands[0], 0)))
6844 = replace_equiv_address (operands[0],
6845 copy_to_reg (XEXP (operands[0], 0)));
6846 if (MEM_P (operands[1])
6847 && !memory_address_p (GET_MODE (operands[1]),
6848 XEXP (operands[1], 0)))
6850 = replace_equiv_address (operands[1],
6851 copy_to_reg (XEXP (operands[1], 0)));
6854 if (MEM_P (operands[1]) && optimize > 0)
6856 rtx reg = gen_reg_rtx (SImode);
6858 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6859 operands[1] = gen_lowpart (QImode, reg);
6862 if (MEM_P (operands[0]))
6863 operands[1] = force_reg (QImode, operands[1]);
6865 else if (TARGET_THUMB
6866 && CONST_INT_P (operands[1])
6867 && !satisfies_constraint_I (operands[1]))
6869 /* Handle loading a large integer during reload. */
6871 /* Writing a constant to memory needs a scratch, which should
6872 be handled with SECONDARY_RELOADs. */
6873 gcc_assert (REG_P (operands[0]));
6875 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6876 emit_insn (gen_movsi (operands[0], operands[1]));
6882 (define_insn "*arm_movqi_insn"
6883 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6884 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6886 && ( register_operand (operands[0], QImode)
6887 || register_operand (operands[1], QImode))"
6898 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6899 (set_attr "predicable" "yes")
6900 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6901 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6902 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6906 (define_expand "movhf"
6907 [(set (match_operand:HF 0 "general_operand" "")
6908 (match_operand:HF 1 "general_operand" ""))]
6913 if (MEM_P (operands[0]))
6914 operands[1] = force_reg (HFmode, operands[1]);
6916 else /* TARGET_THUMB1 */
6918 if (can_create_pseudo_p ())
6920 if (!REG_P (operands[0]))
6921 operands[1] = force_reg (HFmode, operands[1]);
6927 (define_insn "*arm32_movhf"
6928 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6929 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6930 "TARGET_32BIT && !TARGET_HARD_FLOAT
6931 && ( s_register_operand (operands[0], HFmode)
6932 || s_register_operand (operands[1], HFmode))"
6934 switch (which_alternative)
6936 case 0: /* ARM register from memory */
6937 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6938 case 1: /* memory from ARM register */
6939 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6940 case 2: /* ARM register from ARM register */
6941 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6942 case 3: /* ARM register from constant */
6947 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6949 ops[0] = operands[0];
6950 ops[1] = GEN_INT (bits);
6951 ops[2] = GEN_INT (bits & 0xff00);
6952 ops[3] = GEN_INT (bits & 0x00ff);
6954 if (arm_arch_thumb2)
6955 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6957 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6964 [(set_attr "conds" "unconditional")
6965 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6966 (set_attr "length" "4,4,4,8")
6967 (set_attr "predicable" "yes")
6968 (set_attr "predicable_short_it" "no")]
6971 (define_expand "movsf"
6972 [(set (match_operand:SF 0 "general_operand" "")
6973 (match_operand:SF 1 "general_operand" ""))]
6978 if (MEM_P (operands[0]))
6979 operands[1] = force_reg (SFmode, operands[1]);
6981 else /* TARGET_THUMB1 */
6983 if (can_create_pseudo_p ())
6985 if (!REG_P (operands[0]))
6986 operands[1] = force_reg (SFmode, operands[1]);
6992 ;; Transform a floating-point move of a constant into a core register into
6993 ;; an SImode operation.
6995 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6996 (match_operand:SF 1 "immediate_operand" ""))]
6999 && CONST_DOUBLE_P (operands[1])"
7000 [(set (match_dup 2) (match_dup 3))]
7002 operands[2] = gen_lowpart (SImode, operands[0]);
7003 operands[3] = gen_lowpart (SImode, operands[1]);
7004 if (operands[2] == 0 || operands[3] == 0)
7009 (define_insn "*arm_movsf_soft_insn"
7010 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7011 (match_operand:SF 1 "general_operand" "r,mE,r"))]
7013 && TARGET_SOFT_FLOAT
7014 && (!MEM_P (operands[0])
7015 || register_operand (operands[1], SFmode))"
7018 ldr%?\\t%0, %1\\t%@ float
7019 str%?\\t%1, %0\\t%@ float"
7020 [(set_attr "predicable" "yes")
7021 (set_attr "predicable_short_it" "no")
7022 (set_attr "type" "mov_reg,load_4,store_4")
7023 (set_attr "arm_pool_range" "*,4096,*")
7024 (set_attr "thumb2_pool_range" "*,4094,*")
7025 (set_attr "arm_neg_pool_range" "*,4084,*")
7026 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7029 (define_expand "movdf"
7030 [(set (match_operand:DF 0 "general_operand" "")
7031 (match_operand:DF 1 "general_operand" ""))]
7036 if (MEM_P (operands[0]))
7037 operands[1] = force_reg (DFmode, operands[1]);
7039 else /* TARGET_THUMB */
7041 if (can_create_pseudo_p ())
7043 if (!REG_P (operands[0]))
7044 operands[1] = force_reg (DFmode, operands[1]);
7050 ;; Reloading a df mode value stored in integer regs to memory can require a
7052 (define_expand "reload_outdf"
7053 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7054 (match_operand:DF 1 "s_register_operand" "r")
7055 (match_operand:SI 2 "s_register_operand" "=&r")]
7059 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7062 operands[2] = XEXP (operands[0], 0);
7063 else if (code == POST_INC || code == PRE_DEC)
7065 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7066 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7067 emit_insn (gen_movdi (operands[0], operands[1]));
7070 else if (code == PRE_INC)
7072 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7074 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7077 else if (code == POST_DEC)
7078 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7080 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7081 XEXP (XEXP (operands[0], 0), 1)));
7083 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7086 if (code == POST_DEC)
7087 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7093 (define_insn "*movdf_soft_insn"
7094 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7095 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7096 "TARGET_32BIT && TARGET_SOFT_FLOAT
7097 && ( register_operand (operands[0], DFmode)
7098 || register_operand (operands[1], DFmode))"
7100 switch (which_alternative)
7107 return output_move_double (operands, true, NULL);
7110 [(set_attr "length" "8,12,16,8,8")
7111 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7112 (set_attr "arm_pool_range" "*,*,*,1020,*")
7113 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7114 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7115 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7119 ;; load- and store-multiple insns
7120 ;; The arm can load/store any set of registers, provided that they are in
7121 ;; ascending order, but these expanders assume a contiguous set.
7123 (define_expand "load_multiple"
7124 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7125 (match_operand:SI 1 "" ""))
7126 (use (match_operand:SI 2 "" ""))])]
7129 HOST_WIDE_INT offset = 0;
7131 /* Support only fixed point registers. */
7132 if (!CONST_INT_P (operands[2])
7133 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7134 || INTVAL (operands[2]) < 2
7135 || !MEM_P (operands[1])
7136 || !REG_P (operands[0])
7137 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7138 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7142 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7143 INTVAL (operands[2]),
7144 force_reg (SImode, XEXP (operands[1], 0)),
7145 FALSE, operands[1], &offset);
7148 (define_expand "store_multiple"
7149 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7150 (match_operand:SI 1 "" ""))
7151 (use (match_operand:SI 2 "" ""))])]
7154 HOST_WIDE_INT offset = 0;
7156 /* Support only fixed point registers. */
7157 if (!CONST_INT_P (operands[2])
7158 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7159 || INTVAL (operands[2]) < 2
7160 || !REG_P (operands[1])
7161 || !MEM_P (operands[0])
7162 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7163 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7167 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7168 INTVAL (operands[2]),
7169 force_reg (SImode, XEXP (operands[0], 0)),
7170 FALSE, operands[0], &offset);
7174 (define_expand "setmemsi"
7175 [(match_operand:BLK 0 "general_operand" "")
7176 (match_operand:SI 1 "const_int_operand" "")
7177 (match_operand:SI 2 "const_int_operand" "")
7178 (match_operand:SI 3 "const_int_operand" "")]
7181 if (arm_gen_setmem (operands))
7188 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7189 ;; We could let this apply for blocks of less than this, but it clobbers so
7190 ;; many registers that there is then probably a better way.
7192 (define_expand "movmemqi"
7193 [(match_operand:BLK 0 "general_operand" "")
7194 (match_operand:BLK 1 "general_operand" "")
7195 (match_operand:SI 2 "const_int_operand" "")
7196 (match_operand:SI 3 "const_int_operand" "")]
7201 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7202 && !optimize_function_for_size_p (cfun))
7204 if (gen_movmem_ldrd_strd (operands))
7209 if (arm_gen_movmemqi (operands))
7213 else /* TARGET_THUMB1 */
7215 if ( INTVAL (operands[3]) != 4
7216 || INTVAL (operands[2]) > 48)
7219 thumb_expand_movmemqi (operands);
7226 ;; Compare & branch insns
7227 ;; The range calculations are based as follows:
7228 ;; For forward branches, the address calculation returns the address of
7229 ;; the next instruction. This is 2 beyond the branch instruction.
7230 ;; For backward branches, the address calculation returns the address of
7231 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7232 ;; instruction for the shortest sequence, and 4 before the branch instruction
7233 ;; if we have to jump around an unconditional branch.
7234 ;; To the basic branch range the PC offset must be added (this is +4).
7235 ;; So for forward branches we have
7236 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7237 ;; And for backward branches we have
7238 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7240 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7241 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7243 (define_expand "cbranchsi4"
7244 [(set (pc) (if_then_else
7245 (match_operator 0 "expandable_comparison_operator"
7246 [(match_operand:SI 1 "s_register_operand" "")
7247 (match_operand:SI 2 "nonmemory_operand" "")])
7248 (label_ref (match_operand 3 "" ""))
7254 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7256 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7260 if (thumb1_cmpneg_operand (operands[2], SImode))
7262 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7263 operands[3], operands[0]));
7266 if (!thumb1_cmp_operand (operands[2], SImode))
7267 operands[2] = force_reg (SImode, operands[2]);
7270 (define_expand "cbranchsf4"
7271 [(set (pc) (if_then_else
7272 (match_operator 0 "expandable_comparison_operator"
7273 [(match_operand:SF 1 "s_register_operand" "")
7274 (match_operand:SF 2 "vfp_compare_operand" "")])
7275 (label_ref (match_operand 3 "" ""))
7277 "TARGET_32BIT && TARGET_HARD_FLOAT"
7278 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7279 operands[3])); DONE;"
7282 (define_expand "cbranchdf4"
7283 [(set (pc) (if_then_else
7284 (match_operator 0 "expandable_comparison_operator"
7285 [(match_operand:DF 1 "s_register_operand" "")
7286 (match_operand:DF 2 "vfp_compare_operand" "")])
7287 (label_ref (match_operand 3 "" ""))
7289 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7290 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7291 operands[3])); DONE;"
7294 (define_expand "cbranchdi4"
7295 [(set (pc) (if_then_else
7296 (match_operator 0 "expandable_comparison_operator"
7297 [(match_operand:DI 1 "s_register_operand" "")
7298 (match_operand:DI 2 "cmpdi_operand" "")])
7299 (label_ref (match_operand 3 "" ""))
7303 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7305 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7311 ;; Comparison and test insns
7313 (define_insn "*arm_cmpsi_insn"
7314 [(set (reg:CC CC_REGNUM)
7315 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7316 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7324 [(set_attr "conds" "set")
7325 (set_attr "arch" "t2,t2,any,any,any")
7326 (set_attr "length" "2,2,4,4,4")
7327 (set_attr "predicable" "yes")
7328 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7329 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7332 (define_insn "*cmpsi_shiftsi"
7333 [(set (reg:CC CC_REGNUM)
7334 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7335 (match_operator:SI 3 "shift_operator"
7336 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7337 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7340 [(set_attr "conds" "set")
7341 (set_attr "shift" "1")
7342 (set_attr "arch" "32,a,a")
7343 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7345 (define_insn "*cmpsi_shiftsi_swp"
7346 [(set (reg:CC_SWP CC_REGNUM)
7347 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7348 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7349 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7350 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7353 [(set_attr "conds" "set")
7354 (set_attr "shift" "1")
7355 (set_attr "arch" "32,a,a")
7356 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7358 (define_insn "*arm_cmpsi_negshiftsi_si"
7359 [(set (reg:CC_Z CC_REGNUM)
7361 (neg:SI (match_operator:SI 1 "shift_operator"
7362 [(match_operand:SI 2 "s_register_operand" "r")
7363 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7364 (match_operand:SI 0 "s_register_operand" "r")))]
7367 [(set_attr "conds" "set")
7368 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7369 (const_string "alus_shift_imm")
7370 (const_string "alus_shift_reg")))
7371 (set_attr "predicable" "yes")]
7374 ;; DImode comparisons. The generic code generates branches that
7375 ;; if-conversion can not reduce to a conditional compare, so we do
7378 (define_insn_and_split "*arm_cmpdi_insn"
7379 [(set (reg:CC_NCV CC_REGNUM)
7380 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7381 (match_operand:DI 1 "arm_di_operand" "rDi")))
7382 (clobber (match_scratch:SI 2 "=r"))]
7384 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7385 "&& reload_completed"
7386 [(set (reg:CC CC_REGNUM)
7387 (compare:CC (match_dup 0) (match_dup 1)))
7388 (parallel [(set (reg:CC CC_REGNUM)
7389 (compare:CC (match_dup 3) (match_dup 4)))
7391 (minus:SI (match_dup 5)
7392 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7394 operands[3] = gen_highpart (SImode, operands[0]);
7395 operands[0] = gen_lowpart (SImode, operands[0]);
7396 if (CONST_INT_P (operands[1]))
7398 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7401 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7405 operands[4] = gen_highpart (SImode, operands[1]);
7406 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7408 operands[1] = gen_lowpart (SImode, operands[1]);
7409 operands[2] = gen_lowpart (SImode, operands[2]);
7411 [(set_attr "conds" "set")
7412 (set_attr "length" "8")
7413 (set_attr "type" "multiple")]
7416 (define_insn_and_split "*arm_cmpdi_unsigned"
7417 [(set (reg:CC_CZ CC_REGNUM)
7418 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7419 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7422 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7423 "&& reload_completed"
7424 [(set (reg:CC CC_REGNUM)
7425 (compare:CC (match_dup 2) (match_dup 3)))
7426 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7427 (set (reg:CC CC_REGNUM)
7428 (compare:CC (match_dup 0) (match_dup 1))))]
7430 operands[2] = gen_highpart (SImode, operands[0]);
7431 operands[0] = gen_lowpart (SImode, operands[0]);
7432 if (CONST_INT_P (operands[1]))
7433 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7435 operands[3] = gen_highpart (SImode, operands[1]);
7436 operands[1] = gen_lowpart (SImode, operands[1]);
7438 [(set_attr "conds" "set")
7439 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7440 (set_attr "arch" "t2,t2,t2,a")
7441 (set_attr "length" "6,6,10,8")
7442 (set_attr "type" "multiple")]
7445 (define_insn "*arm_cmpdi_zero"
7446 [(set (reg:CC_Z CC_REGNUM)
7447 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7449 (clobber (match_scratch:SI 1 "=r"))]
7451 "orrs%?\\t%1, %Q0, %R0"
7452 [(set_attr "conds" "set")
7453 (set_attr "type" "logics_reg")]
7456 ; This insn allows redundant compares to be removed by cse, nothing should
7457 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7458 ; is deleted later on. The match_dup will match the mode here, so that
7459 ; mode changes of the condition codes aren't lost by this even though we don't
7460 ; specify what they are.
7462 (define_insn "*deleted_compare"
7463 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7465 "\\t%@ deleted compare"
7466 [(set_attr "conds" "set")
7467 (set_attr "length" "0")
7468 (set_attr "type" "no_insn")]
7472 ;; Conditional branch insns
7474 (define_expand "cbranch_cc"
7476 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7477 (match_operand 2 "" "")])
7478 (label_ref (match_operand 3 "" ""))
7481 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7482 operands[1], operands[2], NULL_RTX);
7483 operands[2] = const0_rtx;"
7487 ;; Patterns to match conditional branch insns.
7490 (define_insn "arm_cond_branch"
7492 (if_then_else (match_operator 1 "arm_comparison_operator"
7493 [(match_operand 2 "cc_register" "") (const_int 0)])
7494 (label_ref (match_operand 0 "" ""))
7498 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7500 arm_ccfsm_state += 2;
7503 return \"b%d1\\t%l0\";
7505 [(set_attr "conds" "use")
7506 (set_attr "type" "branch")
7507 (set (attr "length")
7509 (and (match_test "TARGET_THUMB2")
7510 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7511 (le (minus (match_dup 0) (pc)) (const_int 256))))
7516 (define_insn "*arm_cond_branch_reversed"
7518 (if_then_else (match_operator 1 "arm_comparison_operator"
7519 [(match_operand 2 "cc_register" "") (const_int 0)])
7521 (label_ref (match_operand 0 "" ""))))]
7524 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7526 arm_ccfsm_state += 2;
7529 return \"b%D1\\t%l0\";
7531 [(set_attr "conds" "use")
7532 (set_attr "type" "branch")
7533 (set (attr "length")
7535 (and (match_test "TARGET_THUMB2")
7536 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7537 (le (minus (match_dup 0) (pc)) (const_int 256))))
7546 (define_expand "cstore_cc"
7547 [(set (match_operand:SI 0 "s_register_operand" "")
7548 (match_operator:SI 1 "" [(match_operand 2 "" "")
7549 (match_operand 3 "" "")]))]
7551 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7552 operands[2], operands[3], NULL_RTX);
7553 operands[3] = const0_rtx;"
7556 (define_insn_and_split "*mov_scc"
7557 [(set (match_operand:SI 0 "s_register_operand" "=r")
7558 (match_operator:SI 1 "arm_comparison_operator_mode"
7559 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7561 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7564 (if_then_else:SI (match_dup 1)
7568 [(set_attr "conds" "use")
7569 (set_attr "length" "8")
7570 (set_attr "type" "multiple")]
7573 (define_insn_and_split "*mov_negscc"
7574 [(set (match_operand:SI 0 "s_register_operand" "=r")
7575 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7576 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7578 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7581 (if_then_else:SI (match_dup 1)
7585 operands[3] = GEN_INT (~0);
7587 [(set_attr "conds" "use")
7588 (set_attr "length" "8")
7589 (set_attr "type" "multiple")]
7592 (define_insn_and_split "*mov_notscc"
7593 [(set (match_operand:SI 0 "s_register_operand" "=r")
7594 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7595 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7597 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7600 (if_then_else:SI (match_dup 1)
7604 operands[3] = GEN_INT (~1);
7605 operands[4] = GEN_INT (~0);
7607 [(set_attr "conds" "use")
7608 (set_attr "length" "8")
7609 (set_attr "type" "multiple")]
7612 (define_expand "cstoresi4"
7613 [(set (match_operand:SI 0 "s_register_operand" "")
7614 (match_operator:SI 1 "expandable_comparison_operator"
7615 [(match_operand:SI 2 "s_register_operand" "")
7616 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7617 "TARGET_32BIT || TARGET_THUMB1"
7619 rtx op3, scratch, scratch2;
7623 if (!arm_add_operand (operands[3], SImode))
7624 operands[3] = force_reg (SImode, operands[3]);
7625 emit_insn (gen_cstore_cc (operands[0], operands[1],
7626 operands[2], operands[3]));
7630 if (operands[3] == const0_rtx)
7632 switch (GET_CODE (operands[1]))
7635 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7639 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7643 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7644 NULL_RTX, 0, OPTAB_WIDEN);
7645 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7646 NULL_RTX, 0, OPTAB_WIDEN);
7647 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7648 operands[0], 1, OPTAB_WIDEN);
7652 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7654 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7655 NULL_RTX, 1, OPTAB_WIDEN);
7659 scratch = expand_binop (SImode, ashr_optab, operands[2],
7660 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7661 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7662 NULL_RTX, 0, OPTAB_WIDEN);
7663 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7667 /* LT is handled by generic code. No need for unsigned with 0. */
7674 switch (GET_CODE (operands[1]))
7677 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7678 NULL_RTX, 0, OPTAB_WIDEN);
7679 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7683 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7684 NULL_RTX, 0, OPTAB_WIDEN);
7685 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7689 op3 = force_reg (SImode, operands[3]);
7691 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7692 NULL_RTX, 1, OPTAB_WIDEN);
7693 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7694 NULL_RTX, 0, OPTAB_WIDEN);
7695 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7701 if (!thumb1_cmp_operand (op3, SImode))
7702 op3 = force_reg (SImode, op3);
7703 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7704 NULL_RTX, 0, OPTAB_WIDEN);
7705 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7706 NULL_RTX, 1, OPTAB_WIDEN);
7707 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7712 op3 = force_reg (SImode, operands[3]);
7713 scratch = force_reg (SImode, const0_rtx);
7714 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7720 if (!thumb1_cmp_operand (op3, SImode))
7721 op3 = force_reg (SImode, op3);
7722 scratch = force_reg (SImode, const0_rtx);
7723 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7729 if (!thumb1_cmp_operand (op3, SImode))
7730 op3 = force_reg (SImode, op3);
7731 scratch = gen_reg_rtx (SImode);
7732 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7736 op3 = force_reg (SImode, operands[3]);
7737 scratch = gen_reg_rtx (SImode);
7738 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7741 /* No good sequences for GT, LT. */
7748 (define_expand "cstorehf4"
7749 [(set (match_operand:SI 0 "s_register_operand")
7750 (match_operator:SI 1 "expandable_comparison_operator"
7751 [(match_operand:HF 2 "s_register_operand")
7752 (match_operand:HF 3 "vfp_compare_operand")]))]
7753 "TARGET_VFP_FP16INST"
7755 if (!arm_validize_comparison (&operands[1],
7760 emit_insn (gen_cstore_cc (operands[0], operands[1],
7761 operands[2], operands[3]));
7766 (define_expand "cstoresf4"
7767 [(set (match_operand:SI 0 "s_register_operand" "")
7768 (match_operator:SI 1 "expandable_comparison_operator"
7769 [(match_operand:SF 2 "s_register_operand" "")
7770 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7771 "TARGET_32BIT && TARGET_HARD_FLOAT"
7772 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7773 operands[2], operands[3])); DONE;"
7776 (define_expand "cstoredf4"
7777 [(set (match_operand:SI 0 "s_register_operand" "")
7778 (match_operator:SI 1 "expandable_comparison_operator"
7779 [(match_operand:DF 2 "s_register_operand" "")
7780 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7781 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7782 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7783 operands[2], operands[3])); DONE;"
7786 (define_expand "cstoredi4"
7787 [(set (match_operand:SI 0 "s_register_operand" "")
7788 (match_operator:SI 1 "expandable_comparison_operator"
7789 [(match_operand:DI 2 "s_register_operand" "")
7790 (match_operand:DI 3 "cmpdi_operand" "")]))]
7793 if (!arm_validize_comparison (&operands[1],
7797 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7804 ;; Conditional move insns
7806 (define_expand "movsicc"
7807 [(set (match_operand:SI 0 "s_register_operand" "")
7808 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7809 (match_operand:SI 2 "arm_not_operand" "")
7810 (match_operand:SI 3 "arm_not_operand" "")))]
7817 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7818 &XEXP (operands[1], 1)))
7821 code = GET_CODE (operands[1]);
7822 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7823 XEXP (operands[1], 1), NULL_RTX);
7824 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7828 (define_expand "movhfcc"
7829 [(set (match_operand:HF 0 "s_register_operand")
7830 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7831 (match_operand:HF 2 "s_register_operand")
7832 (match_operand:HF 3 "s_register_operand")))]
7833 "TARGET_VFP_FP16INST"
7836 enum rtx_code code = GET_CODE (operands[1]);
7839 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7840 &XEXP (operands[1], 1)))
7843 code = GET_CODE (operands[1]);
7844 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7845 XEXP (operands[1], 1), NULL_RTX);
7846 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7850 (define_expand "movsfcc"
7851 [(set (match_operand:SF 0 "s_register_operand" "")
7852 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7853 (match_operand:SF 2 "s_register_operand" "")
7854 (match_operand:SF 3 "s_register_operand" "")))]
7855 "TARGET_32BIT && TARGET_HARD_FLOAT"
7858 enum rtx_code code = GET_CODE (operands[1]);
7861 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7862 &XEXP (operands[1], 1)))
7865 code = GET_CODE (operands[1]);
7866 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7867 XEXP (operands[1], 1), NULL_RTX);
7868 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7872 (define_expand "movdfcc"
7873 [(set (match_operand:DF 0 "s_register_operand" "")
7874 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7875 (match_operand:DF 2 "s_register_operand" "")
7876 (match_operand:DF 3 "s_register_operand" "")))]
7877 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7880 enum rtx_code code = GET_CODE (operands[1]);
7883 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7884 &XEXP (operands[1], 1)))
7886 code = GET_CODE (operands[1]);
7887 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7888 XEXP (operands[1], 1), NULL_RTX);
7889 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7893 (define_insn "*cmov<mode>"
7894 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7895 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7896 [(match_operand 2 "cc_register" "") (const_int 0)])
7897 (match_operand:SDF 3 "s_register_operand"
7899 (match_operand:SDF 4 "s_register_operand"
7900 "<F_constraint>")))]
7901 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7904 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7911 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7916 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7922 [(set_attr "conds" "use")
7923 (set_attr "type" "fcsel")]
7926 (define_insn "*cmovhf"
7927 [(set (match_operand:HF 0 "s_register_operand" "=t")
7928 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7929 [(match_operand 2 "cc_register" "") (const_int 0)])
7930 (match_operand:HF 3 "s_register_operand" "t")
7931 (match_operand:HF 4 "s_register_operand" "t")))]
7932 "TARGET_VFP_FP16INST"
7935 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7942 return \"vsel%d1.f16\\t%0, %3, %4\";
7947 return \"vsel%D1.f16\\t%0, %4, %3\";
7953 [(set_attr "conds" "use")
7954 (set_attr "type" "fcsel")]
7957 (define_insn_and_split "*movsicc_insn"
7958 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7960 (match_operator 3 "arm_comparison_operator"
7961 [(match_operand 4 "cc_register" "") (const_int 0)])
7962 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7963 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7974 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7975 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7976 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7977 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7978 "&& reload_completed"
7981 enum rtx_code rev_code;
7985 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7987 gen_rtx_SET (operands[0], operands[1])));
7989 rev_code = GET_CODE (operands[3]);
7990 mode = GET_MODE (operands[4]);
7991 if (mode == CCFPmode || mode == CCFPEmode)
7992 rev_code = reverse_condition_maybe_unordered (rev_code);
7994 rev_code = reverse_condition (rev_code);
7996 rev_cond = gen_rtx_fmt_ee (rev_code,
8000 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8002 gen_rtx_SET (operands[0], operands[2])));
8005 [(set_attr "length" "4,4,4,4,8,8,8,8")
8006 (set_attr "conds" "use")
8007 (set_attr_alternative "type"
8008 [(if_then_else (match_operand 2 "const_int_operand" "")
8009 (const_string "mov_imm")
8010 (const_string "mov_reg"))
8011 (const_string "mvn_imm")
8012 (if_then_else (match_operand 1 "const_int_operand" "")
8013 (const_string "mov_imm")
8014 (const_string "mov_reg"))
8015 (const_string "mvn_imm")
8016 (const_string "multiple")
8017 (const_string "multiple")
8018 (const_string "multiple")
8019 (const_string "multiple")])]
8022 (define_insn "*movsfcc_soft_insn"
8023 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8024 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8025 [(match_operand 4 "cc_register" "") (const_int 0)])
8026 (match_operand:SF 1 "s_register_operand" "0,r")
8027 (match_operand:SF 2 "s_register_operand" "r,0")))]
8028 "TARGET_ARM && TARGET_SOFT_FLOAT"
8032 [(set_attr "conds" "use")
8033 (set_attr "type" "mov_reg")]
8037 ;; Jump and linkage insns
8039 (define_expand "jump"
8041 (label_ref (match_operand 0 "" "")))]
8046 (define_insn "*arm_jump"
8048 (label_ref (match_operand 0 "" "")))]
8052 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8054 arm_ccfsm_state += 2;
8057 return \"b%?\\t%l0\";
8060 [(set_attr "predicable" "yes")
8061 (set (attr "length")
8063 (and (match_test "TARGET_THUMB2")
8064 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8065 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8068 (set_attr "type" "branch")]
8071 (define_expand "call"
8072 [(parallel [(call (match_operand 0 "memory_operand" "")
8073 (match_operand 1 "general_operand" ""))
8074 (use (match_operand 2 "" ""))
8075 (clobber (reg:SI LR_REGNUM))])]
8080 tree addr = MEM_EXPR (operands[0]);
8082 /* In an untyped call, we can get NULL for operand 2. */
8083 if (operands[2] == NULL_RTX)
8084 operands[2] = const0_rtx;
8086 /* Decide if we should generate indirect calls by loading the
8087 32-bit address of the callee into a register before performing the
8089 callee = XEXP (operands[0], 0);
8090 if (GET_CODE (callee) == SYMBOL_REF
8091 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8093 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8095 if (detect_cmse_nonsecure_call (addr))
8097 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8099 emit_call_insn (pat);
8103 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8104 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8110 (define_expand "call_internal"
8111 [(parallel [(call (match_operand 0 "memory_operand" "")
8112 (match_operand 1 "general_operand" ""))
8113 (use (match_operand 2 "" ""))
8114 (clobber (reg:SI LR_REGNUM))])])
8116 (define_expand "nonsecure_call_internal"
8117 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8118 UNSPEC_NONSECURE_MEM)
8119 (match_operand 1 "general_operand" ""))
8120 (use (match_operand 2 "" ""))
8121 (clobber (reg:SI LR_REGNUM))
8122 (clobber (reg:SI 4))])]
8127 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8128 gen_rtx_REG (SImode, 4),
8131 operands[0] = replace_equiv_address (operands[0], tmp);
8134 (define_insn "*call_reg_armv5"
8135 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8136 (match_operand 1 "" ""))
8137 (use (match_operand 2 "" ""))
8138 (clobber (reg:SI LR_REGNUM))]
8139 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8141 [(set_attr "type" "call")]
8144 (define_insn "*call_reg_arm"
8145 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8146 (match_operand 1 "" ""))
8147 (use (match_operand 2 "" ""))
8148 (clobber (reg:SI LR_REGNUM))]
8149 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8151 return output_call (operands);
8153 ;; length is worst case, normally it is only two
8154 [(set_attr "length" "12")
8155 (set_attr "type" "call")]
8159 (define_expand "call_value"
8160 [(parallel [(set (match_operand 0 "" "")
8161 (call (match_operand 1 "memory_operand" "")
8162 (match_operand 2 "general_operand" "")))
8163 (use (match_operand 3 "" ""))
8164 (clobber (reg:SI LR_REGNUM))])]
8169 tree addr = MEM_EXPR (operands[1]);
8171 /* In an untyped call, we can get NULL for operand 2. */
8172 if (operands[3] == 0)
8173 operands[3] = const0_rtx;
8175 /* Decide if we should generate indirect calls by loading the
8176 32-bit address of the callee into a register before performing the
8178 callee = XEXP (operands[1], 0);
8179 if (GET_CODE (callee) == SYMBOL_REF
8180 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8182 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8184 if (detect_cmse_nonsecure_call (addr))
8186 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8187 operands[2], operands[3]);
8188 emit_call_insn (pat);
8192 pat = gen_call_value_internal (operands[0], operands[1],
8193 operands[2], operands[3]);
8194 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8200 (define_expand "call_value_internal"
8201 [(parallel [(set (match_operand 0 "" "")
8202 (call (match_operand 1 "memory_operand" "")
8203 (match_operand 2 "general_operand" "")))
8204 (use (match_operand 3 "" ""))
8205 (clobber (reg:SI LR_REGNUM))])])
8207 (define_expand "nonsecure_call_value_internal"
8208 [(parallel [(set (match_operand 0 "" "")
8209 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8210 UNSPEC_NONSECURE_MEM)
8211 (match_operand 2 "general_operand" "")))
8212 (use (match_operand 3 "" ""))
8213 (clobber (reg:SI LR_REGNUM))
8214 (clobber (reg:SI 4))])]
8219 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8220 gen_rtx_REG (SImode, 4),
8223 operands[1] = replace_equiv_address (operands[1], tmp);
8226 (define_insn "*call_value_reg_armv5"
8227 [(set (match_operand 0 "" "")
8228 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8229 (match_operand 2 "" "")))
8230 (use (match_operand 3 "" ""))
8231 (clobber (reg:SI LR_REGNUM))]
8232 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8234 [(set_attr "type" "call")]
8237 (define_insn "*call_value_reg_arm"
8238 [(set (match_operand 0 "" "")
8239 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8240 (match_operand 2 "" "")))
8241 (use (match_operand 3 "" ""))
8242 (clobber (reg:SI LR_REGNUM))]
8243 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8245 return output_call (&operands[1]);
8247 [(set_attr "length" "12")
8248 (set_attr "type" "call")]
8251 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8252 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8254 (define_insn "*call_symbol"
8255 [(call (mem:SI (match_operand:SI 0 "" ""))
8256 (match_operand 1 "" ""))
8257 (use (match_operand 2 "" ""))
8258 (clobber (reg:SI LR_REGNUM))]
8260 && !SIBLING_CALL_P (insn)
8261 && (GET_CODE (operands[0]) == SYMBOL_REF)
8262 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8265 rtx op = operands[0];
8267 /* Switch mode now when possible. */
8268 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8269 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8270 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8272 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8274 [(set_attr "type" "call")]
8277 (define_insn "*call_value_symbol"
8278 [(set (match_operand 0 "" "")
8279 (call (mem:SI (match_operand:SI 1 "" ""))
8280 (match_operand:SI 2 "" "")))
8281 (use (match_operand 3 "" ""))
8282 (clobber (reg:SI LR_REGNUM))]
8284 && !SIBLING_CALL_P (insn)
8285 && (GET_CODE (operands[1]) == SYMBOL_REF)
8286 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8289 rtx op = operands[1];
8291 /* Switch mode now when possible. */
8292 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8293 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8294 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8296 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8298 [(set_attr "type" "call")]
8301 (define_expand "sibcall_internal"
8302 [(parallel [(call (match_operand 0 "memory_operand" "")
8303 (match_operand 1 "general_operand" ""))
8305 (use (match_operand 2 "" ""))])])
8307 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8308 (define_expand "sibcall"
8309 [(parallel [(call (match_operand 0 "memory_operand" "")
8310 (match_operand 1 "general_operand" ""))
8312 (use (match_operand 2 "" ""))])]
8318 if ((!REG_P (XEXP (operands[0], 0))
8319 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8320 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8321 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8322 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8324 if (operands[2] == NULL_RTX)
8325 operands[2] = const0_rtx;
8327 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8328 arm_emit_call_insn (pat, operands[0], true);
8333 (define_expand "sibcall_value_internal"
8334 [(parallel [(set (match_operand 0 "" "")
8335 (call (match_operand 1 "memory_operand" "")
8336 (match_operand 2 "general_operand" "")))
8338 (use (match_operand 3 "" ""))])])
8340 (define_expand "sibcall_value"
8341 [(parallel [(set (match_operand 0 "" "")
8342 (call (match_operand 1 "memory_operand" "")
8343 (match_operand 2 "general_operand" "")))
8345 (use (match_operand 3 "" ""))])]
8351 if ((!REG_P (XEXP (operands[1], 0))
8352 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8353 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8354 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8355 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8357 if (operands[3] == NULL_RTX)
8358 operands[3] = const0_rtx;
8360 pat = gen_sibcall_value_internal (operands[0], operands[1],
8361 operands[2], operands[3]);
8362 arm_emit_call_insn (pat, operands[1], true);
8367 (define_insn "*sibcall_insn"
8368 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8369 (match_operand 1 "" ""))
8371 (use (match_operand 2 "" ""))]
8372 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8374 if (which_alternative == 1)
8375 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8378 if (arm_arch5 || arm_arch4t)
8379 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8381 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8384 [(set_attr "type" "call")]
8387 (define_insn "*sibcall_value_insn"
8388 [(set (match_operand 0 "" "")
8389 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8390 (match_operand 2 "" "")))
8392 (use (match_operand 3 "" ""))]
8393 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8395 if (which_alternative == 1)
8396 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8399 if (arm_arch5 || arm_arch4t)
8400 return \"bx%?\\t%1\";
8402 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8405 [(set_attr "type" "call")]
8408 (define_expand "<return_str>return"
8410 "(TARGET_ARM || (TARGET_THUMB2
8411 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8412 && !IS_STACKALIGN (arm_current_func_type ())))
8413 <return_cond_false>"
8418 thumb2_expand_return (<return_simple_p>);
8425 ;; Often the return insn will be the same as loading from memory, so set attr
8426 (define_insn "*arm_return"
8428 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8431 if (arm_ccfsm_state == 2)
8433 arm_ccfsm_state += 2;
8436 return output_return_instruction (const_true_rtx, true, false, false);
8438 [(set_attr "type" "load_4")
8439 (set_attr "length" "12")
8440 (set_attr "predicable" "yes")]
8443 (define_insn "*cond_<return_str>return"
8445 (if_then_else (match_operator 0 "arm_comparison_operator"
8446 [(match_operand 1 "cc_register" "") (const_int 0)])
8449 "TARGET_ARM <return_cond_true>"
8452 if (arm_ccfsm_state == 2)
8454 arm_ccfsm_state += 2;
8457 return output_return_instruction (operands[0], true, false,
8460 [(set_attr "conds" "use")
8461 (set_attr "length" "12")
8462 (set_attr "type" "load_4")]
8465 (define_insn "*cond_<return_str>return_inverted"
8467 (if_then_else (match_operator 0 "arm_comparison_operator"
8468 [(match_operand 1 "cc_register" "") (const_int 0)])
8471 "TARGET_ARM <return_cond_true>"
8474 if (arm_ccfsm_state == 2)
8476 arm_ccfsm_state += 2;
8479 return output_return_instruction (operands[0], true, true,
8482 [(set_attr "conds" "use")
8483 (set_attr "length" "12")
8484 (set_attr "type" "load_4")]
8487 (define_insn "*arm_simple_return"
8492 if (arm_ccfsm_state == 2)
8494 arm_ccfsm_state += 2;
8497 return output_return_instruction (const_true_rtx, true, false, true);
8499 [(set_attr "type" "branch")
8500 (set_attr "length" "4")
8501 (set_attr "predicable" "yes")]
8504 ;; Generate a sequence of instructions to determine if the processor is
8505 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8508 (define_expand "return_addr_mask"
8510 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8512 (set (match_operand:SI 0 "s_register_operand" "")
8513 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8515 (const_int 67108860)))] ; 0x03fffffc
8518 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8521 (define_insn "*check_arch2"
8522 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8523 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8526 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8527 [(set_attr "length" "8")
8528 (set_attr "conds" "set")
8529 (set_attr "type" "multiple")]
8532 ;; Call subroutine returning any type.
8534 (define_expand "untyped_call"
8535 [(parallel [(call (match_operand 0 "" "")
8537 (match_operand 1 "" "")
8538 (match_operand 2 "" "")])]
8543 rtx par = gen_rtx_PARALLEL (VOIDmode,
8544 rtvec_alloc (XVECLEN (operands[2], 0)));
8545 rtx addr = gen_reg_rtx (Pmode);
8549 emit_move_insn (addr, XEXP (operands[1], 0));
8550 mem = change_address (operands[1], BLKmode, addr);
8552 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8554 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8556 /* Default code only uses r0 as a return value, but we could
8557 be using anything up to 4 registers. */
8558 if (REGNO (src) == R0_REGNUM)
8559 src = gen_rtx_REG (TImode, R0_REGNUM);
8561 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8563 size += GET_MODE_SIZE (GET_MODE (src));
8566 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8570 for (i = 0; i < XVECLEN (par, 0); i++)
8572 HOST_WIDE_INT offset = 0;
8573 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8576 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8578 mem = change_address (mem, GET_MODE (reg), NULL);
8579 if (REGNO (reg) == R0_REGNUM)
8581 /* On thumb we have to use a write-back instruction. */
8582 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8583 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8584 size = TARGET_ARM ? 16 : 0;
8588 emit_move_insn (mem, reg);
8589 size = GET_MODE_SIZE (GET_MODE (reg));
8593 /* The optimizer does not know that the call sets the function value
8594 registers we stored in the result block. We avoid problems by
8595 claiming that all hard registers are used and clobbered at this
8597 emit_insn (gen_blockage ());
8603 (define_expand "untyped_return"
8604 [(match_operand:BLK 0 "memory_operand" "")
8605 (match_operand 1 "" "")]
8610 rtx addr = gen_reg_rtx (Pmode);
8614 emit_move_insn (addr, XEXP (operands[0], 0));
8615 mem = change_address (operands[0], BLKmode, addr);
8617 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8619 HOST_WIDE_INT offset = 0;
8620 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8623 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8625 mem = change_address (mem, GET_MODE (reg), NULL);
8626 if (REGNO (reg) == R0_REGNUM)
8628 /* On thumb we have to use a write-back instruction. */
8629 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8630 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8631 size = TARGET_ARM ? 16 : 0;
8635 emit_move_insn (reg, mem);
8636 size = GET_MODE_SIZE (GET_MODE (reg));
8640 /* Emit USE insns before the return. */
8641 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8642 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8644 /* Construct the return. */
8645 expand_naked_return ();
8651 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8652 ;; all of memory. This blocks insns from being moved across this point.
8654 (define_insn "blockage"
8655 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8658 [(set_attr "length" "0")
8659 (set_attr "type" "block")]
8662 (define_insn "probe_stack"
8663 [(set (match_operand:SI 0 "memory_operand" "=m")
8664 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8667 [(set_attr "type" "store_4")
8668 (set_attr "predicable" "yes")]
8671 (define_insn "probe_stack_range"
8672 [(set (match_operand:SI 0 "register_operand" "=r")
8673 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8674 (match_operand:SI 2 "register_operand" "r")]
8675 VUNSPEC_PROBE_STACK_RANGE))]
8678 return output_probe_stack_range (operands[0], operands[2]);
8680 [(set_attr "type" "multiple")
8681 (set_attr "conds" "clob")]
8684 (define_expand "casesi"
8685 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8686 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8687 (match_operand:SI 2 "const_int_operand" "") ; total range
8688 (match_operand:SI 3 "" "") ; table label
8689 (match_operand:SI 4 "" "")] ; Out of range label
8690 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8693 enum insn_code code;
8694 if (operands[1] != const0_rtx)
8696 rtx reg = gen_reg_rtx (SImode);
8698 emit_insn (gen_addsi3 (reg, operands[0],
8699 gen_int_mode (-INTVAL (operands[1]),
8705 code = CODE_FOR_arm_casesi_internal;
8706 else if (TARGET_THUMB1)
8707 code = CODE_FOR_thumb1_casesi_internal_pic;
8709 code = CODE_FOR_thumb2_casesi_internal_pic;
8711 code = CODE_FOR_thumb2_casesi_internal;
8713 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8714 operands[2] = force_reg (SImode, operands[2]);
8716 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8717 operands[3], operands[4]));
8722 ;; The USE in this pattern is needed to tell flow analysis that this is
8723 ;; a CASESI insn. It has no other purpose.
8724 (define_insn "arm_casesi_internal"
8725 [(parallel [(set (pc)
8727 (leu (match_operand:SI 0 "s_register_operand" "r")
8728 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8729 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8730 (label_ref (match_operand 2 "" ""))))
8731 (label_ref (match_operand 3 "" ""))))
8732 (clobber (reg:CC CC_REGNUM))
8733 (use (label_ref (match_dup 2)))])]
8737 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8738 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8740 [(set_attr "conds" "clob")
8741 (set_attr "length" "12")
8742 (set_attr "type" "multiple")]
8745 (define_expand "indirect_jump"
8747 (match_operand:SI 0 "s_register_operand" ""))]
8750 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8751 address and use bx. */
8755 tmp = gen_reg_rtx (SImode);
8756 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8762 ;; NB Never uses BX.
8763 (define_insn "*arm_indirect_jump"
8765 (match_operand:SI 0 "s_register_operand" "r"))]
8767 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8768 [(set_attr "predicable" "yes")
8769 (set_attr "type" "branch")]
8772 (define_insn "*load_indirect_jump"
8774 (match_operand:SI 0 "memory_operand" "m"))]
8776 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8777 [(set_attr "type" "load_4")
8778 (set_attr "pool_range" "4096")
8779 (set_attr "neg_pool_range" "4084")
8780 (set_attr "predicable" "yes")]
8790 [(set (attr "length")
8791 (if_then_else (eq_attr "is_thumb" "yes")
8794 (set_attr "type" "mov_reg")]
8798 [(trap_if (const_int 1) (const_int 0))]
8802 return \".inst\\t0xe7f000f0\";
8804 return \".inst\\t0xdeff\";
8806 [(set (attr "length")
8807 (if_then_else (eq_attr "is_thumb" "yes")
8810 (set_attr "type" "trap")
8811 (set_attr "conds" "unconditional")]
8815 ;; Patterns to allow combination of arithmetic, cond code and shifts
8817 (define_insn "*<arith_shift_insn>_multsi"
8818 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8820 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8821 (match_operand:SI 3 "power_of_two_operand" ""))
8822 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8824 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8825 [(set_attr "predicable" "yes")
8826 (set_attr "predicable_short_it" "no")
8827 (set_attr "shift" "2")
8828 (set_attr "arch" "a,t2")
8829 (set_attr "type" "alu_shift_imm")])
8831 (define_insn "*<arith_shift_insn>_shiftsi"
8832 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8834 (match_operator:SI 2 "shift_nomul_operator"
8835 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8836 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8837 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8838 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8839 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8840 [(set_attr "predicable" "yes")
8841 (set_attr "predicable_short_it" "no")
8842 (set_attr "shift" "3")
8843 (set_attr "arch" "a,t2,a")
8844 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8847 [(set (match_operand:SI 0 "s_register_operand" "")
8848 (match_operator:SI 1 "shiftable_operator"
8849 [(match_operator:SI 2 "shiftable_operator"
8850 [(match_operator:SI 3 "shift_operator"
8851 [(match_operand:SI 4 "s_register_operand" "")
8852 (match_operand:SI 5 "reg_or_int_operand" "")])
8853 (match_operand:SI 6 "s_register_operand" "")])
8854 (match_operand:SI 7 "arm_rhs_operand" "")]))
8855 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8858 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8861 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8864 (define_insn "*arith_shiftsi_compare0"
8865 [(set (reg:CC_NOOV CC_REGNUM)
8867 (match_operator:SI 1 "shiftable_operator"
8868 [(match_operator:SI 3 "shift_operator"
8869 [(match_operand:SI 4 "s_register_operand" "r,r")
8870 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8871 (match_operand:SI 2 "s_register_operand" "r,r")])
8873 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8874 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8877 "%i1s%?\\t%0, %2, %4%S3"
8878 [(set_attr "conds" "set")
8879 (set_attr "shift" "4")
8880 (set_attr "arch" "32,a")
8881 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8883 (define_insn "*arith_shiftsi_compare0_scratch"
8884 [(set (reg:CC_NOOV CC_REGNUM)
8886 (match_operator:SI 1 "shiftable_operator"
8887 [(match_operator:SI 3 "shift_operator"
8888 [(match_operand:SI 4 "s_register_operand" "r,r")
8889 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8890 (match_operand:SI 2 "s_register_operand" "r,r")])
8892 (clobber (match_scratch:SI 0 "=r,r"))]
8894 "%i1s%?\\t%0, %2, %4%S3"
8895 [(set_attr "conds" "set")
8896 (set_attr "shift" "4")
8897 (set_attr "arch" "32,a")
8898 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8900 (define_insn "*sub_shiftsi"
8901 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8902 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8903 (match_operator:SI 2 "shift_operator"
8904 [(match_operand:SI 3 "s_register_operand" "r,r")
8905 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8907 "sub%?\\t%0, %1, %3%S2"
8908 [(set_attr "predicable" "yes")
8909 (set_attr "shift" "3")
8910 (set_attr "arch" "32,a")
8911 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8913 (define_insn "*sub_shiftsi_compare0"
8914 [(set (reg:CC_NOOV CC_REGNUM)
8916 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8917 (match_operator:SI 2 "shift_operator"
8918 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8919 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8921 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8922 (minus:SI (match_dup 1)
8923 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8925 "subs%?\\t%0, %1, %3%S2"
8926 [(set_attr "conds" "set")
8927 (set_attr "shift" "3")
8928 (set_attr "arch" "32,a,a")
8929 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8931 (define_insn "*sub_shiftsi_compare0_scratch"
8932 [(set (reg:CC_NOOV CC_REGNUM)
8934 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8935 (match_operator:SI 2 "shift_operator"
8936 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8937 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8939 (clobber (match_scratch:SI 0 "=r,r,r"))]
8941 "subs%?\\t%0, %1, %3%S2"
8942 [(set_attr "conds" "set")
8943 (set_attr "shift" "3")
8944 (set_attr "arch" "32,a,a")
8945 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8948 (define_insn_and_split "*and_scc"
8949 [(set (match_operand:SI 0 "s_register_operand" "=r")
8950 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8951 [(match_operand 2 "cc_register" "") (const_int 0)])
8952 (match_operand:SI 3 "s_register_operand" "r")))]
8954 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8955 "&& reload_completed"
8956 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8957 (cond_exec (match_dup 4) (set (match_dup 0)
8958 (and:SI (match_dup 3) (const_int 1))))]
8960 machine_mode mode = GET_MODE (operands[2]);
8961 enum rtx_code rc = GET_CODE (operands[1]);
8963 /* Note that operands[4] is the same as operands[1],
8964 but with VOIDmode as the result. */
8965 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8966 if (mode == CCFPmode || mode == CCFPEmode)
8967 rc = reverse_condition_maybe_unordered (rc);
8969 rc = reverse_condition (rc);
8970 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8972 [(set_attr "conds" "use")
8973 (set_attr "type" "multiple")
8974 (set_attr "length" "8")]
8977 (define_insn_and_split "*ior_scc"
8978 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8979 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8980 [(match_operand 2 "cc_register" "") (const_int 0)])
8981 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8986 "&& reload_completed
8987 && REGNO (operands [0]) != REGNO (operands[3])"
8988 ;; && which_alternative == 1
8989 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8990 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8991 (cond_exec (match_dup 4) (set (match_dup 0)
8992 (ior:SI (match_dup 3) (const_int 1))))]
8994 machine_mode mode = GET_MODE (operands[2]);
8995 enum rtx_code rc = GET_CODE (operands[1]);
8997 /* Note that operands[4] is the same as operands[1],
8998 but with VOIDmode as the result. */
8999 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9000 if (mode == CCFPmode || mode == CCFPEmode)
9001 rc = reverse_condition_maybe_unordered (rc);
9003 rc = reverse_condition (rc);
9004 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9006 [(set_attr "conds" "use")
9007 (set_attr "length" "4,8")
9008 (set_attr "type" "logic_imm,multiple")]
9011 ; A series of splitters for the compare_scc pattern below. Note that
9012 ; order is important.
9014 [(set (match_operand:SI 0 "s_register_operand" "")
9015 (lt:SI (match_operand:SI 1 "s_register_operand" "")
9017 (clobber (reg:CC CC_REGNUM))]
9018 "TARGET_32BIT && reload_completed"
9019 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9022 [(set (match_operand:SI 0 "s_register_operand" "")
9023 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9025 (clobber (reg:CC CC_REGNUM))]
9026 "TARGET_32BIT && reload_completed"
9027 [(set (match_dup 0) (not:SI (match_dup 1)))
9028 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9031 [(set (match_operand:SI 0 "s_register_operand" "")
9032 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9034 (clobber (reg:CC CC_REGNUM))]
9035 "arm_arch5 && TARGET_32BIT"
9036 [(set (match_dup 0) (clz:SI (match_dup 1)))
9037 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9041 [(set (match_operand:SI 0 "s_register_operand" "")
9042 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9044 (clobber (reg:CC CC_REGNUM))]
9045 "TARGET_32BIT && reload_completed"
9047 [(set (reg:CC CC_REGNUM)
9048 (compare:CC (const_int 1) (match_dup 1)))
9050 (minus:SI (const_int 1) (match_dup 1)))])
9051 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9052 (set (match_dup 0) (const_int 0)))])
9055 [(set (match_operand:SI 0 "s_register_operand" "")
9056 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9057 (match_operand:SI 2 "const_int_operand" "")))
9058 (clobber (reg:CC CC_REGNUM))]
9059 "TARGET_32BIT && reload_completed"
9061 [(set (reg:CC CC_REGNUM)
9062 (compare:CC (match_dup 1) (match_dup 2)))
9063 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9064 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9065 (set (match_dup 0) (const_int 1)))]
9067 operands[3] = GEN_INT (-INTVAL (operands[2]));
9071 [(set (match_operand:SI 0 "s_register_operand" "")
9072 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9073 (match_operand:SI 2 "arm_add_operand" "")))
9074 (clobber (reg:CC CC_REGNUM))]
9075 "TARGET_32BIT && reload_completed"
9077 [(set (reg:CC_NOOV CC_REGNUM)
9078 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9080 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9081 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9082 (set (match_dup 0) (const_int 1)))])
9084 (define_insn_and_split "*compare_scc"
9085 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9086 (match_operator:SI 1 "arm_comparison_operator"
9087 [(match_operand:SI 2 "s_register_operand" "r,r")
9088 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9089 (clobber (reg:CC CC_REGNUM))]
9092 "&& reload_completed"
9093 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9094 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9095 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9098 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9099 operands[2], operands[3]);
9100 enum rtx_code rc = GET_CODE (operands[1]);
9102 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9104 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9105 if (mode == CCFPmode || mode == CCFPEmode)
9106 rc = reverse_condition_maybe_unordered (rc);
9108 rc = reverse_condition (rc);
9109 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9111 [(set_attr "type" "multiple")]
9114 ;; Attempt to improve the sequence generated by the compare_scc splitters
9115 ;; not to use conditional execution.
9117 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9121 [(set (reg:CC CC_REGNUM)
9122 (compare:CC (match_operand:SI 1 "register_operand" "")
9124 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9125 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9126 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9127 (set (match_dup 0) (const_int 1)))]
9128 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9129 [(set (match_dup 0) (clz:SI (match_dup 1)))
9130 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9133 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9137 [(set (reg:CC CC_REGNUM)
9138 (compare:CC (match_operand:SI 1 "register_operand" "")
9140 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9141 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9142 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9143 (set (match_dup 0) (const_int 1)))
9144 (match_scratch:SI 2 "r")]
9145 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9147 [(set (reg:CC CC_REGNUM)
9148 (compare:CC (const_int 0) (match_dup 1)))
9149 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9151 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9152 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9155 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9156 ;; sub Rd, Reg1, reg2
9160 [(set (reg:CC CC_REGNUM)
9161 (compare:CC (match_operand:SI 1 "register_operand" "")
9162 (match_operand:SI 2 "arm_rhs_operand" "")))
9163 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9164 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9165 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9166 (set (match_dup 0) (const_int 1)))]
9167 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9168 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9169 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9170 (set (match_dup 0) (clz:SI (match_dup 0)))
9171 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9175 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9176 ;; sub T1, Reg1, reg2
9180 [(set (reg:CC CC_REGNUM)
9181 (compare:CC (match_operand:SI 1 "register_operand" "")
9182 (match_operand:SI 2 "arm_rhs_operand" "")))
9183 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9184 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9185 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9186 (set (match_dup 0) (const_int 1)))
9187 (match_scratch:SI 3 "r")]
9188 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9189 [(set (match_dup 3) (match_dup 4))
9191 [(set (reg:CC CC_REGNUM)
9192 (compare:CC (const_int 0) (match_dup 3)))
9193 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9195 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9196 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9198 if (CONST_INT_P (operands[2]))
9199 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9201 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9204 (define_insn "*cond_move"
9205 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9206 (if_then_else:SI (match_operator 3 "equality_operator"
9207 [(match_operator 4 "arm_comparison_operator"
9208 [(match_operand 5 "cc_register" "") (const_int 0)])
9210 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9211 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9214 if (GET_CODE (operands[3]) == NE)
9216 if (which_alternative != 1)
9217 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9218 if (which_alternative != 0)
9219 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9222 if (which_alternative != 0)
9223 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9224 if (which_alternative != 1)
9225 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9228 [(set_attr "conds" "use")
9229 (set_attr_alternative "type"
9230 [(if_then_else (match_operand 2 "const_int_operand" "")
9231 (const_string "mov_imm")
9232 (const_string "mov_reg"))
9233 (if_then_else (match_operand 1 "const_int_operand" "")
9234 (const_string "mov_imm")
9235 (const_string "mov_reg"))
9236 (const_string "multiple")])
9237 (set_attr "length" "4,4,8")]
9240 (define_insn "*cond_arith"
9241 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9242 (match_operator:SI 5 "shiftable_operator"
9243 [(match_operator:SI 4 "arm_comparison_operator"
9244 [(match_operand:SI 2 "s_register_operand" "r,r")
9245 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9246 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9247 (clobber (reg:CC CC_REGNUM))]
9250 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9251 return \"%i5\\t%0, %1, %2, lsr #31\";
9253 output_asm_insn (\"cmp\\t%2, %3\", operands);
9254 if (GET_CODE (operands[5]) == AND)
9255 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9256 else if (GET_CODE (operands[5]) == MINUS)
9257 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9258 else if (which_alternative != 0)
9259 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9260 return \"%i5%d4\\t%0, %1, #1\";
9262 [(set_attr "conds" "clob")
9263 (set_attr "length" "12")
9264 (set_attr "type" "multiple")]
9267 (define_insn "*cond_sub"
9268 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9269 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9270 (match_operator:SI 4 "arm_comparison_operator"
9271 [(match_operand:SI 2 "s_register_operand" "r,r")
9272 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9273 (clobber (reg:CC CC_REGNUM))]
9276 output_asm_insn (\"cmp\\t%2, %3\", operands);
9277 if (which_alternative != 0)
9278 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9279 return \"sub%d4\\t%0, %1, #1\";
9281 [(set_attr "conds" "clob")
9282 (set_attr "length" "8,12")
9283 (set_attr "type" "multiple")]
9286 (define_insn "*cmp_ite0"
9287 [(set (match_operand 6 "dominant_cc_register" "")
9290 (match_operator 4 "arm_comparison_operator"
9291 [(match_operand:SI 0 "s_register_operand"
9292 "l,l,l,r,r,r,r,r,r")
9293 (match_operand:SI 1 "arm_add_operand"
9294 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9295 (match_operator:SI 5 "arm_comparison_operator"
9296 [(match_operand:SI 2 "s_register_operand"
9297 "l,r,r,l,l,r,r,r,r")
9298 (match_operand:SI 3 "arm_add_operand"
9299 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9305 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9307 {\"cmp%d5\\t%0, %1\",
9308 \"cmp%d4\\t%2, %3\"},
9309 {\"cmn%d5\\t%0, #%n1\",
9310 \"cmp%d4\\t%2, %3\"},
9311 {\"cmp%d5\\t%0, %1\",
9312 \"cmn%d4\\t%2, #%n3\"},
9313 {\"cmn%d5\\t%0, #%n1\",
9314 \"cmn%d4\\t%2, #%n3\"}
9316 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9321 \"cmn\\t%0, #%n1\"},
9322 {\"cmn\\t%2, #%n3\",
9324 {\"cmn\\t%2, #%n3\",
9327 static const char * const ite[2] =
9332 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9333 CMP_CMP, CMN_CMP, CMP_CMP,
9334 CMN_CMP, CMP_CMN, CMN_CMN};
9336 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9338 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9339 if (TARGET_THUMB2) {
9340 output_asm_insn (ite[swap], operands);
9342 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9345 [(set_attr "conds" "set")
9346 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9347 (set_attr "type" "multiple")
9348 (set_attr_alternative "length"
9354 (if_then_else (eq_attr "is_thumb" "no")
9357 (if_then_else (eq_attr "is_thumb" "no")
9360 (if_then_else (eq_attr "is_thumb" "no")
9363 (if_then_else (eq_attr "is_thumb" "no")
9368 (define_insn "*cmp_ite1"
9369 [(set (match_operand 6 "dominant_cc_register" "")
9372 (match_operator 4 "arm_comparison_operator"
9373 [(match_operand:SI 0 "s_register_operand"
9374 "l,l,l,r,r,r,r,r,r")
9375 (match_operand:SI 1 "arm_add_operand"
9376 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9377 (match_operator:SI 5 "arm_comparison_operator"
9378 [(match_operand:SI 2 "s_register_operand"
9379 "l,r,r,l,l,r,r,r,r")
9380 (match_operand:SI 3 "arm_add_operand"
9381 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9387 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9391 {\"cmn\\t%0, #%n1\",
9394 \"cmn\\t%2, #%n3\"},
9395 {\"cmn\\t%0, #%n1\",
9398 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9400 {\"cmp%d4\\t%2, %3\",
9401 \"cmp%D5\\t%0, %1\"},
9402 {\"cmp%d4\\t%2, %3\",
9403 \"cmn%D5\\t%0, #%n1\"},
9404 {\"cmn%d4\\t%2, #%n3\",
9405 \"cmp%D5\\t%0, %1\"},
9406 {\"cmn%d4\\t%2, #%n3\",
9407 \"cmn%D5\\t%0, #%n1\"}
9409 static const char * const ite[2] =
9414 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9415 CMP_CMP, CMN_CMP, CMP_CMP,
9416 CMN_CMP, CMP_CMN, CMN_CMN};
9418 comparison_dominates_p (GET_CODE (operands[5]),
9419 reverse_condition (GET_CODE (operands[4])));
9421 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9422 if (TARGET_THUMB2) {
9423 output_asm_insn (ite[swap], operands);
9425 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9428 [(set_attr "conds" "set")
9429 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9430 (set_attr_alternative "length"
9436 (if_then_else (eq_attr "is_thumb" "no")
9439 (if_then_else (eq_attr "is_thumb" "no")
9442 (if_then_else (eq_attr "is_thumb" "no")
9445 (if_then_else (eq_attr "is_thumb" "no")
9448 (set_attr "type" "multiple")]
9451 (define_insn "*cmp_and"
9452 [(set (match_operand 6 "dominant_cc_register" "")
9455 (match_operator 4 "arm_comparison_operator"
9456 [(match_operand:SI 0 "s_register_operand"
9457 "l,l,l,r,r,r,r,r,r")
9458 (match_operand:SI 1 "arm_add_operand"
9459 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9460 (match_operator:SI 5 "arm_comparison_operator"
9461 [(match_operand:SI 2 "s_register_operand"
9462 "l,r,r,l,l,r,r,r,r")
9463 (match_operand:SI 3 "arm_add_operand"
9464 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9469 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9471 {\"cmp%d5\\t%0, %1\",
9472 \"cmp%d4\\t%2, %3\"},
9473 {\"cmn%d5\\t%0, #%n1\",
9474 \"cmp%d4\\t%2, %3\"},
9475 {\"cmp%d5\\t%0, %1\",
9476 \"cmn%d4\\t%2, #%n3\"},
9477 {\"cmn%d5\\t%0, #%n1\",
9478 \"cmn%d4\\t%2, #%n3\"}
9480 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9485 \"cmn\\t%0, #%n1\"},
9486 {\"cmn\\t%2, #%n3\",
9488 {\"cmn\\t%2, #%n3\",
9491 static const char *const ite[2] =
9496 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9497 CMP_CMP, CMN_CMP, CMP_CMP,
9498 CMN_CMP, CMP_CMN, CMN_CMN};
9500 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9502 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9503 if (TARGET_THUMB2) {
9504 output_asm_insn (ite[swap], operands);
9506 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9509 [(set_attr "conds" "set")
9510 (set_attr "predicable" "no")
9511 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9512 (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9513 (set_attr_alternative "length"
9519 (if_then_else (eq_attr "is_thumb" "no")
9522 (if_then_else (eq_attr "is_thumb" "no")
9525 (if_then_else (eq_attr "is_thumb" "no")
9528 (if_then_else (eq_attr "is_thumb" "no")
9531 (set_attr "type" "multiple")]
9534 (define_insn "*cmp_ior"
9535 [(set (match_operand 6 "dominant_cc_register" "")
9538 (match_operator 4 "arm_comparison_operator"
9539 [(match_operand:SI 0 "s_register_operand"
9540 "l,l,l,r,r,r,r,r,r")
9541 (match_operand:SI 1 "arm_add_operand"
9542 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9543 (match_operator:SI 5 "arm_comparison_operator"
9544 [(match_operand:SI 2 "s_register_operand"
9545 "l,r,r,l,l,r,r,r,r")
9546 (match_operand:SI 3 "arm_add_operand"
9547 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9552 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9556 {\"cmn\\t%0, #%n1\",
9559 \"cmn\\t%2, #%n3\"},
9560 {\"cmn\\t%0, #%n1\",
9563 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9565 {\"cmp%D4\\t%2, %3\",
9566 \"cmp%D5\\t%0, %1\"},
9567 {\"cmp%D4\\t%2, %3\",
9568 \"cmn%D5\\t%0, #%n1\"},
9569 {\"cmn%D4\\t%2, #%n3\",
9570 \"cmp%D5\\t%0, %1\"},
9571 {\"cmn%D4\\t%2, #%n3\",
9572 \"cmn%D5\\t%0, #%n1\"}
9574 static const char *const ite[2] =
9579 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9580 CMP_CMP, CMN_CMP, CMP_CMP,
9581 CMN_CMP, CMP_CMN, CMN_CMN};
9583 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9585 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9586 if (TARGET_THUMB2) {
9587 output_asm_insn (ite[swap], operands);
9589 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9593 [(set_attr "conds" "set")
9594 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9595 (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9596 (set_attr_alternative "length"
9602 (if_then_else (eq_attr "is_thumb" "no")
9605 (if_then_else (eq_attr "is_thumb" "no")
9608 (if_then_else (eq_attr "is_thumb" "no")
9611 (if_then_else (eq_attr "is_thumb" "no")
9614 (set_attr "type" "multiple")]
9617 (define_insn_and_split "*ior_scc_scc"
9618 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9619 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9620 [(match_operand:SI 1 "s_register_operand" "l,r")
9621 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9622 (match_operator:SI 6 "arm_comparison_operator"
9623 [(match_operand:SI 4 "s_register_operand" "l,r")
9624 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9625 (clobber (reg:CC CC_REGNUM))]
9627 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9630 "TARGET_32BIT && reload_completed"
9634 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9635 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9637 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9639 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9642 [(set_attr "conds" "clob")
9643 (set_attr "enabled_for_depr_it" "yes,no")
9644 (set_attr "length" "16")
9645 (set_attr "type" "multiple")]
9648 ; If the above pattern is followed by a CMP insn, then the compare is
9649 ; redundant, since we can rework the conditional instruction that follows.
9650 (define_insn_and_split "*ior_scc_scc_cmp"
9651 [(set (match_operand 0 "dominant_cc_register" "")
9652 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9653 [(match_operand:SI 1 "s_register_operand" "l,r")
9654 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9655 (match_operator:SI 6 "arm_comparison_operator"
9656 [(match_operand:SI 4 "s_register_operand" "l,r")
9657 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9659 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9660 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9661 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9664 "TARGET_32BIT && reload_completed"
9668 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9669 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9671 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9673 [(set_attr "conds" "set")
9674 (set_attr "enabled_for_depr_it" "yes,no")
9675 (set_attr "length" "16")
9676 (set_attr "type" "multiple")]
9679 (define_insn_and_split "*and_scc_scc"
9680 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9681 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9682 [(match_operand:SI 1 "s_register_operand" "l,r")
9683 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9684 (match_operator:SI 6 "arm_comparison_operator"
9685 [(match_operand:SI 4 "s_register_operand" "l,r")
9686 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9687 (clobber (reg:CC CC_REGNUM))]
9689 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9692 "TARGET_32BIT && reload_completed
9693 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9698 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9699 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9701 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9703 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9706 [(set_attr "conds" "clob")
9707 (set_attr "enabled_for_depr_it" "yes,no")
9708 (set_attr "length" "16")
9709 (set_attr "type" "multiple")]
9712 ; If the above pattern is followed by a CMP insn, then the compare is
9713 ; redundant, since we can rework the conditional instruction that follows.
9714 (define_insn_and_split "*and_scc_scc_cmp"
9715 [(set (match_operand 0 "dominant_cc_register" "")
9716 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9717 [(match_operand:SI 1 "s_register_operand" "l,r")
9718 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9719 (match_operator:SI 6 "arm_comparison_operator"
9720 [(match_operand:SI 4 "s_register_operand" "l,r")
9721 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9723 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9724 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9725 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9728 "TARGET_32BIT && reload_completed"
9732 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9733 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9735 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9737 [(set_attr "conds" "set")
9738 (set_attr "enabled_for_depr_it" "yes,no")
9739 (set_attr "length" "16")
9740 (set_attr "type" "multiple")]
9743 ;; If there is no dominance in the comparison, then we can still save an
9744 ;; instruction in the AND case, since we can know that the second compare
9745 ;; need only zero the value if false (if true, then the value is already
9747 (define_insn_and_split "*and_scc_scc_nodom"
9748 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9749 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9750 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9751 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9752 (match_operator:SI 6 "arm_comparison_operator"
9753 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9754 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9755 (clobber (reg:CC CC_REGNUM))]
9757 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9760 "TARGET_32BIT && reload_completed"
9761 [(parallel [(set (match_dup 0)
9762 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9763 (clobber (reg:CC CC_REGNUM))])
9764 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9766 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9769 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9770 operands[4], operands[5]),
9772 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9774 [(set_attr "conds" "clob")
9775 (set_attr "length" "20")
9776 (set_attr "type" "multiple")]
9780 [(set (reg:CC_NOOV CC_REGNUM)
9781 (compare:CC_NOOV (ior:SI
9782 (and:SI (match_operand:SI 0 "s_register_operand" "")
9784 (match_operator:SI 1 "arm_comparison_operator"
9785 [(match_operand:SI 2 "s_register_operand" "")
9786 (match_operand:SI 3 "arm_add_operand" "")]))
9788 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9791 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9793 (set (reg:CC_NOOV CC_REGNUM)
9794 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9799 [(set (reg:CC_NOOV CC_REGNUM)
9800 (compare:CC_NOOV (ior:SI
9801 (match_operator:SI 1 "arm_comparison_operator"
9802 [(match_operand:SI 2 "s_register_operand" "")
9803 (match_operand:SI 3 "arm_add_operand" "")])
9804 (and:SI (match_operand:SI 0 "s_register_operand" "")
9807 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9810 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9812 (set (reg:CC_NOOV CC_REGNUM)
9813 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9816 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9818 (define_insn_and_split "*negscc"
9819 [(set (match_operand:SI 0 "s_register_operand" "=r")
9820 (neg:SI (match_operator 3 "arm_comparison_operator"
9821 [(match_operand:SI 1 "s_register_operand" "r")
9822 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9823 (clobber (reg:CC CC_REGNUM))]
9826 "&& reload_completed"
9829 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9831 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9833 /* Emit mov\\t%0, %1, asr #31 */
9834 emit_insn (gen_rtx_SET (operands[0],
9835 gen_rtx_ASHIFTRT (SImode,
9840 else if (GET_CODE (operands[3]) == NE)
9842 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9843 if (CONST_INT_P (operands[2]))
9844 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9845 GEN_INT (- INTVAL (operands[2]))));
9847 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9849 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9853 gen_rtx_SET (operands[0],
9859 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9860 emit_insn (gen_rtx_SET (cc_reg,
9861 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9862 enum rtx_code rc = GET_CODE (operands[3]);
9864 rc = reverse_condition (rc);
9865 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9870 gen_rtx_SET (operands[0], const0_rtx)));
9871 rc = GET_CODE (operands[3]);
9872 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9877 gen_rtx_SET (operands[0],
9883 [(set_attr "conds" "clob")
9884 (set_attr "length" "12")
9885 (set_attr "type" "multiple")]
9888 (define_insn_and_split "movcond_addsi"
9889 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9891 (match_operator 5 "comparison_operator"
9892 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9893 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9895 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9896 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9897 (clobber (reg:CC CC_REGNUM))]
9900 "&& reload_completed"
9901 [(set (reg:CC_NOOV CC_REGNUM)
9903 (plus:SI (match_dup 3)
9906 (set (match_dup 0) (match_dup 1))
9907 (cond_exec (match_dup 6)
9908 (set (match_dup 0) (match_dup 2)))]
9911 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9912 operands[3], operands[4]);
9913 enum rtx_code rc = GET_CODE (operands[5]);
9914 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9915 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9916 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9917 rc = reverse_condition (rc);
9919 std::swap (operands[1], operands[2]);
9921 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9924 [(set_attr "conds" "clob")
9925 (set_attr "enabled_for_depr_it" "no,yes,yes")
9926 (set_attr "type" "multiple")]
9929 (define_insn "movcond"
9930 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9932 (match_operator 5 "arm_comparison_operator"
9933 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9934 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9935 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9936 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9937 (clobber (reg:CC CC_REGNUM))]
9940 if (GET_CODE (operands[5]) == LT
9941 && (operands[4] == const0_rtx))
9943 if (which_alternative != 1 && REG_P (operands[1]))
9945 if (operands[2] == const0_rtx)
9946 return \"and\\t%0, %1, %3, asr #31\";
9947 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9949 else if (which_alternative != 0 && REG_P (operands[2]))
9951 if (operands[1] == const0_rtx)
9952 return \"bic\\t%0, %2, %3, asr #31\";
9953 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9955 /* The only case that falls through to here is when both ops 1 & 2
9959 if (GET_CODE (operands[5]) == GE
9960 && (operands[4] == const0_rtx))
9962 if (which_alternative != 1 && REG_P (operands[1]))
9964 if (operands[2] == const0_rtx)
9965 return \"bic\\t%0, %1, %3, asr #31\";
9966 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9968 else if (which_alternative != 0 && REG_P (operands[2]))
9970 if (operands[1] == const0_rtx)
9971 return \"and\\t%0, %2, %3, asr #31\";
9972 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9974 /* The only case that falls through to here is when both ops 1 & 2
9977 if (CONST_INT_P (operands[4])
9978 && !const_ok_for_arm (INTVAL (operands[4])))
9979 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9981 output_asm_insn (\"cmp\\t%3, %4\", operands);
9982 if (which_alternative != 0)
9983 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9984 if (which_alternative != 1)
9985 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9988 [(set_attr "conds" "clob")
9989 (set_attr "length" "8,8,12")
9990 (set_attr "type" "multiple")]
9993 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9995 (define_insn "*ifcompare_plus_move"
9996 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9997 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9998 [(match_operand:SI 4 "s_register_operand" "r,r")
9999 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10001 (match_operand:SI 2 "s_register_operand" "r,r")
10002 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10003 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10004 (clobber (reg:CC CC_REGNUM))]
10007 [(set_attr "conds" "clob")
10008 (set_attr "length" "8,12")
10009 (set_attr "type" "multiple")]
10012 (define_insn "*if_plus_move"
10013 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10015 (match_operator 4 "arm_comparison_operator"
10016 [(match_operand 5 "cc_register" "") (const_int 0)])
10018 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10019 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10020 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10023 add%d4\\t%0, %2, %3
10024 sub%d4\\t%0, %2, #%n3
10025 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10026 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10027 [(set_attr "conds" "use")
10028 (set_attr "length" "4,4,8,8")
10029 (set_attr_alternative "type"
10030 [(if_then_else (match_operand 3 "const_int_operand" "")
10031 (const_string "alu_imm" )
10032 (const_string "alu_sreg"))
10033 (const_string "alu_imm")
10034 (const_string "multiple")
10035 (const_string "multiple")])]
10038 (define_insn "*ifcompare_move_plus"
10039 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10040 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10041 [(match_operand:SI 4 "s_register_operand" "r,r")
10042 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10043 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10045 (match_operand:SI 2 "s_register_operand" "r,r")
10046 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10047 (clobber (reg:CC CC_REGNUM))]
10050 [(set_attr "conds" "clob")
10051 (set_attr "length" "8,12")
10052 (set_attr "type" "multiple")]
10055 (define_insn "*if_move_plus"
10056 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10058 (match_operator 4 "arm_comparison_operator"
10059 [(match_operand 5 "cc_register" "") (const_int 0)])
10060 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10062 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10063 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10066 add%D4\\t%0, %2, %3
10067 sub%D4\\t%0, %2, #%n3
10068 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10069 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10070 [(set_attr "conds" "use")
10071 (set_attr "length" "4,4,8,8")
10072 (set_attr_alternative "type"
10073 [(if_then_else (match_operand 3 "const_int_operand" "")
10074 (const_string "alu_imm" )
10075 (const_string "alu_sreg"))
10076 (const_string "alu_imm")
10077 (const_string "multiple")
10078 (const_string "multiple")])]
10081 (define_insn "*ifcompare_arith_arith"
10082 [(set (match_operand:SI 0 "s_register_operand" "=r")
10083 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10084 [(match_operand:SI 5 "s_register_operand" "r")
10085 (match_operand:SI 6 "arm_add_operand" "rIL")])
10086 (match_operator:SI 8 "shiftable_operator"
10087 [(match_operand:SI 1 "s_register_operand" "r")
10088 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10089 (match_operator:SI 7 "shiftable_operator"
10090 [(match_operand:SI 3 "s_register_operand" "r")
10091 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10092 (clobber (reg:CC CC_REGNUM))]
10095 [(set_attr "conds" "clob")
10096 (set_attr "length" "12")
10097 (set_attr "type" "multiple")]
10100 (define_insn "*if_arith_arith"
10101 [(set (match_operand:SI 0 "s_register_operand" "=r")
10102 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10103 [(match_operand 8 "cc_register" "") (const_int 0)])
10104 (match_operator:SI 6 "shiftable_operator"
10105 [(match_operand:SI 1 "s_register_operand" "r")
10106 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10107 (match_operator:SI 7 "shiftable_operator"
10108 [(match_operand:SI 3 "s_register_operand" "r")
10109 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10111 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10112 [(set_attr "conds" "use")
10113 (set_attr "length" "8")
10114 (set_attr "type" "multiple")]
10117 (define_insn "*ifcompare_arith_move"
10118 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10119 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10120 [(match_operand:SI 2 "s_register_operand" "r,r")
10121 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10122 (match_operator:SI 7 "shiftable_operator"
10123 [(match_operand:SI 4 "s_register_operand" "r,r")
10124 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10125 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10126 (clobber (reg:CC CC_REGNUM))]
10129 /* If we have an operation where (op x 0) is the identity operation and
10130 the conditional operator is LT or GE and we are comparing against zero and
10131 everything is in registers then we can do this in two instructions. */
10132 if (operands[3] == const0_rtx
10133 && GET_CODE (operands[7]) != AND
10134 && REG_P (operands[5])
10135 && REG_P (operands[1])
10136 && REGNO (operands[1]) == REGNO (operands[4])
10137 && REGNO (operands[4]) != REGNO (operands[0]))
10139 if (GET_CODE (operands[6]) == LT)
10140 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10141 else if (GET_CODE (operands[6]) == GE)
10142 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10144 if (CONST_INT_P (operands[3])
10145 && !const_ok_for_arm (INTVAL (operands[3])))
10146 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10148 output_asm_insn (\"cmp\\t%2, %3\", operands);
10149 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10150 if (which_alternative != 0)
10151 return \"mov%D6\\t%0, %1\";
10154 [(set_attr "conds" "clob")
10155 (set_attr "length" "8,12")
10156 (set_attr "type" "multiple")]
10159 (define_insn "*if_arith_move"
10160 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10161 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10162 [(match_operand 6 "cc_register" "") (const_int 0)])
10163 (match_operator:SI 5 "shiftable_operator"
10164 [(match_operand:SI 2 "s_register_operand" "r,r")
10165 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10166 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10169 %I5%d4\\t%0, %2, %3
10170 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10171 [(set_attr "conds" "use")
10172 (set_attr "length" "4,8")
10173 (set_attr_alternative "type"
10174 [(if_then_else (match_operand 3 "const_int_operand" "")
10175 (const_string "alu_shift_imm" )
10176 (const_string "alu_shift_reg"))
10177 (const_string "multiple")])]
10180 (define_insn "*ifcompare_move_arith"
10181 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10182 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10183 [(match_operand:SI 4 "s_register_operand" "r,r")
10184 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10185 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10186 (match_operator:SI 7 "shiftable_operator"
10187 [(match_operand:SI 2 "s_register_operand" "r,r")
10188 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10189 (clobber (reg:CC CC_REGNUM))]
10192 /* If we have an operation where (op x 0) is the identity operation and
10193 the conditional operator is LT or GE and we are comparing against zero and
10194 everything is in registers then we can do this in two instructions */
10195 if (operands[5] == const0_rtx
10196 && GET_CODE (operands[7]) != AND
10197 && REG_P (operands[3])
10198 && REG_P (operands[1])
10199 && REGNO (operands[1]) == REGNO (operands[2])
10200 && REGNO (operands[2]) != REGNO (operands[0]))
10202 if (GET_CODE (operands[6]) == GE)
10203 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10204 else if (GET_CODE (operands[6]) == LT)
10205 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10208 if (CONST_INT_P (operands[5])
10209 && !const_ok_for_arm (INTVAL (operands[5])))
10210 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10212 output_asm_insn (\"cmp\\t%4, %5\", operands);
10214 if (which_alternative != 0)
10215 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10216 return \"%I7%D6\\t%0, %2, %3\";
10218 [(set_attr "conds" "clob")
10219 (set_attr "length" "8,12")
10220 (set_attr "type" "multiple")]
10223 (define_insn "*if_move_arith"
10224 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10226 (match_operator 4 "arm_comparison_operator"
10227 [(match_operand 6 "cc_register" "") (const_int 0)])
10228 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10229 (match_operator:SI 5 "shiftable_operator"
10230 [(match_operand:SI 2 "s_register_operand" "r,r")
10231 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10234 %I5%D4\\t%0, %2, %3
10235 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10236 [(set_attr "conds" "use")
10237 (set_attr "length" "4,8")
10238 (set_attr_alternative "type"
10239 [(if_then_else (match_operand 3 "const_int_operand" "")
10240 (const_string "alu_shift_imm" )
10241 (const_string "alu_shift_reg"))
10242 (const_string "multiple")])]
10245 (define_insn "*ifcompare_move_not"
10246 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10248 (match_operator 5 "arm_comparison_operator"
10249 [(match_operand:SI 3 "s_register_operand" "r,r")
10250 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10251 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10253 (match_operand:SI 2 "s_register_operand" "r,r"))))
10254 (clobber (reg:CC CC_REGNUM))]
10257 [(set_attr "conds" "clob")
10258 (set_attr "length" "8,12")
10259 (set_attr "type" "multiple")]
10262 (define_insn "*if_move_not"
10263 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10265 (match_operator 4 "arm_comparison_operator"
10266 [(match_operand 3 "cc_register" "") (const_int 0)])
10267 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10268 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10272 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10273 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10274 [(set_attr "conds" "use")
10275 (set_attr "type" "mvn_reg")
10276 (set_attr "length" "4,8,8")
10277 (set_attr "type" "mvn_reg,multiple,multiple")]
10280 (define_insn "*ifcompare_not_move"
10281 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10283 (match_operator 5 "arm_comparison_operator"
10284 [(match_operand:SI 3 "s_register_operand" "r,r")
10285 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10287 (match_operand:SI 2 "s_register_operand" "r,r"))
10288 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10289 (clobber (reg:CC CC_REGNUM))]
10292 [(set_attr "conds" "clob")
10293 (set_attr "length" "8,12")
10294 (set_attr "type" "multiple")]
10297 (define_insn "*if_not_move"
10298 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10300 (match_operator 4 "arm_comparison_operator"
10301 [(match_operand 3 "cc_register" "") (const_int 0)])
10302 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10303 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10307 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10308 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10309 [(set_attr "conds" "use")
10310 (set_attr "type" "mvn_reg,multiple,multiple")
10311 (set_attr "length" "4,8,8")]
10314 (define_insn "*ifcompare_shift_move"
10315 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10317 (match_operator 6 "arm_comparison_operator"
10318 [(match_operand:SI 4 "s_register_operand" "r,r")
10319 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10320 (match_operator:SI 7 "shift_operator"
10321 [(match_operand:SI 2 "s_register_operand" "r,r")
10322 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10323 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10324 (clobber (reg:CC CC_REGNUM))]
10327 [(set_attr "conds" "clob")
10328 (set_attr "length" "8,12")
10329 (set_attr "type" "multiple")]
10332 (define_insn "*if_shift_move"
10333 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10335 (match_operator 5 "arm_comparison_operator"
10336 [(match_operand 6 "cc_register" "") (const_int 0)])
10337 (match_operator:SI 4 "shift_operator"
10338 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10339 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10340 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10344 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10345 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10346 [(set_attr "conds" "use")
10347 (set_attr "shift" "2")
10348 (set_attr "length" "4,8,8")
10349 (set_attr_alternative "type"
10350 [(if_then_else (match_operand 3 "const_int_operand" "")
10351 (const_string "mov_shift" )
10352 (const_string "mov_shift_reg"))
10353 (const_string "multiple")
10354 (const_string "multiple")])]
10357 (define_insn "*ifcompare_move_shift"
10358 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10360 (match_operator 6 "arm_comparison_operator"
10361 [(match_operand:SI 4 "s_register_operand" "r,r")
10362 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10363 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10364 (match_operator:SI 7 "shift_operator"
10365 [(match_operand:SI 2 "s_register_operand" "r,r")
10366 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10367 (clobber (reg:CC CC_REGNUM))]
10370 [(set_attr "conds" "clob")
10371 (set_attr "length" "8,12")
10372 (set_attr "type" "multiple")]
10375 (define_insn "*if_move_shift"
10376 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10378 (match_operator 5 "arm_comparison_operator"
10379 [(match_operand 6 "cc_register" "") (const_int 0)])
10380 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10381 (match_operator:SI 4 "shift_operator"
10382 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10383 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10387 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10388 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10389 [(set_attr "conds" "use")
10390 (set_attr "shift" "2")
10391 (set_attr "length" "4,8,8")
10392 (set_attr_alternative "type"
10393 [(if_then_else (match_operand 3 "const_int_operand" "")
10394 (const_string "mov_shift" )
10395 (const_string "mov_shift_reg"))
10396 (const_string "multiple")
10397 (const_string "multiple")])]
10400 (define_insn "*ifcompare_shift_shift"
10401 [(set (match_operand:SI 0 "s_register_operand" "=r")
10403 (match_operator 7 "arm_comparison_operator"
10404 [(match_operand:SI 5 "s_register_operand" "r")
10405 (match_operand:SI 6 "arm_add_operand" "rIL")])
10406 (match_operator:SI 8 "shift_operator"
10407 [(match_operand:SI 1 "s_register_operand" "r")
10408 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10409 (match_operator:SI 9 "shift_operator"
10410 [(match_operand:SI 3 "s_register_operand" "r")
10411 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10412 (clobber (reg:CC CC_REGNUM))]
10415 [(set_attr "conds" "clob")
10416 (set_attr "length" "12")
10417 (set_attr "type" "multiple")]
10420 (define_insn "*if_shift_shift"
10421 [(set (match_operand:SI 0 "s_register_operand" "=r")
10423 (match_operator 5 "arm_comparison_operator"
10424 [(match_operand 8 "cc_register" "") (const_int 0)])
10425 (match_operator:SI 6 "shift_operator"
10426 [(match_operand:SI 1 "s_register_operand" "r")
10427 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10428 (match_operator:SI 7 "shift_operator"
10429 [(match_operand:SI 3 "s_register_operand" "r")
10430 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10432 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10433 [(set_attr "conds" "use")
10434 (set_attr "shift" "1")
10435 (set_attr "length" "8")
10436 (set (attr "type") (if_then_else
10437 (and (match_operand 2 "const_int_operand" "")
10438 (match_operand 4 "const_int_operand" ""))
10439 (const_string "mov_shift")
10440 (const_string "mov_shift_reg")))]
10443 (define_insn "*ifcompare_not_arith"
10444 [(set (match_operand:SI 0 "s_register_operand" "=r")
10446 (match_operator 6 "arm_comparison_operator"
10447 [(match_operand:SI 4 "s_register_operand" "r")
10448 (match_operand:SI 5 "arm_add_operand" "rIL")])
10449 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10450 (match_operator:SI 7 "shiftable_operator"
10451 [(match_operand:SI 2 "s_register_operand" "r")
10452 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10453 (clobber (reg:CC CC_REGNUM))]
10456 [(set_attr "conds" "clob")
10457 (set_attr "length" "12")
10458 (set_attr "type" "multiple")]
10461 (define_insn "*if_not_arith"
10462 [(set (match_operand:SI 0 "s_register_operand" "=r")
10464 (match_operator 5 "arm_comparison_operator"
10465 [(match_operand 4 "cc_register" "") (const_int 0)])
10466 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10467 (match_operator:SI 6 "shiftable_operator"
10468 [(match_operand:SI 2 "s_register_operand" "r")
10469 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10471 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10472 [(set_attr "conds" "use")
10473 (set_attr "type" "mvn_reg")
10474 (set_attr "length" "8")]
10477 (define_insn "*ifcompare_arith_not"
10478 [(set (match_operand:SI 0 "s_register_operand" "=r")
10480 (match_operator 6 "arm_comparison_operator"
10481 [(match_operand:SI 4 "s_register_operand" "r")
10482 (match_operand:SI 5 "arm_add_operand" "rIL")])
10483 (match_operator:SI 7 "shiftable_operator"
10484 [(match_operand:SI 2 "s_register_operand" "r")
10485 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10486 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10487 (clobber (reg:CC CC_REGNUM))]
10490 [(set_attr "conds" "clob")
10491 (set_attr "length" "12")
10492 (set_attr "type" "multiple")]
10495 (define_insn "*if_arith_not"
10496 [(set (match_operand:SI 0 "s_register_operand" "=r")
10498 (match_operator 5 "arm_comparison_operator"
10499 [(match_operand 4 "cc_register" "") (const_int 0)])
10500 (match_operator:SI 6 "shiftable_operator"
10501 [(match_operand:SI 2 "s_register_operand" "r")
10502 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10503 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10505 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10506 [(set_attr "conds" "use")
10507 (set_attr "type" "multiple")
10508 (set_attr "length" "8")]
10511 (define_insn "*ifcompare_neg_move"
10512 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10514 (match_operator 5 "arm_comparison_operator"
10515 [(match_operand:SI 3 "s_register_operand" "r,r")
10516 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10517 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10518 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10519 (clobber (reg:CC CC_REGNUM))]
10522 [(set_attr "conds" "clob")
10523 (set_attr "length" "8,12")
10524 (set_attr "type" "multiple")]
10527 (define_insn_and_split "*if_neg_move"
10528 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10530 (match_operator 4 "arm_comparison_operator"
10531 [(match_operand 3 "cc_register" "") (const_int 0)])
10532 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10533 (match_operand:SI 1 "s_register_operand" "0,0")))]
10536 "&& reload_completed"
10537 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10538 (set (match_dup 0) (neg:SI (match_dup 2))))]
10540 [(set_attr "conds" "use")
10541 (set_attr "length" "4")
10542 (set_attr "arch" "t2,32")
10543 (set_attr "enabled_for_depr_it" "yes,no")
10544 (set_attr "type" "logic_shift_imm")]
10547 (define_insn "*ifcompare_move_neg"
10548 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10550 (match_operator 5 "arm_comparison_operator"
10551 [(match_operand:SI 3 "s_register_operand" "r,r")
10552 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10553 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10554 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10555 (clobber (reg:CC CC_REGNUM))]
10558 [(set_attr "conds" "clob")
10559 (set_attr "length" "8,12")
10560 (set_attr "type" "multiple")]
10563 (define_insn_and_split "*if_move_neg"
10564 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10566 (match_operator 4 "arm_comparison_operator"
10567 [(match_operand 3 "cc_register" "") (const_int 0)])
10568 (match_operand:SI 1 "s_register_operand" "0,0")
10569 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10572 "&& reload_completed"
10573 [(cond_exec (match_dup 5)
10574 (set (match_dup 0) (neg:SI (match_dup 2))))]
10576 machine_mode mode = GET_MODE (operands[3]);
10577 rtx_code rc = GET_CODE (operands[4]);
10579 if (mode == CCFPmode || mode == CCFPEmode)
10580 rc = reverse_condition_maybe_unordered (rc);
10582 rc = reverse_condition (rc);
10584 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10586 [(set_attr "conds" "use")
10587 (set_attr "length" "4")
10588 (set_attr "arch" "t2,32")
10589 (set_attr "enabled_for_depr_it" "yes,no")
10590 (set_attr "type" "logic_shift_imm")]
10593 (define_insn "*arith_adjacentmem"
10594 [(set (match_operand:SI 0 "s_register_operand" "=r")
10595 (match_operator:SI 1 "shiftable_operator"
10596 [(match_operand:SI 2 "memory_operand" "m")
10597 (match_operand:SI 3 "memory_operand" "m")]))
10598 (clobber (match_scratch:SI 4 "=r"))]
10599 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10605 HOST_WIDE_INT val1 = 0, val2 = 0;
10607 if (REGNO (operands[0]) > REGNO (operands[4]))
10609 ldm[1] = operands[4];
10610 ldm[2] = operands[0];
10614 ldm[1] = operands[0];
10615 ldm[2] = operands[4];
10618 base_reg = XEXP (operands[2], 0);
10620 if (!REG_P (base_reg))
10622 val1 = INTVAL (XEXP (base_reg, 1));
10623 base_reg = XEXP (base_reg, 0);
10626 if (!REG_P (XEXP (operands[3], 0)))
10627 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10629 arith[0] = operands[0];
10630 arith[3] = operands[1];
10644 if (val1 !=0 && val2 != 0)
10648 if (val1 == 4 || val2 == 4)
10649 /* Other val must be 8, since we know they are adjacent and neither
10651 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10652 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10654 ldm[0] = ops[0] = operands[4];
10656 ops[2] = GEN_INT (val1);
10657 output_add_immediate (ops);
10659 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10661 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10665 /* Offset is out of range for a single add, so use two ldr. */
10668 ops[2] = GEN_INT (val1);
10669 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10671 ops[2] = GEN_INT (val2);
10672 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10675 else if (val1 != 0)
10678 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10680 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10685 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10687 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10689 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10692 [(set_attr "length" "12")
10693 (set_attr "predicable" "yes")
10694 (set_attr "type" "load_4")]
10697 ; This pattern is never tried by combine, so do it as a peephole
10700 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10701 (match_operand:SI 1 "arm_general_register_operand" ""))
10702 (set (reg:CC CC_REGNUM)
10703 (compare:CC (match_dup 1) (const_int 0)))]
10705 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10706 (set (match_dup 0) (match_dup 1))])]
10711 [(set (match_operand:SI 0 "s_register_operand" "")
10712 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10714 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10715 [(match_operand:SI 3 "s_register_operand" "")
10716 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10717 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10719 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10720 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10725 ;; This split can be used because CC_Z mode implies that the following
10726 ;; branch will be an equality, or an unsigned inequality, so the sign
10727 ;; extension is not needed.
10730 [(set (reg:CC_Z CC_REGNUM)
10732 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10734 (match_operand 1 "const_int_operand" "")))
10735 (clobber (match_scratch:SI 2 ""))]
10737 && ((UINTVAL (operands[1]))
10738 == ((UINTVAL (operands[1])) >> 24) << 24)"
10739 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10740 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10742 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10745 ;; ??? Check the patterns above for Thumb-2 usefulness
10747 (define_expand "prologue"
10748 [(clobber (const_int 0))]
10751 arm_expand_prologue ();
10753 thumb1_expand_prologue ();
10758 (define_expand "epilogue"
10759 [(clobber (const_int 0))]
10762 if (crtl->calls_eh_return)
10763 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10766 thumb1_expand_epilogue ();
10767 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10768 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10770 else if (HAVE_return)
10772 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10773 no need for explicit testing again. */
10774 emit_jump_insn (gen_return ());
10776 else if (TARGET_32BIT)
10778 arm_expand_epilogue (true);
10784 ;; Note - although unspec_volatile's USE all hard registers,
10785 ;; USEs are ignored after relaod has completed. Thus we need
10786 ;; to add an unspec of the link register to ensure that flow
10787 ;; does not think that it is unused by the sibcall branch that
10788 ;; will replace the standard function epilogue.
10789 (define_expand "sibcall_epilogue"
10790 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10791 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10794 arm_expand_epilogue (false);
10799 (define_expand "eh_epilogue"
10800 [(use (match_operand:SI 0 "register_operand" ""))
10801 (use (match_operand:SI 1 "register_operand" ""))
10802 (use (match_operand:SI 2 "register_operand" ""))]
10806 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10807 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10809 rtx ra = gen_rtx_REG (Pmode, 2);
10811 emit_move_insn (ra, operands[2]);
10814 /* This is a hack -- we may have crystalized the function type too
10816 cfun->machine->func_type = 0;
10820 ;; This split is only used during output to reduce the number of patterns
10821 ;; that need assembler instructions adding to them. We allowed the setting
10822 ;; of the conditions to be implicit during rtl generation so that
10823 ;; the conditional compare patterns would work. However this conflicts to
10824 ;; some extent with the conditional data operations, so we have to split them
10827 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10828 ;; conditional execution sufficient?
10831 [(set (match_operand:SI 0 "s_register_operand" "")
10832 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10833 [(match_operand 2 "" "") (match_operand 3 "" "")])
10835 (match_operand 4 "" "")))
10836 (clobber (reg:CC CC_REGNUM))]
10837 "TARGET_ARM && reload_completed"
10838 [(set (match_dup 5) (match_dup 6))
10839 (cond_exec (match_dup 7)
10840 (set (match_dup 0) (match_dup 4)))]
10843 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10844 operands[2], operands[3]);
10845 enum rtx_code rc = GET_CODE (operands[1]);
10847 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10848 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10849 if (mode == CCFPmode || mode == CCFPEmode)
10850 rc = reverse_condition_maybe_unordered (rc);
10852 rc = reverse_condition (rc);
10854 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10859 [(set (match_operand:SI 0 "s_register_operand" "")
10860 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10861 [(match_operand 2 "" "") (match_operand 3 "" "")])
10862 (match_operand 4 "" "")
10864 (clobber (reg:CC CC_REGNUM))]
10865 "TARGET_ARM && reload_completed"
10866 [(set (match_dup 5) (match_dup 6))
10867 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10868 (set (match_dup 0) (match_dup 4)))]
10871 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10872 operands[2], operands[3]);
10874 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10875 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10880 [(set (match_operand:SI 0 "s_register_operand" "")
10881 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10882 [(match_operand 2 "" "") (match_operand 3 "" "")])
10883 (match_operand 4 "" "")
10884 (match_operand 5 "" "")))
10885 (clobber (reg:CC CC_REGNUM))]
10886 "TARGET_ARM && reload_completed"
10887 [(set (match_dup 6) (match_dup 7))
10888 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10889 (set (match_dup 0) (match_dup 4)))
10890 (cond_exec (match_dup 8)
10891 (set (match_dup 0) (match_dup 5)))]
10894 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10895 operands[2], operands[3]);
10896 enum rtx_code rc = GET_CODE (operands[1]);
10898 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10899 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10900 if (mode == CCFPmode || mode == CCFPEmode)
10901 rc = reverse_condition_maybe_unordered (rc);
10903 rc = reverse_condition (rc);
10905 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10910 [(set (match_operand:SI 0 "s_register_operand" "")
10911 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10912 [(match_operand:SI 2 "s_register_operand" "")
10913 (match_operand:SI 3 "arm_add_operand" "")])
10914 (match_operand:SI 4 "arm_rhs_operand" "")
10916 (match_operand:SI 5 "s_register_operand" ""))))
10917 (clobber (reg:CC CC_REGNUM))]
10918 "TARGET_ARM && reload_completed"
10919 [(set (match_dup 6) (match_dup 7))
10920 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10921 (set (match_dup 0) (match_dup 4)))
10922 (cond_exec (match_dup 8)
10923 (set (match_dup 0) (not:SI (match_dup 5))))]
10926 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10927 operands[2], operands[3]);
10928 enum rtx_code rc = GET_CODE (operands[1]);
10930 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10931 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10932 if (mode == CCFPmode || mode == CCFPEmode)
10933 rc = reverse_condition_maybe_unordered (rc);
10935 rc = reverse_condition (rc);
10937 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10941 (define_insn "*cond_move_not"
10942 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10943 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10944 [(match_operand 3 "cc_register" "") (const_int 0)])
10945 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10947 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10951 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10952 [(set_attr "conds" "use")
10953 (set_attr "type" "mvn_reg,multiple")
10954 (set_attr "length" "4,8")]
10957 ;; The next two patterns occur when an AND operation is followed by a
10958 ;; scc insn sequence
10960 (define_insn "*sign_extract_onebit"
10961 [(set (match_operand:SI 0 "s_register_operand" "=r")
10962 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10964 (match_operand:SI 2 "const_int_operand" "n")))
10965 (clobber (reg:CC CC_REGNUM))]
10968 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10969 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10970 return \"mvnne\\t%0, #0\";
10972 [(set_attr "conds" "clob")
10973 (set_attr "length" "8")
10974 (set_attr "type" "multiple")]
10977 (define_insn "*not_signextract_onebit"
10978 [(set (match_operand:SI 0 "s_register_operand" "=r")
10980 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10982 (match_operand:SI 2 "const_int_operand" "n"))))
10983 (clobber (reg:CC CC_REGNUM))]
10986 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10987 output_asm_insn (\"tst\\t%1, %2\", operands);
10988 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10989 return \"movne\\t%0, #0\";
10991 [(set_attr "conds" "clob")
10992 (set_attr "length" "12")
10993 (set_attr "type" "multiple")]
10995 ;; ??? The above patterns need auditing for Thumb-2
10997 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10998 ;; expressions. For simplicity, the first register is also in the unspec
11000 ;; To avoid the usage of GNU extension, the length attribute is computed
11001 ;; in a C function arm_attr_length_push_multi.
11002 (define_insn "*push_multi"
11003 [(match_parallel 2 "multi_register_push"
11004 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11005 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11006 UNSPEC_PUSH_MULT))])]
11010 int num_saves = XVECLEN (operands[2], 0);
11012 /* For the StrongARM at least it is faster to
11013 use STR to store only a single register.
11014 In Thumb mode always use push, and the assembler will pick
11015 something appropriate. */
11016 if (num_saves == 1 && TARGET_ARM)
11017 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11024 strcpy (pattern, \"push%?\\t{%1\");
11026 strcpy (pattern, \"push\\t{%1\");
11028 for (i = 1; i < num_saves; i++)
11030 strcat (pattern, \", %|\");
11032 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11035 strcat (pattern, \"}\");
11036 output_asm_insn (pattern, operands);
11041 [(set_attr "type" "store_16")
11042 (set (attr "length")
11043 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11046 (define_insn "stack_tie"
11047 [(set (mem:BLK (scratch))
11048 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11049 (match_operand:SI 1 "s_register_operand" "rk")]
11053 [(set_attr "length" "0")
11054 (set_attr "type" "block")]
11057 ;; Pop (as used in epilogue RTL)
11059 (define_insn "*load_multiple_with_writeback"
11060 [(match_parallel 0 "load_multiple_operation"
11061 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11062 (plus:SI (match_dup 1)
11063 (match_operand:SI 2 "const_int_I_operand" "I")))
11064 (set (match_operand:SI 3 "s_register_operand" "=rk")
11065 (mem:SI (match_dup 1)))
11067 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11070 arm_output_multireg_pop (operands, /*return_pc=*/false,
11071 /*cond=*/const_true_rtx,
11077 [(set_attr "type" "load_16")
11078 (set_attr "predicable" "yes")
11079 (set (attr "length")
11080 (symbol_ref "arm_attr_length_pop_multi (operands,
11081 /*return_pc=*/false,
11082 /*write_back_p=*/true)"))]
11085 ;; Pop with return (as used in epilogue RTL)
11087 ;; This instruction is generated when the registers are popped at the end of
11088 ;; epilogue. Here, instead of popping the value into LR and then generating
11089 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11091 (define_insn "*pop_multiple_with_writeback_and_return"
11092 [(match_parallel 0 "pop_multiple_return"
11094 (set (match_operand:SI 1 "s_register_operand" "+rk")
11095 (plus:SI (match_dup 1)
11096 (match_operand:SI 2 "const_int_I_operand" "I")))
11097 (set (match_operand:SI 3 "s_register_operand" "=rk")
11098 (mem:SI (match_dup 1)))
11100 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11103 arm_output_multireg_pop (operands, /*return_pc=*/true,
11104 /*cond=*/const_true_rtx,
11110 [(set_attr "type" "load_16")
11111 (set_attr "predicable" "yes")
11112 (set (attr "length")
11113 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11114 /*write_back_p=*/true)"))]
11117 (define_insn "*pop_multiple_with_return"
11118 [(match_parallel 0 "pop_multiple_return"
11120 (set (match_operand:SI 2 "s_register_operand" "=rk")
11121 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11123 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11126 arm_output_multireg_pop (operands, /*return_pc=*/true,
11127 /*cond=*/const_true_rtx,
11133 [(set_attr "type" "load_16")
11134 (set_attr "predicable" "yes")
11135 (set (attr "length")
11136 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11137 /*write_back_p=*/false)"))]
11140 ;; Load into PC and return
11141 (define_insn "*ldr_with_return"
11143 (set (reg:SI PC_REGNUM)
11144 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11145 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11146 "ldr%?\t%|pc, [%0], #4"
11147 [(set_attr "type" "load_4")
11148 (set_attr "predicable" "yes")]
11150 ;; Pop for floating point registers (as used in epilogue RTL)
11151 (define_insn "*vfp_pop_multiple_with_writeback"
11152 [(match_parallel 0 "pop_multiple_fp"
11153 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11154 (plus:SI (match_dup 1)
11155 (match_operand:SI 2 "const_int_I_operand" "I")))
11156 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11157 (mem:DF (match_dup 1)))])]
11158 "TARGET_32BIT && TARGET_HARD_FLOAT"
11161 int num_regs = XVECLEN (operands[0], 0);
11164 strcpy (pattern, \"vldm\\t\");
11165 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11166 strcat (pattern, \"!, {\");
11167 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11168 strcat (pattern, \"%P0\");
11169 if ((num_regs - 1) > 1)
11171 strcat (pattern, \"-%P1\");
11172 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11175 strcat (pattern, \"}\");
11176 output_asm_insn (pattern, op_list);
11180 [(set_attr "type" "load_16")
11181 (set_attr "conds" "unconditional")
11182 (set_attr "predicable" "no")]
11185 ;; Special patterns for dealing with the constant pool
11187 (define_insn "align_4"
11188 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11191 assemble_align (32);
11194 [(set_attr "type" "no_insn")]
11197 (define_insn "align_8"
11198 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11201 assemble_align (64);
11204 [(set_attr "type" "no_insn")]
11207 (define_insn "consttable_end"
11208 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11211 making_const_table = FALSE;
11214 [(set_attr "type" "no_insn")]
11217 (define_insn "consttable_1"
11218 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11221 making_const_table = TRUE;
11222 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11223 assemble_zeros (3);
11226 [(set_attr "length" "4")
11227 (set_attr "type" "no_insn")]
11230 (define_insn "consttable_2"
11231 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11235 rtx x = operands[0];
11236 making_const_table = TRUE;
11237 switch (GET_MODE_CLASS (GET_MODE (x)))
11240 arm_emit_fp16_const (x);
11243 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11244 assemble_zeros (2);
11249 [(set_attr "length" "4")
11250 (set_attr "type" "no_insn")]
11253 (define_insn "consttable_4"
11254 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11258 rtx x = operands[0];
11259 making_const_table = TRUE;
11260 scalar_float_mode float_mode;
11261 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11262 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11265 /* XXX: Sometimes gcc does something really dumb and ends up with
11266 a HIGH in a constant pool entry, usually because it's trying to
11267 load into a VFP register. We know this will always be used in
11268 combination with a LO_SUM which ignores the high bits, so just
11269 strip off the HIGH. */
11270 if (GET_CODE (x) == HIGH)
11272 assemble_integer (x, 4, BITS_PER_WORD, 1);
11273 mark_symbol_refs_as_used (x);
11277 [(set_attr "length" "4")
11278 (set_attr "type" "no_insn")]
11281 (define_insn "consttable_8"
11282 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11286 making_const_table = TRUE;
11287 scalar_float_mode float_mode;
11288 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11289 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11290 float_mode, BITS_PER_WORD);
11292 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11295 [(set_attr "length" "8")
11296 (set_attr "type" "no_insn")]
11299 (define_insn "consttable_16"
11300 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11304 making_const_table = TRUE;
11305 scalar_float_mode float_mode;
11306 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11307 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11308 float_mode, BITS_PER_WORD);
11310 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11313 [(set_attr "length" "16")
11314 (set_attr "type" "no_insn")]
11317 ;; V5 Instructions,
11319 (define_insn "clzsi2"
11320 [(set (match_operand:SI 0 "s_register_operand" "=r")
11321 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11322 "TARGET_32BIT && arm_arch5"
11324 [(set_attr "predicable" "yes")
11325 (set_attr "predicable_short_it" "no")
11326 (set_attr "type" "clz")])
11328 (define_insn "rbitsi2"
11329 [(set (match_operand:SI 0 "s_register_operand" "=r")
11330 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11331 "TARGET_32BIT && arm_arch_thumb2"
11333 [(set_attr "predicable" "yes")
11334 (set_attr "predicable_short_it" "no")
11335 (set_attr "type" "clz")])
11337 ;; Keep this as a CTZ expression until after reload and then split
11338 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11339 ;; to fold with any other expression.
11341 (define_insn_and_split "ctzsi2"
11342 [(set (match_operand:SI 0 "s_register_operand" "=r")
11343 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11344 "TARGET_32BIT && arm_arch_thumb2"
11346 "&& reload_completed"
11349 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11350 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11354 ;; V5E instructions.
11356 (define_insn "prefetch"
11357 [(prefetch (match_operand:SI 0 "address_operand" "p")
11358 (match_operand:SI 1 "" "")
11359 (match_operand:SI 2 "" ""))]
11360 "TARGET_32BIT && arm_arch5e"
11362 [(set_attr "type" "load_4")]
11365 ;; General predication pattern
11368 [(match_operator 0 "arm_comparison_operator"
11369 [(match_operand 1 "cc_register" "")
11372 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11374 [(set_attr "predicated" "yes")]
11377 (define_insn "force_register_use"
11378 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11381 [(set_attr "length" "0")
11382 (set_attr "type" "no_insn")]
11386 ;; Patterns for exception handling
11388 (define_expand "eh_return"
11389 [(use (match_operand 0 "general_operand" ""))]
11394 emit_insn (gen_arm_eh_return (operands[0]));
11396 emit_insn (gen_thumb_eh_return (operands[0]));
11401 ;; We can't expand this before we know where the link register is stored.
11402 (define_insn_and_split "arm_eh_return"
11403 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11405 (clobber (match_scratch:SI 1 "=&r"))]
11408 "&& reload_completed"
11412 arm_set_return_address (operands[0], operands[1]);
11420 (define_insn "load_tp_hard"
11421 [(set (match_operand:SI 0 "register_operand" "=r")
11422 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11424 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11425 [(set_attr "predicable" "yes")
11426 (set_attr "type" "mrs")]
11429 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11430 (define_insn "load_tp_soft"
11431 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11432 (clobber (reg:SI LR_REGNUM))
11433 (clobber (reg:SI IP_REGNUM))
11434 (clobber (reg:CC CC_REGNUM))]
11436 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11437 [(set_attr "conds" "clob")
11438 (set_attr "type" "branch")]
11441 ;; tls descriptor call
11442 (define_insn "tlscall"
11443 [(set (reg:SI R0_REGNUM)
11444 (unspec:SI [(reg:SI R0_REGNUM)
11445 (match_operand:SI 0 "" "X")
11446 (match_operand 1 "" "")] UNSPEC_TLS))
11447 (clobber (reg:SI R1_REGNUM))
11448 (clobber (reg:SI LR_REGNUM))
11449 (clobber (reg:SI CC_REGNUM))]
11452 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11453 INTVAL (operands[1]));
11454 return "bl\\t%c0(tlscall)";
11456 [(set_attr "conds" "clob")
11457 (set_attr "length" "4")
11458 (set_attr "type" "branch")]
11461 ;; For thread pointer builtin
11462 (define_expand "get_thread_pointersi"
11463 [(match_operand:SI 0 "s_register_operand" "=r")]
11467 arm_load_tp (operands[0]);
11473 ;; We only care about the lower 16 bits of the constant
11474 ;; being inserted into the upper 16 bits of the register.
11475 (define_insn "*arm_movtas_ze"
11476 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11479 (match_operand:SI 1 "const_int_operand" ""))]
11484 [(set_attr "arch" "32,v8mb")
11485 (set_attr "predicable" "yes")
11486 (set_attr "predicable_short_it" "no")
11487 (set_attr "length" "4")
11488 (set_attr "type" "alu_sreg")]
11491 (define_insn "*arm_rev"
11492 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11493 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11499 [(set_attr "arch" "t1,t2,32")
11500 (set_attr "length" "2,2,4")
11501 (set_attr "predicable" "no,yes,yes")
11502 (set_attr "predicable_short_it" "no")
11503 (set_attr "type" "rev")]
11506 (define_expand "arm_legacy_rev"
11507 [(set (match_operand:SI 2 "s_register_operand" "")
11508 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11512 (lshiftrt:SI (match_dup 2)
11514 (set (match_operand:SI 3 "s_register_operand" "")
11515 (rotatert:SI (match_dup 1)
11518 (and:SI (match_dup 2)
11519 (const_int -65281)))
11520 (set (match_operand:SI 0 "s_register_operand" "")
11521 (xor:SI (match_dup 3)
11527 ;; Reuse temporaries to keep register pressure down.
11528 (define_expand "thumb_legacy_rev"
11529 [(set (match_operand:SI 2 "s_register_operand" "")
11530 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11532 (set (match_operand:SI 3 "s_register_operand" "")
11533 (lshiftrt:SI (match_dup 1)
11536 (ior:SI (match_dup 3)
11538 (set (match_operand:SI 4 "s_register_operand" "")
11540 (set (match_operand:SI 5 "s_register_operand" "")
11541 (rotatert:SI (match_dup 1)
11544 (ashift:SI (match_dup 5)
11547 (lshiftrt:SI (match_dup 5)
11550 (ior:SI (match_dup 5)
11553 (rotatert:SI (match_dup 5)
11555 (set (match_operand:SI 0 "s_register_operand" "")
11556 (ior:SI (match_dup 5)
11562 ;; ARM-specific expansion of signed mod by power of 2
11563 ;; using conditional negate.
11564 ;; For r0 % n where n is a power of 2 produce:
11566 ;; and r0, r0, #(n - 1)
11567 ;; and r1, r1, #(n - 1)
11568 ;; rsbpl r0, r1, #0
11570 (define_expand "modsi3"
11571 [(match_operand:SI 0 "register_operand" "")
11572 (match_operand:SI 1 "register_operand" "")
11573 (match_operand:SI 2 "const_int_operand" "")]
11576 HOST_WIDE_INT val = INTVAL (operands[2]);
11579 || exact_log2 (val) <= 0)
11582 rtx mask = GEN_INT (val - 1);
11584 /* In the special case of x0 % 2 we can do the even shorter:
11587 rsblt r0, r0, #0. */
11591 rtx cc_reg = arm_gen_compare_reg (LT,
11592 operands[1], const0_rtx, NULL_RTX);
11593 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11594 rtx masked = gen_reg_rtx (SImode);
11596 emit_insn (gen_andsi3 (masked, operands[1], mask));
11597 emit_move_insn (operands[0],
11598 gen_rtx_IF_THEN_ELSE (SImode, cond,
11599 gen_rtx_NEG (SImode,
11605 rtx neg_op = gen_reg_rtx (SImode);
11606 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11609 /* Extract the condition register and mode. */
11610 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11611 rtx cc_reg = SET_DEST (cmp);
11612 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11614 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11616 rtx masked_neg = gen_reg_rtx (SImode);
11617 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11619 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11620 during expand does not always work. Do an IF_THEN_ELSE instead. */
11621 emit_move_insn (operands[0],
11622 gen_rtx_IF_THEN_ELSE (SImode, cond,
11623 gen_rtx_NEG (SImode, masked_neg),
11631 (define_expand "bswapsi2"
11632 [(set (match_operand:SI 0 "s_register_operand" "=r")
11633 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11634 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11638 rtx op2 = gen_reg_rtx (SImode);
11639 rtx op3 = gen_reg_rtx (SImode);
11643 rtx op4 = gen_reg_rtx (SImode);
11644 rtx op5 = gen_reg_rtx (SImode);
11646 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11647 op2, op3, op4, op5));
11651 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11660 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11661 ;; and unsigned variants, respectively. For rev16, expose
11662 ;; byte-swapping in the lower 16 bits only.
11663 (define_insn "*arm_revsh"
11664 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11665 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11671 [(set_attr "arch" "t1,t2,32")
11672 (set_attr "length" "2,2,4")
11673 (set_attr "type" "rev")]
11676 (define_insn "*arm_rev16"
11677 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11678 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11684 [(set_attr "arch" "t1,t2,32")
11685 (set_attr "length" "2,2,4")
11686 (set_attr "type" "rev")]
11689 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11690 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11691 ;; each valid permutation.
11693 (define_insn "arm_rev16si2"
11694 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11695 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11697 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11698 (and:SI (lshiftrt:SI (match_dup 1)
11700 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11702 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11703 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11705 [(set_attr "arch" "t1,t2,32")
11706 (set_attr "length" "2,2,4")
11707 (set_attr "type" "rev")]
11710 (define_insn "arm_rev16si2_alt"
11711 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11712 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11714 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11715 (and:SI (ashift:SI (match_dup 1)
11717 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11719 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11720 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11722 [(set_attr "arch" "t1,t2,32")
11723 (set_attr "length" "2,2,4")
11724 (set_attr "type" "rev")]
11727 (define_expand "bswaphi2"
11728 [(set (match_operand:HI 0 "s_register_operand" "=r")
11729 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11734 ;; Patterns for LDRD/STRD in Thumb2 mode
11736 (define_insn "*thumb2_ldrd"
11737 [(set (match_operand:SI 0 "s_register_operand" "=r")
11738 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11739 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11740 (set (match_operand:SI 3 "s_register_operand" "=r")
11741 (mem:SI (plus:SI (match_dup 1)
11742 (match_operand:SI 4 "const_int_operand" ""))))]
11743 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11744 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11745 && (operands_ok_ldrd_strd (operands[0], operands[3],
11746 operands[1], INTVAL (operands[2]),
11748 "ldrd%?\t%0, %3, [%1, %2]"
11749 [(set_attr "type" "load_8")
11750 (set_attr "predicable" "yes")
11751 (set_attr "predicable_short_it" "no")])
11753 (define_insn "*thumb2_ldrd_base"
11754 [(set (match_operand:SI 0 "s_register_operand" "=r")
11755 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11756 (set (match_operand:SI 2 "s_register_operand" "=r")
11757 (mem:SI (plus:SI (match_dup 1)
11759 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11760 && (operands_ok_ldrd_strd (operands[0], operands[2],
11761 operands[1], 0, false, true))"
11762 "ldrd%?\t%0, %2, [%1]"
11763 [(set_attr "type" "load_8")
11764 (set_attr "predicable" "yes")
11765 (set_attr "predicable_short_it" "no")])
11767 (define_insn "*thumb2_ldrd_base_neg"
11768 [(set (match_operand:SI 0 "s_register_operand" "=r")
11769 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11771 (set (match_operand:SI 2 "s_register_operand" "=r")
11772 (mem:SI (match_dup 1)))]
11773 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11774 && (operands_ok_ldrd_strd (operands[0], operands[2],
11775 operands[1], -4, false, true))"
11776 "ldrd%?\t%0, %2, [%1, #-4]"
11777 [(set_attr "type" "load_8")
11778 (set_attr "predicable" "yes")
11779 (set_attr "predicable_short_it" "no")])
11781 (define_insn "*thumb2_strd"
11782 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11783 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11784 (match_operand:SI 2 "s_register_operand" "r"))
11785 (set (mem:SI (plus:SI (match_dup 0)
11786 (match_operand:SI 3 "const_int_operand" "")))
11787 (match_operand:SI 4 "s_register_operand" "r"))]
11788 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11789 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11790 && (operands_ok_ldrd_strd (operands[2], operands[4],
11791 operands[0], INTVAL (operands[1]),
11793 "strd%?\t%2, %4, [%0, %1]"
11794 [(set_attr "type" "store_8")
11795 (set_attr "predicable" "yes")
11796 (set_attr "predicable_short_it" "no")])
11798 (define_insn "*thumb2_strd_base"
11799 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11800 (match_operand:SI 1 "s_register_operand" "r"))
11801 (set (mem:SI (plus:SI (match_dup 0)
11803 (match_operand:SI 2 "s_register_operand" "r"))]
11804 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11805 && (operands_ok_ldrd_strd (operands[1], operands[2],
11806 operands[0], 0, false, false))"
11807 "strd%?\t%1, %2, [%0]"
11808 [(set_attr "type" "store_8")
11809 (set_attr "predicable" "yes")
11810 (set_attr "predicable_short_it" "no")])
11812 (define_insn "*thumb2_strd_base_neg"
11813 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11815 (match_operand:SI 1 "s_register_operand" "r"))
11816 (set (mem:SI (match_dup 0))
11817 (match_operand:SI 2 "s_register_operand" "r"))]
11818 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11819 && (operands_ok_ldrd_strd (operands[1], operands[2],
11820 operands[0], -4, false, false))"
11821 "strd%?\t%1, %2, [%0, #-4]"
11822 [(set_attr "type" "store_8")
11823 (set_attr "predicable" "yes")
11824 (set_attr "predicable_short_it" "no")])
11826 ;; ARMv8 CRC32 instructions.
11827 (define_insn "<crc_variant>"
11828 [(set (match_operand:SI 0 "s_register_operand" "=r")
11829 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11830 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11833 "<crc_variant>\\t%0, %1, %2"
11834 [(set_attr "type" "crc")
11835 (set_attr "conds" "unconditional")]
11838 ;; Load the load/store double peephole optimizations.
11839 (include "ldrdstrd.md")
11841 ;; Load the load/store multiple patterns
11842 (include "ldmstm.md")
11844 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11845 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11846 ;; The operands are validated through the load_multiple_operation
11847 ;; match_parallel predicate rather than through constraints so enable it only
11849 (define_insn "*load_multiple"
11850 [(match_parallel 0 "load_multiple_operation"
11851 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11852 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11854 "TARGET_32BIT && reload_completed"
11857 arm_output_multireg_pop (operands, /*return_pc=*/false,
11858 /*cond=*/const_true_rtx,
11864 [(set_attr "predicable" "yes")]
11867 (define_expand "copysignsf3"
11868 [(match_operand:SF 0 "register_operand")
11869 (match_operand:SF 1 "register_operand")
11870 (match_operand:SF 2 "register_operand")]
11871 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11873 emit_move_insn (operands[0], operands[2]);
11874 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11875 GEN_INT (31), GEN_INT (0),
11876 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11881 (define_expand "copysigndf3"
11882 [(match_operand:DF 0 "register_operand")
11883 (match_operand:DF 1 "register_operand")
11884 (match_operand:DF 2 "register_operand")]
11885 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11887 rtx op0_low = gen_lowpart (SImode, operands[0]);
11888 rtx op0_high = gen_highpart (SImode, operands[0]);
11889 rtx op1_low = gen_lowpart (SImode, operands[1]);
11890 rtx op1_high = gen_highpart (SImode, operands[1]);
11891 rtx op2_high = gen_highpart (SImode, operands[2]);
11893 rtx scratch1 = gen_reg_rtx (SImode);
11894 rtx scratch2 = gen_reg_rtx (SImode);
11895 emit_move_insn (scratch1, op2_high);
11896 emit_move_insn (scratch2, op1_high);
11898 emit_insn(gen_rtx_SET(scratch1,
11899 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11900 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11901 emit_move_insn (op0_low, op1_low);
11902 emit_move_insn (op0_high, scratch2);
11908 ;; movmisalign patterns for HImode and SImode.
11909 (define_expand "movmisalign<mode>"
11910 [(match_operand:HSI 0 "general_operand")
11911 (match_operand:HSI 1 "general_operand")]
11914 /* This pattern is not permitted to fail during expansion: if both arguments
11915 are non-registers (e.g. memory := constant), force operand 1 into a
11917 rtx (* gen_unaligned_load)(rtx, rtx);
11918 rtx tmp_dest = operands[0];
11919 if (!s_register_operand (operands[0], <MODE>mode)
11920 && !s_register_operand (operands[1], <MODE>mode))
11921 operands[1] = force_reg (<MODE>mode, operands[1]);
11923 if (<MODE>mode == HImode)
11925 gen_unaligned_load = gen_unaligned_loadhiu;
11926 tmp_dest = gen_reg_rtx (SImode);
11929 gen_unaligned_load = gen_unaligned_loadsi;
11931 if (MEM_P (operands[1]))
11933 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11934 if (<MODE>mode == HImode)
11935 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11938 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11943 (define_insn "<cdp>"
11944 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11945 (match_operand:SI 1 "immediate_operand" "n")
11946 (match_operand:SI 2 "immediate_operand" "n")
11947 (match_operand:SI 3 "immediate_operand" "n")
11948 (match_operand:SI 4 "immediate_operand" "n")
11949 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11950 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11952 arm_const_bounds (operands[0], 0, 16);
11953 arm_const_bounds (operands[1], 0, 16);
11954 arm_const_bounds (operands[2], 0, (1 << 5));
11955 arm_const_bounds (operands[3], 0, (1 << 5));
11956 arm_const_bounds (operands[4], 0, (1 << 5));
11957 arm_const_bounds (operands[5], 0, 8);
11958 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11960 [(set_attr "length" "4")
11961 (set_attr "type" "coproc")])
11963 (define_insn "*ldc"
11964 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11965 (match_operand:SI 1 "immediate_operand" "n")
11966 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11967 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11969 arm_const_bounds (operands[0], 0, 16);
11970 arm_const_bounds (operands[1], 0, (1 << 5));
11971 return "<ldc>\\tp%c0, CR%c1, %2";
11973 [(set_attr "length" "4")
11974 (set_attr "type" "coproc")])
11976 (define_insn "*stc"
11977 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11978 (match_operand:SI 1 "immediate_operand" "n")
11979 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11980 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11982 arm_const_bounds (operands[0], 0, 16);
11983 arm_const_bounds (operands[1], 0, (1 << 5));
11984 return "<stc>\\tp%c0, CR%c1, %2";
11986 [(set_attr "length" "4")
11987 (set_attr "type" "coproc")])
11989 (define_expand "<ldc>"
11990 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11991 (match_operand:SI 1 "immediate_operand")
11992 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11993 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11995 (define_expand "<stc>"
11996 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11997 (match_operand:SI 1 "immediate_operand")
11998 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11999 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12001 (define_insn "<mcr>"
12002 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12003 (match_operand:SI 1 "immediate_operand" "n")
12004 (match_operand:SI 2 "s_register_operand" "r")
12005 (match_operand:SI 3 "immediate_operand" "n")
12006 (match_operand:SI 4 "immediate_operand" "n")
12007 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12008 (use (match_dup 2))]
12009 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12011 arm_const_bounds (operands[0], 0, 16);
12012 arm_const_bounds (operands[1], 0, 8);
12013 arm_const_bounds (operands[3], 0, (1 << 5));
12014 arm_const_bounds (operands[4], 0, (1 << 5));
12015 arm_const_bounds (operands[5], 0, 8);
12016 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12018 [(set_attr "length" "4")
12019 (set_attr "type" "coproc")])
12021 (define_insn "<mrc>"
12022 [(set (match_operand:SI 0 "s_register_operand" "=r")
12023 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12024 (match_operand:SI 2 "immediate_operand" "n")
12025 (match_operand:SI 3 "immediate_operand" "n")
12026 (match_operand:SI 4 "immediate_operand" "n")
12027 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12028 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12030 arm_const_bounds (operands[1], 0, 16);
12031 arm_const_bounds (operands[2], 0, 8);
12032 arm_const_bounds (operands[3], 0, (1 << 5));
12033 arm_const_bounds (operands[4], 0, (1 << 5));
12034 arm_const_bounds (operands[5], 0, 8);
12035 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12037 [(set_attr "length" "4")
12038 (set_attr "type" "coproc")])
12040 (define_insn "<mcrr>"
12041 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12042 (match_operand:SI 1 "immediate_operand" "n")
12043 (match_operand:DI 2 "s_register_operand" "r")
12044 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12045 (use (match_dup 2))]
12046 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12048 arm_const_bounds (operands[0], 0, 16);
12049 arm_const_bounds (operands[1], 0, 8);
12050 arm_const_bounds (operands[3], 0, (1 << 5));
12051 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12053 [(set_attr "length" "4")
12054 (set_attr "type" "coproc")])
12056 (define_insn "<mrrc>"
12057 [(set (match_operand:DI 0 "s_register_operand" "=r")
12058 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12059 (match_operand:SI 2 "immediate_operand" "n")
12060 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12061 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12063 arm_const_bounds (operands[1], 0, 16);
12064 arm_const_bounds (operands[2], 0, 8);
12065 arm_const_bounds (operands[3], 0, (1 << 5));
12066 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12068 [(set_attr "length" "4")
12069 (set_attr "type" "coproc")])
12071 ;; Vector bits common to IWMMXT and Neon
12072 (include "vec-common.md")
12073 ;; Load the Intel Wireless Multimedia Extension patterns
12074 (include "iwmmxt.md")
12075 ;; Load the VFP co-processor patterns
12077 ;; Thumb-1 patterns
12078 (include "thumb1.md")
12079 ;; Thumb-2 patterns
12080 (include "thumb2.md")
12082 (include "neon.md")
12084 (include "crypto.md")
12085 ;; Synchronization Primitives
12086 (include "sync.md")
12087 ;; Fixed-point patterns
12088 (include "arm-fixed.md")