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. This attribute is
122 ; used to compute attribute "enabled", use type "any" to enable an
123 ; alternative in all cases.
124 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,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" "avoid_neon_for_64bits")
164 (match_test "TARGET_NEON")
165 (not (match_test "TARGET_PREFER_NEON_64BITS")))
168 (and (eq_attr "arch" "neon_for_64bits")
169 (match_test "TARGET_NEON")
170 (match_test "TARGET_PREFER_NEON_64BITS"))
173 (and (eq_attr "arch" "iwmmxt2")
174 (match_test "TARGET_REALLY_IWMMXT2"))
177 (and (eq_attr "arch" "armv6_or_vfpv3")
178 (match_test "arm_arch6 || TARGET_VFP3"))
181 (and (eq_attr "arch" "neon")
182 (match_test "TARGET_NEON"))
186 (const_string "no")))
188 (define_attr "opt" "any,speed,size"
189 (const_string "any"))
191 (define_attr "opt_enabled" "no,yes"
192 (cond [(eq_attr "opt" "any")
195 (and (eq_attr "opt" "speed")
196 (match_test "optimize_function_for_speed_p (cfun)"))
199 (and (eq_attr "opt" "size")
200 (match_test "optimize_function_for_size_p (cfun)"))
201 (const_string "yes")]
202 (const_string "no")))
204 (define_attr "use_literal_pool" "no,yes"
205 (cond [(and (eq_attr "type" "f_loads,f_loadd")
206 (match_test "CONSTANT_P (operands[1])"))
207 (const_string "yes")]
208 (const_string "no")))
210 ; Enable all alternatives that are both arch_enabled and insn_enabled.
211 ; FIXME:: opt_enabled has been temporarily removed till the time we have
212 ; an attribute that allows the use of such alternatives.
213 ; This depends on caching of speed_p, size_p on a per
214 ; alternative basis. The problem is that the enabled attribute
215 ; cannot depend on any state that is not cached or is not constant
216 ; for a compilation unit. We probably need a generic "hot/cold"
217 ; alternative which if implemented can help with this. We disable this
218 ; until such a time as this is implemented and / or the improvements or
219 ; regressions with removing this attribute are double checked.
220 ; See ashldi3_neon and <shift>di3_neon in neon.md.
222 (define_attr "enabled" "no,yes"
223 (cond [(and (eq_attr "predicable_short_it" "no")
224 (and (eq_attr "predicated" "yes")
225 (match_test "arm_restrict_it")))
228 (and (eq_attr "enabled_for_depr_it" "no")
229 (match_test "arm_restrict_it"))
232 (and (eq_attr "use_literal_pool" "yes")
233 (match_test "arm_disable_literal_pool"))
236 (eq_attr "arch_enabled" "no")
238 (const_string "yes")))
240 ; POOL_RANGE is how far away from a constant pool entry that this insn
241 ; can be placed. If the distance is zero, then this insn will never
242 ; reference the pool.
243 ; Note that for Thumb constant pools the PC value is rounded down to the
244 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
245 ; Thumb insns) should be set to <max_range> - 2.
246 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
247 ; before its address. It is set to <max_range> - (8 + <data_size>).
248 (define_attr "arm_pool_range" "" (const_int 0))
249 (define_attr "thumb2_pool_range" "" (const_int 0))
250 (define_attr "arm_neg_pool_range" "" (const_int 0))
251 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
253 (define_attr "pool_range" ""
254 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
255 (attr "arm_pool_range")))
256 (define_attr "neg_pool_range" ""
257 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
258 (attr "arm_neg_pool_range")))
260 ; An assembler sequence may clobber the condition codes without us knowing.
261 ; If such an insn references the pool, then we have no way of knowing how,
262 ; so use the most conservative value for pool_range.
263 (define_asm_attributes
264 [(set_attr "conds" "clob")
265 (set_attr "length" "4")
266 (set_attr "pool_range" "250")])
268 ; Load scheduling, set from the arm_ld_sched variable
269 ; initialized by arm_option_override()
270 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
272 ; condition codes: this one is used by final_prescan_insn to speed up
273 ; conditionalizing instructions. It saves having to scan the rtl to see if
274 ; it uses or alters the condition codes.
276 ; USE means that the condition codes are used by the insn in the process of
277 ; outputting code, this means (at present) that we can't use the insn in
280 ; SET means that the purpose of the insn is to set the condition codes in a
281 ; well defined manner.
283 ; CLOB means that the condition codes are altered in an undefined manner, if
284 ; they are altered at all
286 ; UNCONDITIONAL means the instruction can not be conditionally executed and
287 ; that the instruction does not use or alter the condition codes.
289 ; NOCOND means that the instruction does not use or alter the condition
290 ; codes but can be converted into a conditionally exectuted instruction.
292 (define_attr "conds" "use,set,clob,unconditional,nocond"
294 (ior (eq_attr "is_thumb1" "yes")
295 (eq_attr "type" "call"))
296 (const_string "clob")
297 (if_then_else (eq_attr "is_neon_type" "no")
298 (const_string "nocond")
299 (const_string "unconditional"))))
301 ; Predicable means that the insn can be conditionally executed based on
302 ; an automatically added predicate (additional patterns are generated by
303 ; gen...). We default to 'no' because no Thumb patterns match this rule
304 ; and not all ARM patterns do.
305 (define_attr "predicable" "no,yes" (const_string "no"))
307 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
308 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
309 ; suffer blockages enough to warrant modelling this (and it can adversely
310 ; affect the schedule).
311 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
313 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
314 ; to stall the processor. Used with model_wbuf above.
315 (define_attr "write_conflict" "no,yes"
316 (if_then_else (eq_attr "type"
319 (const_string "no")))
321 ; Classify the insns into those that take one cycle and those that take more
322 ; than one on the main cpu execution unit.
323 (define_attr "core_cycles" "single,multi"
324 (if_then_else (eq_attr "type"
325 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
326 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
327 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
328 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
329 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
330 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
331 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
332 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
333 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
334 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
335 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
336 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
337 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
338 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
339 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
340 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
341 (const_string "single")
342 (const_string "multi")))
344 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
345 ;; distant label. Only applicable to Thumb code.
346 (define_attr "far_jump" "yes,no" (const_string "no"))
349 ;; The number of machine instructions this pattern expands to.
350 ;; Used for Thumb-2 conditional execution.
351 (define_attr "ce_count" "" (const_int 1))
353 ;;---------------------------------------------------------------------------
356 (include "unspecs.md")
358 ;;---------------------------------------------------------------------------
361 (include "iterators.md")
363 ;;---------------------------------------------------------------------------
366 (include "predicates.md")
367 (include "constraints.md")
369 ;;---------------------------------------------------------------------------
370 ;; Pipeline descriptions
372 (define_attr "tune_cortexr4" "yes,no"
374 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
376 (const_string "no"))))
378 ;; True if the generic scheduling description should be used.
380 (define_attr "generic_sched" "yes,no"
382 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
383 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
384 arm1136jfs,cortexa5,cortexa7,cortexa8,\
385 cortexa9,cortexa12,cortexa15,cortexa17,\
386 cortexa53,cortexa57,cortexm4,cortexm7,\
387 exynosm1,marvell_pj4,xgene1")
388 (eq_attr "tune_cortexr4" "yes"))
390 (const_string "yes"))))
392 (define_attr "generic_vfp" "yes,no"
394 (and (eq_attr "fpu" "vfp")
395 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
396 cortexa8,cortexa9,cortexa53,cortexm4,\
397 cortexm7,marvell_pj4,xgene1")
398 (eq_attr "tune_cortexr4" "no"))
400 (const_string "no"))))
402 (include "marvell-f-iwmmxt.md")
403 (include "arm-generic.md")
404 (include "arm926ejs.md")
405 (include "arm1020e.md")
406 (include "arm1026ejs.md")
407 (include "arm1136jfs.md")
409 (include "fa606te.md")
410 (include "fa626te.md")
411 (include "fmp626.md")
412 (include "fa726te.md")
413 (include "cortex-a5.md")
414 (include "cortex-a7.md")
415 (include "cortex-a8.md")
416 (include "cortex-a9.md")
417 (include "cortex-a15.md")
418 (include "cortex-a17.md")
419 (include "cortex-a53.md")
420 (include "cortex-a57.md")
421 (include "cortex-r4.md")
422 (include "cortex-r4f.md")
423 (include "cortex-m7.md")
424 (include "cortex-m4.md")
425 (include "cortex-m4-fpu.md")
426 (include "exynos-m1.md")
428 (include "marvell-pj4.md")
429 (include "xgene1.md")
432 ;;---------------------------------------------------------------------------
437 ;; Note: For DImode insns, there is normally no reason why operands should
438 ;; not be in the same register, what we don't want is for something being
439 ;; written to partially overlap something that is an input.
441 (define_expand "adddi3"
443 [(set (match_operand:DI 0 "s_register_operand" "")
444 (plus:DI (match_operand:DI 1 "s_register_operand" "")
445 (match_operand:DI 2 "arm_adddi_operand" "")))
446 (clobber (reg:CC CC_REGNUM))])]
451 if (!REG_P (operands[1]))
452 operands[1] = force_reg (DImode, operands[1]);
453 if (!REG_P (operands[2]))
454 operands[2] = force_reg (DImode, operands[2]);
459 (define_insn_and_split "*arm_adddi3"
460 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
461 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
462 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
463 (clobber (reg:CC CC_REGNUM))]
464 "TARGET_32BIT && !TARGET_NEON"
466 "TARGET_32BIT && reload_completed
467 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
468 [(parallel [(set (reg:CC_C CC_REGNUM)
469 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
471 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
472 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
473 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
476 operands[3] = gen_highpart (SImode, operands[0]);
477 operands[0] = gen_lowpart (SImode, operands[0]);
478 operands[4] = gen_highpart (SImode, operands[1]);
479 operands[1] = gen_lowpart (SImode, operands[1]);
480 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
481 operands[2] = gen_lowpart (SImode, operands[2]);
483 [(set_attr "conds" "clob")
484 (set_attr "length" "8")
485 (set_attr "type" "multiple")]
488 (define_insn_and_split "*adddi_sesidi_di"
489 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
490 (plus:DI (sign_extend:DI
491 (match_operand:SI 2 "s_register_operand" "r,r"))
492 (match_operand:DI 1 "s_register_operand" "0,r")))
493 (clobber (reg:CC CC_REGNUM))]
496 "TARGET_32BIT && reload_completed"
497 [(parallel [(set (reg:CC_C CC_REGNUM)
498 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
500 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
501 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
504 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
507 operands[3] = gen_highpart (SImode, operands[0]);
508 operands[0] = gen_lowpart (SImode, operands[0]);
509 operands[4] = gen_highpart (SImode, operands[1]);
510 operands[1] = gen_lowpart (SImode, operands[1]);
511 operands[2] = gen_lowpart (SImode, operands[2]);
513 [(set_attr "conds" "clob")
514 (set_attr "length" "8")
515 (set_attr "type" "multiple")]
518 (define_insn_and_split "*adddi_zesidi_di"
519 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
520 (plus:DI (zero_extend:DI
521 (match_operand:SI 2 "s_register_operand" "r,r"))
522 (match_operand:DI 1 "s_register_operand" "0,r")))
523 (clobber (reg:CC CC_REGNUM))]
526 "TARGET_32BIT && reload_completed"
527 [(parallel [(set (reg:CC_C CC_REGNUM)
528 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
530 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
531 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
532 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
535 operands[3] = gen_highpart (SImode, operands[0]);
536 operands[0] = gen_lowpart (SImode, operands[0]);
537 operands[4] = gen_highpart (SImode, operands[1]);
538 operands[1] = gen_lowpart (SImode, operands[1]);
539 operands[2] = gen_lowpart (SImode, operands[2]);
541 [(set_attr "conds" "clob")
542 (set_attr "length" "8")
543 (set_attr "type" "multiple")]
546 (define_expand "addsi3"
547 [(set (match_operand:SI 0 "s_register_operand" "")
548 (plus:SI (match_operand:SI 1 "s_register_operand" "")
549 (match_operand:SI 2 "reg_or_int_operand" "")))]
552 if (TARGET_32BIT && CONST_INT_P (operands[2]))
554 arm_split_constant (PLUS, SImode, NULL_RTX,
555 INTVAL (operands[2]), operands[0], operands[1],
556 optimize && can_create_pseudo_p ());
562 ; If there is a scratch available, this will be faster than synthesizing the
565 [(match_scratch:SI 3 "r")
566 (set (match_operand:SI 0 "arm_general_register_operand" "")
567 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
568 (match_operand:SI 2 "const_int_operand" "")))]
570 !(const_ok_for_arm (INTVAL (operands[2]))
571 || const_ok_for_arm (-INTVAL (operands[2])))
572 && const_ok_for_arm (~INTVAL (operands[2]))"
573 [(set (match_dup 3) (match_dup 2))
574 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
578 ;; The r/r/k alternative is required when reloading the address
579 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
580 ;; put the duplicated register first, and not try the commutative version.
581 (define_insn_and_split "*arm_addsi3"
582 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
583 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
584 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
599 subw%?\\t%0, %1, #%n2
600 subw%?\\t%0, %1, #%n2
603 && CONST_INT_P (operands[2])
604 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
605 && (reload_completed || !arm_eliminable_register (operands[1]))"
606 [(clobber (const_int 0))]
608 arm_split_constant (PLUS, SImode, curr_insn,
609 INTVAL (operands[2]), operands[0],
613 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
614 (set_attr "predicable" "yes")
615 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
616 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
617 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
618 (const_string "alu_imm")
619 (const_string "alu_sreg")))
623 (define_insn "addsi3_compare0"
624 [(set (reg:CC_NOOV CC_REGNUM)
626 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
627 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
629 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
630 (plus:SI (match_dup 1) (match_dup 2)))]
634 subs%?\\t%0, %1, #%n2
636 [(set_attr "conds" "set")
637 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
640 (define_insn "*addsi3_compare0_scratch"
641 [(set (reg:CC_NOOV CC_REGNUM)
643 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
644 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
651 [(set_attr "conds" "set")
652 (set_attr "predicable" "yes")
653 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
656 (define_insn "*compare_negsi_si"
657 [(set (reg:CC_Z CC_REGNUM)
659 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
660 (match_operand:SI 1 "s_register_operand" "l,r")))]
663 [(set_attr "conds" "set")
664 (set_attr "predicable" "yes")
665 (set_attr "arch" "t2,*")
666 (set_attr "length" "2,4")
667 (set_attr "predicable_short_it" "yes,no")
668 (set_attr "type" "alus_sreg")]
671 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
672 ;; addend is a constant.
673 (define_insn "cmpsi2_addneg"
674 [(set (reg:CC CC_REGNUM)
676 (match_operand:SI 1 "s_register_operand" "r,r")
677 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
678 (set (match_operand:SI 0 "s_register_operand" "=r,r")
679 (plus:SI (match_dup 1)
680 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
681 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
684 subs%?\\t%0, %1, #%n3"
685 [(set_attr "conds" "set")
686 (set_attr "type" "alus_sreg")]
689 ;; Convert the sequence
691 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
695 ;; bcs dest ((unsigned)rn >= 1)
696 ;; similarly for the beq variant using bcc.
697 ;; This is a common looping idiom (while (n--))
699 [(set (match_operand:SI 0 "arm_general_register_operand" "")
700 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
702 (set (match_operand 2 "cc_register" "")
703 (compare (match_dup 0) (const_int -1)))
705 (if_then_else (match_operator 3 "equality_operator"
706 [(match_dup 2) (const_int 0)])
707 (match_operand 4 "" "")
708 (match_operand 5 "" "")))]
709 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
713 (match_dup 1) (const_int 1)))
714 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
716 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
719 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
720 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
723 operands[2], const0_rtx);"
726 ;; The next four insns work because they compare the result with one of
727 ;; the operands, and we know that the use of the condition code is
728 ;; either GEU or LTU, so we can use the carry flag from the addition
729 ;; instead of doing the compare a second time.
730 (define_insn "*addsi3_compare_op1"
731 [(set (reg:CC_C CC_REGNUM)
733 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
734 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
736 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
737 (plus:SI (match_dup 1) (match_dup 2)))]
741 subs%?\\t%0, %1, #%n2
743 [(set_attr "conds" "set")
744 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
747 (define_insn "*addsi3_compare_op2"
748 [(set (reg:CC_C CC_REGNUM)
750 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
751 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
753 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
754 (plus:SI (match_dup 1) (match_dup 2)))]
758 subs%?\\t%0, %1, #%n2
760 [(set_attr "conds" "set")
761 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
764 (define_insn "*compare_addsi2_op0"
765 [(set (reg:CC_C CC_REGNUM)
767 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
768 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
777 [(set_attr "conds" "set")
778 (set_attr "predicable" "yes")
779 (set_attr "arch" "t2,t2,*,*,*")
780 (set_attr "predicable_short_it" "yes,yes,no,no,no")
781 (set_attr "length" "2,2,4,4,4")
782 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
785 (define_insn "*compare_addsi2_op1"
786 [(set (reg:CC_C CC_REGNUM)
788 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
789 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
798 [(set_attr "conds" "set")
799 (set_attr "predicable" "yes")
800 (set_attr "arch" "t2,t2,*,*,*")
801 (set_attr "predicable_short_it" "yes,yes,no,no,no")
802 (set_attr "length" "2,2,4,4,4")
803 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
806 (define_insn "*addsi3_carryin_<optab>"
807 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
808 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
809 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
810 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
815 sbc%?\\t%0, %1, #%B2"
816 [(set_attr "conds" "use")
817 (set_attr "predicable" "yes")
818 (set_attr "arch" "t2,*,*")
819 (set_attr "length" "4")
820 (set_attr "predicable_short_it" "yes,no,no")
821 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
824 (define_insn "*addsi3_carryin_alt2_<optab>"
825 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
826 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
827 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
828 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
833 sbc%?\\t%0, %1, #%B2"
834 [(set_attr "conds" "use")
835 (set_attr "predicable" "yes")
836 (set_attr "arch" "t2,*,*")
837 (set_attr "length" "4")
838 (set_attr "predicable_short_it" "yes,no,no")
839 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
842 (define_insn "*addsi3_carryin_shift_<optab>"
843 [(set (match_operand:SI 0 "s_register_operand" "=r")
845 (match_operator:SI 2 "shift_operator"
846 [(match_operand:SI 3 "s_register_operand" "r")
847 (match_operand:SI 4 "reg_or_int_operand" "rM")])
848 (match_operand:SI 1 "s_register_operand" "r"))
849 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
851 "adc%?\\t%0, %1, %3%S2"
852 [(set_attr "conds" "use")
853 (set_attr "predicable" "yes")
854 (set_attr "predicable_short_it" "no")
855 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
856 (const_string "alu_shift_imm")
857 (const_string "alu_shift_reg")))]
860 (define_insn "*addsi3_carryin_clobercc_<optab>"
861 [(set (match_operand:SI 0 "s_register_operand" "=r")
862 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
863 (match_operand:SI 2 "arm_rhs_operand" "rI"))
864 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
865 (clobber (reg:CC CC_REGNUM))]
867 "adcs%?\\t%0, %1, %2"
868 [(set_attr "conds" "set")
869 (set_attr "type" "adcs_reg")]
872 (define_insn "*subsi3_carryin"
873 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
874 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
875 (match_operand:SI 2 "s_register_operand" "r,r"))
876 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
881 [(set_attr "conds" "use")
882 (set_attr "arch" "*,a")
883 (set_attr "predicable" "yes")
884 (set_attr "predicable_short_it" "no")
885 (set_attr "type" "adc_reg,adc_imm")]
888 (define_insn "*subsi3_carryin_const"
889 [(set (match_operand:SI 0 "s_register_operand" "=r")
890 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
891 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
892 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
895 [(set_attr "conds" "use")
896 (set_attr "type" "adc_imm")]
899 (define_insn "*subsi3_carryin_compare"
900 [(set (reg:CC CC_REGNUM)
901 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
902 (match_operand:SI 2 "s_register_operand" "r")))
903 (set (match_operand:SI 0 "s_register_operand" "=r")
904 (minus:SI (minus:SI (match_dup 1)
906 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
909 [(set_attr "conds" "set")
910 (set_attr "type" "adcs_reg")]
913 (define_insn "*subsi3_carryin_compare_const"
914 [(set (reg:CC CC_REGNUM)
915 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
916 (match_operand:SI 2 "arm_not_operand" "K")))
917 (set (match_operand:SI 0 "s_register_operand" "=r")
918 (minus:SI (plus:SI (match_dup 1)
920 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
922 "sbcs\\t%0, %1, #%B2"
923 [(set_attr "conds" "set")
924 (set_attr "type" "adcs_imm")]
927 (define_insn "*subsi3_carryin_shift"
928 [(set (match_operand:SI 0 "s_register_operand" "=r")
930 (match_operand:SI 1 "s_register_operand" "r")
931 (match_operator:SI 2 "shift_operator"
932 [(match_operand:SI 3 "s_register_operand" "r")
933 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
934 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
936 "sbc%?\\t%0, %1, %3%S2"
937 [(set_attr "conds" "use")
938 (set_attr "predicable" "yes")
939 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
940 (const_string "alu_shift_imm")
941 (const_string "alu_shift_reg")))]
944 (define_insn "*rsbsi3_carryin_shift"
945 [(set (match_operand:SI 0 "s_register_operand" "=r")
947 (match_operator:SI 2 "shift_operator"
948 [(match_operand:SI 3 "s_register_operand" "r")
949 (match_operand:SI 4 "reg_or_int_operand" "rM")])
950 (match_operand:SI 1 "s_register_operand" "r"))
951 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
953 "rsc%?\\t%0, %1, %3%S2"
954 [(set_attr "conds" "use")
955 (set_attr "predicable" "yes")
956 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
957 (const_string "alu_shift_imm")
958 (const_string "alu_shift_reg")))]
961 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
963 [(set (match_operand:SI 0 "s_register_operand" "")
964 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
965 (match_operand:SI 2 "s_register_operand" ""))
967 (clobber (match_operand:SI 3 "s_register_operand" ""))]
969 [(set (match_dup 3) (match_dup 1))
970 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
972 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
975 (define_expand "addsf3"
976 [(set (match_operand:SF 0 "s_register_operand" "")
977 (plus:SF (match_operand:SF 1 "s_register_operand" "")
978 (match_operand:SF 2 "s_register_operand" "")))]
979 "TARGET_32BIT && TARGET_HARD_FLOAT"
983 (define_expand "adddf3"
984 [(set (match_operand:DF 0 "s_register_operand" "")
985 (plus:DF (match_operand:DF 1 "s_register_operand" "")
986 (match_operand:DF 2 "s_register_operand" "")))]
987 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
991 (define_expand "subdi3"
993 [(set (match_operand:DI 0 "s_register_operand" "")
994 (minus:DI (match_operand:DI 1 "s_register_operand" "")
995 (match_operand:DI 2 "s_register_operand" "")))
996 (clobber (reg:CC CC_REGNUM))])]
1001 if (!REG_P (operands[1]))
1002 operands[1] = force_reg (DImode, operands[1]);
1003 if (!REG_P (operands[2]))
1004 operands[2] = force_reg (DImode, operands[2]);
1009 (define_insn_and_split "*arm_subdi3"
1010 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1011 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1012 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1013 (clobber (reg:CC CC_REGNUM))]
1014 "TARGET_32BIT && !TARGET_NEON"
1015 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1016 "&& reload_completed"
1017 [(parallel [(set (reg:CC CC_REGNUM)
1018 (compare:CC (match_dup 1) (match_dup 2)))
1019 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1020 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1021 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1023 operands[3] = gen_highpart (SImode, operands[0]);
1024 operands[0] = gen_lowpart (SImode, operands[0]);
1025 operands[4] = gen_highpart (SImode, operands[1]);
1026 operands[1] = gen_lowpart (SImode, operands[1]);
1027 operands[5] = gen_highpart (SImode, operands[2]);
1028 operands[2] = gen_lowpart (SImode, operands[2]);
1030 [(set_attr "conds" "clob")
1031 (set_attr "length" "8")
1032 (set_attr "type" "multiple")]
1035 (define_insn_and_split "*subdi_di_zesidi"
1036 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1037 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1039 (match_operand:SI 2 "s_register_operand" "r,r"))))
1040 (clobber (reg:CC CC_REGNUM))]
1042 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1043 "&& reload_completed"
1044 [(parallel [(set (reg:CC CC_REGNUM)
1045 (compare:CC (match_dup 1) (match_dup 2)))
1046 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1047 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1048 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1050 operands[3] = gen_highpart (SImode, operands[0]);
1051 operands[0] = gen_lowpart (SImode, operands[0]);
1052 operands[4] = gen_highpart (SImode, operands[1]);
1053 operands[1] = gen_lowpart (SImode, operands[1]);
1054 operands[5] = GEN_INT (~0);
1056 [(set_attr "conds" "clob")
1057 (set_attr "length" "8")
1058 (set_attr "type" "multiple")]
1061 (define_insn_and_split "*subdi_di_sesidi"
1062 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1063 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1065 (match_operand:SI 2 "s_register_operand" "r,r"))))
1066 (clobber (reg:CC CC_REGNUM))]
1068 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1069 "&& reload_completed"
1070 [(parallel [(set (reg:CC CC_REGNUM)
1071 (compare:CC (match_dup 1) (match_dup 2)))
1072 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1073 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1074 (ashiftrt:SI (match_dup 2)
1076 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1078 operands[3] = gen_highpart (SImode, operands[0]);
1079 operands[0] = gen_lowpart (SImode, operands[0]);
1080 operands[4] = gen_highpart (SImode, operands[1]);
1081 operands[1] = gen_lowpart (SImode, operands[1]);
1083 [(set_attr "conds" "clob")
1084 (set_attr "length" "8")
1085 (set_attr "type" "multiple")]
1088 (define_insn_and_split "*subdi_zesidi_di"
1089 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1090 (minus:DI (zero_extend:DI
1091 (match_operand:SI 2 "s_register_operand" "r,r"))
1092 (match_operand:DI 1 "s_register_operand" "0,r")))
1093 (clobber (reg:CC CC_REGNUM))]
1095 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1097 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1098 "&& reload_completed"
1099 [(parallel [(set (reg:CC CC_REGNUM)
1100 (compare:CC (match_dup 2) (match_dup 1)))
1101 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1102 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1103 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1105 operands[3] = gen_highpart (SImode, operands[0]);
1106 operands[0] = gen_lowpart (SImode, operands[0]);
1107 operands[4] = gen_highpart (SImode, operands[1]);
1108 operands[1] = gen_lowpart (SImode, operands[1]);
1110 [(set_attr "conds" "clob")
1111 (set_attr "length" "8")
1112 (set_attr "type" "multiple")]
1115 (define_insn_and_split "*subdi_sesidi_di"
1116 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1117 (minus:DI (sign_extend:DI
1118 (match_operand:SI 2 "s_register_operand" "r,r"))
1119 (match_operand:DI 1 "s_register_operand" "0,r")))
1120 (clobber (reg:CC CC_REGNUM))]
1122 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1124 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1125 "&& reload_completed"
1126 [(parallel [(set (reg:CC CC_REGNUM)
1127 (compare:CC (match_dup 2) (match_dup 1)))
1128 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1129 (set (match_dup 3) (minus:SI (minus:SI
1130 (ashiftrt:SI (match_dup 2)
1133 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1135 operands[3] = gen_highpart (SImode, operands[0]);
1136 operands[0] = gen_lowpart (SImode, operands[0]);
1137 operands[4] = gen_highpart (SImode, operands[1]);
1138 operands[1] = gen_lowpart (SImode, operands[1]);
1140 [(set_attr "conds" "clob")
1141 (set_attr "length" "8")
1142 (set_attr "type" "multiple")]
1145 (define_insn_and_split "*subdi_zesidi_zesidi"
1146 [(set (match_operand:DI 0 "s_register_operand" "=r")
1147 (minus:DI (zero_extend:DI
1148 (match_operand:SI 1 "s_register_operand" "r"))
1150 (match_operand:SI 2 "s_register_operand" "r"))))
1151 (clobber (reg:CC CC_REGNUM))]
1153 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1154 "&& reload_completed"
1155 [(parallel [(set (reg:CC CC_REGNUM)
1156 (compare:CC (match_dup 1) (match_dup 2)))
1157 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1158 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1159 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1161 operands[3] = gen_highpart (SImode, operands[0]);
1162 operands[0] = gen_lowpart (SImode, operands[0]);
1164 [(set_attr "conds" "clob")
1165 (set_attr "length" "8")
1166 (set_attr "type" "multiple")]
1169 (define_expand "subsi3"
1170 [(set (match_operand:SI 0 "s_register_operand" "")
1171 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1172 (match_operand:SI 2 "s_register_operand" "")))]
1175 if (CONST_INT_P (operands[1]))
1179 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1180 operands[1] = force_reg (SImode, operands[1]);
1183 arm_split_constant (MINUS, SImode, NULL_RTX,
1184 INTVAL (operands[1]), operands[0],
1186 optimize && can_create_pseudo_p ());
1190 else /* TARGET_THUMB1 */
1191 operands[1] = force_reg (SImode, operands[1]);
1196 ; ??? Check Thumb-2 split length
1197 (define_insn_and_split "*arm_subsi3_insn"
1198 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1199 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1200 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1212 "&& (CONST_INT_P (operands[1])
1213 && !const_ok_for_arm (INTVAL (operands[1])))"
1214 [(clobber (const_int 0))]
1216 arm_split_constant (MINUS, SImode, curr_insn,
1217 INTVAL (operands[1]), operands[0], operands[2], 0);
1220 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1221 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1222 (set_attr "predicable" "yes")
1223 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1224 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1228 [(match_scratch:SI 3 "r")
1229 (set (match_operand:SI 0 "arm_general_register_operand" "")
1230 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1231 (match_operand:SI 2 "arm_general_register_operand" "")))]
1233 && !const_ok_for_arm (INTVAL (operands[1]))
1234 && const_ok_for_arm (~INTVAL (operands[1]))"
1235 [(set (match_dup 3) (match_dup 1))
1236 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1240 (define_insn "subsi3_compare0"
1241 [(set (reg:CC_NOOV CC_REGNUM)
1243 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1244 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1246 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1247 (minus:SI (match_dup 1) (match_dup 2)))]
1252 rsbs%?\\t%0, %2, %1"
1253 [(set_attr "conds" "set")
1254 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1257 (define_insn "subsi3_compare"
1258 [(set (reg:CC CC_REGNUM)
1259 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1260 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1261 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1262 (minus:SI (match_dup 1) (match_dup 2)))]
1267 rsbs%?\\t%0, %2, %1"
1268 [(set_attr "conds" "set")
1269 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1272 (define_expand "subsf3"
1273 [(set (match_operand:SF 0 "s_register_operand" "")
1274 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1275 (match_operand:SF 2 "s_register_operand" "")))]
1276 "TARGET_32BIT && TARGET_HARD_FLOAT"
1280 (define_expand "subdf3"
1281 [(set (match_operand:DF 0 "s_register_operand" "")
1282 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1283 (match_operand:DF 2 "s_register_operand" "")))]
1284 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1289 ;; Multiplication insns
1291 (define_expand "mulhi3"
1292 [(set (match_operand:HI 0 "s_register_operand" "")
1293 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1294 (match_operand:HI 2 "s_register_operand" "")))]
1295 "TARGET_DSP_MULTIPLY"
1298 rtx result = gen_reg_rtx (SImode);
1299 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1300 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1305 (define_expand "mulsi3"
1306 [(set (match_operand:SI 0 "s_register_operand" "")
1307 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1308 (match_operand:SI 1 "s_register_operand" "")))]
1313 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1314 (define_insn "*arm_mulsi3"
1315 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1316 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1317 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1318 "TARGET_32BIT && !arm_arch6"
1319 "mul%?\\t%0, %2, %1"
1320 [(set_attr "type" "mul")
1321 (set_attr "predicable" "yes")]
1324 (define_insn "*arm_mulsi3_v6"
1325 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1326 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1327 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1328 "TARGET_32BIT && arm_arch6"
1329 "mul%?\\t%0, %1, %2"
1330 [(set_attr "type" "mul")
1331 (set_attr "predicable" "yes")
1332 (set_attr "arch" "t2,t2,*")
1333 (set_attr "length" "4")
1334 (set_attr "predicable_short_it" "yes,yes,no")]
1337 (define_insn "*mulsi3_compare0"
1338 [(set (reg:CC_NOOV CC_REGNUM)
1339 (compare:CC_NOOV (mult:SI
1340 (match_operand:SI 2 "s_register_operand" "r,r")
1341 (match_operand:SI 1 "s_register_operand" "%0,r"))
1343 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1344 (mult:SI (match_dup 2) (match_dup 1)))]
1345 "TARGET_ARM && !arm_arch6"
1346 "muls%?\\t%0, %2, %1"
1347 [(set_attr "conds" "set")
1348 (set_attr "type" "muls")]
1351 (define_insn "*mulsi3_compare0_v6"
1352 [(set (reg:CC_NOOV CC_REGNUM)
1353 (compare:CC_NOOV (mult:SI
1354 (match_operand:SI 2 "s_register_operand" "r")
1355 (match_operand:SI 1 "s_register_operand" "r"))
1357 (set (match_operand:SI 0 "s_register_operand" "=r")
1358 (mult:SI (match_dup 2) (match_dup 1)))]
1359 "TARGET_ARM && arm_arch6 && optimize_size"
1360 "muls%?\\t%0, %2, %1"
1361 [(set_attr "conds" "set")
1362 (set_attr "type" "muls")]
1365 (define_insn "*mulsi_compare0_scratch"
1366 [(set (reg:CC_NOOV CC_REGNUM)
1367 (compare:CC_NOOV (mult:SI
1368 (match_operand:SI 2 "s_register_operand" "r,r")
1369 (match_operand:SI 1 "s_register_operand" "%0,r"))
1371 (clobber (match_scratch:SI 0 "=&r,&r"))]
1372 "TARGET_ARM && !arm_arch6"
1373 "muls%?\\t%0, %2, %1"
1374 [(set_attr "conds" "set")
1375 (set_attr "type" "muls")]
1378 (define_insn "*mulsi_compare0_scratch_v6"
1379 [(set (reg:CC_NOOV CC_REGNUM)
1380 (compare:CC_NOOV (mult:SI
1381 (match_operand:SI 2 "s_register_operand" "r")
1382 (match_operand:SI 1 "s_register_operand" "r"))
1384 (clobber (match_scratch:SI 0 "=r"))]
1385 "TARGET_ARM && arm_arch6 && optimize_size"
1386 "muls%?\\t%0, %2, %1"
1387 [(set_attr "conds" "set")
1388 (set_attr "type" "muls")]
1391 ;; Unnamed templates to match MLA instruction.
1393 (define_insn "*mulsi3addsi"
1394 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1396 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1397 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1398 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1399 "TARGET_32BIT && !arm_arch6"
1400 "mla%?\\t%0, %2, %1, %3"
1401 [(set_attr "type" "mla")
1402 (set_attr "predicable" "yes")]
1405 (define_insn "*mulsi3addsi_v6"
1406 [(set (match_operand:SI 0 "s_register_operand" "=r")
1408 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1409 (match_operand:SI 1 "s_register_operand" "r"))
1410 (match_operand:SI 3 "s_register_operand" "r")))]
1411 "TARGET_32BIT && arm_arch6"
1412 "mla%?\\t%0, %2, %1, %3"
1413 [(set_attr "type" "mla")
1414 (set_attr "predicable" "yes")
1415 (set_attr "predicable_short_it" "no")]
1418 (define_insn "*mulsi3addsi_compare0"
1419 [(set (reg:CC_NOOV CC_REGNUM)
1422 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1423 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1424 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1426 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1427 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1429 "TARGET_ARM && arm_arch6"
1430 "mlas%?\\t%0, %2, %1, %3"
1431 [(set_attr "conds" "set")
1432 (set_attr "type" "mlas")]
1435 (define_insn "*mulsi3addsi_compare0_v6"
1436 [(set (reg:CC_NOOV CC_REGNUM)
1439 (match_operand:SI 2 "s_register_operand" "r")
1440 (match_operand:SI 1 "s_register_operand" "r"))
1441 (match_operand:SI 3 "s_register_operand" "r"))
1443 (set (match_operand:SI 0 "s_register_operand" "=r")
1444 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1446 "TARGET_ARM && arm_arch6 && optimize_size"
1447 "mlas%?\\t%0, %2, %1, %3"
1448 [(set_attr "conds" "set")
1449 (set_attr "type" "mlas")]
1452 (define_insn "*mulsi3addsi_compare0_scratch"
1453 [(set (reg:CC_NOOV CC_REGNUM)
1456 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1457 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1458 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1460 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1461 "TARGET_ARM && !arm_arch6"
1462 "mlas%?\\t%0, %2, %1, %3"
1463 [(set_attr "conds" "set")
1464 (set_attr "type" "mlas")]
1467 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1468 [(set (reg:CC_NOOV CC_REGNUM)
1471 (match_operand:SI 2 "s_register_operand" "r")
1472 (match_operand:SI 1 "s_register_operand" "r"))
1473 (match_operand:SI 3 "s_register_operand" "r"))
1475 (clobber (match_scratch:SI 0 "=r"))]
1476 "TARGET_ARM && arm_arch6 && optimize_size"
1477 "mlas%?\\t%0, %2, %1, %3"
1478 [(set_attr "conds" "set")
1479 (set_attr "type" "mlas")]
1482 (define_insn "*mulsi3subsi"
1483 [(set (match_operand:SI 0 "s_register_operand" "=r")
1485 (match_operand:SI 3 "s_register_operand" "r")
1486 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1487 (match_operand:SI 1 "s_register_operand" "r"))))]
1488 "TARGET_32BIT && arm_arch_thumb2"
1489 "mls%?\\t%0, %2, %1, %3"
1490 [(set_attr "type" "mla")
1491 (set_attr "predicable" "yes")
1492 (set_attr "predicable_short_it" "no")]
1495 (define_expand "maddsidi4"
1496 [(set (match_operand:DI 0 "s_register_operand" "")
1499 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1500 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1501 (match_operand:DI 3 "s_register_operand" "")))]
1502 "TARGET_32BIT && arm_arch3m"
1505 (define_insn "*mulsidi3adddi"
1506 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1509 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1510 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1511 (match_operand:DI 1 "s_register_operand" "0")))]
1512 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1513 "smlal%?\\t%Q0, %R0, %3, %2"
1514 [(set_attr "type" "smlal")
1515 (set_attr "predicable" "yes")]
1518 (define_insn "*mulsidi3adddi_v6"
1519 [(set (match_operand:DI 0 "s_register_operand" "=r")
1522 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1523 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1524 (match_operand:DI 1 "s_register_operand" "0")))]
1525 "TARGET_32BIT && arm_arch6"
1526 "smlal%?\\t%Q0, %R0, %3, %2"
1527 [(set_attr "type" "smlal")
1528 (set_attr "predicable" "yes")
1529 (set_attr "predicable_short_it" "no")]
1532 ;; 32x32->64 widening multiply.
1533 ;; As with mulsi3, the only difference between the v3-5 and v6+
1534 ;; versions of these patterns is the requirement that the output not
1535 ;; overlap the inputs, but that still means we have to have a named
1536 ;; expander and two different starred insns.
1538 (define_expand "mulsidi3"
1539 [(set (match_operand:DI 0 "s_register_operand" "")
1541 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1542 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1543 "TARGET_32BIT && arm_arch3m"
1547 (define_insn "*mulsidi3_nov6"
1548 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1550 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1551 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1552 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1553 "smull%?\\t%Q0, %R0, %1, %2"
1554 [(set_attr "type" "smull")
1555 (set_attr "predicable" "yes")]
1558 (define_insn "*mulsidi3_v6"
1559 [(set (match_operand:DI 0 "s_register_operand" "=r")
1561 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1562 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1563 "TARGET_32BIT && arm_arch6"
1564 "smull%?\\t%Q0, %R0, %1, %2"
1565 [(set_attr "type" "smull")
1566 (set_attr "predicable" "yes")
1567 (set_attr "predicable_short_it" "no")]
1570 (define_expand "umulsidi3"
1571 [(set (match_operand:DI 0 "s_register_operand" "")
1573 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1574 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1575 "TARGET_32BIT && arm_arch3m"
1579 (define_insn "*umulsidi3_nov6"
1580 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1582 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1583 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1584 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1585 "umull%?\\t%Q0, %R0, %1, %2"
1586 [(set_attr "type" "umull")
1587 (set_attr "predicable" "yes")]
1590 (define_insn "*umulsidi3_v6"
1591 [(set (match_operand:DI 0 "s_register_operand" "=r")
1593 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1594 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1595 "TARGET_32BIT && arm_arch6"
1596 "umull%?\\t%Q0, %R0, %1, %2"
1597 [(set_attr "type" "umull")
1598 (set_attr "predicable" "yes")
1599 (set_attr "predicable_short_it" "no")]
1602 (define_expand "umaddsidi4"
1603 [(set (match_operand:DI 0 "s_register_operand" "")
1606 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1607 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1608 (match_operand:DI 3 "s_register_operand" "")))]
1609 "TARGET_32BIT && arm_arch3m"
1612 (define_insn "*umulsidi3adddi"
1613 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1616 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1617 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1618 (match_operand:DI 1 "s_register_operand" "0")))]
1619 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1620 "umlal%?\\t%Q0, %R0, %3, %2"
1621 [(set_attr "type" "umlal")
1622 (set_attr "predicable" "yes")]
1625 (define_insn "*umulsidi3adddi_v6"
1626 [(set (match_operand:DI 0 "s_register_operand" "=r")
1629 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1630 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1631 (match_operand:DI 1 "s_register_operand" "0")))]
1632 "TARGET_32BIT && arm_arch6"
1633 "umlal%?\\t%Q0, %R0, %3, %2"
1634 [(set_attr "type" "umlal")
1635 (set_attr "predicable" "yes")
1636 (set_attr "predicable_short_it" "no")]
1639 (define_expand "smulsi3_highpart"
1641 [(set (match_operand:SI 0 "s_register_operand" "")
1645 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1646 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1648 (clobber (match_scratch:SI 3 ""))])]
1649 "TARGET_32BIT && arm_arch3m"
1653 (define_insn "*smulsi3_highpart_nov6"
1654 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1658 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1659 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1661 (clobber (match_scratch:SI 3 "=&r,&r"))]
1662 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1663 "smull%?\\t%3, %0, %2, %1"
1664 [(set_attr "type" "smull")
1665 (set_attr "predicable" "yes")]
1668 (define_insn "*smulsi3_highpart_v6"
1669 [(set (match_operand:SI 0 "s_register_operand" "=r")
1673 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1674 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1676 (clobber (match_scratch:SI 3 "=r"))]
1677 "TARGET_32BIT && arm_arch6"
1678 "smull%?\\t%3, %0, %2, %1"
1679 [(set_attr "type" "smull")
1680 (set_attr "predicable" "yes")
1681 (set_attr "predicable_short_it" "no")]
1684 (define_expand "umulsi3_highpart"
1686 [(set (match_operand:SI 0 "s_register_operand" "")
1690 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1691 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1693 (clobber (match_scratch:SI 3 ""))])]
1694 "TARGET_32BIT && arm_arch3m"
1698 (define_insn "*umulsi3_highpart_nov6"
1699 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1703 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1704 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1706 (clobber (match_scratch:SI 3 "=&r,&r"))]
1707 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1708 "umull%?\\t%3, %0, %2, %1"
1709 [(set_attr "type" "umull")
1710 (set_attr "predicable" "yes")]
1713 (define_insn "*umulsi3_highpart_v6"
1714 [(set (match_operand:SI 0 "s_register_operand" "=r")
1718 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1719 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1721 (clobber (match_scratch:SI 3 "=r"))]
1722 "TARGET_32BIT && arm_arch6"
1723 "umull%?\\t%3, %0, %2, %1"
1724 [(set_attr "type" "umull")
1725 (set_attr "predicable" "yes")
1726 (set_attr "predicable_short_it" "no")]
1729 (define_insn "mulhisi3"
1730 [(set (match_operand:SI 0 "s_register_operand" "=r")
1731 (mult:SI (sign_extend:SI
1732 (match_operand:HI 1 "s_register_operand" "%r"))
1734 (match_operand:HI 2 "s_register_operand" "r"))))]
1735 "TARGET_DSP_MULTIPLY"
1736 "smulbb%?\\t%0, %1, %2"
1737 [(set_attr "type" "smulxy")
1738 (set_attr "predicable" "yes")]
1741 (define_insn "*mulhisi3tb"
1742 [(set (match_operand:SI 0 "s_register_operand" "=r")
1743 (mult:SI (ashiftrt:SI
1744 (match_operand:SI 1 "s_register_operand" "r")
1747 (match_operand:HI 2 "s_register_operand" "r"))))]
1748 "TARGET_DSP_MULTIPLY"
1749 "smultb%?\\t%0, %1, %2"
1750 [(set_attr "type" "smulxy")
1751 (set_attr "predicable" "yes")
1752 (set_attr "predicable_short_it" "no")]
1755 (define_insn "*mulhisi3bt"
1756 [(set (match_operand:SI 0 "s_register_operand" "=r")
1757 (mult:SI (sign_extend:SI
1758 (match_operand:HI 1 "s_register_operand" "r"))
1760 (match_operand:SI 2 "s_register_operand" "r")
1762 "TARGET_DSP_MULTIPLY"
1763 "smulbt%?\\t%0, %1, %2"
1764 [(set_attr "type" "smulxy")
1765 (set_attr "predicable" "yes")
1766 (set_attr "predicable_short_it" "no")]
1769 (define_insn "*mulhisi3tt"
1770 [(set (match_operand:SI 0 "s_register_operand" "=r")
1771 (mult:SI (ashiftrt:SI
1772 (match_operand:SI 1 "s_register_operand" "r")
1775 (match_operand:SI 2 "s_register_operand" "r")
1777 "TARGET_DSP_MULTIPLY"
1778 "smultt%?\\t%0, %1, %2"
1779 [(set_attr "type" "smulxy")
1780 (set_attr "predicable" "yes")
1781 (set_attr "predicable_short_it" "no")]
1784 (define_insn "maddhisi4"
1785 [(set (match_operand:SI 0 "s_register_operand" "=r")
1786 (plus:SI (mult:SI (sign_extend:SI
1787 (match_operand:HI 1 "s_register_operand" "r"))
1789 (match_operand:HI 2 "s_register_operand" "r")))
1790 (match_operand:SI 3 "s_register_operand" "r")))]
1791 "TARGET_DSP_MULTIPLY"
1792 "smlabb%?\\t%0, %1, %2, %3"
1793 [(set_attr "type" "smlaxy")
1794 (set_attr "predicable" "yes")
1795 (set_attr "predicable_short_it" "no")]
1798 ;; Note: there is no maddhisi4ibt because this one is canonical form
1799 (define_insn "*maddhisi4tb"
1800 [(set (match_operand:SI 0 "s_register_operand" "=r")
1801 (plus:SI (mult:SI (ashiftrt:SI
1802 (match_operand:SI 1 "s_register_operand" "r")
1805 (match_operand:HI 2 "s_register_operand" "r")))
1806 (match_operand:SI 3 "s_register_operand" "r")))]
1807 "TARGET_DSP_MULTIPLY"
1808 "smlatb%?\\t%0, %1, %2, %3"
1809 [(set_attr "type" "smlaxy")
1810 (set_attr "predicable" "yes")
1811 (set_attr "predicable_short_it" "no")]
1814 (define_insn "*maddhisi4tt"
1815 [(set (match_operand:SI 0 "s_register_operand" "=r")
1816 (plus:SI (mult:SI (ashiftrt:SI
1817 (match_operand:SI 1 "s_register_operand" "r")
1820 (match_operand:SI 2 "s_register_operand" "r")
1822 (match_operand:SI 3 "s_register_operand" "r")))]
1823 "TARGET_DSP_MULTIPLY"
1824 "smlatt%?\\t%0, %1, %2, %3"
1825 [(set_attr "type" "smlaxy")
1826 (set_attr "predicable" "yes")
1827 (set_attr "predicable_short_it" "no")]
1830 (define_insn "maddhidi4"
1831 [(set (match_operand:DI 0 "s_register_operand" "=r")
1833 (mult:DI (sign_extend:DI
1834 (match_operand:HI 1 "s_register_operand" "r"))
1836 (match_operand:HI 2 "s_register_operand" "r")))
1837 (match_operand:DI 3 "s_register_operand" "0")))]
1838 "TARGET_DSP_MULTIPLY"
1839 "smlalbb%?\\t%Q0, %R0, %1, %2"
1840 [(set_attr "type" "smlalxy")
1841 (set_attr "predicable" "yes")
1842 (set_attr "predicable_short_it" "no")])
1844 ;; Note: there is no maddhidi4ibt because this one is canonical form
1845 (define_insn "*maddhidi4tb"
1846 [(set (match_operand:DI 0 "s_register_operand" "=r")
1848 (mult:DI (sign_extend:DI
1850 (match_operand:SI 1 "s_register_operand" "r")
1853 (match_operand:HI 2 "s_register_operand" "r")))
1854 (match_operand:DI 3 "s_register_operand" "0")))]
1855 "TARGET_DSP_MULTIPLY"
1856 "smlaltb%?\\t%Q0, %R0, %1, %2"
1857 [(set_attr "type" "smlalxy")
1858 (set_attr "predicable" "yes")
1859 (set_attr "predicable_short_it" "no")])
1861 (define_insn "*maddhidi4tt"
1862 [(set (match_operand:DI 0 "s_register_operand" "=r")
1864 (mult:DI (sign_extend:DI
1866 (match_operand:SI 1 "s_register_operand" "r")
1870 (match_operand:SI 2 "s_register_operand" "r")
1872 (match_operand:DI 3 "s_register_operand" "0")))]
1873 "TARGET_DSP_MULTIPLY"
1874 "smlaltt%?\\t%Q0, %R0, %1, %2"
1875 [(set_attr "type" "smlalxy")
1876 (set_attr "predicable" "yes")
1877 (set_attr "predicable_short_it" "no")])
1879 (define_expand "mulsf3"
1880 [(set (match_operand:SF 0 "s_register_operand" "")
1881 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1882 (match_operand:SF 2 "s_register_operand" "")))]
1883 "TARGET_32BIT && TARGET_HARD_FLOAT"
1887 (define_expand "muldf3"
1888 [(set (match_operand:DF 0 "s_register_operand" "")
1889 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1890 (match_operand:DF 2 "s_register_operand" "")))]
1891 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1897 (define_expand "divsf3"
1898 [(set (match_operand:SF 0 "s_register_operand" "")
1899 (div:SF (match_operand:SF 1 "s_register_operand" "")
1900 (match_operand:SF 2 "s_register_operand" "")))]
1901 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1904 (define_expand "divdf3"
1905 [(set (match_operand:DF 0 "s_register_operand" "")
1906 (div:DF (match_operand:DF 1 "s_register_operand" "")
1907 (match_operand:DF 2 "s_register_operand" "")))]
1908 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1911 ;; Boolean and,ior,xor insns
1913 ;; Split up double word logical operations
1915 ;; Split up simple DImode logical operations. Simply perform the logical
1916 ;; operation on the upper and lower halves of the registers.
1918 [(set (match_operand:DI 0 "s_register_operand" "")
1919 (match_operator:DI 6 "logical_binary_operator"
1920 [(match_operand:DI 1 "s_register_operand" "")
1921 (match_operand:DI 2 "s_register_operand" "")]))]
1922 "TARGET_32BIT && reload_completed
1923 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1924 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1925 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1926 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1929 operands[3] = gen_highpart (SImode, operands[0]);
1930 operands[0] = gen_lowpart (SImode, operands[0]);
1931 operands[4] = gen_highpart (SImode, operands[1]);
1932 operands[1] = gen_lowpart (SImode, operands[1]);
1933 operands[5] = gen_highpart (SImode, operands[2]);
1934 operands[2] = gen_lowpart (SImode, operands[2]);
1939 [(set (match_operand:DI 0 "s_register_operand" "")
1940 (match_operator:DI 6 "logical_binary_operator"
1941 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1942 (match_operand:DI 1 "s_register_operand" "")]))]
1943 "TARGET_32BIT && reload_completed"
1944 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1945 (set (match_dup 3) (match_op_dup:SI 6
1946 [(ashiftrt:SI (match_dup 2) (const_int 31))
1950 operands[3] = gen_highpart (SImode, operands[0]);
1951 operands[0] = gen_lowpart (SImode, operands[0]);
1952 operands[4] = gen_highpart (SImode, operands[1]);
1953 operands[1] = gen_lowpart (SImode, operands[1]);
1954 operands[5] = gen_highpart (SImode, operands[2]);
1955 operands[2] = gen_lowpart (SImode, operands[2]);
1959 ;; The zero extend of operand 2 means we can just copy the high part of
1960 ;; operand1 into operand0.
1962 [(set (match_operand:DI 0 "s_register_operand" "")
1964 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1965 (match_operand:DI 1 "s_register_operand" "")))]
1966 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1967 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1968 (set (match_dup 3) (match_dup 4))]
1971 operands[4] = gen_highpart (SImode, operands[1]);
1972 operands[3] = gen_highpart (SImode, operands[0]);
1973 operands[0] = gen_lowpart (SImode, operands[0]);
1974 operands[1] = gen_lowpart (SImode, operands[1]);
1978 ;; The zero extend of operand 2 means we can just copy the high part of
1979 ;; operand1 into operand0.
1981 [(set (match_operand:DI 0 "s_register_operand" "")
1983 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1984 (match_operand:DI 1 "s_register_operand" "")))]
1985 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1986 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1987 (set (match_dup 3) (match_dup 4))]
1990 operands[4] = gen_highpart (SImode, operands[1]);
1991 operands[3] = gen_highpart (SImode, operands[0]);
1992 operands[0] = gen_lowpart (SImode, operands[0]);
1993 operands[1] = gen_lowpart (SImode, operands[1]);
1997 (define_expand "anddi3"
1998 [(set (match_operand:DI 0 "s_register_operand" "")
1999 (and:DI (match_operand:DI 1 "s_register_operand" "")
2000 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2005 (define_insn_and_split "*anddi3_insn"
2006 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2007 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2008 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2009 "TARGET_32BIT && !TARGET_IWMMXT"
2011 switch (which_alternative)
2013 case 0: /* fall through */
2014 case 6: return "vand\t%P0, %P1, %P2";
2015 case 1: /* fall through */
2016 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2017 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2021 case 5: /* fall through */
2023 default: gcc_unreachable ();
2026 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2027 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2028 [(set (match_dup 3) (match_dup 4))
2029 (set (match_dup 5) (match_dup 6))]
2032 operands[3] = gen_lowpart (SImode, operands[0]);
2033 operands[5] = gen_highpart (SImode, operands[0]);
2035 operands[4] = simplify_gen_binary (AND, SImode,
2036 gen_lowpart (SImode, operands[1]),
2037 gen_lowpart (SImode, operands[2]));
2038 operands[6] = simplify_gen_binary (AND, SImode,
2039 gen_highpart (SImode, operands[1]),
2040 gen_highpart_mode (SImode, DImode, operands[2]));
2043 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2044 multiple,multiple,neon_logic,neon_logic")
2045 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2046 avoid_neon_for_64bits,avoid_neon_for_64bits")
2047 (set_attr "length" "*,*,8,8,8,8,*,*")
2051 (define_insn_and_split "*anddi_zesidi_di"
2052 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2053 (and:DI (zero_extend:DI
2054 (match_operand:SI 2 "s_register_operand" "r,r"))
2055 (match_operand:DI 1 "s_register_operand" "0,r")))]
2058 "TARGET_32BIT && reload_completed"
2059 ; The zero extend of operand 2 clears the high word of the output
2061 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2062 (set (match_dup 3) (const_int 0))]
2065 operands[3] = gen_highpart (SImode, operands[0]);
2066 operands[0] = gen_lowpart (SImode, operands[0]);
2067 operands[1] = gen_lowpart (SImode, operands[1]);
2069 [(set_attr "length" "8")
2070 (set_attr "type" "multiple")]
2073 (define_insn "*anddi_sesdi_di"
2074 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2075 (and:DI (sign_extend:DI
2076 (match_operand:SI 2 "s_register_operand" "r,r"))
2077 (match_operand:DI 1 "s_register_operand" "0,r")))]
2080 [(set_attr "length" "8")
2081 (set_attr "type" "multiple")]
2084 (define_expand "andsi3"
2085 [(set (match_operand:SI 0 "s_register_operand" "")
2086 (and:SI (match_operand:SI 1 "s_register_operand" "")
2087 (match_operand:SI 2 "reg_or_int_operand" "")))]
2092 if (CONST_INT_P (operands[2]))
2094 if (INTVAL (operands[2]) == 255 && arm_arch6)
2096 operands[1] = convert_to_mode (QImode, operands[1], 1);
2097 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2101 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2102 operands[2] = force_reg (SImode, operands[2]);
2105 arm_split_constant (AND, SImode, NULL_RTX,
2106 INTVAL (operands[2]), operands[0],
2108 optimize && can_create_pseudo_p ());
2114 else /* TARGET_THUMB1 */
2116 if (!CONST_INT_P (operands[2]))
2118 rtx tmp = force_reg (SImode, operands[2]);
2119 if (rtx_equal_p (operands[0], operands[1]))
2123 operands[2] = operands[1];
2131 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2133 operands[2] = force_reg (SImode,
2134 GEN_INT (~INTVAL (operands[2])));
2136 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2141 for (i = 9; i <= 31; i++)
2143 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2145 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2149 else if ((HOST_WIDE_INT_1 << i) - 1
2150 == ~INTVAL (operands[2]))
2152 rtx shift = GEN_INT (i);
2153 rtx reg = gen_reg_rtx (SImode);
2155 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2156 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2162 operands[2] = force_reg (SImode, operands[2]);
2168 ; ??? Check split length for Thumb-2
2169 (define_insn_and_split "*arm_andsi3_insn"
2170 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2171 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2172 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2177 bic%?\\t%0, %1, #%B2
2181 && CONST_INT_P (operands[2])
2182 && !(const_ok_for_arm (INTVAL (operands[2]))
2183 || const_ok_for_arm (~INTVAL (operands[2])))"
2184 [(clobber (const_int 0))]
2186 arm_split_constant (AND, SImode, curr_insn,
2187 INTVAL (operands[2]), operands[0], operands[1], 0);
2190 [(set_attr "length" "4,4,4,4,16")
2191 (set_attr "predicable" "yes")
2192 (set_attr "predicable_short_it" "no,yes,no,no,no")
2193 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2196 (define_insn "*andsi3_compare0"
2197 [(set (reg:CC_NOOV CC_REGNUM)
2199 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2200 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2202 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2203 (and:SI (match_dup 1) (match_dup 2)))]
2207 bics%?\\t%0, %1, #%B2
2208 ands%?\\t%0, %1, %2"
2209 [(set_attr "conds" "set")
2210 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2213 (define_insn "*andsi3_compare0_scratch"
2214 [(set (reg:CC_NOOV CC_REGNUM)
2216 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2217 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2219 (clobber (match_scratch:SI 2 "=X,r,X"))]
2223 bics%?\\t%2, %0, #%B1
2225 [(set_attr "conds" "set")
2226 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2229 (define_insn "*zeroextractsi_compare0_scratch"
2230 [(set (reg:CC_NOOV CC_REGNUM)
2231 (compare:CC_NOOV (zero_extract:SI
2232 (match_operand:SI 0 "s_register_operand" "r")
2233 (match_operand 1 "const_int_operand" "n")
2234 (match_operand 2 "const_int_operand" "n"))
2237 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2238 && INTVAL (operands[1]) > 0
2239 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2240 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2242 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2243 << INTVAL (operands[2]));
2244 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2247 [(set_attr "conds" "set")
2248 (set_attr "predicable" "yes")
2249 (set_attr "predicable_short_it" "no")
2250 (set_attr "type" "logics_imm")]
2253 (define_insn_and_split "*ne_zeroextractsi"
2254 [(set (match_operand:SI 0 "s_register_operand" "=r")
2255 (ne:SI (zero_extract:SI
2256 (match_operand:SI 1 "s_register_operand" "r")
2257 (match_operand:SI 2 "const_int_operand" "n")
2258 (match_operand:SI 3 "const_int_operand" "n"))
2260 (clobber (reg:CC CC_REGNUM))]
2262 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2263 && INTVAL (operands[2]) > 0
2264 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2265 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2268 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2269 && INTVAL (operands[2]) > 0
2270 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2271 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2272 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2273 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2275 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2277 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2278 (match_dup 0) (const_int 1)))]
2280 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2281 << INTVAL (operands[3]));
2283 [(set_attr "conds" "clob")
2284 (set (attr "length")
2285 (if_then_else (eq_attr "is_thumb" "yes")
2288 (set_attr "type" "multiple")]
2291 (define_insn_and_split "*ne_zeroextractsi_shifted"
2292 [(set (match_operand:SI 0 "s_register_operand" "=r")
2293 (ne:SI (zero_extract:SI
2294 (match_operand:SI 1 "s_register_operand" "r")
2295 (match_operand:SI 2 "const_int_operand" "n")
2298 (clobber (reg:CC CC_REGNUM))]
2302 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2303 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2305 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2307 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2308 (match_dup 0) (const_int 1)))]
2310 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2312 [(set_attr "conds" "clob")
2313 (set_attr "length" "8")
2314 (set_attr "type" "multiple")]
2317 (define_insn_and_split "*ite_ne_zeroextractsi"
2318 [(set (match_operand:SI 0 "s_register_operand" "=r")
2319 (if_then_else:SI (ne (zero_extract:SI
2320 (match_operand:SI 1 "s_register_operand" "r")
2321 (match_operand:SI 2 "const_int_operand" "n")
2322 (match_operand:SI 3 "const_int_operand" "n"))
2324 (match_operand:SI 4 "arm_not_operand" "rIK")
2326 (clobber (reg:CC CC_REGNUM))]
2328 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2329 && INTVAL (operands[2]) > 0
2330 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2331 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2332 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2335 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2336 && INTVAL (operands[2]) > 0
2337 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2338 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2339 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2340 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2341 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2343 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2345 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2346 (match_dup 0) (match_dup 4)))]
2348 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2349 << INTVAL (operands[3]));
2351 [(set_attr "conds" "clob")
2352 (set_attr "length" "8")
2353 (set_attr "type" "multiple")]
2356 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2357 [(set (match_operand:SI 0 "s_register_operand" "=r")
2358 (if_then_else:SI (ne (zero_extract:SI
2359 (match_operand:SI 1 "s_register_operand" "r")
2360 (match_operand:SI 2 "const_int_operand" "n")
2363 (match_operand:SI 3 "arm_not_operand" "rIK")
2365 (clobber (reg:CC CC_REGNUM))]
2366 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2368 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2369 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2370 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2372 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2374 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2375 (match_dup 0) (match_dup 3)))]
2377 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2379 [(set_attr "conds" "clob")
2380 (set_attr "length" "8")
2381 (set_attr "type" "multiple")]
2384 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2386 [(set (match_operand:SI 0 "s_register_operand" "")
2387 (match_operator:SI 1 "shiftable_operator"
2388 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2389 (match_operand:SI 3 "const_int_operand" "")
2390 (match_operand:SI 4 "const_int_operand" ""))
2391 (match_operand:SI 5 "s_register_operand" "")]))
2392 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2394 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2397 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2400 HOST_WIDE_INT temp = INTVAL (operands[3]);
2402 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2403 operands[4] = GEN_INT (32 - temp);
2408 [(set (match_operand:SI 0 "s_register_operand" "")
2409 (match_operator:SI 1 "shiftable_operator"
2410 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2411 (match_operand:SI 3 "const_int_operand" "")
2412 (match_operand:SI 4 "const_int_operand" ""))
2413 (match_operand:SI 5 "s_register_operand" "")]))
2414 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2416 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2419 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2422 HOST_WIDE_INT temp = INTVAL (operands[3]);
2424 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2425 operands[4] = GEN_INT (32 - temp);
2429 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2430 ;;; represented by the bitfield, then this will produce incorrect results.
2431 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2432 ;;; which have a real bit-field insert instruction, the truncation happens
2433 ;;; in the bit-field insert instruction itself. Since arm does not have a
2434 ;;; bit-field insert instruction, we would have to emit code here to truncate
2435 ;;; the value before we insert. This loses some of the advantage of having
2436 ;;; this insv pattern, so this pattern needs to be reevalutated.
2438 (define_expand "insv"
2439 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2440 (match_operand 1 "general_operand" "")
2441 (match_operand 2 "general_operand" ""))
2442 (match_operand 3 "reg_or_int_operand" ""))]
2443 "TARGET_ARM || arm_arch_thumb2"
2446 int start_bit = INTVAL (operands[2]);
2447 int width = INTVAL (operands[1]);
2448 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2449 rtx target, subtarget;
2451 if (arm_arch_thumb2)
2453 if (unaligned_access && MEM_P (operands[0])
2454 && s_register_operand (operands[3], GET_MODE (operands[3]))
2455 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2459 if (BYTES_BIG_ENDIAN)
2460 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2465 base_addr = adjust_address (operands[0], SImode,
2466 start_bit / BITS_PER_UNIT);
2467 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2471 rtx tmp = gen_reg_rtx (HImode);
2473 base_addr = adjust_address (operands[0], HImode,
2474 start_bit / BITS_PER_UNIT);
2475 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2476 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2480 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2482 bool use_bfi = TRUE;
2484 if (CONST_INT_P (operands[3]))
2486 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2490 emit_insn (gen_insv_zero (operands[0], operands[1],
2495 /* See if the set can be done with a single orr instruction. */
2496 if (val == mask && const_ok_for_arm (val << start_bit))
2502 if (!REG_P (operands[3]))
2503 operands[3] = force_reg (SImode, operands[3]);
2505 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2514 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2517 target = copy_rtx (operands[0]);
2518 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2519 subreg as the final target. */
2520 if (GET_CODE (target) == SUBREG)
2522 subtarget = gen_reg_rtx (SImode);
2523 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2524 < GET_MODE_SIZE (SImode))
2525 target = SUBREG_REG (target);
2530 if (CONST_INT_P (operands[3]))
2532 /* Since we are inserting a known constant, we may be able to
2533 reduce the number of bits that we have to clear so that
2534 the mask becomes simple. */
2535 /* ??? This code does not check to see if the new mask is actually
2536 simpler. It may not be. */
2537 rtx op1 = gen_reg_rtx (SImode);
2538 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2539 start of this pattern. */
2540 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2541 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2543 emit_insn (gen_andsi3 (op1, operands[0],
2544 gen_int_mode (~mask2, SImode)));
2545 emit_insn (gen_iorsi3 (subtarget, op1,
2546 gen_int_mode (op3_value << start_bit, SImode)));
2548 else if (start_bit == 0
2549 && !(const_ok_for_arm (mask)
2550 || const_ok_for_arm (~mask)))
2552 /* A Trick, since we are setting the bottom bits in the word,
2553 we can shift operand[3] up, operand[0] down, OR them together
2554 and rotate the result back again. This takes 3 insns, and
2555 the third might be mergeable into another op. */
2556 /* The shift up copes with the possibility that operand[3] is
2557 wider than the bitfield. */
2558 rtx op0 = gen_reg_rtx (SImode);
2559 rtx op1 = gen_reg_rtx (SImode);
2561 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2562 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2563 emit_insn (gen_iorsi3 (op1, op1, op0));
2564 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2566 else if ((width + start_bit == 32)
2567 && !(const_ok_for_arm (mask)
2568 || const_ok_for_arm (~mask)))
2570 /* Similar trick, but slightly less efficient. */
2572 rtx op0 = gen_reg_rtx (SImode);
2573 rtx op1 = gen_reg_rtx (SImode);
2575 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2576 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2577 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2578 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2582 rtx op0 = gen_int_mode (mask, SImode);
2583 rtx op1 = gen_reg_rtx (SImode);
2584 rtx op2 = gen_reg_rtx (SImode);
2586 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2588 rtx tmp = gen_reg_rtx (SImode);
2590 emit_insn (gen_movsi (tmp, op0));
2594 /* Mask out any bits in operand[3] that are not needed. */
2595 emit_insn (gen_andsi3 (op1, operands[3], op0));
2597 if (CONST_INT_P (op0)
2598 && (const_ok_for_arm (mask << start_bit)
2599 || const_ok_for_arm (~(mask << start_bit))))
2601 op0 = gen_int_mode (~(mask << start_bit), SImode);
2602 emit_insn (gen_andsi3 (op2, operands[0], op0));
2606 if (CONST_INT_P (op0))
2608 rtx tmp = gen_reg_rtx (SImode);
2610 emit_insn (gen_movsi (tmp, op0));
2615 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2617 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2621 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2623 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2626 if (subtarget != target)
2628 /* If TARGET is still a SUBREG, then it must be wider than a word,
2629 so we must be careful only to set the subword we were asked to. */
2630 if (GET_CODE (target) == SUBREG)
2631 emit_move_insn (target, subtarget);
2633 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2640 (define_insn "insv_zero"
2641 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2642 (match_operand:SI 1 "const_int_M_operand" "M")
2643 (match_operand:SI 2 "const_int_M_operand" "M"))
2647 [(set_attr "length" "4")
2648 (set_attr "predicable" "yes")
2649 (set_attr "predicable_short_it" "no")
2650 (set_attr "type" "bfm")]
2653 (define_insn "insv_t2"
2654 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2655 (match_operand:SI 1 "const_int_M_operand" "M")
2656 (match_operand:SI 2 "const_int_M_operand" "M"))
2657 (match_operand:SI 3 "s_register_operand" "r"))]
2659 "bfi%?\t%0, %3, %2, %1"
2660 [(set_attr "length" "4")
2661 (set_attr "predicable" "yes")
2662 (set_attr "predicable_short_it" "no")
2663 (set_attr "type" "bfm")]
2666 ; constants for op 2 will never be given to these patterns.
2667 (define_insn_and_split "*anddi_notdi_di"
2668 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2669 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2670 (match_operand:DI 2 "s_register_operand" "r,0")))]
2673 "TARGET_32BIT && reload_completed
2674 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2675 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2676 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2677 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2680 operands[3] = gen_highpart (SImode, operands[0]);
2681 operands[0] = gen_lowpart (SImode, operands[0]);
2682 operands[4] = gen_highpart (SImode, operands[1]);
2683 operands[1] = gen_lowpart (SImode, operands[1]);
2684 operands[5] = gen_highpart (SImode, operands[2]);
2685 operands[2] = gen_lowpart (SImode, operands[2]);
2687 [(set_attr "length" "8")
2688 (set_attr "predicable" "yes")
2689 (set_attr "type" "multiple")]
2692 (define_insn_and_split "*anddi_notzesidi_di"
2693 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2694 (and:DI (not:DI (zero_extend:DI
2695 (match_operand:SI 2 "s_register_operand" "r,r")))
2696 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2699 bic%?\\t%Q0, %Q1, %2
2701 ; (not (zero_extend ...)) allows us to just copy the high word from
2702 ; operand1 to operand0.
2705 && operands[0] != operands[1]"
2706 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2707 (set (match_dup 3) (match_dup 4))]
2710 operands[3] = gen_highpart (SImode, operands[0]);
2711 operands[0] = gen_lowpart (SImode, operands[0]);
2712 operands[4] = gen_highpart (SImode, operands[1]);
2713 operands[1] = gen_lowpart (SImode, operands[1]);
2715 [(set_attr "length" "4,8")
2716 (set_attr "predicable" "yes")
2717 (set_attr "predicable_short_it" "no")
2718 (set_attr "type" "multiple")]
2721 (define_insn_and_split "*anddi_notdi_zesidi"
2722 [(set (match_operand:DI 0 "s_register_operand" "=r")
2723 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2725 (match_operand:SI 1 "s_register_operand" "r"))))]
2728 "TARGET_32BIT && reload_completed"
2729 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2730 (set (match_dup 3) (const_int 0))]
2733 operands[3] = gen_highpart (SImode, operands[0]);
2734 operands[0] = gen_lowpart (SImode, operands[0]);
2735 operands[2] = gen_lowpart (SImode, operands[2]);
2737 [(set_attr "length" "8")
2738 (set_attr "predicable" "yes")
2739 (set_attr "predicable_short_it" "no")
2740 (set_attr "type" "multiple")]
2743 (define_insn_and_split "*anddi_notsesidi_di"
2744 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2745 (and:DI (not:DI (sign_extend:DI
2746 (match_operand:SI 2 "s_register_operand" "r,r")))
2747 (match_operand:DI 1 "s_register_operand" "0,r")))]
2750 "TARGET_32BIT && reload_completed"
2751 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2752 (set (match_dup 3) (and:SI (not:SI
2753 (ashiftrt:SI (match_dup 2) (const_int 31)))
2757 operands[3] = gen_highpart (SImode, operands[0]);
2758 operands[0] = gen_lowpart (SImode, operands[0]);
2759 operands[4] = gen_highpart (SImode, operands[1]);
2760 operands[1] = gen_lowpart (SImode, operands[1]);
2762 [(set_attr "length" "8")
2763 (set_attr "predicable" "yes")
2764 (set_attr "predicable_short_it" "no")
2765 (set_attr "type" "multiple")]
2768 (define_insn "andsi_notsi_si"
2769 [(set (match_operand:SI 0 "s_register_operand" "=r")
2770 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2771 (match_operand:SI 1 "s_register_operand" "r")))]
2773 "bic%?\\t%0, %1, %2"
2774 [(set_attr "predicable" "yes")
2775 (set_attr "predicable_short_it" "no")
2776 (set_attr "type" "logic_reg")]
2779 (define_insn "andsi_not_shiftsi_si"
2780 [(set (match_operand:SI 0 "s_register_operand" "=r")
2781 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2782 [(match_operand:SI 2 "s_register_operand" "r")
2783 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2784 (match_operand:SI 1 "s_register_operand" "r")))]
2786 "bic%?\\t%0, %1, %2%S4"
2787 [(set_attr "predicable" "yes")
2788 (set_attr "shift" "2")
2789 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2790 (const_string "logic_shift_imm")
2791 (const_string "logic_shift_reg")))]
2794 ;; Shifted bics pattern used to set up CC status register and not reusing
2795 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
2796 ;; does not support shift by register.
2797 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
2798 [(set (reg:CC_NOOV CC_REGNUM)
2800 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2801 [(match_operand:SI 1 "s_register_operand" "r")
2802 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2803 (match_operand:SI 3 "s_register_operand" "r"))
2805 (clobber (match_scratch:SI 4 "=r"))]
2806 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2807 "bics%?\\t%4, %3, %1%S0"
2808 [(set_attr "predicable" "yes")
2809 (set_attr "predicable_short_it" "no")
2810 (set_attr "conds" "set")
2811 (set_attr "shift" "1")
2812 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2813 (const_string "logic_shift_imm")
2814 (const_string "logic_shift_reg")))]
2817 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
2818 ;; getting reused later.
2819 (define_insn "andsi_not_shiftsi_si_scc"
2820 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2822 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2823 [(match_operand:SI 1 "s_register_operand" "r")
2824 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2825 (match_operand:SI 3 "s_register_operand" "r"))
2827 (set (match_operand:SI 4 "s_register_operand" "=r")
2828 (and:SI (not:SI (match_op_dup 0
2832 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2833 "bics%?\\t%4, %3, %1%S0"
2834 [(set_attr "predicable" "yes")
2835 (set_attr "predicable_short_it" "no")
2836 (set_attr "conds" "set")
2837 (set_attr "shift" "1")
2838 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2839 (const_string "logic_shift_imm")
2840 (const_string "logic_shift_reg")))]
2843 (define_insn "*andsi_notsi_si_compare0"
2844 [(set (reg:CC_NOOV CC_REGNUM)
2846 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2847 (match_operand:SI 1 "s_register_operand" "r"))
2849 (set (match_operand:SI 0 "s_register_operand" "=r")
2850 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2853 [(set_attr "conds" "set")
2854 (set_attr "type" "logics_shift_reg")]
2857 (define_insn "*andsi_notsi_si_compare0_scratch"
2858 [(set (reg:CC_NOOV CC_REGNUM)
2860 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2861 (match_operand:SI 1 "s_register_operand" "r"))
2863 (clobber (match_scratch:SI 0 "=r"))]
2866 [(set_attr "conds" "set")
2867 (set_attr "type" "logics_shift_reg")]
2870 (define_expand "iordi3"
2871 [(set (match_operand:DI 0 "s_register_operand" "")
2872 (ior:DI (match_operand:DI 1 "s_register_operand" "")
2873 (match_operand:DI 2 "neon_logic_op2" "")))]
2878 (define_insn_and_split "*iordi3_insn"
2879 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2880 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2881 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
2882 "TARGET_32BIT && !TARGET_IWMMXT"
2884 switch (which_alternative)
2886 case 0: /* fall through */
2887 case 6: return "vorr\t%P0, %P1, %P2";
2888 case 1: /* fall through */
2889 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2890 DImode, 0, VALID_NEON_QREG_MODE (DImode));
2896 default: gcc_unreachable ();
2899 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2900 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2901 [(set (match_dup 3) (match_dup 4))
2902 (set (match_dup 5) (match_dup 6))]
2905 operands[3] = gen_lowpart (SImode, operands[0]);
2906 operands[5] = gen_highpart (SImode, operands[0]);
2908 operands[4] = simplify_gen_binary (IOR, SImode,
2909 gen_lowpart (SImode, operands[1]),
2910 gen_lowpart (SImode, operands[2]));
2911 operands[6] = simplify_gen_binary (IOR, SImode,
2912 gen_highpart (SImode, operands[1]),
2913 gen_highpart_mode (SImode, DImode, operands[2]));
2916 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2917 multiple,neon_logic,neon_logic")
2918 (set_attr "length" "*,*,8,8,8,8,*,*")
2919 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
2922 (define_insn "*iordi_zesidi_di"
2923 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2924 (ior:DI (zero_extend:DI
2925 (match_operand:SI 2 "s_register_operand" "r,r"))
2926 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2929 orr%?\\t%Q0, %Q1, %2
2931 [(set_attr "length" "4,8")
2932 (set_attr "predicable" "yes")
2933 (set_attr "predicable_short_it" "no")
2934 (set_attr "type" "logic_reg,multiple")]
2937 (define_insn "*iordi_sesidi_di"
2938 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2939 (ior:DI (sign_extend:DI
2940 (match_operand:SI 2 "s_register_operand" "r,r"))
2941 (match_operand:DI 1 "s_register_operand" "0,r")))]
2944 [(set_attr "length" "8")
2945 (set_attr "predicable" "yes")
2946 (set_attr "type" "multiple")]
2949 (define_expand "iorsi3"
2950 [(set (match_operand:SI 0 "s_register_operand" "")
2951 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2952 (match_operand:SI 2 "reg_or_int_operand" "")))]
2955 if (CONST_INT_P (operands[2]))
2959 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
2960 operands[2] = force_reg (SImode, operands[2]);
2963 arm_split_constant (IOR, SImode, NULL_RTX,
2964 INTVAL (operands[2]), operands[0],
2966 optimize && can_create_pseudo_p ());
2970 else /* TARGET_THUMB1 */
2972 rtx tmp = force_reg (SImode, operands[2]);
2973 if (rtx_equal_p (operands[0], operands[1]))
2977 operands[2] = operands[1];
2985 (define_insn_and_split "*iorsi3_insn"
2986 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2987 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2988 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2993 orn%?\\t%0, %1, #%B2
2997 && CONST_INT_P (operands[2])
2998 && !(const_ok_for_arm (INTVAL (operands[2]))
2999 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3000 [(clobber (const_int 0))]
3002 arm_split_constant (IOR, SImode, curr_insn,
3003 INTVAL (operands[2]), operands[0], operands[1], 0);
3006 [(set_attr "length" "4,4,4,4,16")
3007 (set_attr "arch" "32,t2,t2,32,32")
3008 (set_attr "predicable" "yes")
3009 (set_attr "predicable_short_it" "no,yes,no,no,no")
3010 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3014 [(match_scratch:SI 3 "r")
3015 (set (match_operand:SI 0 "arm_general_register_operand" "")
3016 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3017 (match_operand:SI 2 "const_int_operand" "")))]
3019 && !const_ok_for_arm (INTVAL (operands[2]))
3020 && const_ok_for_arm (~INTVAL (operands[2]))"
3021 [(set (match_dup 3) (match_dup 2))
3022 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3026 (define_insn "*iorsi3_compare0"
3027 [(set (reg:CC_NOOV CC_REGNUM)
3028 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3029 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3031 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3032 (ior:SI (match_dup 1) (match_dup 2)))]
3034 "orrs%?\\t%0, %1, %2"
3035 [(set_attr "conds" "set")
3036 (set_attr "type" "logics_imm,logics_reg")]
3039 (define_insn "*iorsi3_compare0_scratch"
3040 [(set (reg:CC_NOOV CC_REGNUM)
3041 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3042 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3044 (clobber (match_scratch:SI 0 "=r,r"))]
3046 "orrs%?\\t%0, %1, %2"
3047 [(set_attr "conds" "set")
3048 (set_attr "type" "logics_imm,logics_reg")]
3051 (define_expand "xordi3"
3052 [(set (match_operand:DI 0 "s_register_operand" "")
3053 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3054 (match_operand:DI 2 "arm_xordi_operand" "")))]
3059 (define_insn_and_split "*xordi3_insn"
3060 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3061 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3062 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3063 "TARGET_32BIT && !TARGET_IWMMXT"
3065 switch (which_alternative)
3070 case 4: /* fall through */
3072 case 0: /* fall through */
3073 case 5: return "veor\t%P0, %P1, %P2";
3074 default: gcc_unreachable ();
3077 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3078 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3079 [(set (match_dup 3) (match_dup 4))
3080 (set (match_dup 5) (match_dup 6))]
3083 operands[3] = gen_lowpart (SImode, operands[0]);
3084 operands[5] = gen_highpart (SImode, operands[0]);
3086 operands[4] = simplify_gen_binary (XOR, SImode,
3087 gen_lowpart (SImode, operands[1]),
3088 gen_lowpart (SImode, operands[2]));
3089 operands[6] = simplify_gen_binary (XOR, SImode,
3090 gen_highpart (SImode, operands[1]),
3091 gen_highpart_mode (SImode, DImode, operands[2]));
3094 [(set_attr "length" "*,8,8,8,8,*")
3095 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3096 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3099 (define_insn "*xordi_zesidi_di"
3100 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3101 (xor:DI (zero_extend:DI
3102 (match_operand:SI 2 "s_register_operand" "r,r"))
3103 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3106 eor%?\\t%Q0, %Q1, %2
3108 [(set_attr "length" "4,8")
3109 (set_attr "predicable" "yes")
3110 (set_attr "predicable_short_it" "no")
3111 (set_attr "type" "logic_reg")]
3114 (define_insn "*xordi_sesidi_di"
3115 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3116 (xor:DI (sign_extend:DI
3117 (match_operand:SI 2 "s_register_operand" "r,r"))
3118 (match_operand:DI 1 "s_register_operand" "0,r")))]
3121 [(set_attr "length" "8")
3122 (set_attr "predicable" "yes")
3123 (set_attr "type" "multiple")]
3126 (define_expand "xorsi3"
3127 [(set (match_operand:SI 0 "s_register_operand" "")
3128 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3129 (match_operand:SI 2 "reg_or_int_operand" "")))]
3131 "if (CONST_INT_P (operands[2]))
3135 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3136 operands[2] = force_reg (SImode, operands[2]);
3139 arm_split_constant (XOR, SImode, NULL_RTX,
3140 INTVAL (operands[2]), operands[0],
3142 optimize && can_create_pseudo_p ());
3146 else /* TARGET_THUMB1 */
3148 rtx tmp = force_reg (SImode, operands[2]);
3149 if (rtx_equal_p (operands[0], operands[1]))
3153 operands[2] = operands[1];
3160 (define_insn_and_split "*arm_xorsi3"
3161 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3162 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3163 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3171 && CONST_INT_P (operands[2])
3172 && !const_ok_for_arm (INTVAL (operands[2]))"
3173 [(clobber (const_int 0))]
3175 arm_split_constant (XOR, SImode, curr_insn,
3176 INTVAL (operands[2]), operands[0], operands[1], 0);
3179 [(set_attr "length" "4,4,4,16")
3180 (set_attr "predicable" "yes")
3181 (set_attr "predicable_short_it" "no,yes,no,no")
3182 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3185 (define_insn "*xorsi3_compare0"
3186 [(set (reg:CC_NOOV CC_REGNUM)
3187 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3188 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3190 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3191 (xor:SI (match_dup 1) (match_dup 2)))]
3193 "eors%?\\t%0, %1, %2"
3194 [(set_attr "conds" "set")
3195 (set_attr "type" "logics_imm,logics_reg")]
3198 (define_insn "*xorsi3_compare0_scratch"
3199 [(set (reg:CC_NOOV CC_REGNUM)
3200 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3201 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3205 [(set_attr "conds" "set")
3206 (set_attr "type" "logics_imm,logics_reg")]
3209 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3210 ; (NOT D) we can sometimes merge the final NOT into one of the following
3214 [(set (match_operand:SI 0 "s_register_operand" "")
3215 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3216 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3217 (match_operand:SI 3 "arm_rhs_operand" "")))
3218 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3220 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3221 (not:SI (match_dup 3))))
3222 (set (match_dup 0) (not:SI (match_dup 4)))]
3226 (define_insn_and_split "*andsi_iorsi3_notsi"
3227 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3228 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3229 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3230 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3232 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3233 "&& reload_completed"
3234 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3235 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3237 /* If operands[3] is a constant make sure to fold the NOT into it
3238 to avoid creating a NOT of a CONST_INT. */
3239 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3240 if (CONST_INT_P (not_rtx))
3242 operands[4] = operands[0];
3243 operands[5] = not_rtx;
3247 operands[5] = operands[0];
3248 operands[4] = not_rtx;
3251 [(set_attr "length" "8")
3252 (set_attr "ce_count" "2")
3253 (set_attr "predicable" "yes")
3254 (set_attr "predicable_short_it" "no")
3255 (set_attr "type" "multiple")]
3258 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3259 ; insns are available?
3261 [(set (match_operand:SI 0 "s_register_operand" "")
3262 (match_operator:SI 1 "logical_binary_operator"
3263 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3264 (match_operand:SI 3 "const_int_operand" "")
3265 (match_operand:SI 4 "const_int_operand" ""))
3266 (match_operator:SI 9 "logical_binary_operator"
3267 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3268 (match_operand:SI 6 "const_int_operand" ""))
3269 (match_operand:SI 7 "s_register_operand" "")])]))
3270 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3272 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3273 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3276 [(ashift:SI (match_dup 2) (match_dup 4))
3280 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3283 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3287 [(set (match_operand:SI 0 "s_register_operand" "")
3288 (match_operator:SI 1 "logical_binary_operator"
3289 [(match_operator:SI 9 "logical_binary_operator"
3290 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3291 (match_operand:SI 6 "const_int_operand" ""))
3292 (match_operand:SI 7 "s_register_operand" "")])
3293 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3294 (match_operand:SI 3 "const_int_operand" "")
3295 (match_operand:SI 4 "const_int_operand" ""))]))
3296 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3298 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3299 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3302 [(ashift:SI (match_dup 2) (match_dup 4))
3306 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3309 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3313 [(set (match_operand:SI 0 "s_register_operand" "")
3314 (match_operator:SI 1 "logical_binary_operator"
3315 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3316 (match_operand:SI 3 "const_int_operand" "")
3317 (match_operand:SI 4 "const_int_operand" ""))
3318 (match_operator:SI 9 "logical_binary_operator"
3319 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3320 (match_operand:SI 6 "const_int_operand" ""))
3321 (match_operand:SI 7 "s_register_operand" "")])]))
3322 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3324 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3325 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3328 [(ashift:SI (match_dup 2) (match_dup 4))
3332 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3335 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3339 [(set (match_operand:SI 0 "s_register_operand" "")
3340 (match_operator:SI 1 "logical_binary_operator"
3341 [(match_operator:SI 9 "logical_binary_operator"
3342 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3343 (match_operand:SI 6 "const_int_operand" ""))
3344 (match_operand:SI 7 "s_register_operand" "")])
3345 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3346 (match_operand:SI 3 "const_int_operand" "")
3347 (match_operand:SI 4 "const_int_operand" ""))]))
3348 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3350 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3351 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3354 [(ashift:SI (match_dup 2) (match_dup 4))
3358 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3361 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3365 ;; Minimum and maximum insns
3367 (define_expand "smaxsi3"
3369 (set (match_operand:SI 0 "s_register_operand" "")
3370 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3371 (match_operand:SI 2 "arm_rhs_operand" "")))
3372 (clobber (reg:CC CC_REGNUM))])]
3375 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3377 /* No need for a clobber of the condition code register here. */
3378 emit_insn (gen_rtx_SET (operands[0],
3379 gen_rtx_SMAX (SImode, operands[1],
3385 (define_insn "*smax_0"
3386 [(set (match_operand:SI 0 "s_register_operand" "=r")
3387 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3390 "bic%?\\t%0, %1, %1, asr #31"
3391 [(set_attr "predicable" "yes")
3392 (set_attr "predicable_short_it" "no")
3393 (set_attr "type" "logic_shift_reg")]
3396 (define_insn "*smax_m1"
3397 [(set (match_operand:SI 0 "s_register_operand" "=r")
3398 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3401 "orr%?\\t%0, %1, %1, asr #31"
3402 [(set_attr "predicable" "yes")
3403 (set_attr "predicable_short_it" "no")
3404 (set_attr "type" "logic_shift_reg")]
3407 (define_insn_and_split "*arm_smax_insn"
3408 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3409 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3410 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3411 (clobber (reg:CC CC_REGNUM))]
3414 ; cmp\\t%1, %2\;movlt\\t%0, %2
3415 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3417 [(set (reg:CC CC_REGNUM)
3418 (compare:CC (match_dup 1) (match_dup 2)))
3420 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3424 [(set_attr "conds" "clob")
3425 (set_attr "length" "8,12")
3426 (set_attr "type" "multiple")]
3429 (define_expand "sminsi3"
3431 (set (match_operand:SI 0 "s_register_operand" "")
3432 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3433 (match_operand:SI 2 "arm_rhs_operand" "")))
3434 (clobber (reg:CC CC_REGNUM))])]
3437 if (operands[2] == const0_rtx)
3439 /* No need for a clobber of the condition code register here. */
3440 emit_insn (gen_rtx_SET (operands[0],
3441 gen_rtx_SMIN (SImode, operands[1],
3447 (define_insn "*smin_0"
3448 [(set (match_operand:SI 0 "s_register_operand" "=r")
3449 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3452 "and%?\\t%0, %1, %1, asr #31"
3453 [(set_attr "predicable" "yes")
3454 (set_attr "predicable_short_it" "no")
3455 (set_attr "type" "logic_shift_reg")]
3458 (define_insn_and_split "*arm_smin_insn"
3459 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3460 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3461 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3462 (clobber (reg:CC CC_REGNUM))]
3465 ; cmp\\t%1, %2\;movge\\t%0, %2
3466 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3468 [(set (reg:CC CC_REGNUM)
3469 (compare:CC (match_dup 1) (match_dup 2)))
3471 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3475 [(set_attr "conds" "clob")
3476 (set_attr "length" "8,12")
3477 (set_attr "type" "multiple,multiple")]
3480 (define_expand "umaxsi3"
3482 (set (match_operand:SI 0 "s_register_operand" "")
3483 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3484 (match_operand:SI 2 "arm_rhs_operand" "")))
3485 (clobber (reg:CC CC_REGNUM))])]
3490 (define_insn_and_split "*arm_umaxsi3"
3491 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3492 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3493 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3494 (clobber (reg:CC CC_REGNUM))]
3497 ; cmp\\t%1, %2\;movcc\\t%0, %2
3498 ; cmp\\t%1, %2\;movcs\\t%0, %1
3499 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3501 [(set (reg:CC CC_REGNUM)
3502 (compare:CC (match_dup 1) (match_dup 2)))
3504 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3508 [(set_attr "conds" "clob")
3509 (set_attr "length" "8,8,12")
3510 (set_attr "type" "store1")]
3513 (define_expand "uminsi3"
3515 (set (match_operand:SI 0 "s_register_operand" "")
3516 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3517 (match_operand:SI 2 "arm_rhs_operand" "")))
3518 (clobber (reg:CC CC_REGNUM))])]
3523 (define_insn_and_split "*arm_uminsi3"
3524 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3525 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3526 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3527 (clobber (reg:CC CC_REGNUM))]
3530 ; cmp\\t%1, %2\;movcs\\t%0, %2
3531 ; cmp\\t%1, %2\;movcc\\t%0, %1
3532 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3534 [(set (reg:CC CC_REGNUM)
3535 (compare:CC (match_dup 1) (match_dup 2)))
3537 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3541 [(set_attr "conds" "clob")
3542 (set_attr "length" "8,8,12")
3543 (set_attr "type" "store1")]
3546 (define_insn "*store_minmaxsi"
3547 [(set (match_operand:SI 0 "memory_operand" "=m")
3548 (match_operator:SI 3 "minmax_operator"
3549 [(match_operand:SI 1 "s_register_operand" "r")
3550 (match_operand:SI 2 "s_register_operand" "r")]))
3551 (clobber (reg:CC CC_REGNUM))]
3552 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3554 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3555 operands[1], operands[2]);
3556 output_asm_insn (\"cmp\\t%1, %2\", operands);
3558 output_asm_insn (\"ite\t%d3\", operands);
3559 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3560 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3563 [(set_attr "conds" "clob")
3564 (set (attr "length")
3565 (if_then_else (eq_attr "is_thumb" "yes")
3568 (set_attr "type" "store1")]
3571 ; Reject the frame pointer in operand[1], since reloading this after
3572 ; it has been eliminated can cause carnage.
3573 (define_insn "*minmax_arithsi"
3574 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3575 (match_operator:SI 4 "shiftable_operator"
3576 [(match_operator:SI 5 "minmax_operator"
3577 [(match_operand:SI 2 "s_register_operand" "r,r")
3578 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3579 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3580 (clobber (reg:CC CC_REGNUM))]
3581 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3584 enum rtx_code code = GET_CODE (operands[4]);
3587 if (which_alternative != 0 || operands[3] != const0_rtx
3588 || (code != PLUS && code != IOR && code != XOR))
3593 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3594 operands[2], operands[3]);
3595 output_asm_insn (\"cmp\\t%2, %3\", operands);
3599 output_asm_insn (\"ite\\t%d5\", operands);
3601 output_asm_insn (\"it\\t%d5\", operands);
3603 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3605 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3608 [(set_attr "conds" "clob")
3609 (set (attr "length")
3610 (if_then_else (eq_attr "is_thumb" "yes")
3613 (set_attr "type" "multiple")]
3616 ; Reject the frame pointer in operand[1], since reloading this after
3617 ; it has been eliminated can cause carnage.
3618 (define_insn_and_split "*minmax_arithsi_non_canon"
3619 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3621 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3622 (match_operator:SI 4 "minmax_operator"
3623 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3624 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3625 (clobber (reg:CC CC_REGNUM))]
3626 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3627 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3629 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3630 [(set (reg:CC CC_REGNUM)
3631 (compare:CC (match_dup 2) (match_dup 3)))
3633 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3635 (minus:SI (match_dup 1)
3637 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3641 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3642 operands[2], operands[3]);
3643 enum rtx_code rc = minmax_code (operands[4]);
3644 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3645 operands[2], operands[3]);
3647 if (mode == CCFPmode || mode == CCFPEmode)
3648 rc = reverse_condition_maybe_unordered (rc);
3650 rc = reverse_condition (rc);
3651 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3652 if (CONST_INT_P (operands[3]))
3653 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3655 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3657 [(set_attr "conds" "clob")
3658 (set (attr "length")
3659 (if_then_else (eq_attr "is_thumb" "yes")
3662 (set_attr "type" "multiple")]
3665 (define_code_iterator SAT [smin smax])
3666 (define_code_iterator SATrev [smin smax])
3667 (define_code_attr SATlo [(smin "1") (smax "2")])
3668 (define_code_attr SAThi [(smin "2") (smax "1")])
3670 (define_insn "*satsi_<SAT:code>"
3671 [(set (match_operand:SI 0 "s_register_operand" "=r")
3672 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3673 (match_operand:SI 1 "const_int_operand" "i"))
3674 (match_operand:SI 2 "const_int_operand" "i")))]
3675 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3676 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3680 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3681 &mask, &signed_sat))
3684 operands[1] = GEN_INT (mask);
3686 return "ssat%?\t%0, %1, %3";
3688 return "usat%?\t%0, %1, %3";
3690 [(set_attr "predicable" "yes")
3691 (set_attr "predicable_short_it" "no")
3692 (set_attr "type" "alus_imm")]
3695 (define_insn "*satsi_<SAT:code>_shift"
3696 [(set (match_operand:SI 0 "s_register_operand" "=r")
3697 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3698 [(match_operand:SI 4 "s_register_operand" "r")
3699 (match_operand:SI 5 "const_int_operand" "i")])
3700 (match_operand:SI 1 "const_int_operand" "i"))
3701 (match_operand:SI 2 "const_int_operand" "i")))]
3702 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3703 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3707 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3708 &mask, &signed_sat))
3711 operands[1] = GEN_INT (mask);
3713 return "ssat%?\t%0, %1, %4%S3";
3715 return "usat%?\t%0, %1, %4%S3";
3717 [(set_attr "predicable" "yes")
3718 (set_attr "predicable_short_it" "no")
3719 (set_attr "shift" "3")
3720 (set_attr "type" "logic_shift_reg")])
3722 ;; Shift and rotation insns
3724 (define_expand "ashldi3"
3725 [(set (match_operand:DI 0 "s_register_operand" "")
3726 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3727 (match_operand:SI 2 "general_operand" "")))]
3732 /* Delay the decision whether to use NEON or core-regs until
3733 register allocation. */
3734 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3739 /* Only the NEON case can handle in-memory shift counts. */
3740 if (!reg_or_int_operand (operands[2], SImode))
3741 operands[2] = force_reg (SImode, operands[2]);
3744 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3745 ; /* No special preparation statements; expand pattern as above. */
3748 rtx scratch1, scratch2;
3750 if (operands[2] == CONST1_RTX (SImode))
3752 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3756 /* Ideally we should use iwmmxt here if we could know that operands[1]
3757 ends up already living in an iwmmxt register. Otherwise it's
3758 cheaper to have the alternate code being generated than moving
3759 values to iwmmxt regs and back. */
3761 /* If we're optimizing for size, we prefer the libgcc calls. */
3762 if (optimize_function_for_size_p (cfun))
3765 /* Expand operation using core-registers.
3766 'FAIL' would achieve the same thing, but this is a bit smarter. */
3767 scratch1 = gen_reg_rtx (SImode);
3768 scratch2 = gen_reg_rtx (SImode);
3769 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3770 operands[2], scratch1, scratch2);
3776 (define_insn "arm_ashldi3_1bit"
3777 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3778 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3780 (clobber (reg:CC CC_REGNUM))]
3782 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3783 [(set_attr "conds" "clob")
3784 (set_attr "length" "8")
3785 (set_attr "type" "multiple")]
3788 (define_expand "ashlsi3"
3789 [(set (match_operand:SI 0 "s_register_operand" "")
3790 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3791 (match_operand:SI 2 "arm_rhs_operand" "")))]
3794 if (CONST_INT_P (operands[2])
3795 && (UINTVAL (operands[2])) > 31)
3797 emit_insn (gen_movsi (operands[0], const0_rtx));
3803 (define_expand "ashrdi3"
3804 [(set (match_operand:DI 0 "s_register_operand" "")
3805 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3806 (match_operand:SI 2 "reg_or_int_operand" "")))]
3811 /* Delay the decision whether to use NEON or core-regs until
3812 register allocation. */
3813 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3817 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3818 ; /* No special preparation statements; expand pattern as above. */
3821 rtx scratch1, scratch2;
3823 if (operands[2] == CONST1_RTX (SImode))
3825 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3829 /* Ideally we should use iwmmxt here if we could know that operands[1]
3830 ends up already living in an iwmmxt register. Otherwise it's
3831 cheaper to have the alternate code being generated than moving
3832 values to iwmmxt regs and back. */
3834 /* If we're optimizing for size, we prefer the libgcc calls. */
3835 if (optimize_function_for_size_p (cfun))
3838 /* Expand operation using core-registers.
3839 'FAIL' would achieve the same thing, but this is a bit smarter. */
3840 scratch1 = gen_reg_rtx (SImode);
3841 scratch2 = gen_reg_rtx (SImode);
3842 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3843 operands[2], scratch1, scratch2);
3849 (define_insn "arm_ashrdi3_1bit"
3850 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3851 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3853 (clobber (reg:CC CC_REGNUM))]
3855 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3856 [(set_attr "conds" "clob")
3857 (set_attr "length" "8")
3858 (set_attr "type" "multiple")]
3861 (define_expand "ashrsi3"
3862 [(set (match_operand:SI 0 "s_register_operand" "")
3863 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3864 (match_operand:SI 2 "arm_rhs_operand" "")))]
3867 if (CONST_INT_P (operands[2])
3868 && UINTVAL (operands[2]) > 31)
3869 operands[2] = GEN_INT (31);
3873 (define_expand "lshrdi3"
3874 [(set (match_operand:DI 0 "s_register_operand" "")
3875 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3876 (match_operand:SI 2 "reg_or_int_operand" "")))]
3881 /* Delay the decision whether to use NEON or core-regs until
3882 register allocation. */
3883 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3887 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3888 ; /* No special preparation statements; expand pattern as above. */
3891 rtx scratch1, scratch2;
3893 if (operands[2] == CONST1_RTX (SImode))
3895 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3899 /* Ideally we should use iwmmxt here if we could know that operands[1]
3900 ends up already living in an iwmmxt register. Otherwise it's
3901 cheaper to have the alternate code being generated than moving
3902 values to iwmmxt regs and back. */
3904 /* If we're optimizing for size, we prefer the libgcc calls. */
3905 if (optimize_function_for_size_p (cfun))
3908 /* Expand operation using core-registers.
3909 'FAIL' would achieve the same thing, but this is a bit smarter. */
3910 scratch1 = gen_reg_rtx (SImode);
3911 scratch2 = gen_reg_rtx (SImode);
3912 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3913 operands[2], scratch1, scratch2);
3919 (define_insn "arm_lshrdi3_1bit"
3920 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3921 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3923 (clobber (reg:CC CC_REGNUM))]
3925 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3926 [(set_attr "conds" "clob")
3927 (set_attr "length" "8")
3928 (set_attr "type" "multiple")]
3931 (define_expand "lshrsi3"
3932 [(set (match_operand:SI 0 "s_register_operand" "")
3933 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3934 (match_operand:SI 2 "arm_rhs_operand" "")))]
3937 if (CONST_INT_P (operands[2])
3938 && (UINTVAL (operands[2])) > 31)
3940 emit_insn (gen_movsi (operands[0], const0_rtx));
3946 (define_expand "rotlsi3"
3947 [(set (match_operand:SI 0 "s_register_operand" "")
3948 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3949 (match_operand:SI 2 "reg_or_int_operand" "")))]
3952 if (CONST_INT_P (operands[2]))
3953 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3956 rtx reg = gen_reg_rtx (SImode);
3957 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3963 (define_expand "rotrsi3"
3964 [(set (match_operand:SI 0 "s_register_operand" "")
3965 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3966 (match_operand:SI 2 "arm_rhs_operand" "")))]
3971 if (CONST_INT_P (operands[2])
3972 && UINTVAL (operands[2]) > 31)
3973 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3975 else /* TARGET_THUMB1 */
3977 if (CONST_INT_P (operands [2]))
3978 operands [2] = force_reg (SImode, operands[2]);
3983 (define_insn "*arm_shiftsi3"
3984 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
3985 (match_operator:SI 3 "shift_operator"
3986 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
3987 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
3989 "* return arm_output_shift(operands, 0);"
3990 [(set_attr "predicable" "yes")
3991 (set_attr "arch" "t2,t2,*,*")
3992 (set_attr "predicable_short_it" "yes,yes,no,no")
3993 (set_attr "length" "4")
3994 (set_attr "shift" "1")
3995 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
3998 (define_insn "*shiftsi3_compare0"
3999 [(set (reg:CC_NOOV CC_REGNUM)
4000 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4001 [(match_operand:SI 1 "s_register_operand" "r,r")
4002 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4004 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4005 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4007 "* return arm_output_shift(operands, 1);"
4008 [(set_attr "conds" "set")
4009 (set_attr "shift" "1")
4010 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4013 (define_insn "*shiftsi3_compare0_scratch"
4014 [(set (reg:CC_NOOV CC_REGNUM)
4015 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4016 [(match_operand:SI 1 "s_register_operand" "r,r")
4017 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4019 (clobber (match_scratch:SI 0 "=r,r"))]
4021 "* return arm_output_shift(operands, 1);"
4022 [(set_attr "conds" "set")
4023 (set_attr "shift" "1")
4024 (set_attr "type" "shift_imm,shift_reg")]
4027 (define_insn "*not_shiftsi"
4028 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4029 (not:SI (match_operator:SI 3 "shift_operator"
4030 [(match_operand:SI 1 "s_register_operand" "r,r")
4031 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4034 [(set_attr "predicable" "yes")
4035 (set_attr "predicable_short_it" "no")
4036 (set_attr "shift" "1")
4037 (set_attr "arch" "32,a")
4038 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4040 (define_insn "*not_shiftsi_compare0"
4041 [(set (reg:CC_NOOV CC_REGNUM)
4043 (not:SI (match_operator:SI 3 "shift_operator"
4044 [(match_operand:SI 1 "s_register_operand" "r,r")
4045 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4047 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4048 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4050 "mvns%?\\t%0, %1%S3"
4051 [(set_attr "conds" "set")
4052 (set_attr "shift" "1")
4053 (set_attr "arch" "32,a")
4054 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4056 (define_insn "*not_shiftsi_compare0_scratch"
4057 [(set (reg:CC_NOOV CC_REGNUM)
4059 (not:SI (match_operator:SI 3 "shift_operator"
4060 [(match_operand:SI 1 "s_register_operand" "r,r")
4061 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4063 (clobber (match_scratch:SI 0 "=r,r"))]
4065 "mvns%?\\t%0, %1%S3"
4066 [(set_attr "conds" "set")
4067 (set_attr "shift" "1")
4068 (set_attr "arch" "32,a")
4069 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4071 ;; We don't really have extzv, but defining this using shifts helps
4072 ;; to reduce register pressure later on.
4074 (define_expand "extzv"
4075 [(set (match_operand 0 "s_register_operand" "")
4076 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4077 (match_operand 2 "const_int_operand" "")
4078 (match_operand 3 "const_int_operand" "")))]
4079 "TARGET_THUMB1 || arm_arch_thumb2"
4082 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4083 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4085 if (arm_arch_thumb2)
4087 HOST_WIDE_INT width = INTVAL (operands[2]);
4088 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4090 if (unaligned_access && MEM_P (operands[1])
4091 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4095 if (BYTES_BIG_ENDIAN)
4096 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4101 base_addr = adjust_address (operands[1], SImode,
4102 bitpos / BITS_PER_UNIT);
4103 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4107 rtx dest = operands[0];
4108 rtx tmp = gen_reg_rtx (SImode);
4110 /* We may get a paradoxical subreg here. Strip it off. */
4111 if (GET_CODE (dest) == SUBREG
4112 && GET_MODE (dest) == SImode
4113 && GET_MODE (SUBREG_REG (dest)) == HImode)
4114 dest = SUBREG_REG (dest);
4116 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4119 base_addr = adjust_address (operands[1], HImode,
4120 bitpos / BITS_PER_UNIT);
4121 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4122 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4126 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4128 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4136 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4139 operands[3] = GEN_INT (rshift);
4143 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4147 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4148 operands[3], gen_reg_rtx (SImode)));
4153 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4155 (define_expand "extzv_t1"
4156 [(set (match_operand:SI 4 "s_register_operand" "")
4157 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4158 (match_operand:SI 2 "const_int_operand" "")))
4159 (set (match_operand:SI 0 "s_register_operand" "")
4160 (lshiftrt:SI (match_dup 4)
4161 (match_operand:SI 3 "const_int_operand" "")))]
4165 (define_expand "extv"
4166 [(set (match_operand 0 "s_register_operand" "")
4167 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4168 (match_operand 2 "const_int_operand" "")
4169 (match_operand 3 "const_int_operand" "")))]
4172 HOST_WIDE_INT width = INTVAL (operands[2]);
4173 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4175 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4176 && (bitpos % BITS_PER_UNIT) == 0)
4180 if (BYTES_BIG_ENDIAN)
4181 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4185 base_addr = adjust_address (operands[1], SImode,
4186 bitpos / BITS_PER_UNIT);
4187 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4191 rtx dest = operands[0];
4192 rtx tmp = gen_reg_rtx (SImode);
4194 /* We may get a paradoxical subreg here. Strip it off. */
4195 if (GET_CODE (dest) == SUBREG
4196 && GET_MODE (dest) == SImode
4197 && GET_MODE (SUBREG_REG (dest)) == HImode)
4198 dest = SUBREG_REG (dest);
4200 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4203 base_addr = adjust_address (operands[1], HImode,
4204 bitpos / BITS_PER_UNIT);
4205 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4206 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4211 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4213 else if (GET_MODE (operands[0]) == SImode
4214 && GET_MODE (operands[1]) == SImode)
4216 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4224 ; Helper to expand register forms of extv with the proper modes.
4226 (define_expand "extv_regsi"
4227 [(set (match_operand:SI 0 "s_register_operand" "")
4228 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4229 (match_operand 2 "const_int_operand" "")
4230 (match_operand 3 "const_int_operand" "")))]
4235 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4237 (define_insn "unaligned_loadsi"
4238 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4239 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4240 UNSPEC_UNALIGNED_LOAD))]
4242 "ldr%?\t%0, %1\t@ unaligned"
4243 [(set_attr "arch" "t2,any")
4244 (set_attr "length" "2,4")
4245 (set_attr "predicable" "yes")
4246 (set_attr "predicable_short_it" "yes,no")
4247 (set_attr "type" "load1")])
4249 (define_insn "unaligned_loadhis"
4250 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4252 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4253 UNSPEC_UNALIGNED_LOAD)))]
4255 "ldrsh%?\t%0, %1\t@ unaligned"
4256 [(set_attr "arch" "t2,any")
4257 (set_attr "length" "2,4")
4258 (set_attr "predicable" "yes")
4259 (set_attr "predicable_short_it" "yes,no")
4260 (set_attr "type" "load_byte")])
4262 (define_insn "unaligned_loadhiu"
4263 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4265 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4266 UNSPEC_UNALIGNED_LOAD)))]
4268 "ldrh%?\t%0, %1\t@ unaligned"
4269 [(set_attr "arch" "t2,any")
4270 (set_attr "length" "2,4")
4271 (set_attr "predicable" "yes")
4272 (set_attr "predicable_short_it" "yes,no")
4273 (set_attr "type" "load_byte")])
4275 (define_insn "unaligned_storesi"
4276 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4277 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4278 UNSPEC_UNALIGNED_STORE))]
4280 "str%?\t%1, %0\t@ unaligned"
4281 [(set_attr "arch" "t2,any")
4282 (set_attr "length" "2,4")
4283 (set_attr "predicable" "yes")
4284 (set_attr "predicable_short_it" "yes,no")
4285 (set_attr "type" "store1")])
4287 (define_insn "unaligned_storehi"
4288 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4289 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4290 UNSPEC_UNALIGNED_STORE))]
4292 "strh%?\t%1, %0\t@ unaligned"
4293 [(set_attr "arch" "t2,any")
4294 (set_attr "length" "2,4")
4295 (set_attr "predicable" "yes")
4296 (set_attr "predicable_short_it" "yes,no")
4297 (set_attr "type" "store1")])
4300 (define_insn "*extv_reg"
4301 [(set (match_operand:SI 0 "s_register_operand" "=r")
4302 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4303 (match_operand:SI 2 "const_int_M_operand" "M")
4304 (match_operand:SI 3 "const_int_M_operand" "M")))]
4306 "sbfx%?\t%0, %1, %3, %2"
4307 [(set_attr "length" "4")
4308 (set_attr "predicable" "yes")
4309 (set_attr "predicable_short_it" "no")
4310 (set_attr "type" "bfm")]
4313 (define_insn "extzv_t2"
4314 [(set (match_operand:SI 0 "s_register_operand" "=r")
4315 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4316 (match_operand:SI 2 "const_int_M_operand" "M")
4317 (match_operand:SI 3 "const_int_M_operand" "M")))]
4319 "ubfx%?\t%0, %1, %3, %2"
4320 [(set_attr "length" "4")
4321 (set_attr "predicable" "yes")
4322 (set_attr "predicable_short_it" "no")
4323 (set_attr "type" "bfm")]
4327 ;; Division instructions
4328 (define_insn "divsi3"
4329 [(set (match_operand:SI 0 "s_register_operand" "=r")
4330 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4331 (match_operand:SI 2 "s_register_operand" "r")))]
4333 "sdiv%?\t%0, %1, %2"
4334 [(set_attr "predicable" "yes")
4335 (set_attr "predicable_short_it" "no")
4336 (set_attr "type" "sdiv")]
4339 (define_insn "udivsi3"
4340 [(set (match_operand:SI 0 "s_register_operand" "=r")
4341 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4342 (match_operand:SI 2 "s_register_operand" "r")))]
4344 "udiv%?\t%0, %1, %2"
4345 [(set_attr "predicable" "yes")
4346 (set_attr "predicable_short_it" "no")
4347 (set_attr "type" "udiv")]
4351 ;; Unary arithmetic insns
4353 (define_expand "negdi2"
4355 [(set (match_operand:DI 0 "s_register_operand" "")
4356 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4357 (clobber (reg:CC CC_REGNUM))])]
4362 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4368 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4369 ;; The first alternative allows the common case of a *full* overlap.
4370 (define_insn_and_split "*arm_negdi2"
4371 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4372 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4373 (clobber (reg:CC CC_REGNUM))]
4375 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4376 "&& reload_completed"
4377 [(parallel [(set (reg:CC CC_REGNUM)
4378 (compare:CC (const_int 0) (match_dup 1)))
4379 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4380 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4381 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4383 operands[2] = gen_highpart (SImode, operands[0]);
4384 operands[0] = gen_lowpart (SImode, operands[0]);
4385 operands[3] = gen_highpart (SImode, operands[1]);
4386 operands[1] = gen_lowpart (SImode, operands[1]);
4388 [(set_attr "conds" "clob")
4389 (set_attr "length" "8")
4390 (set_attr "type" "multiple")]
4393 (define_expand "negsi2"
4394 [(set (match_operand:SI 0 "s_register_operand" "")
4395 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4400 (define_insn "*arm_negsi2"
4401 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4402 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4404 "rsb%?\\t%0, %1, #0"
4405 [(set_attr "predicable" "yes")
4406 (set_attr "predicable_short_it" "yes,no")
4407 (set_attr "arch" "t2,*")
4408 (set_attr "length" "4")
4409 (set_attr "type" "alu_sreg")]
4412 (define_expand "negsf2"
4413 [(set (match_operand:SF 0 "s_register_operand" "")
4414 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4415 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4419 (define_expand "negdf2"
4420 [(set (match_operand:DF 0 "s_register_operand" "")
4421 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4422 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4425 (define_insn_and_split "*zextendsidi_negsi"
4426 [(set (match_operand:DI 0 "s_register_operand" "=r")
4427 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4432 (neg:SI (match_dup 1)))
4436 operands[2] = gen_lowpart (SImode, operands[0]);
4437 operands[3] = gen_highpart (SImode, operands[0]);
4439 [(set_attr "length" "8")
4440 (set_attr "type" "multiple")]
4443 ;; Negate an extended 32-bit value.
4444 (define_insn_and_split "*negdi_extendsidi"
4445 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4446 (neg:DI (sign_extend:DI
4447 (match_operand:SI 1 "s_register_operand" "l,r"))))
4448 (clobber (reg:CC CC_REGNUM))]
4451 "&& reload_completed"
4454 rtx low = gen_lowpart (SImode, operands[0]);
4455 rtx high = gen_highpart (SImode, operands[0]);
4457 if (reg_overlap_mentioned_p (low, operands[1]))
4459 /* Input overlaps the low word of the output. Use:
4462 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4463 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4465 emit_insn (gen_rtx_SET (high,
4466 gen_rtx_ASHIFTRT (SImode, operands[1],
4469 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4471 emit_insn (gen_rtx_SET (high,
4472 gen_rtx_MINUS (SImode,
4473 gen_rtx_MINUS (SImode,
4476 gen_rtx_LTU (SImode,
4481 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4482 emit_insn (gen_rtx_SET (high,
4483 gen_rtx_MINUS (SImode,
4484 gen_rtx_MINUS (SImode,
4487 gen_rtx_LTU (SImode,
4494 /* No overlap, or overlap on high word. Use:
4498 Flags not needed for this sequence. */
4499 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4500 emit_insn (gen_rtx_SET (high,
4501 gen_rtx_AND (SImode,
4502 gen_rtx_NOT (SImode, operands[1]),
4504 emit_insn (gen_rtx_SET (high,
4505 gen_rtx_ASHIFTRT (SImode, high,
4510 [(set_attr "length" "12")
4511 (set_attr "arch" "t2,*")
4512 (set_attr "type" "multiple")]
4515 (define_insn_and_split "*negdi_zero_extendsidi"
4516 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4517 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4518 (clobber (reg:CC CC_REGNUM))]
4520 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4521 ;; Don't care what register is input to sbc,
4522 ;; since we just need to propagate the carry.
4523 "&& reload_completed"
4524 [(parallel [(set (reg:CC CC_REGNUM)
4525 (compare:CC (const_int 0) (match_dup 1)))
4526 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4527 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4528 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4530 operands[2] = gen_highpart (SImode, operands[0]);
4531 operands[0] = gen_lowpart (SImode, operands[0]);
4533 [(set_attr "conds" "clob")
4534 (set_attr "length" "8")
4535 (set_attr "type" "multiple")] ;; length in thumb is 4
4538 ;; abssi2 doesn't really clobber the condition codes if a different register
4539 ;; is being set. To keep things simple, assume during rtl manipulations that
4540 ;; it does, but tell the final scan operator the truth. Similarly for
4543 (define_expand "abssi2"
4545 [(set (match_operand:SI 0 "s_register_operand" "")
4546 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4547 (clobber (match_dup 2))])]
4551 operands[2] = gen_rtx_SCRATCH (SImode);
4553 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4556 (define_insn_and_split "*arm_abssi2"
4557 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4558 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4559 (clobber (reg:CC CC_REGNUM))]
4562 "&& reload_completed"
4565 /* if (which_alternative == 0) */
4566 if (REGNO(operands[0]) == REGNO(operands[1]))
4568 /* Emit the pattern:
4569 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4570 [(set (reg:CC CC_REGNUM)
4571 (compare:CC (match_dup 0) (const_int 0)))
4572 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4573 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4575 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4576 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4577 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4578 (gen_rtx_LT (SImode,
4579 gen_rtx_REG (CCmode, CC_REGNUM),
4581 (gen_rtx_SET (operands[0],
4582 (gen_rtx_MINUS (SImode,
4589 /* Emit the pattern:
4590 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4592 (xor:SI (match_dup 1)
4593 (ashiftrt:SI (match_dup 1) (const_int 31))))
4595 (minus:SI (match_dup 0)
4596 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4598 emit_insn (gen_rtx_SET (operands[0],
4599 gen_rtx_XOR (SImode,
4600 gen_rtx_ASHIFTRT (SImode,
4604 emit_insn (gen_rtx_SET (operands[0],
4605 gen_rtx_MINUS (SImode,
4607 gen_rtx_ASHIFTRT (SImode,
4613 [(set_attr "conds" "clob,*")
4614 (set_attr "shift" "1")
4615 (set_attr "predicable" "no, yes")
4616 (set_attr "length" "8")
4617 (set_attr "type" "multiple")]
4620 (define_insn_and_split "*arm_neg_abssi2"
4621 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4622 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4623 (clobber (reg:CC CC_REGNUM))]
4626 "&& reload_completed"
4629 /* if (which_alternative == 0) */
4630 if (REGNO (operands[0]) == REGNO (operands[1]))
4632 /* Emit the pattern:
4633 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4635 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4636 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4637 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4639 gen_rtx_REG (CCmode, CC_REGNUM),
4641 gen_rtx_SET (operands[0],
4642 (gen_rtx_MINUS (SImode,
4648 /* Emit the pattern:
4649 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4651 emit_insn (gen_rtx_SET (operands[0],
4652 gen_rtx_XOR (SImode,
4653 gen_rtx_ASHIFTRT (SImode,
4657 emit_insn (gen_rtx_SET (operands[0],
4658 gen_rtx_MINUS (SImode,
4659 gen_rtx_ASHIFTRT (SImode,
4666 [(set_attr "conds" "clob,*")
4667 (set_attr "shift" "1")
4668 (set_attr "predicable" "no, yes")
4669 (set_attr "length" "8")
4670 (set_attr "type" "multiple")]
4673 (define_expand "abssf2"
4674 [(set (match_operand:SF 0 "s_register_operand" "")
4675 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4676 "TARGET_32BIT && TARGET_HARD_FLOAT"
4679 (define_expand "absdf2"
4680 [(set (match_operand:DF 0 "s_register_operand" "")
4681 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4682 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4685 (define_expand "sqrtsf2"
4686 [(set (match_operand:SF 0 "s_register_operand" "")
4687 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4688 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4691 (define_expand "sqrtdf2"
4692 [(set (match_operand:DF 0 "s_register_operand" "")
4693 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4694 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4697 (define_insn_and_split "one_cmpldi2"
4698 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4699 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4706 "TARGET_32BIT && reload_completed
4707 && arm_general_register_operand (operands[0], DImode)"
4708 [(set (match_dup 0) (not:SI (match_dup 1)))
4709 (set (match_dup 2) (not:SI (match_dup 3)))]
4712 operands[2] = gen_highpart (SImode, operands[0]);
4713 operands[0] = gen_lowpart (SImode, operands[0]);
4714 operands[3] = gen_highpart (SImode, operands[1]);
4715 operands[1] = gen_lowpart (SImode, operands[1]);
4717 [(set_attr "length" "*,8,8,*")
4718 (set_attr "predicable" "no,yes,yes,no")
4719 (set_attr "type" "neon_move,multiple,multiple,neon_move")
4720 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4723 (define_expand "one_cmplsi2"
4724 [(set (match_operand:SI 0 "s_register_operand" "")
4725 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4730 (define_insn "*arm_one_cmplsi2"
4731 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4732 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4735 [(set_attr "predicable" "yes")
4736 (set_attr "predicable_short_it" "yes,no")
4737 (set_attr "arch" "t2,*")
4738 (set_attr "length" "4")
4739 (set_attr "type" "mvn_reg")]
4742 (define_insn "*notsi_compare0"
4743 [(set (reg:CC_NOOV CC_REGNUM)
4744 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4746 (set (match_operand:SI 0 "s_register_operand" "=r")
4747 (not:SI (match_dup 1)))]
4750 [(set_attr "conds" "set")
4751 (set_attr "type" "mvn_reg")]
4754 (define_insn "*notsi_compare0_scratch"
4755 [(set (reg:CC_NOOV CC_REGNUM)
4756 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4758 (clobber (match_scratch:SI 0 "=r"))]
4761 [(set_attr "conds" "set")
4762 (set_attr "type" "mvn_reg")]
4765 ;; Fixed <--> Floating conversion insns
4767 (define_expand "floatsihf2"
4768 [(set (match_operand:HF 0 "general_operand" "")
4769 (float:HF (match_operand:SI 1 "general_operand" "")))]
4773 rtx op1 = gen_reg_rtx (SFmode);
4774 expand_float (op1, operands[1], 0);
4775 op1 = convert_to_mode (HFmode, op1, 0);
4776 emit_move_insn (operands[0], op1);
4781 (define_expand "floatdihf2"
4782 [(set (match_operand:HF 0 "general_operand" "")
4783 (float:HF (match_operand:DI 1 "general_operand" "")))]
4787 rtx op1 = gen_reg_rtx (SFmode);
4788 expand_float (op1, operands[1], 0);
4789 op1 = convert_to_mode (HFmode, op1, 0);
4790 emit_move_insn (operands[0], op1);
4795 (define_expand "floatsisf2"
4796 [(set (match_operand:SF 0 "s_register_operand" "")
4797 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
4798 "TARGET_32BIT && TARGET_HARD_FLOAT"
4802 (define_expand "floatsidf2"
4803 [(set (match_operand:DF 0 "s_register_operand" "")
4804 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
4805 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4809 (define_expand "fix_trunchfsi2"
4810 [(set (match_operand:SI 0 "general_operand" "")
4811 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4815 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4816 expand_fix (operands[0], op1, 0);
4821 (define_expand "fix_trunchfdi2"
4822 [(set (match_operand:DI 0 "general_operand" "")
4823 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4827 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4828 expand_fix (operands[0], op1, 0);
4833 (define_expand "fix_truncsfsi2"
4834 [(set (match_operand:SI 0 "s_register_operand" "")
4835 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
4836 "TARGET_32BIT && TARGET_HARD_FLOAT"
4840 (define_expand "fix_truncdfsi2"
4841 [(set (match_operand:SI 0 "s_register_operand" "")
4842 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
4843 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4849 (define_expand "truncdfsf2"
4850 [(set (match_operand:SF 0 "s_register_operand" "")
4852 (match_operand:DF 1 "s_register_operand" "")))]
4853 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4857 /* DFmode -> HFmode conversions have to go through SFmode. */
4858 (define_expand "truncdfhf2"
4859 [(set (match_operand:HF 0 "general_operand" "")
4861 (match_operand:DF 1 "general_operand" "")))]
4866 op1 = convert_to_mode (SFmode, operands[1], 0);
4867 op1 = convert_to_mode (HFmode, op1, 0);
4868 emit_move_insn (operands[0], op1);
4873 ;; Zero and sign extension instructions.
4875 (define_insn "zero_extend<mode>di2"
4876 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
4877 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4878 "<qhs_zextenddi_cstr>")))]
4879 "TARGET_32BIT <qhs_zextenddi_cond>"
4881 [(set_attr "length" "8,4,8,8")
4882 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
4883 (set_attr "ce_count" "2")
4884 (set_attr "predicable" "yes")
4885 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
4888 (define_insn "extend<mode>di2"
4889 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
4890 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4891 "<qhs_extenddi_cstr>")))]
4892 "TARGET_32BIT <qhs_sextenddi_cond>"
4894 [(set_attr "length" "8,4,8,8,8")
4895 (set_attr "ce_count" "2")
4896 (set_attr "shift" "1")
4897 (set_attr "predicable" "yes")
4898 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4899 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
4902 ;; Splits for all extensions to DImode
4904 [(set (match_operand:DI 0 "s_register_operand" "")
4905 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4906 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4907 [(set (match_dup 0) (match_dup 1))]
4909 rtx lo_part = gen_lowpart (SImode, operands[0]);
4910 machine_mode src_mode = GET_MODE (operands[1]);
4912 if (REG_P (operands[0])
4913 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4914 emit_clobber (operands[0]);
4915 if (!REG_P (lo_part) || src_mode != SImode
4916 || !rtx_equal_p (lo_part, operands[1]))
4918 if (src_mode == SImode)
4919 emit_move_insn (lo_part, operands[1]);
4921 emit_insn (gen_rtx_SET (lo_part,
4922 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4923 operands[1] = lo_part;
4925 operands[0] = gen_highpart (SImode, operands[0]);
4926 operands[1] = const0_rtx;
4930 [(set (match_operand:DI 0 "s_register_operand" "")
4931 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4932 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4933 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4935 rtx lo_part = gen_lowpart (SImode, operands[0]);
4936 machine_mode src_mode = GET_MODE (operands[1]);
4938 if (REG_P (operands[0])
4939 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4940 emit_clobber (operands[0]);
4942 if (!REG_P (lo_part) || src_mode != SImode
4943 || !rtx_equal_p (lo_part, operands[1]))
4945 if (src_mode == SImode)
4946 emit_move_insn (lo_part, operands[1]);
4948 emit_insn (gen_rtx_SET (lo_part,
4949 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4950 operands[1] = lo_part;
4952 operands[0] = gen_highpart (SImode, operands[0]);
4955 (define_expand "zero_extendhisi2"
4956 [(set (match_operand:SI 0 "s_register_operand" "")
4957 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4960 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4962 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4965 if (!arm_arch6 && !MEM_P (operands[1]))
4967 rtx t = gen_lowpart (SImode, operands[1]);
4968 rtx tmp = gen_reg_rtx (SImode);
4969 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4970 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4976 [(set (match_operand:SI 0 "s_register_operand" "")
4977 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4978 "!TARGET_THUMB2 && !arm_arch6"
4979 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4980 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4982 operands[2] = gen_lowpart (SImode, operands[1]);
4985 (define_insn "*arm_zero_extendhisi2"
4986 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4987 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4988 "TARGET_ARM && arm_arch4 && !arm_arch6"
4992 [(set_attr "type" "alu_shift_reg,load_byte")
4993 (set_attr "predicable" "yes")]
4996 (define_insn "*arm_zero_extendhisi2_v6"
4997 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4998 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4999 "TARGET_ARM && arm_arch6"
5003 [(set_attr "predicable" "yes")
5004 (set_attr "type" "extend,load_byte")]
5007 (define_insn "*arm_zero_extendhisi2addsi"
5008 [(set (match_operand:SI 0 "s_register_operand" "=r")
5009 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5010 (match_operand:SI 2 "s_register_operand" "r")))]
5012 "uxtah%?\\t%0, %2, %1"
5013 [(set_attr "type" "alu_shift_reg")
5014 (set_attr "predicable" "yes")
5015 (set_attr "predicable_short_it" "no")]
5018 (define_expand "zero_extendqisi2"
5019 [(set (match_operand:SI 0 "s_register_operand" "")
5020 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5023 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5025 emit_insn (gen_andsi3 (operands[0],
5026 gen_lowpart (SImode, operands[1]),
5030 if (!arm_arch6 && !MEM_P (operands[1]))
5032 rtx t = gen_lowpart (SImode, operands[1]);
5033 rtx tmp = gen_reg_rtx (SImode);
5034 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5035 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5041 [(set (match_operand:SI 0 "s_register_operand" "")
5042 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5044 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5045 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5047 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5050 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5055 (define_insn "*arm_zero_extendqisi2"
5056 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5057 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5058 "TARGET_ARM && !arm_arch6"
5061 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5062 [(set_attr "length" "8,4")
5063 (set_attr "type" "alu_shift_reg,load_byte")
5064 (set_attr "predicable" "yes")]
5067 (define_insn "*arm_zero_extendqisi2_v6"
5068 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5069 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5070 "TARGET_ARM && arm_arch6"
5073 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5074 [(set_attr "type" "extend,load_byte")
5075 (set_attr "predicable" "yes")]
5078 (define_insn "*arm_zero_extendqisi2addsi"
5079 [(set (match_operand:SI 0 "s_register_operand" "=r")
5080 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5081 (match_operand:SI 2 "s_register_operand" "r")))]
5083 "uxtab%?\\t%0, %2, %1"
5084 [(set_attr "predicable" "yes")
5085 (set_attr "predicable_short_it" "no")
5086 (set_attr "type" "alu_shift_reg")]
5090 [(set (match_operand:SI 0 "s_register_operand" "")
5091 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5092 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5093 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5094 [(set (match_dup 2) (match_dup 1))
5095 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5100 [(set (match_operand:SI 0 "s_register_operand" "")
5101 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5102 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5103 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5104 [(set (match_dup 2) (match_dup 1))
5105 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5111 [(set (match_operand:SI 0 "s_register_operand" "")
5112 (IOR_XOR:SI (and:SI (ashift:SI
5113 (match_operand:SI 1 "s_register_operand" "")
5114 (match_operand:SI 2 "const_int_operand" ""))
5115 (match_operand:SI 3 "const_int_operand" ""))
5117 (match_operator 5 "subreg_lowpart_operator"
5118 [(match_operand:SI 4 "s_register_operand" "")]))))]
5120 && (UINTVAL (operands[3])
5121 == (GET_MODE_MASK (GET_MODE (operands[5]))
5122 & (GET_MODE_MASK (GET_MODE (operands[5]))
5123 << (INTVAL (operands[2])))))"
5124 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5126 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5127 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5130 (define_insn "*compareqi_eq0"
5131 [(set (reg:CC_Z CC_REGNUM)
5132 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5136 [(set_attr "conds" "set")
5137 (set_attr "predicable" "yes")
5138 (set_attr "predicable_short_it" "no")
5139 (set_attr "type" "logic_imm")]
5142 (define_expand "extendhisi2"
5143 [(set (match_operand:SI 0 "s_register_operand" "")
5144 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5149 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5152 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5154 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5158 if (!arm_arch6 && !MEM_P (operands[1]))
5160 rtx t = gen_lowpart (SImode, operands[1]);
5161 rtx tmp = gen_reg_rtx (SImode);
5162 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5163 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5170 [(set (match_operand:SI 0 "register_operand" "")
5171 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5172 (clobber (match_scratch:SI 2 ""))])]
5174 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5175 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5177 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5180 ;; This pattern will only be used when ldsh is not available
5181 (define_expand "extendhisi2_mem"
5182 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5184 (zero_extend:SI (match_dup 7)))
5185 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5186 (set (match_operand:SI 0 "" "")
5187 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5192 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5194 mem1 = change_address (operands[1], QImode, addr);
5195 mem2 = change_address (operands[1], QImode,
5196 plus_constant (Pmode, addr, 1));
5197 operands[0] = gen_lowpart (SImode, operands[0]);
5199 operands[2] = gen_reg_rtx (SImode);
5200 operands[3] = gen_reg_rtx (SImode);
5201 operands[6] = gen_reg_rtx (SImode);
5204 if (BYTES_BIG_ENDIAN)
5206 operands[4] = operands[2];
5207 operands[5] = operands[3];
5211 operands[4] = operands[3];
5212 operands[5] = operands[2];
5218 [(set (match_operand:SI 0 "register_operand" "")
5219 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5221 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5222 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5224 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5227 (define_insn "*arm_extendhisi2"
5228 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5229 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5230 "TARGET_ARM && arm_arch4 && !arm_arch6"
5234 [(set_attr "length" "8,4")
5235 (set_attr "type" "alu_shift_reg,load_byte")
5236 (set_attr "predicable" "yes")]
5239 ;; ??? Check Thumb-2 pool range
5240 (define_insn "*arm_extendhisi2_v6"
5241 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5242 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5243 "TARGET_32BIT && arm_arch6"
5247 [(set_attr "type" "extend,load_byte")
5248 (set_attr "predicable" "yes")
5249 (set_attr "predicable_short_it" "no")]
5252 (define_insn "*arm_extendhisi2addsi"
5253 [(set (match_operand:SI 0 "s_register_operand" "=r")
5254 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5255 (match_operand:SI 2 "s_register_operand" "r")))]
5257 "sxtah%?\\t%0, %2, %1"
5258 [(set_attr "type" "alu_shift_reg")]
5261 (define_expand "extendqihi2"
5263 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5265 (set (match_operand:HI 0 "s_register_operand" "")
5266 (ashiftrt:SI (match_dup 2)
5271 if (arm_arch4 && MEM_P (operands[1]))
5273 emit_insn (gen_rtx_SET (operands[0],
5274 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5277 if (!s_register_operand (operands[1], QImode))
5278 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5279 operands[0] = gen_lowpart (SImode, operands[0]);
5280 operands[1] = gen_lowpart (SImode, operands[1]);
5281 operands[2] = gen_reg_rtx (SImode);
5285 (define_insn "*arm_extendqihi_insn"
5286 [(set (match_operand:HI 0 "s_register_operand" "=r")
5287 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5288 "TARGET_ARM && arm_arch4"
5290 [(set_attr "type" "load_byte")
5291 (set_attr "predicable" "yes")]
5294 (define_expand "extendqisi2"
5295 [(set (match_operand:SI 0 "s_register_operand" "")
5296 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5299 if (!arm_arch4 && MEM_P (operands[1]))
5300 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5302 if (!arm_arch6 && !MEM_P (operands[1]))
5304 rtx t = gen_lowpart (SImode, operands[1]);
5305 rtx tmp = gen_reg_rtx (SImode);
5306 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5307 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5313 [(set (match_operand:SI 0 "register_operand" "")
5314 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5316 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5317 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5319 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5322 (define_insn "*arm_extendqisi"
5323 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5324 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5325 "TARGET_ARM && arm_arch4 && !arm_arch6"
5329 [(set_attr "length" "8,4")
5330 (set_attr "type" "alu_shift_reg,load_byte")
5331 (set_attr "predicable" "yes")]
5334 (define_insn "*arm_extendqisi_v6"
5335 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5337 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5338 "TARGET_ARM && arm_arch6"
5342 [(set_attr "type" "extend,load_byte")
5343 (set_attr "predicable" "yes")]
5346 (define_insn "*arm_extendqisi2addsi"
5347 [(set (match_operand:SI 0 "s_register_operand" "=r")
5348 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5349 (match_operand:SI 2 "s_register_operand" "r")))]
5351 "sxtab%?\\t%0, %2, %1"
5352 [(set_attr "type" "alu_shift_reg")
5353 (set_attr "predicable" "yes")
5354 (set_attr "predicable_short_it" "no")]
5357 (define_expand "extendsfdf2"
5358 [(set (match_operand:DF 0 "s_register_operand" "")
5359 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5360 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5364 /* HFmode -> DFmode conversions have to go through SFmode. */
5365 (define_expand "extendhfdf2"
5366 [(set (match_operand:DF 0 "general_operand" "")
5367 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5372 op1 = convert_to_mode (SFmode, operands[1], 0);
5373 op1 = convert_to_mode (DFmode, op1, 0);
5374 emit_insn (gen_movdf (operands[0], op1));
5379 ;; Move insns (including loads and stores)
5381 ;; XXX Just some ideas about movti.
5382 ;; I don't think these are a good idea on the arm, there just aren't enough
5384 ;;(define_expand "loadti"
5385 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5386 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5389 ;;(define_expand "storeti"
5390 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5391 ;; (match_operand:TI 1 "s_register_operand" ""))]
5394 ;;(define_expand "movti"
5395 ;; [(set (match_operand:TI 0 "general_operand" "")
5396 ;; (match_operand:TI 1 "general_operand" ""))]
5402 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5403 ;; operands[1] = copy_to_reg (operands[1]);
5404 ;; if (MEM_P (operands[0]))
5405 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5406 ;; else if (MEM_P (operands[1]))
5407 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5411 ;; emit_insn (insn);
5415 ;; Recognize garbage generated above.
5418 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5419 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5423 ;; register mem = (which_alternative < 3);
5424 ;; register const char *template;
5426 ;; operands[mem] = XEXP (operands[mem], 0);
5427 ;; switch (which_alternative)
5429 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5430 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5431 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5432 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5433 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5434 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5436 ;; output_asm_insn (template, operands);
5440 (define_expand "movdi"
5441 [(set (match_operand:DI 0 "general_operand" "")
5442 (match_operand:DI 1 "general_operand" ""))]
5445 if (can_create_pseudo_p ())
5447 if (!REG_P (operands[0]))
5448 operands[1] = force_reg (DImode, operands[1]);
5450 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5451 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5453 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5454 when expanding function calls. */
5455 gcc_assert (can_create_pseudo_p ());
5456 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5458 /* Perform load into legal reg pair first, then move. */
5459 rtx reg = gen_reg_rtx (DImode);
5460 emit_insn (gen_movdi (reg, operands[1]));
5463 emit_move_insn (gen_lowpart (SImode, operands[0]),
5464 gen_lowpart (SImode, operands[1]));
5465 emit_move_insn (gen_highpart (SImode, operands[0]),
5466 gen_highpart (SImode, operands[1]));
5469 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5470 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5472 /* Avoid STRD's from an odd-numbered register pair in ARM state
5473 when expanding function prologue. */
5474 gcc_assert (can_create_pseudo_p ());
5475 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5476 ? gen_reg_rtx (DImode)
5478 emit_move_insn (gen_lowpart (SImode, split_dest),
5479 gen_lowpart (SImode, operands[1]));
5480 emit_move_insn (gen_highpart (SImode, split_dest),
5481 gen_highpart (SImode, operands[1]));
5482 if (split_dest != operands[0])
5483 emit_insn (gen_movdi (operands[0], split_dest));
5489 (define_insn "*arm_movdi"
5490 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5491 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5493 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5495 && ( register_operand (operands[0], DImode)
5496 || register_operand (operands[1], DImode))"
5498 switch (which_alternative)
5505 return output_move_double (operands, true, NULL);
5508 [(set_attr "length" "8,12,16,8,8")
5509 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5510 (set_attr "arm_pool_range" "*,*,*,1020,*")
5511 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5512 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5513 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5517 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5518 (match_operand:ANY64 1 "immediate_operand" ""))]
5521 && (arm_const_double_inline_cost (operands[1])
5522 <= arm_max_const_double_inline_cost ())"
5525 arm_split_constant (SET, SImode, curr_insn,
5526 INTVAL (gen_lowpart (SImode, operands[1])),
5527 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5528 arm_split_constant (SET, SImode, curr_insn,
5529 INTVAL (gen_highpart_mode (SImode,
5530 GET_MODE (operands[0]),
5532 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5537 ; If optimizing for size, or if we have load delay slots, then
5538 ; we want to split the constant into two separate operations.
5539 ; In both cases this may split a trivial part into a single data op
5540 ; leaving a single complex constant to load. We can also get longer
5541 ; offsets in a LDR which means we get better chances of sharing the pool
5542 ; entries. Finally, we can normally do a better job of scheduling
5543 ; LDR instructions than we can with LDM.
5544 ; This pattern will only match if the one above did not.
5546 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5547 (match_operand:ANY64 1 "const_double_operand" ""))]
5548 "TARGET_ARM && reload_completed
5549 && arm_const_double_by_parts (operands[1])"
5550 [(set (match_dup 0) (match_dup 1))
5551 (set (match_dup 2) (match_dup 3))]
5553 operands[2] = gen_highpart (SImode, operands[0]);
5554 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5556 operands[0] = gen_lowpart (SImode, operands[0]);
5557 operands[1] = gen_lowpart (SImode, operands[1]);
5562 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5563 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5564 "TARGET_EITHER && reload_completed"
5565 [(set (match_dup 0) (match_dup 1))
5566 (set (match_dup 2) (match_dup 3))]
5568 operands[2] = gen_highpart (SImode, operands[0]);
5569 operands[3] = gen_highpart (SImode, operands[1]);
5570 operands[0] = gen_lowpart (SImode, operands[0]);
5571 operands[1] = gen_lowpart (SImode, operands[1]);
5573 /* Handle a partial overlap. */
5574 if (rtx_equal_p (operands[0], operands[3]))
5576 rtx tmp0 = operands[0];
5577 rtx tmp1 = operands[1];
5579 operands[0] = operands[2];
5580 operands[1] = operands[3];
5587 ;; We can't actually do base+index doubleword loads if the index and
5588 ;; destination overlap. Split here so that we at least have chance to
5591 [(set (match_operand:DI 0 "s_register_operand" "")
5592 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5593 (match_operand:SI 2 "s_register_operand" ""))))]
5595 && reg_overlap_mentioned_p (operands[0], operands[1])
5596 && reg_overlap_mentioned_p (operands[0], operands[2])"
5598 (plus:SI (match_dup 1)
5601 (mem:DI (match_dup 4)))]
5603 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5607 (define_expand "movsi"
5608 [(set (match_operand:SI 0 "general_operand" "")
5609 (match_operand:SI 1 "general_operand" ""))]
5613 rtx base, offset, tmp;
5617 /* Everything except mem = const or mem = mem can be done easily. */
5618 if (MEM_P (operands[0]))
5619 operands[1] = force_reg (SImode, operands[1]);
5620 if (arm_general_register_operand (operands[0], SImode)
5621 && CONST_INT_P (operands[1])
5622 && !(const_ok_for_arm (INTVAL (operands[1]))
5623 || const_ok_for_arm (~INTVAL (operands[1]))))
5625 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5627 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5632 arm_split_constant (SET, SImode, NULL_RTX,
5633 INTVAL (operands[1]), operands[0], NULL_RTX,
5634 optimize && can_create_pseudo_p ());
5639 else /* TARGET_THUMB1... */
5641 if (can_create_pseudo_p ())
5643 if (!REG_P (operands[0]))
5644 operands[1] = force_reg (SImode, operands[1]);
5648 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5650 split_const (operands[1], &base, &offset);
5651 if (GET_CODE (base) == SYMBOL_REF
5652 && !offset_within_block_p (base, INTVAL (offset)))
5654 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5655 emit_move_insn (tmp, base);
5656 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5661 /* Recognize the case where operand[1] is a reference to thread-local
5662 data and load its address to a register. */
5663 if (arm_tls_referenced_p (operands[1]))
5665 rtx tmp = operands[1];
5668 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5670 addend = XEXP (XEXP (tmp, 0), 1);
5671 tmp = XEXP (XEXP (tmp, 0), 0);
5674 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5675 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5677 tmp = legitimize_tls_address (tmp,
5678 !can_create_pseudo_p () ? operands[0] : 0);
5681 tmp = gen_rtx_PLUS (SImode, tmp, addend);
5682 tmp = force_operand (tmp, operands[0]);
5687 && (CONSTANT_P (operands[1])
5688 || symbol_mentioned_p (operands[1])
5689 || label_mentioned_p (operands[1])))
5690 operands[1] = legitimize_pic_address (operands[1], SImode,
5691 (!can_create_pseudo_p ()
5698 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5699 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5700 ;; so this does not matter.
5701 (define_insn "*arm_movt"
5702 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5703 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5704 (match_operand:SI 2 "general_operand" "i")))]
5705 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
5706 "movt%?\t%0, #:upper16:%c2"
5707 [(set_attr "predicable" "yes")
5708 (set_attr "predicable_short_it" "no")
5709 (set_attr "length" "4")
5710 (set_attr "type" "alu_sreg")]
5713 (define_insn "*arm_movsi_insn"
5714 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5715 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
5716 "TARGET_ARM && ! TARGET_IWMMXT
5717 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5718 && ( register_operand (operands[0], SImode)
5719 || register_operand (operands[1], SImode))"
5727 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
5728 (set_attr "predicable" "yes")
5729 (set_attr "pool_range" "*,*,*,*,4096,*")
5730 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5734 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5735 (match_operand:SI 1 "const_int_operand" ""))]
5737 && (!(const_ok_for_arm (INTVAL (operands[1]))
5738 || const_ok_for_arm (~INTVAL (operands[1]))))"
5739 [(clobber (const_int 0))]
5741 arm_split_constant (SET, SImode, NULL_RTX,
5742 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5747 ;; A normal way to do (symbol + offset) requires three instructions at least
5748 ;; (depends on how big the offset is) as below:
5749 ;; movw r0, #:lower16:g
5750 ;; movw r0, #:upper16:g
5753 ;; A better way would be:
5754 ;; movw r0, #:lower16:g+4
5755 ;; movw r0, #:upper16:g+4
5757 ;; The limitation of this way is that the length of offset should be a 16-bit
5758 ;; signed value, because current assembler only supports REL type relocation for
5759 ;; such case. If the more powerful RELA type is supported in future, we should
5760 ;; update this pattern to go with better way.
5762 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5763 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5764 (match_operand:SI 2 "const_int_operand" ""))))]
5767 && arm_disable_literal_pool
5769 && GET_CODE (operands[1]) == SYMBOL_REF"
5770 [(clobber (const_int 0))]
5772 int offset = INTVAL (operands[2]);
5774 if (offset < -0x8000 || offset > 0x7fff)
5776 arm_emit_movpair (operands[0], operands[1]);
5777 emit_insn (gen_rtx_SET (operands[0],
5778 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5782 rtx op = gen_rtx_CONST (SImode,
5783 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5784 arm_emit_movpair (operands[0], op);
5789 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5790 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5791 ;; and lo_sum would be merged back into memory load at cprop. However,
5792 ;; if the default is to prefer movt/movw rather than a load from the constant
5793 ;; pool, the performance is better.
5795 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5796 (match_operand:SI 1 "general_operand" ""))]
5797 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5798 && !flag_pic && !target_word_relocations
5799 && !arm_tls_referenced_p (operands[1])"
5800 [(clobber (const_int 0))]
5802 arm_emit_movpair (operands[0], operands[1]);
5806 ;; When generating pic, we need to load the symbol offset into a register.
5807 ;; So that the optimizer does not confuse this with a normal symbol load
5808 ;; we use an unspec. The offset will be loaded from a constant pool entry,
5809 ;; since that is the only type of relocation we can use.
5811 ;; Wrap calculation of the whole PIC address in a single pattern for the
5812 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5813 ;; a PIC address involves two loads from memory, so we want to CSE it
5814 ;; as often as possible.
5815 ;; This pattern will be split into one of the pic_load_addr_* patterns
5816 ;; and a move after GCSE optimizations.
5818 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5819 (define_expand "calculate_pic_address"
5820 [(set (match_operand:SI 0 "register_operand" "")
5821 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5822 (unspec:SI [(match_operand:SI 2 "" "")]
5827 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5829 [(set (match_operand:SI 0 "register_operand" "")
5830 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5831 (unspec:SI [(match_operand:SI 2 "" "")]
5834 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5835 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5836 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5839 ;; operand1 is the memory address to go into
5840 ;; pic_load_addr_32bit.
5841 ;; operand2 is the PIC label to be emitted
5842 ;; from pic_add_dot_plus_eight.
5843 ;; We do this to allow hoisting of the entire insn.
5844 (define_insn_and_split "pic_load_addr_unified"
5845 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5846 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5847 (match_operand:SI 2 "" "")]
5848 UNSPEC_PIC_UNIFIED))]
5851 "&& reload_completed"
5852 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5853 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5854 (match_dup 2)] UNSPEC_PIC_BASE))]
5855 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5856 [(set_attr "type" "load1,load1,load1")
5857 (set_attr "pool_range" "4096,4094,1022")
5858 (set_attr "neg_pool_range" "4084,0,0")
5859 (set_attr "arch" "a,t2,t1")
5860 (set_attr "length" "8,6,4")]
5863 ;; The rather odd constraints on the following are to force reload to leave
5864 ;; the insn alone, and to force the minipool generation pass to then move
5865 ;; the GOT symbol to memory.
5867 (define_insn "pic_load_addr_32bit"
5868 [(set (match_operand:SI 0 "s_register_operand" "=r")
5869 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5870 "TARGET_32BIT && flag_pic"
5872 [(set_attr "type" "load1")
5873 (set (attr "pool_range")
5874 (if_then_else (eq_attr "is_thumb" "no")
5877 (set (attr "neg_pool_range")
5878 (if_then_else (eq_attr "is_thumb" "no")
5883 (define_insn "pic_load_addr_thumb1"
5884 [(set (match_operand:SI 0 "s_register_operand" "=l")
5885 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5886 "TARGET_THUMB1 && flag_pic"
5888 [(set_attr "type" "load1")
5889 (set (attr "pool_range") (const_int 1018))]
5892 (define_insn "pic_add_dot_plus_four"
5893 [(set (match_operand:SI 0 "register_operand" "=r")
5894 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5896 (match_operand 2 "" "")]
5900 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5901 INTVAL (operands[2]));
5902 return \"add\\t%0, %|pc\";
5904 [(set_attr "length" "2")
5905 (set_attr "type" "alu_sreg")]
5908 (define_insn "pic_add_dot_plus_eight"
5909 [(set (match_operand:SI 0 "register_operand" "=r")
5910 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5912 (match_operand 2 "" "")]
5916 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5917 INTVAL (operands[2]));
5918 return \"add%?\\t%0, %|pc, %1\";
5920 [(set_attr "predicable" "yes")
5921 (set_attr "type" "alu_sreg")]
5924 (define_insn "tls_load_dot_plus_eight"
5925 [(set (match_operand:SI 0 "register_operand" "=r")
5926 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5928 (match_operand 2 "" "")]
5932 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5933 INTVAL (operands[2]));
5934 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5936 [(set_attr "predicable" "yes")
5937 (set_attr "type" "load1")]
5940 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5941 ;; followed by a load. These sequences can be crunched down to
5942 ;; tls_load_dot_plus_eight by a peephole.
5945 [(set (match_operand:SI 0 "register_operand" "")
5946 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5948 (match_operand 1 "" "")]
5950 (set (match_operand:SI 2 "arm_general_register_operand" "")
5951 (mem:SI (match_dup 0)))]
5952 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5954 (mem:SI (unspec:SI [(match_dup 3)
5961 (define_insn "pic_offset_arm"
5962 [(set (match_operand:SI 0 "register_operand" "=r")
5963 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5964 (unspec:SI [(match_operand:SI 2 "" "X")]
5965 UNSPEC_PIC_OFFSET))))]
5966 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5967 "ldr%?\\t%0, [%1,%2]"
5968 [(set_attr "type" "load1")]
5971 (define_expand "builtin_setjmp_receiver"
5972 [(label_ref (match_operand 0 "" ""))]
5976 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5978 if (arm_pic_register != INVALID_REGNUM)
5979 arm_load_pic_register (1UL << 3);
5983 ;; If copying one reg to another we can set the condition codes according to
5984 ;; its value. Such a move is common after a return from subroutine and the
5985 ;; result is being tested against zero.
5987 (define_insn "*movsi_compare0"
5988 [(set (reg:CC CC_REGNUM)
5989 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5991 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5996 subs%?\\t%0, %1, #0"
5997 [(set_attr "conds" "set")
5998 (set_attr "type" "alus_imm,alus_imm")]
6001 ;; Subroutine to store a half word from a register into memory.
6002 ;; Operand 0 is the source register (HImode)
6003 ;; Operand 1 is the destination address in a register (SImode)
6005 ;; In both this routine and the next, we must be careful not to spill
6006 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6007 ;; can generate unrecognizable rtl.
6009 (define_expand "storehi"
6010 [;; store the low byte
6011 (set (match_operand 1 "" "") (match_dup 3))
6012 ;; extract the high byte
6014 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6015 ;; store the high byte
6016 (set (match_dup 4) (match_dup 5))]
6020 rtx op1 = operands[1];
6021 rtx addr = XEXP (op1, 0);
6022 enum rtx_code code = GET_CODE (addr);
6024 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6026 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6028 operands[4] = adjust_address (op1, QImode, 1);
6029 operands[1] = adjust_address (operands[1], QImode, 0);
6030 operands[3] = gen_lowpart (QImode, operands[0]);
6031 operands[0] = gen_lowpart (SImode, operands[0]);
6032 operands[2] = gen_reg_rtx (SImode);
6033 operands[5] = gen_lowpart (QImode, operands[2]);
6037 (define_expand "storehi_bigend"
6038 [(set (match_dup 4) (match_dup 3))
6040 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6041 (set (match_operand 1 "" "") (match_dup 5))]
6045 rtx op1 = operands[1];
6046 rtx addr = XEXP (op1, 0);
6047 enum rtx_code code = GET_CODE (addr);
6049 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6051 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6053 operands[4] = adjust_address (op1, QImode, 1);
6054 operands[1] = adjust_address (operands[1], QImode, 0);
6055 operands[3] = gen_lowpart (QImode, operands[0]);
6056 operands[0] = gen_lowpart (SImode, operands[0]);
6057 operands[2] = gen_reg_rtx (SImode);
6058 operands[5] = gen_lowpart (QImode, operands[2]);
6062 ;; Subroutine to store a half word integer constant into memory.
6063 (define_expand "storeinthi"
6064 [(set (match_operand 0 "" "")
6065 (match_operand 1 "" ""))
6066 (set (match_dup 3) (match_dup 2))]
6070 HOST_WIDE_INT value = INTVAL (operands[1]);
6071 rtx addr = XEXP (operands[0], 0);
6072 rtx op0 = operands[0];
6073 enum rtx_code code = GET_CODE (addr);
6075 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6077 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6079 operands[1] = gen_reg_rtx (SImode);
6080 if (BYTES_BIG_ENDIAN)
6082 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6083 if ((value & 255) == ((value >> 8) & 255))
6084 operands[2] = operands[1];
6087 operands[2] = gen_reg_rtx (SImode);
6088 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6093 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6094 if ((value & 255) == ((value >> 8) & 255))
6095 operands[2] = operands[1];
6098 operands[2] = gen_reg_rtx (SImode);
6099 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6103 operands[3] = adjust_address (op0, QImode, 1);
6104 operands[0] = adjust_address (operands[0], QImode, 0);
6105 operands[2] = gen_lowpart (QImode, operands[2]);
6106 operands[1] = gen_lowpart (QImode, operands[1]);
6110 (define_expand "storehi_single_op"
6111 [(set (match_operand:HI 0 "memory_operand" "")
6112 (match_operand:HI 1 "general_operand" ""))]
6113 "TARGET_32BIT && arm_arch4"
6115 if (!s_register_operand (operands[1], HImode))
6116 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6120 (define_expand "movhi"
6121 [(set (match_operand:HI 0 "general_operand" "")
6122 (match_operand:HI 1 "general_operand" ""))]
6127 if (can_create_pseudo_p ())
6129 if (MEM_P (operands[0]))
6133 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6136 if (CONST_INT_P (operands[1]))
6137 emit_insn (gen_storeinthi (operands[0], operands[1]));
6140 if (MEM_P (operands[1]))
6141 operands[1] = force_reg (HImode, operands[1]);
6142 if (BYTES_BIG_ENDIAN)
6143 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6145 emit_insn (gen_storehi (operands[1], operands[0]));
6149 /* Sign extend a constant, and keep it in an SImode reg. */
6150 else if (CONST_INT_P (operands[1]))
6152 rtx reg = gen_reg_rtx (SImode);
6153 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6155 /* If the constant is already valid, leave it alone. */
6156 if (!const_ok_for_arm (val))
6158 /* If setting all the top bits will make the constant
6159 loadable in a single instruction, then set them.
6160 Otherwise, sign extend the number. */
6162 if (const_ok_for_arm (~(val | ~0xffff)))
6164 else if (val & 0x8000)
6168 emit_insn (gen_movsi (reg, GEN_INT (val)));
6169 operands[1] = gen_lowpart (HImode, reg);
6171 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6172 && MEM_P (operands[1]))
6174 rtx reg = gen_reg_rtx (SImode);
6176 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6177 operands[1] = gen_lowpart (HImode, reg);
6179 else if (!arm_arch4)
6181 if (MEM_P (operands[1]))
6184 rtx offset = const0_rtx;
6185 rtx reg = gen_reg_rtx (SImode);
6187 if ((REG_P (base = XEXP (operands[1], 0))
6188 || (GET_CODE (base) == PLUS
6189 && (CONST_INT_P (offset = XEXP (base, 1)))
6190 && ((INTVAL(offset) & 1) != 1)
6191 && REG_P (base = XEXP (base, 0))))
6192 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6196 new_rtx = widen_memory_access (operands[1], SImode,
6197 ((INTVAL (offset) & ~3)
6198 - INTVAL (offset)));
6199 emit_insn (gen_movsi (reg, new_rtx));
6200 if (((INTVAL (offset) & 2) != 0)
6201 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6203 rtx reg2 = gen_reg_rtx (SImode);
6205 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6210 emit_insn (gen_movhi_bytes (reg, operands[1]));
6212 operands[1] = gen_lowpart (HImode, reg);
6216 /* Handle loading a large integer during reload. */
6217 else if (CONST_INT_P (operands[1])
6218 && !const_ok_for_arm (INTVAL (operands[1]))
6219 && !const_ok_for_arm (~INTVAL (operands[1])))
6221 /* Writing a constant to memory needs a scratch, which should
6222 be handled with SECONDARY_RELOADs. */
6223 gcc_assert (REG_P (operands[0]));
6225 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6226 emit_insn (gen_movsi (operands[0], operands[1]));
6230 else if (TARGET_THUMB2)
6232 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6233 if (can_create_pseudo_p ())
6235 if (!REG_P (operands[0]))
6236 operands[1] = force_reg (HImode, operands[1]);
6237 /* Zero extend a constant, and keep it in an SImode reg. */
6238 else if (CONST_INT_P (operands[1]))
6240 rtx reg = gen_reg_rtx (SImode);
6241 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6243 emit_insn (gen_movsi (reg, GEN_INT (val)));
6244 operands[1] = gen_lowpart (HImode, reg);
6248 else /* TARGET_THUMB1 */
6250 if (can_create_pseudo_p ())
6252 if (CONST_INT_P (operands[1]))
6254 rtx reg = gen_reg_rtx (SImode);
6256 emit_insn (gen_movsi (reg, operands[1]));
6257 operands[1] = gen_lowpart (HImode, reg);
6260 /* ??? We shouldn't really get invalid addresses here, but this can
6261 happen if we are passed a SP (never OK for HImode/QImode) or
6262 virtual register (also rejected as illegitimate for HImode/QImode)
6263 relative address. */
6264 /* ??? This should perhaps be fixed elsewhere, for instance, in
6265 fixup_stack_1, by checking for other kinds of invalid addresses,
6266 e.g. a bare reference to a virtual register. This may confuse the
6267 alpha though, which must handle this case differently. */
6268 if (MEM_P (operands[0])
6269 && !memory_address_p (GET_MODE (operands[0]),
6270 XEXP (operands[0], 0)))
6272 = replace_equiv_address (operands[0],
6273 copy_to_reg (XEXP (operands[0], 0)));
6275 if (MEM_P (operands[1])
6276 && !memory_address_p (GET_MODE (operands[1]),
6277 XEXP (operands[1], 0)))
6279 = replace_equiv_address (operands[1],
6280 copy_to_reg (XEXP (operands[1], 0)));
6282 if (MEM_P (operands[1]) && optimize > 0)
6284 rtx reg = gen_reg_rtx (SImode);
6286 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6287 operands[1] = gen_lowpart (HImode, reg);
6290 if (MEM_P (operands[0]))
6291 operands[1] = force_reg (HImode, operands[1]);
6293 else if (CONST_INT_P (operands[1])
6294 && !satisfies_constraint_I (operands[1]))
6296 /* Handle loading a large integer during reload. */
6298 /* Writing a constant to memory needs a scratch, which should
6299 be handled with SECONDARY_RELOADs. */
6300 gcc_assert (REG_P (operands[0]));
6302 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6303 emit_insn (gen_movsi (operands[0], operands[1]));
6310 (define_expand "movhi_bytes"
6311 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6313 (zero_extend:SI (match_dup 6)))
6314 (set (match_operand:SI 0 "" "")
6315 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6320 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6322 mem1 = change_address (operands[1], QImode, addr);
6323 mem2 = change_address (operands[1], QImode,
6324 plus_constant (Pmode, addr, 1));
6325 operands[0] = gen_lowpart (SImode, operands[0]);
6327 operands[2] = gen_reg_rtx (SImode);
6328 operands[3] = gen_reg_rtx (SImode);
6331 if (BYTES_BIG_ENDIAN)
6333 operands[4] = operands[2];
6334 operands[5] = operands[3];
6338 operands[4] = operands[3];
6339 operands[5] = operands[2];
6344 (define_expand "movhi_bigend"
6346 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6349 (ashiftrt:SI (match_dup 2) (const_int 16)))
6350 (set (match_operand:HI 0 "s_register_operand" "")
6354 operands[2] = gen_reg_rtx (SImode);
6355 operands[3] = gen_reg_rtx (SImode);
6356 operands[4] = gen_lowpart (HImode, operands[3]);
6360 ;; Pattern to recognize insn generated default case above
6361 (define_insn "*movhi_insn_arch4"
6362 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6363 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6366 && (register_operand (operands[0], HImode)
6367 || register_operand (operands[1], HImode))"
6369 mov%?\\t%0, %1\\t%@ movhi
6370 mvn%?\\t%0, #%B1\\t%@ movhi
6371 movw%?\\t%0, %L1\\t%@ movhi
6372 strh%?\\t%1, %0\\t%@ movhi
6373 ldrh%?\\t%0, %1\\t%@ movhi"
6374 [(set_attr "predicable" "yes")
6375 (set_attr "pool_range" "*,*,*,*,256")
6376 (set_attr "neg_pool_range" "*,*,*,*,244")
6377 (set_attr "arch" "*,*,v6t2,*,*")
6378 (set_attr_alternative "type"
6379 [(if_then_else (match_operand 1 "const_int_operand" "")
6380 (const_string "mov_imm" )
6381 (const_string "mov_reg"))
6382 (const_string "mvn_imm")
6383 (const_string "mov_imm")
6384 (const_string "store1")
6385 (const_string "load1")])]
6388 (define_insn "*movhi_bytes"
6389 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6390 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6393 mov%?\\t%0, %1\\t%@ movhi
6394 mov%?\\t%0, %1\\t%@ movhi
6395 mvn%?\\t%0, #%B1\\t%@ movhi"
6396 [(set_attr "predicable" "yes")
6397 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6400 ;; We use a DImode scratch because we may occasionally need an additional
6401 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6402 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6403 (define_expand "reload_outhi"
6404 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6405 (match_operand:HI 1 "s_register_operand" "r")
6406 (match_operand:DI 2 "s_register_operand" "=&l")])]
6409 arm_reload_out_hi (operands);
6411 thumb_reload_out_hi (operands);
6416 (define_expand "reload_inhi"
6417 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6418 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6419 (match_operand:DI 2 "s_register_operand" "=&r")])]
6423 arm_reload_in_hi (operands);
6425 thumb_reload_out_hi (operands);
6429 (define_expand "movqi"
6430 [(set (match_operand:QI 0 "general_operand" "")
6431 (match_operand:QI 1 "general_operand" ""))]
6434 /* Everything except mem = const or mem = mem can be done easily */
6436 if (can_create_pseudo_p ())
6438 if (CONST_INT_P (operands[1]))
6440 rtx reg = gen_reg_rtx (SImode);
6442 /* For thumb we want an unsigned immediate, then we are more likely
6443 to be able to use a movs insn. */
6445 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6447 emit_insn (gen_movsi (reg, operands[1]));
6448 operands[1] = gen_lowpart (QImode, reg);
6453 /* ??? We shouldn't really get invalid addresses here, but this can
6454 happen if we are passed a SP (never OK for HImode/QImode) or
6455 virtual register (also rejected as illegitimate for HImode/QImode)
6456 relative address. */
6457 /* ??? This should perhaps be fixed elsewhere, for instance, in
6458 fixup_stack_1, by checking for other kinds of invalid addresses,
6459 e.g. a bare reference to a virtual register. This may confuse the
6460 alpha though, which must handle this case differently. */
6461 if (MEM_P (operands[0])
6462 && !memory_address_p (GET_MODE (operands[0]),
6463 XEXP (operands[0], 0)))
6465 = replace_equiv_address (operands[0],
6466 copy_to_reg (XEXP (operands[0], 0)));
6467 if (MEM_P (operands[1])
6468 && !memory_address_p (GET_MODE (operands[1]),
6469 XEXP (operands[1], 0)))
6471 = replace_equiv_address (operands[1],
6472 copy_to_reg (XEXP (operands[1], 0)));
6475 if (MEM_P (operands[1]) && optimize > 0)
6477 rtx reg = gen_reg_rtx (SImode);
6479 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6480 operands[1] = gen_lowpart (QImode, reg);
6483 if (MEM_P (operands[0]))
6484 operands[1] = force_reg (QImode, operands[1]);
6486 else if (TARGET_THUMB
6487 && CONST_INT_P (operands[1])
6488 && !satisfies_constraint_I (operands[1]))
6490 /* Handle loading a large integer during reload. */
6492 /* Writing a constant to memory needs a scratch, which should
6493 be handled with SECONDARY_RELOADs. */
6494 gcc_assert (REG_P (operands[0]));
6496 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6497 emit_insn (gen_movsi (operands[0], operands[1]));
6503 (define_insn "*arm_movqi_insn"
6504 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6505 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6507 && ( register_operand (operands[0], QImode)
6508 || register_operand (operands[1], QImode))"
6519 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6520 (set_attr "predicable" "yes")
6521 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6522 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6523 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6527 (define_expand "movhf"
6528 [(set (match_operand:HF 0 "general_operand" "")
6529 (match_operand:HF 1 "general_operand" ""))]
6534 if (MEM_P (operands[0]))
6535 operands[1] = force_reg (HFmode, operands[1]);
6537 else /* TARGET_THUMB1 */
6539 if (can_create_pseudo_p ())
6541 if (!REG_P (operands[0]))
6542 operands[1] = force_reg (HFmode, operands[1]);
6548 (define_insn "*arm32_movhf"
6549 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6550 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6551 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_VFP)
6552 && ( s_register_operand (operands[0], HFmode)
6553 || s_register_operand (operands[1], HFmode))"
6555 switch (which_alternative)
6557 case 0: /* ARM register from memory */
6558 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6559 case 1: /* memory from ARM register */
6560 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6561 case 2: /* ARM register from ARM register */
6562 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6563 case 3: /* ARM register from constant */
6568 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6570 ops[0] = operands[0];
6571 ops[1] = GEN_INT (bits);
6572 ops[2] = GEN_INT (bits & 0xff00);
6573 ops[3] = GEN_INT (bits & 0x00ff);
6575 if (arm_arch_thumb2)
6576 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6578 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6585 [(set_attr "conds" "unconditional")
6586 (set_attr "type" "load1,store1,mov_reg,multiple")
6587 (set_attr "length" "4,4,4,8")
6588 (set_attr "predicable" "yes")
6589 (set_attr "predicable_short_it" "no")]
6592 (define_expand "movsf"
6593 [(set (match_operand:SF 0 "general_operand" "")
6594 (match_operand:SF 1 "general_operand" ""))]
6599 if (MEM_P (operands[0]))
6600 operands[1] = force_reg (SFmode, operands[1]);
6602 else /* TARGET_THUMB1 */
6604 if (can_create_pseudo_p ())
6606 if (!REG_P (operands[0]))
6607 operands[1] = force_reg (SFmode, operands[1]);
6613 ;; Transform a floating-point move of a constant into a core register into
6614 ;; an SImode operation.
6616 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6617 (match_operand:SF 1 "immediate_operand" ""))]
6620 && CONST_DOUBLE_P (operands[1])"
6621 [(set (match_dup 2) (match_dup 3))]
6623 operands[2] = gen_lowpart (SImode, operands[0]);
6624 operands[3] = gen_lowpart (SImode, operands[1]);
6625 if (operands[2] == 0 || operands[3] == 0)
6630 (define_insn "*arm_movsf_soft_insn"
6631 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6632 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6634 && TARGET_SOFT_FLOAT
6635 && (!MEM_P (operands[0])
6636 || register_operand (operands[1], SFmode))"
6639 ldr%?\\t%0, %1\\t%@ float
6640 str%?\\t%1, %0\\t%@ float"
6641 [(set_attr "predicable" "yes")
6642 (set_attr "predicable_short_it" "no")
6643 (set_attr "type" "mov_reg,load1,store1")
6644 (set_attr "arm_pool_range" "*,4096,*")
6645 (set_attr "thumb2_pool_range" "*,4094,*")
6646 (set_attr "arm_neg_pool_range" "*,4084,*")
6647 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6650 (define_expand "movdf"
6651 [(set (match_operand:DF 0 "general_operand" "")
6652 (match_operand:DF 1 "general_operand" ""))]
6657 if (MEM_P (operands[0]))
6658 operands[1] = force_reg (DFmode, operands[1]);
6660 else /* TARGET_THUMB */
6662 if (can_create_pseudo_p ())
6664 if (!REG_P (operands[0]))
6665 operands[1] = force_reg (DFmode, operands[1]);
6671 ;; Reloading a df mode value stored in integer regs to memory can require a
6673 (define_expand "reload_outdf"
6674 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6675 (match_operand:DF 1 "s_register_operand" "r")
6676 (match_operand:SI 2 "s_register_operand" "=&r")]
6680 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6683 operands[2] = XEXP (operands[0], 0);
6684 else if (code == POST_INC || code == PRE_DEC)
6686 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6687 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6688 emit_insn (gen_movdi (operands[0], operands[1]));
6691 else if (code == PRE_INC)
6693 rtx reg = XEXP (XEXP (operands[0], 0), 0);
6695 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6698 else if (code == POST_DEC)
6699 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6701 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6702 XEXP (XEXP (operands[0], 0), 1)));
6704 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
6707 if (code == POST_DEC)
6708 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6714 (define_insn "*movdf_soft_insn"
6715 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6716 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
6717 "TARGET_32BIT && TARGET_SOFT_FLOAT
6718 && ( register_operand (operands[0], DFmode)
6719 || register_operand (operands[1], DFmode))"
6721 switch (which_alternative)
6728 return output_move_double (operands, true, NULL);
6731 [(set_attr "length" "8,12,16,8,8")
6732 (set_attr "type" "multiple,multiple,multiple,load2,store2")
6733 (set_attr "arm_pool_range" "*,*,*,1020,*")
6734 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6735 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6736 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6740 ;; load- and store-multiple insns
6741 ;; The arm can load/store any set of registers, provided that they are in
6742 ;; ascending order, but these expanders assume a contiguous set.
6744 (define_expand "load_multiple"
6745 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6746 (match_operand:SI 1 "" ""))
6747 (use (match_operand:SI 2 "" ""))])]
6750 HOST_WIDE_INT offset = 0;
6752 /* Support only fixed point registers. */
6753 if (!CONST_INT_P (operands[2])
6754 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6755 || INTVAL (operands[2]) < 2
6756 || !MEM_P (operands[1])
6757 || !REG_P (operands[0])
6758 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6759 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6763 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6764 INTVAL (operands[2]),
6765 force_reg (SImode, XEXP (operands[1], 0)),
6766 FALSE, operands[1], &offset);
6769 (define_expand "store_multiple"
6770 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6771 (match_operand:SI 1 "" ""))
6772 (use (match_operand:SI 2 "" ""))])]
6775 HOST_WIDE_INT offset = 0;
6777 /* Support only fixed point registers. */
6778 if (!CONST_INT_P (operands[2])
6779 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6780 || INTVAL (operands[2]) < 2
6781 || !REG_P (operands[1])
6782 || !MEM_P (operands[0])
6783 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6784 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6788 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6789 INTVAL (operands[2]),
6790 force_reg (SImode, XEXP (operands[0], 0)),
6791 FALSE, operands[0], &offset);
6795 (define_expand "setmemsi"
6796 [(match_operand:BLK 0 "general_operand" "")
6797 (match_operand:SI 1 "const_int_operand" "")
6798 (match_operand:SI 2 "const_int_operand" "")
6799 (match_operand:SI 3 "const_int_operand" "")]
6802 if (arm_gen_setmem (operands))
6809 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6810 ;; We could let this apply for blocks of less than this, but it clobbers so
6811 ;; many registers that there is then probably a better way.
6813 (define_expand "movmemqi"
6814 [(match_operand:BLK 0 "general_operand" "")
6815 (match_operand:BLK 1 "general_operand" "")
6816 (match_operand:SI 2 "const_int_operand" "")
6817 (match_operand:SI 3 "const_int_operand" "")]
6822 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6823 && !optimize_function_for_size_p (cfun))
6825 if (gen_movmem_ldrd_strd (operands))
6830 if (arm_gen_movmemqi (operands))
6834 else /* TARGET_THUMB1 */
6836 if ( INTVAL (operands[3]) != 4
6837 || INTVAL (operands[2]) > 48)
6840 thumb_expand_movmemqi (operands);
6847 ;; Compare & branch insns
6848 ;; The range calculations are based as follows:
6849 ;; For forward branches, the address calculation returns the address of
6850 ;; the next instruction. This is 2 beyond the branch instruction.
6851 ;; For backward branches, the address calculation returns the address of
6852 ;; the first instruction in this pattern (cmp). This is 2 before the branch
6853 ;; instruction for the shortest sequence, and 4 before the branch instruction
6854 ;; if we have to jump around an unconditional branch.
6855 ;; To the basic branch range the PC offset must be added (this is +4).
6856 ;; So for forward branches we have
6857 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6858 ;; And for backward branches we have
6859 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6861 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6862 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
6864 (define_expand "cbranchsi4"
6865 [(set (pc) (if_then_else
6866 (match_operator 0 "expandable_comparison_operator"
6867 [(match_operand:SI 1 "s_register_operand" "")
6868 (match_operand:SI 2 "nonmemory_operand" "")])
6869 (label_ref (match_operand 3 "" ""))
6875 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6877 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6881 if (thumb1_cmpneg_operand (operands[2], SImode))
6883 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6884 operands[3], operands[0]));
6887 if (!thumb1_cmp_operand (operands[2], SImode))
6888 operands[2] = force_reg (SImode, operands[2]);
6891 (define_expand "cbranchsf4"
6892 [(set (pc) (if_then_else
6893 (match_operator 0 "expandable_comparison_operator"
6894 [(match_operand:SF 1 "s_register_operand" "")
6895 (match_operand:SF 2 "arm_float_compare_operand" "")])
6896 (label_ref (match_operand 3 "" ""))
6898 "TARGET_32BIT && TARGET_HARD_FLOAT"
6899 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6900 operands[3])); DONE;"
6903 (define_expand "cbranchdf4"
6904 [(set (pc) (if_then_else
6905 (match_operator 0 "expandable_comparison_operator"
6906 [(match_operand:DF 1 "s_register_operand" "")
6907 (match_operand:DF 2 "arm_float_compare_operand" "")])
6908 (label_ref (match_operand 3 "" ""))
6910 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6911 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6912 operands[3])); DONE;"
6915 (define_expand "cbranchdi4"
6916 [(set (pc) (if_then_else
6917 (match_operator 0 "expandable_comparison_operator"
6918 [(match_operand:DI 1 "s_register_operand" "")
6919 (match_operand:DI 2 "cmpdi_operand" "")])
6920 (label_ref (match_operand 3 "" ""))
6924 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6926 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6932 ;; Comparison and test insns
6934 (define_insn "*arm_cmpsi_insn"
6935 [(set (reg:CC CC_REGNUM)
6936 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6937 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
6945 [(set_attr "conds" "set")
6946 (set_attr "arch" "t2,t2,any,any,any")
6947 (set_attr "length" "2,2,4,4,4")
6948 (set_attr "predicable" "yes")
6949 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6950 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6953 (define_insn "*cmpsi_shiftsi"
6954 [(set (reg:CC CC_REGNUM)
6955 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
6956 (match_operator:SI 3 "shift_operator"
6957 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6958 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6961 [(set_attr "conds" "set")
6962 (set_attr "shift" "1")
6963 (set_attr "arch" "32,a,a")
6964 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6966 (define_insn "*cmpsi_shiftsi_swp"
6967 [(set (reg:CC_SWP CC_REGNUM)
6968 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6969 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6970 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6971 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6974 [(set_attr "conds" "set")
6975 (set_attr "shift" "1")
6976 (set_attr "arch" "32,a,a")
6977 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6979 (define_insn "*arm_cmpsi_negshiftsi_si"
6980 [(set (reg:CC_Z CC_REGNUM)
6982 (neg:SI (match_operator:SI 1 "shift_operator"
6983 [(match_operand:SI 2 "s_register_operand" "r")
6984 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6985 (match_operand:SI 0 "s_register_operand" "r")))]
6988 [(set_attr "conds" "set")
6989 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6990 (const_string "alus_shift_imm")
6991 (const_string "alus_shift_reg")))
6992 (set_attr "predicable" "yes")]
6995 ;; DImode comparisons. The generic code generates branches that
6996 ;; if-conversion can not reduce to a conditional compare, so we do
6999 (define_insn_and_split "*arm_cmpdi_insn"
7000 [(set (reg:CC_NCV CC_REGNUM)
7001 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7002 (match_operand:DI 1 "arm_di_operand" "rDi")))
7003 (clobber (match_scratch:SI 2 "=r"))]
7005 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7006 "&& reload_completed"
7007 [(set (reg:CC CC_REGNUM)
7008 (compare:CC (match_dup 0) (match_dup 1)))
7009 (parallel [(set (reg:CC CC_REGNUM)
7010 (compare:CC (match_dup 3) (match_dup 4)))
7012 (minus:SI (match_dup 5)
7013 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7015 operands[3] = gen_highpart (SImode, operands[0]);
7016 operands[0] = gen_lowpart (SImode, operands[0]);
7017 if (CONST_INT_P (operands[1]))
7019 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7022 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7026 operands[4] = gen_highpart (SImode, operands[1]);
7027 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7029 operands[1] = gen_lowpart (SImode, operands[1]);
7030 operands[2] = gen_lowpart (SImode, operands[2]);
7032 [(set_attr "conds" "set")
7033 (set_attr "length" "8")
7034 (set_attr "type" "multiple")]
7037 (define_insn_and_split "*arm_cmpdi_unsigned"
7038 [(set (reg:CC_CZ CC_REGNUM)
7039 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7040 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7043 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7044 "&& reload_completed"
7045 [(set (reg:CC CC_REGNUM)
7046 (compare:CC (match_dup 2) (match_dup 3)))
7047 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7048 (set (reg:CC CC_REGNUM)
7049 (compare:CC (match_dup 0) (match_dup 1))))]
7051 operands[2] = gen_highpart (SImode, operands[0]);
7052 operands[0] = gen_lowpart (SImode, operands[0]);
7053 if (CONST_INT_P (operands[1]))
7054 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7056 operands[3] = gen_highpart (SImode, operands[1]);
7057 operands[1] = gen_lowpart (SImode, operands[1]);
7059 [(set_attr "conds" "set")
7060 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7061 (set_attr "arch" "t2,t2,t2,a")
7062 (set_attr "length" "6,6,10,8")
7063 (set_attr "type" "multiple")]
7066 (define_insn "*arm_cmpdi_zero"
7067 [(set (reg:CC_Z CC_REGNUM)
7068 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7070 (clobber (match_scratch:SI 1 "=r"))]
7072 "orrs%?\\t%1, %Q0, %R0"
7073 [(set_attr "conds" "set")
7074 (set_attr "type" "logics_reg")]
7077 ; This insn allows redundant compares to be removed by cse, nothing should
7078 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7079 ; is deleted later on. The match_dup will match the mode here, so that
7080 ; mode changes of the condition codes aren't lost by this even though we don't
7081 ; specify what they are.
7083 (define_insn "*deleted_compare"
7084 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7086 "\\t%@ deleted compare"
7087 [(set_attr "conds" "set")
7088 (set_attr "length" "0")
7089 (set_attr "type" "no_insn")]
7093 ;; Conditional branch insns
7095 (define_expand "cbranch_cc"
7097 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7098 (match_operand 2 "" "")])
7099 (label_ref (match_operand 3 "" ""))
7102 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7103 operands[1], operands[2], NULL_RTX);
7104 operands[2] = const0_rtx;"
7108 ;; Patterns to match conditional branch insns.
7111 (define_insn "arm_cond_branch"
7113 (if_then_else (match_operator 1 "arm_comparison_operator"
7114 [(match_operand 2 "cc_register" "") (const_int 0)])
7115 (label_ref (match_operand 0 "" ""))
7119 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7121 arm_ccfsm_state += 2;
7124 return \"b%d1\\t%l0\";
7126 [(set_attr "conds" "use")
7127 (set_attr "type" "branch")
7128 (set (attr "length")
7130 (and (match_test "TARGET_THUMB2")
7131 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7132 (le (minus (match_dup 0) (pc)) (const_int 256))))
7137 (define_insn "*arm_cond_branch_reversed"
7139 (if_then_else (match_operator 1 "arm_comparison_operator"
7140 [(match_operand 2 "cc_register" "") (const_int 0)])
7142 (label_ref (match_operand 0 "" ""))))]
7145 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7147 arm_ccfsm_state += 2;
7150 return \"b%D1\\t%l0\";
7152 [(set_attr "conds" "use")
7153 (set_attr "type" "branch")
7154 (set (attr "length")
7156 (and (match_test "TARGET_THUMB2")
7157 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7158 (le (minus (match_dup 0) (pc)) (const_int 256))))
7167 (define_expand "cstore_cc"
7168 [(set (match_operand:SI 0 "s_register_operand" "")
7169 (match_operator:SI 1 "" [(match_operand 2 "" "")
7170 (match_operand 3 "" "")]))]
7172 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7173 operands[2], operands[3], NULL_RTX);
7174 operands[3] = const0_rtx;"
7177 (define_insn_and_split "*mov_scc"
7178 [(set (match_operand:SI 0 "s_register_operand" "=r")
7179 (match_operator:SI 1 "arm_comparison_operator_mode"
7180 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7182 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7185 (if_then_else:SI (match_dup 1)
7189 [(set_attr "conds" "use")
7190 (set_attr "length" "8")
7191 (set_attr "type" "multiple")]
7194 (define_insn_and_split "*mov_negscc"
7195 [(set (match_operand:SI 0 "s_register_operand" "=r")
7196 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7197 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7199 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7202 (if_then_else:SI (match_dup 1)
7206 operands[3] = GEN_INT (~0);
7208 [(set_attr "conds" "use")
7209 (set_attr "length" "8")
7210 (set_attr "type" "multiple")]
7213 (define_insn_and_split "*mov_notscc"
7214 [(set (match_operand:SI 0 "s_register_operand" "=r")
7215 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7216 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7218 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7221 (if_then_else:SI (match_dup 1)
7225 operands[3] = GEN_INT (~1);
7226 operands[4] = GEN_INT (~0);
7228 [(set_attr "conds" "use")
7229 (set_attr "length" "8")
7230 (set_attr "type" "multiple")]
7233 (define_expand "cstoresi4"
7234 [(set (match_operand:SI 0 "s_register_operand" "")
7235 (match_operator:SI 1 "expandable_comparison_operator"
7236 [(match_operand:SI 2 "s_register_operand" "")
7237 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7238 "TARGET_32BIT || TARGET_THUMB1"
7240 rtx op3, scratch, scratch2;
7244 if (!arm_add_operand (operands[3], SImode))
7245 operands[3] = force_reg (SImode, operands[3]);
7246 emit_insn (gen_cstore_cc (operands[0], operands[1],
7247 operands[2], operands[3]));
7251 if (operands[3] == const0_rtx)
7253 switch (GET_CODE (operands[1]))
7256 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7260 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7264 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7265 NULL_RTX, 0, OPTAB_WIDEN);
7266 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7267 NULL_RTX, 0, OPTAB_WIDEN);
7268 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7269 operands[0], 1, OPTAB_WIDEN);
7273 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7275 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7276 NULL_RTX, 1, OPTAB_WIDEN);
7280 scratch = expand_binop (SImode, ashr_optab, operands[2],
7281 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7282 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7283 NULL_RTX, 0, OPTAB_WIDEN);
7284 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7288 /* LT is handled by generic code. No need for unsigned with 0. */
7295 switch (GET_CODE (operands[1]))
7298 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7299 NULL_RTX, 0, OPTAB_WIDEN);
7300 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7304 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7305 NULL_RTX, 0, OPTAB_WIDEN);
7306 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7310 op3 = force_reg (SImode, operands[3]);
7312 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7313 NULL_RTX, 1, OPTAB_WIDEN);
7314 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7315 NULL_RTX, 0, OPTAB_WIDEN);
7316 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7322 if (!thumb1_cmp_operand (op3, SImode))
7323 op3 = force_reg (SImode, op3);
7324 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7325 NULL_RTX, 0, OPTAB_WIDEN);
7326 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7327 NULL_RTX, 1, OPTAB_WIDEN);
7328 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7333 op3 = force_reg (SImode, operands[3]);
7334 scratch = force_reg (SImode, const0_rtx);
7335 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7341 if (!thumb1_cmp_operand (op3, SImode))
7342 op3 = force_reg (SImode, op3);
7343 scratch = force_reg (SImode, const0_rtx);
7344 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7350 if (!thumb1_cmp_operand (op3, SImode))
7351 op3 = force_reg (SImode, op3);
7352 scratch = gen_reg_rtx (SImode);
7353 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7357 op3 = force_reg (SImode, operands[3]);
7358 scratch = gen_reg_rtx (SImode);
7359 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7362 /* No good sequences for GT, LT. */
7369 (define_expand "cstoresf4"
7370 [(set (match_operand:SI 0 "s_register_operand" "")
7371 (match_operator:SI 1 "expandable_comparison_operator"
7372 [(match_operand:SF 2 "s_register_operand" "")
7373 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7374 "TARGET_32BIT && TARGET_HARD_FLOAT"
7375 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7376 operands[2], operands[3])); DONE;"
7379 (define_expand "cstoredf4"
7380 [(set (match_operand:SI 0 "s_register_operand" "")
7381 (match_operator:SI 1 "expandable_comparison_operator"
7382 [(match_operand:DF 2 "s_register_operand" "")
7383 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7384 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7385 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7386 operands[2], operands[3])); DONE;"
7389 (define_expand "cstoredi4"
7390 [(set (match_operand:SI 0 "s_register_operand" "")
7391 (match_operator:SI 1 "expandable_comparison_operator"
7392 [(match_operand:DI 2 "s_register_operand" "")
7393 (match_operand:DI 3 "cmpdi_operand" "")]))]
7396 if (!arm_validize_comparison (&operands[1],
7400 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7407 ;; Conditional move insns
7409 (define_expand "movsicc"
7410 [(set (match_operand:SI 0 "s_register_operand" "")
7411 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7412 (match_operand:SI 2 "arm_not_operand" "")
7413 (match_operand:SI 3 "arm_not_operand" "")))]
7420 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7421 &XEXP (operands[1], 1)))
7424 code = GET_CODE (operands[1]);
7425 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7426 XEXP (operands[1], 1), NULL_RTX);
7427 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7431 (define_expand "movsfcc"
7432 [(set (match_operand:SF 0 "s_register_operand" "")
7433 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7434 (match_operand:SF 2 "s_register_operand" "")
7435 (match_operand:SF 3 "s_register_operand" "")))]
7436 "TARGET_32BIT && TARGET_HARD_FLOAT"
7439 enum rtx_code code = GET_CODE (operands[1]);
7442 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7443 &XEXP (operands[1], 1)))
7446 code = GET_CODE (operands[1]);
7447 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7448 XEXP (operands[1], 1), NULL_RTX);
7449 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7453 (define_expand "movdfcc"
7454 [(set (match_operand:DF 0 "s_register_operand" "")
7455 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7456 (match_operand:DF 2 "s_register_operand" "")
7457 (match_operand:DF 3 "s_register_operand" "")))]
7458 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7461 enum rtx_code code = GET_CODE (operands[1]);
7464 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7465 &XEXP (operands[1], 1)))
7467 code = GET_CODE (operands[1]);
7468 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7469 XEXP (operands[1], 1), NULL_RTX);
7470 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7474 (define_insn "*cmov<mode>"
7475 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7476 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7477 [(match_operand 2 "cc_register" "") (const_int 0)])
7478 (match_operand:SDF 3 "s_register_operand"
7480 (match_operand:SDF 4 "s_register_operand"
7481 "<F_constraint>")))]
7482 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7485 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7492 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7497 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7503 [(set_attr "conds" "use")
7504 (set_attr "type" "fcsel")]
7507 (define_insn_and_split "*movsicc_insn"
7508 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7510 (match_operator 3 "arm_comparison_operator"
7511 [(match_operand 4 "cc_register" "") (const_int 0)])
7512 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7513 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7524 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7525 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7526 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7527 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7528 "&& reload_completed"
7531 enum rtx_code rev_code;
7535 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7537 gen_rtx_SET (operands[0], operands[1])));
7539 rev_code = GET_CODE (operands[3]);
7540 mode = GET_MODE (operands[4]);
7541 if (mode == CCFPmode || mode == CCFPEmode)
7542 rev_code = reverse_condition_maybe_unordered (rev_code);
7544 rev_code = reverse_condition (rev_code);
7546 rev_cond = gen_rtx_fmt_ee (rev_code,
7550 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7552 gen_rtx_SET (operands[0], operands[2])));
7555 [(set_attr "length" "4,4,4,4,8,8,8,8")
7556 (set_attr "conds" "use")
7557 (set_attr_alternative "type"
7558 [(if_then_else (match_operand 2 "const_int_operand" "")
7559 (const_string "mov_imm")
7560 (const_string "mov_reg"))
7561 (const_string "mvn_imm")
7562 (if_then_else (match_operand 1 "const_int_operand" "")
7563 (const_string "mov_imm")
7564 (const_string "mov_reg"))
7565 (const_string "mvn_imm")
7566 (const_string "multiple")
7567 (const_string "multiple")
7568 (const_string "multiple")
7569 (const_string "multiple")])]
7572 (define_insn "*movsfcc_soft_insn"
7573 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7574 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7575 [(match_operand 4 "cc_register" "") (const_int 0)])
7576 (match_operand:SF 1 "s_register_operand" "0,r")
7577 (match_operand:SF 2 "s_register_operand" "r,0")))]
7578 "TARGET_ARM && TARGET_SOFT_FLOAT"
7582 [(set_attr "conds" "use")
7583 (set_attr "type" "mov_reg")]
7587 ;; Jump and linkage insns
7589 (define_expand "jump"
7591 (label_ref (match_operand 0 "" "")))]
7596 (define_insn "*arm_jump"
7598 (label_ref (match_operand 0 "" "")))]
7602 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7604 arm_ccfsm_state += 2;
7607 return \"b%?\\t%l0\";
7610 [(set_attr "predicable" "yes")
7611 (set (attr "length")
7613 (and (match_test "TARGET_THUMB2")
7614 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7615 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7618 (set_attr "type" "branch")]
7621 (define_expand "call"
7622 [(parallel [(call (match_operand 0 "memory_operand" "")
7623 (match_operand 1 "general_operand" ""))
7624 (use (match_operand 2 "" ""))
7625 (clobber (reg:SI LR_REGNUM))])]
7631 /* In an untyped call, we can get NULL for operand 2. */
7632 if (operands[2] == NULL_RTX)
7633 operands[2] = const0_rtx;
7635 /* Decide if we should generate indirect calls by loading the
7636 32-bit address of the callee into a register before performing the
7638 callee = XEXP (operands[0], 0);
7639 if (GET_CODE (callee) == SYMBOL_REF
7640 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7642 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7644 pat = gen_call_internal (operands[0], operands[1], operands[2]);
7645 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7650 (define_expand "call_internal"
7651 [(parallel [(call (match_operand 0 "memory_operand" "")
7652 (match_operand 1 "general_operand" ""))
7653 (use (match_operand 2 "" ""))
7654 (clobber (reg:SI LR_REGNUM))])])
7656 (define_insn "*call_reg_armv5"
7657 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7658 (match_operand 1 "" ""))
7659 (use (match_operand 2 "" ""))
7660 (clobber (reg:SI LR_REGNUM))]
7661 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7663 [(set_attr "type" "call")]
7666 (define_insn "*call_reg_arm"
7667 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7668 (match_operand 1 "" ""))
7669 (use (match_operand 2 "" ""))
7670 (clobber (reg:SI LR_REGNUM))]
7671 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7673 return output_call (operands);
7675 ;; length is worst case, normally it is only two
7676 [(set_attr "length" "12")
7677 (set_attr "type" "call")]
7681 (define_expand "call_value"
7682 [(parallel [(set (match_operand 0 "" "")
7683 (call (match_operand 1 "memory_operand" "")
7684 (match_operand 2 "general_operand" "")))
7685 (use (match_operand 3 "" ""))
7686 (clobber (reg:SI LR_REGNUM))])]
7692 /* In an untyped call, we can get NULL for operand 2. */
7693 if (operands[3] == 0)
7694 operands[3] = const0_rtx;
7696 /* Decide if we should generate indirect calls by loading the
7697 32-bit address of the callee into a register before performing the
7699 callee = XEXP (operands[1], 0);
7700 if (GET_CODE (callee) == SYMBOL_REF
7701 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7703 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7705 pat = gen_call_value_internal (operands[0], operands[1],
7706 operands[2], operands[3]);
7707 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7712 (define_expand "call_value_internal"
7713 [(parallel [(set (match_operand 0 "" "")
7714 (call (match_operand 1 "memory_operand" "")
7715 (match_operand 2 "general_operand" "")))
7716 (use (match_operand 3 "" ""))
7717 (clobber (reg:SI LR_REGNUM))])])
7719 (define_insn "*call_value_reg_armv5"
7720 [(set (match_operand 0 "" "")
7721 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7722 (match_operand 2 "" "")))
7723 (use (match_operand 3 "" ""))
7724 (clobber (reg:SI LR_REGNUM))]
7725 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7727 [(set_attr "type" "call")]
7730 (define_insn "*call_value_reg_arm"
7731 [(set (match_operand 0 "" "")
7732 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7733 (match_operand 2 "" "")))
7734 (use (match_operand 3 "" ""))
7735 (clobber (reg:SI LR_REGNUM))]
7736 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7738 return output_call (&operands[1]);
7740 [(set_attr "length" "12")
7741 (set_attr "type" "call")]
7744 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7745 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7747 (define_insn "*call_symbol"
7748 [(call (mem:SI (match_operand:SI 0 "" ""))
7749 (match_operand 1 "" ""))
7750 (use (match_operand 2 "" ""))
7751 (clobber (reg:SI LR_REGNUM))]
7753 && !SIBLING_CALL_P (insn)
7754 && (GET_CODE (operands[0]) == SYMBOL_REF)
7755 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7758 rtx op = operands[0];
7760 /* Switch mode now when possible. */
7761 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7762 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7763 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7765 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7767 [(set_attr "type" "call")]
7770 (define_insn "*call_value_symbol"
7771 [(set (match_operand 0 "" "")
7772 (call (mem:SI (match_operand:SI 1 "" ""))
7773 (match_operand:SI 2 "" "")))
7774 (use (match_operand 3 "" ""))
7775 (clobber (reg:SI LR_REGNUM))]
7777 && !SIBLING_CALL_P (insn)
7778 && (GET_CODE (operands[1]) == SYMBOL_REF)
7779 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7782 rtx op = operands[1];
7784 /* Switch mode now when possible. */
7785 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7786 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7787 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
7789 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7791 [(set_attr "type" "call")]
7794 (define_expand "sibcall_internal"
7795 [(parallel [(call (match_operand 0 "memory_operand" "")
7796 (match_operand 1 "general_operand" ""))
7798 (use (match_operand 2 "" ""))])])
7800 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7801 (define_expand "sibcall"
7802 [(parallel [(call (match_operand 0 "memory_operand" "")
7803 (match_operand 1 "general_operand" ""))
7805 (use (match_operand 2 "" ""))])]
7811 if ((!REG_P (XEXP (operands[0], 0))
7812 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7813 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7814 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7815 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7817 if (operands[2] == NULL_RTX)
7818 operands[2] = const0_rtx;
7820 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7821 arm_emit_call_insn (pat, operands[0], true);
7826 (define_expand "sibcall_value_internal"
7827 [(parallel [(set (match_operand 0 "" "")
7828 (call (match_operand 1 "memory_operand" "")
7829 (match_operand 2 "general_operand" "")))
7831 (use (match_operand 3 "" ""))])])
7833 (define_expand "sibcall_value"
7834 [(parallel [(set (match_operand 0 "" "")
7835 (call (match_operand 1 "memory_operand" "")
7836 (match_operand 2 "general_operand" "")))
7838 (use (match_operand 3 "" ""))])]
7844 if ((!REG_P (XEXP (operands[1], 0))
7845 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7846 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7847 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7848 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7850 if (operands[3] == NULL_RTX)
7851 operands[3] = const0_rtx;
7853 pat = gen_sibcall_value_internal (operands[0], operands[1],
7854 operands[2], operands[3]);
7855 arm_emit_call_insn (pat, operands[1], true);
7860 (define_insn "*sibcall_insn"
7861 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7862 (match_operand 1 "" ""))
7864 (use (match_operand 2 "" ""))]
7865 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7867 if (which_alternative == 1)
7868 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7871 if (arm_arch5 || arm_arch4t)
7872 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7874 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7877 [(set_attr "type" "call")]
7880 (define_insn "*sibcall_value_insn"
7881 [(set (match_operand 0 "" "")
7882 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7883 (match_operand 2 "" "")))
7885 (use (match_operand 3 "" ""))]
7886 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7888 if (which_alternative == 1)
7889 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7892 if (arm_arch5 || arm_arch4t)
7893 return \"bx%?\\t%1\";
7895 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7898 [(set_attr "type" "call")]
7901 (define_expand "<return_str>return"
7903 "(TARGET_ARM || (TARGET_THUMB2
7904 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7905 && !IS_STACKALIGN (arm_current_func_type ())))
7906 <return_cond_false>"
7911 thumb2_expand_return (<return_simple_p>);
7918 ;; Often the return insn will be the same as loading from memory, so set attr
7919 (define_insn "*arm_return"
7921 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7924 if (arm_ccfsm_state == 2)
7926 arm_ccfsm_state += 2;
7929 return output_return_instruction (const_true_rtx, true, false, false);
7931 [(set_attr "type" "load1")
7932 (set_attr "length" "12")
7933 (set_attr "predicable" "yes")]
7936 (define_insn "*cond_<return_str>return"
7938 (if_then_else (match_operator 0 "arm_comparison_operator"
7939 [(match_operand 1 "cc_register" "") (const_int 0)])
7942 "TARGET_ARM <return_cond_true>"
7945 if (arm_ccfsm_state == 2)
7947 arm_ccfsm_state += 2;
7950 return output_return_instruction (operands[0], true, false,
7953 [(set_attr "conds" "use")
7954 (set_attr "length" "12")
7955 (set_attr "type" "load1")]
7958 (define_insn "*cond_<return_str>return_inverted"
7960 (if_then_else (match_operator 0 "arm_comparison_operator"
7961 [(match_operand 1 "cc_register" "") (const_int 0)])
7964 "TARGET_ARM <return_cond_true>"
7967 if (arm_ccfsm_state == 2)
7969 arm_ccfsm_state += 2;
7972 return output_return_instruction (operands[0], true, true,
7975 [(set_attr "conds" "use")
7976 (set_attr "length" "12")
7977 (set_attr "type" "load1")]
7980 (define_insn "*arm_simple_return"
7985 if (arm_ccfsm_state == 2)
7987 arm_ccfsm_state += 2;
7990 return output_return_instruction (const_true_rtx, true, false, true);
7992 [(set_attr "type" "branch")
7993 (set_attr "length" "4")
7994 (set_attr "predicable" "yes")]
7997 ;; Generate a sequence of instructions to determine if the processor is
7998 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8001 (define_expand "return_addr_mask"
8003 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8005 (set (match_operand:SI 0 "s_register_operand" "")
8006 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8008 (const_int 67108860)))] ; 0x03fffffc
8011 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8014 (define_insn "*check_arch2"
8015 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8016 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8019 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8020 [(set_attr "length" "8")
8021 (set_attr "conds" "set")
8022 (set_attr "type" "multiple")]
8025 ;; Call subroutine returning any type.
8027 (define_expand "untyped_call"
8028 [(parallel [(call (match_operand 0 "" "")
8030 (match_operand 1 "" "")
8031 (match_operand 2 "" "")])]
8036 rtx par = gen_rtx_PARALLEL (VOIDmode,
8037 rtvec_alloc (XVECLEN (operands[2], 0)));
8038 rtx addr = gen_reg_rtx (Pmode);
8042 emit_move_insn (addr, XEXP (operands[1], 0));
8043 mem = change_address (operands[1], BLKmode, addr);
8045 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8047 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8049 /* Default code only uses r0 as a return value, but we could
8050 be using anything up to 4 registers. */
8051 if (REGNO (src) == R0_REGNUM)
8052 src = gen_rtx_REG (TImode, R0_REGNUM);
8054 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8056 size += GET_MODE_SIZE (GET_MODE (src));
8059 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8063 for (i = 0; i < XVECLEN (par, 0); i++)
8065 HOST_WIDE_INT offset = 0;
8066 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8069 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8071 mem = change_address (mem, GET_MODE (reg), NULL);
8072 if (REGNO (reg) == R0_REGNUM)
8074 /* On thumb we have to use a write-back instruction. */
8075 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8076 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8077 size = TARGET_ARM ? 16 : 0;
8081 emit_move_insn (mem, reg);
8082 size = GET_MODE_SIZE (GET_MODE (reg));
8086 /* The optimizer does not know that the call sets the function value
8087 registers we stored in the result block. We avoid problems by
8088 claiming that all hard registers are used and clobbered at this
8090 emit_insn (gen_blockage ());
8096 (define_expand "untyped_return"
8097 [(match_operand:BLK 0 "memory_operand" "")
8098 (match_operand 1 "" "")]
8103 rtx addr = gen_reg_rtx (Pmode);
8107 emit_move_insn (addr, XEXP (operands[0], 0));
8108 mem = change_address (operands[0], BLKmode, addr);
8110 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8112 HOST_WIDE_INT offset = 0;
8113 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8116 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8118 mem = change_address (mem, GET_MODE (reg), NULL);
8119 if (REGNO (reg) == R0_REGNUM)
8121 /* On thumb we have to use a write-back instruction. */
8122 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8123 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8124 size = TARGET_ARM ? 16 : 0;
8128 emit_move_insn (reg, mem);
8129 size = GET_MODE_SIZE (GET_MODE (reg));
8133 /* Emit USE insns before the return. */
8134 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8135 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8137 /* Construct the return. */
8138 expand_naked_return ();
8144 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8145 ;; all of memory. This blocks insns from being moved across this point.
8147 (define_insn "blockage"
8148 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8151 [(set_attr "length" "0")
8152 (set_attr "type" "block")]
8155 (define_insn "probe_stack"
8156 [(set (match_operand:SI 0 "memory_operand" "=m")
8157 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8160 [(set_attr "type" "store1")
8161 (set_attr "predicable" "yes")]
8164 (define_insn "probe_stack_range"
8165 [(set (match_operand:SI 0 "register_operand" "=r")
8166 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8167 (match_operand:SI 2 "register_operand" "r")]
8168 VUNSPEC_PROBE_STACK_RANGE))]
8171 return output_probe_stack_range (operands[0], operands[2]);
8173 [(set_attr "type" "multiple")
8174 (set_attr "conds" "clob")]
8177 (define_expand "casesi"
8178 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8179 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8180 (match_operand:SI 2 "const_int_operand" "") ; total range
8181 (match_operand:SI 3 "" "") ; table label
8182 (match_operand:SI 4 "" "")] ; Out of range label
8183 "TARGET_32BIT || optimize_size || flag_pic"
8186 enum insn_code code;
8187 if (operands[1] != const0_rtx)
8189 rtx reg = gen_reg_rtx (SImode);
8191 emit_insn (gen_addsi3 (reg, operands[0],
8192 gen_int_mode (-INTVAL (operands[1]),
8198 code = CODE_FOR_arm_casesi_internal;
8199 else if (TARGET_THUMB1)
8200 code = CODE_FOR_thumb1_casesi_internal_pic;
8202 code = CODE_FOR_thumb2_casesi_internal_pic;
8204 code = CODE_FOR_thumb2_casesi_internal;
8206 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8207 operands[2] = force_reg (SImode, operands[2]);
8209 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8210 operands[3], operands[4]));
8215 ;; The USE in this pattern is needed to tell flow analysis that this is
8216 ;; a CASESI insn. It has no other purpose.
8217 (define_insn "arm_casesi_internal"
8218 [(parallel [(set (pc)
8220 (leu (match_operand:SI 0 "s_register_operand" "r")
8221 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8222 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8223 (label_ref (match_operand 2 "" ""))))
8224 (label_ref (match_operand 3 "" ""))))
8225 (clobber (reg:CC CC_REGNUM))
8226 (use (label_ref (match_dup 2)))])]
8230 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8231 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8233 [(set_attr "conds" "clob")
8234 (set_attr "length" "12")
8235 (set_attr "type" "multiple")]
8238 (define_expand "indirect_jump"
8240 (match_operand:SI 0 "s_register_operand" ""))]
8243 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8244 address and use bx. */
8248 tmp = gen_reg_rtx (SImode);
8249 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8255 ;; NB Never uses BX.
8256 (define_insn "*arm_indirect_jump"
8258 (match_operand:SI 0 "s_register_operand" "r"))]
8260 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8261 [(set_attr "predicable" "yes")
8262 (set_attr "type" "branch")]
8265 (define_insn "*load_indirect_jump"
8267 (match_operand:SI 0 "memory_operand" "m"))]
8269 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8270 [(set_attr "type" "load1")
8271 (set_attr "pool_range" "4096")
8272 (set_attr "neg_pool_range" "4084")
8273 (set_attr "predicable" "yes")]
8283 [(set (attr "length")
8284 (if_then_else (eq_attr "is_thumb" "yes")
8287 (set_attr "type" "mov_reg")]
8291 [(trap_if (const_int 1) (const_int 0))]
8295 return \".inst\\t0xe7f000f0\";
8297 return \".inst\\t0xdeff\";
8299 [(set (attr "length")
8300 (if_then_else (eq_attr "is_thumb" "yes")
8303 (set_attr "type" "trap")
8304 (set_attr "conds" "unconditional")]
8308 ;; Patterns to allow combination of arithmetic, cond code and shifts
8310 (define_insn "*<arith_shift_insn>_multsi"
8311 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8313 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8314 (match_operand:SI 3 "power_of_two_operand" ""))
8315 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8317 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8318 [(set_attr "predicable" "yes")
8319 (set_attr "predicable_short_it" "no")
8320 (set_attr "shift" "2")
8321 (set_attr "arch" "a,t2")
8322 (set_attr "type" "alu_shift_imm")])
8324 (define_insn "*<arith_shift_insn>_shiftsi"
8325 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8327 (match_operator:SI 2 "shift_nomul_operator"
8328 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8329 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8330 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8331 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8332 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8333 [(set_attr "predicable" "yes")
8334 (set_attr "predicable_short_it" "no")
8335 (set_attr "shift" "3")
8336 (set_attr "arch" "a,t2,a")
8337 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8340 [(set (match_operand:SI 0 "s_register_operand" "")
8341 (match_operator:SI 1 "shiftable_operator"
8342 [(match_operator:SI 2 "shiftable_operator"
8343 [(match_operator:SI 3 "shift_operator"
8344 [(match_operand:SI 4 "s_register_operand" "")
8345 (match_operand:SI 5 "reg_or_int_operand" "")])
8346 (match_operand:SI 6 "s_register_operand" "")])
8347 (match_operand:SI 7 "arm_rhs_operand" "")]))
8348 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8351 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8354 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8357 (define_insn "*arith_shiftsi_compare0"
8358 [(set (reg:CC_NOOV CC_REGNUM)
8360 (match_operator:SI 1 "shiftable_operator"
8361 [(match_operator:SI 3 "shift_operator"
8362 [(match_operand:SI 4 "s_register_operand" "r,r")
8363 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8364 (match_operand:SI 2 "s_register_operand" "r,r")])
8366 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8367 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8370 "%i1s%?\\t%0, %2, %4%S3"
8371 [(set_attr "conds" "set")
8372 (set_attr "shift" "4")
8373 (set_attr "arch" "32,a")
8374 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8376 (define_insn "*arith_shiftsi_compare0_scratch"
8377 [(set (reg:CC_NOOV CC_REGNUM)
8379 (match_operator:SI 1 "shiftable_operator"
8380 [(match_operator:SI 3 "shift_operator"
8381 [(match_operand:SI 4 "s_register_operand" "r,r")
8382 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8383 (match_operand:SI 2 "s_register_operand" "r,r")])
8385 (clobber (match_scratch:SI 0 "=r,r"))]
8387 "%i1s%?\\t%0, %2, %4%S3"
8388 [(set_attr "conds" "set")
8389 (set_attr "shift" "4")
8390 (set_attr "arch" "32,a")
8391 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8393 (define_insn "*sub_shiftsi"
8394 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8395 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8396 (match_operator:SI 2 "shift_operator"
8397 [(match_operand:SI 3 "s_register_operand" "r,r")
8398 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8400 "sub%?\\t%0, %1, %3%S2"
8401 [(set_attr "predicable" "yes")
8402 (set_attr "shift" "3")
8403 (set_attr "arch" "32,a")
8404 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8406 (define_insn "*sub_shiftsi_compare0"
8407 [(set (reg:CC_NOOV CC_REGNUM)
8409 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8410 (match_operator:SI 2 "shift_operator"
8411 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8412 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8414 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8415 (minus:SI (match_dup 1)
8416 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8418 "subs%?\\t%0, %1, %3%S2"
8419 [(set_attr "conds" "set")
8420 (set_attr "shift" "3")
8421 (set_attr "arch" "32,a,a")
8422 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8424 (define_insn "*sub_shiftsi_compare0_scratch"
8425 [(set (reg:CC_NOOV CC_REGNUM)
8427 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8428 (match_operator:SI 2 "shift_operator"
8429 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8430 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8432 (clobber (match_scratch:SI 0 "=r,r,r"))]
8434 "subs%?\\t%0, %1, %3%S2"
8435 [(set_attr "conds" "set")
8436 (set_attr "shift" "3")
8437 (set_attr "arch" "32,a,a")
8438 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8441 (define_insn_and_split "*and_scc"
8442 [(set (match_operand:SI 0 "s_register_operand" "=r")
8443 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8444 [(match_operand 2 "cc_register" "") (const_int 0)])
8445 (match_operand:SI 3 "s_register_operand" "r")))]
8447 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8448 "&& reload_completed"
8449 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8450 (cond_exec (match_dup 4) (set (match_dup 0)
8451 (and:SI (match_dup 3) (const_int 1))))]
8453 machine_mode mode = GET_MODE (operands[2]);
8454 enum rtx_code rc = GET_CODE (operands[1]);
8456 /* Note that operands[4] is the same as operands[1],
8457 but with VOIDmode as the result. */
8458 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8459 if (mode == CCFPmode || mode == CCFPEmode)
8460 rc = reverse_condition_maybe_unordered (rc);
8462 rc = reverse_condition (rc);
8463 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8465 [(set_attr "conds" "use")
8466 (set_attr "type" "multiple")
8467 (set_attr "length" "8")]
8470 (define_insn_and_split "*ior_scc"
8471 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8472 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8473 [(match_operand 2 "cc_register" "") (const_int 0)])
8474 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8479 "&& reload_completed
8480 && REGNO (operands [0]) != REGNO (operands[3])"
8481 ;; && which_alternative == 1
8482 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8483 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8484 (cond_exec (match_dup 4) (set (match_dup 0)
8485 (ior:SI (match_dup 3) (const_int 1))))]
8487 machine_mode mode = GET_MODE (operands[2]);
8488 enum rtx_code rc = GET_CODE (operands[1]);
8490 /* Note that operands[4] is the same as operands[1],
8491 but with VOIDmode as the result. */
8492 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8493 if (mode == CCFPmode || mode == CCFPEmode)
8494 rc = reverse_condition_maybe_unordered (rc);
8496 rc = reverse_condition (rc);
8497 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8499 [(set_attr "conds" "use")
8500 (set_attr "length" "4,8")
8501 (set_attr "type" "logic_imm,multiple")]
8504 ; A series of splitters for the compare_scc pattern below. Note that
8505 ; order is important.
8507 [(set (match_operand:SI 0 "s_register_operand" "")
8508 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8510 (clobber (reg:CC CC_REGNUM))]
8511 "TARGET_32BIT && reload_completed"
8512 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8515 [(set (match_operand:SI 0 "s_register_operand" "")
8516 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8518 (clobber (reg:CC CC_REGNUM))]
8519 "TARGET_32BIT && reload_completed"
8520 [(set (match_dup 0) (not:SI (match_dup 1)))
8521 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8524 [(set (match_operand:SI 0 "s_register_operand" "")
8525 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8527 (clobber (reg:CC CC_REGNUM))]
8528 "arm_arch5 && TARGET_32BIT"
8529 [(set (match_dup 0) (clz:SI (match_dup 1)))
8530 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8534 [(set (match_operand:SI 0 "s_register_operand" "")
8535 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8537 (clobber (reg:CC CC_REGNUM))]
8538 "TARGET_32BIT && reload_completed"
8540 [(set (reg:CC CC_REGNUM)
8541 (compare:CC (const_int 1) (match_dup 1)))
8543 (minus:SI (const_int 1) (match_dup 1)))])
8544 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8545 (set (match_dup 0) (const_int 0)))])
8548 [(set (match_operand:SI 0 "s_register_operand" "")
8549 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8550 (match_operand:SI 2 "const_int_operand" "")))
8551 (clobber (reg:CC CC_REGNUM))]
8552 "TARGET_32BIT && reload_completed"
8554 [(set (reg:CC CC_REGNUM)
8555 (compare:CC (match_dup 1) (match_dup 2)))
8556 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8557 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8558 (set (match_dup 0) (const_int 1)))]
8560 operands[3] = GEN_INT (-INTVAL (operands[2]));
8564 [(set (match_operand:SI 0 "s_register_operand" "")
8565 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8566 (match_operand:SI 2 "arm_add_operand" "")))
8567 (clobber (reg:CC CC_REGNUM))]
8568 "TARGET_32BIT && reload_completed"
8570 [(set (reg:CC_NOOV CC_REGNUM)
8571 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8573 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8574 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8575 (set (match_dup 0) (const_int 1)))])
8577 (define_insn_and_split "*compare_scc"
8578 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8579 (match_operator:SI 1 "arm_comparison_operator"
8580 [(match_operand:SI 2 "s_register_operand" "r,r")
8581 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8582 (clobber (reg:CC CC_REGNUM))]
8585 "&& reload_completed"
8586 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8587 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8588 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8591 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8592 operands[2], operands[3]);
8593 enum rtx_code rc = GET_CODE (operands[1]);
8595 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8597 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8598 if (mode == CCFPmode || mode == CCFPEmode)
8599 rc = reverse_condition_maybe_unordered (rc);
8601 rc = reverse_condition (rc);
8602 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8604 [(set_attr "type" "multiple")]
8607 ;; Attempt to improve the sequence generated by the compare_scc splitters
8608 ;; not to use conditional execution.
8610 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
8614 [(set (reg:CC CC_REGNUM)
8615 (compare:CC (match_operand:SI 1 "register_operand" "")
8617 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8618 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8619 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8620 (set (match_dup 0) (const_int 1)))]
8621 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8622 [(set (match_dup 0) (clz:SI (match_dup 1)))
8623 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8626 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8630 [(set (reg:CC CC_REGNUM)
8631 (compare:CC (match_operand:SI 1 "register_operand" "")
8633 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8634 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8635 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8636 (set (match_dup 0) (const_int 1)))
8637 (match_scratch:SI 2 "r")]
8638 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8640 [(set (reg:CC CC_REGNUM)
8641 (compare:CC (const_int 0) (match_dup 1)))
8642 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8644 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8645 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8648 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
8649 ;; sub Rd, Reg1, reg2
8653 [(set (reg:CC CC_REGNUM)
8654 (compare:CC (match_operand:SI 1 "register_operand" "")
8655 (match_operand:SI 2 "arm_rhs_operand" "")))
8656 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8657 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8658 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8659 (set (match_dup 0) (const_int 1)))]
8660 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8661 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8662 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8663 (set (match_dup 0) (clz:SI (match_dup 0)))
8664 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8668 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
8669 ;; sub T1, Reg1, reg2
8673 [(set (reg:CC CC_REGNUM)
8674 (compare:CC (match_operand:SI 1 "register_operand" "")
8675 (match_operand:SI 2 "arm_rhs_operand" "")))
8676 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8677 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8678 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8679 (set (match_dup 0) (const_int 1)))
8680 (match_scratch:SI 3 "r")]
8681 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8682 [(set (match_dup 3) (match_dup 4))
8684 [(set (reg:CC CC_REGNUM)
8685 (compare:CC (const_int 0) (match_dup 3)))
8686 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8688 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8689 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8691 if (CONST_INT_P (operands[2]))
8692 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8694 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8697 (define_insn "*cond_move"
8698 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8699 (if_then_else:SI (match_operator 3 "equality_operator"
8700 [(match_operator 4 "arm_comparison_operator"
8701 [(match_operand 5 "cc_register" "") (const_int 0)])
8703 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8704 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8707 if (GET_CODE (operands[3]) == NE)
8709 if (which_alternative != 1)
8710 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8711 if (which_alternative != 0)
8712 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8715 if (which_alternative != 0)
8716 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8717 if (which_alternative != 1)
8718 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8721 [(set_attr "conds" "use")
8722 (set_attr_alternative "type"
8723 [(if_then_else (match_operand 2 "const_int_operand" "")
8724 (const_string "mov_imm")
8725 (const_string "mov_reg"))
8726 (if_then_else (match_operand 1 "const_int_operand" "")
8727 (const_string "mov_imm")
8728 (const_string "mov_reg"))
8729 (const_string "multiple")])
8730 (set_attr "length" "4,4,8")]
8733 (define_insn "*cond_arith"
8734 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8735 (match_operator:SI 5 "shiftable_operator"
8736 [(match_operator:SI 4 "arm_comparison_operator"
8737 [(match_operand:SI 2 "s_register_operand" "r,r")
8738 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8739 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8740 (clobber (reg:CC CC_REGNUM))]
8743 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8744 return \"%i5\\t%0, %1, %2, lsr #31\";
8746 output_asm_insn (\"cmp\\t%2, %3\", operands);
8747 if (GET_CODE (operands[5]) == AND)
8748 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8749 else if (GET_CODE (operands[5]) == MINUS)
8750 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8751 else if (which_alternative != 0)
8752 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8753 return \"%i5%d4\\t%0, %1, #1\";
8755 [(set_attr "conds" "clob")
8756 (set_attr "length" "12")
8757 (set_attr "type" "multiple")]
8760 (define_insn "*cond_sub"
8761 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8762 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8763 (match_operator:SI 4 "arm_comparison_operator"
8764 [(match_operand:SI 2 "s_register_operand" "r,r")
8765 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8766 (clobber (reg:CC CC_REGNUM))]
8769 output_asm_insn (\"cmp\\t%2, %3\", operands);
8770 if (which_alternative != 0)
8771 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8772 return \"sub%d4\\t%0, %1, #1\";
8774 [(set_attr "conds" "clob")
8775 (set_attr "length" "8,12")
8776 (set_attr "type" "multiple")]
8779 (define_insn "*cmp_ite0"
8780 [(set (match_operand 6 "dominant_cc_register" "")
8783 (match_operator 4 "arm_comparison_operator"
8784 [(match_operand:SI 0 "s_register_operand"
8785 "l,l,l,r,r,r,r,r,r")
8786 (match_operand:SI 1 "arm_add_operand"
8787 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8788 (match_operator:SI 5 "arm_comparison_operator"
8789 [(match_operand:SI 2 "s_register_operand"
8790 "l,r,r,l,l,r,r,r,r")
8791 (match_operand:SI 3 "arm_add_operand"
8792 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8798 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8800 {\"cmp%d5\\t%0, %1\",
8801 \"cmp%d4\\t%2, %3\"},
8802 {\"cmn%d5\\t%0, #%n1\",
8803 \"cmp%d4\\t%2, %3\"},
8804 {\"cmp%d5\\t%0, %1\",
8805 \"cmn%d4\\t%2, #%n3\"},
8806 {\"cmn%d5\\t%0, #%n1\",
8807 \"cmn%d4\\t%2, #%n3\"}
8809 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8814 \"cmn\\t%0, #%n1\"},
8815 {\"cmn\\t%2, #%n3\",
8817 {\"cmn\\t%2, #%n3\",
8820 static const char * const ite[2] =
8825 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8826 CMP_CMP, CMN_CMP, CMP_CMP,
8827 CMN_CMP, CMP_CMN, CMN_CMN};
8829 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8831 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8832 if (TARGET_THUMB2) {
8833 output_asm_insn (ite[swap], operands);
8835 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8838 [(set_attr "conds" "set")
8839 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8840 (set_attr "type" "multiple")
8841 (set_attr_alternative "length"
8847 (if_then_else (eq_attr "is_thumb" "no")
8850 (if_then_else (eq_attr "is_thumb" "no")
8853 (if_then_else (eq_attr "is_thumb" "no")
8856 (if_then_else (eq_attr "is_thumb" "no")
8861 (define_insn "*cmp_ite1"
8862 [(set (match_operand 6 "dominant_cc_register" "")
8865 (match_operator 4 "arm_comparison_operator"
8866 [(match_operand:SI 0 "s_register_operand"
8867 "l,l,l,r,r,r,r,r,r")
8868 (match_operand:SI 1 "arm_add_operand"
8869 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8870 (match_operator:SI 5 "arm_comparison_operator"
8871 [(match_operand:SI 2 "s_register_operand"
8872 "l,r,r,l,l,r,r,r,r")
8873 (match_operand:SI 3 "arm_add_operand"
8874 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8880 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8884 {\"cmn\\t%0, #%n1\",
8887 \"cmn\\t%2, #%n3\"},
8888 {\"cmn\\t%0, #%n1\",
8891 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8893 {\"cmp%d4\\t%2, %3\",
8894 \"cmp%D5\\t%0, %1\"},
8895 {\"cmp%d4\\t%2, %3\",
8896 \"cmn%D5\\t%0, #%n1\"},
8897 {\"cmn%d4\\t%2, #%n3\",
8898 \"cmp%D5\\t%0, %1\"},
8899 {\"cmn%d4\\t%2, #%n3\",
8900 \"cmn%D5\\t%0, #%n1\"}
8902 static const char * const ite[2] =
8907 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8908 CMP_CMP, CMN_CMP, CMP_CMP,
8909 CMN_CMP, CMP_CMN, CMN_CMN};
8911 comparison_dominates_p (GET_CODE (operands[5]),
8912 reverse_condition (GET_CODE (operands[4])));
8914 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8915 if (TARGET_THUMB2) {
8916 output_asm_insn (ite[swap], operands);
8918 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8921 [(set_attr "conds" "set")
8922 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8923 (set_attr_alternative "length"
8929 (if_then_else (eq_attr "is_thumb" "no")
8932 (if_then_else (eq_attr "is_thumb" "no")
8935 (if_then_else (eq_attr "is_thumb" "no")
8938 (if_then_else (eq_attr "is_thumb" "no")
8941 (set_attr "type" "multiple")]
8944 (define_insn "*cmp_and"
8945 [(set (match_operand 6 "dominant_cc_register" "")
8948 (match_operator 4 "arm_comparison_operator"
8949 [(match_operand:SI 0 "s_register_operand"
8950 "l,l,l,r,r,r,r,r,r")
8951 (match_operand:SI 1 "arm_add_operand"
8952 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8953 (match_operator:SI 5 "arm_comparison_operator"
8954 [(match_operand:SI 2 "s_register_operand"
8955 "l,r,r,l,l,r,r,r,r")
8956 (match_operand:SI 3 "arm_add_operand"
8957 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8962 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8964 {\"cmp%d5\\t%0, %1\",
8965 \"cmp%d4\\t%2, %3\"},
8966 {\"cmn%d5\\t%0, #%n1\",
8967 \"cmp%d4\\t%2, %3\"},
8968 {\"cmp%d5\\t%0, %1\",
8969 \"cmn%d4\\t%2, #%n3\"},
8970 {\"cmn%d5\\t%0, #%n1\",
8971 \"cmn%d4\\t%2, #%n3\"}
8973 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8978 \"cmn\\t%0, #%n1\"},
8979 {\"cmn\\t%2, #%n3\",
8981 {\"cmn\\t%2, #%n3\",
8984 static const char *const ite[2] =
8989 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8990 CMP_CMP, CMN_CMP, CMP_CMP,
8991 CMN_CMP, CMP_CMN, CMN_CMN};
8993 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8995 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8996 if (TARGET_THUMB2) {
8997 output_asm_insn (ite[swap], operands);
8999 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9002 [(set_attr "conds" "set")
9003 (set_attr "predicable" "no")
9004 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9005 (set_attr_alternative "length"
9011 (if_then_else (eq_attr "is_thumb" "no")
9014 (if_then_else (eq_attr "is_thumb" "no")
9017 (if_then_else (eq_attr "is_thumb" "no")
9020 (if_then_else (eq_attr "is_thumb" "no")
9023 (set_attr "type" "multiple")]
9026 (define_insn "*cmp_ior"
9027 [(set (match_operand 6 "dominant_cc_register" "")
9030 (match_operator 4 "arm_comparison_operator"
9031 [(match_operand:SI 0 "s_register_operand"
9032 "l,l,l,r,r,r,r,r,r")
9033 (match_operand:SI 1 "arm_add_operand"
9034 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9035 (match_operator:SI 5 "arm_comparison_operator"
9036 [(match_operand:SI 2 "s_register_operand"
9037 "l,r,r,l,l,r,r,r,r")
9038 (match_operand:SI 3 "arm_add_operand"
9039 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9044 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9048 {\"cmn\\t%0, #%n1\",
9051 \"cmn\\t%2, #%n3\"},
9052 {\"cmn\\t%0, #%n1\",
9055 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9057 {\"cmp%D4\\t%2, %3\",
9058 \"cmp%D5\\t%0, %1\"},
9059 {\"cmp%D4\\t%2, %3\",
9060 \"cmn%D5\\t%0, #%n1\"},
9061 {\"cmn%D4\\t%2, #%n3\",
9062 \"cmp%D5\\t%0, %1\"},
9063 {\"cmn%D4\\t%2, #%n3\",
9064 \"cmn%D5\\t%0, #%n1\"}
9066 static const char *const ite[2] =
9071 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9072 CMP_CMP, CMN_CMP, CMP_CMP,
9073 CMN_CMP, CMP_CMN, CMN_CMN};
9075 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9077 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9078 if (TARGET_THUMB2) {
9079 output_asm_insn (ite[swap], operands);
9081 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9085 [(set_attr "conds" "set")
9086 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9087 (set_attr_alternative "length"
9093 (if_then_else (eq_attr "is_thumb" "no")
9096 (if_then_else (eq_attr "is_thumb" "no")
9099 (if_then_else (eq_attr "is_thumb" "no")
9102 (if_then_else (eq_attr "is_thumb" "no")
9105 (set_attr "type" "multiple")]
9108 (define_insn_and_split "*ior_scc_scc"
9109 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9110 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9111 [(match_operand:SI 1 "s_register_operand" "r")
9112 (match_operand:SI 2 "arm_add_operand" "rIL")])
9113 (match_operator:SI 6 "arm_comparison_operator"
9114 [(match_operand:SI 4 "s_register_operand" "r")
9115 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9116 (clobber (reg:CC CC_REGNUM))]
9118 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9121 "TARGET_32BIT && reload_completed"
9125 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9126 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9128 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9130 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9133 [(set_attr "conds" "clob")
9134 (set_attr "length" "16")
9135 (set_attr "type" "multiple")]
9138 ; If the above pattern is followed by a CMP insn, then the compare is
9139 ; redundant, since we can rework the conditional instruction that follows.
9140 (define_insn_and_split "*ior_scc_scc_cmp"
9141 [(set (match_operand 0 "dominant_cc_register" "")
9142 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9143 [(match_operand:SI 1 "s_register_operand" "r")
9144 (match_operand:SI 2 "arm_add_operand" "rIL")])
9145 (match_operator:SI 6 "arm_comparison_operator"
9146 [(match_operand:SI 4 "s_register_operand" "r")
9147 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9149 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9150 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9151 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9154 "TARGET_32BIT && reload_completed"
9158 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9159 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9161 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9163 [(set_attr "conds" "set")
9164 (set_attr "length" "16")
9165 (set_attr "type" "multiple")]
9168 (define_insn_and_split "*and_scc_scc"
9169 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9170 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9171 [(match_operand:SI 1 "s_register_operand" "r")
9172 (match_operand:SI 2 "arm_add_operand" "rIL")])
9173 (match_operator:SI 6 "arm_comparison_operator"
9174 [(match_operand:SI 4 "s_register_operand" "r")
9175 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9176 (clobber (reg:CC CC_REGNUM))]
9178 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9181 "TARGET_32BIT && reload_completed
9182 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9187 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9188 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9190 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9192 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9195 [(set_attr "conds" "clob")
9196 (set_attr "length" "16")
9197 (set_attr "type" "multiple")]
9200 ; If the above pattern is followed by a CMP insn, then the compare is
9201 ; redundant, since we can rework the conditional instruction that follows.
9202 (define_insn_and_split "*and_scc_scc_cmp"
9203 [(set (match_operand 0 "dominant_cc_register" "")
9204 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9205 [(match_operand:SI 1 "s_register_operand" "r")
9206 (match_operand:SI 2 "arm_add_operand" "rIL")])
9207 (match_operator:SI 6 "arm_comparison_operator"
9208 [(match_operand:SI 4 "s_register_operand" "r")
9209 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9211 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9212 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9213 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9216 "TARGET_32BIT && reload_completed"
9220 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9221 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9223 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9225 [(set_attr "conds" "set")
9226 (set_attr "length" "16")
9227 (set_attr "type" "multiple")]
9230 ;; If there is no dominance in the comparison, then we can still save an
9231 ;; instruction in the AND case, since we can know that the second compare
9232 ;; need only zero the value if false (if true, then the value is already
9234 (define_insn_and_split "*and_scc_scc_nodom"
9235 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9236 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9237 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9238 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9239 (match_operator:SI 6 "arm_comparison_operator"
9240 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9241 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9242 (clobber (reg:CC CC_REGNUM))]
9244 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9247 "TARGET_32BIT && reload_completed"
9248 [(parallel [(set (match_dup 0)
9249 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9250 (clobber (reg:CC CC_REGNUM))])
9251 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9253 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9256 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9257 operands[4], operands[5]),
9259 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9261 [(set_attr "conds" "clob")
9262 (set_attr "length" "20")
9263 (set_attr "type" "multiple")]
9267 [(set (reg:CC_NOOV CC_REGNUM)
9268 (compare:CC_NOOV (ior:SI
9269 (and:SI (match_operand:SI 0 "s_register_operand" "")
9271 (match_operator:SI 1 "arm_comparison_operator"
9272 [(match_operand:SI 2 "s_register_operand" "")
9273 (match_operand:SI 3 "arm_add_operand" "")]))
9275 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9278 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9280 (set (reg:CC_NOOV CC_REGNUM)
9281 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9286 [(set (reg:CC_NOOV CC_REGNUM)
9287 (compare:CC_NOOV (ior:SI
9288 (match_operator:SI 1 "arm_comparison_operator"
9289 [(match_operand:SI 2 "s_register_operand" "")
9290 (match_operand:SI 3 "arm_add_operand" "")])
9291 (and:SI (match_operand:SI 0 "s_register_operand" "")
9294 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9297 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9299 (set (reg:CC_NOOV CC_REGNUM)
9300 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9303 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9305 (define_insn_and_split "*negscc"
9306 [(set (match_operand:SI 0 "s_register_operand" "=r")
9307 (neg:SI (match_operator 3 "arm_comparison_operator"
9308 [(match_operand:SI 1 "s_register_operand" "r")
9309 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9310 (clobber (reg:CC CC_REGNUM))]
9313 "&& reload_completed"
9316 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9318 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9320 /* Emit mov\\t%0, %1, asr #31 */
9321 emit_insn (gen_rtx_SET (operands[0],
9322 gen_rtx_ASHIFTRT (SImode,
9327 else if (GET_CODE (operands[3]) == NE)
9329 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9330 if (CONST_INT_P (operands[2]))
9331 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9332 GEN_INT (- INTVAL (operands[2]))));
9334 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9336 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9340 gen_rtx_SET (operands[0],
9346 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9347 emit_insn (gen_rtx_SET (cc_reg,
9348 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9349 enum rtx_code rc = GET_CODE (operands[3]);
9351 rc = reverse_condition (rc);
9352 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9357 gen_rtx_SET (operands[0], const0_rtx)));
9358 rc = GET_CODE (operands[3]);
9359 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9364 gen_rtx_SET (operands[0],
9370 [(set_attr "conds" "clob")
9371 (set_attr "length" "12")
9372 (set_attr "type" "multiple")]
9375 (define_insn_and_split "movcond_addsi"
9376 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9378 (match_operator 5 "comparison_operator"
9379 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9380 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9382 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9383 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9384 (clobber (reg:CC CC_REGNUM))]
9387 "&& reload_completed"
9388 [(set (reg:CC_NOOV CC_REGNUM)
9390 (plus:SI (match_dup 3)
9393 (set (match_dup 0) (match_dup 1))
9394 (cond_exec (match_dup 6)
9395 (set (match_dup 0) (match_dup 2)))]
9398 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9399 operands[3], operands[4]);
9400 enum rtx_code rc = GET_CODE (operands[5]);
9401 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9402 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9403 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9404 rc = reverse_condition (rc);
9406 std::swap (operands[1], operands[2]);
9408 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9411 [(set_attr "conds" "clob")
9412 (set_attr "enabled_for_depr_it" "no,yes,yes")
9413 (set_attr "type" "multiple")]
9416 (define_insn "movcond"
9417 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9419 (match_operator 5 "arm_comparison_operator"
9420 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9421 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9422 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9423 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9424 (clobber (reg:CC CC_REGNUM))]
9427 if (GET_CODE (operands[5]) == LT
9428 && (operands[4] == const0_rtx))
9430 if (which_alternative != 1 && REG_P (operands[1]))
9432 if (operands[2] == const0_rtx)
9433 return \"and\\t%0, %1, %3, asr #31\";
9434 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9436 else if (which_alternative != 0 && REG_P (operands[2]))
9438 if (operands[1] == const0_rtx)
9439 return \"bic\\t%0, %2, %3, asr #31\";
9440 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9442 /* The only case that falls through to here is when both ops 1 & 2
9446 if (GET_CODE (operands[5]) == GE
9447 && (operands[4] == const0_rtx))
9449 if (which_alternative != 1 && REG_P (operands[1]))
9451 if (operands[2] == const0_rtx)
9452 return \"bic\\t%0, %1, %3, asr #31\";
9453 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9455 else if (which_alternative != 0 && REG_P (operands[2]))
9457 if (operands[1] == const0_rtx)
9458 return \"and\\t%0, %2, %3, asr #31\";
9459 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9461 /* The only case that falls through to here is when both ops 1 & 2
9464 if (CONST_INT_P (operands[4])
9465 && !const_ok_for_arm (INTVAL (operands[4])))
9466 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9468 output_asm_insn (\"cmp\\t%3, %4\", operands);
9469 if (which_alternative != 0)
9470 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9471 if (which_alternative != 1)
9472 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9475 [(set_attr "conds" "clob")
9476 (set_attr "length" "8,8,12")
9477 (set_attr "type" "multiple")]
9480 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9482 (define_insn "*ifcompare_plus_move"
9483 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9484 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9485 [(match_operand:SI 4 "s_register_operand" "r,r")
9486 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9488 (match_operand:SI 2 "s_register_operand" "r,r")
9489 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9490 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9491 (clobber (reg:CC CC_REGNUM))]
9494 [(set_attr "conds" "clob")
9495 (set_attr "length" "8,12")
9496 (set_attr "type" "multiple")]
9499 (define_insn "*if_plus_move"
9500 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9502 (match_operator 4 "arm_comparison_operator"
9503 [(match_operand 5 "cc_register" "") (const_int 0)])
9505 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9506 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9507 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9511 sub%d4\\t%0, %2, #%n3
9512 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9513 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9514 [(set_attr "conds" "use")
9515 (set_attr "length" "4,4,8,8")
9516 (set_attr_alternative "type"
9517 [(if_then_else (match_operand 3 "const_int_operand" "")
9518 (const_string "alu_imm" )
9519 (const_string "alu_sreg"))
9520 (const_string "alu_imm")
9521 (const_string "multiple")
9522 (const_string "multiple")])]
9525 (define_insn "*ifcompare_move_plus"
9526 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9527 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9528 [(match_operand:SI 4 "s_register_operand" "r,r")
9529 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9530 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9532 (match_operand:SI 2 "s_register_operand" "r,r")
9533 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9534 (clobber (reg:CC CC_REGNUM))]
9537 [(set_attr "conds" "clob")
9538 (set_attr "length" "8,12")
9539 (set_attr "type" "multiple")]
9542 (define_insn "*if_move_plus"
9543 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9545 (match_operator 4 "arm_comparison_operator"
9546 [(match_operand 5 "cc_register" "") (const_int 0)])
9547 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9549 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9550 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9554 sub%D4\\t%0, %2, #%n3
9555 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9556 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9557 [(set_attr "conds" "use")
9558 (set_attr "length" "4,4,8,8")
9559 (set_attr_alternative "type"
9560 [(if_then_else (match_operand 3 "const_int_operand" "")
9561 (const_string "alu_imm" )
9562 (const_string "alu_sreg"))
9563 (const_string "alu_imm")
9564 (const_string "multiple")
9565 (const_string "multiple")])]
9568 (define_insn "*ifcompare_arith_arith"
9569 [(set (match_operand:SI 0 "s_register_operand" "=r")
9570 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9571 [(match_operand:SI 5 "s_register_operand" "r")
9572 (match_operand:SI 6 "arm_add_operand" "rIL")])
9573 (match_operator:SI 8 "shiftable_operator"
9574 [(match_operand:SI 1 "s_register_operand" "r")
9575 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9576 (match_operator:SI 7 "shiftable_operator"
9577 [(match_operand:SI 3 "s_register_operand" "r")
9578 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9579 (clobber (reg:CC CC_REGNUM))]
9582 [(set_attr "conds" "clob")
9583 (set_attr "length" "12")
9584 (set_attr "type" "multiple")]
9587 (define_insn "*if_arith_arith"
9588 [(set (match_operand:SI 0 "s_register_operand" "=r")
9589 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9590 [(match_operand 8 "cc_register" "") (const_int 0)])
9591 (match_operator:SI 6 "shiftable_operator"
9592 [(match_operand:SI 1 "s_register_operand" "r")
9593 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9594 (match_operator:SI 7 "shiftable_operator"
9595 [(match_operand:SI 3 "s_register_operand" "r")
9596 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9598 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9599 [(set_attr "conds" "use")
9600 (set_attr "length" "8")
9601 (set_attr "type" "multiple")]
9604 (define_insn "*ifcompare_arith_move"
9605 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9606 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9607 [(match_operand:SI 2 "s_register_operand" "r,r")
9608 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9609 (match_operator:SI 7 "shiftable_operator"
9610 [(match_operand:SI 4 "s_register_operand" "r,r")
9611 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9612 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9613 (clobber (reg:CC CC_REGNUM))]
9616 /* If we have an operation where (op x 0) is the identity operation and
9617 the conditional operator is LT or GE and we are comparing against zero and
9618 everything is in registers then we can do this in two instructions. */
9619 if (operands[3] == const0_rtx
9620 && GET_CODE (operands[7]) != AND
9621 && REG_P (operands[5])
9622 && REG_P (operands[1])
9623 && REGNO (operands[1]) == REGNO (operands[4])
9624 && REGNO (operands[4]) != REGNO (operands[0]))
9626 if (GET_CODE (operands[6]) == LT)
9627 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9628 else if (GET_CODE (operands[6]) == GE)
9629 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9631 if (CONST_INT_P (operands[3])
9632 && !const_ok_for_arm (INTVAL (operands[3])))
9633 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9635 output_asm_insn (\"cmp\\t%2, %3\", operands);
9636 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9637 if (which_alternative != 0)
9638 return \"mov%D6\\t%0, %1\";
9641 [(set_attr "conds" "clob")
9642 (set_attr "length" "8,12")
9643 (set_attr "type" "multiple")]
9646 (define_insn "*if_arith_move"
9647 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9648 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9649 [(match_operand 6 "cc_register" "") (const_int 0)])
9650 (match_operator:SI 5 "shiftable_operator"
9651 [(match_operand:SI 2 "s_register_operand" "r,r")
9652 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9653 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9657 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9658 [(set_attr "conds" "use")
9659 (set_attr "length" "4,8")
9660 (set_attr_alternative "type"
9661 [(if_then_else (match_operand 3 "const_int_operand" "")
9662 (const_string "alu_shift_imm" )
9663 (const_string "alu_shift_reg"))
9664 (const_string "multiple")])]
9667 (define_insn "*ifcompare_move_arith"
9668 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9669 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9670 [(match_operand:SI 4 "s_register_operand" "r,r")
9671 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9672 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9673 (match_operator:SI 7 "shiftable_operator"
9674 [(match_operand:SI 2 "s_register_operand" "r,r")
9675 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9676 (clobber (reg:CC CC_REGNUM))]
9679 /* If we have an operation where (op x 0) is the identity operation and
9680 the conditional operator is LT or GE and we are comparing against zero and
9681 everything is in registers then we can do this in two instructions */
9682 if (operands[5] == const0_rtx
9683 && GET_CODE (operands[7]) != AND
9684 && REG_P (operands[3])
9685 && REG_P (operands[1])
9686 && REGNO (operands[1]) == REGNO (operands[2])
9687 && REGNO (operands[2]) != REGNO (operands[0]))
9689 if (GET_CODE (operands[6]) == GE)
9690 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9691 else if (GET_CODE (operands[6]) == LT)
9692 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9695 if (CONST_INT_P (operands[5])
9696 && !const_ok_for_arm (INTVAL (operands[5])))
9697 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9699 output_asm_insn (\"cmp\\t%4, %5\", operands);
9701 if (which_alternative != 0)
9702 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9703 return \"%I7%D6\\t%0, %2, %3\";
9705 [(set_attr "conds" "clob")
9706 (set_attr "length" "8,12")
9707 (set_attr "type" "multiple")]
9710 (define_insn "*if_move_arith"
9711 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9713 (match_operator 4 "arm_comparison_operator"
9714 [(match_operand 6 "cc_register" "") (const_int 0)])
9715 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9716 (match_operator:SI 5 "shiftable_operator"
9717 [(match_operand:SI 2 "s_register_operand" "r,r")
9718 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9722 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9723 [(set_attr "conds" "use")
9724 (set_attr "length" "4,8")
9725 (set_attr_alternative "type"
9726 [(if_then_else (match_operand 3 "const_int_operand" "")
9727 (const_string "alu_shift_imm" )
9728 (const_string "alu_shift_reg"))
9729 (const_string "multiple")])]
9732 (define_insn "*ifcompare_move_not"
9733 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9735 (match_operator 5 "arm_comparison_operator"
9736 [(match_operand:SI 3 "s_register_operand" "r,r")
9737 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9738 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9740 (match_operand:SI 2 "s_register_operand" "r,r"))))
9741 (clobber (reg:CC CC_REGNUM))]
9744 [(set_attr "conds" "clob")
9745 (set_attr "length" "8,12")
9746 (set_attr "type" "multiple")]
9749 (define_insn "*if_move_not"
9750 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9752 (match_operator 4 "arm_comparison_operator"
9753 [(match_operand 3 "cc_register" "") (const_int 0)])
9754 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9755 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9759 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9760 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9761 [(set_attr "conds" "use")
9762 (set_attr "type" "mvn_reg")
9763 (set_attr "length" "4,8,8")
9764 (set_attr "type" "mvn_reg,multiple,multiple")]
9767 (define_insn "*ifcompare_not_move"
9768 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9770 (match_operator 5 "arm_comparison_operator"
9771 [(match_operand:SI 3 "s_register_operand" "r,r")
9772 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9774 (match_operand:SI 2 "s_register_operand" "r,r"))
9775 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9776 (clobber (reg:CC CC_REGNUM))]
9779 [(set_attr "conds" "clob")
9780 (set_attr "length" "8,12")
9781 (set_attr "type" "multiple")]
9784 (define_insn "*if_not_move"
9785 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9787 (match_operator 4 "arm_comparison_operator"
9788 [(match_operand 3 "cc_register" "") (const_int 0)])
9789 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9790 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9794 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9795 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9796 [(set_attr "conds" "use")
9797 (set_attr "type" "mvn_reg,multiple,multiple")
9798 (set_attr "length" "4,8,8")]
9801 (define_insn "*ifcompare_shift_move"
9802 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9804 (match_operator 6 "arm_comparison_operator"
9805 [(match_operand:SI 4 "s_register_operand" "r,r")
9806 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9807 (match_operator:SI 7 "shift_operator"
9808 [(match_operand:SI 2 "s_register_operand" "r,r")
9809 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9810 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9811 (clobber (reg:CC CC_REGNUM))]
9814 [(set_attr "conds" "clob")
9815 (set_attr "length" "8,12")
9816 (set_attr "type" "multiple")]
9819 (define_insn "*if_shift_move"
9820 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9822 (match_operator 5 "arm_comparison_operator"
9823 [(match_operand 6 "cc_register" "") (const_int 0)])
9824 (match_operator:SI 4 "shift_operator"
9825 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9826 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9827 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9831 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9832 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9833 [(set_attr "conds" "use")
9834 (set_attr "shift" "2")
9835 (set_attr "length" "4,8,8")
9836 (set_attr_alternative "type"
9837 [(if_then_else (match_operand 3 "const_int_operand" "")
9838 (const_string "mov_shift" )
9839 (const_string "mov_shift_reg"))
9840 (const_string "multiple")
9841 (const_string "multiple")])]
9844 (define_insn "*ifcompare_move_shift"
9845 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9847 (match_operator 6 "arm_comparison_operator"
9848 [(match_operand:SI 4 "s_register_operand" "r,r")
9849 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9850 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9851 (match_operator:SI 7 "shift_operator"
9852 [(match_operand:SI 2 "s_register_operand" "r,r")
9853 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9854 (clobber (reg:CC CC_REGNUM))]
9857 [(set_attr "conds" "clob")
9858 (set_attr "length" "8,12")
9859 (set_attr "type" "multiple")]
9862 (define_insn "*if_move_shift"
9863 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9865 (match_operator 5 "arm_comparison_operator"
9866 [(match_operand 6 "cc_register" "") (const_int 0)])
9867 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9868 (match_operator:SI 4 "shift_operator"
9869 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9870 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9874 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9875 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9876 [(set_attr "conds" "use")
9877 (set_attr "shift" "2")
9878 (set_attr "length" "4,8,8")
9879 (set_attr_alternative "type"
9880 [(if_then_else (match_operand 3 "const_int_operand" "")
9881 (const_string "mov_shift" )
9882 (const_string "mov_shift_reg"))
9883 (const_string "multiple")
9884 (const_string "multiple")])]
9887 (define_insn "*ifcompare_shift_shift"
9888 [(set (match_operand:SI 0 "s_register_operand" "=r")
9890 (match_operator 7 "arm_comparison_operator"
9891 [(match_operand:SI 5 "s_register_operand" "r")
9892 (match_operand:SI 6 "arm_add_operand" "rIL")])
9893 (match_operator:SI 8 "shift_operator"
9894 [(match_operand:SI 1 "s_register_operand" "r")
9895 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9896 (match_operator:SI 9 "shift_operator"
9897 [(match_operand:SI 3 "s_register_operand" "r")
9898 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9899 (clobber (reg:CC CC_REGNUM))]
9902 [(set_attr "conds" "clob")
9903 (set_attr "length" "12")
9904 (set_attr "type" "multiple")]
9907 (define_insn "*if_shift_shift"
9908 [(set (match_operand:SI 0 "s_register_operand" "=r")
9910 (match_operator 5 "arm_comparison_operator"
9911 [(match_operand 8 "cc_register" "") (const_int 0)])
9912 (match_operator:SI 6 "shift_operator"
9913 [(match_operand:SI 1 "s_register_operand" "r")
9914 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9915 (match_operator:SI 7 "shift_operator"
9916 [(match_operand:SI 3 "s_register_operand" "r")
9917 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9919 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9920 [(set_attr "conds" "use")
9921 (set_attr "shift" "1")
9922 (set_attr "length" "8")
9923 (set (attr "type") (if_then_else
9924 (and (match_operand 2 "const_int_operand" "")
9925 (match_operand 4 "const_int_operand" ""))
9926 (const_string "mov_shift")
9927 (const_string "mov_shift_reg")))]
9930 (define_insn "*ifcompare_not_arith"
9931 [(set (match_operand:SI 0 "s_register_operand" "=r")
9933 (match_operator 6 "arm_comparison_operator"
9934 [(match_operand:SI 4 "s_register_operand" "r")
9935 (match_operand:SI 5 "arm_add_operand" "rIL")])
9936 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9937 (match_operator:SI 7 "shiftable_operator"
9938 [(match_operand:SI 2 "s_register_operand" "r")
9939 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9940 (clobber (reg:CC CC_REGNUM))]
9943 [(set_attr "conds" "clob")
9944 (set_attr "length" "12")
9945 (set_attr "type" "multiple")]
9948 (define_insn "*if_not_arith"
9949 [(set (match_operand:SI 0 "s_register_operand" "=r")
9951 (match_operator 5 "arm_comparison_operator"
9952 [(match_operand 4 "cc_register" "") (const_int 0)])
9953 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9954 (match_operator:SI 6 "shiftable_operator"
9955 [(match_operand:SI 2 "s_register_operand" "r")
9956 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9958 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9959 [(set_attr "conds" "use")
9960 (set_attr "type" "mvn_reg")
9961 (set_attr "length" "8")]
9964 (define_insn "*ifcompare_arith_not"
9965 [(set (match_operand:SI 0 "s_register_operand" "=r")
9967 (match_operator 6 "arm_comparison_operator"
9968 [(match_operand:SI 4 "s_register_operand" "r")
9969 (match_operand:SI 5 "arm_add_operand" "rIL")])
9970 (match_operator:SI 7 "shiftable_operator"
9971 [(match_operand:SI 2 "s_register_operand" "r")
9972 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9973 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9974 (clobber (reg:CC CC_REGNUM))]
9977 [(set_attr "conds" "clob")
9978 (set_attr "length" "12")
9979 (set_attr "type" "multiple")]
9982 (define_insn "*if_arith_not"
9983 [(set (match_operand:SI 0 "s_register_operand" "=r")
9985 (match_operator 5 "arm_comparison_operator"
9986 [(match_operand 4 "cc_register" "") (const_int 0)])
9987 (match_operator:SI 6 "shiftable_operator"
9988 [(match_operand:SI 2 "s_register_operand" "r")
9989 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9990 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9992 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9993 [(set_attr "conds" "use")
9994 (set_attr "type" "multiple")
9995 (set_attr "length" "8")]
9998 (define_insn "*ifcompare_neg_move"
9999 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10001 (match_operator 5 "arm_comparison_operator"
10002 [(match_operand:SI 3 "s_register_operand" "r,r")
10003 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10004 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10005 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10006 (clobber (reg:CC CC_REGNUM))]
10009 [(set_attr "conds" "clob")
10010 (set_attr "length" "8,12")
10011 (set_attr "type" "multiple")]
10014 (define_insn_and_split "*if_neg_move"
10015 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10017 (match_operator 4 "arm_comparison_operator"
10018 [(match_operand 3 "cc_register" "") (const_int 0)])
10019 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10020 (match_operand:SI 1 "s_register_operand" "0,0")))]
10023 "&& reload_completed"
10024 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10025 (set (match_dup 0) (neg:SI (match_dup 2))))]
10027 [(set_attr "conds" "use")
10028 (set_attr "length" "4")
10029 (set_attr "arch" "t2,32")
10030 (set_attr "enabled_for_depr_it" "yes,no")
10031 (set_attr "type" "logic_shift_imm")]
10034 (define_insn "*ifcompare_move_neg"
10035 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10037 (match_operator 5 "arm_comparison_operator"
10038 [(match_operand:SI 3 "s_register_operand" "r,r")
10039 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10040 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10041 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10042 (clobber (reg:CC CC_REGNUM))]
10045 [(set_attr "conds" "clob")
10046 (set_attr "length" "8,12")
10047 (set_attr "type" "multiple")]
10050 (define_insn_and_split "*if_move_neg"
10051 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10053 (match_operator 4 "arm_comparison_operator"
10054 [(match_operand 3 "cc_register" "") (const_int 0)])
10055 (match_operand:SI 1 "s_register_operand" "0,0")
10056 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10059 "&& reload_completed"
10060 [(cond_exec (match_dup 5)
10061 (set (match_dup 0) (neg:SI (match_dup 2))))]
10063 machine_mode mode = GET_MODE (operands[3]);
10064 rtx_code rc = GET_CODE (operands[4]);
10066 if (mode == CCFPmode || mode == CCFPEmode)
10067 rc = reverse_condition_maybe_unordered (rc);
10069 rc = reverse_condition (rc);
10071 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10073 [(set_attr "conds" "use")
10074 (set_attr "length" "4")
10075 (set_attr "arch" "t2,32")
10076 (set_attr "enabled_for_depr_it" "yes,no")
10077 (set_attr "type" "logic_shift_imm")]
10080 (define_insn "*arith_adjacentmem"
10081 [(set (match_operand:SI 0 "s_register_operand" "=r")
10082 (match_operator:SI 1 "shiftable_operator"
10083 [(match_operand:SI 2 "memory_operand" "m")
10084 (match_operand:SI 3 "memory_operand" "m")]))
10085 (clobber (match_scratch:SI 4 "=r"))]
10086 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10092 HOST_WIDE_INT val1 = 0, val2 = 0;
10094 if (REGNO (operands[0]) > REGNO (operands[4]))
10096 ldm[1] = operands[4];
10097 ldm[2] = operands[0];
10101 ldm[1] = operands[0];
10102 ldm[2] = operands[4];
10105 base_reg = XEXP (operands[2], 0);
10107 if (!REG_P (base_reg))
10109 val1 = INTVAL (XEXP (base_reg, 1));
10110 base_reg = XEXP (base_reg, 0);
10113 if (!REG_P (XEXP (operands[3], 0)))
10114 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10116 arith[0] = operands[0];
10117 arith[3] = operands[1];
10131 if (val1 !=0 && val2 != 0)
10135 if (val1 == 4 || val2 == 4)
10136 /* Other val must be 8, since we know they are adjacent and neither
10138 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10139 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10141 ldm[0] = ops[0] = operands[4];
10143 ops[2] = GEN_INT (val1);
10144 output_add_immediate (ops);
10146 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10148 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10152 /* Offset is out of range for a single add, so use two ldr. */
10155 ops[2] = GEN_INT (val1);
10156 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10158 ops[2] = GEN_INT (val2);
10159 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10162 else if (val1 != 0)
10165 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10167 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10172 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10174 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10176 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10179 [(set_attr "length" "12")
10180 (set_attr "predicable" "yes")
10181 (set_attr "type" "load1")]
10184 ; This pattern is never tried by combine, so do it as a peephole
10187 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10188 (match_operand:SI 1 "arm_general_register_operand" ""))
10189 (set (reg:CC CC_REGNUM)
10190 (compare:CC (match_dup 1) (const_int 0)))]
10192 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10193 (set (match_dup 0) (match_dup 1))])]
10198 [(set (match_operand:SI 0 "s_register_operand" "")
10199 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10201 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10202 [(match_operand:SI 3 "s_register_operand" "")
10203 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10204 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10206 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10207 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10212 ;; This split can be used because CC_Z mode implies that the following
10213 ;; branch will be an equality, or an unsigned inequality, so the sign
10214 ;; extension is not needed.
10217 [(set (reg:CC_Z CC_REGNUM)
10219 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10221 (match_operand 1 "const_int_operand" "")))
10222 (clobber (match_scratch:SI 2 ""))]
10224 && ((UINTVAL (operands[1]))
10225 == ((UINTVAL (operands[1])) >> 24) << 24)"
10226 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10227 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10229 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10232 ;; ??? Check the patterns above for Thumb-2 usefulness
10234 (define_expand "prologue"
10235 [(clobber (const_int 0))]
10238 arm_expand_prologue ();
10240 thumb1_expand_prologue ();
10245 (define_expand "epilogue"
10246 [(clobber (const_int 0))]
10249 if (crtl->calls_eh_return)
10250 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10253 thumb1_expand_epilogue ();
10254 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10255 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10257 else if (HAVE_return)
10259 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10260 no need for explicit testing again. */
10261 emit_jump_insn (gen_return ());
10263 else if (TARGET_32BIT)
10265 arm_expand_epilogue (true);
10271 ;; Note - although unspec_volatile's USE all hard registers,
10272 ;; USEs are ignored after relaod has completed. Thus we need
10273 ;; to add an unspec of the link register to ensure that flow
10274 ;; does not think that it is unused by the sibcall branch that
10275 ;; will replace the standard function epilogue.
10276 (define_expand "sibcall_epilogue"
10277 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10278 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10281 arm_expand_epilogue (false);
10286 (define_expand "eh_epilogue"
10287 [(use (match_operand:SI 0 "register_operand" ""))
10288 (use (match_operand:SI 1 "register_operand" ""))
10289 (use (match_operand:SI 2 "register_operand" ""))]
10293 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10294 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10296 rtx ra = gen_rtx_REG (Pmode, 2);
10298 emit_move_insn (ra, operands[2]);
10301 /* This is a hack -- we may have crystalized the function type too
10303 cfun->machine->func_type = 0;
10307 ;; This split is only used during output to reduce the number of patterns
10308 ;; that need assembler instructions adding to them. We allowed the setting
10309 ;; of the conditions to be implicit during rtl generation so that
10310 ;; the conditional compare patterns would work. However this conflicts to
10311 ;; some extent with the conditional data operations, so we have to split them
10314 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10315 ;; conditional execution sufficient?
10318 [(set (match_operand:SI 0 "s_register_operand" "")
10319 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10320 [(match_operand 2 "" "") (match_operand 3 "" "")])
10322 (match_operand 4 "" "")))
10323 (clobber (reg:CC CC_REGNUM))]
10324 "TARGET_ARM && reload_completed"
10325 [(set (match_dup 5) (match_dup 6))
10326 (cond_exec (match_dup 7)
10327 (set (match_dup 0) (match_dup 4)))]
10330 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10331 operands[2], operands[3]);
10332 enum rtx_code rc = GET_CODE (operands[1]);
10334 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10335 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10336 if (mode == CCFPmode || mode == CCFPEmode)
10337 rc = reverse_condition_maybe_unordered (rc);
10339 rc = reverse_condition (rc);
10341 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10346 [(set (match_operand:SI 0 "s_register_operand" "")
10347 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10348 [(match_operand 2 "" "") (match_operand 3 "" "")])
10349 (match_operand 4 "" "")
10351 (clobber (reg:CC CC_REGNUM))]
10352 "TARGET_ARM && reload_completed"
10353 [(set (match_dup 5) (match_dup 6))
10354 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10355 (set (match_dup 0) (match_dup 4)))]
10358 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10359 operands[2], operands[3]);
10361 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10362 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10367 [(set (match_operand:SI 0 "s_register_operand" "")
10368 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10369 [(match_operand 2 "" "") (match_operand 3 "" "")])
10370 (match_operand 4 "" "")
10371 (match_operand 5 "" "")))
10372 (clobber (reg:CC CC_REGNUM))]
10373 "TARGET_ARM && reload_completed"
10374 [(set (match_dup 6) (match_dup 7))
10375 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10376 (set (match_dup 0) (match_dup 4)))
10377 (cond_exec (match_dup 8)
10378 (set (match_dup 0) (match_dup 5)))]
10381 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10382 operands[2], operands[3]);
10383 enum rtx_code rc = GET_CODE (operands[1]);
10385 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10386 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10387 if (mode == CCFPmode || mode == CCFPEmode)
10388 rc = reverse_condition_maybe_unordered (rc);
10390 rc = reverse_condition (rc);
10392 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10397 [(set (match_operand:SI 0 "s_register_operand" "")
10398 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10399 [(match_operand:SI 2 "s_register_operand" "")
10400 (match_operand:SI 3 "arm_add_operand" "")])
10401 (match_operand:SI 4 "arm_rhs_operand" "")
10403 (match_operand:SI 5 "s_register_operand" ""))))
10404 (clobber (reg:CC CC_REGNUM))]
10405 "TARGET_ARM && reload_completed"
10406 [(set (match_dup 6) (match_dup 7))
10407 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10408 (set (match_dup 0) (match_dup 4)))
10409 (cond_exec (match_dup 8)
10410 (set (match_dup 0) (not:SI (match_dup 5))))]
10413 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10414 operands[2], operands[3]);
10415 enum rtx_code rc = GET_CODE (operands[1]);
10417 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10418 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10419 if (mode == CCFPmode || mode == CCFPEmode)
10420 rc = reverse_condition_maybe_unordered (rc);
10422 rc = reverse_condition (rc);
10424 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10428 (define_insn "*cond_move_not"
10429 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10430 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10431 [(match_operand 3 "cc_register" "") (const_int 0)])
10432 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10434 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10438 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10439 [(set_attr "conds" "use")
10440 (set_attr "type" "mvn_reg,multiple")
10441 (set_attr "length" "4,8")]
10444 ;; The next two patterns occur when an AND operation is followed by a
10445 ;; scc insn sequence
10447 (define_insn "*sign_extract_onebit"
10448 [(set (match_operand:SI 0 "s_register_operand" "=r")
10449 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10451 (match_operand:SI 2 "const_int_operand" "n")))
10452 (clobber (reg:CC CC_REGNUM))]
10455 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10456 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10457 return \"mvnne\\t%0, #0\";
10459 [(set_attr "conds" "clob")
10460 (set_attr "length" "8")
10461 (set_attr "type" "multiple")]
10464 (define_insn "*not_signextract_onebit"
10465 [(set (match_operand:SI 0 "s_register_operand" "=r")
10467 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10469 (match_operand:SI 2 "const_int_operand" "n"))))
10470 (clobber (reg:CC CC_REGNUM))]
10473 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10474 output_asm_insn (\"tst\\t%1, %2\", operands);
10475 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10476 return \"movne\\t%0, #0\";
10478 [(set_attr "conds" "clob")
10479 (set_attr "length" "12")
10480 (set_attr "type" "multiple")]
10482 ;; ??? The above patterns need auditing for Thumb-2
10484 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10485 ;; expressions. For simplicity, the first register is also in the unspec
10487 ;; To avoid the usage of GNU extension, the length attribute is computed
10488 ;; in a C function arm_attr_length_push_multi.
10489 (define_insn "*push_multi"
10490 [(match_parallel 2 "multi_register_push"
10491 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10492 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10493 UNSPEC_PUSH_MULT))])]
10497 int num_saves = XVECLEN (operands[2], 0);
10499 /* For the StrongARM at least it is faster to
10500 use STR to store only a single register.
10501 In Thumb mode always use push, and the assembler will pick
10502 something appropriate. */
10503 if (num_saves == 1 && TARGET_ARM)
10504 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10511 strcpy (pattern, \"push%?\\t{%1\");
10513 strcpy (pattern, \"push\\t{%1\");
10515 for (i = 1; i < num_saves; i++)
10517 strcat (pattern, \", %|\");
10519 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10522 strcat (pattern, \"}\");
10523 output_asm_insn (pattern, operands);
10528 [(set_attr "type" "store4")
10529 (set (attr "length")
10530 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10533 (define_insn "stack_tie"
10534 [(set (mem:BLK (scratch))
10535 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10536 (match_operand:SI 1 "s_register_operand" "rk")]
10540 [(set_attr "length" "0")
10541 (set_attr "type" "block")]
10544 ;; Pop (as used in epilogue RTL)
10546 (define_insn "*load_multiple_with_writeback"
10547 [(match_parallel 0 "load_multiple_operation"
10548 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10549 (plus:SI (match_dup 1)
10550 (match_operand:SI 2 "const_int_I_operand" "I")))
10551 (set (match_operand:SI 3 "s_register_operand" "=rk")
10552 (mem:SI (match_dup 1)))
10554 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10557 arm_output_multireg_pop (operands, /*return_pc=*/false,
10558 /*cond=*/const_true_rtx,
10564 [(set_attr "type" "load4")
10565 (set_attr "predicable" "yes")
10566 (set (attr "length")
10567 (symbol_ref "arm_attr_length_pop_multi (operands,
10568 /*return_pc=*/false,
10569 /*write_back_p=*/true)"))]
10572 ;; Pop with return (as used in epilogue RTL)
10574 ;; This instruction is generated when the registers are popped at the end of
10575 ;; epilogue. Here, instead of popping the value into LR and then generating
10576 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10578 (define_insn "*pop_multiple_with_writeback_and_return"
10579 [(match_parallel 0 "pop_multiple_return"
10581 (set (match_operand:SI 1 "s_register_operand" "+rk")
10582 (plus:SI (match_dup 1)
10583 (match_operand:SI 2 "const_int_I_operand" "I")))
10584 (set (match_operand:SI 3 "s_register_operand" "=rk")
10585 (mem:SI (match_dup 1)))
10587 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10590 arm_output_multireg_pop (operands, /*return_pc=*/true,
10591 /*cond=*/const_true_rtx,
10597 [(set_attr "type" "load4")
10598 (set_attr "predicable" "yes")
10599 (set (attr "length")
10600 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10601 /*write_back_p=*/true)"))]
10604 (define_insn "*pop_multiple_with_return"
10605 [(match_parallel 0 "pop_multiple_return"
10607 (set (match_operand:SI 2 "s_register_operand" "=rk")
10608 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10610 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10613 arm_output_multireg_pop (operands, /*return_pc=*/true,
10614 /*cond=*/const_true_rtx,
10620 [(set_attr "type" "load4")
10621 (set_attr "predicable" "yes")
10622 (set (attr "length")
10623 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10624 /*write_back_p=*/false)"))]
10627 ;; Load into PC and return
10628 (define_insn "*ldr_with_return"
10630 (set (reg:SI PC_REGNUM)
10631 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10632 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10633 "ldr%?\t%|pc, [%0], #4"
10634 [(set_attr "type" "load1")
10635 (set_attr "predicable" "yes")]
10637 ;; Pop for floating point registers (as used in epilogue RTL)
10638 (define_insn "*vfp_pop_multiple_with_writeback"
10639 [(match_parallel 0 "pop_multiple_fp"
10640 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10641 (plus:SI (match_dup 1)
10642 (match_operand:SI 2 "const_int_I_operand" "I")))
10643 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10644 (mem:DF (match_dup 1)))])]
10645 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10648 int num_regs = XVECLEN (operands[0], 0);
10651 strcpy (pattern, \"vldm\\t\");
10652 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10653 strcat (pattern, \"!, {\");
10654 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10655 strcat (pattern, \"%P0\");
10656 if ((num_regs - 1) > 1)
10658 strcat (pattern, \"-%P1\");
10659 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10662 strcat (pattern, \"}\");
10663 output_asm_insn (pattern, op_list);
10667 [(set_attr "type" "load4")
10668 (set_attr "conds" "unconditional")
10669 (set_attr "predicable" "no")]
10672 ;; Special patterns for dealing with the constant pool
10674 (define_insn "align_4"
10675 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10678 assemble_align (32);
10681 [(set_attr "type" "no_insn")]
10684 (define_insn "align_8"
10685 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10688 assemble_align (64);
10691 [(set_attr "type" "no_insn")]
10694 (define_insn "consttable_end"
10695 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10698 making_const_table = FALSE;
10701 [(set_attr "type" "no_insn")]
10704 (define_insn "consttable_1"
10705 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10708 making_const_table = TRUE;
10709 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10710 assemble_zeros (3);
10713 [(set_attr "length" "4")
10714 (set_attr "type" "no_insn")]
10717 (define_insn "consttable_2"
10718 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10722 rtx x = operands[0];
10723 making_const_table = TRUE;
10724 switch (GET_MODE_CLASS (GET_MODE (x)))
10727 arm_emit_fp16_const (x);
10730 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10731 assemble_zeros (2);
10736 [(set_attr "length" "4")
10737 (set_attr "type" "no_insn")]
10740 (define_insn "consttable_4"
10741 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10745 rtx x = operands[0];
10746 making_const_table = TRUE;
10747 switch (GET_MODE_CLASS (GET_MODE (x)))
10750 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
10754 /* XXX: Sometimes gcc does something really dumb and ends up with
10755 a HIGH in a constant pool entry, usually because it's trying to
10756 load into a VFP register. We know this will always be used in
10757 combination with a LO_SUM which ignores the high bits, so just
10758 strip off the HIGH. */
10759 if (GET_CODE (x) == HIGH)
10761 assemble_integer (x, 4, BITS_PER_WORD, 1);
10762 mark_symbol_refs_as_used (x);
10767 [(set_attr "length" "4")
10768 (set_attr "type" "no_insn")]
10771 (define_insn "consttable_8"
10772 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10776 making_const_table = TRUE;
10777 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10780 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10781 GET_MODE (operands[0]), BITS_PER_WORD);
10784 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10789 [(set_attr "length" "8")
10790 (set_attr "type" "no_insn")]
10793 (define_insn "consttable_16"
10794 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10798 making_const_table = TRUE;
10799 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10802 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10803 GET_MODE (operands[0]), BITS_PER_WORD);
10806 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10811 [(set_attr "length" "16")
10812 (set_attr "type" "no_insn")]
10815 ;; V5 Instructions,
10817 (define_insn "clzsi2"
10818 [(set (match_operand:SI 0 "s_register_operand" "=r")
10819 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10820 "TARGET_32BIT && arm_arch5"
10822 [(set_attr "predicable" "yes")
10823 (set_attr "predicable_short_it" "no")
10824 (set_attr "type" "clz")])
10826 (define_insn "rbitsi2"
10827 [(set (match_operand:SI 0 "s_register_operand" "=r")
10828 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10829 "TARGET_32BIT && arm_arch_thumb2"
10831 [(set_attr "predicable" "yes")
10832 (set_attr "predicable_short_it" "no")
10833 (set_attr "type" "clz")])
10835 ;; Keep this as a CTZ expression until after reload and then split
10836 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
10837 ;; to fold with any other expression.
10839 (define_insn_and_split "ctzsi2"
10840 [(set (match_operand:SI 0 "s_register_operand" "=r")
10841 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10842 "TARGET_32BIT && arm_arch_thumb2"
10844 "&& reload_completed"
10847 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
10848 emit_insn (gen_clzsi2 (operands[0], operands[0]));
10852 ;; V5E instructions.
10854 (define_insn "prefetch"
10855 [(prefetch (match_operand:SI 0 "address_operand" "p")
10856 (match_operand:SI 1 "" "")
10857 (match_operand:SI 2 "" ""))]
10858 "TARGET_32BIT && arm_arch5e"
10860 [(set_attr "type" "load1")]
10863 ;; General predication pattern
10866 [(match_operator 0 "arm_comparison_operator"
10867 [(match_operand 1 "cc_register" "")
10870 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
10872 [(set_attr "predicated" "yes")]
10875 (define_insn "force_register_use"
10876 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10879 [(set_attr "length" "0")
10880 (set_attr "type" "no_insn")]
10884 ;; Patterns for exception handling
10886 (define_expand "eh_return"
10887 [(use (match_operand 0 "general_operand" ""))]
10892 emit_insn (gen_arm_eh_return (operands[0]));
10894 emit_insn (gen_thumb_eh_return (operands[0]));
10899 ;; We can't expand this before we know where the link register is stored.
10900 (define_insn_and_split "arm_eh_return"
10901 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10903 (clobber (match_scratch:SI 1 "=&r"))]
10906 "&& reload_completed"
10910 arm_set_return_address (operands[0], operands[1]);
10918 (define_insn "load_tp_hard"
10919 [(set (match_operand:SI 0 "register_operand" "=r")
10920 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10922 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
10923 [(set_attr "predicable" "yes")
10924 (set_attr "type" "mrs")]
10927 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
10928 (define_insn "load_tp_soft"
10929 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10930 (clobber (reg:SI LR_REGNUM))
10931 (clobber (reg:SI IP_REGNUM))
10932 (clobber (reg:CC CC_REGNUM))]
10934 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
10935 [(set_attr "conds" "clob")
10936 (set_attr "type" "branch")]
10939 ;; tls descriptor call
10940 (define_insn "tlscall"
10941 [(set (reg:SI R0_REGNUM)
10942 (unspec:SI [(reg:SI R0_REGNUM)
10943 (match_operand:SI 0 "" "X")
10944 (match_operand 1 "" "")] UNSPEC_TLS))
10945 (clobber (reg:SI R1_REGNUM))
10946 (clobber (reg:SI LR_REGNUM))
10947 (clobber (reg:SI CC_REGNUM))]
10950 targetm.asm_out.internal_label (asm_out_file, "LPIC",
10951 INTVAL (operands[1]));
10952 return "bl\\t%c0(tlscall)";
10954 [(set_attr "conds" "clob")
10955 (set_attr "length" "4")
10956 (set_attr "type" "branch")]
10959 ;; For thread pointer builtin
10960 (define_expand "get_thread_pointersi"
10961 [(match_operand:SI 0 "s_register_operand" "=r")]
10965 arm_load_tp (operands[0]);
10971 ;; We only care about the lower 16 bits of the constant
10972 ;; being inserted into the upper 16 bits of the register.
10973 (define_insn "*arm_movtas_ze"
10974 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10977 (match_operand:SI 1 "const_int_operand" ""))]
10980 [(set_attr "predicable" "yes")
10981 (set_attr "predicable_short_it" "no")
10982 (set_attr "length" "4")
10983 (set_attr "type" "alu_sreg")]
10986 (define_insn "*arm_rev"
10987 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10988 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10994 [(set_attr "arch" "t1,t2,32")
10995 (set_attr "length" "2,2,4")
10996 (set_attr "predicable" "no,yes,yes")
10997 (set_attr "predicable_short_it" "no")
10998 (set_attr "type" "rev")]
11001 (define_expand "arm_legacy_rev"
11002 [(set (match_operand:SI 2 "s_register_operand" "")
11003 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11007 (lshiftrt:SI (match_dup 2)
11009 (set (match_operand:SI 3 "s_register_operand" "")
11010 (rotatert:SI (match_dup 1)
11013 (and:SI (match_dup 2)
11014 (const_int -65281)))
11015 (set (match_operand:SI 0 "s_register_operand" "")
11016 (xor:SI (match_dup 3)
11022 ;; Reuse temporaries to keep register pressure down.
11023 (define_expand "thumb_legacy_rev"
11024 [(set (match_operand:SI 2 "s_register_operand" "")
11025 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11027 (set (match_operand:SI 3 "s_register_operand" "")
11028 (lshiftrt:SI (match_dup 1)
11031 (ior:SI (match_dup 3)
11033 (set (match_operand:SI 4 "s_register_operand" "")
11035 (set (match_operand:SI 5 "s_register_operand" "")
11036 (rotatert:SI (match_dup 1)
11039 (ashift:SI (match_dup 5)
11042 (lshiftrt:SI (match_dup 5)
11045 (ior:SI (match_dup 5)
11048 (rotatert:SI (match_dup 5)
11050 (set (match_operand:SI 0 "s_register_operand" "")
11051 (ior:SI (match_dup 5)
11057 ;; ARM-specific expansion of signed mod by power of 2
11058 ;; using conditional negate.
11059 ;; For r0 % n where n is a power of 2 produce:
11061 ;; and r0, r0, #(n - 1)
11062 ;; and r1, r1, #(n - 1)
11063 ;; rsbpl r0, r1, #0
11065 (define_expand "modsi3"
11066 [(match_operand:SI 0 "register_operand" "")
11067 (match_operand:SI 1 "register_operand" "")
11068 (match_operand:SI 2 "const_int_operand" "")]
11071 HOST_WIDE_INT val = INTVAL (operands[2]);
11074 || exact_log2 (val) <= 0)
11077 rtx mask = GEN_INT (val - 1);
11079 /* In the special case of x0 % 2 we can do the even shorter:
11082 rsblt r0, r0, #0. */
11086 rtx cc_reg = arm_gen_compare_reg (LT,
11087 operands[1], const0_rtx, NULL_RTX);
11088 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11089 rtx masked = gen_reg_rtx (SImode);
11091 emit_insn (gen_andsi3 (masked, operands[1], mask));
11092 emit_move_insn (operands[0],
11093 gen_rtx_IF_THEN_ELSE (SImode, cond,
11094 gen_rtx_NEG (SImode,
11100 rtx neg_op = gen_reg_rtx (SImode);
11101 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11104 /* Extract the condition register and mode. */
11105 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11106 rtx cc_reg = SET_DEST (cmp);
11107 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11109 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11111 rtx masked_neg = gen_reg_rtx (SImode);
11112 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11114 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11115 during expand does not always work. Do an IF_THEN_ELSE instead. */
11116 emit_move_insn (operands[0],
11117 gen_rtx_IF_THEN_ELSE (SImode, cond,
11118 gen_rtx_NEG (SImode, masked_neg),
11126 (define_expand "bswapsi2"
11127 [(set (match_operand:SI 0 "s_register_operand" "=r")
11128 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11129 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11133 rtx op2 = gen_reg_rtx (SImode);
11134 rtx op3 = gen_reg_rtx (SImode);
11138 rtx op4 = gen_reg_rtx (SImode);
11139 rtx op5 = gen_reg_rtx (SImode);
11141 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11142 op2, op3, op4, op5));
11146 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11155 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11156 ;; and unsigned variants, respectively. For rev16, expose
11157 ;; byte-swapping in the lower 16 bits only.
11158 (define_insn "*arm_revsh"
11159 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11160 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11166 [(set_attr "arch" "t1,t2,32")
11167 (set_attr "length" "2,2,4")
11168 (set_attr "type" "rev")]
11171 (define_insn "*arm_rev16"
11172 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11173 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11179 [(set_attr "arch" "t1,t2,32")
11180 (set_attr "length" "2,2,4")
11181 (set_attr "type" "rev")]
11184 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11185 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11186 ;; each valid permutation.
11188 (define_insn "arm_rev16si2"
11189 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11190 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11192 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11193 (and:SI (lshiftrt:SI (match_dup 1)
11195 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11197 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11198 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11200 [(set_attr "arch" "t1,t2,32")
11201 (set_attr "length" "2,2,4")
11202 (set_attr "type" "rev")]
11205 (define_insn "arm_rev16si2_alt"
11206 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11207 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11209 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11210 (and:SI (ashift:SI (match_dup 1)
11212 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11214 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11215 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11217 [(set_attr "arch" "t1,t2,32")
11218 (set_attr "length" "2,2,4")
11219 (set_attr "type" "rev")]
11222 (define_expand "bswaphi2"
11223 [(set (match_operand:HI 0 "s_register_operand" "=r")
11224 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11229 ;; Patterns for LDRD/STRD in Thumb2 mode
11231 (define_insn "*thumb2_ldrd"
11232 [(set (match_operand:SI 0 "s_register_operand" "=r")
11233 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11234 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11235 (set (match_operand:SI 3 "s_register_operand" "=r")
11236 (mem:SI (plus:SI (match_dup 1)
11237 (match_operand:SI 4 "const_int_operand" ""))))]
11238 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11239 && current_tune->prefer_ldrd_strd
11240 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11241 && (operands_ok_ldrd_strd (operands[0], operands[3],
11242 operands[1], INTVAL (operands[2]),
11244 "ldrd%?\t%0, %3, [%1, %2]"
11245 [(set_attr "type" "load2")
11246 (set_attr "predicable" "yes")
11247 (set_attr "predicable_short_it" "no")])
11249 (define_insn "*thumb2_ldrd_base"
11250 [(set (match_operand:SI 0 "s_register_operand" "=r")
11251 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11252 (set (match_operand:SI 2 "s_register_operand" "=r")
11253 (mem:SI (plus:SI (match_dup 1)
11255 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11256 && current_tune->prefer_ldrd_strd
11257 && (operands_ok_ldrd_strd (operands[0], operands[2],
11258 operands[1], 0, false, true))"
11259 "ldrd%?\t%0, %2, [%1]"
11260 [(set_attr "type" "load2")
11261 (set_attr "predicable" "yes")
11262 (set_attr "predicable_short_it" "no")])
11264 (define_insn "*thumb2_ldrd_base_neg"
11265 [(set (match_operand:SI 0 "s_register_operand" "=r")
11266 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11268 (set (match_operand:SI 2 "s_register_operand" "=r")
11269 (mem:SI (match_dup 1)))]
11270 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11271 && current_tune->prefer_ldrd_strd
11272 && (operands_ok_ldrd_strd (operands[0], operands[2],
11273 operands[1], -4, false, true))"
11274 "ldrd%?\t%0, %2, [%1, #-4]"
11275 [(set_attr "type" "load2")
11276 (set_attr "predicable" "yes")
11277 (set_attr "predicable_short_it" "no")])
11279 (define_insn "*thumb2_strd"
11280 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11281 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11282 (match_operand:SI 2 "s_register_operand" "r"))
11283 (set (mem:SI (plus:SI (match_dup 0)
11284 (match_operand:SI 3 "const_int_operand" "")))
11285 (match_operand:SI 4 "s_register_operand" "r"))]
11286 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11287 && current_tune->prefer_ldrd_strd
11288 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11289 && (operands_ok_ldrd_strd (operands[2], operands[4],
11290 operands[0], INTVAL (operands[1]),
11292 "strd%?\t%2, %4, [%0, %1]"
11293 [(set_attr "type" "store2")
11294 (set_attr "predicable" "yes")
11295 (set_attr "predicable_short_it" "no")])
11297 (define_insn "*thumb2_strd_base"
11298 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11299 (match_operand:SI 1 "s_register_operand" "r"))
11300 (set (mem:SI (plus:SI (match_dup 0)
11302 (match_operand:SI 2 "s_register_operand" "r"))]
11303 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11304 && current_tune->prefer_ldrd_strd
11305 && (operands_ok_ldrd_strd (operands[1], operands[2],
11306 operands[0], 0, false, false))"
11307 "strd%?\t%1, %2, [%0]"
11308 [(set_attr "type" "store2")
11309 (set_attr "predicable" "yes")
11310 (set_attr "predicable_short_it" "no")])
11312 (define_insn "*thumb2_strd_base_neg"
11313 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11315 (match_operand:SI 1 "s_register_operand" "r"))
11316 (set (mem:SI (match_dup 0))
11317 (match_operand:SI 2 "s_register_operand" "r"))]
11318 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11319 && current_tune->prefer_ldrd_strd
11320 && (operands_ok_ldrd_strd (operands[1], operands[2],
11321 operands[0], -4, false, false))"
11322 "strd%?\t%1, %2, [%0, #-4]"
11323 [(set_attr "type" "store2")
11324 (set_attr "predicable" "yes")
11325 (set_attr "predicable_short_it" "no")])
11327 ;; ARMv8 CRC32 instructions.
11328 (define_insn "<crc_variant>"
11329 [(set (match_operand:SI 0 "s_register_operand" "=r")
11330 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11331 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11334 "<crc_variant>\\t%0, %1, %2"
11335 [(set_attr "type" "crc")
11336 (set_attr "conds" "unconditional")]
11339 ;; Load the load/store double peephole optimizations.
11340 (include "ldrdstrd.md")
11342 ;; Load the load/store multiple patterns
11343 (include "ldmstm.md")
11345 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11346 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11347 (define_insn "*load_multiple"
11348 [(match_parallel 0 "load_multiple_operation"
11349 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11350 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11355 arm_output_multireg_pop (operands, /*return_pc=*/false,
11356 /*cond=*/const_true_rtx,
11362 [(set_attr "predicable" "yes")]
11365 (define_expand "copysignsf3"
11366 [(match_operand:SF 0 "register_operand")
11367 (match_operand:SF 1 "register_operand")
11368 (match_operand:SF 2 "register_operand")]
11369 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11371 emit_move_insn (operands[0], operands[2]);
11372 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11373 GEN_INT (31), GEN_INT (0),
11374 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11379 (define_expand "copysigndf3"
11380 [(match_operand:DF 0 "register_operand")
11381 (match_operand:DF 1 "register_operand")
11382 (match_operand:DF 2 "register_operand")]
11383 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11385 rtx op0_low = gen_lowpart (SImode, operands[0]);
11386 rtx op0_high = gen_highpart (SImode, operands[0]);
11387 rtx op1_low = gen_lowpart (SImode, operands[1]);
11388 rtx op1_high = gen_highpart (SImode, operands[1]);
11389 rtx op2_high = gen_highpart (SImode, operands[2]);
11391 rtx scratch1 = gen_reg_rtx (SImode);
11392 rtx scratch2 = gen_reg_rtx (SImode);
11393 emit_move_insn (scratch1, op2_high);
11394 emit_move_insn (scratch2, op1_high);
11396 emit_insn(gen_rtx_SET(scratch1,
11397 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11398 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11399 emit_move_insn (op0_low, op1_low);
11400 emit_move_insn (op0_high, scratch2);
11406 ;; movmisalign patterns for HImode and SImode.
11407 (define_expand "movmisalign<mode>"
11408 [(match_operand:HSI 0 "general_operand")
11409 (match_operand:HSI 1 "general_operand")]
11412 /* This pattern is not permitted to fail during expansion: if both arguments
11413 are non-registers (e.g. memory := constant), force operand 1 into a
11415 rtx (* gen_unaligned_load)(rtx, rtx);
11416 rtx tmp_dest = operands[0];
11417 if (!s_register_operand (operands[0], <MODE>mode)
11418 && !s_register_operand (operands[1], <MODE>mode))
11419 operands[1] = force_reg (<MODE>mode, operands[1]);
11421 if (<MODE>mode == HImode)
11423 gen_unaligned_load = gen_unaligned_loadhiu;
11424 tmp_dest = gen_reg_rtx (SImode);
11427 gen_unaligned_load = gen_unaligned_loadsi;
11429 if (MEM_P (operands[1]))
11431 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11432 if (<MODE>mode == HImode)
11433 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11436 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11441 ;; Vector bits common to IWMMXT and Neon
11442 (include "vec-common.md")
11443 ;; Load the Intel Wireless Multimedia Extension patterns
11444 (include "iwmmxt.md")
11445 ;; Load the VFP co-processor patterns
11447 ;; Thumb-1 patterns
11448 (include "thumb1.md")
11449 ;; Thumb-2 patterns
11450 (include "thumb2.md")
11452 (include "neon.md")
11454 (include "crypto.md")
11455 ;; Synchronization Primitives
11456 (include "sync.md")
11457 ;; Fixed-point patterns
11458 (include "arm-fixed.md")