1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2016 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;---------------------------------------------------------------------------
29 ;; Register numbers -- All machine registers should be defined here
31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (IP_REGNUM 12) ; Scratch register
34 (SP_REGNUM 13) ; Stack pointer
35 (LR_REGNUM 14) ; Return address register
36 (PC_REGNUM 15) ; Program counter
37 (LAST_ARM_REGNUM 15) ;
38 (CC_REGNUM 100) ; Condition code pseudo register
39 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
42 ;; 3rd operand to select_dominance_cc_mode
49 ;; conditional compare combination
60 ;;---------------------------------------------------------------------------
63 ;; Processor type. This is created automatically from arm-cores.def.
64 (include "arm-tune.md")
66 ;; Instruction classification types
69 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70 ; generating ARM code. This is used to control the length of some insn
71 ; patterns that share the same RTL in both ARM and Thumb code.
72 (define_attr "is_thumb" "yes,no"
73 (const (if_then_else (symbol_ref "TARGET_THUMB")
74 (const_string "yes") (const_string "no"))))
76 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
79 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
80 (define_attr "is_thumb1" "yes,no"
81 (const (if_then_else (symbol_ref "TARGET_THUMB1")
82 (const_string "yes") (const_string "no"))))
84 ; We use this attribute to disable alternatives that can produce 32-bit
85 ; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
86 ; that contain 32-bit instructions.
87 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
89 ; This attribute is used to disable a predicated alternative when we have
91 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
93 ;; Operand number of an input operand that is shifted. Zero if the
94 ;; given instruction does not shift one of its input operands.
95 (define_attr "shift" "" (const_int 0))
97 ;; [For compatibility with AArch64 in pipeline models]
98 ;; Attribute that specifies whether or not the instruction touches fp
100 (define_attr "fp" "no,yes" (const_string "no"))
102 ; Floating Point Unit. If we only have floating point emulation, then there
103 ; is no point in scheduling the floating point insns. (Well, for best
104 ; performance we should try and group them together).
105 (define_attr "fpu" "none,vfp"
106 (const (symbol_ref "arm_fpu_attr")))
108 ; Predicated means that the insn form is conditionally executed based on a
109 ; predicate. We default to 'no' because no Thumb patterns match this rule
110 ; and not all ARM insns do.
111 (define_attr "predicated" "yes,no" (const_string "no"))
113 ; LENGTH of an instruction (in bytes)
114 (define_attr "length" ""
117 ; The architecture which supports the instruction (or alternative).
118 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
119 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
120 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
121 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
122 ; Baseline. This attribute is used to compute attribute "enabled",
123 ; use type "any" to enable an alternative in all cases.
124 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
125 (const_string "any"))
127 (define_attr "arch_enabled" "no,yes"
128 (cond [(eq_attr "arch" "any")
131 (and (eq_attr "arch" "a")
132 (match_test "TARGET_ARM"))
135 (and (eq_attr "arch" "t")
136 (match_test "TARGET_THUMB"))
139 (and (eq_attr "arch" "t1")
140 (match_test "TARGET_THUMB1"))
143 (and (eq_attr "arch" "t2")
144 (match_test "TARGET_THUMB2"))
147 (and (eq_attr "arch" "32")
148 (match_test "TARGET_32BIT"))
151 (and (eq_attr "arch" "v6")
152 (match_test "TARGET_32BIT && arm_arch6"))
155 (and (eq_attr "arch" "nov6")
156 (match_test "TARGET_32BIT && !arm_arch6"))
159 (and (eq_attr "arch" "v6t2")
160 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
163 (and (eq_attr "arch" "v8mb")
164 (match_test "TARGET_THUMB1 && arm_arch8"))
167 (and (eq_attr "arch" "avoid_neon_for_64bits")
168 (match_test "TARGET_NEON")
169 (not (match_test "TARGET_PREFER_NEON_64BITS")))
172 (and (eq_attr "arch" "neon_for_64bits")
173 (match_test "TARGET_NEON")
174 (match_test "TARGET_PREFER_NEON_64BITS"))
177 (and (eq_attr "arch" "iwmmxt2")
178 (match_test "TARGET_REALLY_IWMMXT2"))
181 (and (eq_attr "arch" "armv6_or_vfpv3")
182 (match_test "arm_arch6 || TARGET_VFP3"))
185 (and (eq_attr "arch" "neon")
186 (match_test "TARGET_NEON"))
190 (const_string "no")))
192 (define_attr "opt" "any,speed,size"
193 (const_string "any"))
195 (define_attr "opt_enabled" "no,yes"
196 (cond [(eq_attr "opt" "any")
199 (and (eq_attr "opt" "speed")
200 (match_test "optimize_function_for_speed_p (cfun)"))
203 (and (eq_attr "opt" "size")
204 (match_test "optimize_function_for_size_p (cfun)"))
205 (const_string "yes")]
206 (const_string "no")))
208 (define_attr "use_literal_pool" "no,yes"
209 (cond [(and (eq_attr "type" "f_loads,f_loadd")
210 (match_test "CONSTANT_P (operands[1])"))
211 (const_string "yes")]
212 (const_string "no")))
214 ; Enable all alternatives that are both arch_enabled and insn_enabled.
215 ; FIXME:: opt_enabled has been temporarily removed till the time we have
216 ; an attribute that allows the use of such alternatives.
217 ; This depends on caching of speed_p, size_p on a per
218 ; alternative basis. The problem is that the enabled attribute
219 ; cannot depend on any state that is not cached or is not constant
220 ; for a compilation unit. We probably need a generic "hot/cold"
221 ; alternative which if implemented can help with this. We disable this
222 ; until such a time as this is implemented and / or the improvements or
223 ; regressions with removing this attribute are double checked.
224 ; See ashldi3_neon and <shift>di3_neon in neon.md.
226 (define_attr "enabled" "no,yes"
227 (cond [(and (eq_attr "predicable_short_it" "no")
228 (and (eq_attr "predicated" "yes")
229 (match_test "arm_restrict_it")))
232 (and (eq_attr "enabled_for_depr_it" "no")
233 (match_test "arm_restrict_it"))
236 (and (eq_attr "use_literal_pool" "yes")
237 (match_test "arm_disable_literal_pool"))
240 (eq_attr "arch_enabled" "no")
242 (const_string "yes")))
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed. If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address. It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
257 (define_attr "pool_range" ""
258 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259 (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262 (attr "arm_neg_pool_range")))
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268 [(set_attr "conds" "clob")
269 (set_attr "length" "4")
270 (set_attr "pool_range" "250")])
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions. It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
280 ; USE means that the condition codes are used by the insn in the process of
281 ; outputting code, this means (at present) that we can't use the insn in
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ; well defined manner.
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ; they are altered at all
290 ; UNCONDITIONAL means the instruction can not be conditionally executed and
291 ; that the instruction does not use or alter the condition codes.
293 ; NOCOND means that the instruction does not use or alter the condition
294 ; codes but can be converted into a conditionally exectuted instruction.
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
298 (ior (eq_attr "is_thumb1" "yes")
299 (eq_attr "type" "call"))
300 (const_string "clob")
301 (if_then_else (eq_attr "is_neon_type" "no")
302 (const_string "nocond")
303 (const_string "unconditional"))))
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by
307 ; gen...). We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
311 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
312 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor. Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320 (if_then_else (eq_attr "type"
323 (const_string "no")))
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328 (if_then_else (eq_attr "type"
329 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345 (const_string "single")
346 (const_string "multi")))
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label. Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
357 ;;---------------------------------------------------------------------------
360 (include "unspecs.md")
362 ;;---------------------------------------------------------------------------
365 (include "iterators.md")
367 ;;---------------------------------------------------------------------------
370 (include "predicates.md")
371 (include "constraints.md")
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
376 (define_attr "tune_cortexr4" "yes,no"
378 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
380 (const_string "no"))))
382 ;; True if the generic scheduling description should be used.
384 (define_attr "generic_sched" "yes,no"
386 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
388 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389 cortexa9,cortexa12,cortexa15,cortexa17,\
390 cortexa53,cortexa57,cortexm4,cortexm7,\
391 exynosm1,marvell_pj4,xgene1")
392 (eq_attr "tune_cortexr4" "yes"))
394 (const_string "yes"))))
396 (define_attr "generic_vfp" "yes,no"
398 (and (eq_attr "fpu" "vfp")
399 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
400 cortexa8,cortexa9,cortexa53,cortexm4,\
401 cortexm7,marvell_pj4,xgene1")
402 (eq_attr "tune_cortexr4" "no"))
404 (const_string "no"))))
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
436 ;;---------------------------------------------------------------------------
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
445 (define_expand "adddi3"
447 [(set (match_operand:DI 0 "s_register_operand" "")
448 (plus:DI (match_operand:DI 1 "s_register_operand" "")
449 (match_operand:DI 2 "arm_adddi_operand" "")))
450 (clobber (reg:CC CC_REGNUM))])]
455 if (!REG_P (operands[1]))
456 operands[1] = force_reg (DImode, operands[1]);
457 if (!REG_P (operands[2]))
458 operands[2] = force_reg (DImode, operands[2]);
463 (define_insn_and_split "*arm_adddi3"
464 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
465 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
466 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
467 (clobber (reg:CC CC_REGNUM))]
468 "TARGET_32BIT && !TARGET_NEON"
470 "TARGET_32BIT && reload_completed
471 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
472 [(parallel [(set (reg:CC_C CC_REGNUM)
473 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
475 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
476 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
477 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
480 operands[3] = gen_highpart (SImode, operands[0]);
481 operands[0] = gen_lowpart (SImode, operands[0]);
482 operands[4] = gen_highpart (SImode, operands[1]);
483 operands[1] = gen_lowpart (SImode, operands[1]);
484 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
485 operands[2] = gen_lowpart (SImode, operands[2]);
487 [(set_attr "conds" "clob")
488 (set_attr "length" "8")
489 (set_attr "type" "multiple")]
492 (define_insn_and_split "*adddi_sesidi_di"
493 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
494 (plus:DI (sign_extend:DI
495 (match_operand:SI 2 "s_register_operand" "r,r"))
496 (match_operand:DI 1 "s_register_operand" "0,r")))
497 (clobber (reg:CC CC_REGNUM))]
500 "TARGET_32BIT && reload_completed"
501 [(parallel [(set (reg:CC_C CC_REGNUM)
502 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
504 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
505 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
508 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
511 operands[3] = gen_highpart (SImode, operands[0]);
512 operands[0] = gen_lowpart (SImode, operands[0]);
513 operands[4] = gen_highpart (SImode, operands[1]);
514 operands[1] = gen_lowpart (SImode, operands[1]);
515 operands[2] = gen_lowpart (SImode, operands[2]);
517 [(set_attr "conds" "clob")
518 (set_attr "length" "8")
519 (set_attr "type" "multiple")]
522 (define_insn_and_split "*adddi_zesidi_di"
523 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
524 (plus:DI (zero_extend:DI
525 (match_operand:SI 2 "s_register_operand" "r,r"))
526 (match_operand:DI 1 "s_register_operand" "0,r")))
527 (clobber (reg:CC CC_REGNUM))]
530 "TARGET_32BIT && reload_completed"
531 [(parallel [(set (reg:CC_C CC_REGNUM)
532 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
534 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
535 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
536 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
539 operands[3] = gen_highpart (SImode, operands[0]);
540 operands[0] = gen_lowpart (SImode, operands[0]);
541 operands[4] = gen_highpart (SImode, operands[1]);
542 operands[1] = gen_lowpart (SImode, operands[1]);
543 operands[2] = gen_lowpart (SImode, operands[2]);
545 [(set_attr "conds" "clob")
546 (set_attr "length" "8")
547 (set_attr "type" "multiple")]
550 (define_expand "addsi3"
551 [(set (match_operand:SI 0 "s_register_operand" "")
552 (plus:SI (match_operand:SI 1 "s_register_operand" "")
553 (match_operand:SI 2 "reg_or_int_operand" "")))]
556 if (TARGET_32BIT && CONST_INT_P (operands[2]))
558 arm_split_constant (PLUS, SImode, NULL_RTX,
559 INTVAL (operands[2]), operands[0], operands[1],
560 optimize && can_create_pseudo_p ());
566 ; If there is a scratch available, this will be faster than synthesizing the
569 [(match_scratch:SI 3 "r")
570 (set (match_operand:SI 0 "arm_general_register_operand" "")
571 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
572 (match_operand:SI 2 "const_int_operand" "")))]
574 !(const_ok_for_arm (INTVAL (operands[2]))
575 || const_ok_for_arm (-INTVAL (operands[2])))
576 && const_ok_for_arm (~INTVAL (operands[2]))"
577 [(set (match_dup 3) (match_dup 2))
578 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
582 ;; The r/r/k alternative is required when reloading the address
583 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
584 ;; put the duplicated register first, and not try the commutative version.
585 (define_insn_and_split "*arm_addsi3"
586 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
587 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
588 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
603 subw%?\\t%0, %1, #%n2
604 subw%?\\t%0, %1, #%n2
607 && CONST_INT_P (operands[2])
608 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
609 && (reload_completed || !arm_eliminable_register (operands[1]))"
610 [(clobber (const_int 0))]
612 arm_split_constant (PLUS, SImode, curr_insn,
613 INTVAL (operands[2]), operands[0],
617 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
618 (set_attr "predicable" "yes")
619 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
620 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
621 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
622 (const_string "alu_imm")
623 (const_string "alu_sreg")))
627 (define_insn "addsi3_compare0"
628 [(set (reg:CC_NOOV CC_REGNUM)
630 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
631 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
633 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
634 (plus:SI (match_dup 1) (match_dup 2)))]
638 subs%?\\t%0, %1, #%n2
640 [(set_attr "conds" "set")
641 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
644 (define_insn "*addsi3_compare0_scratch"
645 [(set (reg:CC_NOOV CC_REGNUM)
647 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
648 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
655 [(set_attr "conds" "set")
656 (set_attr "predicable" "yes")
657 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
660 (define_insn "*compare_negsi_si"
661 [(set (reg:CC_Z CC_REGNUM)
663 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
664 (match_operand:SI 1 "s_register_operand" "l,r")))]
667 [(set_attr "conds" "set")
668 (set_attr "predicable" "yes")
669 (set_attr "arch" "t2,*")
670 (set_attr "length" "2,4")
671 (set_attr "predicable_short_it" "yes,no")
672 (set_attr "type" "alus_sreg")]
675 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
676 ;; addend is a constant.
677 (define_insn "cmpsi2_addneg"
678 [(set (reg:CC CC_REGNUM)
680 (match_operand:SI 1 "s_register_operand" "r,r")
681 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
682 (set (match_operand:SI 0 "s_register_operand" "=r,r")
683 (plus:SI (match_dup 1)
684 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
685 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
688 subs%?\\t%0, %1, #%n3"
689 [(set_attr "conds" "set")
690 (set_attr "type" "alus_sreg")]
693 ;; Convert the sequence
695 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
699 ;; bcs dest ((unsigned)rn >= 1)
700 ;; similarly for the beq variant using bcc.
701 ;; This is a common looping idiom (while (n--))
703 [(set (match_operand:SI 0 "arm_general_register_operand" "")
704 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
706 (set (match_operand 2 "cc_register" "")
707 (compare (match_dup 0) (const_int -1)))
709 (if_then_else (match_operator 3 "equality_operator"
710 [(match_dup 2) (const_int 0)])
711 (match_operand 4 "" "")
712 (match_operand 5 "" "")))]
713 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
717 (match_dup 1) (const_int 1)))
718 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
720 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
723 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
724 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
727 operands[2], const0_rtx);"
730 ;; The next four insns work because they compare the result with one of
731 ;; the operands, and we know that the use of the condition code is
732 ;; either GEU or LTU, so we can use the carry flag from the addition
733 ;; instead of doing the compare a second time.
734 (define_insn "*addsi3_compare_op1"
735 [(set (reg:CC_C CC_REGNUM)
737 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
738 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
740 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
741 (plus:SI (match_dup 1) (match_dup 2)))]
745 subs%?\\t%0, %1, #%n2
747 [(set_attr "conds" "set")
748 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
751 (define_insn "*addsi3_compare_op2"
752 [(set (reg:CC_C CC_REGNUM)
754 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
755 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
757 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
758 (plus:SI (match_dup 1) (match_dup 2)))]
762 subs%?\\t%0, %1, #%n2
764 [(set_attr "conds" "set")
765 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
768 (define_insn "*compare_addsi2_op0"
769 [(set (reg:CC_C CC_REGNUM)
771 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
772 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
781 [(set_attr "conds" "set")
782 (set_attr "predicable" "yes")
783 (set_attr "arch" "t2,t2,*,*,*")
784 (set_attr "predicable_short_it" "yes,yes,no,no,no")
785 (set_attr "length" "2,2,4,4,4")
786 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
789 (define_insn "*compare_addsi2_op1"
790 [(set (reg:CC_C CC_REGNUM)
792 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
793 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
802 [(set_attr "conds" "set")
803 (set_attr "predicable" "yes")
804 (set_attr "arch" "t2,t2,*,*,*")
805 (set_attr "predicable_short_it" "yes,yes,no,no,no")
806 (set_attr "length" "2,2,4,4,4")
807 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
810 (define_insn "*addsi3_carryin_<optab>"
811 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
812 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
813 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
814 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
819 sbc%?\\t%0, %1, #%B2"
820 [(set_attr "conds" "use")
821 (set_attr "predicable" "yes")
822 (set_attr "arch" "t2,*,*")
823 (set_attr "length" "4")
824 (set_attr "predicable_short_it" "yes,no,no")
825 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
828 (define_insn "*addsi3_carryin_alt2_<optab>"
829 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
830 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
831 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
832 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
837 sbc%?\\t%0, %1, #%B2"
838 [(set_attr "conds" "use")
839 (set_attr "predicable" "yes")
840 (set_attr "arch" "t2,*,*")
841 (set_attr "length" "4")
842 (set_attr "predicable_short_it" "yes,no,no")
843 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
846 (define_insn "*addsi3_carryin_shift_<optab>"
847 [(set (match_operand:SI 0 "s_register_operand" "=r")
849 (match_operator:SI 2 "shift_operator"
850 [(match_operand:SI 3 "s_register_operand" "r")
851 (match_operand:SI 4 "reg_or_int_operand" "rM")])
852 (match_operand:SI 1 "s_register_operand" "r"))
853 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
855 "adc%?\\t%0, %1, %3%S2"
856 [(set_attr "conds" "use")
857 (set_attr "predicable" "yes")
858 (set_attr "predicable_short_it" "no")
859 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
860 (const_string "alu_shift_imm")
861 (const_string "alu_shift_reg")))]
864 (define_insn "*addsi3_carryin_clobercc_<optab>"
865 [(set (match_operand:SI 0 "s_register_operand" "=r")
866 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
867 (match_operand:SI 2 "arm_rhs_operand" "rI"))
868 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
869 (clobber (reg:CC CC_REGNUM))]
871 "adcs%?\\t%0, %1, %2"
872 [(set_attr "conds" "set")
873 (set_attr "type" "adcs_reg")]
876 (define_insn "*subsi3_carryin"
877 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
878 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
879 (match_operand:SI 2 "s_register_operand" "r,r"))
880 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
885 [(set_attr "conds" "use")
886 (set_attr "arch" "*,a")
887 (set_attr "predicable" "yes")
888 (set_attr "predicable_short_it" "no")
889 (set_attr "type" "adc_reg,adc_imm")]
892 (define_insn "*subsi3_carryin_const"
893 [(set (match_operand:SI 0 "s_register_operand" "=r")
894 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
895 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
896 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
899 [(set_attr "conds" "use")
900 (set_attr "type" "adc_imm")]
903 (define_insn "*subsi3_carryin_compare"
904 [(set (reg:CC CC_REGNUM)
905 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
906 (match_operand:SI 2 "s_register_operand" "r")))
907 (set (match_operand:SI 0 "s_register_operand" "=r")
908 (minus:SI (minus:SI (match_dup 1)
910 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
913 [(set_attr "conds" "set")
914 (set_attr "type" "adcs_reg")]
917 (define_insn "*subsi3_carryin_compare_const"
918 [(set (reg:CC CC_REGNUM)
919 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
920 (match_operand:SI 2 "arm_not_operand" "K")))
921 (set (match_operand:SI 0 "s_register_operand" "=r")
922 (minus:SI (plus:SI (match_dup 1)
924 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
926 "sbcs\\t%0, %1, #%B2"
927 [(set_attr "conds" "set")
928 (set_attr "type" "adcs_imm")]
931 (define_insn "*subsi3_carryin_shift"
932 [(set (match_operand:SI 0 "s_register_operand" "=r")
934 (match_operand:SI 1 "s_register_operand" "r")
935 (match_operator:SI 2 "shift_operator"
936 [(match_operand:SI 3 "s_register_operand" "r")
937 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
938 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
940 "sbc%?\\t%0, %1, %3%S2"
941 [(set_attr "conds" "use")
942 (set_attr "predicable" "yes")
943 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
944 (const_string "alu_shift_imm")
945 (const_string "alu_shift_reg")))]
948 (define_insn "*rsbsi3_carryin_shift"
949 [(set (match_operand:SI 0 "s_register_operand" "=r")
951 (match_operator:SI 2 "shift_operator"
952 [(match_operand:SI 3 "s_register_operand" "r")
953 (match_operand:SI 4 "reg_or_int_operand" "rM")])
954 (match_operand:SI 1 "s_register_operand" "r"))
955 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
957 "rsc%?\\t%0, %1, %3%S2"
958 [(set_attr "conds" "use")
959 (set_attr "predicable" "yes")
960 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
961 (const_string "alu_shift_imm")
962 (const_string "alu_shift_reg")))]
965 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
967 [(set (match_operand:SI 0 "s_register_operand" "")
968 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
969 (match_operand:SI 2 "s_register_operand" ""))
971 (clobber (match_operand:SI 3 "s_register_operand" ""))]
973 [(set (match_dup 3) (match_dup 1))
974 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
976 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
979 (define_expand "addsf3"
980 [(set (match_operand:SF 0 "s_register_operand" "")
981 (plus:SF (match_operand:SF 1 "s_register_operand" "")
982 (match_operand:SF 2 "s_register_operand" "")))]
983 "TARGET_32BIT && TARGET_HARD_FLOAT"
987 (define_expand "adddf3"
988 [(set (match_operand:DF 0 "s_register_operand" "")
989 (plus:DF (match_operand:DF 1 "s_register_operand" "")
990 (match_operand:DF 2 "s_register_operand" "")))]
991 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
995 (define_expand "subdi3"
997 [(set (match_operand:DI 0 "s_register_operand" "")
998 (minus:DI (match_operand:DI 1 "s_register_operand" "")
999 (match_operand:DI 2 "s_register_operand" "")))
1000 (clobber (reg:CC CC_REGNUM))])]
1005 if (!REG_P (operands[1]))
1006 operands[1] = force_reg (DImode, operands[1]);
1007 if (!REG_P (operands[2]))
1008 operands[2] = force_reg (DImode, operands[2]);
1013 (define_insn_and_split "*arm_subdi3"
1014 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1015 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1016 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1017 (clobber (reg:CC CC_REGNUM))]
1018 "TARGET_32BIT && !TARGET_NEON"
1019 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1020 "&& reload_completed"
1021 [(parallel [(set (reg:CC CC_REGNUM)
1022 (compare:CC (match_dup 1) (match_dup 2)))
1023 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1024 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1025 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1027 operands[3] = gen_highpart (SImode, operands[0]);
1028 operands[0] = gen_lowpart (SImode, operands[0]);
1029 operands[4] = gen_highpart (SImode, operands[1]);
1030 operands[1] = gen_lowpart (SImode, operands[1]);
1031 operands[5] = gen_highpart (SImode, operands[2]);
1032 operands[2] = gen_lowpart (SImode, operands[2]);
1034 [(set_attr "conds" "clob")
1035 (set_attr "length" "8")
1036 (set_attr "type" "multiple")]
1039 (define_insn_and_split "*subdi_di_zesidi"
1040 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1041 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1043 (match_operand:SI 2 "s_register_operand" "r,r"))))
1044 (clobber (reg:CC CC_REGNUM))]
1046 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1047 "&& reload_completed"
1048 [(parallel [(set (reg:CC CC_REGNUM)
1049 (compare:CC (match_dup 1) (match_dup 2)))
1050 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1051 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1052 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1054 operands[3] = gen_highpart (SImode, operands[0]);
1055 operands[0] = gen_lowpart (SImode, operands[0]);
1056 operands[4] = gen_highpart (SImode, operands[1]);
1057 operands[1] = gen_lowpart (SImode, operands[1]);
1058 operands[5] = GEN_INT (~0);
1060 [(set_attr "conds" "clob")
1061 (set_attr "length" "8")
1062 (set_attr "type" "multiple")]
1065 (define_insn_and_split "*subdi_di_sesidi"
1066 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1067 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1069 (match_operand:SI 2 "s_register_operand" "r,r"))))
1070 (clobber (reg:CC CC_REGNUM))]
1072 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1073 "&& reload_completed"
1074 [(parallel [(set (reg:CC CC_REGNUM)
1075 (compare:CC (match_dup 1) (match_dup 2)))
1076 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1077 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1078 (ashiftrt:SI (match_dup 2)
1080 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1082 operands[3] = gen_highpart (SImode, operands[0]);
1083 operands[0] = gen_lowpart (SImode, operands[0]);
1084 operands[4] = gen_highpart (SImode, operands[1]);
1085 operands[1] = gen_lowpart (SImode, operands[1]);
1087 [(set_attr "conds" "clob")
1088 (set_attr "length" "8")
1089 (set_attr "type" "multiple")]
1092 (define_insn_and_split "*subdi_zesidi_di"
1093 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1094 (minus:DI (zero_extend:DI
1095 (match_operand:SI 2 "s_register_operand" "r,r"))
1096 (match_operand:DI 1 "s_register_operand" "0,r")))
1097 (clobber (reg:CC CC_REGNUM))]
1099 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1101 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1102 "&& reload_completed"
1103 [(parallel [(set (reg:CC CC_REGNUM)
1104 (compare:CC (match_dup 2) (match_dup 1)))
1105 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1106 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1107 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1109 operands[3] = gen_highpart (SImode, operands[0]);
1110 operands[0] = gen_lowpart (SImode, operands[0]);
1111 operands[4] = gen_highpart (SImode, operands[1]);
1112 operands[1] = gen_lowpart (SImode, operands[1]);
1114 [(set_attr "conds" "clob")
1115 (set_attr "length" "8")
1116 (set_attr "type" "multiple")]
1119 (define_insn_and_split "*subdi_sesidi_di"
1120 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1121 (minus:DI (sign_extend:DI
1122 (match_operand:SI 2 "s_register_operand" "r,r"))
1123 (match_operand:DI 1 "s_register_operand" "0,r")))
1124 (clobber (reg:CC CC_REGNUM))]
1126 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1128 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1129 "&& reload_completed"
1130 [(parallel [(set (reg:CC CC_REGNUM)
1131 (compare:CC (match_dup 2) (match_dup 1)))
1132 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1133 (set (match_dup 3) (minus:SI (minus:SI
1134 (ashiftrt:SI (match_dup 2)
1137 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1139 operands[3] = gen_highpart (SImode, operands[0]);
1140 operands[0] = gen_lowpart (SImode, operands[0]);
1141 operands[4] = gen_highpart (SImode, operands[1]);
1142 operands[1] = gen_lowpart (SImode, operands[1]);
1144 [(set_attr "conds" "clob")
1145 (set_attr "length" "8")
1146 (set_attr "type" "multiple")]
1149 (define_insn_and_split "*subdi_zesidi_zesidi"
1150 [(set (match_operand:DI 0 "s_register_operand" "=r")
1151 (minus:DI (zero_extend:DI
1152 (match_operand:SI 1 "s_register_operand" "r"))
1154 (match_operand:SI 2 "s_register_operand" "r"))))
1155 (clobber (reg:CC CC_REGNUM))]
1157 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1158 "&& reload_completed"
1159 [(parallel [(set (reg:CC CC_REGNUM)
1160 (compare:CC (match_dup 1) (match_dup 2)))
1161 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1162 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1163 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1165 operands[3] = gen_highpart (SImode, operands[0]);
1166 operands[0] = gen_lowpart (SImode, operands[0]);
1168 [(set_attr "conds" "clob")
1169 (set_attr "length" "8")
1170 (set_attr "type" "multiple")]
1173 (define_expand "subsi3"
1174 [(set (match_operand:SI 0 "s_register_operand" "")
1175 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1176 (match_operand:SI 2 "s_register_operand" "")))]
1179 if (CONST_INT_P (operands[1]))
1183 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1184 operands[1] = force_reg (SImode, operands[1]);
1187 arm_split_constant (MINUS, SImode, NULL_RTX,
1188 INTVAL (operands[1]), operands[0],
1190 optimize && can_create_pseudo_p ());
1194 else /* TARGET_THUMB1 */
1195 operands[1] = force_reg (SImode, operands[1]);
1200 ; ??? Check Thumb-2 split length
1201 (define_insn_and_split "*arm_subsi3_insn"
1202 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1203 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1204 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1216 "&& (CONST_INT_P (operands[1])
1217 && !const_ok_for_arm (INTVAL (operands[1])))"
1218 [(clobber (const_int 0))]
1220 arm_split_constant (MINUS, SImode, curr_insn,
1221 INTVAL (operands[1]), operands[0], operands[2], 0);
1224 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1225 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1226 (set_attr "predicable" "yes")
1227 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1228 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1232 [(match_scratch:SI 3 "r")
1233 (set (match_operand:SI 0 "arm_general_register_operand" "")
1234 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1235 (match_operand:SI 2 "arm_general_register_operand" "")))]
1237 && !const_ok_for_arm (INTVAL (operands[1]))
1238 && const_ok_for_arm (~INTVAL (operands[1]))"
1239 [(set (match_dup 3) (match_dup 1))
1240 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1244 (define_insn "subsi3_compare0"
1245 [(set (reg:CC_NOOV CC_REGNUM)
1247 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1248 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1250 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1251 (minus:SI (match_dup 1) (match_dup 2)))]
1256 rsbs%?\\t%0, %2, %1"
1257 [(set_attr "conds" "set")
1258 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1261 (define_insn "subsi3_compare"
1262 [(set (reg:CC CC_REGNUM)
1263 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1264 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1265 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1266 (minus:SI (match_dup 1) (match_dup 2)))]
1271 rsbs%?\\t%0, %2, %1"
1272 [(set_attr "conds" "set")
1273 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1276 (define_expand "subsf3"
1277 [(set (match_operand:SF 0 "s_register_operand" "")
1278 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1279 (match_operand:SF 2 "s_register_operand" "")))]
1280 "TARGET_32BIT && TARGET_HARD_FLOAT"
1284 (define_expand "subdf3"
1285 [(set (match_operand:DF 0 "s_register_operand" "")
1286 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1287 (match_operand:DF 2 "s_register_operand" "")))]
1288 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1293 ;; Multiplication insns
1295 (define_expand "mulhi3"
1296 [(set (match_operand:HI 0 "s_register_operand" "")
1297 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1298 (match_operand:HI 2 "s_register_operand" "")))]
1299 "TARGET_DSP_MULTIPLY"
1302 rtx result = gen_reg_rtx (SImode);
1303 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1304 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1309 (define_expand "mulsi3"
1310 [(set (match_operand:SI 0 "s_register_operand" "")
1311 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1312 (match_operand:SI 1 "s_register_operand" "")))]
1317 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1318 (define_insn "*arm_mulsi3"
1319 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1320 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1321 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1322 "TARGET_32BIT && !arm_arch6"
1323 "mul%?\\t%0, %2, %1"
1324 [(set_attr "type" "mul")
1325 (set_attr "predicable" "yes")]
1328 (define_insn "*arm_mulsi3_v6"
1329 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1330 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1331 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1332 "TARGET_32BIT && arm_arch6"
1333 "mul%?\\t%0, %1, %2"
1334 [(set_attr "type" "mul")
1335 (set_attr "predicable" "yes")
1336 (set_attr "arch" "t2,t2,*")
1337 (set_attr "length" "4")
1338 (set_attr "predicable_short_it" "yes,yes,no")]
1341 (define_insn "*mulsi3_compare0"
1342 [(set (reg:CC_NOOV CC_REGNUM)
1343 (compare:CC_NOOV (mult:SI
1344 (match_operand:SI 2 "s_register_operand" "r,r")
1345 (match_operand:SI 1 "s_register_operand" "%0,r"))
1347 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1348 (mult:SI (match_dup 2) (match_dup 1)))]
1349 "TARGET_ARM && !arm_arch6"
1350 "muls%?\\t%0, %2, %1"
1351 [(set_attr "conds" "set")
1352 (set_attr "type" "muls")]
1355 (define_insn "*mulsi3_compare0_v6"
1356 [(set (reg:CC_NOOV CC_REGNUM)
1357 (compare:CC_NOOV (mult:SI
1358 (match_operand:SI 2 "s_register_operand" "r")
1359 (match_operand:SI 1 "s_register_operand" "r"))
1361 (set (match_operand:SI 0 "s_register_operand" "=r")
1362 (mult:SI (match_dup 2) (match_dup 1)))]
1363 "TARGET_ARM && arm_arch6 && optimize_size"
1364 "muls%?\\t%0, %2, %1"
1365 [(set_attr "conds" "set")
1366 (set_attr "type" "muls")]
1369 (define_insn "*mulsi_compare0_scratch"
1370 [(set (reg:CC_NOOV CC_REGNUM)
1371 (compare:CC_NOOV (mult:SI
1372 (match_operand:SI 2 "s_register_operand" "r,r")
1373 (match_operand:SI 1 "s_register_operand" "%0,r"))
1375 (clobber (match_scratch:SI 0 "=&r,&r"))]
1376 "TARGET_ARM && !arm_arch6"
1377 "muls%?\\t%0, %2, %1"
1378 [(set_attr "conds" "set")
1379 (set_attr "type" "muls")]
1382 (define_insn "*mulsi_compare0_scratch_v6"
1383 [(set (reg:CC_NOOV CC_REGNUM)
1384 (compare:CC_NOOV (mult:SI
1385 (match_operand:SI 2 "s_register_operand" "r")
1386 (match_operand:SI 1 "s_register_operand" "r"))
1388 (clobber (match_scratch:SI 0 "=r"))]
1389 "TARGET_ARM && arm_arch6 && optimize_size"
1390 "muls%?\\t%0, %2, %1"
1391 [(set_attr "conds" "set")
1392 (set_attr "type" "muls")]
1395 ;; Unnamed templates to match MLA instruction.
1397 (define_insn "*mulsi3addsi"
1398 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1400 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1401 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1402 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1403 "TARGET_32BIT && !arm_arch6"
1404 "mla%?\\t%0, %2, %1, %3"
1405 [(set_attr "type" "mla")
1406 (set_attr "predicable" "yes")]
1409 (define_insn "*mulsi3addsi_v6"
1410 [(set (match_operand:SI 0 "s_register_operand" "=r")
1412 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1413 (match_operand:SI 1 "s_register_operand" "r"))
1414 (match_operand:SI 3 "s_register_operand" "r")))]
1415 "TARGET_32BIT && arm_arch6"
1416 "mla%?\\t%0, %2, %1, %3"
1417 [(set_attr "type" "mla")
1418 (set_attr "predicable" "yes")
1419 (set_attr "predicable_short_it" "no")]
1422 (define_insn "*mulsi3addsi_compare0"
1423 [(set (reg:CC_NOOV CC_REGNUM)
1426 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1427 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1428 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1430 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1431 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1433 "TARGET_ARM && arm_arch6"
1434 "mlas%?\\t%0, %2, %1, %3"
1435 [(set_attr "conds" "set")
1436 (set_attr "type" "mlas")]
1439 (define_insn "*mulsi3addsi_compare0_v6"
1440 [(set (reg:CC_NOOV CC_REGNUM)
1443 (match_operand:SI 2 "s_register_operand" "r")
1444 (match_operand:SI 1 "s_register_operand" "r"))
1445 (match_operand:SI 3 "s_register_operand" "r"))
1447 (set (match_operand:SI 0 "s_register_operand" "=r")
1448 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1450 "TARGET_ARM && arm_arch6 && optimize_size"
1451 "mlas%?\\t%0, %2, %1, %3"
1452 [(set_attr "conds" "set")
1453 (set_attr "type" "mlas")]
1456 (define_insn "*mulsi3addsi_compare0_scratch"
1457 [(set (reg:CC_NOOV CC_REGNUM)
1460 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1461 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1462 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1464 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1465 "TARGET_ARM && !arm_arch6"
1466 "mlas%?\\t%0, %2, %1, %3"
1467 [(set_attr "conds" "set")
1468 (set_attr "type" "mlas")]
1471 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1472 [(set (reg:CC_NOOV CC_REGNUM)
1475 (match_operand:SI 2 "s_register_operand" "r")
1476 (match_operand:SI 1 "s_register_operand" "r"))
1477 (match_operand:SI 3 "s_register_operand" "r"))
1479 (clobber (match_scratch:SI 0 "=r"))]
1480 "TARGET_ARM && arm_arch6 && optimize_size"
1481 "mlas%?\\t%0, %2, %1, %3"
1482 [(set_attr "conds" "set")
1483 (set_attr "type" "mlas")]
1486 (define_insn "*mulsi3subsi"
1487 [(set (match_operand:SI 0 "s_register_operand" "=r")
1489 (match_operand:SI 3 "s_register_operand" "r")
1490 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1491 (match_operand:SI 1 "s_register_operand" "r"))))]
1492 "TARGET_32BIT && arm_arch_thumb2"
1493 "mls%?\\t%0, %2, %1, %3"
1494 [(set_attr "type" "mla")
1495 (set_attr "predicable" "yes")
1496 (set_attr "predicable_short_it" "no")]
1499 (define_expand "maddsidi4"
1500 [(set (match_operand:DI 0 "s_register_operand" "")
1503 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1504 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1505 (match_operand:DI 3 "s_register_operand" "")))]
1506 "TARGET_32BIT && arm_arch3m"
1509 (define_insn "*mulsidi3adddi"
1510 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1513 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1514 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1515 (match_operand:DI 1 "s_register_operand" "0")))]
1516 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1517 "smlal%?\\t%Q0, %R0, %3, %2"
1518 [(set_attr "type" "smlal")
1519 (set_attr "predicable" "yes")]
1522 (define_insn "*mulsidi3adddi_v6"
1523 [(set (match_operand:DI 0 "s_register_operand" "=r")
1526 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1527 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1528 (match_operand:DI 1 "s_register_operand" "0")))]
1529 "TARGET_32BIT && arm_arch6"
1530 "smlal%?\\t%Q0, %R0, %3, %2"
1531 [(set_attr "type" "smlal")
1532 (set_attr "predicable" "yes")
1533 (set_attr "predicable_short_it" "no")]
1536 ;; 32x32->64 widening multiply.
1537 ;; As with mulsi3, the only difference between the v3-5 and v6+
1538 ;; versions of these patterns is the requirement that the output not
1539 ;; overlap the inputs, but that still means we have to have a named
1540 ;; expander and two different starred insns.
1542 (define_expand "mulsidi3"
1543 [(set (match_operand:DI 0 "s_register_operand" "")
1545 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1546 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1547 "TARGET_32BIT && arm_arch3m"
1551 (define_insn "*mulsidi3_nov6"
1552 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1554 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1555 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1556 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1557 "smull%?\\t%Q0, %R0, %1, %2"
1558 [(set_attr "type" "smull")
1559 (set_attr "predicable" "yes")]
1562 (define_insn "*mulsidi3_v6"
1563 [(set (match_operand:DI 0 "s_register_operand" "=r")
1565 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1566 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1567 "TARGET_32BIT && arm_arch6"
1568 "smull%?\\t%Q0, %R0, %1, %2"
1569 [(set_attr "type" "smull")
1570 (set_attr "predicable" "yes")
1571 (set_attr "predicable_short_it" "no")]
1574 (define_expand "umulsidi3"
1575 [(set (match_operand:DI 0 "s_register_operand" "")
1577 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1578 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1579 "TARGET_32BIT && arm_arch3m"
1583 (define_insn "*umulsidi3_nov6"
1584 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1586 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1587 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1588 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1589 "umull%?\\t%Q0, %R0, %1, %2"
1590 [(set_attr "type" "umull")
1591 (set_attr "predicable" "yes")]
1594 (define_insn "*umulsidi3_v6"
1595 [(set (match_operand:DI 0 "s_register_operand" "=r")
1597 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1598 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1599 "TARGET_32BIT && arm_arch6"
1600 "umull%?\\t%Q0, %R0, %1, %2"
1601 [(set_attr "type" "umull")
1602 (set_attr "predicable" "yes")
1603 (set_attr "predicable_short_it" "no")]
1606 (define_expand "umaddsidi4"
1607 [(set (match_operand:DI 0 "s_register_operand" "")
1610 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1611 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1612 (match_operand:DI 3 "s_register_operand" "")))]
1613 "TARGET_32BIT && arm_arch3m"
1616 (define_insn "*umulsidi3adddi"
1617 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1620 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1621 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1622 (match_operand:DI 1 "s_register_operand" "0")))]
1623 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1624 "umlal%?\\t%Q0, %R0, %3, %2"
1625 [(set_attr "type" "umlal")
1626 (set_attr "predicable" "yes")]
1629 (define_insn "*umulsidi3adddi_v6"
1630 [(set (match_operand:DI 0 "s_register_operand" "=r")
1633 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1634 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1635 (match_operand:DI 1 "s_register_operand" "0")))]
1636 "TARGET_32BIT && arm_arch6"
1637 "umlal%?\\t%Q0, %R0, %3, %2"
1638 [(set_attr "type" "umlal")
1639 (set_attr "predicable" "yes")
1640 (set_attr "predicable_short_it" "no")]
1643 (define_expand "smulsi3_highpart"
1645 [(set (match_operand:SI 0 "s_register_operand" "")
1649 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1650 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1652 (clobber (match_scratch:SI 3 ""))])]
1653 "TARGET_32BIT && arm_arch3m"
1657 (define_insn "*smulsi3_highpart_nov6"
1658 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1662 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1663 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1665 (clobber (match_scratch:SI 3 "=&r,&r"))]
1666 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1667 "smull%?\\t%3, %0, %2, %1"
1668 [(set_attr "type" "smull")
1669 (set_attr "predicable" "yes")]
1672 (define_insn "*smulsi3_highpart_v6"
1673 [(set (match_operand:SI 0 "s_register_operand" "=r")
1677 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1678 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1680 (clobber (match_scratch:SI 3 "=r"))]
1681 "TARGET_32BIT && arm_arch6"
1682 "smull%?\\t%3, %0, %2, %1"
1683 [(set_attr "type" "smull")
1684 (set_attr "predicable" "yes")
1685 (set_attr "predicable_short_it" "no")]
1688 (define_expand "umulsi3_highpart"
1690 [(set (match_operand:SI 0 "s_register_operand" "")
1694 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1695 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1697 (clobber (match_scratch:SI 3 ""))])]
1698 "TARGET_32BIT && arm_arch3m"
1702 (define_insn "*umulsi3_highpart_nov6"
1703 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1707 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1708 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1710 (clobber (match_scratch:SI 3 "=&r,&r"))]
1711 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1712 "umull%?\\t%3, %0, %2, %1"
1713 [(set_attr "type" "umull")
1714 (set_attr "predicable" "yes")]
1717 (define_insn "*umulsi3_highpart_v6"
1718 [(set (match_operand:SI 0 "s_register_operand" "=r")
1722 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1723 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1725 (clobber (match_scratch:SI 3 "=r"))]
1726 "TARGET_32BIT && arm_arch6"
1727 "umull%?\\t%3, %0, %2, %1"
1728 [(set_attr "type" "umull")
1729 (set_attr "predicable" "yes")
1730 (set_attr "predicable_short_it" "no")]
1733 (define_insn "mulhisi3"
1734 [(set (match_operand:SI 0 "s_register_operand" "=r")
1735 (mult:SI (sign_extend:SI
1736 (match_operand:HI 1 "s_register_operand" "%r"))
1738 (match_operand:HI 2 "s_register_operand" "r"))))]
1739 "TARGET_DSP_MULTIPLY"
1740 "smulbb%?\\t%0, %1, %2"
1741 [(set_attr "type" "smulxy")
1742 (set_attr "predicable" "yes")]
1745 (define_insn "*mulhisi3tb"
1746 [(set (match_operand:SI 0 "s_register_operand" "=r")
1747 (mult:SI (ashiftrt:SI
1748 (match_operand:SI 1 "s_register_operand" "r")
1751 (match_operand:HI 2 "s_register_operand" "r"))))]
1752 "TARGET_DSP_MULTIPLY"
1753 "smultb%?\\t%0, %1, %2"
1754 [(set_attr "type" "smulxy")
1755 (set_attr "predicable" "yes")
1756 (set_attr "predicable_short_it" "no")]
1759 (define_insn "*mulhisi3bt"
1760 [(set (match_operand:SI 0 "s_register_operand" "=r")
1761 (mult:SI (sign_extend:SI
1762 (match_operand:HI 1 "s_register_operand" "r"))
1764 (match_operand:SI 2 "s_register_operand" "r")
1766 "TARGET_DSP_MULTIPLY"
1767 "smulbt%?\\t%0, %1, %2"
1768 [(set_attr "type" "smulxy")
1769 (set_attr "predicable" "yes")
1770 (set_attr "predicable_short_it" "no")]
1773 (define_insn "*mulhisi3tt"
1774 [(set (match_operand:SI 0 "s_register_operand" "=r")
1775 (mult:SI (ashiftrt:SI
1776 (match_operand:SI 1 "s_register_operand" "r")
1779 (match_operand:SI 2 "s_register_operand" "r")
1781 "TARGET_DSP_MULTIPLY"
1782 "smultt%?\\t%0, %1, %2"
1783 [(set_attr "type" "smulxy")
1784 (set_attr "predicable" "yes")
1785 (set_attr "predicable_short_it" "no")]
1788 (define_insn "maddhisi4"
1789 [(set (match_operand:SI 0 "s_register_operand" "=r")
1790 (plus:SI (mult:SI (sign_extend:SI
1791 (match_operand:HI 1 "s_register_operand" "r"))
1793 (match_operand:HI 2 "s_register_operand" "r")))
1794 (match_operand:SI 3 "s_register_operand" "r")))]
1795 "TARGET_DSP_MULTIPLY"
1796 "smlabb%?\\t%0, %1, %2, %3"
1797 [(set_attr "type" "smlaxy")
1798 (set_attr "predicable" "yes")
1799 (set_attr "predicable_short_it" "no")]
1802 ;; Note: there is no maddhisi4ibt because this one is canonical form
1803 (define_insn "*maddhisi4tb"
1804 [(set (match_operand:SI 0 "s_register_operand" "=r")
1805 (plus:SI (mult:SI (ashiftrt:SI
1806 (match_operand:SI 1 "s_register_operand" "r")
1809 (match_operand:HI 2 "s_register_operand" "r")))
1810 (match_operand:SI 3 "s_register_operand" "r")))]
1811 "TARGET_DSP_MULTIPLY"
1812 "smlatb%?\\t%0, %1, %2, %3"
1813 [(set_attr "type" "smlaxy")
1814 (set_attr "predicable" "yes")
1815 (set_attr "predicable_short_it" "no")]
1818 (define_insn "*maddhisi4tt"
1819 [(set (match_operand:SI 0 "s_register_operand" "=r")
1820 (plus:SI (mult:SI (ashiftrt:SI
1821 (match_operand:SI 1 "s_register_operand" "r")
1824 (match_operand:SI 2 "s_register_operand" "r")
1826 (match_operand:SI 3 "s_register_operand" "r")))]
1827 "TARGET_DSP_MULTIPLY"
1828 "smlatt%?\\t%0, %1, %2, %3"
1829 [(set_attr "type" "smlaxy")
1830 (set_attr "predicable" "yes")
1831 (set_attr "predicable_short_it" "no")]
1834 (define_insn "maddhidi4"
1835 [(set (match_operand:DI 0 "s_register_operand" "=r")
1837 (mult:DI (sign_extend:DI
1838 (match_operand:HI 1 "s_register_operand" "r"))
1840 (match_operand:HI 2 "s_register_operand" "r")))
1841 (match_operand:DI 3 "s_register_operand" "0")))]
1842 "TARGET_DSP_MULTIPLY"
1843 "smlalbb%?\\t%Q0, %R0, %1, %2"
1844 [(set_attr "type" "smlalxy")
1845 (set_attr "predicable" "yes")
1846 (set_attr "predicable_short_it" "no")])
1848 ;; Note: there is no maddhidi4ibt because this one is canonical form
1849 (define_insn "*maddhidi4tb"
1850 [(set (match_operand:DI 0 "s_register_operand" "=r")
1852 (mult:DI (sign_extend:DI
1854 (match_operand:SI 1 "s_register_operand" "r")
1857 (match_operand:HI 2 "s_register_operand" "r")))
1858 (match_operand:DI 3 "s_register_operand" "0")))]
1859 "TARGET_DSP_MULTIPLY"
1860 "smlaltb%?\\t%Q0, %R0, %1, %2"
1861 [(set_attr "type" "smlalxy")
1862 (set_attr "predicable" "yes")
1863 (set_attr "predicable_short_it" "no")])
1865 (define_insn "*maddhidi4tt"
1866 [(set (match_operand:DI 0 "s_register_operand" "=r")
1868 (mult:DI (sign_extend:DI
1870 (match_operand:SI 1 "s_register_operand" "r")
1874 (match_operand:SI 2 "s_register_operand" "r")
1876 (match_operand:DI 3 "s_register_operand" "0")))]
1877 "TARGET_DSP_MULTIPLY"
1878 "smlaltt%?\\t%Q0, %R0, %1, %2"
1879 [(set_attr "type" "smlalxy")
1880 (set_attr "predicable" "yes")
1881 (set_attr "predicable_short_it" "no")])
1883 (define_expand "mulsf3"
1884 [(set (match_operand:SF 0 "s_register_operand" "")
1885 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1886 (match_operand:SF 2 "s_register_operand" "")))]
1887 "TARGET_32BIT && TARGET_HARD_FLOAT"
1891 (define_expand "muldf3"
1892 [(set (match_operand:DF 0 "s_register_operand" "")
1893 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1894 (match_operand:DF 2 "s_register_operand" "")))]
1895 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1901 (define_expand "divsf3"
1902 [(set (match_operand:SF 0 "s_register_operand" "")
1903 (div:SF (match_operand:SF 1 "s_register_operand" "")
1904 (match_operand:SF 2 "s_register_operand" "")))]
1905 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1908 (define_expand "divdf3"
1909 [(set (match_operand:DF 0 "s_register_operand" "")
1910 (div:DF (match_operand:DF 1 "s_register_operand" "")
1911 (match_operand:DF 2 "s_register_operand" "")))]
1912 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1915 ;; Boolean and,ior,xor insns
1917 ;; Split up double word logical operations
1919 ;; Split up simple DImode logical operations. Simply perform the logical
1920 ;; operation on the upper and lower halves of the registers.
1922 [(set (match_operand:DI 0 "s_register_operand" "")
1923 (match_operator:DI 6 "logical_binary_operator"
1924 [(match_operand:DI 1 "s_register_operand" "")
1925 (match_operand:DI 2 "s_register_operand" "")]))]
1926 "TARGET_32BIT && reload_completed
1927 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1928 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1929 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1930 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1933 operands[3] = gen_highpart (SImode, operands[0]);
1934 operands[0] = gen_lowpart (SImode, operands[0]);
1935 operands[4] = gen_highpart (SImode, operands[1]);
1936 operands[1] = gen_lowpart (SImode, operands[1]);
1937 operands[5] = gen_highpart (SImode, operands[2]);
1938 operands[2] = gen_lowpart (SImode, operands[2]);
1943 [(set (match_operand:DI 0 "s_register_operand" "")
1944 (match_operator:DI 6 "logical_binary_operator"
1945 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1946 (match_operand:DI 1 "s_register_operand" "")]))]
1947 "TARGET_32BIT && reload_completed"
1948 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1949 (set (match_dup 3) (match_op_dup:SI 6
1950 [(ashiftrt:SI (match_dup 2) (const_int 31))
1954 operands[3] = gen_highpart (SImode, operands[0]);
1955 operands[0] = gen_lowpart (SImode, operands[0]);
1956 operands[4] = gen_highpart (SImode, operands[1]);
1957 operands[1] = gen_lowpart (SImode, operands[1]);
1958 operands[5] = gen_highpart (SImode, operands[2]);
1959 operands[2] = gen_lowpart (SImode, operands[2]);
1963 ;; The zero extend of operand 2 means we can just copy the high part of
1964 ;; operand1 into operand0.
1966 [(set (match_operand:DI 0 "s_register_operand" "")
1968 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1969 (match_operand:DI 1 "s_register_operand" "")))]
1970 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1971 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1972 (set (match_dup 3) (match_dup 4))]
1975 operands[4] = gen_highpart (SImode, operands[1]);
1976 operands[3] = gen_highpart (SImode, operands[0]);
1977 operands[0] = gen_lowpart (SImode, operands[0]);
1978 operands[1] = gen_lowpart (SImode, operands[1]);
1982 ;; The zero extend of operand 2 means we can just copy the high part of
1983 ;; operand1 into operand0.
1985 [(set (match_operand:DI 0 "s_register_operand" "")
1987 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1988 (match_operand:DI 1 "s_register_operand" "")))]
1989 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1990 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1991 (set (match_dup 3) (match_dup 4))]
1994 operands[4] = gen_highpart (SImode, operands[1]);
1995 operands[3] = gen_highpart (SImode, operands[0]);
1996 operands[0] = gen_lowpart (SImode, operands[0]);
1997 operands[1] = gen_lowpart (SImode, operands[1]);
2001 (define_expand "anddi3"
2002 [(set (match_operand:DI 0 "s_register_operand" "")
2003 (and:DI (match_operand:DI 1 "s_register_operand" "")
2004 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2009 (define_insn_and_split "*anddi3_insn"
2010 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2011 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2012 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2013 "TARGET_32BIT && !TARGET_IWMMXT"
2015 switch (which_alternative)
2017 case 0: /* fall through */
2018 case 6: return "vand\t%P0, %P1, %P2";
2019 case 1: /* fall through */
2020 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2021 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2025 case 5: /* fall through */
2027 default: gcc_unreachable ();
2030 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2031 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2032 [(set (match_dup 3) (match_dup 4))
2033 (set (match_dup 5) (match_dup 6))]
2036 operands[3] = gen_lowpart (SImode, operands[0]);
2037 operands[5] = gen_highpart (SImode, operands[0]);
2039 operands[4] = simplify_gen_binary (AND, SImode,
2040 gen_lowpart (SImode, operands[1]),
2041 gen_lowpart (SImode, operands[2]));
2042 operands[6] = simplify_gen_binary (AND, SImode,
2043 gen_highpart (SImode, operands[1]),
2044 gen_highpart_mode (SImode, DImode, operands[2]));
2047 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2048 multiple,multiple,neon_logic,neon_logic")
2049 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2050 avoid_neon_for_64bits,avoid_neon_for_64bits")
2051 (set_attr "length" "*,*,8,8,8,8,*,*")
2055 (define_insn_and_split "*anddi_zesidi_di"
2056 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2057 (and:DI (zero_extend:DI
2058 (match_operand:SI 2 "s_register_operand" "r,r"))
2059 (match_operand:DI 1 "s_register_operand" "0,r")))]
2062 "TARGET_32BIT && reload_completed"
2063 ; The zero extend of operand 2 clears the high word of the output
2065 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2066 (set (match_dup 3) (const_int 0))]
2069 operands[3] = gen_highpart (SImode, operands[0]);
2070 operands[0] = gen_lowpart (SImode, operands[0]);
2071 operands[1] = gen_lowpart (SImode, operands[1]);
2073 [(set_attr "length" "8")
2074 (set_attr "type" "multiple")]
2077 (define_insn "*anddi_sesdi_di"
2078 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2079 (and:DI (sign_extend:DI
2080 (match_operand:SI 2 "s_register_operand" "r,r"))
2081 (match_operand:DI 1 "s_register_operand" "0,r")))]
2084 [(set_attr "length" "8")
2085 (set_attr "type" "multiple")]
2088 (define_expand "andsi3"
2089 [(set (match_operand:SI 0 "s_register_operand" "")
2090 (and:SI (match_operand:SI 1 "s_register_operand" "")
2091 (match_operand:SI 2 "reg_or_int_operand" "")))]
2096 if (CONST_INT_P (operands[2]))
2098 if (INTVAL (operands[2]) == 255 && arm_arch6)
2100 operands[1] = convert_to_mode (QImode, operands[1], 1);
2101 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2105 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2106 operands[2] = force_reg (SImode, operands[2]);
2109 arm_split_constant (AND, SImode, NULL_RTX,
2110 INTVAL (operands[2]), operands[0],
2112 optimize && can_create_pseudo_p ());
2118 else /* TARGET_THUMB1 */
2120 if (!CONST_INT_P (operands[2]))
2122 rtx tmp = force_reg (SImode, operands[2]);
2123 if (rtx_equal_p (operands[0], operands[1]))
2127 operands[2] = operands[1];
2135 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2137 operands[2] = force_reg (SImode,
2138 GEN_INT (~INTVAL (operands[2])));
2140 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2145 for (i = 9; i <= 31; i++)
2147 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2149 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2153 else if ((HOST_WIDE_INT_1 << i) - 1
2154 == ~INTVAL (operands[2]))
2156 rtx shift = GEN_INT (i);
2157 rtx reg = gen_reg_rtx (SImode);
2159 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2160 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2166 operands[2] = force_reg (SImode, operands[2]);
2172 ; ??? Check split length for Thumb-2
2173 (define_insn_and_split "*arm_andsi3_insn"
2174 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2175 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2176 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2181 bic%?\\t%0, %1, #%B2
2185 && CONST_INT_P (operands[2])
2186 && !(const_ok_for_arm (INTVAL (operands[2]))
2187 || const_ok_for_arm (~INTVAL (operands[2])))"
2188 [(clobber (const_int 0))]
2190 arm_split_constant (AND, SImode, curr_insn,
2191 INTVAL (operands[2]), operands[0], operands[1], 0);
2194 [(set_attr "length" "4,4,4,4,16")
2195 (set_attr "predicable" "yes")
2196 (set_attr "predicable_short_it" "no,yes,no,no,no")
2197 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2200 (define_insn "*andsi3_compare0"
2201 [(set (reg:CC_NOOV CC_REGNUM)
2203 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2204 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2206 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2207 (and:SI (match_dup 1) (match_dup 2)))]
2211 bics%?\\t%0, %1, #%B2
2212 ands%?\\t%0, %1, %2"
2213 [(set_attr "conds" "set")
2214 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2217 (define_insn "*andsi3_compare0_scratch"
2218 [(set (reg:CC_NOOV CC_REGNUM)
2220 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2221 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2223 (clobber (match_scratch:SI 2 "=X,r,X"))]
2227 bics%?\\t%2, %0, #%B1
2229 [(set_attr "conds" "set")
2230 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2233 (define_insn "*zeroextractsi_compare0_scratch"
2234 [(set (reg:CC_NOOV CC_REGNUM)
2235 (compare:CC_NOOV (zero_extract:SI
2236 (match_operand:SI 0 "s_register_operand" "r")
2237 (match_operand 1 "const_int_operand" "n")
2238 (match_operand 2 "const_int_operand" "n"))
2241 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2242 && INTVAL (operands[1]) > 0
2243 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2244 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2246 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2247 << INTVAL (operands[2]));
2248 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2251 [(set_attr "conds" "set")
2252 (set_attr "predicable" "yes")
2253 (set_attr "predicable_short_it" "no")
2254 (set_attr "type" "logics_imm")]
2257 (define_insn_and_split "*ne_zeroextractsi"
2258 [(set (match_operand:SI 0 "s_register_operand" "=r")
2259 (ne:SI (zero_extract:SI
2260 (match_operand:SI 1 "s_register_operand" "r")
2261 (match_operand:SI 2 "const_int_operand" "n")
2262 (match_operand:SI 3 "const_int_operand" "n"))
2264 (clobber (reg:CC CC_REGNUM))]
2266 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2267 && INTVAL (operands[2]) > 0
2268 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2269 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2272 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2273 && INTVAL (operands[2]) > 0
2274 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2275 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2276 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2277 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2279 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2281 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2282 (match_dup 0) (const_int 1)))]
2284 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2285 << INTVAL (operands[3]));
2287 [(set_attr "conds" "clob")
2288 (set (attr "length")
2289 (if_then_else (eq_attr "is_thumb" "yes")
2292 (set_attr "type" "multiple")]
2295 (define_insn_and_split "*ne_zeroextractsi_shifted"
2296 [(set (match_operand:SI 0 "s_register_operand" "=r")
2297 (ne:SI (zero_extract:SI
2298 (match_operand:SI 1 "s_register_operand" "r")
2299 (match_operand:SI 2 "const_int_operand" "n")
2302 (clobber (reg:CC CC_REGNUM))]
2306 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2307 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2309 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2311 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2312 (match_dup 0) (const_int 1)))]
2314 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2316 [(set_attr "conds" "clob")
2317 (set_attr "length" "8")
2318 (set_attr "type" "multiple")]
2321 (define_insn_and_split "*ite_ne_zeroextractsi"
2322 [(set (match_operand:SI 0 "s_register_operand" "=r")
2323 (if_then_else:SI (ne (zero_extract:SI
2324 (match_operand:SI 1 "s_register_operand" "r")
2325 (match_operand:SI 2 "const_int_operand" "n")
2326 (match_operand:SI 3 "const_int_operand" "n"))
2328 (match_operand:SI 4 "arm_not_operand" "rIK")
2330 (clobber (reg:CC CC_REGNUM))]
2332 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2333 && INTVAL (operands[2]) > 0
2334 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2335 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2336 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2339 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2340 && INTVAL (operands[2]) > 0
2341 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2342 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2343 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2344 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2345 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2347 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2349 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2350 (match_dup 0) (match_dup 4)))]
2352 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2353 << INTVAL (operands[3]));
2355 [(set_attr "conds" "clob")
2356 (set_attr "length" "8")
2357 (set_attr "type" "multiple")]
2360 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2361 [(set (match_operand:SI 0 "s_register_operand" "=r")
2362 (if_then_else:SI (ne (zero_extract:SI
2363 (match_operand:SI 1 "s_register_operand" "r")
2364 (match_operand:SI 2 "const_int_operand" "n")
2367 (match_operand:SI 3 "arm_not_operand" "rIK")
2369 (clobber (reg:CC CC_REGNUM))]
2370 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2372 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2373 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2374 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2376 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2378 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2379 (match_dup 0) (match_dup 3)))]
2381 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2383 [(set_attr "conds" "clob")
2384 (set_attr "length" "8")
2385 (set_attr "type" "multiple")]
2388 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2390 [(set (match_operand:SI 0 "s_register_operand" "")
2391 (match_operator:SI 1 "shiftable_operator"
2392 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2393 (match_operand:SI 3 "const_int_operand" "")
2394 (match_operand:SI 4 "const_int_operand" ""))
2395 (match_operand:SI 5 "s_register_operand" "")]))
2396 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2398 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2401 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2404 HOST_WIDE_INT temp = INTVAL (operands[3]);
2406 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2407 operands[4] = GEN_INT (32 - temp);
2412 [(set (match_operand:SI 0 "s_register_operand" "")
2413 (match_operator:SI 1 "shiftable_operator"
2414 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2415 (match_operand:SI 3 "const_int_operand" "")
2416 (match_operand:SI 4 "const_int_operand" ""))
2417 (match_operand:SI 5 "s_register_operand" "")]))
2418 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2420 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2423 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2426 HOST_WIDE_INT temp = INTVAL (operands[3]);
2428 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2429 operands[4] = GEN_INT (32 - temp);
2433 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2434 ;;; represented by the bitfield, then this will produce incorrect results.
2435 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2436 ;;; which have a real bit-field insert instruction, the truncation happens
2437 ;;; in the bit-field insert instruction itself. Since arm does not have a
2438 ;;; bit-field insert instruction, we would have to emit code here to truncate
2439 ;;; the value before we insert. This loses some of the advantage of having
2440 ;;; this insv pattern, so this pattern needs to be reevalutated.
2442 (define_expand "insv"
2443 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2444 (match_operand 1 "general_operand" "")
2445 (match_operand 2 "general_operand" ""))
2446 (match_operand 3 "reg_or_int_operand" ""))]
2447 "TARGET_ARM || arm_arch_thumb2"
2450 int start_bit = INTVAL (operands[2]);
2451 int width = INTVAL (operands[1]);
2452 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2453 rtx target, subtarget;
2455 if (arm_arch_thumb2)
2457 if (unaligned_access && MEM_P (operands[0])
2458 && s_register_operand (operands[3], GET_MODE (operands[3]))
2459 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2463 if (BYTES_BIG_ENDIAN)
2464 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2469 base_addr = adjust_address (operands[0], SImode,
2470 start_bit / BITS_PER_UNIT);
2471 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2475 rtx tmp = gen_reg_rtx (HImode);
2477 base_addr = adjust_address (operands[0], HImode,
2478 start_bit / BITS_PER_UNIT);
2479 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2480 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2484 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2486 bool use_bfi = TRUE;
2488 if (CONST_INT_P (operands[3]))
2490 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2494 emit_insn (gen_insv_zero (operands[0], operands[1],
2499 /* See if the set can be done with a single orr instruction. */
2500 if (val == mask && const_ok_for_arm (val << start_bit))
2506 if (!REG_P (operands[3]))
2507 operands[3] = force_reg (SImode, operands[3]);
2509 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2518 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2521 target = copy_rtx (operands[0]);
2522 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2523 subreg as the final target. */
2524 if (GET_CODE (target) == SUBREG)
2526 subtarget = gen_reg_rtx (SImode);
2527 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2528 < GET_MODE_SIZE (SImode))
2529 target = SUBREG_REG (target);
2534 if (CONST_INT_P (operands[3]))
2536 /* Since we are inserting a known constant, we may be able to
2537 reduce the number of bits that we have to clear so that
2538 the mask becomes simple. */
2539 /* ??? This code does not check to see if the new mask is actually
2540 simpler. It may not be. */
2541 rtx op1 = gen_reg_rtx (SImode);
2542 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2543 start of this pattern. */
2544 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2545 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2547 emit_insn (gen_andsi3 (op1, operands[0],
2548 gen_int_mode (~mask2, SImode)));
2549 emit_insn (gen_iorsi3 (subtarget, op1,
2550 gen_int_mode (op3_value << start_bit, SImode)));
2552 else if (start_bit == 0
2553 && !(const_ok_for_arm (mask)
2554 || const_ok_for_arm (~mask)))
2556 /* A Trick, since we are setting the bottom bits in the word,
2557 we can shift operand[3] up, operand[0] down, OR them together
2558 and rotate the result back again. This takes 3 insns, and
2559 the third might be mergeable into another op. */
2560 /* The shift up copes with the possibility that operand[3] is
2561 wider than the bitfield. */
2562 rtx op0 = gen_reg_rtx (SImode);
2563 rtx op1 = gen_reg_rtx (SImode);
2565 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2566 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2567 emit_insn (gen_iorsi3 (op1, op1, op0));
2568 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2570 else if ((width + start_bit == 32)
2571 && !(const_ok_for_arm (mask)
2572 || const_ok_for_arm (~mask)))
2574 /* Similar trick, but slightly less efficient. */
2576 rtx op0 = gen_reg_rtx (SImode);
2577 rtx op1 = gen_reg_rtx (SImode);
2579 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2580 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2581 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2582 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2586 rtx op0 = gen_int_mode (mask, SImode);
2587 rtx op1 = gen_reg_rtx (SImode);
2588 rtx op2 = gen_reg_rtx (SImode);
2590 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2592 rtx tmp = gen_reg_rtx (SImode);
2594 emit_insn (gen_movsi (tmp, op0));
2598 /* Mask out any bits in operand[3] that are not needed. */
2599 emit_insn (gen_andsi3 (op1, operands[3], op0));
2601 if (CONST_INT_P (op0)
2602 && (const_ok_for_arm (mask << start_bit)
2603 || const_ok_for_arm (~(mask << start_bit))))
2605 op0 = gen_int_mode (~(mask << start_bit), SImode);
2606 emit_insn (gen_andsi3 (op2, operands[0], op0));
2610 if (CONST_INT_P (op0))
2612 rtx tmp = gen_reg_rtx (SImode);
2614 emit_insn (gen_movsi (tmp, op0));
2619 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2621 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2625 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2627 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2630 if (subtarget != target)
2632 /* If TARGET is still a SUBREG, then it must be wider than a word,
2633 so we must be careful only to set the subword we were asked to. */
2634 if (GET_CODE (target) == SUBREG)
2635 emit_move_insn (target, subtarget);
2637 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2644 (define_insn "insv_zero"
2645 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2646 (match_operand:SI 1 "const_int_M_operand" "M")
2647 (match_operand:SI 2 "const_int_M_operand" "M"))
2651 [(set_attr "length" "4")
2652 (set_attr "predicable" "yes")
2653 (set_attr "predicable_short_it" "no")
2654 (set_attr "type" "bfm")]
2657 (define_insn "insv_t2"
2658 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2659 (match_operand:SI 1 "const_int_M_operand" "M")
2660 (match_operand:SI 2 "const_int_M_operand" "M"))
2661 (match_operand:SI 3 "s_register_operand" "r"))]
2663 "bfi%?\t%0, %3, %2, %1"
2664 [(set_attr "length" "4")
2665 (set_attr "predicable" "yes")
2666 (set_attr "predicable_short_it" "no")
2667 (set_attr "type" "bfm")]
2670 ; constants for op 2 will never be given to these patterns.
2671 (define_insn_and_split "*anddi_notdi_di"
2672 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2673 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2674 (match_operand:DI 2 "s_register_operand" "r,0")))]
2677 "TARGET_32BIT && reload_completed
2678 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2679 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2680 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2681 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2684 operands[3] = gen_highpart (SImode, operands[0]);
2685 operands[0] = gen_lowpart (SImode, operands[0]);
2686 operands[4] = gen_highpart (SImode, operands[1]);
2687 operands[1] = gen_lowpart (SImode, operands[1]);
2688 operands[5] = gen_highpart (SImode, operands[2]);
2689 operands[2] = gen_lowpart (SImode, operands[2]);
2691 [(set_attr "length" "8")
2692 (set_attr "predicable" "yes")
2693 (set_attr "type" "multiple")]
2696 (define_insn_and_split "*anddi_notzesidi_di"
2697 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2698 (and:DI (not:DI (zero_extend:DI
2699 (match_operand:SI 2 "s_register_operand" "r,r")))
2700 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2703 bic%?\\t%Q0, %Q1, %2
2705 ; (not (zero_extend ...)) allows us to just copy the high word from
2706 ; operand1 to operand0.
2709 && operands[0] != operands[1]"
2710 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2711 (set (match_dup 3) (match_dup 4))]
2714 operands[3] = gen_highpart (SImode, operands[0]);
2715 operands[0] = gen_lowpart (SImode, operands[0]);
2716 operands[4] = gen_highpart (SImode, operands[1]);
2717 operands[1] = gen_lowpart (SImode, operands[1]);
2719 [(set_attr "length" "4,8")
2720 (set_attr "predicable" "yes")
2721 (set_attr "predicable_short_it" "no")
2722 (set_attr "type" "multiple")]
2725 (define_insn_and_split "*anddi_notdi_zesidi"
2726 [(set (match_operand:DI 0 "s_register_operand" "=r")
2727 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2729 (match_operand:SI 1 "s_register_operand" "r"))))]
2732 "TARGET_32BIT && reload_completed"
2733 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2734 (set (match_dup 3) (const_int 0))]
2737 operands[3] = gen_highpart (SImode, operands[0]);
2738 operands[0] = gen_lowpart (SImode, operands[0]);
2739 operands[2] = gen_lowpart (SImode, operands[2]);
2741 [(set_attr "length" "8")
2742 (set_attr "predicable" "yes")
2743 (set_attr "predicable_short_it" "no")
2744 (set_attr "type" "multiple")]
2747 (define_insn_and_split "*anddi_notsesidi_di"
2748 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2749 (and:DI (not:DI (sign_extend:DI
2750 (match_operand:SI 2 "s_register_operand" "r,r")))
2751 (match_operand:DI 1 "s_register_operand" "0,r")))]
2754 "TARGET_32BIT && reload_completed"
2755 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2756 (set (match_dup 3) (and:SI (not:SI
2757 (ashiftrt:SI (match_dup 2) (const_int 31)))
2761 operands[3] = gen_highpart (SImode, operands[0]);
2762 operands[0] = gen_lowpart (SImode, operands[0]);
2763 operands[4] = gen_highpart (SImode, operands[1]);
2764 operands[1] = gen_lowpart (SImode, operands[1]);
2766 [(set_attr "length" "8")
2767 (set_attr "predicable" "yes")
2768 (set_attr "predicable_short_it" "no")
2769 (set_attr "type" "multiple")]
2772 (define_insn "andsi_notsi_si"
2773 [(set (match_operand:SI 0 "s_register_operand" "=r")
2774 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2775 (match_operand:SI 1 "s_register_operand" "r")))]
2777 "bic%?\\t%0, %1, %2"
2778 [(set_attr "predicable" "yes")
2779 (set_attr "predicable_short_it" "no")
2780 (set_attr "type" "logic_reg")]
2783 (define_insn "andsi_not_shiftsi_si"
2784 [(set (match_operand:SI 0 "s_register_operand" "=r")
2785 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2786 [(match_operand:SI 2 "s_register_operand" "r")
2787 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2788 (match_operand:SI 1 "s_register_operand" "r")))]
2790 "bic%?\\t%0, %1, %2%S4"
2791 [(set_attr "predicable" "yes")
2792 (set_attr "shift" "2")
2793 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2794 (const_string "logic_shift_imm")
2795 (const_string "logic_shift_reg")))]
2798 ;; Shifted bics pattern used to set up CC status register and not reusing
2799 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
2800 ;; does not support shift by register.
2801 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
2802 [(set (reg:CC_NOOV CC_REGNUM)
2804 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2805 [(match_operand:SI 1 "s_register_operand" "r")
2806 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2807 (match_operand:SI 3 "s_register_operand" "r"))
2809 (clobber (match_scratch:SI 4 "=r"))]
2810 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2811 "bics%?\\t%4, %3, %1%S0"
2812 [(set_attr "predicable" "yes")
2813 (set_attr "predicable_short_it" "no")
2814 (set_attr "conds" "set")
2815 (set_attr "shift" "1")
2816 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2817 (const_string "logic_shift_imm")
2818 (const_string "logic_shift_reg")))]
2821 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
2822 ;; getting reused later.
2823 (define_insn "andsi_not_shiftsi_si_scc"
2824 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2826 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2827 [(match_operand:SI 1 "s_register_operand" "r")
2828 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2829 (match_operand:SI 3 "s_register_operand" "r"))
2831 (set (match_operand:SI 4 "s_register_operand" "=r")
2832 (and:SI (not:SI (match_op_dup 0
2836 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2837 "bics%?\\t%4, %3, %1%S0"
2838 [(set_attr "predicable" "yes")
2839 (set_attr "predicable_short_it" "no")
2840 (set_attr "conds" "set")
2841 (set_attr "shift" "1")
2842 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2843 (const_string "logic_shift_imm")
2844 (const_string "logic_shift_reg")))]
2847 (define_insn "*andsi_notsi_si_compare0"
2848 [(set (reg:CC_NOOV CC_REGNUM)
2850 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2851 (match_operand:SI 1 "s_register_operand" "r"))
2853 (set (match_operand:SI 0 "s_register_operand" "=r")
2854 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2857 [(set_attr "conds" "set")
2858 (set_attr "type" "logics_shift_reg")]
2861 (define_insn "*andsi_notsi_si_compare0_scratch"
2862 [(set (reg:CC_NOOV CC_REGNUM)
2864 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2865 (match_operand:SI 1 "s_register_operand" "r"))
2867 (clobber (match_scratch:SI 0 "=r"))]
2870 [(set_attr "conds" "set")
2871 (set_attr "type" "logics_shift_reg")]
2874 (define_expand "iordi3"
2875 [(set (match_operand:DI 0 "s_register_operand" "")
2876 (ior:DI (match_operand:DI 1 "s_register_operand" "")
2877 (match_operand:DI 2 "neon_logic_op2" "")))]
2882 (define_insn_and_split "*iordi3_insn"
2883 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2884 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2885 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
2886 "TARGET_32BIT && !TARGET_IWMMXT"
2888 switch (which_alternative)
2890 case 0: /* fall through */
2891 case 6: return "vorr\t%P0, %P1, %P2";
2892 case 1: /* fall through */
2893 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2894 DImode, 0, VALID_NEON_QREG_MODE (DImode));
2900 default: gcc_unreachable ();
2903 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2904 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2905 [(set (match_dup 3) (match_dup 4))
2906 (set (match_dup 5) (match_dup 6))]
2909 operands[3] = gen_lowpart (SImode, operands[0]);
2910 operands[5] = gen_highpart (SImode, operands[0]);
2912 operands[4] = simplify_gen_binary (IOR, SImode,
2913 gen_lowpart (SImode, operands[1]),
2914 gen_lowpart (SImode, operands[2]));
2915 operands[6] = simplify_gen_binary (IOR, SImode,
2916 gen_highpart (SImode, operands[1]),
2917 gen_highpart_mode (SImode, DImode, operands[2]));
2920 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2921 multiple,neon_logic,neon_logic")
2922 (set_attr "length" "*,*,8,8,8,8,*,*")
2923 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
2926 (define_insn "*iordi_zesidi_di"
2927 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2928 (ior:DI (zero_extend:DI
2929 (match_operand:SI 2 "s_register_operand" "r,r"))
2930 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2933 orr%?\\t%Q0, %Q1, %2
2935 [(set_attr "length" "4,8")
2936 (set_attr "predicable" "yes")
2937 (set_attr "predicable_short_it" "no")
2938 (set_attr "type" "logic_reg,multiple")]
2941 (define_insn "*iordi_sesidi_di"
2942 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2943 (ior:DI (sign_extend:DI
2944 (match_operand:SI 2 "s_register_operand" "r,r"))
2945 (match_operand:DI 1 "s_register_operand" "0,r")))]
2948 [(set_attr "length" "8")
2949 (set_attr "predicable" "yes")
2950 (set_attr "type" "multiple")]
2953 (define_expand "iorsi3"
2954 [(set (match_operand:SI 0 "s_register_operand" "")
2955 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2956 (match_operand:SI 2 "reg_or_int_operand" "")))]
2959 if (CONST_INT_P (operands[2]))
2963 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
2964 operands[2] = force_reg (SImode, operands[2]);
2967 arm_split_constant (IOR, SImode, NULL_RTX,
2968 INTVAL (operands[2]), operands[0],
2970 optimize && can_create_pseudo_p ());
2974 else /* TARGET_THUMB1 */
2976 rtx tmp = force_reg (SImode, operands[2]);
2977 if (rtx_equal_p (operands[0], operands[1]))
2981 operands[2] = operands[1];
2989 (define_insn_and_split "*iorsi3_insn"
2990 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2991 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2992 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2997 orn%?\\t%0, %1, #%B2
3001 && CONST_INT_P (operands[2])
3002 && !(const_ok_for_arm (INTVAL (operands[2]))
3003 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3004 [(clobber (const_int 0))]
3006 arm_split_constant (IOR, SImode, curr_insn,
3007 INTVAL (operands[2]), operands[0], operands[1], 0);
3010 [(set_attr "length" "4,4,4,4,16")
3011 (set_attr "arch" "32,t2,t2,32,32")
3012 (set_attr "predicable" "yes")
3013 (set_attr "predicable_short_it" "no,yes,no,no,no")
3014 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3018 [(match_scratch:SI 3 "r")
3019 (set (match_operand:SI 0 "arm_general_register_operand" "")
3020 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3021 (match_operand:SI 2 "const_int_operand" "")))]
3023 && !const_ok_for_arm (INTVAL (operands[2]))
3024 && const_ok_for_arm (~INTVAL (operands[2]))"
3025 [(set (match_dup 3) (match_dup 2))
3026 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3030 (define_insn "*iorsi3_compare0"
3031 [(set (reg:CC_NOOV CC_REGNUM)
3032 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3033 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3035 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3036 (ior:SI (match_dup 1) (match_dup 2)))]
3038 "orrs%?\\t%0, %1, %2"
3039 [(set_attr "conds" "set")
3040 (set_attr "type" "logics_imm,logics_reg")]
3043 (define_insn "*iorsi3_compare0_scratch"
3044 [(set (reg:CC_NOOV CC_REGNUM)
3045 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3046 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3048 (clobber (match_scratch:SI 0 "=r,r"))]
3050 "orrs%?\\t%0, %1, %2"
3051 [(set_attr "conds" "set")
3052 (set_attr "type" "logics_imm,logics_reg")]
3055 (define_expand "xordi3"
3056 [(set (match_operand:DI 0 "s_register_operand" "")
3057 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3058 (match_operand:DI 2 "arm_xordi_operand" "")))]
3063 (define_insn_and_split "*xordi3_insn"
3064 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3065 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3066 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3067 "TARGET_32BIT && !TARGET_IWMMXT"
3069 switch (which_alternative)
3074 case 4: /* fall through */
3076 case 0: /* fall through */
3077 case 5: return "veor\t%P0, %P1, %P2";
3078 default: gcc_unreachable ();
3081 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3082 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3083 [(set (match_dup 3) (match_dup 4))
3084 (set (match_dup 5) (match_dup 6))]
3087 operands[3] = gen_lowpart (SImode, operands[0]);
3088 operands[5] = gen_highpart (SImode, operands[0]);
3090 operands[4] = simplify_gen_binary (XOR, SImode,
3091 gen_lowpart (SImode, operands[1]),
3092 gen_lowpart (SImode, operands[2]));
3093 operands[6] = simplify_gen_binary (XOR, SImode,
3094 gen_highpart (SImode, operands[1]),
3095 gen_highpart_mode (SImode, DImode, operands[2]));
3098 [(set_attr "length" "*,8,8,8,8,*")
3099 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3100 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3103 (define_insn "*xordi_zesidi_di"
3104 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3105 (xor:DI (zero_extend:DI
3106 (match_operand:SI 2 "s_register_operand" "r,r"))
3107 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3110 eor%?\\t%Q0, %Q1, %2
3112 [(set_attr "length" "4,8")
3113 (set_attr "predicable" "yes")
3114 (set_attr "predicable_short_it" "no")
3115 (set_attr "type" "logic_reg")]
3118 (define_insn "*xordi_sesidi_di"
3119 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3120 (xor:DI (sign_extend:DI
3121 (match_operand:SI 2 "s_register_operand" "r,r"))
3122 (match_operand:DI 1 "s_register_operand" "0,r")))]
3125 [(set_attr "length" "8")
3126 (set_attr "predicable" "yes")
3127 (set_attr "type" "multiple")]
3130 (define_expand "xorsi3"
3131 [(set (match_operand:SI 0 "s_register_operand" "")
3132 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3133 (match_operand:SI 2 "reg_or_int_operand" "")))]
3135 "if (CONST_INT_P (operands[2]))
3139 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3140 operands[2] = force_reg (SImode, operands[2]);
3143 arm_split_constant (XOR, SImode, NULL_RTX,
3144 INTVAL (operands[2]), operands[0],
3146 optimize && can_create_pseudo_p ());
3150 else /* TARGET_THUMB1 */
3152 rtx tmp = force_reg (SImode, operands[2]);
3153 if (rtx_equal_p (operands[0], operands[1]))
3157 operands[2] = operands[1];
3164 (define_insn_and_split "*arm_xorsi3"
3165 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3166 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3167 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3175 && CONST_INT_P (operands[2])
3176 && !const_ok_for_arm (INTVAL (operands[2]))"
3177 [(clobber (const_int 0))]
3179 arm_split_constant (XOR, SImode, curr_insn,
3180 INTVAL (operands[2]), operands[0], operands[1], 0);
3183 [(set_attr "length" "4,4,4,16")
3184 (set_attr "predicable" "yes")
3185 (set_attr "predicable_short_it" "no,yes,no,no")
3186 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3189 (define_insn "*xorsi3_compare0"
3190 [(set (reg:CC_NOOV CC_REGNUM)
3191 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3192 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3194 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3195 (xor:SI (match_dup 1) (match_dup 2)))]
3197 "eors%?\\t%0, %1, %2"
3198 [(set_attr "conds" "set")
3199 (set_attr "type" "logics_imm,logics_reg")]
3202 (define_insn "*xorsi3_compare0_scratch"
3203 [(set (reg:CC_NOOV CC_REGNUM)
3204 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3205 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3209 [(set_attr "conds" "set")
3210 (set_attr "type" "logics_imm,logics_reg")]
3213 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3214 ; (NOT D) we can sometimes merge the final NOT into one of the following
3218 [(set (match_operand:SI 0 "s_register_operand" "")
3219 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3220 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3221 (match_operand:SI 3 "arm_rhs_operand" "")))
3222 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3224 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3225 (not:SI (match_dup 3))))
3226 (set (match_dup 0) (not:SI (match_dup 4)))]
3230 (define_insn_and_split "*andsi_iorsi3_notsi"
3231 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3232 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3233 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3234 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3236 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3237 "&& reload_completed"
3238 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3239 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3241 /* If operands[3] is a constant make sure to fold the NOT into it
3242 to avoid creating a NOT of a CONST_INT. */
3243 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3244 if (CONST_INT_P (not_rtx))
3246 operands[4] = operands[0];
3247 operands[5] = not_rtx;
3251 operands[5] = operands[0];
3252 operands[4] = not_rtx;
3255 [(set_attr "length" "8")
3256 (set_attr "ce_count" "2")
3257 (set_attr "predicable" "yes")
3258 (set_attr "predicable_short_it" "no")
3259 (set_attr "type" "multiple")]
3262 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3263 ; insns are available?
3265 [(set (match_operand:SI 0 "s_register_operand" "")
3266 (match_operator:SI 1 "logical_binary_operator"
3267 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3268 (match_operand:SI 3 "const_int_operand" "")
3269 (match_operand:SI 4 "const_int_operand" ""))
3270 (match_operator:SI 9 "logical_binary_operator"
3271 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3272 (match_operand:SI 6 "const_int_operand" ""))
3273 (match_operand:SI 7 "s_register_operand" "")])]))
3274 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3276 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3277 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3280 [(ashift:SI (match_dup 2) (match_dup 4))
3284 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3287 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3291 [(set (match_operand:SI 0 "s_register_operand" "")
3292 (match_operator:SI 1 "logical_binary_operator"
3293 [(match_operator:SI 9 "logical_binary_operator"
3294 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3295 (match_operand:SI 6 "const_int_operand" ""))
3296 (match_operand:SI 7 "s_register_operand" "")])
3297 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3298 (match_operand:SI 3 "const_int_operand" "")
3299 (match_operand:SI 4 "const_int_operand" ""))]))
3300 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3302 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3303 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3306 [(ashift:SI (match_dup 2) (match_dup 4))
3310 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3313 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3317 [(set (match_operand:SI 0 "s_register_operand" "")
3318 (match_operator:SI 1 "logical_binary_operator"
3319 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3320 (match_operand:SI 3 "const_int_operand" "")
3321 (match_operand:SI 4 "const_int_operand" ""))
3322 (match_operator:SI 9 "logical_binary_operator"
3323 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3324 (match_operand:SI 6 "const_int_operand" ""))
3325 (match_operand:SI 7 "s_register_operand" "")])]))
3326 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3328 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3329 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3332 [(ashift:SI (match_dup 2) (match_dup 4))
3336 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3339 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3343 [(set (match_operand:SI 0 "s_register_operand" "")
3344 (match_operator:SI 1 "logical_binary_operator"
3345 [(match_operator:SI 9 "logical_binary_operator"
3346 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3347 (match_operand:SI 6 "const_int_operand" ""))
3348 (match_operand:SI 7 "s_register_operand" "")])
3349 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3350 (match_operand:SI 3 "const_int_operand" "")
3351 (match_operand:SI 4 "const_int_operand" ""))]))
3352 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3354 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3355 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3358 [(ashift:SI (match_dup 2) (match_dup 4))
3362 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3365 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3369 ;; Minimum and maximum insns
3371 (define_expand "smaxsi3"
3373 (set (match_operand:SI 0 "s_register_operand" "")
3374 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3375 (match_operand:SI 2 "arm_rhs_operand" "")))
3376 (clobber (reg:CC CC_REGNUM))])]
3379 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3381 /* No need for a clobber of the condition code register here. */
3382 emit_insn (gen_rtx_SET (operands[0],
3383 gen_rtx_SMAX (SImode, operands[1],
3389 (define_insn "*smax_0"
3390 [(set (match_operand:SI 0 "s_register_operand" "=r")
3391 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3394 "bic%?\\t%0, %1, %1, asr #31"
3395 [(set_attr "predicable" "yes")
3396 (set_attr "predicable_short_it" "no")
3397 (set_attr "type" "logic_shift_reg")]
3400 (define_insn "*smax_m1"
3401 [(set (match_operand:SI 0 "s_register_operand" "=r")
3402 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3405 "orr%?\\t%0, %1, %1, asr #31"
3406 [(set_attr "predicable" "yes")
3407 (set_attr "predicable_short_it" "no")
3408 (set_attr "type" "logic_shift_reg")]
3411 (define_insn_and_split "*arm_smax_insn"
3412 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3413 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3414 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3415 (clobber (reg:CC CC_REGNUM))]
3418 ; cmp\\t%1, %2\;movlt\\t%0, %2
3419 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3421 [(set (reg:CC CC_REGNUM)
3422 (compare:CC (match_dup 1) (match_dup 2)))
3424 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3428 [(set_attr "conds" "clob")
3429 (set_attr "length" "8,12")
3430 (set_attr "type" "multiple")]
3433 (define_expand "sminsi3"
3435 (set (match_operand:SI 0 "s_register_operand" "")
3436 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3437 (match_operand:SI 2 "arm_rhs_operand" "")))
3438 (clobber (reg:CC CC_REGNUM))])]
3441 if (operands[2] == const0_rtx)
3443 /* No need for a clobber of the condition code register here. */
3444 emit_insn (gen_rtx_SET (operands[0],
3445 gen_rtx_SMIN (SImode, operands[1],
3451 (define_insn "*smin_0"
3452 [(set (match_operand:SI 0 "s_register_operand" "=r")
3453 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3456 "and%?\\t%0, %1, %1, asr #31"
3457 [(set_attr "predicable" "yes")
3458 (set_attr "predicable_short_it" "no")
3459 (set_attr "type" "logic_shift_reg")]
3462 (define_insn_and_split "*arm_smin_insn"
3463 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3464 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3465 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3466 (clobber (reg:CC CC_REGNUM))]
3469 ; cmp\\t%1, %2\;movge\\t%0, %2
3470 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3472 [(set (reg:CC CC_REGNUM)
3473 (compare:CC (match_dup 1) (match_dup 2)))
3475 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3479 [(set_attr "conds" "clob")
3480 (set_attr "length" "8,12")
3481 (set_attr "type" "multiple,multiple")]
3484 (define_expand "umaxsi3"
3486 (set (match_operand:SI 0 "s_register_operand" "")
3487 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3488 (match_operand:SI 2 "arm_rhs_operand" "")))
3489 (clobber (reg:CC CC_REGNUM))])]
3494 (define_insn_and_split "*arm_umaxsi3"
3495 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3496 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3497 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3498 (clobber (reg:CC CC_REGNUM))]
3501 ; cmp\\t%1, %2\;movcc\\t%0, %2
3502 ; cmp\\t%1, %2\;movcs\\t%0, %1
3503 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3505 [(set (reg:CC CC_REGNUM)
3506 (compare:CC (match_dup 1) (match_dup 2)))
3508 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3512 [(set_attr "conds" "clob")
3513 (set_attr "length" "8,8,12")
3514 (set_attr "type" "store1")]
3517 (define_expand "uminsi3"
3519 (set (match_operand:SI 0 "s_register_operand" "")
3520 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3521 (match_operand:SI 2 "arm_rhs_operand" "")))
3522 (clobber (reg:CC CC_REGNUM))])]
3527 (define_insn_and_split "*arm_uminsi3"
3528 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3529 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3530 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3531 (clobber (reg:CC CC_REGNUM))]
3534 ; cmp\\t%1, %2\;movcs\\t%0, %2
3535 ; cmp\\t%1, %2\;movcc\\t%0, %1
3536 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3538 [(set (reg:CC CC_REGNUM)
3539 (compare:CC (match_dup 1) (match_dup 2)))
3541 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3545 [(set_attr "conds" "clob")
3546 (set_attr "length" "8,8,12")
3547 (set_attr "type" "store1")]
3550 (define_insn "*store_minmaxsi"
3551 [(set (match_operand:SI 0 "memory_operand" "=m")
3552 (match_operator:SI 3 "minmax_operator"
3553 [(match_operand:SI 1 "s_register_operand" "r")
3554 (match_operand:SI 2 "s_register_operand" "r")]))
3555 (clobber (reg:CC CC_REGNUM))]
3556 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3558 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3559 operands[1], operands[2]);
3560 output_asm_insn (\"cmp\\t%1, %2\", operands);
3562 output_asm_insn (\"ite\t%d3\", operands);
3563 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3564 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3567 [(set_attr "conds" "clob")
3568 (set (attr "length")
3569 (if_then_else (eq_attr "is_thumb" "yes")
3572 (set_attr "type" "store1")]
3575 ; Reject the frame pointer in operand[1], since reloading this after
3576 ; it has been eliminated can cause carnage.
3577 (define_insn "*minmax_arithsi"
3578 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3579 (match_operator:SI 4 "shiftable_operator"
3580 [(match_operator:SI 5 "minmax_operator"
3581 [(match_operand:SI 2 "s_register_operand" "r,r")
3582 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3583 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3584 (clobber (reg:CC CC_REGNUM))]
3585 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3588 enum rtx_code code = GET_CODE (operands[4]);
3591 if (which_alternative != 0 || operands[3] != const0_rtx
3592 || (code != PLUS && code != IOR && code != XOR))
3597 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3598 operands[2], operands[3]);
3599 output_asm_insn (\"cmp\\t%2, %3\", operands);
3603 output_asm_insn (\"ite\\t%d5\", operands);
3605 output_asm_insn (\"it\\t%d5\", operands);
3607 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3609 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3612 [(set_attr "conds" "clob")
3613 (set (attr "length")
3614 (if_then_else (eq_attr "is_thumb" "yes")
3617 (set_attr "type" "multiple")]
3620 ; Reject the frame pointer in operand[1], since reloading this after
3621 ; it has been eliminated can cause carnage.
3622 (define_insn_and_split "*minmax_arithsi_non_canon"
3623 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3625 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3626 (match_operator:SI 4 "minmax_operator"
3627 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3628 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3629 (clobber (reg:CC CC_REGNUM))]
3630 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3631 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3633 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3634 [(set (reg:CC CC_REGNUM)
3635 (compare:CC (match_dup 2) (match_dup 3)))
3637 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3639 (minus:SI (match_dup 1)
3641 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3645 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3646 operands[2], operands[3]);
3647 enum rtx_code rc = minmax_code (operands[4]);
3648 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3649 operands[2], operands[3]);
3651 if (mode == CCFPmode || mode == CCFPEmode)
3652 rc = reverse_condition_maybe_unordered (rc);
3654 rc = reverse_condition (rc);
3655 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3656 if (CONST_INT_P (operands[3]))
3657 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3659 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3661 [(set_attr "conds" "clob")
3662 (set (attr "length")
3663 (if_then_else (eq_attr "is_thumb" "yes")
3666 (set_attr "type" "multiple")]
3669 (define_code_iterator SAT [smin smax])
3670 (define_code_iterator SATrev [smin smax])
3671 (define_code_attr SATlo [(smin "1") (smax "2")])
3672 (define_code_attr SAThi [(smin "2") (smax "1")])
3674 (define_insn "*satsi_<SAT:code>"
3675 [(set (match_operand:SI 0 "s_register_operand" "=r")
3676 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3677 (match_operand:SI 1 "const_int_operand" "i"))
3678 (match_operand:SI 2 "const_int_operand" "i")))]
3679 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3680 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3684 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3685 &mask, &signed_sat))
3688 operands[1] = GEN_INT (mask);
3690 return "ssat%?\t%0, %1, %3";
3692 return "usat%?\t%0, %1, %3";
3694 [(set_attr "predicable" "yes")
3695 (set_attr "predicable_short_it" "no")
3696 (set_attr "type" "alus_imm")]
3699 (define_insn "*satsi_<SAT:code>_shift"
3700 [(set (match_operand:SI 0 "s_register_operand" "=r")
3701 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3702 [(match_operand:SI 4 "s_register_operand" "r")
3703 (match_operand:SI 5 "const_int_operand" "i")])
3704 (match_operand:SI 1 "const_int_operand" "i"))
3705 (match_operand:SI 2 "const_int_operand" "i")))]
3706 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3707 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3711 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3712 &mask, &signed_sat))
3715 operands[1] = GEN_INT (mask);
3717 return "ssat%?\t%0, %1, %4%S3";
3719 return "usat%?\t%0, %1, %4%S3";
3721 [(set_attr "predicable" "yes")
3722 (set_attr "predicable_short_it" "no")
3723 (set_attr "shift" "3")
3724 (set_attr "type" "logic_shift_reg")])
3726 ;; Shift and rotation insns
3728 (define_expand "ashldi3"
3729 [(set (match_operand:DI 0 "s_register_operand" "")
3730 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3731 (match_operand:SI 2 "general_operand" "")))]
3736 /* Delay the decision whether to use NEON or core-regs until
3737 register allocation. */
3738 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3743 /* Only the NEON case can handle in-memory shift counts. */
3744 if (!reg_or_int_operand (operands[2], SImode))
3745 operands[2] = force_reg (SImode, operands[2]);
3748 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3749 ; /* No special preparation statements; expand pattern as above. */
3752 rtx scratch1, scratch2;
3754 if (operands[2] == CONST1_RTX (SImode))
3756 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3760 /* Ideally we should use iwmmxt here if we could know that operands[1]
3761 ends up already living in an iwmmxt register. Otherwise it's
3762 cheaper to have the alternate code being generated than moving
3763 values to iwmmxt regs and back. */
3765 /* If we're optimizing for size, we prefer the libgcc calls. */
3766 if (optimize_function_for_size_p (cfun))
3769 /* Expand operation using core-registers.
3770 'FAIL' would achieve the same thing, but this is a bit smarter. */
3771 scratch1 = gen_reg_rtx (SImode);
3772 scratch2 = gen_reg_rtx (SImode);
3773 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3774 operands[2], scratch1, scratch2);
3780 (define_insn "arm_ashldi3_1bit"
3781 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3782 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3784 (clobber (reg:CC CC_REGNUM))]
3786 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3787 [(set_attr "conds" "clob")
3788 (set_attr "length" "8")
3789 (set_attr "type" "multiple")]
3792 (define_expand "ashlsi3"
3793 [(set (match_operand:SI 0 "s_register_operand" "")
3794 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3795 (match_operand:SI 2 "arm_rhs_operand" "")))]
3798 if (CONST_INT_P (operands[2])
3799 && (UINTVAL (operands[2])) > 31)
3801 emit_insn (gen_movsi (operands[0], const0_rtx));
3807 (define_expand "ashrdi3"
3808 [(set (match_operand:DI 0 "s_register_operand" "")
3809 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3810 (match_operand:SI 2 "reg_or_int_operand" "")))]
3815 /* Delay the decision whether to use NEON or core-regs until
3816 register allocation. */
3817 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3821 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3822 ; /* No special preparation statements; expand pattern as above. */
3825 rtx scratch1, scratch2;
3827 if (operands[2] == CONST1_RTX (SImode))
3829 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3833 /* Ideally we should use iwmmxt here if we could know that operands[1]
3834 ends up already living in an iwmmxt register. Otherwise it's
3835 cheaper to have the alternate code being generated than moving
3836 values to iwmmxt regs and back. */
3838 /* If we're optimizing for size, we prefer the libgcc calls. */
3839 if (optimize_function_for_size_p (cfun))
3842 /* Expand operation using core-registers.
3843 'FAIL' would achieve the same thing, but this is a bit smarter. */
3844 scratch1 = gen_reg_rtx (SImode);
3845 scratch2 = gen_reg_rtx (SImode);
3846 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3847 operands[2], scratch1, scratch2);
3853 (define_insn "arm_ashrdi3_1bit"
3854 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3855 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3857 (clobber (reg:CC CC_REGNUM))]
3859 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3860 [(set_attr "conds" "clob")
3861 (set_attr "length" "8")
3862 (set_attr "type" "multiple")]
3865 (define_expand "ashrsi3"
3866 [(set (match_operand:SI 0 "s_register_operand" "")
3867 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3868 (match_operand:SI 2 "arm_rhs_operand" "")))]
3871 if (CONST_INT_P (operands[2])
3872 && UINTVAL (operands[2]) > 31)
3873 operands[2] = GEN_INT (31);
3877 (define_expand "lshrdi3"
3878 [(set (match_operand:DI 0 "s_register_operand" "")
3879 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3880 (match_operand:SI 2 "reg_or_int_operand" "")))]
3885 /* Delay the decision whether to use NEON or core-regs until
3886 register allocation. */
3887 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3891 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3892 ; /* No special preparation statements; expand pattern as above. */
3895 rtx scratch1, scratch2;
3897 if (operands[2] == CONST1_RTX (SImode))
3899 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3903 /* Ideally we should use iwmmxt here if we could know that operands[1]
3904 ends up already living in an iwmmxt register. Otherwise it's
3905 cheaper to have the alternate code being generated than moving
3906 values to iwmmxt regs and back. */
3908 /* If we're optimizing for size, we prefer the libgcc calls. */
3909 if (optimize_function_for_size_p (cfun))
3912 /* Expand operation using core-registers.
3913 'FAIL' would achieve the same thing, but this is a bit smarter. */
3914 scratch1 = gen_reg_rtx (SImode);
3915 scratch2 = gen_reg_rtx (SImode);
3916 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3917 operands[2], scratch1, scratch2);
3923 (define_insn "arm_lshrdi3_1bit"
3924 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3925 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3927 (clobber (reg:CC CC_REGNUM))]
3929 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3930 [(set_attr "conds" "clob")
3931 (set_attr "length" "8")
3932 (set_attr "type" "multiple")]
3935 (define_expand "lshrsi3"
3936 [(set (match_operand:SI 0 "s_register_operand" "")
3937 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3938 (match_operand:SI 2 "arm_rhs_operand" "")))]
3941 if (CONST_INT_P (operands[2])
3942 && (UINTVAL (operands[2])) > 31)
3944 emit_insn (gen_movsi (operands[0], const0_rtx));
3950 (define_expand "rotlsi3"
3951 [(set (match_operand:SI 0 "s_register_operand" "")
3952 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3953 (match_operand:SI 2 "reg_or_int_operand" "")))]
3956 if (CONST_INT_P (operands[2]))
3957 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3960 rtx reg = gen_reg_rtx (SImode);
3961 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3967 (define_expand "rotrsi3"
3968 [(set (match_operand:SI 0 "s_register_operand" "")
3969 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3970 (match_operand:SI 2 "arm_rhs_operand" "")))]
3975 if (CONST_INT_P (operands[2])
3976 && UINTVAL (operands[2]) > 31)
3977 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3979 else /* TARGET_THUMB1 */
3981 if (CONST_INT_P (operands [2]))
3982 operands [2] = force_reg (SImode, operands[2]);
3987 (define_insn "*arm_shiftsi3"
3988 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
3989 (match_operator:SI 3 "shift_operator"
3990 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
3991 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
3993 "* return arm_output_shift(operands, 0);"
3994 [(set_attr "predicable" "yes")
3995 (set_attr "arch" "t2,t2,*,*")
3996 (set_attr "predicable_short_it" "yes,yes,no,no")
3997 (set_attr "length" "4")
3998 (set_attr "shift" "1")
3999 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4002 (define_insn "*shiftsi3_compare0"
4003 [(set (reg:CC_NOOV CC_REGNUM)
4004 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4005 [(match_operand:SI 1 "s_register_operand" "r,r")
4006 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4008 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4009 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4011 "* return arm_output_shift(operands, 1);"
4012 [(set_attr "conds" "set")
4013 (set_attr "shift" "1")
4014 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4017 (define_insn "*shiftsi3_compare0_scratch"
4018 [(set (reg:CC_NOOV CC_REGNUM)
4019 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4020 [(match_operand:SI 1 "s_register_operand" "r,r")
4021 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4023 (clobber (match_scratch:SI 0 "=r,r"))]
4025 "* return arm_output_shift(operands, 1);"
4026 [(set_attr "conds" "set")
4027 (set_attr "shift" "1")
4028 (set_attr "type" "shift_imm,shift_reg")]
4031 (define_insn "*not_shiftsi"
4032 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4033 (not:SI (match_operator:SI 3 "shift_operator"
4034 [(match_operand:SI 1 "s_register_operand" "r,r")
4035 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4038 [(set_attr "predicable" "yes")
4039 (set_attr "predicable_short_it" "no")
4040 (set_attr "shift" "1")
4041 (set_attr "arch" "32,a")
4042 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4044 (define_insn "*not_shiftsi_compare0"
4045 [(set (reg:CC_NOOV CC_REGNUM)
4047 (not:SI (match_operator:SI 3 "shift_operator"
4048 [(match_operand:SI 1 "s_register_operand" "r,r")
4049 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4051 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4052 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4054 "mvns%?\\t%0, %1%S3"
4055 [(set_attr "conds" "set")
4056 (set_attr "shift" "1")
4057 (set_attr "arch" "32,a")
4058 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4060 (define_insn "*not_shiftsi_compare0_scratch"
4061 [(set (reg:CC_NOOV CC_REGNUM)
4063 (not:SI (match_operator:SI 3 "shift_operator"
4064 [(match_operand:SI 1 "s_register_operand" "r,r")
4065 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4067 (clobber (match_scratch:SI 0 "=r,r"))]
4069 "mvns%?\\t%0, %1%S3"
4070 [(set_attr "conds" "set")
4071 (set_attr "shift" "1")
4072 (set_attr "arch" "32,a")
4073 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4075 ;; We don't really have extzv, but defining this using shifts helps
4076 ;; to reduce register pressure later on.
4078 (define_expand "extzv"
4079 [(set (match_operand 0 "s_register_operand" "")
4080 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4081 (match_operand 2 "const_int_operand" "")
4082 (match_operand 3 "const_int_operand" "")))]
4083 "TARGET_THUMB1 || arm_arch_thumb2"
4086 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4087 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4089 if (arm_arch_thumb2)
4091 HOST_WIDE_INT width = INTVAL (operands[2]);
4092 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4094 if (unaligned_access && MEM_P (operands[1])
4095 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4099 if (BYTES_BIG_ENDIAN)
4100 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4105 base_addr = adjust_address (operands[1], SImode,
4106 bitpos / BITS_PER_UNIT);
4107 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4111 rtx dest = operands[0];
4112 rtx tmp = gen_reg_rtx (SImode);
4114 /* We may get a paradoxical subreg here. Strip it off. */
4115 if (GET_CODE (dest) == SUBREG
4116 && GET_MODE (dest) == SImode
4117 && GET_MODE (SUBREG_REG (dest)) == HImode)
4118 dest = SUBREG_REG (dest);
4120 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4123 base_addr = adjust_address (operands[1], HImode,
4124 bitpos / BITS_PER_UNIT);
4125 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4126 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4130 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4132 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4140 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4143 operands[3] = GEN_INT (rshift);
4147 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4151 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4152 operands[3], gen_reg_rtx (SImode)));
4157 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4159 (define_expand "extzv_t1"
4160 [(set (match_operand:SI 4 "s_register_operand" "")
4161 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4162 (match_operand:SI 2 "const_int_operand" "")))
4163 (set (match_operand:SI 0 "s_register_operand" "")
4164 (lshiftrt:SI (match_dup 4)
4165 (match_operand:SI 3 "const_int_operand" "")))]
4169 (define_expand "extv"
4170 [(set (match_operand 0 "s_register_operand" "")
4171 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4172 (match_operand 2 "const_int_operand" "")
4173 (match_operand 3 "const_int_operand" "")))]
4176 HOST_WIDE_INT width = INTVAL (operands[2]);
4177 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4179 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4180 && (bitpos % BITS_PER_UNIT) == 0)
4184 if (BYTES_BIG_ENDIAN)
4185 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4189 base_addr = adjust_address (operands[1], SImode,
4190 bitpos / BITS_PER_UNIT);
4191 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4195 rtx dest = operands[0];
4196 rtx tmp = gen_reg_rtx (SImode);
4198 /* We may get a paradoxical subreg here. Strip it off. */
4199 if (GET_CODE (dest) == SUBREG
4200 && GET_MODE (dest) == SImode
4201 && GET_MODE (SUBREG_REG (dest)) == HImode)
4202 dest = SUBREG_REG (dest);
4204 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4207 base_addr = adjust_address (operands[1], HImode,
4208 bitpos / BITS_PER_UNIT);
4209 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4210 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4215 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4217 else if (GET_MODE (operands[0]) == SImode
4218 && GET_MODE (operands[1]) == SImode)
4220 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4228 ; Helper to expand register forms of extv with the proper modes.
4230 (define_expand "extv_regsi"
4231 [(set (match_operand:SI 0 "s_register_operand" "")
4232 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4233 (match_operand 2 "const_int_operand" "")
4234 (match_operand 3 "const_int_operand" "")))]
4239 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4241 (define_insn "unaligned_loadsi"
4242 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4243 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4244 UNSPEC_UNALIGNED_LOAD))]
4246 "ldr%?\t%0, %1\t@ unaligned"
4247 [(set_attr "arch" "t2,any")
4248 (set_attr "length" "2,4")
4249 (set_attr "predicable" "yes")
4250 (set_attr "predicable_short_it" "yes,no")
4251 (set_attr "type" "load1")])
4253 (define_insn "unaligned_loadhis"
4254 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4256 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4257 UNSPEC_UNALIGNED_LOAD)))]
4259 "ldrsh%?\t%0, %1\t@ unaligned"
4260 [(set_attr "arch" "t2,any")
4261 (set_attr "length" "2,4")
4262 (set_attr "predicable" "yes")
4263 (set_attr "predicable_short_it" "yes,no")
4264 (set_attr "type" "load_byte")])
4266 (define_insn "unaligned_loadhiu"
4267 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4269 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4270 UNSPEC_UNALIGNED_LOAD)))]
4272 "ldrh%?\t%0, %1\t@ unaligned"
4273 [(set_attr "arch" "t2,any")
4274 (set_attr "length" "2,4")
4275 (set_attr "predicable" "yes")
4276 (set_attr "predicable_short_it" "yes,no")
4277 (set_attr "type" "load_byte")])
4279 (define_insn "unaligned_storesi"
4280 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4281 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4282 UNSPEC_UNALIGNED_STORE))]
4284 "str%?\t%1, %0\t@ unaligned"
4285 [(set_attr "arch" "t2,any")
4286 (set_attr "length" "2,4")
4287 (set_attr "predicable" "yes")
4288 (set_attr "predicable_short_it" "yes,no")
4289 (set_attr "type" "store1")])
4291 (define_insn "unaligned_storehi"
4292 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4293 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4294 UNSPEC_UNALIGNED_STORE))]
4296 "strh%?\t%1, %0\t@ unaligned"
4297 [(set_attr "arch" "t2,any")
4298 (set_attr "length" "2,4")
4299 (set_attr "predicable" "yes")
4300 (set_attr "predicable_short_it" "yes,no")
4301 (set_attr "type" "store1")])
4304 (define_insn "*extv_reg"
4305 [(set (match_operand:SI 0 "s_register_operand" "=r")
4306 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4307 (match_operand:SI 2 "const_int_M_operand" "M")
4308 (match_operand:SI 3 "const_int_M_operand" "M")))]
4310 "sbfx%?\t%0, %1, %3, %2"
4311 [(set_attr "length" "4")
4312 (set_attr "predicable" "yes")
4313 (set_attr "predicable_short_it" "no")
4314 (set_attr "type" "bfm")]
4317 (define_insn "extzv_t2"
4318 [(set (match_operand:SI 0 "s_register_operand" "=r")
4319 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4320 (match_operand:SI 2 "const_int_M_operand" "M")
4321 (match_operand:SI 3 "const_int_M_operand" "M")))]
4323 "ubfx%?\t%0, %1, %3, %2"
4324 [(set_attr "length" "4")
4325 (set_attr "predicable" "yes")
4326 (set_attr "predicable_short_it" "no")
4327 (set_attr "type" "bfm")]
4331 ;; Division instructions
4332 (define_insn "divsi3"
4333 [(set (match_operand:SI 0 "s_register_operand" "=r")
4334 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4335 (match_operand:SI 2 "s_register_operand" "r")))]
4337 "sdiv%?\t%0, %1, %2"
4338 [(set_attr "predicable" "yes")
4339 (set_attr "predicable_short_it" "no")
4340 (set_attr "type" "sdiv")]
4343 (define_insn "udivsi3"
4344 [(set (match_operand:SI 0 "s_register_operand" "=r")
4345 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4346 (match_operand:SI 2 "s_register_operand" "r")))]
4348 "udiv%?\t%0, %1, %2"
4349 [(set_attr "predicable" "yes")
4350 (set_attr "predicable_short_it" "no")
4351 (set_attr "type" "udiv")]
4355 ;; Unary arithmetic insns
4357 (define_expand "negdi2"
4359 [(set (match_operand:DI 0 "s_register_operand" "")
4360 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4361 (clobber (reg:CC CC_REGNUM))])]
4366 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4372 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4373 ;; The first alternative allows the common case of a *full* overlap.
4374 (define_insn_and_split "*arm_negdi2"
4375 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4376 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4377 (clobber (reg:CC CC_REGNUM))]
4379 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4380 "&& reload_completed"
4381 [(parallel [(set (reg:CC CC_REGNUM)
4382 (compare:CC (const_int 0) (match_dup 1)))
4383 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4384 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4385 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4387 operands[2] = gen_highpart (SImode, operands[0]);
4388 operands[0] = gen_lowpart (SImode, operands[0]);
4389 operands[3] = gen_highpart (SImode, operands[1]);
4390 operands[1] = gen_lowpart (SImode, operands[1]);
4392 [(set_attr "conds" "clob")
4393 (set_attr "length" "8")
4394 (set_attr "type" "multiple")]
4397 (define_expand "negsi2"
4398 [(set (match_operand:SI 0 "s_register_operand" "")
4399 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4404 (define_insn "*arm_negsi2"
4405 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4406 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4408 "rsb%?\\t%0, %1, #0"
4409 [(set_attr "predicable" "yes")
4410 (set_attr "predicable_short_it" "yes,no")
4411 (set_attr "arch" "t2,*")
4412 (set_attr "length" "4")
4413 (set_attr "type" "alu_sreg")]
4416 (define_expand "negsf2"
4417 [(set (match_operand:SF 0 "s_register_operand" "")
4418 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4419 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4423 (define_expand "negdf2"
4424 [(set (match_operand:DF 0 "s_register_operand" "")
4425 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4426 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4429 (define_insn_and_split "*zextendsidi_negsi"
4430 [(set (match_operand:DI 0 "s_register_operand" "=r")
4431 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4436 (neg:SI (match_dup 1)))
4440 operands[2] = gen_lowpart (SImode, operands[0]);
4441 operands[3] = gen_highpart (SImode, operands[0]);
4443 [(set_attr "length" "8")
4444 (set_attr "type" "multiple")]
4447 ;; Negate an extended 32-bit value.
4448 (define_insn_and_split "*negdi_extendsidi"
4449 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4450 (neg:DI (sign_extend:DI
4451 (match_operand:SI 1 "s_register_operand" "l,r"))))
4452 (clobber (reg:CC CC_REGNUM))]
4455 "&& reload_completed"
4458 rtx low = gen_lowpart (SImode, operands[0]);
4459 rtx high = gen_highpart (SImode, operands[0]);
4461 if (reg_overlap_mentioned_p (low, operands[1]))
4463 /* Input overlaps the low word of the output. Use:
4466 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4467 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4469 emit_insn (gen_rtx_SET (high,
4470 gen_rtx_ASHIFTRT (SImode, operands[1],
4473 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4475 emit_insn (gen_rtx_SET (high,
4476 gen_rtx_MINUS (SImode,
4477 gen_rtx_MINUS (SImode,
4480 gen_rtx_LTU (SImode,
4485 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4486 emit_insn (gen_rtx_SET (high,
4487 gen_rtx_MINUS (SImode,
4488 gen_rtx_MINUS (SImode,
4491 gen_rtx_LTU (SImode,
4498 /* No overlap, or overlap on high word. Use:
4502 Flags not needed for this sequence. */
4503 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4504 emit_insn (gen_rtx_SET (high,
4505 gen_rtx_AND (SImode,
4506 gen_rtx_NOT (SImode, operands[1]),
4508 emit_insn (gen_rtx_SET (high,
4509 gen_rtx_ASHIFTRT (SImode, high,
4514 [(set_attr "length" "12")
4515 (set_attr "arch" "t2,*")
4516 (set_attr "type" "multiple")]
4519 (define_insn_and_split "*negdi_zero_extendsidi"
4520 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4521 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4522 (clobber (reg:CC CC_REGNUM))]
4524 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4525 ;; Don't care what register is input to sbc,
4526 ;; since we just need to propagate the carry.
4527 "&& reload_completed"
4528 [(parallel [(set (reg:CC CC_REGNUM)
4529 (compare:CC (const_int 0) (match_dup 1)))
4530 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4531 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4532 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4534 operands[2] = gen_highpart (SImode, operands[0]);
4535 operands[0] = gen_lowpart (SImode, operands[0]);
4537 [(set_attr "conds" "clob")
4538 (set_attr "length" "8")
4539 (set_attr "type" "multiple")] ;; length in thumb is 4
4542 ;; abssi2 doesn't really clobber the condition codes if a different register
4543 ;; is being set. To keep things simple, assume during rtl manipulations that
4544 ;; it does, but tell the final scan operator the truth. Similarly for
4547 (define_expand "abssi2"
4549 [(set (match_operand:SI 0 "s_register_operand" "")
4550 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4551 (clobber (match_dup 2))])]
4555 operands[2] = gen_rtx_SCRATCH (SImode);
4557 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4560 (define_insn_and_split "*arm_abssi2"
4561 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4562 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4563 (clobber (reg:CC CC_REGNUM))]
4566 "&& reload_completed"
4569 /* if (which_alternative == 0) */
4570 if (REGNO(operands[0]) == REGNO(operands[1]))
4572 /* Emit the pattern:
4573 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4574 [(set (reg:CC CC_REGNUM)
4575 (compare:CC (match_dup 0) (const_int 0)))
4576 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4577 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4579 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4580 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4581 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4582 (gen_rtx_LT (SImode,
4583 gen_rtx_REG (CCmode, CC_REGNUM),
4585 (gen_rtx_SET (operands[0],
4586 (gen_rtx_MINUS (SImode,
4593 /* Emit the pattern:
4594 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4596 (xor:SI (match_dup 1)
4597 (ashiftrt:SI (match_dup 1) (const_int 31))))
4599 (minus:SI (match_dup 0)
4600 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4602 emit_insn (gen_rtx_SET (operands[0],
4603 gen_rtx_XOR (SImode,
4604 gen_rtx_ASHIFTRT (SImode,
4608 emit_insn (gen_rtx_SET (operands[0],
4609 gen_rtx_MINUS (SImode,
4611 gen_rtx_ASHIFTRT (SImode,
4617 [(set_attr "conds" "clob,*")
4618 (set_attr "shift" "1")
4619 (set_attr "predicable" "no, yes")
4620 (set_attr "length" "8")
4621 (set_attr "type" "multiple")]
4624 (define_insn_and_split "*arm_neg_abssi2"
4625 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4626 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4627 (clobber (reg:CC CC_REGNUM))]
4630 "&& reload_completed"
4633 /* if (which_alternative == 0) */
4634 if (REGNO (operands[0]) == REGNO (operands[1]))
4636 /* Emit the pattern:
4637 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4639 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4640 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4641 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4643 gen_rtx_REG (CCmode, CC_REGNUM),
4645 gen_rtx_SET (operands[0],
4646 (gen_rtx_MINUS (SImode,
4652 /* Emit the pattern:
4653 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4655 emit_insn (gen_rtx_SET (operands[0],
4656 gen_rtx_XOR (SImode,
4657 gen_rtx_ASHIFTRT (SImode,
4661 emit_insn (gen_rtx_SET (operands[0],
4662 gen_rtx_MINUS (SImode,
4663 gen_rtx_ASHIFTRT (SImode,
4670 [(set_attr "conds" "clob,*")
4671 (set_attr "shift" "1")
4672 (set_attr "predicable" "no, yes")
4673 (set_attr "length" "8")
4674 (set_attr "type" "multiple")]
4677 (define_expand "abssf2"
4678 [(set (match_operand:SF 0 "s_register_operand" "")
4679 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4680 "TARGET_32BIT && TARGET_HARD_FLOAT"
4683 (define_expand "absdf2"
4684 [(set (match_operand:DF 0 "s_register_operand" "")
4685 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4686 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4689 (define_expand "sqrtsf2"
4690 [(set (match_operand:SF 0 "s_register_operand" "")
4691 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4692 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4695 (define_expand "sqrtdf2"
4696 [(set (match_operand:DF 0 "s_register_operand" "")
4697 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4698 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4701 (define_insn_and_split "one_cmpldi2"
4702 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4703 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4710 "TARGET_32BIT && reload_completed
4711 && arm_general_register_operand (operands[0], DImode)"
4712 [(set (match_dup 0) (not:SI (match_dup 1)))
4713 (set (match_dup 2) (not:SI (match_dup 3)))]
4716 operands[2] = gen_highpart (SImode, operands[0]);
4717 operands[0] = gen_lowpart (SImode, operands[0]);
4718 operands[3] = gen_highpart (SImode, operands[1]);
4719 operands[1] = gen_lowpart (SImode, operands[1]);
4721 [(set_attr "length" "*,8,8,*")
4722 (set_attr "predicable" "no,yes,yes,no")
4723 (set_attr "type" "neon_move,multiple,multiple,neon_move")
4724 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4727 (define_expand "one_cmplsi2"
4728 [(set (match_operand:SI 0 "s_register_operand" "")
4729 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4734 (define_insn "*arm_one_cmplsi2"
4735 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4736 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4739 [(set_attr "predicable" "yes")
4740 (set_attr "predicable_short_it" "yes,no")
4741 (set_attr "arch" "t2,*")
4742 (set_attr "length" "4")
4743 (set_attr "type" "mvn_reg")]
4746 (define_insn "*notsi_compare0"
4747 [(set (reg:CC_NOOV CC_REGNUM)
4748 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4750 (set (match_operand:SI 0 "s_register_operand" "=r")
4751 (not:SI (match_dup 1)))]
4754 [(set_attr "conds" "set")
4755 (set_attr "type" "mvn_reg")]
4758 (define_insn "*notsi_compare0_scratch"
4759 [(set (reg:CC_NOOV CC_REGNUM)
4760 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4762 (clobber (match_scratch:SI 0 "=r"))]
4765 [(set_attr "conds" "set")
4766 (set_attr "type" "mvn_reg")]
4769 ;; Fixed <--> Floating conversion insns
4771 (define_expand "floatsihf2"
4772 [(set (match_operand:HF 0 "general_operand" "")
4773 (float:HF (match_operand:SI 1 "general_operand" "")))]
4777 rtx op1 = gen_reg_rtx (SFmode);
4778 expand_float (op1, operands[1], 0);
4779 op1 = convert_to_mode (HFmode, op1, 0);
4780 emit_move_insn (operands[0], op1);
4785 (define_expand "floatdihf2"
4786 [(set (match_operand:HF 0 "general_operand" "")
4787 (float:HF (match_operand:DI 1 "general_operand" "")))]
4791 rtx op1 = gen_reg_rtx (SFmode);
4792 expand_float (op1, operands[1], 0);
4793 op1 = convert_to_mode (HFmode, op1, 0);
4794 emit_move_insn (operands[0], op1);
4799 (define_expand "floatsisf2"
4800 [(set (match_operand:SF 0 "s_register_operand" "")
4801 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
4802 "TARGET_32BIT && TARGET_HARD_FLOAT"
4806 (define_expand "floatsidf2"
4807 [(set (match_operand:DF 0 "s_register_operand" "")
4808 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
4809 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4813 (define_expand "fix_trunchfsi2"
4814 [(set (match_operand:SI 0 "general_operand" "")
4815 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4819 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4820 expand_fix (operands[0], op1, 0);
4825 (define_expand "fix_trunchfdi2"
4826 [(set (match_operand:DI 0 "general_operand" "")
4827 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4831 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4832 expand_fix (operands[0], op1, 0);
4837 (define_expand "fix_truncsfsi2"
4838 [(set (match_operand:SI 0 "s_register_operand" "")
4839 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
4840 "TARGET_32BIT && TARGET_HARD_FLOAT"
4844 (define_expand "fix_truncdfsi2"
4845 [(set (match_operand:SI 0 "s_register_operand" "")
4846 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
4847 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4853 (define_expand "truncdfsf2"
4854 [(set (match_operand:SF 0 "s_register_operand" "")
4856 (match_operand:DF 1 "s_register_operand" "")))]
4857 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4861 /* DFmode -> HFmode conversions have to go through SFmode. */
4862 (define_expand "truncdfhf2"
4863 [(set (match_operand:HF 0 "general_operand" "")
4865 (match_operand:DF 1 "general_operand" "")))]
4870 op1 = convert_to_mode (SFmode, operands[1], 0);
4871 op1 = convert_to_mode (HFmode, op1, 0);
4872 emit_move_insn (operands[0], op1);
4877 ;; Zero and sign extension instructions.
4879 (define_insn "zero_extend<mode>di2"
4880 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
4881 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4882 "<qhs_zextenddi_cstr>")))]
4883 "TARGET_32BIT <qhs_zextenddi_cond>"
4885 [(set_attr "length" "8,4,8,8")
4886 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
4887 (set_attr "ce_count" "2")
4888 (set_attr "predicable" "yes")
4889 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
4892 (define_insn "extend<mode>di2"
4893 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
4894 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4895 "<qhs_extenddi_cstr>")))]
4896 "TARGET_32BIT <qhs_sextenddi_cond>"
4898 [(set_attr "length" "8,4,8,8,8")
4899 (set_attr "ce_count" "2")
4900 (set_attr "shift" "1")
4901 (set_attr "predicable" "yes")
4902 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4903 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
4906 ;; Splits for all extensions to DImode
4908 [(set (match_operand:DI 0 "s_register_operand" "")
4909 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4910 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4911 [(set (match_dup 0) (match_dup 1))]
4913 rtx lo_part = gen_lowpart (SImode, operands[0]);
4914 machine_mode src_mode = GET_MODE (operands[1]);
4916 if (REG_P (operands[0])
4917 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4918 emit_clobber (operands[0]);
4919 if (!REG_P (lo_part) || src_mode != SImode
4920 || !rtx_equal_p (lo_part, operands[1]))
4922 if (src_mode == SImode)
4923 emit_move_insn (lo_part, operands[1]);
4925 emit_insn (gen_rtx_SET (lo_part,
4926 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4927 operands[1] = lo_part;
4929 operands[0] = gen_highpart (SImode, operands[0]);
4930 operands[1] = const0_rtx;
4934 [(set (match_operand:DI 0 "s_register_operand" "")
4935 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4936 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4937 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4939 rtx lo_part = gen_lowpart (SImode, operands[0]);
4940 machine_mode src_mode = GET_MODE (operands[1]);
4942 if (REG_P (operands[0])
4943 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4944 emit_clobber (operands[0]);
4946 if (!REG_P (lo_part) || src_mode != SImode
4947 || !rtx_equal_p (lo_part, operands[1]))
4949 if (src_mode == SImode)
4950 emit_move_insn (lo_part, operands[1]);
4952 emit_insn (gen_rtx_SET (lo_part,
4953 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4954 operands[1] = lo_part;
4956 operands[0] = gen_highpart (SImode, operands[0]);
4959 (define_expand "zero_extendhisi2"
4960 [(set (match_operand:SI 0 "s_register_operand" "")
4961 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4964 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4966 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4969 if (!arm_arch6 && !MEM_P (operands[1]))
4971 rtx t = gen_lowpart (SImode, operands[1]);
4972 rtx tmp = gen_reg_rtx (SImode);
4973 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4974 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4980 [(set (match_operand:SI 0 "s_register_operand" "")
4981 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4982 "!TARGET_THUMB2 && !arm_arch6"
4983 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4984 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4986 operands[2] = gen_lowpart (SImode, operands[1]);
4989 (define_insn "*arm_zero_extendhisi2"
4990 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4991 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4992 "TARGET_ARM && arm_arch4 && !arm_arch6"
4996 [(set_attr "type" "alu_shift_reg,load_byte")
4997 (set_attr "predicable" "yes")]
5000 (define_insn "*arm_zero_extendhisi2_v6"
5001 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5002 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5003 "TARGET_ARM && arm_arch6"
5007 [(set_attr "predicable" "yes")
5008 (set_attr "type" "extend,load_byte")]
5011 (define_insn "*arm_zero_extendhisi2addsi"
5012 [(set (match_operand:SI 0 "s_register_operand" "=r")
5013 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5014 (match_operand:SI 2 "s_register_operand" "r")))]
5016 "uxtah%?\\t%0, %2, %1"
5017 [(set_attr "type" "alu_shift_reg")
5018 (set_attr "predicable" "yes")
5019 (set_attr "predicable_short_it" "no")]
5022 (define_expand "zero_extendqisi2"
5023 [(set (match_operand:SI 0 "s_register_operand" "")
5024 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5027 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5029 emit_insn (gen_andsi3 (operands[0],
5030 gen_lowpart (SImode, operands[1]),
5034 if (!arm_arch6 && !MEM_P (operands[1]))
5036 rtx t = gen_lowpart (SImode, operands[1]);
5037 rtx tmp = gen_reg_rtx (SImode);
5038 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5039 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5045 [(set (match_operand:SI 0 "s_register_operand" "")
5046 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5048 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5049 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5051 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5054 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5059 (define_insn "*arm_zero_extendqisi2"
5060 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5061 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5062 "TARGET_ARM && !arm_arch6"
5065 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5066 [(set_attr "length" "8,4")
5067 (set_attr "type" "alu_shift_reg,load_byte")
5068 (set_attr "predicable" "yes")]
5071 (define_insn "*arm_zero_extendqisi2_v6"
5072 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5073 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5074 "TARGET_ARM && arm_arch6"
5077 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5078 [(set_attr "type" "extend,load_byte")
5079 (set_attr "predicable" "yes")]
5082 (define_insn "*arm_zero_extendqisi2addsi"
5083 [(set (match_operand:SI 0 "s_register_operand" "=r")
5084 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5085 (match_operand:SI 2 "s_register_operand" "r")))]
5087 "uxtab%?\\t%0, %2, %1"
5088 [(set_attr "predicable" "yes")
5089 (set_attr "predicable_short_it" "no")
5090 (set_attr "type" "alu_shift_reg")]
5094 [(set (match_operand:SI 0 "s_register_operand" "")
5095 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5096 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5097 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5098 [(set (match_dup 2) (match_dup 1))
5099 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5104 [(set (match_operand:SI 0 "s_register_operand" "")
5105 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5106 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5107 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5108 [(set (match_dup 2) (match_dup 1))
5109 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5115 [(set (match_operand:SI 0 "s_register_operand" "")
5116 (IOR_XOR:SI (and:SI (ashift:SI
5117 (match_operand:SI 1 "s_register_operand" "")
5118 (match_operand:SI 2 "const_int_operand" ""))
5119 (match_operand:SI 3 "const_int_operand" ""))
5121 (match_operator 5 "subreg_lowpart_operator"
5122 [(match_operand:SI 4 "s_register_operand" "")]))))]
5124 && (UINTVAL (operands[3])
5125 == (GET_MODE_MASK (GET_MODE (operands[5]))
5126 & (GET_MODE_MASK (GET_MODE (operands[5]))
5127 << (INTVAL (operands[2])))))"
5128 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5130 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5131 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5134 (define_insn "*compareqi_eq0"
5135 [(set (reg:CC_Z CC_REGNUM)
5136 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5140 [(set_attr "conds" "set")
5141 (set_attr "predicable" "yes")
5142 (set_attr "predicable_short_it" "no")
5143 (set_attr "type" "logic_imm")]
5146 (define_expand "extendhisi2"
5147 [(set (match_operand:SI 0 "s_register_operand" "")
5148 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5153 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5156 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5158 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5162 if (!arm_arch6 && !MEM_P (operands[1]))
5164 rtx t = gen_lowpart (SImode, operands[1]);
5165 rtx tmp = gen_reg_rtx (SImode);
5166 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5167 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5174 [(set (match_operand:SI 0 "register_operand" "")
5175 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5176 (clobber (match_scratch:SI 2 ""))])]
5178 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5179 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5181 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5184 ;; This pattern will only be used when ldsh is not available
5185 (define_expand "extendhisi2_mem"
5186 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5188 (zero_extend:SI (match_dup 7)))
5189 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5190 (set (match_operand:SI 0 "" "")
5191 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5196 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5198 mem1 = change_address (operands[1], QImode, addr);
5199 mem2 = change_address (operands[1], QImode,
5200 plus_constant (Pmode, addr, 1));
5201 operands[0] = gen_lowpart (SImode, operands[0]);
5203 operands[2] = gen_reg_rtx (SImode);
5204 operands[3] = gen_reg_rtx (SImode);
5205 operands[6] = gen_reg_rtx (SImode);
5208 if (BYTES_BIG_ENDIAN)
5210 operands[4] = operands[2];
5211 operands[5] = operands[3];
5215 operands[4] = operands[3];
5216 operands[5] = operands[2];
5222 [(set (match_operand:SI 0 "register_operand" "")
5223 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5225 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5226 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5228 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5231 (define_insn "*arm_extendhisi2"
5232 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5233 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5234 "TARGET_ARM && arm_arch4 && !arm_arch6"
5238 [(set_attr "length" "8,4")
5239 (set_attr "type" "alu_shift_reg,load_byte")
5240 (set_attr "predicable" "yes")]
5243 ;; ??? Check Thumb-2 pool range
5244 (define_insn "*arm_extendhisi2_v6"
5245 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5246 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5247 "TARGET_32BIT && arm_arch6"
5251 [(set_attr "type" "extend,load_byte")
5252 (set_attr "predicable" "yes")
5253 (set_attr "predicable_short_it" "no")]
5256 (define_insn "*arm_extendhisi2addsi"
5257 [(set (match_operand:SI 0 "s_register_operand" "=r")
5258 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5259 (match_operand:SI 2 "s_register_operand" "r")))]
5261 "sxtah%?\\t%0, %2, %1"
5262 [(set_attr "type" "alu_shift_reg")]
5265 (define_expand "extendqihi2"
5267 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5269 (set (match_operand:HI 0 "s_register_operand" "")
5270 (ashiftrt:SI (match_dup 2)
5275 if (arm_arch4 && MEM_P (operands[1]))
5277 emit_insn (gen_rtx_SET (operands[0],
5278 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5281 if (!s_register_operand (operands[1], QImode))
5282 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5283 operands[0] = gen_lowpart (SImode, operands[0]);
5284 operands[1] = gen_lowpart (SImode, operands[1]);
5285 operands[2] = gen_reg_rtx (SImode);
5289 (define_insn "*arm_extendqihi_insn"
5290 [(set (match_operand:HI 0 "s_register_operand" "=r")
5291 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5292 "TARGET_ARM && arm_arch4"
5294 [(set_attr "type" "load_byte")
5295 (set_attr "predicable" "yes")]
5298 (define_expand "extendqisi2"
5299 [(set (match_operand:SI 0 "s_register_operand" "")
5300 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5303 if (!arm_arch4 && MEM_P (operands[1]))
5304 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5306 if (!arm_arch6 && !MEM_P (operands[1]))
5308 rtx t = gen_lowpart (SImode, operands[1]);
5309 rtx tmp = gen_reg_rtx (SImode);
5310 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5311 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5317 [(set (match_operand:SI 0 "register_operand" "")
5318 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5320 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5321 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5323 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5326 (define_insn "*arm_extendqisi"
5327 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5328 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5329 "TARGET_ARM && arm_arch4 && !arm_arch6"
5333 [(set_attr "length" "8,4")
5334 (set_attr "type" "alu_shift_reg,load_byte")
5335 (set_attr "predicable" "yes")]
5338 (define_insn "*arm_extendqisi_v6"
5339 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5341 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5342 "TARGET_ARM && arm_arch6"
5346 [(set_attr "type" "extend,load_byte")
5347 (set_attr "predicable" "yes")]
5350 (define_insn "*arm_extendqisi2addsi"
5351 [(set (match_operand:SI 0 "s_register_operand" "=r")
5352 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5353 (match_operand:SI 2 "s_register_operand" "r")))]
5355 "sxtab%?\\t%0, %2, %1"
5356 [(set_attr "type" "alu_shift_reg")
5357 (set_attr "predicable" "yes")
5358 (set_attr "predicable_short_it" "no")]
5361 (define_expand "extendsfdf2"
5362 [(set (match_operand:DF 0 "s_register_operand" "")
5363 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5364 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5368 /* HFmode -> DFmode conversions have to go through SFmode. */
5369 (define_expand "extendhfdf2"
5370 [(set (match_operand:DF 0 "general_operand" "")
5371 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5376 op1 = convert_to_mode (SFmode, operands[1], 0);
5377 op1 = convert_to_mode (DFmode, op1, 0);
5378 emit_insn (gen_movdf (operands[0], op1));
5383 ;; Move insns (including loads and stores)
5385 ;; XXX Just some ideas about movti.
5386 ;; I don't think these are a good idea on the arm, there just aren't enough
5388 ;;(define_expand "loadti"
5389 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5390 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5393 ;;(define_expand "storeti"
5394 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5395 ;; (match_operand:TI 1 "s_register_operand" ""))]
5398 ;;(define_expand "movti"
5399 ;; [(set (match_operand:TI 0 "general_operand" "")
5400 ;; (match_operand:TI 1 "general_operand" ""))]
5406 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5407 ;; operands[1] = copy_to_reg (operands[1]);
5408 ;; if (MEM_P (operands[0]))
5409 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5410 ;; else if (MEM_P (operands[1]))
5411 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5415 ;; emit_insn (insn);
5419 ;; Recognize garbage generated above.
5422 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5423 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5427 ;; register mem = (which_alternative < 3);
5428 ;; register const char *template;
5430 ;; operands[mem] = XEXP (operands[mem], 0);
5431 ;; switch (which_alternative)
5433 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5434 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5435 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5436 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5437 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5438 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5440 ;; output_asm_insn (template, operands);
5444 (define_expand "movdi"
5445 [(set (match_operand:DI 0 "general_operand" "")
5446 (match_operand:DI 1 "general_operand" ""))]
5449 if (can_create_pseudo_p ())
5451 if (!REG_P (operands[0]))
5452 operands[1] = force_reg (DImode, operands[1]);
5454 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5455 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5457 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5458 when expanding function calls. */
5459 gcc_assert (can_create_pseudo_p ());
5460 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5462 /* Perform load into legal reg pair first, then move. */
5463 rtx reg = gen_reg_rtx (DImode);
5464 emit_insn (gen_movdi (reg, operands[1]));
5467 emit_move_insn (gen_lowpart (SImode, operands[0]),
5468 gen_lowpart (SImode, operands[1]));
5469 emit_move_insn (gen_highpart (SImode, operands[0]),
5470 gen_highpart (SImode, operands[1]));
5473 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5474 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5476 /* Avoid STRD's from an odd-numbered register pair in ARM state
5477 when expanding function prologue. */
5478 gcc_assert (can_create_pseudo_p ());
5479 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5480 ? gen_reg_rtx (DImode)
5482 emit_move_insn (gen_lowpart (SImode, split_dest),
5483 gen_lowpart (SImode, operands[1]));
5484 emit_move_insn (gen_highpart (SImode, split_dest),
5485 gen_highpart (SImode, operands[1]));
5486 if (split_dest != operands[0])
5487 emit_insn (gen_movdi (operands[0], split_dest));
5493 (define_insn "*arm_movdi"
5494 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5495 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5497 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5499 && ( register_operand (operands[0], DImode)
5500 || register_operand (operands[1], DImode))"
5502 switch (which_alternative)
5509 return output_move_double (operands, true, NULL);
5512 [(set_attr "length" "8,12,16,8,8")
5513 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5514 (set_attr "arm_pool_range" "*,*,*,1020,*")
5515 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5516 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5517 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5521 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5522 (match_operand:ANY64 1 "immediate_operand" ""))]
5525 && (arm_const_double_inline_cost (operands[1])
5526 <= arm_max_const_double_inline_cost ())"
5529 arm_split_constant (SET, SImode, curr_insn,
5530 INTVAL (gen_lowpart (SImode, operands[1])),
5531 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5532 arm_split_constant (SET, SImode, curr_insn,
5533 INTVAL (gen_highpart_mode (SImode,
5534 GET_MODE (operands[0]),
5536 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5541 ; If optimizing for size, or if we have load delay slots, then
5542 ; we want to split the constant into two separate operations.
5543 ; In both cases this may split a trivial part into a single data op
5544 ; leaving a single complex constant to load. We can also get longer
5545 ; offsets in a LDR which means we get better chances of sharing the pool
5546 ; entries. Finally, we can normally do a better job of scheduling
5547 ; LDR instructions than we can with LDM.
5548 ; This pattern will only match if the one above did not.
5550 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5551 (match_operand:ANY64 1 "const_double_operand" ""))]
5552 "TARGET_ARM && reload_completed
5553 && arm_const_double_by_parts (operands[1])"
5554 [(set (match_dup 0) (match_dup 1))
5555 (set (match_dup 2) (match_dup 3))]
5557 operands[2] = gen_highpart (SImode, operands[0]);
5558 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5560 operands[0] = gen_lowpart (SImode, operands[0]);
5561 operands[1] = gen_lowpart (SImode, operands[1]);
5566 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5567 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5568 "TARGET_EITHER && reload_completed"
5569 [(set (match_dup 0) (match_dup 1))
5570 (set (match_dup 2) (match_dup 3))]
5572 operands[2] = gen_highpart (SImode, operands[0]);
5573 operands[3] = gen_highpart (SImode, operands[1]);
5574 operands[0] = gen_lowpart (SImode, operands[0]);
5575 operands[1] = gen_lowpart (SImode, operands[1]);
5577 /* Handle a partial overlap. */
5578 if (rtx_equal_p (operands[0], operands[3]))
5580 rtx tmp0 = operands[0];
5581 rtx tmp1 = operands[1];
5583 operands[0] = operands[2];
5584 operands[1] = operands[3];
5591 ;; We can't actually do base+index doubleword loads if the index and
5592 ;; destination overlap. Split here so that we at least have chance to
5595 [(set (match_operand:DI 0 "s_register_operand" "")
5596 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5597 (match_operand:SI 2 "s_register_operand" ""))))]
5599 && reg_overlap_mentioned_p (operands[0], operands[1])
5600 && reg_overlap_mentioned_p (operands[0], operands[2])"
5602 (plus:SI (match_dup 1)
5605 (mem:DI (match_dup 4)))]
5607 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5611 (define_expand "movsi"
5612 [(set (match_operand:SI 0 "general_operand" "")
5613 (match_operand:SI 1 "general_operand" ""))]
5617 rtx base, offset, tmp;
5621 /* Everything except mem = const or mem = mem can be done easily. */
5622 if (MEM_P (operands[0]))
5623 operands[1] = force_reg (SImode, operands[1]);
5624 if (arm_general_register_operand (operands[0], SImode)
5625 && CONST_INT_P (operands[1])
5626 && !(const_ok_for_arm (INTVAL (operands[1]))
5627 || const_ok_for_arm (~INTVAL (operands[1]))))
5629 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5631 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5636 arm_split_constant (SET, SImode, NULL_RTX,
5637 INTVAL (operands[1]), operands[0], NULL_RTX,
5638 optimize && can_create_pseudo_p ());
5643 else /* TARGET_THUMB1... */
5645 if (can_create_pseudo_p ())
5647 if (!REG_P (operands[0]))
5648 operands[1] = force_reg (SImode, operands[1]);
5652 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5654 split_const (operands[1], &base, &offset);
5655 if (GET_CODE (base) == SYMBOL_REF
5656 && !offset_within_block_p (base, INTVAL (offset)))
5658 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5659 emit_move_insn (tmp, base);
5660 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5665 /* Recognize the case where operand[1] is a reference to thread-local
5666 data and load its address to a register. */
5667 if (arm_tls_referenced_p (operands[1]))
5669 rtx tmp = operands[1];
5672 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5674 addend = XEXP (XEXP (tmp, 0), 1);
5675 tmp = XEXP (XEXP (tmp, 0), 0);
5678 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5679 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5681 tmp = legitimize_tls_address (tmp,
5682 !can_create_pseudo_p () ? operands[0] : 0);
5685 tmp = gen_rtx_PLUS (SImode, tmp, addend);
5686 tmp = force_operand (tmp, operands[0]);
5691 && (CONSTANT_P (operands[1])
5692 || symbol_mentioned_p (operands[1])
5693 || label_mentioned_p (operands[1])))
5694 operands[1] = legitimize_pic_address (operands[1], SImode,
5695 (!can_create_pseudo_p ()
5702 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5703 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5704 ;; so this does not matter.
5705 (define_insn "*arm_movt"
5706 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
5707 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5708 (match_operand:SI 2 "general_operand" "i,i")))]
5709 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
5711 movt%?\t%0, #:upper16:%c2
5712 movt\t%0, #:upper16:%c2"
5713 [(set_attr "arch" "32,v8mb")
5714 (set_attr "predicable" "yes")
5715 (set_attr "predicable_short_it" "no")
5716 (set_attr "length" "4")
5717 (set_attr "type" "alu_sreg")]
5720 (define_insn "*arm_movsi_insn"
5721 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5722 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
5723 "TARGET_ARM && ! TARGET_IWMMXT
5724 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5725 && ( register_operand (operands[0], SImode)
5726 || register_operand (operands[1], SImode))"
5734 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
5735 (set_attr "predicable" "yes")
5736 (set_attr "pool_range" "*,*,*,*,4096,*")
5737 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5741 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5742 (match_operand:SI 1 "const_int_operand" ""))]
5744 && (!(const_ok_for_arm (INTVAL (operands[1]))
5745 || const_ok_for_arm (~INTVAL (operands[1]))))"
5746 [(clobber (const_int 0))]
5748 arm_split_constant (SET, SImode, NULL_RTX,
5749 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5754 ;; A normal way to do (symbol + offset) requires three instructions at least
5755 ;; (depends on how big the offset is) as below:
5756 ;; movw r0, #:lower16:g
5757 ;; movw r0, #:upper16:g
5760 ;; A better way would be:
5761 ;; movw r0, #:lower16:g+4
5762 ;; movw r0, #:upper16:g+4
5764 ;; The limitation of this way is that the length of offset should be a 16-bit
5765 ;; signed value, because current assembler only supports REL type relocation for
5766 ;; such case. If the more powerful RELA type is supported in future, we should
5767 ;; update this pattern to go with better way.
5769 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5770 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5771 (match_operand:SI 2 "const_int_operand" ""))))]
5774 && arm_disable_literal_pool
5776 && GET_CODE (operands[1]) == SYMBOL_REF"
5777 [(clobber (const_int 0))]
5779 int offset = INTVAL (operands[2]);
5781 if (offset < -0x8000 || offset > 0x7fff)
5783 arm_emit_movpair (operands[0], operands[1]);
5784 emit_insn (gen_rtx_SET (operands[0],
5785 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5789 rtx op = gen_rtx_CONST (SImode,
5790 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5791 arm_emit_movpair (operands[0], op);
5796 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5797 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5798 ;; and lo_sum would be merged back into memory load at cprop. However,
5799 ;; if the default is to prefer movt/movw rather than a load from the constant
5800 ;; pool, the performance is better.
5802 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5803 (match_operand:SI 1 "general_operand" ""))]
5804 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5805 && !flag_pic && !target_word_relocations
5806 && !arm_tls_referenced_p (operands[1])"
5807 [(clobber (const_int 0))]
5809 arm_emit_movpair (operands[0], operands[1]);
5813 ;; When generating pic, we need to load the symbol offset into a register.
5814 ;; So that the optimizer does not confuse this with a normal symbol load
5815 ;; we use an unspec. The offset will be loaded from a constant pool entry,
5816 ;; since that is the only type of relocation we can use.
5818 ;; Wrap calculation of the whole PIC address in a single pattern for the
5819 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5820 ;; a PIC address involves two loads from memory, so we want to CSE it
5821 ;; as often as possible.
5822 ;; This pattern will be split into one of the pic_load_addr_* patterns
5823 ;; and a move after GCSE optimizations.
5825 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5826 (define_expand "calculate_pic_address"
5827 [(set (match_operand:SI 0 "register_operand" "")
5828 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5829 (unspec:SI [(match_operand:SI 2 "" "")]
5834 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5836 [(set (match_operand:SI 0 "register_operand" "")
5837 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5838 (unspec:SI [(match_operand:SI 2 "" "")]
5841 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5842 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5843 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5846 ;; operand1 is the memory address to go into
5847 ;; pic_load_addr_32bit.
5848 ;; operand2 is the PIC label to be emitted
5849 ;; from pic_add_dot_plus_eight.
5850 ;; We do this to allow hoisting of the entire insn.
5851 (define_insn_and_split "pic_load_addr_unified"
5852 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5853 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5854 (match_operand:SI 2 "" "")]
5855 UNSPEC_PIC_UNIFIED))]
5858 "&& reload_completed"
5859 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5860 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5861 (match_dup 2)] UNSPEC_PIC_BASE))]
5862 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5863 [(set_attr "type" "load1,load1,load1")
5864 (set_attr "pool_range" "4096,4094,1022")
5865 (set_attr "neg_pool_range" "4084,0,0")
5866 (set_attr "arch" "a,t2,t1")
5867 (set_attr "length" "8,6,4")]
5870 ;; The rather odd constraints on the following are to force reload to leave
5871 ;; the insn alone, and to force the minipool generation pass to then move
5872 ;; the GOT symbol to memory.
5874 (define_insn "pic_load_addr_32bit"
5875 [(set (match_operand:SI 0 "s_register_operand" "=r")
5876 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5877 "TARGET_32BIT && flag_pic"
5879 [(set_attr "type" "load1")
5880 (set (attr "pool_range")
5881 (if_then_else (eq_attr "is_thumb" "no")
5884 (set (attr "neg_pool_range")
5885 (if_then_else (eq_attr "is_thumb" "no")
5890 (define_insn "pic_load_addr_thumb1"
5891 [(set (match_operand:SI 0 "s_register_operand" "=l")
5892 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5893 "TARGET_THUMB1 && flag_pic"
5895 [(set_attr "type" "load1")
5896 (set (attr "pool_range") (const_int 1018))]
5899 (define_insn "pic_add_dot_plus_four"
5900 [(set (match_operand:SI 0 "register_operand" "=r")
5901 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5903 (match_operand 2 "" "")]
5907 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5908 INTVAL (operands[2]));
5909 return \"add\\t%0, %|pc\";
5911 [(set_attr "length" "2")
5912 (set_attr "type" "alu_sreg")]
5915 (define_insn "pic_add_dot_plus_eight"
5916 [(set (match_operand:SI 0 "register_operand" "=r")
5917 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5919 (match_operand 2 "" "")]
5923 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5924 INTVAL (operands[2]));
5925 return \"add%?\\t%0, %|pc, %1\";
5927 [(set_attr "predicable" "yes")
5928 (set_attr "type" "alu_sreg")]
5931 (define_insn "tls_load_dot_plus_eight"
5932 [(set (match_operand:SI 0 "register_operand" "=r")
5933 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5935 (match_operand 2 "" "")]
5939 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5940 INTVAL (operands[2]));
5941 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5943 [(set_attr "predicable" "yes")
5944 (set_attr "type" "load1")]
5947 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5948 ;; followed by a load. These sequences can be crunched down to
5949 ;; tls_load_dot_plus_eight by a peephole.
5952 [(set (match_operand:SI 0 "register_operand" "")
5953 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5955 (match_operand 1 "" "")]
5957 (set (match_operand:SI 2 "arm_general_register_operand" "")
5958 (mem:SI (match_dup 0)))]
5959 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5961 (mem:SI (unspec:SI [(match_dup 3)
5968 (define_insn "pic_offset_arm"
5969 [(set (match_operand:SI 0 "register_operand" "=r")
5970 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5971 (unspec:SI [(match_operand:SI 2 "" "X")]
5972 UNSPEC_PIC_OFFSET))))]
5973 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5974 "ldr%?\\t%0, [%1,%2]"
5975 [(set_attr "type" "load1")]
5978 (define_expand "builtin_setjmp_receiver"
5979 [(label_ref (match_operand 0 "" ""))]
5983 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5985 if (arm_pic_register != INVALID_REGNUM)
5986 arm_load_pic_register (1UL << 3);
5990 ;; If copying one reg to another we can set the condition codes according to
5991 ;; its value. Such a move is common after a return from subroutine and the
5992 ;; result is being tested against zero.
5994 (define_insn "*movsi_compare0"
5995 [(set (reg:CC CC_REGNUM)
5996 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5998 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6003 subs%?\\t%0, %1, #0"
6004 [(set_attr "conds" "set")
6005 (set_attr "type" "alus_imm,alus_imm")]
6008 ;; Subroutine to store a half word from a register into memory.
6009 ;; Operand 0 is the source register (HImode)
6010 ;; Operand 1 is the destination address in a register (SImode)
6012 ;; In both this routine and the next, we must be careful not to spill
6013 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6014 ;; can generate unrecognizable rtl.
6016 (define_expand "storehi"
6017 [;; store the low byte
6018 (set (match_operand 1 "" "") (match_dup 3))
6019 ;; extract the high byte
6021 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6022 ;; store the high byte
6023 (set (match_dup 4) (match_dup 5))]
6027 rtx op1 = operands[1];
6028 rtx addr = XEXP (op1, 0);
6029 enum rtx_code code = GET_CODE (addr);
6031 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6033 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6035 operands[4] = adjust_address (op1, QImode, 1);
6036 operands[1] = adjust_address (operands[1], QImode, 0);
6037 operands[3] = gen_lowpart (QImode, operands[0]);
6038 operands[0] = gen_lowpart (SImode, operands[0]);
6039 operands[2] = gen_reg_rtx (SImode);
6040 operands[5] = gen_lowpart (QImode, operands[2]);
6044 (define_expand "storehi_bigend"
6045 [(set (match_dup 4) (match_dup 3))
6047 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6048 (set (match_operand 1 "" "") (match_dup 5))]
6052 rtx op1 = operands[1];
6053 rtx addr = XEXP (op1, 0);
6054 enum rtx_code code = GET_CODE (addr);
6056 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6058 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6060 operands[4] = adjust_address (op1, QImode, 1);
6061 operands[1] = adjust_address (operands[1], QImode, 0);
6062 operands[3] = gen_lowpart (QImode, operands[0]);
6063 operands[0] = gen_lowpart (SImode, operands[0]);
6064 operands[2] = gen_reg_rtx (SImode);
6065 operands[5] = gen_lowpart (QImode, operands[2]);
6069 ;; Subroutine to store a half word integer constant into memory.
6070 (define_expand "storeinthi"
6071 [(set (match_operand 0 "" "")
6072 (match_operand 1 "" ""))
6073 (set (match_dup 3) (match_dup 2))]
6077 HOST_WIDE_INT value = INTVAL (operands[1]);
6078 rtx addr = XEXP (operands[0], 0);
6079 rtx op0 = operands[0];
6080 enum rtx_code code = GET_CODE (addr);
6082 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6084 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6086 operands[1] = gen_reg_rtx (SImode);
6087 if (BYTES_BIG_ENDIAN)
6089 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6090 if ((value & 255) == ((value >> 8) & 255))
6091 operands[2] = operands[1];
6094 operands[2] = gen_reg_rtx (SImode);
6095 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6100 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6101 if ((value & 255) == ((value >> 8) & 255))
6102 operands[2] = operands[1];
6105 operands[2] = gen_reg_rtx (SImode);
6106 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6110 operands[3] = adjust_address (op0, QImode, 1);
6111 operands[0] = adjust_address (operands[0], QImode, 0);
6112 operands[2] = gen_lowpart (QImode, operands[2]);
6113 operands[1] = gen_lowpart (QImode, operands[1]);
6117 (define_expand "storehi_single_op"
6118 [(set (match_operand:HI 0 "memory_operand" "")
6119 (match_operand:HI 1 "general_operand" ""))]
6120 "TARGET_32BIT && arm_arch4"
6122 if (!s_register_operand (operands[1], HImode))
6123 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6127 (define_expand "movhi"
6128 [(set (match_operand:HI 0 "general_operand" "")
6129 (match_operand:HI 1 "general_operand" ""))]
6134 if (can_create_pseudo_p ())
6136 if (MEM_P (operands[0]))
6140 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6143 if (CONST_INT_P (operands[1]))
6144 emit_insn (gen_storeinthi (operands[0], operands[1]));
6147 if (MEM_P (operands[1]))
6148 operands[1] = force_reg (HImode, operands[1]);
6149 if (BYTES_BIG_ENDIAN)
6150 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6152 emit_insn (gen_storehi (operands[1], operands[0]));
6156 /* Sign extend a constant, and keep it in an SImode reg. */
6157 else if (CONST_INT_P (operands[1]))
6159 rtx reg = gen_reg_rtx (SImode);
6160 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6162 /* If the constant is already valid, leave it alone. */
6163 if (!const_ok_for_arm (val))
6165 /* If setting all the top bits will make the constant
6166 loadable in a single instruction, then set them.
6167 Otherwise, sign extend the number. */
6169 if (const_ok_for_arm (~(val | ~0xffff)))
6171 else if (val & 0x8000)
6175 emit_insn (gen_movsi (reg, GEN_INT (val)));
6176 operands[1] = gen_lowpart (HImode, reg);
6178 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6179 && MEM_P (operands[1]))
6181 rtx reg = gen_reg_rtx (SImode);
6183 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6184 operands[1] = gen_lowpart (HImode, reg);
6186 else if (!arm_arch4)
6188 if (MEM_P (operands[1]))
6191 rtx offset = const0_rtx;
6192 rtx reg = gen_reg_rtx (SImode);
6194 if ((REG_P (base = XEXP (operands[1], 0))
6195 || (GET_CODE (base) == PLUS
6196 && (CONST_INT_P (offset = XEXP (base, 1)))
6197 && ((INTVAL(offset) & 1) != 1)
6198 && REG_P (base = XEXP (base, 0))))
6199 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6203 new_rtx = widen_memory_access (operands[1], SImode,
6204 ((INTVAL (offset) & ~3)
6205 - INTVAL (offset)));
6206 emit_insn (gen_movsi (reg, new_rtx));
6207 if (((INTVAL (offset) & 2) != 0)
6208 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6210 rtx reg2 = gen_reg_rtx (SImode);
6212 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6217 emit_insn (gen_movhi_bytes (reg, operands[1]));
6219 operands[1] = gen_lowpart (HImode, reg);
6223 /* Handle loading a large integer during reload. */
6224 else if (CONST_INT_P (operands[1])
6225 && !const_ok_for_arm (INTVAL (operands[1]))
6226 && !const_ok_for_arm (~INTVAL (operands[1])))
6228 /* Writing a constant to memory needs a scratch, which should
6229 be handled with SECONDARY_RELOADs. */
6230 gcc_assert (REG_P (operands[0]));
6232 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6233 emit_insn (gen_movsi (operands[0], operands[1]));
6237 else if (TARGET_THUMB2)
6239 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6240 if (can_create_pseudo_p ())
6242 if (!REG_P (operands[0]))
6243 operands[1] = force_reg (HImode, operands[1]);
6244 /* Zero extend a constant, and keep it in an SImode reg. */
6245 else if (CONST_INT_P (operands[1]))
6247 rtx reg = gen_reg_rtx (SImode);
6248 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6250 emit_insn (gen_movsi (reg, GEN_INT (val)));
6251 operands[1] = gen_lowpart (HImode, reg);
6255 else /* TARGET_THUMB1 */
6257 if (can_create_pseudo_p ())
6259 if (CONST_INT_P (operands[1]))
6261 rtx reg = gen_reg_rtx (SImode);
6263 emit_insn (gen_movsi (reg, operands[1]));
6264 operands[1] = gen_lowpart (HImode, reg);
6267 /* ??? We shouldn't really get invalid addresses here, but this can
6268 happen if we are passed a SP (never OK for HImode/QImode) or
6269 virtual register (also rejected as illegitimate for HImode/QImode)
6270 relative address. */
6271 /* ??? This should perhaps be fixed elsewhere, for instance, in
6272 fixup_stack_1, by checking for other kinds of invalid addresses,
6273 e.g. a bare reference to a virtual register. This may confuse the
6274 alpha though, which must handle this case differently. */
6275 if (MEM_P (operands[0])
6276 && !memory_address_p (GET_MODE (operands[0]),
6277 XEXP (operands[0], 0)))
6279 = replace_equiv_address (operands[0],
6280 copy_to_reg (XEXP (operands[0], 0)));
6282 if (MEM_P (operands[1])
6283 && !memory_address_p (GET_MODE (operands[1]),
6284 XEXP (operands[1], 0)))
6286 = replace_equiv_address (operands[1],
6287 copy_to_reg (XEXP (operands[1], 0)));
6289 if (MEM_P (operands[1]) && optimize > 0)
6291 rtx reg = gen_reg_rtx (SImode);
6293 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6294 operands[1] = gen_lowpart (HImode, reg);
6297 if (MEM_P (operands[0]))
6298 operands[1] = force_reg (HImode, operands[1]);
6300 else if (CONST_INT_P (operands[1])
6301 && !satisfies_constraint_I (operands[1]))
6303 /* Handle loading a large integer during reload. */
6305 /* Writing a constant to memory needs a scratch, which should
6306 be handled with SECONDARY_RELOADs. */
6307 gcc_assert (REG_P (operands[0]));
6309 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6310 emit_insn (gen_movsi (operands[0], operands[1]));
6317 (define_expand "movhi_bytes"
6318 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6320 (zero_extend:SI (match_dup 6)))
6321 (set (match_operand:SI 0 "" "")
6322 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6327 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6329 mem1 = change_address (operands[1], QImode, addr);
6330 mem2 = change_address (operands[1], QImode,
6331 plus_constant (Pmode, addr, 1));
6332 operands[0] = gen_lowpart (SImode, operands[0]);
6334 operands[2] = gen_reg_rtx (SImode);
6335 operands[3] = gen_reg_rtx (SImode);
6338 if (BYTES_BIG_ENDIAN)
6340 operands[4] = operands[2];
6341 operands[5] = operands[3];
6345 operands[4] = operands[3];
6346 operands[5] = operands[2];
6351 (define_expand "movhi_bigend"
6353 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6356 (ashiftrt:SI (match_dup 2) (const_int 16)))
6357 (set (match_operand:HI 0 "s_register_operand" "")
6361 operands[2] = gen_reg_rtx (SImode);
6362 operands[3] = gen_reg_rtx (SImode);
6363 operands[4] = gen_lowpart (HImode, operands[3]);
6367 ;; Pattern to recognize insn generated default case above
6368 (define_insn "*movhi_insn_arch4"
6369 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6370 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6373 && (register_operand (operands[0], HImode)
6374 || register_operand (operands[1], HImode))"
6376 mov%?\\t%0, %1\\t%@ movhi
6377 mvn%?\\t%0, #%B1\\t%@ movhi
6378 movw%?\\t%0, %L1\\t%@ movhi
6379 strh%?\\t%1, %0\\t%@ movhi
6380 ldrh%?\\t%0, %1\\t%@ movhi"
6381 [(set_attr "predicable" "yes")
6382 (set_attr "pool_range" "*,*,*,*,256")
6383 (set_attr "neg_pool_range" "*,*,*,*,244")
6384 (set_attr "arch" "*,*,v6t2,*,*")
6385 (set_attr_alternative "type"
6386 [(if_then_else (match_operand 1 "const_int_operand" "")
6387 (const_string "mov_imm" )
6388 (const_string "mov_reg"))
6389 (const_string "mvn_imm")
6390 (const_string "mov_imm")
6391 (const_string "store1")
6392 (const_string "load1")])]
6395 (define_insn "*movhi_bytes"
6396 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6397 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6400 mov%?\\t%0, %1\\t%@ movhi
6401 mov%?\\t%0, %1\\t%@ movhi
6402 mvn%?\\t%0, #%B1\\t%@ movhi"
6403 [(set_attr "predicable" "yes")
6404 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6407 ;; We use a DImode scratch because we may occasionally need an additional
6408 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6409 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6410 (define_expand "reload_outhi"
6411 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6412 (match_operand:HI 1 "s_register_operand" "r")
6413 (match_operand:DI 2 "s_register_operand" "=&l")])]
6416 arm_reload_out_hi (operands);
6418 thumb_reload_out_hi (operands);
6423 (define_expand "reload_inhi"
6424 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6425 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6426 (match_operand:DI 2 "s_register_operand" "=&r")])]
6430 arm_reload_in_hi (operands);
6432 thumb_reload_out_hi (operands);
6436 (define_expand "movqi"
6437 [(set (match_operand:QI 0 "general_operand" "")
6438 (match_operand:QI 1 "general_operand" ""))]
6441 /* Everything except mem = const or mem = mem can be done easily */
6443 if (can_create_pseudo_p ())
6445 if (CONST_INT_P (operands[1]))
6447 rtx reg = gen_reg_rtx (SImode);
6449 /* For thumb we want an unsigned immediate, then we are more likely
6450 to be able to use a movs insn. */
6452 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6454 emit_insn (gen_movsi (reg, operands[1]));
6455 operands[1] = gen_lowpart (QImode, reg);
6460 /* ??? We shouldn't really get invalid addresses here, but this can
6461 happen if we are passed a SP (never OK for HImode/QImode) or
6462 virtual register (also rejected as illegitimate for HImode/QImode)
6463 relative address. */
6464 /* ??? This should perhaps be fixed elsewhere, for instance, in
6465 fixup_stack_1, by checking for other kinds of invalid addresses,
6466 e.g. a bare reference to a virtual register. This may confuse the
6467 alpha though, which must handle this case differently. */
6468 if (MEM_P (operands[0])
6469 && !memory_address_p (GET_MODE (operands[0]),
6470 XEXP (operands[0], 0)))
6472 = replace_equiv_address (operands[0],
6473 copy_to_reg (XEXP (operands[0], 0)));
6474 if (MEM_P (operands[1])
6475 && !memory_address_p (GET_MODE (operands[1]),
6476 XEXP (operands[1], 0)))
6478 = replace_equiv_address (operands[1],
6479 copy_to_reg (XEXP (operands[1], 0)));
6482 if (MEM_P (operands[1]) && optimize > 0)
6484 rtx reg = gen_reg_rtx (SImode);
6486 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6487 operands[1] = gen_lowpart (QImode, reg);
6490 if (MEM_P (operands[0]))
6491 operands[1] = force_reg (QImode, operands[1]);
6493 else if (TARGET_THUMB
6494 && CONST_INT_P (operands[1])
6495 && !satisfies_constraint_I (operands[1]))
6497 /* Handle loading a large integer during reload. */
6499 /* Writing a constant to memory needs a scratch, which should
6500 be handled with SECONDARY_RELOADs. */
6501 gcc_assert (REG_P (operands[0]));
6503 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6504 emit_insn (gen_movsi (operands[0], operands[1]));
6510 (define_insn "*arm_movqi_insn"
6511 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6512 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6514 && ( register_operand (operands[0], QImode)
6515 || register_operand (operands[1], QImode))"
6526 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6527 (set_attr "predicable" "yes")
6528 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6529 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6530 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6534 (define_expand "movhf"
6535 [(set (match_operand:HF 0 "general_operand" "")
6536 (match_operand:HF 1 "general_operand" ""))]
6541 if (MEM_P (operands[0]))
6542 operands[1] = force_reg (HFmode, operands[1]);
6544 else /* TARGET_THUMB1 */
6546 if (can_create_pseudo_p ())
6548 if (!REG_P (operands[0]))
6549 operands[1] = force_reg (HFmode, operands[1]);
6555 (define_insn "*arm32_movhf"
6556 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6557 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6558 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_VFP)
6559 && ( s_register_operand (operands[0], HFmode)
6560 || s_register_operand (operands[1], HFmode))"
6562 switch (which_alternative)
6564 case 0: /* ARM register from memory */
6565 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6566 case 1: /* memory from ARM register */
6567 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6568 case 2: /* ARM register from ARM register */
6569 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6570 case 3: /* ARM register from constant */
6575 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6577 ops[0] = operands[0];
6578 ops[1] = GEN_INT (bits);
6579 ops[2] = GEN_INT (bits & 0xff00);
6580 ops[3] = GEN_INT (bits & 0x00ff);
6582 if (arm_arch_thumb2)
6583 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6585 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6592 [(set_attr "conds" "unconditional")
6593 (set_attr "type" "load1,store1,mov_reg,multiple")
6594 (set_attr "length" "4,4,4,8")
6595 (set_attr "predicable" "yes")
6596 (set_attr "predicable_short_it" "no")]
6599 (define_expand "movsf"
6600 [(set (match_operand:SF 0 "general_operand" "")
6601 (match_operand:SF 1 "general_operand" ""))]
6606 if (MEM_P (operands[0]))
6607 operands[1] = force_reg (SFmode, operands[1]);
6609 else /* TARGET_THUMB1 */
6611 if (can_create_pseudo_p ())
6613 if (!REG_P (operands[0]))
6614 operands[1] = force_reg (SFmode, operands[1]);
6620 ;; Transform a floating-point move of a constant into a core register into
6621 ;; an SImode operation.
6623 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6624 (match_operand:SF 1 "immediate_operand" ""))]
6627 && CONST_DOUBLE_P (operands[1])"
6628 [(set (match_dup 2) (match_dup 3))]
6630 operands[2] = gen_lowpart (SImode, operands[0]);
6631 operands[3] = gen_lowpart (SImode, operands[1]);
6632 if (operands[2] == 0 || operands[3] == 0)
6637 (define_insn "*arm_movsf_soft_insn"
6638 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6639 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6641 && TARGET_SOFT_FLOAT
6642 && (!MEM_P (operands[0])
6643 || register_operand (operands[1], SFmode))"
6646 ldr%?\\t%0, %1\\t%@ float
6647 str%?\\t%1, %0\\t%@ float"
6648 [(set_attr "predicable" "yes")
6649 (set_attr "predicable_short_it" "no")
6650 (set_attr "type" "mov_reg,load1,store1")
6651 (set_attr "arm_pool_range" "*,4096,*")
6652 (set_attr "thumb2_pool_range" "*,4094,*")
6653 (set_attr "arm_neg_pool_range" "*,4084,*")
6654 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6657 (define_expand "movdf"
6658 [(set (match_operand:DF 0 "general_operand" "")
6659 (match_operand:DF 1 "general_operand" ""))]
6664 if (MEM_P (operands[0]))
6665 operands[1] = force_reg (DFmode, operands[1]);
6667 else /* TARGET_THUMB */
6669 if (can_create_pseudo_p ())
6671 if (!REG_P (operands[0]))
6672 operands[1] = force_reg (DFmode, operands[1]);
6678 ;; Reloading a df mode value stored in integer regs to memory can require a
6680 (define_expand "reload_outdf"
6681 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6682 (match_operand:DF 1 "s_register_operand" "r")
6683 (match_operand:SI 2 "s_register_operand" "=&r")]
6687 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6690 operands[2] = XEXP (operands[0], 0);
6691 else if (code == POST_INC || code == PRE_DEC)
6693 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6694 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6695 emit_insn (gen_movdi (operands[0], operands[1]));
6698 else if (code == PRE_INC)
6700 rtx reg = XEXP (XEXP (operands[0], 0), 0);
6702 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6705 else if (code == POST_DEC)
6706 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6708 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6709 XEXP (XEXP (operands[0], 0), 1)));
6711 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
6714 if (code == POST_DEC)
6715 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6721 (define_insn "*movdf_soft_insn"
6722 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6723 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
6724 "TARGET_32BIT && TARGET_SOFT_FLOAT
6725 && ( register_operand (operands[0], DFmode)
6726 || register_operand (operands[1], DFmode))"
6728 switch (which_alternative)
6735 return output_move_double (operands, true, NULL);
6738 [(set_attr "length" "8,12,16,8,8")
6739 (set_attr "type" "multiple,multiple,multiple,load2,store2")
6740 (set_attr "arm_pool_range" "*,*,*,1020,*")
6741 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6742 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6743 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6747 ;; load- and store-multiple insns
6748 ;; The arm can load/store any set of registers, provided that they are in
6749 ;; ascending order, but these expanders assume a contiguous set.
6751 (define_expand "load_multiple"
6752 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6753 (match_operand:SI 1 "" ""))
6754 (use (match_operand:SI 2 "" ""))])]
6757 HOST_WIDE_INT offset = 0;
6759 /* Support only fixed point registers. */
6760 if (!CONST_INT_P (operands[2])
6761 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6762 || INTVAL (operands[2]) < 2
6763 || !MEM_P (operands[1])
6764 || !REG_P (operands[0])
6765 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6766 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6770 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6771 INTVAL (operands[2]),
6772 force_reg (SImode, XEXP (operands[1], 0)),
6773 FALSE, operands[1], &offset);
6776 (define_expand "store_multiple"
6777 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6778 (match_operand:SI 1 "" ""))
6779 (use (match_operand:SI 2 "" ""))])]
6782 HOST_WIDE_INT offset = 0;
6784 /* Support only fixed point registers. */
6785 if (!CONST_INT_P (operands[2])
6786 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6787 || INTVAL (operands[2]) < 2
6788 || !REG_P (operands[1])
6789 || !MEM_P (operands[0])
6790 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6791 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6795 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6796 INTVAL (operands[2]),
6797 force_reg (SImode, XEXP (operands[0], 0)),
6798 FALSE, operands[0], &offset);
6802 (define_expand "setmemsi"
6803 [(match_operand:BLK 0 "general_operand" "")
6804 (match_operand:SI 1 "const_int_operand" "")
6805 (match_operand:SI 2 "const_int_operand" "")
6806 (match_operand:SI 3 "const_int_operand" "")]
6809 if (arm_gen_setmem (operands))
6816 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6817 ;; We could let this apply for blocks of less than this, but it clobbers so
6818 ;; many registers that there is then probably a better way.
6820 (define_expand "movmemqi"
6821 [(match_operand:BLK 0 "general_operand" "")
6822 (match_operand:BLK 1 "general_operand" "")
6823 (match_operand:SI 2 "const_int_operand" "")
6824 (match_operand:SI 3 "const_int_operand" "")]
6829 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6830 && !optimize_function_for_size_p (cfun))
6832 if (gen_movmem_ldrd_strd (operands))
6837 if (arm_gen_movmemqi (operands))
6841 else /* TARGET_THUMB1 */
6843 if ( INTVAL (operands[3]) != 4
6844 || INTVAL (operands[2]) > 48)
6847 thumb_expand_movmemqi (operands);
6854 ;; Compare & branch insns
6855 ;; The range calculations are based as follows:
6856 ;; For forward branches, the address calculation returns the address of
6857 ;; the next instruction. This is 2 beyond the branch instruction.
6858 ;; For backward branches, the address calculation returns the address of
6859 ;; the first instruction in this pattern (cmp). This is 2 before the branch
6860 ;; instruction for the shortest sequence, and 4 before the branch instruction
6861 ;; if we have to jump around an unconditional branch.
6862 ;; To the basic branch range the PC offset must be added (this is +4).
6863 ;; So for forward branches we have
6864 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6865 ;; And for backward branches we have
6866 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6868 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6869 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
6871 (define_expand "cbranchsi4"
6872 [(set (pc) (if_then_else
6873 (match_operator 0 "expandable_comparison_operator"
6874 [(match_operand:SI 1 "s_register_operand" "")
6875 (match_operand:SI 2 "nonmemory_operand" "")])
6876 (label_ref (match_operand 3 "" ""))
6882 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6884 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6888 if (thumb1_cmpneg_operand (operands[2], SImode))
6890 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6891 operands[3], operands[0]));
6894 if (!thumb1_cmp_operand (operands[2], SImode))
6895 operands[2] = force_reg (SImode, operands[2]);
6898 (define_expand "cbranchsf4"
6899 [(set (pc) (if_then_else
6900 (match_operator 0 "expandable_comparison_operator"
6901 [(match_operand:SF 1 "s_register_operand" "")
6902 (match_operand:SF 2 "arm_float_compare_operand" "")])
6903 (label_ref (match_operand 3 "" ""))
6905 "TARGET_32BIT && TARGET_HARD_FLOAT"
6906 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6907 operands[3])); DONE;"
6910 (define_expand "cbranchdf4"
6911 [(set (pc) (if_then_else
6912 (match_operator 0 "expandable_comparison_operator"
6913 [(match_operand:DF 1 "s_register_operand" "")
6914 (match_operand:DF 2 "arm_float_compare_operand" "")])
6915 (label_ref (match_operand 3 "" ""))
6917 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6918 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6919 operands[3])); DONE;"
6922 (define_expand "cbranchdi4"
6923 [(set (pc) (if_then_else
6924 (match_operator 0 "expandable_comparison_operator"
6925 [(match_operand:DI 1 "s_register_operand" "")
6926 (match_operand:DI 2 "cmpdi_operand" "")])
6927 (label_ref (match_operand 3 "" ""))
6931 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6933 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6939 ;; Comparison and test insns
6941 (define_insn "*arm_cmpsi_insn"
6942 [(set (reg:CC CC_REGNUM)
6943 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6944 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
6952 [(set_attr "conds" "set")
6953 (set_attr "arch" "t2,t2,any,any,any")
6954 (set_attr "length" "2,2,4,4,4")
6955 (set_attr "predicable" "yes")
6956 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6957 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6960 (define_insn "*cmpsi_shiftsi"
6961 [(set (reg:CC CC_REGNUM)
6962 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
6963 (match_operator:SI 3 "shift_operator"
6964 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6965 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6968 [(set_attr "conds" "set")
6969 (set_attr "shift" "1")
6970 (set_attr "arch" "32,a,a")
6971 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6973 (define_insn "*cmpsi_shiftsi_swp"
6974 [(set (reg:CC_SWP CC_REGNUM)
6975 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6976 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6977 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6978 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6981 [(set_attr "conds" "set")
6982 (set_attr "shift" "1")
6983 (set_attr "arch" "32,a,a")
6984 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6986 (define_insn "*arm_cmpsi_negshiftsi_si"
6987 [(set (reg:CC_Z CC_REGNUM)
6989 (neg:SI (match_operator:SI 1 "shift_operator"
6990 [(match_operand:SI 2 "s_register_operand" "r")
6991 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6992 (match_operand:SI 0 "s_register_operand" "r")))]
6995 [(set_attr "conds" "set")
6996 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6997 (const_string "alus_shift_imm")
6998 (const_string "alus_shift_reg")))
6999 (set_attr "predicable" "yes")]
7002 ;; DImode comparisons. The generic code generates branches that
7003 ;; if-conversion can not reduce to a conditional compare, so we do
7006 (define_insn_and_split "*arm_cmpdi_insn"
7007 [(set (reg:CC_NCV CC_REGNUM)
7008 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7009 (match_operand:DI 1 "arm_di_operand" "rDi")))
7010 (clobber (match_scratch:SI 2 "=r"))]
7012 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7013 "&& reload_completed"
7014 [(set (reg:CC CC_REGNUM)
7015 (compare:CC (match_dup 0) (match_dup 1)))
7016 (parallel [(set (reg:CC CC_REGNUM)
7017 (compare:CC (match_dup 3) (match_dup 4)))
7019 (minus:SI (match_dup 5)
7020 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7022 operands[3] = gen_highpart (SImode, operands[0]);
7023 operands[0] = gen_lowpart (SImode, operands[0]);
7024 if (CONST_INT_P (operands[1]))
7026 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7029 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7033 operands[4] = gen_highpart (SImode, operands[1]);
7034 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7036 operands[1] = gen_lowpart (SImode, operands[1]);
7037 operands[2] = gen_lowpart (SImode, operands[2]);
7039 [(set_attr "conds" "set")
7040 (set_attr "length" "8")
7041 (set_attr "type" "multiple")]
7044 (define_insn_and_split "*arm_cmpdi_unsigned"
7045 [(set (reg:CC_CZ CC_REGNUM)
7046 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7047 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7050 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7051 "&& reload_completed"
7052 [(set (reg:CC CC_REGNUM)
7053 (compare:CC (match_dup 2) (match_dup 3)))
7054 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7055 (set (reg:CC CC_REGNUM)
7056 (compare:CC (match_dup 0) (match_dup 1))))]
7058 operands[2] = gen_highpart (SImode, operands[0]);
7059 operands[0] = gen_lowpart (SImode, operands[0]);
7060 if (CONST_INT_P (operands[1]))
7061 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7063 operands[3] = gen_highpart (SImode, operands[1]);
7064 operands[1] = gen_lowpart (SImode, operands[1]);
7066 [(set_attr "conds" "set")
7067 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7068 (set_attr "arch" "t2,t2,t2,a")
7069 (set_attr "length" "6,6,10,8")
7070 (set_attr "type" "multiple")]
7073 (define_insn "*arm_cmpdi_zero"
7074 [(set (reg:CC_Z CC_REGNUM)
7075 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7077 (clobber (match_scratch:SI 1 "=r"))]
7079 "orrs%?\\t%1, %Q0, %R0"
7080 [(set_attr "conds" "set")
7081 (set_attr "type" "logics_reg")]
7084 ; This insn allows redundant compares to be removed by cse, nothing should
7085 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7086 ; is deleted later on. The match_dup will match the mode here, so that
7087 ; mode changes of the condition codes aren't lost by this even though we don't
7088 ; specify what they are.
7090 (define_insn "*deleted_compare"
7091 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7093 "\\t%@ deleted compare"
7094 [(set_attr "conds" "set")
7095 (set_attr "length" "0")
7096 (set_attr "type" "no_insn")]
7100 ;; Conditional branch insns
7102 (define_expand "cbranch_cc"
7104 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7105 (match_operand 2 "" "")])
7106 (label_ref (match_operand 3 "" ""))
7109 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7110 operands[1], operands[2], NULL_RTX);
7111 operands[2] = const0_rtx;"
7115 ;; Patterns to match conditional branch insns.
7118 (define_insn "arm_cond_branch"
7120 (if_then_else (match_operator 1 "arm_comparison_operator"
7121 [(match_operand 2 "cc_register" "") (const_int 0)])
7122 (label_ref (match_operand 0 "" ""))
7126 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7128 arm_ccfsm_state += 2;
7131 return \"b%d1\\t%l0\";
7133 [(set_attr "conds" "use")
7134 (set_attr "type" "branch")
7135 (set (attr "length")
7137 (and (match_test "TARGET_THUMB2")
7138 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7139 (le (minus (match_dup 0) (pc)) (const_int 256))))
7144 (define_insn "*arm_cond_branch_reversed"
7146 (if_then_else (match_operator 1 "arm_comparison_operator"
7147 [(match_operand 2 "cc_register" "") (const_int 0)])
7149 (label_ref (match_operand 0 "" ""))))]
7152 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7154 arm_ccfsm_state += 2;
7157 return \"b%D1\\t%l0\";
7159 [(set_attr "conds" "use")
7160 (set_attr "type" "branch")
7161 (set (attr "length")
7163 (and (match_test "TARGET_THUMB2")
7164 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7165 (le (minus (match_dup 0) (pc)) (const_int 256))))
7174 (define_expand "cstore_cc"
7175 [(set (match_operand:SI 0 "s_register_operand" "")
7176 (match_operator:SI 1 "" [(match_operand 2 "" "")
7177 (match_operand 3 "" "")]))]
7179 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7180 operands[2], operands[3], NULL_RTX);
7181 operands[3] = const0_rtx;"
7184 (define_insn_and_split "*mov_scc"
7185 [(set (match_operand:SI 0 "s_register_operand" "=r")
7186 (match_operator:SI 1 "arm_comparison_operator_mode"
7187 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7189 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7192 (if_then_else:SI (match_dup 1)
7196 [(set_attr "conds" "use")
7197 (set_attr "length" "8")
7198 (set_attr "type" "multiple")]
7201 (define_insn_and_split "*mov_negscc"
7202 [(set (match_operand:SI 0 "s_register_operand" "=r")
7203 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7204 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7206 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7209 (if_then_else:SI (match_dup 1)
7213 operands[3] = GEN_INT (~0);
7215 [(set_attr "conds" "use")
7216 (set_attr "length" "8")
7217 (set_attr "type" "multiple")]
7220 (define_insn_and_split "*mov_notscc"
7221 [(set (match_operand:SI 0 "s_register_operand" "=r")
7222 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7223 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7225 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7228 (if_then_else:SI (match_dup 1)
7232 operands[3] = GEN_INT (~1);
7233 operands[4] = GEN_INT (~0);
7235 [(set_attr "conds" "use")
7236 (set_attr "length" "8")
7237 (set_attr "type" "multiple")]
7240 (define_expand "cstoresi4"
7241 [(set (match_operand:SI 0 "s_register_operand" "")
7242 (match_operator:SI 1 "expandable_comparison_operator"
7243 [(match_operand:SI 2 "s_register_operand" "")
7244 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7245 "TARGET_32BIT || TARGET_THUMB1"
7247 rtx op3, scratch, scratch2;
7251 if (!arm_add_operand (operands[3], SImode))
7252 operands[3] = force_reg (SImode, operands[3]);
7253 emit_insn (gen_cstore_cc (operands[0], operands[1],
7254 operands[2], operands[3]));
7258 if (operands[3] == const0_rtx)
7260 switch (GET_CODE (operands[1]))
7263 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7267 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7271 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7272 NULL_RTX, 0, OPTAB_WIDEN);
7273 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7274 NULL_RTX, 0, OPTAB_WIDEN);
7275 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7276 operands[0], 1, OPTAB_WIDEN);
7280 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7282 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7283 NULL_RTX, 1, OPTAB_WIDEN);
7287 scratch = expand_binop (SImode, ashr_optab, operands[2],
7288 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7289 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7290 NULL_RTX, 0, OPTAB_WIDEN);
7291 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7295 /* LT is handled by generic code. No need for unsigned with 0. */
7302 switch (GET_CODE (operands[1]))
7305 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7306 NULL_RTX, 0, OPTAB_WIDEN);
7307 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7311 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7312 NULL_RTX, 0, OPTAB_WIDEN);
7313 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7317 op3 = force_reg (SImode, operands[3]);
7319 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7320 NULL_RTX, 1, OPTAB_WIDEN);
7321 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7322 NULL_RTX, 0, OPTAB_WIDEN);
7323 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7329 if (!thumb1_cmp_operand (op3, SImode))
7330 op3 = force_reg (SImode, op3);
7331 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7332 NULL_RTX, 0, OPTAB_WIDEN);
7333 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7334 NULL_RTX, 1, OPTAB_WIDEN);
7335 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7340 op3 = force_reg (SImode, operands[3]);
7341 scratch = force_reg (SImode, const0_rtx);
7342 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7348 if (!thumb1_cmp_operand (op3, SImode))
7349 op3 = force_reg (SImode, op3);
7350 scratch = force_reg (SImode, const0_rtx);
7351 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7357 if (!thumb1_cmp_operand (op3, SImode))
7358 op3 = force_reg (SImode, op3);
7359 scratch = gen_reg_rtx (SImode);
7360 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7364 op3 = force_reg (SImode, operands[3]);
7365 scratch = gen_reg_rtx (SImode);
7366 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7369 /* No good sequences for GT, LT. */
7376 (define_expand "cstoresf4"
7377 [(set (match_operand:SI 0 "s_register_operand" "")
7378 (match_operator:SI 1 "expandable_comparison_operator"
7379 [(match_operand:SF 2 "s_register_operand" "")
7380 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7381 "TARGET_32BIT && TARGET_HARD_FLOAT"
7382 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7383 operands[2], operands[3])); DONE;"
7386 (define_expand "cstoredf4"
7387 [(set (match_operand:SI 0 "s_register_operand" "")
7388 (match_operator:SI 1 "expandable_comparison_operator"
7389 [(match_operand:DF 2 "s_register_operand" "")
7390 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7391 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7392 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7393 operands[2], operands[3])); DONE;"
7396 (define_expand "cstoredi4"
7397 [(set (match_operand:SI 0 "s_register_operand" "")
7398 (match_operator:SI 1 "expandable_comparison_operator"
7399 [(match_operand:DI 2 "s_register_operand" "")
7400 (match_operand:DI 3 "cmpdi_operand" "")]))]
7403 if (!arm_validize_comparison (&operands[1],
7407 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7414 ;; Conditional move insns
7416 (define_expand "movsicc"
7417 [(set (match_operand:SI 0 "s_register_operand" "")
7418 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7419 (match_operand:SI 2 "arm_not_operand" "")
7420 (match_operand:SI 3 "arm_not_operand" "")))]
7427 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7428 &XEXP (operands[1], 1)))
7431 code = GET_CODE (operands[1]);
7432 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7433 XEXP (operands[1], 1), NULL_RTX);
7434 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7438 (define_expand "movsfcc"
7439 [(set (match_operand:SF 0 "s_register_operand" "")
7440 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7441 (match_operand:SF 2 "s_register_operand" "")
7442 (match_operand:SF 3 "s_register_operand" "")))]
7443 "TARGET_32BIT && TARGET_HARD_FLOAT"
7446 enum rtx_code code = GET_CODE (operands[1]);
7449 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7450 &XEXP (operands[1], 1)))
7453 code = GET_CODE (operands[1]);
7454 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7455 XEXP (operands[1], 1), NULL_RTX);
7456 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7460 (define_expand "movdfcc"
7461 [(set (match_operand:DF 0 "s_register_operand" "")
7462 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7463 (match_operand:DF 2 "s_register_operand" "")
7464 (match_operand:DF 3 "s_register_operand" "")))]
7465 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7468 enum rtx_code code = GET_CODE (operands[1]);
7471 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7472 &XEXP (operands[1], 1)))
7474 code = GET_CODE (operands[1]);
7475 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7476 XEXP (operands[1], 1), NULL_RTX);
7477 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7481 (define_insn "*cmov<mode>"
7482 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7483 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7484 [(match_operand 2 "cc_register" "") (const_int 0)])
7485 (match_operand:SDF 3 "s_register_operand"
7487 (match_operand:SDF 4 "s_register_operand"
7488 "<F_constraint>")))]
7489 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7492 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7499 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7504 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7510 [(set_attr "conds" "use")
7511 (set_attr "type" "fcsel")]
7514 (define_insn_and_split "*movsicc_insn"
7515 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7517 (match_operator 3 "arm_comparison_operator"
7518 [(match_operand 4 "cc_register" "") (const_int 0)])
7519 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7520 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7531 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7532 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7533 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7534 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7535 "&& reload_completed"
7538 enum rtx_code rev_code;
7542 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7544 gen_rtx_SET (operands[0], operands[1])));
7546 rev_code = GET_CODE (operands[3]);
7547 mode = GET_MODE (operands[4]);
7548 if (mode == CCFPmode || mode == CCFPEmode)
7549 rev_code = reverse_condition_maybe_unordered (rev_code);
7551 rev_code = reverse_condition (rev_code);
7553 rev_cond = gen_rtx_fmt_ee (rev_code,
7557 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7559 gen_rtx_SET (operands[0], operands[2])));
7562 [(set_attr "length" "4,4,4,4,8,8,8,8")
7563 (set_attr "conds" "use")
7564 (set_attr_alternative "type"
7565 [(if_then_else (match_operand 2 "const_int_operand" "")
7566 (const_string "mov_imm")
7567 (const_string "mov_reg"))
7568 (const_string "mvn_imm")
7569 (if_then_else (match_operand 1 "const_int_operand" "")
7570 (const_string "mov_imm")
7571 (const_string "mov_reg"))
7572 (const_string "mvn_imm")
7573 (const_string "multiple")
7574 (const_string "multiple")
7575 (const_string "multiple")
7576 (const_string "multiple")])]
7579 (define_insn "*movsfcc_soft_insn"
7580 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7581 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7582 [(match_operand 4 "cc_register" "") (const_int 0)])
7583 (match_operand:SF 1 "s_register_operand" "0,r")
7584 (match_operand:SF 2 "s_register_operand" "r,0")))]
7585 "TARGET_ARM && TARGET_SOFT_FLOAT"
7589 [(set_attr "conds" "use")
7590 (set_attr "type" "mov_reg")]
7594 ;; Jump and linkage insns
7596 (define_expand "jump"
7598 (label_ref (match_operand 0 "" "")))]
7603 (define_insn "*arm_jump"
7605 (label_ref (match_operand 0 "" "")))]
7609 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7611 arm_ccfsm_state += 2;
7614 return \"b%?\\t%l0\";
7617 [(set_attr "predicable" "yes")
7618 (set (attr "length")
7620 (and (match_test "TARGET_THUMB2")
7621 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7622 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7625 (set_attr "type" "branch")]
7628 (define_expand "call"
7629 [(parallel [(call (match_operand 0 "memory_operand" "")
7630 (match_operand 1 "general_operand" ""))
7631 (use (match_operand 2 "" ""))
7632 (clobber (reg:SI LR_REGNUM))])]
7638 /* In an untyped call, we can get NULL for operand 2. */
7639 if (operands[2] == NULL_RTX)
7640 operands[2] = const0_rtx;
7642 /* Decide if we should generate indirect calls by loading the
7643 32-bit address of the callee into a register before performing the
7645 callee = XEXP (operands[0], 0);
7646 if (GET_CODE (callee) == SYMBOL_REF
7647 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7649 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7651 pat = gen_call_internal (operands[0], operands[1], operands[2]);
7652 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7657 (define_expand "call_internal"
7658 [(parallel [(call (match_operand 0 "memory_operand" "")
7659 (match_operand 1 "general_operand" ""))
7660 (use (match_operand 2 "" ""))
7661 (clobber (reg:SI LR_REGNUM))])])
7663 (define_insn "*call_reg_armv5"
7664 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7665 (match_operand 1 "" ""))
7666 (use (match_operand 2 "" ""))
7667 (clobber (reg:SI LR_REGNUM))]
7668 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7670 [(set_attr "type" "call")]
7673 (define_insn "*call_reg_arm"
7674 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7675 (match_operand 1 "" ""))
7676 (use (match_operand 2 "" ""))
7677 (clobber (reg:SI LR_REGNUM))]
7678 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7680 return output_call (operands);
7682 ;; length is worst case, normally it is only two
7683 [(set_attr "length" "12")
7684 (set_attr "type" "call")]
7688 (define_expand "call_value"
7689 [(parallel [(set (match_operand 0 "" "")
7690 (call (match_operand 1 "memory_operand" "")
7691 (match_operand 2 "general_operand" "")))
7692 (use (match_operand 3 "" ""))
7693 (clobber (reg:SI LR_REGNUM))])]
7699 /* In an untyped call, we can get NULL for operand 2. */
7700 if (operands[3] == 0)
7701 operands[3] = const0_rtx;
7703 /* Decide if we should generate indirect calls by loading the
7704 32-bit address of the callee into a register before performing the
7706 callee = XEXP (operands[1], 0);
7707 if (GET_CODE (callee) == SYMBOL_REF
7708 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7710 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7712 pat = gen_call_value_internal (operands[0], operands[1],
7713 operands[2], operands[3]);
7714 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7719 (define_expand "call_value_internal"
7720 [(parallel [(set (match_operand 0 "" "")
7721 (call (match_operand 1 "memory_operand" "")
7722 (match_operand 2 "general_operand" "")))
7723 (use (match_operand 3 "" ""))
7724 (clobber (reg:SI LR_REGNUM))])])
7726 (define_insn "*call_value_reg_armv5"
7727 [(set (match_operand 0 "" "")
7728 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7729 (match_operand 2 "" "")))
7730 (use (match_operand 3 "" ""))
7731 (clobber (reg:SI LR_REGNUM))]
7732 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7734 [(set_attr "type" "call")]
7737 (define_insn "*call_value_reg_arm"
7738 [(set (match_operand 0 "" "")
7739 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7740 (match_operand 2 "" "")))
7741 (use (match_operand 3 "" ""))
7742 (clobber (reg:SI LR_REGNUM))]
7743 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7745 return output_call (&operands[1]);
7747 [(set_attr "length" "12")
7748 (set_attr "type" "call")]
7751 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7752 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7754 (define_insn "*call_symbol"
7755 [(call (mem:SI (match_operand:SI 0 "" ""))
7756 (match_operand 1 "" ""))
7757 (use (match_operand 2 "" ""))
7758 (clobber (reg:SI LR_REGNUM))]
7760 && !SIBLING_CALL_P (insn)
7761 && (GET_CODE (operands[0]) == SYMBOL_REF)
7762 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7765 rtx op = operands[0];
7767 /* Switch mode now when possible. */
7768 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7769 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7770 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7772 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7774 [(set_attr "type" "call")]
7777 (define_insn "*call_value_symbol"
7778 [(set (match_operand 0 "" "")
7779 (call (mem:SI (match_operand:SI 1 "" ""))
7780 (match_operand:SI 2 "" "")))
7781 (use (match_operand 3 "" ""))
7782 (clobber (reg:SI LR_REGNUM))]
7784 && !SIBLING_CALL_P (insn)
7785 && (GET_CODE (operands[1]) == SYMBOL_REF)
7786 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7789 rtx op = operands[1];
7791 /* Switch mode now when possible. */
7792 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7793 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7794 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
7796 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7798 [(set_attr "type" "call")]
7801 (define_expand "sibcall_internal"
7802 [(parallel [(call (match_operand 0 "memory_operand" "")
7803 (match_operand 1 "general_operand" ""))
7805 (use (match_operand 2 "" ""))])])
7807 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7808 (define_expand "sibcall"
7809 [(parallel [(call (match_operand 0 "memory_operand" "")
7810 (match_operand 1 "general_operand" ""))
7812 (use (match_operand 2 "" ""))])]
7818 if ((!REG_P (XEXP (operands[0], 0))
7819 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7820 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7821 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7822 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7824 if (operands[2] == NULL_RTX)
7825 operands[2] = const0_rtx;
7827 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7828 arm_emit_call_insn (pat, operands[0], true);
7833 (define_expand "sibcall_value_internal"
7834 [(parallel [(set (match_operand 0 "" "")
7835 (call (match_operand 1 "memory_operand" "")
7836 (match_operand 2 "general_operand" "")))
7838 (use (match_operand 3 "" ""))])])
7840 (define_expand "sibcall_value"
7841 [(parallel [(set (match_operand 0 "" "")
7842 (call (match_operand 1 "memory_operand" "")
7843 (match_operand 2 "general_operand" "")))
7845 (use (match_operand 3 "" ""))])]
7851 if ((!REG_P (XEXP (operands[1], 0))
7852 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7853 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7854 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7855 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7857 if (operands[3] == NULL_RTX)
7858 operands[3] = const0_rtx;
7860 pat = gen_sibcall_value_internal (operands[0], operands[1],
7861 operands[2], operands[3]);
7862 arm_emit_call_insn (pat, operands[1], true);
7867 (define_insn "*sibcall_insn"
7868 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7869 (match_operand 1 "" ""))
7871 (use (match_operand 2 "" ""))]
7872 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7874 if (which_alternative == 1)
7875 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7878 if (arm_arch5 || arm_arch4t)
7879 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7881 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7884 [(set_attr "type" "call")]
7887 (define_insn "*sibcall_value_insn"
7888 [(set (match_operand 0 "" "")
7889 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7890 (match_operand 2 "" "")))
7892 (use (match_operand 3 "" ""))]
7893 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7895 if (which_alternative == 1)
7896 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7899 if (arm_arch5 || arm_arch4t)
7900 return \"bx%?\\t%1\";
7902 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7905 [(set_attr "type" "call")]
7908 (define_expand "<return_str>return"
7910 "(TARGET_ARM || (TARGET_THUMB2
7911 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7912 && !IS_STACKALIGN (arm_current_func_type ())))
7913 <return_cond_false>"
7918 thumb2_expand_return (<return_simple_p>);
7925 ;; Often the return insn will be the same as loading from memory, so set attr
7926 (define_insn "*arm_return"
7928 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7931 if (arm_ccfsm_state == 2)
7933 arm_ccfsm_state += 2;
7936 return output_return_instruction (const_true_rtx, true, false, false);
7938 [(set_attr "type" "load1")
7939 (set_attr "length" "12")
7940 (set_attr "predicable" "yes")]
7943 (define_insn "*cond_<return_str>return"
7945 (if_then_else (match_operator 0 "arm_comparison_operator"
7946 [(match_operand 1 "cc_register" "") (const_int 0)])
7949 "TARGET_ARM <return_cond_true>"
7952 if (arm_ccfsm_state == 2)
7954 arm_ccfsm_state += 2;
7957 return output_return_instruction (operands[0], true, false,
7960 [(set_attr "conds" "use")
7961 (set_attr "length" "12")
7962 (set_attr "type" "load1")]
7965 (define_insn "*cond_<return_str>return_inverted"
7967 (if_then_else (match_operator 0 "arm_comparison_operator"
7968 [(match_operand 1 "cc_register" "") (const_int 0)])
7971 "TARGET_ARM <return_cond_true>"
7974 if (arm_ccfsm_state == 2)
7976 arm_ccfsm_state += 2;
7979 return output_return_instruction (operands[0], true, true,
7982 [(set_attr "conds" "use")
7983 (set_attr "length" "12")
7984 (set_attr "type" "load1")]
7987 (define_insn "*arm_simple_return"
7992 if (arm_ccfsm_state == 2)
7994 arm_ccfsm_state += 2;
7997 return output_return_instruction (const_true_rtx, true, false, true);
7999 [(set_attr "type" "branch")
8000 (set_attr "length" "4")
8001 (set_attr "predicable" "yes")]
8004 ;; Generate a sequence of instructions to determine if the processor is
8005 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8008 (define_expand "return_addr_mask"
8010 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8012 (set (match_operand:SI 0 "s_register_operand" "")
8013 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8015 (const_int 67108860)))] ; 0x03fffffc
8018 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8021 (define_insn "*check_arch2"
8022 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8023 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8026 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8027 [(set_attr "length" "8")
8028 (set_attr "conds" "set")
8029 (set_attr "type" "multiple")]
8032 ;; Call subroutine returning any type.
8034 (define_expand "untyped_call"
8035 [(parallel [(call (match_operand 0 "" "")
8037 (match_operand 1 "" "")
8038 (match_operand 2 "" "")])]
8043 rtx par = gen_rtx_PARALLEL (VOIDmode,
8044 rtvec_alloc (XVECLEN (operands[2], 0)));
8045 rtx addr = gen_reg_rtx (Pmode);
8049 emit_move_insn (addr, XEXP (operands[1], 0));
8050 mem = change_address (operands[1], BLKmode, addr);
8052 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8054 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8056 /* Default code only uses r0 as a return value, but we could
8057 be using anything up to 4 registers. */
8058 if (REGNO (src) == R0_REGNUM)
8059 src = gen_rtx_REG (TImode, R0_REGNUM);
8061 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8063 size += GET_MODE_SIZE (GET_MODE (src));
8066 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8070 for (i = 0; i < XVECLEN (par, 0); i++)
8072 HOST_WIDE_INT offset = 0;
8073 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8076 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8078 mem = change_address (mem, GET_MODE (reg), NULL);
8079 if (REGNO (reg) == R0_REGNUM)
8081 /* On thumb we have to use a write-back instruction. */
8082 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8083 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8084 size = TARGET_ARM ? 16 : 0;
8088 emit_move_insn (mem, reg);
8089 size = GET_MODE_SIZE (GET_MODE (reg));
8093 /* The optimizer does not know that the call sets the function value
8094 registers we stored in the result block. We avoid problems by
8095 claiming that all hard registers are used and clobbered at this
8097 emit_insn (gen_blockage ());
8103 (define_expand "untyped_return"
8104 [(match_operand:BLK 0 "memory_operand" "")
8105 (match_operand 1 "" "")]
8110 rtx addr = gen_reg_rtx (Pmode);
8114 emit_move_insn (addr, XEXP (operands[0], 0));
8115 mem = change_address (operands[0], BLKmode, addr);
8117 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8119 HOST_WIDE_INT offset = 0;
8120 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8123 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8125 mem = change_address (mem, GET_MODE (reg), NULL);
8126 if (REGNO (reg) == R0_REGNUM)
8128 /* On thumb we have to use a write-back instruction. */
8129 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8130 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8131 size = TARGET_ARM ? 16 : 0;
8135 emit_move_insn (reg, mem);
8136 size = GET_MODE_SIZE (GET_MODE (reg));
8140 /* Emit USE insns before the return. */
8141 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8142 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8144 /* Construct the return. */
8145 expand_naked_return ();
8151 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8152 ;; all of memory. This blocks insns from being moved across this point.
8154 (define_insn "blockage"
8155 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8158 [(set_attr "length" "0")
8159 (set_attr "type" "block")]
8162 (define_insn "probe_stack"
8163 [(set (match_operand:SI 0 "memory_operand" "=m")
8164 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8167 [(set_attr "type" "store1")
8168 (set_attr "predicable" "yes")]
8171 (define_insn "probe_stack_range"
8172 [(set (match_operand:SI 0 "register_operand" "=r")
8173 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8174 (match_operand:SI 2 "register_operand" "r")]
8175 VUNSPEC_PROBE_STACK_RANGE))]
8178 return output_probe_stack_range (operands[0], operands[2]);
8180 [(set_attr "type" "multiple")
8181 (set_attr "conds" "clob")]
8184 (define_expand "casesi"
8185 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8186 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8187 (match_operand:SI 2 "const_int_operand" "") ; total range
8188 (match_operand:SI 3 "" "") ; table label
8189 (match_operand:SI 4 "" "")] ; Out of range label
8190 "TARGET_32BIT || optimize_size || flag_pic"
8193 enum insn_code code;
8194 if (operands[1] != const0_rtx)
8196 rtx reg = gen_reg_rtx (SImode);
8198 emit_insn (gen_addsi3 (reg, operands[0],
8199 gen_int_mode (-INTVAL (operands[1]),
8205 code = CODE_FOR_arm_casesi_internal;
8206 else if (TARGET_THUMB1)
8207 code = CODE_FOR_thumb1_casesi_internal_pic;
8209 code = CODE_FOR_thumb2_casesi_internal_pic;
8211 code = CODE_FOR_thumb2_casesi_internal;
8213 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8214 operands[2] = force_reg (SImode, operands[2]);
8216 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8217 operands[3], operands[4]));
8222 ;; The USE in this pattern is needed to tell flow analysis that this is
8223 ;; a CASESI insn. It has no other purpose.
8224 (define_insn "arm_casesi_internal"
8225 [(parallel [(set (pc)
8227 (leu (match_operand:SI 0 "s_register_operand" "r")
8228 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8229 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8230 (label_ref (match_operand 2 "" ""))))
8231 (label_ref (match_operand 3 "" ""))))
8232 (clobber (reg:CC CC_REGNUM))
8233 (use (label_ref (match_dup 2)))])]
8237 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8238 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8240 [(set_attr "conds" "clob")
8241 (set_attr "length" "12")
8242 (set_attr "type" "multiple")]
8245 (define_expand "indirect_jump"
8247 (match_operand:SI 0 "s_register_operand" ""))]
8250 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8251 address and use bx. */
8255 tmp = gen_reg_rtx (SImode);
8256 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8262 ;; NB Never uses BX.
8263 (define_insn "*arm_indirect_jump"
8265 (match_operand:SI 0 "s_register_operand" "r"))]
8267 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8268 [(set_attr "predicable" "yes")
8269 (set_attr "type" "branch")]
8272 (define_insn "*load_indirect_jump"
8274 (match_operand:SI 0 "memory_operand" "m"))]
8276 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8277 [(set_attr "type" "load1")
8278 (set_attr "pool_range" "4096")
8279 (set_attr "neg_pool_range" "4084")
8280 (set_attr "predicable" "yes")]
8290 [(set (attr "length")
8291 (if_then_else (eq_attr "is_thumb" "yes")
8294 (set_attr "type" "mov_reg")]
8298 [(trap_if (const_int 1) (const_int 0))]
8302 return \".inst\\t0xe7f000f0\";
8304 return \".inst\\t0xdeff\";
8306 [(set (attr "length")
8307 (if_then_else (eq_attr "is_thumb" "yes")
8310 (set_attr "type" "trap")
8311 (set_attr "conds" "unconditional")]
8315 ;; Patterns to allow combination of arithmetic, cond code and shifts
8317 (define_insn "*<arith_shift_insn>_multsi"
8318 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8320 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8321 (match_operand:SI 3 "power_of_two_operand" ""))
8322 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8324 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8325 [(set_attr "predicable" "yes")
8326 (set_attr "predicable_short_it" "no")
8327 (set_attr "shift" "2")
8328 (set_attr "arch" "a,t2")
8329 (set_attr "type" "alu_shift_imm")])
8331 (define_insn "*<arith_shift_insn>_shiftsi"
8332 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8334 (match_operator:SI 2 "shift_nomul_operator"
8335 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8336 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8337 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8338 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8339 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8340 [(set_attr "predicable" "yes")
8341 (set_attr "predicable_short_it" "no")
8342 (set_attr "shift" "3")
8343 (set_attr "arch" "a,t2,a")
8344 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8347 [(set (match_operand:SI 0 "s_register_operand" "")
8348 (match_operator:SI 1 "shiftable_operator"
8349 [(match_operator:SI 2 "shiftable_operator"
8350 [(match_operator:SI 3 "shift_operator"
8351 [(match_operand:SI 4 "s_register_operand" "")
8352 (match_operand:SI 5 "reg_or_int_operand" "")])
8353 (match_operand:SI 6 "s_register_operand" "")])
8354 (match_operand:SI 7 "arm_rhs_operand" "")]))
8355 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8358 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8361 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8364 (define_insn "*arith_shiftsi_compare0"
8365 [(set (reg:CC_NOOV CC_REGNUM)
8367 (match_operator:SI 1 "shiftable_operator"
8368 [(match_operator:SI 3 "shift_operator"
8369 [(match_operand:SI 4 "s_register_operand" "r,r")
8370 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8371 (match_operand:SI 2 "s_register_operand" "r,r")])
8373 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8374 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8377 "%i1s%?\\t%0, %2, %4%S3"
8378 [(set_attr "conds" "set")
8379 (set_attr "shift" "4")
8380 (set_attr "arch" "32,a")
8381 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8383 (define_insn "*arith_shiftsi_compare0_scratch"
8384 [(set (reg:CC_NOOV CC_REGNUM)
8386 (match_operator:SI 1 "shiftable_operator"
8387 [(match_operator:SI 3 "shift_operator"
8388 [(match_operand:SI 4 "s_register_operand" "r,r")
8389 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8390 (match_operand:SI 2 "s_register_operand" "r,r")])
8392 (clobber (match_scratch:SI 0 "=r,r"))]
8394 "%i1s%?\\t%0, %2, %4%S3"
8395 [(set_attr "conds" "set")
8396 (set_attr "shift" "4")
8397 (set_attr "arch" "32,a")
8398 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8400 (define_insn "*sub_shiftsi"
8401 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8402 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8403 (match_operator:SI 2 "shift_operator"
8404 [(match_operand:SI 3 "s_register_operand" "r,r")
8405 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8407 "sub%?\\t%0, %1, %3%S2"
8408 [(set_attr "predicable" "yes")
8409 (set_attr "shift" "3")
8410 (set_attr "arch" "32,a")
8411 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8413 (define_insn "*sub_shiftsi_compare0"
8414 [(set (reg:CC_NOOV CC_REGNUM)
8416 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8417 (match_operator:SI 2 "shift_operator"
8418 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8419 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8421 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8422 (minus:SI (match_dup 1)
8423 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8425 "subs%?\\t%0, %1, %3%S2"
8426 [(set_attr "conds" "set")
8427 (set_attr "shift" "3")
8428 (set_attr "arch" "32,a,a")
8429 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8431 (define_insn "*sub_shiftsi_compare0_scratch"
8432 [(set (reg:CC_NOOV CC_REGNUM)
8434 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8435 (match_operator:SI 2 "shift_operator"
8436 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8437 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8439 (clobber (match_scratch:SI 0 "=r,r,r"))]
8441 "subs%?\\t%0, %1, %3%S2"
8442 [(set_attr "conds" "set")
8443 (set_attr "shift" "3")
8444 (set_attr "arch" "32,a,a")
8445 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8448 (define_insn_and_split "*and_scc"
8449 [(set (match_operand:SI 0 "s_register_operand" "=r")
8450 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8451 [(match_operand 2 "cc_register" "") (const_int 0)])
8452 (match_operand:SI 3 "s_register_operand" "r")))]
8454 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8455 "&& reload_completed"
8456 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8457 (cond_exec (match_dup 4) (set (match_dup 0)
8458 (and:SI (match_dup 3) (const_int 1))))]
8460 machine_mode mode = GET_MODE (operands[2]);
8461 enum rtx_code rc = GET_CODE (operands[1]);
8463 /* Note that operands[4] is the same as operands[1],
8464 but with VOIDmode as the result. */
8465 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8466 if (mode == CCFPmode || mode == CCFPEmode)
8467 rc = reverse_condition_maybe_unordered (rc);
8469 rc = reverse_condition (rc);
8470 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8472 [(set_attr "conds" "use")
8473 (set_attr "type" "multiple")
8474 (set_attr "length" "8")]
8477 (define_insn_and_split "*ior_scc"
8478 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8479 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8480 [(match_operand 2 "cc_register" "") (const_int 0)])
8481 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8486 "&& reload_completed
8487 && REGNO (operands [0]) != REGNO (operands[3])"
8488 ;; && which_alternative == 1
8489 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8490 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8491 (cond_exec (match_dup 4) (set (match_dup 0)
8492 (ior:SI (match_dup 3) (const_int 1))))]
8494 machine_mode mode = GET_MODE (operands[2]);
8495 enum rtx_code rc = GET_CODE (operands[1]);
8497 /* Note that operands[4] is the same as operands[1],
8498 but with VOIDmode as the result. */
8499 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8500 if (mode == CCFPmode || mode == CCFPEmode)
8501 rc = reverse_condition_maybe_unordered (rc);
8503 rc = reverse_condition (rc);
8504 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8506 [(set_attr "conds" "use")
8507 (set_attr "length" "4,8")
8508 (set_attr "type" "logic_imm,multiple")]
8511 ; A series of splitters for the compare_scc pattern below. Note that
8512 ; order is important.
8514 [(set (match_operand:SI 0 "s_register_operand" "")
8515 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8517 (clobber (reg:CC CC_REGNUM))]
8518 "TARGET_32BIT && reload_completed"
8519 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8522 [(set (match_operand:SI 0 "s_register_operand" "")
8523 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8525 (clobber (reg:CC CC_REGNUM))]
8526 "TARGET_32BIT && reload_completed"
8527 [(set (match_dup 0) (not:SI (match_dup 1)))
8528 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8531 [(set (match_operand:SI 0 "s_register_operand" "")
8532 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8534 (clobber (reg:CC CC_REGNUM))]
8535 "arm_arch5 && TARGET_32BIT"
8536 [(set (match_dup 0) (clz:SI (match_dup 1)))
8537 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8541 [(set (match_operand:SI 0 "s_register_operand" "")
8542 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8544 (clobber (reg:CC CC_REGNUM))]
8545 "TARGET_32BIT && reload_completed"
8547 [(set (reg:CC CC_REGNUM)
8548 (compare:CC (const_int 1) (match_dup 1)))
8550 (minus:SI (const_int 1) (match_dup 1)))])
8551 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8552 (set (match_dup 0) (const_int 0)))])
8555 [(set (match_operand:SI 0 "s_register_operand" "")
8556 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8557 (match_operand:SI 2 "const_int_operand" "")))
8558 (clobber (reg:CC CC_REGNUM))]
8559 "TARGET_32BIT && reload_completed"
8561 [(set (reg:CC CC_REGNUM)
8562 (compare:CC (match_dup 1) (match_dup 2)))
8563 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8564 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8565 (set (match_dup 0) (const_int 1)))]
8567 operands[3] = GEN_INT (-INTVAL (operands[2]));
8571 [(set (match_operand:SI 0 "s_register_operand" "")
8572 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8573 (match_operand:SI 2 "arm_add_operand" "")))
8574 (clobber (reg:CC CC_REGNUM))]
8575 "TARGET_32BIT && reload_completed"
8577 [(set (reg:CC_NOOV CC_REGNUM)
8578 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8580 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8581 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8582 (set (match_dup 0) (const_int 1)))])
8584 (define_insn_and_split "*compare_scc"
8585 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8586 (match_operator:SI 1 "arm_comparison_operator"
8587 [(match_operand:SI 2 "s_register_operand" "r,r")
8588 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8589 (clobber (reg:CC CC_REGNUM))]
8592 "&& reload_completed"
8593 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8594 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8595 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8598 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8599 operands[2], operands[3]);
8600 enum rtx_code rc = GET_CODE (operands[1]);
8602 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8604 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8605 if (mode == CCFPmode || mode == CCFPEmode)
8606 rc = reverse_condition_maybe_unordered (rc);
8608 rc = reverse_condition (rc);
8609 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8611 [(set_attr "type" "multiple")]
8614 ;; Attempt to improve the sequence generated by the compare_scc splitters
8615 ;; not to use conditional execution.
8617 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
8621 [(set (reg:CC CC_REGNUM)
8622 (compare:CC (match_operand:SI 1 "register_operand" "")
8624 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8625 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8626 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8627 (set (match_dup 0) (const_int 1)))]
8628 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8629 [(set (match_dup 0) (clz:SI (match_dup 1)))
8630 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8633 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8637 [(set (reg:CC CC_REGNUM)
8638 (compare:CC (match_operand:SI 1 "register_operand" "")
8640 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8641 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8642 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8643 (set (match_dup 0) (const_int 1)))
8644 (match_scratch:SI 2 "r")]
8645 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8647 [(set (reg:CC CC_REGNUM)
8648 (compare:CC (const_int 0) (match_dup 1)))
8649 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8651 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8652 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8655 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
8656 ;; sub Rd, Reg1, reg2
8660 [(set (reg:CC CC_REGNUM)
8661 (compare:CC (match_operand:SI 1 "register_operand" "")
8662 (match_operand:SI 2 "arm_rhs_operand" "")))
8663 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8664 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8665 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8666 (set (match_dup 0) (const_int 1)))]
8667 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8668 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8669 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8670 (set (match_dup 0) (clz:SI (match_dup 0)))
8671 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8675 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
8676 ;; sub T1, Reg1, reg2
8680 [(set (reg:CC CC_REGNUM)
8681 (compare:CC (match_operand:SI 1 "register_operand" "")
8682 (match_operand:SI 2 "arm_rhs_operand" "")))
8683 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8684 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8685 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8686 (set (match_dup 0) (const_int 1)))
8687 (match_scratch:SI 3 "r")]
8688 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8689 [(set (match_dup 3) (match_dup 4))
8691 [(set (reg:CC CC_REGNUM)
8692 (compare:CC (const_int 0) (match_dup 3)))
8693 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8695 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8696 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8698 if (CONST_INT_P (operands[2]))
8699 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8701 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8704 (define_insn "*cond_move"
8705 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8706 (if_then_else:SI (match_operator 3 "equality_operator"
8707 [(match_operator 4 "arm_comparison_operator"
8708 [(match_operand 5 "cc_register" "") (const_int 0)])
8710 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8711 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8714 if (GET_CODE (operands[3]) == NE)
8716 if (which_alternative != 1)
8717 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8718 if (which_alternative != 0)
8719 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8722 if (which_alternative != 0)
8723 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8724 if (which_alternative != 1)
8725 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8728 [(set_attr "conds" "use")
8729 (set_attr_alternative "type"
8730 [(if_then_else (match_operand 2 "const_int_operand" "")
8731 (const_string "mov_imm")
8732 (const_string "mov_reg"))
8733 (if_then_else (match_operand 1 "const_int_operand" "")
8734 (const_string "mov_imm")
8735 (const_string "mov_reg"))
8736 (const_string "multiple")])
8737 (set_attr "length" "4,4,8")]
8740 (define_insn "*cond_arith"
8741 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8742 (match_operator:SI 5 "shiftable_operator"
8743 [(match_operator:SI 4 "arm_comparison_operator"
8744 [(match_operand:SI 2 "s_register_operand" "r,r")
8745 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8746 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8747 (clobber (reg:CC CC_REGNUM))]
8750 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8751 return \"%i5\\t%0, %1, %2, lsr #31\";
8753 output_asm_insn (\"cmp\\t%2, %3\", operands);
8754 if (GET_CODE (operands[5]) == AND)
8755 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8756 else if (GET_CODE (operands[5]) == MINUS)
8757 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8758 else if (which_alternative != 0)
8759 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8760 return \"%i5%d4\\t%0, %1, #1\";
8762 [(set_attr "conds" "clob")
8763 (set_attr "length" "12")
8764 (set_attr "type" "multiple")]
8767 (define_insn "*cond_sub"
8768 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8769 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8770 (match_operator:SI 4 "arm_comparison_operator"
8771 [(match_operand:SI 2 "s_register_operand" "r,r")
8772 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8773 (clobber (reg:CC CC_REGNUM))]
8776 output_asm_insn (\"cmp\\t%2, %3\", operands);
8777 if (which_alternative != 0)
8778 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8779 return \"sub%d4\\t%0, %1, #1\";
8781 [(set_attr "conds" "clob")
8782 (set_attr "length" "8,12")
8783 (set_attr "type" "multiple")]
8786 (define_insn "*cmp_ite0"
8787 [(set (match_operand 6 "dominant_cc_register" "")
8790 (match_operator 4 "arm_comparison_operator"
8791 [(match_operand:SI 0 "s_register_operand"
8792 "l,l,l,r,r,r,r,r,r")
8793 (match_operand:SI 1 "arm_add_operand"
8794 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8795 (match_operator:SI 5 "arm_comparison_operator"
8796 [(match_operand:SI 2 "s_register_operand"
8797 "l,r,r,l,l,r,r,r,r")
8798 (match_operand:SI 3 "arm_add_operand"
8799 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8805 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8807 {\"cmp%d5\\t%0, %1\",
8808 \"cmp%d4\\t%2, %3\"},
8809 {\"cmn%d5\\t%0, #%n1\",
8810 \"cmp%d4\\t%2, %3\"},
8811 {\"cmp%d5\\t%0, %1\",
8812 \"cmn%d4\\t%2, #%n3\"},
8813 {\"cmn%d5\\t%0, #%n1\",
8814 \"cmn%d4\\t%2, #%n3\"}
8816 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8821 \"cmn\\t%0, #%n1\"},
8822 {\"cmn\\t%2, #%n3\",
8824 {\"cmn\\t%2, #%n3\",
8827 static const char * const ite[2] =
8832 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8833 CMP_CMP, CMN_CMP, CMP_CMP,
8834 CMN_CMP, CMP_CMN, CMN_CMN};
8836 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8838 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8839 if (TARGET_THUMB2) {
8840 output_asm_insn (ite[swap], operands);
8842 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8845 [(set_attr "conds" "set")
8846 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8847 (set_attr "type" "multiple")
8848 (set_attr_alternative "length"
8854 (if_then_else (eq_attr "is_thumb" "no")
8857 (if_then_else (eq_attr "is_thumb" "no")
8860 (if_then_else (eq_attr "is_thumb" "no")
8863 (if_then_else (eq_attr "is_thumb" "no")
8868 (define_insn "*cmp_ite1"
8869 [(set (match_operand 6 "dominant_cc_register" "")
8872 (match_operator 4 "arm_comparison_operator"
8873 [(match_operand:SI 0 "s_register_operand"
8874 "l,l,l,r,r,r,r,r,r")
8875 (match_operand:SI 1 "arm_add_operand"
8876 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8877 (match_operator:SI 5 "arm_comparison_operator"
8878 [(match_operand:SI 2 "s_register_operand"
8879 "l,r,r,l,l,r,r,r,r")
8880 (match_operand:SI 3 "arm_add_operand"
8881 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8887 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8891 {\"cmn\\t%0, #%n1\",
8894 \"cmn\\t%2, #%n3\"},
8895 {\"cmn\\t%0, #%n1\",
8898 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8900 {\"cmp%d4\\t%2, %3\",
8901 \"cmp%D5\\t%0, %1\"},
8902 {\"cmp%d4\\t%2, %3\",
8903 \"cmn%D5\\t%0, #%n1\"},
8904 {\"cmn%d4\\t%2, #%n3\",
8905 \"cmp%D5\\t%0, %1\"},
8906 {\"cmn%d4\\t%2, #%n3\",
8907 \"cmn%D5\\t%0, #%n1\"}
8909 static const char * const ite[2] =
8914 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8915 CMP_CMP, CMN_CMP, CMP_CMP,
8916 CMN_CMP, CMP_CMN, CMN_CMN};
8918 comparison_dominates_p (GET_CODE (operands[5]),
8919 reverse_condition (GET_CODE (operands[4])));
8921 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8922 if (TARGET_THUMB2) {
8923 output_asm_insn (ite[swap], operands);
8925 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8928 [(set_attr "conds" "set")
8929 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8930 (set_attr_alternative "length"
8936 (if_then_else (eq_attr "is_thumb" "no")
8939 (if_then_else (eq_attr "is_thumb" "no")
8942 (if_then_else (eq_attr "is_thumb" "no")
8945 (if_then_else (eq_attr "is_thumb" "no")
8948 (set_attr "type" "multiple")]
8951 (define_insn "*cmp_and"
8952 [(set (match_operand 6 "dominant_cc_register" "")
8955 (match_operator 4 "arm_comparison_operator"
8956 [(match_operand:SI 0 "s_register_operand"
8957 "l,l,l,r,r,r,r,r,r")
8958 (match_operand:SI 1 "arm_add_operand"
8959 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8960 (match_operator:SI 5 "arm_comparison_operator"
8961 [(match_operand:SI 2 "s_register_operand"
8962 "l,r,r,l,l,r,r,r,r")
8963 (match_operand:SI 3 "arm_add_operand"
8964 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8969 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8971 {\"cmp%d5\\t%0, %1\",
8972 \"cmp%d4\\t%2, %3\"},
8973 {\"cmn%d5\\t%0, #%n1\",
8974 \"cmp%d4\\t%2, %3\"},
8975 {\"cmp%d5\\t%0, %1\",
8976 \"cmn%d4\\t%2, #%n3\"},
8977 {\"cmn%d5\\t%0, #%n1\",
8978 \"cmn%d4\\t%2, #%n3\"}
8980 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8985 \"cmn\\t%0, #%n1\"},
8986 {\"cmn\\t%2, #%n3\",
8988 {\"cmn\\t%2, #%n3\",
8991 static const char *const ite[2] =
8996 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8997 CMP_CMP, CMN_CMP, CMP_CMP,
8998 CMN_CMP, CMP_CMN, CMN_CMN};
9000 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9002 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9003 if (TARGET_THUMB2) {
9004 output_asm_insn (ite[swap], operands);
9006 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9009 [(set_attr "conds" "set")
9010 (set_attr "predicable" "no")
9011 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9012 (set_attr_alternative "length"
9018 (if_then_else (eq_attr "is_thumb" "no")
9021 (if_then_else (eq_attr "is_thumb" "no")
9024 (if_then_else (eq_attr "is_thumb" "no")
9027 (if_then_else (eq_attr "is_thumb" "no")
9030 (set_attr "type" "multiple")]
9033 (define_insn "*cmp_ior"
9034 [(set (match_operand 6 "dominant_cc_register" "")
9037 (match_operator 4 "arm_comparison_operator"
9038 [(match_operand:SI 0 "s_register_operand"
9039 "l,l,l,r,r,r,r,r,r")
9040 (match_operand:SI 1 "arm_add_operand"
9041 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9042 (match_operator:SI 5 "arm_comparison_operator"
9043 [(match_operand:SI 2 "s_register_operand"
9044 "l,r,r,l,l,r,r,r,r")
9045 (match_operand:SI 3 "arm_add_operand"
9046 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9051 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9055 {\"cmn\\t%0, #%n1\",
9058 \"cmn\\t%2, #%n3\"},
9059 {\"cmn\\t%0, #%n1\",
9062 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9064 {\"cmp%D4\\t%2, %3\",
9065 \"cmp%D5\\t%0, %1\"},
9066 {\"cmp%D4\\t%2, %3\",
9067 \"cmn%D5\\t%0, #%n1\"},
9068 {\"cmn%D4\\t%2, #%n3\",
9069 \"cmp%D5\\t%0, %1\"},
9070 {\"cmn%D4\\t%2, #%n3\",
9071 \"cmn%D5\\t%0, #%n1\"}
9073 static const char *const ite[2] =
9078 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9079 CMP_CMP, CMN_CMP, CMP_CMP,
9080 CMN_CMP, CMP_CMN, CMN_CMN};
9082 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9084 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9085 if (TARGET_THUMB2) {
9086 output_asm_insn (ite[swap], operands);
9088 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9092 [(set_attr "conds" "set")
9093 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9094 (set_attr_alternative "length"
9100 (if_then_else (eq_attr "is_thumb" "no")
9103 (if_then_else (eq_attr "is_thumb" "no")
9106 (if_then_else (eq_attr "is_thumb" "no")
9109 (if_then_else (eq_attr "is_thumb" "no")
9112 (set_attr "type" "multiple")]
9115 (define_insn_and_split "*ior_scc_scc"
9116 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9117 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9118 [(match_operand:SI 1 "s_register_operand" "r")
9119 (match_operand:SI 2 "arm_add_operand" "rIL")])
9120 (match_operator:SI 6 "arm_comparison_operator"
9121 [(match_operand:SI 4 "s_register_operand" "r")
9122 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9123 (clobber (reg:CC CC_REGNUM))]
9125 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9128 "TARGET_32BIT && reload_completed"
9132 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9133 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9135 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9137 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9140 [(set_attr "conds" "clob")
9141 (set_attr "length" "16")
9142 (set_attr "type" "multiple")]
9145 ; If the above pattern is followed by a CMP insn, then the compare is
9146 ; redundant, since we can rework the conditional instruction that follows.
9147 (define_insn_and_split "*ior_scc_scc_cmp"
9148 [(set (match_operand 0 "dominant_cc_register" "")
9149 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9150 [(match_operand:SI 1 "s_register_operand" "r")
9151 (match_operand:SI 2 "arm_add_operand" "rIL")])
9152 (match_operator:SI 6 "arm_comparison_operator"
9153 [(match_operand:SI 4 "s_register_operand" "r")
9154 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9156 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9157 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9158 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9161 "TARGET_32BIT && reload_completed"
9165 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9166 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9168 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9170 [(set_attr "conds" "set")
9171 (set_attr "length" "16")
9172 (set_attr "type" "multiple")]
9175 (define_insn_and_split "*and_scc_scc"
9176 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9177 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9178 [(match_operand:SI 1 "s_register_operand" "r")
9179 (match_operand:SI 2 "arm_add_operand" "rIL")])
9180 (match_operator:SI 6 "arm_comparison_operator"
9181 [(match_operand:SI 4 "s_register_operand" "r")
9182 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9183 (clobber (reg:CC CC_REGNUM))]
9185 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9188 "TARGET_32BIT && reload_completed
9189 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9194 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9195 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9197 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9199 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9202 [(set_attr "conds" "clob")
9203 (set_attr "length" "16")
9204 (set_attr "type" "multiple")]
9207 ; If the above pattern is followed by a CMP insn, then the compare is
9208 ; redundant, since we can rework the conditional instruction that follows.
9209 (define_insn_and_split "*and_scc_scc_cmp"
9210 [(set (match_operand 0 "dominant_cc_register" "")
9211 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9212 [(match_operand:SI 1 "s_register_operand" "r")
9213 (match_operand:SI 2 "arm_add_operand" "rIL")])
9214 (match_operator:SI 6 "arm_comparison_operator"
9215 [(match_operand:SI 4 "s_register_operand" "r")
9216 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9218 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9219 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9220 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9223 "TARGET_32BIT && reload_completed"
9227 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9228 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9230 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9232 [(set_attr "conds" "set")
9233 (set_attr "length" "16")
9234 (set_attr "type" "multiple")]
9237 ;; If there is no dominance in the comparison, then we can still save an
9238 ;; instruction in the AND case, since we can know that the second compare
9239 ;; need only zero the value if false (if true, then the value is already
9241 (define_insn_and_split "*and_scc_scc_nodom"
9242 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9243 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9244 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9245 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9246 (match_operator:SI 6 "arm_comparison_operator"
9247 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9248 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9249 (clobber (reg:CC CC_REGNUM))]
9251 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9254 "TARGET_32BIT && reload_completed"
9255 [(parallel [(set (match_dup 0)
9256 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9257 (clobber (reg:CC CC_REGNUM))])
9258 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9260 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9263 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9264 operands[4], operands[5]),
9266 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9268 [(set_attr "conds" "clob")
9269 (set_attr "length" "20")
9270 (set_attr "type" "multiple")]
9274 [(set (reg:CC_NOOV CC_REGNUM)
9275 (compare:CC_NOOV (ior:SI
9276 (and:SI (match_operand:SI 0 "s_register_operand" "")
9278 (match_operator:SI 1 "arm_comparison_operator"
9279 [(match_operand:SI 2 "s_register_operand" "")
9280 (match_operand:SI 3 "arm_add_operand" "")]))
9282 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9285 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9287 (set (reg:CC_NOOV CC_REGNUM)
9288 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9293 [(set (reg:CC_NOOV CC_REGNUM)
9294 (compare:CC_NOOV (ior:SI
9295 (match_operator:SI 1 "arm_comparison_operator"
9296 [(match_operand:SI 2 "s_register_operand" "")
9297 (match_operand:SI 3 "arm_add_operand" "")])
9298 (and:SI (match_operand:SI 0 "s_register_operand" "")
9301 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9304 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9306 (set (reg:CC_NOOV CC_REGNUM)
9307 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9310 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9312 (define_insn_and_split "*negscc"
9313 [(set (match_operand:SI 0 "s_register_operand" "=r")
9314 (neg:SI (match_operator 3 "arm_comparison_operator"
9315 [(match_operand:SI 1 "s_register_operand" "r")
9316 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9317 (clobber (reg:CC CC_REGNUM))]
9320 "&& reload_completed"
9323 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9325 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9327 /* Emit mov\\t%0, %1, asr #31 */
9328 emit_insn (gen_rtx_SET (operands[0],
9329 gen_rtx_ASHIFTRT (SImode,
9334 else if (GET_CODE (operands[3]) == NE)
9336 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9337 if (CONST_INT_P (operands[2]))
9338 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9339 GEN_INT (- INTVAL (operands[2]))));
9341 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9343 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9347 gen_rtx_SET (operands[0],
9353 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9354 emit_insn (gen_rtx_SET (cc_reg,
9355 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9356 enum rtx_code rc = GET_CODE (operands[3]);
9358 rc = reverse_condition (rc);
9359 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9364 gen_rtx_SET (operands[0], const0_rtx)));
9365 rc = GET_CODE (operands[3]);
9366 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9371 gen_rtx_SET (operands[0],
9377 [(set_attr "conds" "clob")
9378 (set_attr "length" "12")
9379 (set_attr "type" "multiple")]
9382 (define_insn_and_split "movcond_addsi"
9383 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9385 (match_operator 5 "comparison_operator"
9386 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9387 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9389 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9390 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9391 (clobber (reg:CC CC_REGNUM))]
9394 "&& reload_completed"
9395 [(set (reg:CC_NOOV CC_REGNUM)
9397 (plus:SI (match_dup 3)
9400 (set (match_dup 0) (match_dup 1))
9401 (cond_exec (match_dup 6)
9402 (set (match_dup 0) (match_dup 2)))]
9405 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9406 operands[3], operands[4]);
9407 enum rtx_code rc = GET_CODE (operands[5]);
9408 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9409 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9410 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9411 rc = reverse_condition (rc);
9413 std::swap (operands[1], operands[2]);
9415 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9418 [(set_attr "conds" "clob")
9419 (set_attr "enabled_for_depr_it" "no,yes,yes")
9420 (set_attr "type" "multiple")]
9423 (define_insn "movcond"
9424 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9426 (match_operator 5 "arm_comparison_operator"
9427 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9428 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9429 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9430 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9431 (clobber (reg:CC CC_REGNUM))]
9434 if (GET_CODE (operands[5]) == LT
9435 && (operands[4] == const0_rtx))
9437 if (which_alternative != 1 && REG_P (operands[1]))
9439 if (operands[2] == const0_rtx)
9440 return \"and\\t%0, %1, %3, asr #31\";
9441 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9443 else if (which_alternative != 0 && REG_P (operands[2]))
9445 if (operands[1] == const0_rtx)
9446 return \"bic\\t%0, %2, %3, asr #31\";
9447 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9449 /* The only case that falls through to here is when both ops 1 & 2
9453 if (GET_CODE (operands[5]) == GE
9454 && (operands[4] == const0_rtx))
9456 if (which_alternative != 1 && REG_P (operands[1]))
9458 if (operands[2] == const0_rtx)
9459 return \"bic\\t%0, %1, %3, asr #31\";
9460 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9462 else if (which_alternative != 0 && REG_P (operands[2]))
9464 if (operands[1] == const0_rtx)
9465 return \"and\\t%0, %2, %3, asr #31\";
9466 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9468 /* The only case that falls through to here is when both ops 1 & 2
9471 if (CONST_INT_P (operands[4])
9472 && !const_ok_for_arm (INTVAL (operands[4])))
9473 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9475 output_asm_insn (\"cmp\\t%3, %4\", operands);
9476 if (which_alternative != 0)
9477 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9478 if (which_alternative != 1)
9479 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9482 [(set_attr "conds" "clob")
9483 (set_attr "length" "8,8,12")
9484 (set_attr "type" "multiple")]
9487 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9489 (define_insn "*ifcompare_plus_move"
9490 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9491 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9492 [(match_operand:SI 4 "s_register_operand" "r,r")
9493 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9495 (match_operand:SI 2 "s_register_operand" "r,r")
9496 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9497 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9498 (clobber (reg:CC CC_REGNUM))]
9501 [(set_attr "conds" "clob")
9502 (set_attr "length" "8,12")
9503 (set_attr "type" "multiple")]
9506 (define_insn "*if_plus_move"
9507 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9509 (match_operator 4 "arm_comparison_operator"
9510 [(match_operand 5 "cc_register" "") (const_int 0)])
9512 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9513 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9514 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9518 sub%d4\\t%0, %2, #%n3
9519 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9520 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9521 [(set_attr "conds" "use")
9522 (set_attr "length" "4,4,8,8")
9523 (set_attr_alternative "type"
9524 [(if_then_else (match_operand 3 "const_int_operand" "")
9525 (const_string "alu_imm" )
9526 (const_string "alu_sreg"))
9527 (const_string "alu_imm")
9528 (const_string "multiple")
9529 (const_string "multiple")])]
9532 (define_insn "*ifcompare_move_plus"
9533 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9534 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9535 [(match_operand:SI 4 "s_register_operand" "r,r")
9536 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9537 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9539 (match_operand:SI 2 "s_register_operand" "r,r")
9540 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9541 (clobber (reg:CC CC_REGNUM))]
9544 [(set_attr "conds" "clob")
9545 (set_attr "length" "8,12")
9546 (set_attr "type" "multiple")]
9549 (define_insn "*if_move_plus"
9550 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9552 (match_operator 4 "arm_comparison_operator"
9553 [(match_operand 5 "cc_register" "") (const_int 0)])
9554 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9556 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9557 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9561 sub%D4\\t%0, %2, #%n3
9562 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9563 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9564 [(set_attr "conds" "use")
9565 (set_attr "length" "4,4,8,8")
9566 (set_attr_alternative "type"
9567 [(if_then_else (match_operand 3 "const_int_operand" "")
9568 (const_string "alu_imm" )
9569 (const_string "alu_sreg"))
9570 (const_string "alu_imm")
9571 (const_string "multiple")
9572 (const_string "multiple")])]
9575 (define_insn "*ifcompare_arith_arith"
9576 [(set (match_operand:SI 0 "s_register_operand" "=r")
9577 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9578 [(match_operand:SI 5 "s_register_operand" "r")
9579 (match_operand:SI 6 "arm_add_operand" "rIL")])
9580 (match_operator:SI 8 "shiftable_operator"
9581 [(match_operand:SI 1 "s_register_operand" "r")
9582 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9583 (match_operator:SI 7 "shiftable_operator"
9584 [(match_operand:SI 3 "s_register_operand" "r")
9585 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9586 (clobber (reg:CC CC_REGNUM))]
9589 [(set_attr "conds" "clob")
9590 (set_attr "length" "12")
9591 (set_attr "type" "multiple")]
9594 (define_insn "*if_arith_arith"
9595 [(set (match_operand:SI 0 "s_register_operand" "=r")
9596 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9597 [(match_operand 8 "cc_register" "") (const_int 0)])
9598 (match_operator:SI 6 "shiftable_operator"
9599 [(match_operand:SI 1 "s_register_operand" "r")
9600 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9601 (match_operator:SI 7 "shiftable_operator"
9602 [(match_operand:SI 3 "s_register_operand" "r")
9603 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9605 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9606 [(set_attr "conds" "use")
9607 (set_attr "length" "8")
9608 (set_attr "type" "multiple")]
9611 (define_insn "*ifcompare_arith_move"
9612 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9613 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9614 [(match_operand:SI 2 "s_register_operand" "r,r")
9615 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9616 (match_operator:SI 7 "shiftable_operator"
9617 [(match_operand:SI 4 "s_register_operand" "r,r")
9618 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9619 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9620 (clobber (reg:CC CC_REGNUM))]
9623 /* If we have an operation where (op x 0) is the identity operation and
9624 the conditional operator is LT or GE and we are comparing against zero and
9625 everything is in registers then we can do this in two instructions. */
9626 if (operands[3] == const0_rtx
9627 && GET_CODE (operands[7]) != AND
9628 && REG_P (operands[5])
9629 && REG_P (operands[1])
9630 && REGNO (operands[1]) == REGNO (operands[4])
9631 && REGNO (operands[4]) != REGNO (operands[0]))
9633 if (GET_CODE (operands[6]) == LT)
9634 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9635 else if (GET_CODE (operands[6]) == GE)
9636 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9638 if (CONST_INT_P (operands[3])
9639 && !const_ok_for_arm (INTVAL (operands[3])))
9640 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9642 output_asm_insn (\"cmp\\t%2, %3\", operands);
9643 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9644 if (which_alternative != 0)
9645 return \"mov%D6\\t%0, %1\";
9648 [(set_attr "conds" "clob")
9649 (set_attr "length" "8,12")
9650 (set_attr "type" "multiple")]
9653 (define_insn "*if_arith_move"
9654 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9655 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9656 [(match_operand 6 "cc_register" "") (const_int 0)])
9657 (match_operator:SI 5 "shiftable_operator"
9658 [(match_operand:SI 2 "s_register_operand" "r,r")
9659 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9660 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9664 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9665 [(set_attr "conds" "use")
9666 (set_attr "length" "4,8")
9667 (set_attr_alternative "type"
9668 [(if_then_else (match_operand 3 "const_int_operand" "")
9669 (const_string "alu_shift_imm" )
9670 (const_string "alu_shift_reg"))
9671 (const_string "multiple")])]
9674 (define_insn "*ifcompare_move_arith"
9675 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9676 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9677 [(match_operand:SI 4 "s_register_operand" "r,r")
9678 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9679 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9680 (match_operator:SI 7 "shiftable_operator"
9681 [(match_operand:SI 2 "s_register_operand" "r,r")
9682 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9683 (clobber (reg:CC CC_REGNUM))]
9686 /* If we have an operation where (op x 0) is the identity operation and
9687 the conditional operator is LT or GE and we are comparing against zero and
9688 everything is in registers then we can do this in two instructions */
9689 if (operands[5] == const0_rtx
9690 && GET_CODE (operands[7]) != AND
9691 && REG_P (operands[3])
9692 && REG_P (operands[1])
9693 && REGNO (operands[1]) == REGNO (operands[2])
9694 && REGNO (operands[2]) != REGNO (operands[0]))
9696 if (GET_CODE (operands[6]) == GE)
9697 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9698 else if (GET_CODE (operands[6]) == LT)
9699 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9702 if (CONST_INT_P (operands[5])
9703 && !const_ok_for_arm (INTVAL (operands[5])))
9704 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9706 output_asm_insn (\"cmp\\t%4, %5\", operands);
9708 if (which_alternative != 0)
9709 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9710 return \"%I7%D6\\t%0, %2, %3\";
9712 [(set_attr "conds" "clob")
9713 (set_attr "length" "8,12")
9714 (set_attr "type" "multiple")]
9717 (define_insn "*if_move_arith"
9718 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9720 (match_operator 4 "arm_comparison_operator"
9721 [(match_operand 6 "cc_register" "") (const_int 0)])
9722 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9723 (match_operator:SI 5 "shiftable_operator"
9724 [(match_operand:SI 2 "s_register_operand" "r,r")
9725 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9729 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9730 [(set_attr "conds" "use")
9731 (set_attr "length" "4,8")
9732 (set_attr_alternative "type"
9733 [(if_then_else (match_operand 3 "const_int_operand" "")
9734 (const_string "alu_shift_imm" )
9735 (const_string "alu_shift_reg"))
9736 (const_string "multiple")])]
9739 (define_insn "*ifcompare_move_not"
9740 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9742 (match_operator 5 "arm_comparison_operator"
9743 [(match_operand:SI 3 "s_register_operand" "r,r")
9744 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9745 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9747 (match_operand:SI 2 "s_register_operand" "r,r"))))
9748 (clobber (reg:CC CC_REGNUM))]
9751 [(set_attr "conds" "clob")
9752 (set_attr "length" "8,12")
9753 (set_attr "type" "multiple")]
9756 (define_insn "*if_move_not"
9757 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9759 (match_operator 4 "arm_comparison_operator"
9760 [(match_operand 3 "cc_register" "") (const_int 0)])
9761 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9762 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9766 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9767 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9768 [(set_attr "conds" "use")
9769 (set_attr "type" "mvn_reg")
9770 (set_attr "length" "4,8,8")
9771 (set_attr "type" "mvn_reg,multiple,multiple")]
9774 (define_insn "*ifcompare_not_move"
9775 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9777 (match_operator 5 "arm_comparison_operator"
9778 [(match_operand:SI 3 "s_register_operand" "r,r")
9779 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9781 (match_operand:SI 2 "s_register_operand" "r,r"))
9782 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9783 (clobber (reg:CC CC_REGNUM))]
9786 [(set_attr "conds" "clob")
9787 (set_attr "length" "8,12")
9788 (set_attr "type" "multiple")]
9791 (define_insn "*if_not_move"
9792 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9794 (match_operator 4 "arm_comparison_operator"
9795 [(match_operand 3 "cc_register" "") (const_int 0)])
9796 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9797 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9801 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9802 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9803 [(set_attr "conds" "use")
9804 (set_attr "type" "mvn_reg,multiple,multiple")
9805 (set_attr "length" "4,8,8")]
9808 (define_insn "*ifcompare_shift_move"
9809 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9811 (match_operator 6 "arm_comparison_operator"
9812 [(match_operand:SI 4 "s_register_operand" "r,r")
9813 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9814 (match_operator:SI 7 "shift_operator"
9815 [(match_operand:SI 2 "s_register_operand" "r,r")
9816 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9817 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9818 (clobber (reg:CC CC_REGNUM))]
9821 [(set_attr "conds" "clob")
9822 (set_attr "length" "8,12")
9823 (set_attr "type" "multiple")]
9826 (define_insn "*if_shift_move"
9827 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9829 (match_operator 5 "arm_comparison_operator"
9830 [(match_operand 6 "cc_register" "") (const_int 0)])
9831 (match_operator:SI 4 "shift_operator"
9832 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9833 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9834 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9838 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9839 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9840 [(set_attr "conds" "use")
9841 (set_attr "shift" "2")
9842 (set_attr "length" "4,8,8")
9843 (set_attr_alternative "type"
9844 [(if_then_else (match_operand 3 "const_int_operand" "")
9845 (const_string "mov_shift" )
9846 (const_string "mov_shift_reg"))
9847 (const_string "multiple")
9848 (const_string "multiple")])]
9851 (define_insn "*ifcompare_move_shift"
9852 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9854 (match_operator 6 "arm_comparison_operator"
9855 [(match_operand:SI 4 "s_register_operand" "r,r")
9856 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9857 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9858 (match_operator:SI 7 "shift_operator"
9859 [(match_operand:SI 2 "s_register_operand" "r,r")
9860 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9861 (clobber (reg:CC CC_REGNUM))]
9864 [(set_attr "conds" "clob")
9865 (set_attr "length" "8,12")
9866 (set_attr "type" "multiple")]
9869 (define_insn "*if_move_shift"
9870 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9872 (match_operator 5 "arm_comparison_operator"
9873 [(match_operand 6 "cc_register" "") (const_int 0)])
9874 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9875 (match_operator:SI 4 "shift_operator"
9876 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9877 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9881 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9882 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9883 [(set_attr "conds" "use")
9884 (set_attr "shift" "2")
9885 (set_attr "length" "4,8,8")
9886 (set_attr_alternative "type"
9887 [(if_then_else (match_operand 3 "const_int_operand" "")
9888 (const_string "mov_shift" )
9889 (const_string "mov_shift_reg"))
9890 (const_string "multiple")
9891 (const_string "multiple")])]
9894 (define_insn "*ifcompare_shift_shift"
9895 [(set (match_operand:SI 0 "s_register_operand" "=r")
9897 (match_operator 7 "arm_comparison_operator"
9898 [(match_operand:SI 5 "s_register_operand" "r")
9899 (match_operand:SI 6 "arm_add_operand" "rIL")])
9900 (match_operator:SI 8 "shift_operator"
9901 [(match_operand:SI 1 "s_register_operand" "r")
9902 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9903 (match_operator:SI 9 "shift_operator"
9904 [(match_operand:SI 3 "s_register_operand" "r")
9905 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9906 (clobber (reg:CC CC_REGNUM))]
9909 [(set_attr "conds" "clob")
9910 (set_attr "length" "12")
9911 (set_attr "type" "multiple")]
9914 (define_insn "*if_shift_shift"
9915 [(set (match_operand:SI 0 "s_register_operand" "=r")
9917 (match_operator 5 "arm_comparison_operator"
9918 [(match_operand 8 "cc_register" "") (const_int 0)])
9919 (match_operator:SI 6 "shift_operator"
9920 [(match_operand:SI 1 "s_register_operand" "r")
9921 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9922 (match_operator:SI 7 "shift_operator"
9923 [(match_operand:SI 3 "s_register_operand" "r")
9924 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9926 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9927 [(set_attr "conds" "use")
9928 (set_attr "shift" "1")
9929 (set_attr "length" "8")
9930 (set (attr "type") (if_then_else
9931 (and (match_operand 2 "const_int_operand" "")
9932 (match_operand 4 "const_int_operand" ""))
9933 (const_string "mov_shift")
9934 (const_string "mov_shift_reg")))]
9937 (define_insn "*ifcompare_not_arith"
9938 [(set (match_operand:SI 0 "s_register_operand" "=r")
9940 (match_operator 6 "arm_comparison_operator"
9941 [(match_operand:SI 4 "s_register_operand" "r")
9942 (match_operand:SI 5 "arm_add_operand" "rIL")])
9943 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9944 (match_operator:SI 7 "shiftable_operator"
9945 [(match_operand:SI 2 "s_register_operand" "r")
9946 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9947 (clobber (reg:CC CC_REGNUM))]
9950 [(set_attr "conds" "clob")
9951 (set_attr "length" "12")
9952 (set_attr "type" "multiple")]
9955 (define_insn "*if_not_arith"
9956 [(set (match_operand:SI 0 "s_register_operand" "=r")
9958 (match_operator 5 "arm_comparison_operator"
9959 [(match_operand 4 "cc_register" "") (const_int 0)])
9960 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9961 (match_operator:SI 6 "shiftable_operator"
9962 [(match_operand:SI 2 "s_register_operand" "r")
9963 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9965 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9966 [(set_attr "conds" "use")
9967 (set_attr "type" "mvn_reg")
9968 (set_attr "length" "8")]
9971 (define_insn "*ifcompare_arith_not"
9972 [(set (match_operand:SI 0 "s_register_operand" "=r")
9974 (match_operator 6 "arm_comparison_operator"
9975 [(match_operand:SI 4 "s_register_operand" "r")
9976 (match_operand:SI 5 "arm_add_operand" "rIL")])
9977 (match_operator:SI 7 "shiftable_operator"
9978 [(match_operand:SI 2 "s_register_operand" "r")
9979 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9980 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9981 (clobber (reg:CC CC_REGNUM))]
9984 [(set_attr "conds" "clob")
9985 (set_attr "length" "12")
9986 (set_attr "type" "multiple")]
9989 (define_insn "*if_arith_not"
9990 [(set (match_operand:SI 0 "s_register_operand" "=r")
9992 (match_operator 5 "arm_comparison_operator"
9993 [(match_operand 4 "cc_register" "") (const_int 0)])
9994 (match_operator:SI 6 "shiftable_operator"
9995 [(match_operand:SI 2 "s_register_operand" "r")
9996 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9997 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9999 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10000 [(set_attr "conds" "use")
10001 (set_attr "type" "multiple")
10002 (set_attr "length" "8")]
10005 (define_insn "*ifcompare_neg_move"
10006 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10008 (match_operator 5 "arm_comparison_operator"
10009 [(match_operand:SI 3 "s_register_operand" "r,r")
10010 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10011 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10012 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10013 (clobber (reg:CC CC_REGNUM))]
10016 [(set_attr "conds" "clob")
10017 (set_attr "length" "8,12")
10018 (set_attr "type" "multiple")]
10021 (define_insn_and_split "*if_neg_move"
10022 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10024 (match_operator 4 "arm_comparison_operator"
10025 [(match_operand 3 "cc_register" "") (const_int 0)])
10026 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10027 (match_operand:SI 1 "s_register_operand" "0,0")))]
10030 "&& reload_completed"
10031 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10032 (set (match_dup 0) (neg:SI (match_dup 2))))]
10034 [(set_attr "conds" "use")
10035 (set_attr "length" "4")
10036 (set_attr "arch" "t2,32")
10037 (set_attr "enabled_for_depr_it" "yes,no")
10038 (set_attr "type" "logic_shift_imm")]
10041 (define_insn "*ifcompare_move_neg"
10042 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10044 (match_operator 5 "arm_comparison_operator"
10045 [(match_operand:SI 3 "s_register_operand" "r,r")
10046 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10047 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10048 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10049 (clobber (reg:CC CC_REGNUM))]
10052 [(set_attr "conds" "clob")
10053 (set_attr "length" "8,12")
10054 (set_attr "type" "multiple")]
10057 (define_insn_and_split "*if_move_neg"
10058 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10060 (match_operator 4 "arm_comparison_operator"
10061 [(match_operand 3 "cc_register" "") (const_int 0)])
10062 (match_operand:SI 1 "s_register_operand" "0,0")
10063 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10066 "&& reload_completed"
10067 [(cond_exec (match_dup 5)
10068 (set (match_dup 0) (neg:SI (match_dup 2))))]
10070 machine_mode mode = GET_MODE (operands[3]);
10071 rtx_code rc = GET_CODE (operands[4]);
10073 if (mode == CCFPmode || mode == CCFPEmode)
10074 rc = reverse_condition_maybe_unordered (rc);
10076 rc = reverse_condition (rc);
10078 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10080 [(set_attr "conds" "use")
10081 (set_attr "length" "4")
10082 (set_attr "arch" "t2,32")
10083 (set_attr "enabled_for_depr_it" "yes,no")
10084 (set_attr "type" "logic_shift_imm")]
10087 (define_insn "*arith_adjacentmem"
10088 [(set (match_operand:SI 0 "s_register_operand" "=r")
10089 (match_operator:SI 1 "shiftable_operator"
10090 [(match_operand:SI 2 "memory_operand" "m")
10091 (match_operand:SI 3 "memory_operand" "m")]))
10092 (clobber (match_scratch:SI 4 "=r"))]
10093 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10099 HOST_WIDE_INT val1 = 0, val2 = 0;
10101 if (REGNO (operands[0]) > REGNO (operands[4]))
10103 ldm[1] = operands[4];
10104 ldm[2] = operands[0];
10108 ldm[1] = operands[0];
10109 ldm[2] = operands[4];
10112 base_reg = XEXP (operands[2], 0);
10114 if (!REG_P (base_reg))
10116 val1 = INTVAL (XEXP (base_reg, 1));
10117 base_reg = XEXP (base_reg, 0);
10120 if (!REG_P (XEXP (operands[3], 0)))
10121 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10123 arith[0] = operands[0];
10124 arith[3] = operands[1];
10138 if (val1 !=0 && val2 != 0)
10142 if (val1 == 4 || val2 == 4)
10143 /* Other val must be 8, since we know they are adjacent and neither
10145 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10146 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10148 ldm[0] = ops[0] = operands[4];
10150 ops[2] = GEN_INT (val1);
10151 output_add_immediate (ops);
10153 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10155 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10159 /* Offset is out of range for a single add, so use two ldr. */
10162 ops[2] = GEN_INT (val1);
10163 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10165 ops[2] = GEN_INT (val2);
10166 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10169 else if (val1 != 0)
10172 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10174 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10179 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10181 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10183 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10186 [(set_attr "length" "12")
10187 (set_attr "predicable" "yes")
10188 (set_attr "type" "load1")]
10191 ; This pattern is never tried by combine, so do it as a peephole
10194 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10195 (match_operand:SI 1 "arm_general_register_operand" ""))
10196 (set (reg:CC CC_REGNUM)
10197 (compare:CC (match_dup 1) (const_int 0)))]
10199 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10200 (set (match_dup 0) (match_dup 1))])]
10205 [(set (match_operand:SI 0 "s_register_operand" "")
10206 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10208 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10209 [(match_operand:SI 3 "s_register_operand" "")
10210 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10211 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10213 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10214 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10219 ;; This split can be used because CC_Z mode implies that the following
10220 ;; branch will be an equality, or an unsigned inequality, so the sign
10221 ;; extension is not needed.
10224 [(set (reg:CC_Z CC_REGNUM)
10226 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10228 (match_operand 1 "const_int_operand" "")))
10229 (clobber (match_scratch:SI 2 ""))]
10231 && ((UINTVAL (operands[1]))
10232 == ((UINTVAL (operands[1])) >> 24) << 24)"
10233 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10234 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10236 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10239 ;; ??? Check the patterns above for Thumb-2 usefulness
10241 (define_expand "prologue"
10242 [(clobber (const_int 0))]
10245 arm_expand_prologue ();
10247 thumb1_expand_prologue ();
10252 (define_expand "epilogue"
10253 [(clobber (const_int 0))]
10256 if (crtl->calls_eh_return)
10257 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10260 thumb1_expand_epilogue ();
10261 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10262 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10264 else if (HAVE_return)
10266 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10267 no need for explicit testing again. */
10268 emit_jump_insn (gen_return ());
10270 else if (TARGET_32BIT)
10272 arm_expand_epilogue (true);
10278 ;; Note - although unspec_volatile's USE all hard registers,
10279 ;; USEs are ignored after relaod has completed. Thus we need
10280 ;; to add an unspec of the link register to ensure that flow
10281 ;; does not think that it is unused by the sibcall branch that
10282 ;; will replace the standard function epilogue.
10283 (define_expand "sibcall_epilogue"
10284 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10285 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10288 arm_expand_epilogue (false);
10293 (define_expand "eh_epilogue"
10294 [(use (match_operand:SI 0 "register_operand" ""))
10295 (use (match_operand:SI 1 "register_operand" ""))
10296 (use (match_operand:SI 2 "register_operand" ""))]
10300 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10301 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10303 rtx ra = gen_rtx_REG (Pmode, 2);
10305 emit_move_insn (ra, operands[2]);
10308 /* This is a hack -- we may have crystalized the function type too
10310 cfun->machine->func_type = 0;
10314 ;; This split is only used during output to reduce the number of patterns
10315 ;; that need assembler instructions adding to them. We allowed the setting
10316 ;; of the conditions to be implicit during rtl generation so that
10317 ;; the conditional compare patterns would work. However this conflicts to
10318 ;; some extent with the conditional data operations, so we have to split them
10321 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10322 ;; conditional execution sufficient?
10325 [(set (match_operand:SI 0 "s_register_operand" "")
10326 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10327 [(match_operand 2 "" "") (match_operand 3 "" "")])
10329 (match_operand 4 "" "")))
10330 (clobber (reg:CC CC_REGNUM))]
10331 "TARGET_ARM && reload_completed"
10332 [(set (match_dup 5) (match_dup 6))
10333 (cond_exec (match_dup 7)
10334 (set (match_dup 0) (match_dup 4)))]
10337 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10338 operands[2], operands[3]);
10339 enum rtx_code rc = GET_CODE (operands[1]);
10341 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10342 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10343 if (mode == CCFPmode || mode == CCFPEmode)
10344 rc = reverse_condition_maybe_unordered (rc);
10346 rc = reverse_condition (rc);
10348 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10353 [(set (match_operand:SI 0 "s_register_operand" "")
10354 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10355 [(match_operand 2 "" "") (match_operand 3 "" "")])
10356 (match_operand 4 "" "")
10358 (clobber (reg:CC CC_REGNUM))]
10359 "TARGET_ARM && reload_completed"
10360 [(set (match_dup 5) (match_dup 6))
10361 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10362 (set (match_dup 0) (match_dup 4)))]
10365 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10366 operands[2], operands[3]);
10368 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10369 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10374 [(set (match_operand:SI 0 "s_register_operand" "")
10375 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10376 [(match_operand 2 "" "") (match_operand 3 "" "")])
10377 (match_operand 4 "" "")
10378 (match_operand 5 "" "")))
10379 (clobber (reg:CC CC_REGNUM))]
10380 "TARGET_ARM && reload_completed"
10381 [(set (match_dup 6) (match_dup 7))
10382 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10383 (set (match_dup 0) (match_dup 4)))
10384 (cond_exec (match_dup 8)
10385 (set (match_dup 0) (match_dup 5)))]
10388 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10389 operands[2], operands[3]);
10390 enum rtx_code rc = GET_CODE (operands[1]);
10392 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10393 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10394 if (mode == CCFPmode || mode == CCFPEmode)
10395 rc = reverse_condition_maybe_unordered (rc);
10397 rc = reverse_condition (rc);
10399 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10404 [(set (match_operand:SI 0 "s_register_operand" "")
10405 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10406 [(match_operand:SI 2 "s_register_operand" "")
10407 (match_operand:SI 3 "arm_add_operand" "")])
10408 (match_operand:SI 4 "arm_rhs_operand" "")
10410 (match_operand:SI 5 "s_register_operand" ""))))
10411 (clobber (reg:CC CC_REGNUM))]
10412 "TARGET_ARM && reload_completed"
10413 [(set (match_dup 6) (match_dup 7))
10414 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10415 (set (match_dup 0) (match_dup 4)))
10416 (cond_exec (match_dup 8)
10417 (set (match_dup 0) (not:SI (match_dup 5))))]
10420 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10421 operands[2], operands[3]);
10422 enum rtx_code rc = GET_CODE (operands[1]);
10424 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10425 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10426 if (mode == CCFPmode || mode == CCFPEmode)
10427 rc = reverse_condition_maybe_unordered (rc);
10429 rc = reverse_condition (rc);
10431 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10435 (define_insn "*cond_move_not"
10436 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10437 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10438 [(match_operand 3 "cc_register" "") (const_int 0)])
10439 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10441 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10445 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10446 [(set_attr "conds" "use")
10447 (set_attr "type" "mvn_reg,multiple")
10448 (set_attr "length" "4,8")]
10451 ;; The next two patterns occur when an AND operation is followed by a
10452 ;; scc insn sequence
10454 (define_insn "*sign_extract_onebit"
10455 [(set (match_operand:SI 0 "s_register_operand" "=r")
10456 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10458 (match_operand:SI 2 "const_int_operand" "n")))
10459 (clobber (reg:CC CC_REGNUM))]
10462 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10463 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10464 return \"mvnne\\t%0, #0\";
10466 [(set_attr "conds" "clob")
10467 (set_attr "length" "8")
10468 (set_attr "type" "multiple")]
10471 (define_insn "*not_signextract_onebit"
10472 [(set (match_operand:SI 0 "s_register_operand" "=r")
10474 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10476 (match_operand:SI 2 "const_int_operand" "n"))))
10477 (clobber (reg:CC CC_REGNUM))]
10480 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10481 output_asm_insn (\"tst\\t%1, %2\", operands);
10482 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10483 return \"movne\\t%0, #0\";
10485 [(set_attr "conds" "clob")
10486 (set_attr "length" "12")
10487 (set_attr "type" "multiple")]
10489 ;; ??? The above patterns need auditing for Thumb-2
10491 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10492 ;; expressions. For simplicity, the first register is also in the unspec
10494 ;; To avoid the usage of GNU extension, the length attribute is computed
10495 ;; in a C function arm_attr_length_push_multi.
10496 (define_insn "*push_multi"
10497 [(match_parallel 2 "multi_register_push"
10498 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10499 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10500 UNSPEC_PUSH_MULT))])]
10504 int num_saves = XVECLEN (operands[2], 0);
10506 /* For the StrongARM at least it is faster to
10507 use STR to store only a single register.
10508 In Thumb mode always use push, and the assembler will pick
10509 something appropriate. */
10510 if (num_saves == 1 && TARGET_ARM)
10511 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10518 strcpy (pattern, \"push%?\\t{%1\");
10520 strcpy (pattern, \"push\\t{%1\");
10522 for (i = 1; i < num_saves; i++)
10524 strcat (pattern, \", %|\");
10526 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10529 strcat (pattern, \"}\");
10530 output_asm_insn (pattern, operands);
10535 [(set_attr "type" "store4")
10536 (set (attr "length")
10537 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10540 (define_insn "stack_tie"
10541 [(set (mem:BLK (scratch))
10542 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10543 (match_operand:SI 1 "s_register_operand" "rk")]
10547 [(set_attr "length" "0")
10548 (set_attr "type" "block")]
10551 ;; Pop (as used in epilogue RTL)
10553 (define_insn "*load_multiple_with_writeback"
10554 [(match_parallel 0 "load_multiple_operation"
10555 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10556 (plus:SI (match_dup 1)
10557 (match_operand:SI 2 "const_int_I_operand" "I")))
10558 (set (match_operand:SI 3 "s_register_operand" "=rk")
10559 (mem:SI (match_dup 1)))
10561 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10564 arm_output_multireg_pop (operands, /*return_pc=*/false,
10565 /*cond=*/const_true_rtx,
10571 [(set_attr "type" "load4")
10572 (set_attr "predicable" "yes")
10573 (set (attr "length")
10574 (symbol_ref "arm_attr_length_pop_multi (operands,
10575 /*return_pc=*/false,
10576 /*write_back_p=*/true)"))]
10579 ;; Pop with return (as used in epilogue RTL)
10581 ;; This instruction is generated when the registers are popped at the end of
10582 ;; epilogue. Here, instead of popping the value into LR and then generating
10583 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10585 (define_insn "*pop_multiple_with_writeback_and_return"
10586 [(match_parallel 0 "pop_multiple_return"
10588 (set (match_operand:SI 1 "s_register_operand" "+rk")
10589 (plus:SI (match_dup 1)
10590 (match_operand:SI 2 "const_int_I_operand" "I")))
10591 (set (match_operand:SI 3 "s_register_operand" "=rk")
10592 (mem:SI (match_dup 1)))
10594 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10597 arm_output_multireg_pop (operands, /*return_pc=*/true,
10598 /*cond=*/const_true_rtx,
10604 [(set_attr "type" "load4")
10605 (set_attr "predicable" "yes")
10606 (set (attr "length")
10607 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10608 /*write_back_p=*/true)"))]
10611 (define_insn "*pop_multiple_with_return"
10612 [(match_parallel 0 "pop_multiple_return"
10614 (set (match_operand:SI 2 "s_register_operand" "=rk")
10615 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10617 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10620 arm_output_multireg_pop (operands, /*return_pc=*/true,
10621 /*cond=*/const_true_rtx,
10627 [(set_attr "type" "load4")
10628 (set_attr "predicable" "yes")
10629 (set (attr "length")
10630 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10631 /*write_back_p=*/false)"))]
10634 ;; Load into PC and return
10635 (define_insn "*ldr_with_return"
10637 (set (reg:SI PC_REGNUM)
10638 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10639 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10640 "ldr%?\t%|pc, [%0], #4"
10641 [(set_attr "type" "load1")
10642 (set_attr "predicable" "yes")]
10644 ;; Pop for floating point registers (as used in epilogue RTL)
10645 (define_insn "*vfp_pop_multiple_with_writeback"
10646 [(match_parallel 0 "pop_multiple_fp"
10647 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10648 (plus:SI (match_dup 1)
10649 (match_operand:SI 2 "const_int_I_operand" "I")))
10650 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10651 (mem:DF (match_dup 1)))])]
10652 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10655 int num_regs = XVECLEN (operands[0], 0);
10658 strcpy (pattern, \"vldm\\t\");
10659 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10660 strcat (pattern, \"!, {\");
10661 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10662 strcat (pattern, \"%P0\");
10663 if ((num_regs - 1) > 1)
10665 strcat (pattern, \"-%P1\");
10666 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10669 strcat (pattern, \"}\");
10670 output_asm_insn (pattern, op_list);
10674 [(set_attr "type" "load4")
10675 (set_attr "conds" "unconditional")
10676 (set_attr "predicable" "no")]
10679 ;; Special patterns for dealing with the constant pool
10681 (define_insn "align_4"
10682 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10685 assemble_align (32);
10688 [(set_attr "type" "no_insn")]
10691 (define_insn "align_8"
10692 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10695 assemble_align (64);
10698 [(set_attr "type" "no_insn")]
10701 (define_insn "consttable_end"
10702 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10705 making_const_table = FALSE;
10708 [(set_attr "type" "no_insn")]
10711 (define_insn "consttable_1"
10712 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10715 making_const_table = TRUE;
10716 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10717 assemble_zeros (3);
10720 [(set_attr "length" "4")
10721 (set_attr "type" "no_insn")]
10724 (define_insn "consttable_2"
10725 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10729 rtx x = operands[0];
10730 making_const_table = TRUE;
10731 switch (GET_MODE_CLASS (GET_MODE (x)))
10734 arm_emit_fp16_const (x);
10737 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10738 assemble_zeros (2);
10743 [(set_attr "length" "4")
10744 (set_attr "type" "no_insn")]
10747 (define_insn "consttable_4"
10748 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10752 rtx x = operands[0];
10753 making_const_table = TRUE;
10754 switch (GET_MODE_CLASS (GET_MODE (x)))
10757 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
10761 /* XXX: Sometimes gcc does something really dumb and ends up with
10762 a HIGH in a constant pool entry, usually because it's trying to
10763 load into a VFP register. We know this will always be used in
10764 combination with a LO_SUM which ignores the high bits, so just
10765 strip off the HIGH. */
10766 if (GET_CODE (x) == HIGH)
10768 assemble_integer (x, 4, BITS_PER_WORD, 1);
10769 mark_symbol_refs_as_used (x);
10774 [(set_attr "length" "4")
10775 (set_attr "type" "no_insn")]
10778 (define_insn "consttable_8"
10779 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10783 making_const_table = TRUE;
10784 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10787 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10788 GET_MODE (operands[0]), BITS_PER_WORD);
10791 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10796 [(set_attr "length" "8")
10797 (set_attr "type" "no_insn")]
10800 (define_insn "consttable_16"
10801 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10805 making_const_table = TRUE;
10806 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10809 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10810 GET_MODE (operands[0]), BITS_PER_WORD);
10813 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10818 [(set_attr "length" "16")
10819 (set_attr "type" "no_insn")]
10822 ;; V5 Instructions,
10824 (define_insn "clzsi2"
10825 [(set (match_operand:SI 0 "s_register_operand" "=r")
10826 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10827 "TARGET_32BIT && arm_arch5"
10829 [(set_attr "predicable" "yes")
10830 (set_attr "predicable_short_it" "no")
10831 (set_attr "type" "clz")])
10833 (define_insn "rbitsi2"
10834 [(set (match_operand:SI 0 "s_register_operand" "=r")
10835 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10836 "TARGET_32BIT && arm_arch_thumb2"
10838 [(set_attr "predicable" "yes")
10839 (set_attr "predicable_short_it" "no")
10840 (set_attr "type" "clz")])
10842 ;; Keep this as a CTZ expression until after reload and then split
10843 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
10844 ;; to fold with any other expression.
10846 (define_insn_and_split "ctzsi2"
10847 [(set (match_operand:SI 0 "s_register_operand" "=r")
10848 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10849 "TARGET_32BIT && arm_arch_thumb2"
10851 "&& reload_completed"
10854 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
10855 emit_insn (gen_clzsi2 (operands[0], operands[0]));
10859 ;; V5E instructions.
10861 (define_insn "prefetch"
10862 [(prefetch (match_operand:SI 0 "address_operand" "p")
10863 (match_operand:SI 1 "" "")
10864 (match_operand:SI 2 "" ""))]
10865 "TARGET_32BIT && arm_arch5e"
10867 [(set_attr "type" "load1")]
10870 ;; General predication pattern
10873 [(match_operator 0 "arm_comparison_operator"
10874 [(match_operand 1 "cc_register" "")
10877 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
10879 [(set_attr "predicated" "yes")]
10882 (define_insn "force_register_use"
10883 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10886 [(set_attr "length" "0")
10887 (set_attr "type" "no_insn")]
10891 ;; Patterns for exception handling
10893 (define_expand "eh_return"
10894 [(use (match_operand 0 "general_operand" ""))]
10899 emit_insn (gen_arm_eh_return (operands[0]));
10901 emit_insn (gen_thumb_eh_return (operands[0]));
10906 ;; We can't expand this before we know where the link register is stored.
10907 (define_insn_and_split "arm_eh_return"
10908 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10910 (clobber (match_scratch:SI 1 "=&r"))]
10913 "&& reload_completed"
10917 arm_set_return_address (operands[0], operands[1]);
10925 (define_insn "load_tp_hard"
10926 [(set (match_operand:SI 0 "register_operand" "=r")
10927 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10929 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
10930 [(set_attr "predicable" "yes")
10931 (set_attr "type" "mrs")]
10934 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
10935 (define_insn "load_tp_soft"
10936 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10937 (clobber (reg:SI LR_REGNUM))
10938 (clobber (reg:SI IP_REGNUM))
10939 (clobber (reg:CC CC_REGNUM))]
10941 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
10942 [(set_attr "conds" "clob")
10943 (set_attr "type" "branch")]
10946 ;; tls descriptor call
10947 (define_insn "tlscall"
10948 [(set (reg:SI R0_REGNUM)
10949 (unspec:SI [(reg:SI R0_REGNUM)
10950 (match_operand:SI 0 "" "X")
10951 (match_operand 1 "" "")] UNSPEC_TLS))
10952 (clobber (reg:SI R1_REGNUM))
10953 (clobber (reg:SI LR_REGNUM))
10954 (clobber (reg:SI CC_REGNUM))]
10957 targetm.asm_out.internal_label (asm_out_file, "LPIC",
10958 INTVAL (operands[1]));
10959 return "bl\\t%c0(tlscall)";
10961 [(set_attr "conds" "clob")
10962 (set_attr "length" "4")
10963 (set_attr "type" "branch")]
10966 ;; For thread pointer builtin
10967 (define_expand "get_thread_pointersi"
10968 [(match_operand:SI 0 "s_register_operand" "=r")]
10972 arm_load_tp (operands[0]);
10978 ;; We only care about the lower 16 bits of the constant
10979 ;; being inserted into the upper 16 bits of the register.
10980 (define_insn "*arm_movtas_ze"
10981 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
10984 (match_operand:SI 1 "const_int_operand" ""))]
10989 [(set_attr "arch" "32,v8mb")
10990 (set_attr "predicable" "yes")
10991 (set_attr "predicable_short_it" "no")
10992 (set_attr "length" "4")
10993 (set_attr "type" "alu_sreg")]
10996 (define_insn "*arm_rev"
10997 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10998 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11004 [(set_attr "arch" "t1,t2,32")
11005 (set_attr "length" "2,2,4")
11006 (set_attr "predicable" "no,yes,yes")
11007 (set_attr "predicable_short_it" "no")
11008 (set_attr "type" "rev")]
11011 (define_expand "arm_legacy_rev"
11012 [(set (match_operand:SI 2 "s_register_operand" "")
11013 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11017 (lshiftrt:SI (match_dup 2)
11019 (set (match_operand:SI 3 "s_register_operand" "")
11020 (rotatert:SI (match_dup 1)
11023 (and:SI (match_dup 2)
11024 (const_int -65281)))
11025 (set (match_operand:SI 0 "s_register_operand" "")
11026 (xor:SI (match_dup 3)
11032 ;; Reuse temporaries to keep register pressure down.
11033 (define_expand "thumb_legacy_rev"
11034 [(set (match_operand:SI 2 "s_register_operand" "")
11035 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11037 (set (match_operand:SI 3 "s_register_operand" "")
11038 (lshiftrt:SI (match_dup 1)
11041 (ior:SI (match_dup 3)
11043 (set (match_operand:SI 4 "s_register_operand" "")
11045 (set (match_operand:SI 5 "s_register_operand" "")
11046 (rotatert:SI (match_dup 1)
11049 (ashift:SI (match_dup 5)
11052 (lshiftrt:SI (match_dup 5)
11055 (ior:SI (match_dup 5)
11058 (rotatert:SI (match_dup 5)
11060 (set (match_operand:SI 0 "s_register_operand" "")
11061 (ior:SI (match_dup 5)
11067 ;; ARM-specific expansion of signed mod by power of 2
11068 ;; using conditional negate.
11069 ;; For r0 % n where n is a power of 2 produce:
11071 ;; and r0, r0, #(n - 1)
11072 ;; and r1, r1, #(n - 1)
11073 ;; rsbpl r0, r1, #0
11075 (define_expand "modsi3"
11076 [(match_operand:SI 0 "register_operand" "")
11077 (match_operand:SI 1 "register_operand" "")
11078 (match_operand:SI 2 "const_int_operand" "")]
11081 HOST_WIDE_INT val = INTVAL (operands[2]);
11084 || exact_log2 (val) <= 0)
11087 rtx mask = GEN_INT (val - 1);
11089 /* In the special case of x0 % 2 we can do the even shorter:
11092 rsblt r0, r0, #0. */
11096 rtx cc_reg = arm_gen_compare_reg (LT,
11097 operands[1], const0_rtx, NULL_RTX);
11098 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11099 rtx masked = gen_reg_rtx (SImode);
11101 emit_insn (gen_andsi3 (masked, operands[1], mask));
11102 emit_move_insn (operands[0],
11103 gen_rtx_IF_THEN_ELSE (SImode, cond,
11104 gen_rtx_NEG (SImode,
11110 rtx neg_op = gen_reg_rtx (SImode);
11111 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11114 /* Extract the condition register and mode. */
11115 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11116 rtx cc_reg = SET_DEST (cmp);
11117 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11119 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11121 rtx masked_neg = gen_reg_rtx (SImode);
11122 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11124 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11125 during expand does not always work. Do an IF_THEN_ELSE instead. */
11126 emit_move_insn (operands[0],
11127 gen_rtx_IF_THEN_ELSE (SImode, cond,
11128 gen_rtx_NEG (SImode, masked_neg),
11136 (define_expand "bswapsi2"
11137 [(set (match_operand:SI 0 "s_register_operand" "=r")
11138 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11139 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11143 rtx op2 = gen_reg_rtx (SImode);
11144 rtx op3 = gen_reg_rtx (SImode);
11148 rtx op4 = gen_reg_rtx (SImode);
11149 rtx op5 = gen_reg_rtx (SImode);
11151 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11152 op2, op3, op4, op5));
11156 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11165 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11166 ;; and unsigned variants, respectively. For rev16, expose
11167 ;; byte-swapping in the lower 16 bits only.
11168 (define_insn "*arm_revsh"
11169 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11170 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11176 [(set_attr "arch" "t1,t2,32")
11177 (set_attr "length" "2,2,4")
11178 (set_attr "type" "rev")]
11181 (define_insn "*arm_rev16"
11182 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11183 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11189 [(set_attr "arch" "t1,t2,32")
11190 (set_attr "length" "2,2,4")
11191 (set_attr "type" "rev")]
11194 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11195 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11196 ;; each valid permutation.
11198 (define_insn "arm_rev16si2"
11199 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11200 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11202 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11203 (and:SI (lshiftrt:SI (match_dup 1)
11205 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11207 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11208 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11210 [(set_attr "arch" "t1,t2,32")
11211 (set_attr "length" "2,2,4")
11212 (set_attr "type" "rev")]
11215 (define_insn "arm_rev16si2_alt"
11216 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11217 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11219 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11220 (and:SI (ashift:SI (match_dup 1)
11222 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11224 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11225 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11227 [(set_attr "arch" "t1,t2,32")
11228 (set_attr "length" "2,2,4")
11229 (set_attr "type" "rev")]
11232 (define_expand "bswaphi2"
11233 [(set (match_operand:HI 0 "s_register_operand" "=r")
11234 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11239 ;; Patterns for LDRD/STRD in Thumb2 mode
11241 (define_insn "*thumb2_ldrd"
11242 [(set (match_operand:SI 0 "s_register_operand" "=r")
11243 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11244 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11245 (set (match_operand:SI 3 "s_register_operand" "=r")
11246 (mem:SI (plus:SI (match_dup 1)
11247 (match_operand:SI 4 "const_int_operand" ""))))]
11248 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11249 && current_tune->prefer_ldrd_strd
11250 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11251 && (operands_ok_ldrd_strd (operands[0], operands[3],
11252 operands[1], INTVAL (operands[2]),
11254 "ldrd%?\t%0, %3, [%1, %2]"
11255 [(set_attr "type" "load2")
11256 (set_attr "predicable" "yes")
11257 (set_attr "predicable_short_it" "no")])
11259 (define_insn "*thumb2_ldrd_base"
11260 [(set (match_operand:SI 0 "s_register_operand" "=r")
11261 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11262 (set (match_operand:SI 2 "s_register_operand" "=r")
11263 (mem:SI (plus:SI (match_dup 1)
11265 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11266 && current_tune->prefer_ldrd_strd
11267 && (operands_ok_ldrd_strd (operands[0], operands[2],
11268 operands[1], 0, false, true))"
11269 "ldrd%?\t%0, %2, [%1]"
11270 [(set_attr "type" "load2")
11271 (set_attr "predicable" "yes")
11272 (set_attr "predicable_short_it" "no")])
11274 (define_insn "*thumb2_ldrd_base_neg"
11275 [(set (match_operand:SI 0 "s_register_operand" "=r")
11276 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11278 (set (match_operand:SI 2 "s_register_operand" "=r")
11279 (mem:SI (match_dup 1)))]
11280 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11281 && current_tune->prefer_ldrd_strd
11282 && (operands_ok_ldrd_strd (operands[0], operands[2],
11283 operands[1], -4, false, true))"
11284 "ldrd%?\t%0, %2, [%1, #-4]"
11285 [(set_attr "type" "load2")
11286 (set_attr "predicable" "yes")
11287 (set_attr "predicable_short_it" "no")])
11289 (define_insn "*thumb2_strd"
11290 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11291 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11292 (match_operand:SI 2 "s_register_operand" "r"))
11293 (set (mem:SI (plus:SI (match_dup 0)
11294 (match_operand:SI 3 "const_int_operand" "")))
11295 (match_operand:SI 4 "s_register_operand" "r"))]
11296 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11297 && current_tune->prefer_ldrd_strd
11298 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11299 && (operands_ok_ldrd_strd (operands[2], operands[4],
11300 operands[0], INTVAL (operands[1]),
11302 "strd%?\t%2, %4, [%0, %1]"
11303 [(set_attr "type" "store2")
11304 (set_attr "predicable" "yes")
11305 (set_attr "predicable_short_it" "no")])
11307 (define_insn "*thumb2_strd_base"
11308 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11309 (match_operand:SI 1 "s_register_operand" "r"))
11310 (set (mem:SI (plus:SI (match_dup 0)
11312 (match_operand:SI 2 "s_register_operand" "r"))]
11313 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11314 && current_tune->prefer_ldrd_strd
11315 && (operands_ok_ldrd_strd (operands[1], operands[2],
11316 operands[0], 0, false, false))"
11317 "strd%?\t%1, %2, [%0]"
11318 [(set_attr "type" "store2")
11319 (set_attr "predicable" "yes")
11320 (set_attr "predicable_short_it" "no")])
11322 (define_insn "*thumb2_strd_base_neg"
11323 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11325 (match_operand:SI 1 "s_register_operand" "r"))
11326 (set (mem:SI (match_dup 0))
11327 (match_operand:SI 2 "s_register_operand" "r"))]
11328 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11329 && current_tune->prefer_ldrd_strd
11330 && (operands_ok_ldrd_strd (operands[1], operands[2],
11331 operands[0], -4, false, false))"
11332 "strd%?\t%1, %2, [%0, #-4]"
11333 [(set_attr "type" "store2")
11334 (set_attr "predicable" "yes")
11335 (set_attr "predicable_short_it" "no")])
11337 ;; ARMv8 CRC32 instructions.
11338 (define_insn "<crc_variant>"
11339 [(set (match_operand:SI 0 "s_register_operand" "=r")
11340 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11341 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11344 "<crc_variant>\\t%0, %1, %2"
11345 [(set_attr "type" "crc")
11346 (set_attr "conds" "unconditional")]
11349 ;; Load the load/store double peephole optimizations.
11350 (include "ldrdstrd.md")
11352 ;; Load the load/store multiple patterns
11353 (include "ldmstm.md")
11355 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11356 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11357 (define_insn "*load_multiple"
11358 [(match_parallel 0 "load_multiple_operation"
11359 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11360 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11365 arm_output_multireg_pop (operands, /*return_pc=*/false,
11366 /*cond=*/const_true_rtx,
11372 [(set_attr "predicable" "yes")]
11375 (define_expand "copysignsf3"
11376 [(match_operand:SF 0 "register_operand")
11377 (match_operand:SF 1 "register_operand")
11378 (match_operand:SF 2 "register_operand")]
11379 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11381 emit_move_insn (operands[0], operands[2]);
11382 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11383 GEN_INT (31), GEN_INT (0),
11384 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11389 (define_expand "copysigndf3"
11390 [(match_operand:DF 0 "register_operand")
11391 (match_operand:DF 1 "register_operand")
11392 (match_operand:DF 2 "register_operand")]
11393 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11395 rtx op0_low = gen_lowpart (SImode, operands[0]);
11396 rtx op0_high = gen_highpart (SImode, operands[0]);
11397 rtx op1_low = gen_lowpart (SImode, operands[1]);
11398 rtx op1_high = gen_highpart (SImode, operands[1]);
11399 rtx op2_high = gen_highpart (SImode, operands[2]);
11401 rtx scratch1 = gen_reg_rtx (SImode);
11402 rtx scratch2 = gen_reg_rtx (SImode);
11403 emit_move_insn (scratch1, op2_high);
11404 emit_move_insn (scratch2, op1_high);
11406 emit_insn(gen_rtx_SET(scratch1,
11407 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11408 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11409 emit_move_insn (op0_low, op1_low);
11410 emit_move_insn (op0_high, scratch2);
11416 ;; movmisalign patterns for HImode and SImode.
11417 (define_expand "movmisalign<mode>"
11418 [(match_operand:HSI 0 "general_operand")
11419 (match_operand:HSI 1 "general_operand")]
11422 /* This pattern is not permitted to fail during expansion: if both arguments
11423 are non-registers (e.g. memory := constant), force operand 1 into a
11425 rtx (* gen_unaligned_load)(rtx, rtx);
11426 rtx tmp_dest = operands[0];
11427 if (!s_register_operand (operands[0], <MODE>mode)
11428 && !s_register_operand (operands[1], <MODE>mode))
11429 operands[1] = force_reg (<MODE>mode, operands[1]);
11431 if (<MODE>mode == HImode)
11433 gen_unaligned_load = gen_unaligned_loadhiu;
11434 tmp_dest = gen_reg_rtx (SImode);
11437 gen_unaligned_load = gen_unaligned_loadsi;
11439 if (MEM_P (operands[1]))
11441 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11442 if (<MODE>mode == HImode)
11443 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11446 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11451 ;; Vector bits common to IWMMXT and Neon
11452 (include "vec-common.md")
11453 ;; Load the Intel Wireless Multimedia Extension patterns
11454 (include "iwmmxt.md")
11455 ;; Load the VFP co-processor patterns
11457 ;; Thumb-1 patterns
11458 (include "thumb1.md")
11459 ;; Thumb-2 patterns
11460 (include "thumb2.md")
11462 (include "neon.md")
11464 (include "crypto.md")
11465 ;; Synchronization Primitives
11466 (include "sync.md")
11467 ;; Fixed-point patterns
11468 (include "arm-fixed.md")