1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2014 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.
25 ;; Beware of splitting Thumb1 patterns that output multiple
26 ;; assembly instructions, in particular instruction such as SBC and
27 ;; ADC which consume flags. For example, in the pattern thumb_subdi3
28 ;; below, the output SUB implicitly sets the flags (assembled to SUBS)
29 ;; and then the Carry flag is used by SBC to compute the correct
30 ;; result. If we split thumb_subdi3 pattern into two separate RTL
31 ;; insns (using define_insn_and_split), the scheduler might place
32 ;; other RTL insns between SUB and SBC, possibly modifying the Carry
33 ;; flag used by SBC. This might happen because most Thumb1 patterns
34 ;; for flag-setting instructions do not have explicit RTL for setting
35 ;; or clobbering the flags. Instead, they have the attribute "conds"
36 ;; with value "set" or "clob". However, this attribute is not used to
37 ;; identify dependencies and therefore the scheduler might reorder
38 ;; these instruction. Currenly, this problem cannot happen because
39 ;; there are no separate Thumb1 patterns for individual instruction
40 ;; that consume flags (except conditional execution, which is treated
41 ;; differently). In particular there is no Thumb1 armv6-m pattern for
45 ;;---------------------------------------------------------------------------
48 ;; Register numbers -- All machine registers should be defined here
50 [(R0_REGNUM 0) ; First CORE register
51 (R1_REGNUM 1) ; Second CORE register
52 (IP_REGNUM 12) ; Scratch register
53 (SP_REGNUM 13) ; Stack pointer
54 (LR_REGNUM 14) ; Return address register
55 (PC_REGNUM 15) ; Program counter
56 (LAST_ARM_REGNUM 15) ;
57 (CC_REGNUM 100) ; Condition code pseudo register
58 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
61 ;; 3rd operand to select_dominance_cc_mode
68 ;; conditional compare combination
79 ;;---------------------------------------------------------------------------
82 ;; Processor type. This is created automatically from arm-cores.def.
83 (include "arm-tune.md")
85 ;; Instruction classification types
88 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
89 ; generating ARM code. This is used to control the length of some insn
90 ; patterns that share the same RTL in both ARM and Thumb code.
91 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
93 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
94 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
96 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
97 (define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
99 ; We use this attribute to disable alternatives that can produce 32-bit
100 ; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
101 ; that contain 32-bit instructions.
102 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
104 ; This attribute is used to disable a predicated alternative when we have
106 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
108 ;; Operand number of an input operand that is shifted. Zero if the
109 ;; given instruction does not shift one of its input operands.
110 (define_attr "shift" "" (const_int 0))
112 ; Floating Point Unit. If we only have floating point emulation, then there
113 ; is no point in scheduling the floating point insns. (Well, for best
114 ; performance we should try and group them together).
115 (define_attr "fpu" "none,vfp"
116 (const (symbol_ref "arm_fpu_attr")))
118 (define_attr "predicated" "yes,no" (const_string "no"))
120 ; LENGTH of an instruction (in bytes)
121 (define_attr "length" ""
124 ; The architecture which supports the instruction (or alternative).
125 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
126 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
127 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
128 ; arm_arch6. This attribute is used to compute attribute "enabled",
129 ; use type "any" to enable an alternative in all cases.
130 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3"
131 (const_string "any"))
133 (define_attr "arch_enabled" "no,yes"
134 (cond [(eq_attr "arch" "any")
137 (and (eq_attr "arch" "a")
138 (match_test "TARGET_ARM"))
141 (and (eq_attr "arch" "t")
142 (match_test "TARGET_THUMB"))
145 (and (eq_attr "arch" "t1")
146 (match_test "TARGET_THUMB1"))
149 (and (eq_attr "arch" "t2")
150 (match_test "TARGET_THUMB2"))
153 (and (eq_attr "arch" "32")
154 (match_test "TARGET_32BIT"))
157 (and (eq_attr "arch" "v6")
158 (match_test "TARGET_32BIT && arm_arch6"))
161 (and (eq_attr "arch" "nov6")
162 (match_test "TARGET_32BIT && !arm_arch6"))
165 (and (eq_attr "arch" "avoid_neon_for_64bits")
166 (match_test "TARGET_NEON")
167 (not (match_test "TARGET_PREFER_NEON_64BITS")))
170 (and (eq_attr "arch" "neon_for_64bits")
171 (match_test "TARGET_NEON")
172 (match_test "TARGET_PREFER_NEON_64BITS"))
175 (and (eq_attr "arch" "iwmmxt2")
176 (match_test "TARGET_REALLY_IWMMXT2"))
179 (and (eq_attr "arch" "armv6_or_vfpv3")
180 (match_test "arm_arch6 || TARGET_VFP3"))
184 (const_string "no")))
186 (define_attr "opt" "any,speed,size"
187 (const_string "any"))
189 (define_attr "opt_enabled" "no,yes"
190 (cond [(eq_attr "opt" "any")
193 (and (eq_attr "opt" "speed")
194 (match_test "optimize_function_for_speed_p (cfun)"))
197 (and (eq_attr "opt" "size")
198 (match_test "optimize_function_for_size_p (cfun)"))
199 (const_string "yes")]
200 (const_string "no")))
202 (define_attr "use_literal_pool" "no,yes"
203 (cond [(and (eq_attr "type" "f_loads,f_loadd")
204 (match_test "CONSTANT_P (operands[1])"))
205 (const_string "yes")]
206 (const_string "no")))
208 ; Enable all alternatives that are both arch_enabled and insn_enabled.
209 ; FIXME:: opt_enabled has been temporarily removed till the time we have
210 ; an attribute that allows the use of such alternatives.
211 ; This depends on caching of speed_p, size_p on a per
212 ; alternative basis. The problem is that the enabled attribute
213 ; cannot depend on any state that is not cached or is not constant
214 ; for a compilation unit. We probably need a generic "hot/cold"
215 ; alternative which if implemented can help with this. We disable this
216 ; until such a time as this is implemented and / or the improvements or
217 ; regressions with removing this attribute are double checked.
218 ; See ashldi3_neon and <shift>di3_neon in neon.md.
220 (define_attr "enabled" "no,yes"
221 (cond [(and (eq_attr "predicable_short_it" "no")
222 (and (eq_attr "predicated" "yes")
223 (match_test "arm_restrict_it")))
226 (and (eq_attr "enabled_for_depr_it" "no")
227 (match_test "arm_restrict_it"))
230 (and (eq_attr "use_literal_pool" "yes")
231 (match_test "arm_disable_literal_pool"))
234 (eq_attr "arch_enabled" "no")
236 (const_string "yes")))
238 ; POOL_RANGE is how far away from a constant pool entry that this insn
239 ; can be placed. If the distance is zero, then this insn will never
240 ; reference the pool.
241 ; Note that for Thumb constant pools the PC value is rounded down to the
242 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
243 ; Thumb insns) should be set to <max_range> - 2.
244 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
245 ; before its address. It is set to <max_range> - (8 + <data_size>).
246 (define_attr "arm_pool_range" "" (const_int 0))
247 (define_attr "thumb2_pool_range" "" (const_int 0))
248 (define_attr "arm_neg_pool_range" "" (const_int 0))
249 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
251 (define_attr "pool_range" ""
252 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
253 (attr "arm_pool_range")))
254 (define_attr "neg_pool_range" ""
255 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
256 (attr "arm_neg_pool_range")))
258 ; An assembler sequence may clobber the condition codes without us knowing.
259 ; If such an insn references the pool, then we have no way of knowing how,
260 ; so use the most conservative value for pool_range.
261 (define_asm_attributes
262 [(set_attr "conds" "clob")
263 (set_attr "length" "4")
264 (set_attr "pool_range" "250")])
266 ; Load scheduling, set from the arm_ld_sched variable
267 ; initialized by arm_option_override()
268 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
270 ; condition codes: this one is used by final_prescan_insn to speed up
271 ; conditionalizing instructions. It saves having to scan the rtl to see if
272 ; it uses or alters the condition codes.
274 ; USE means that the condition codes are used by the insn in the process of
275 ; outputting code, this means (at present) that we can't use the insn in
278 ; SET means that the purpose of the insn is to set the condition codes in a
279 ; well defined manner.
281 ; CLOB means that the condition codes are altered in an undefined manner, if
282 ; they are altered at all
284 ; UNCONDITIONAL means the instruction can not be conditionally executed and
285 ; that the instruction does not use or alter the condition codes.
287 ; NOCOND means that the instruction does not use or alter the condition
288 ; codes but can be converted into a conditionally exectuted instruction.
290 (define_attr "conds" "use,set,clob,unconditional,nocond"
292 (ior (eq_attr "is_thumb1" "yes")
293 (eq_attr "type" "call"))
294 (const_string "clob")
295 (if_then_else (eq_attr "is_neon_type" "no")
296 (const_string "nocond")
297 (const_string "unconditional"))))
299 ; Predicable means that the insn can be conditionally executed based on
300 ; an automatically added predicate (additional patterns are generated by
301 ; gen...). We default to 'no' because no Thumb patterns match this rule
302 ; and not all ARM patterns do.
303 (define_attr "predicable" "no,yes" (const_string "no"))
305 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
306 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
307 ; suffer blockages enough to warrant modelling this (and it can adversely
308 ; affect the schedule).
309 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
311 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
312 ; to stall the processor. Used with model_wbuf above.
313 (define_attr "write_conflict" "no,yes"
314 (if_then_else (eq_attr "type"
317 (const_string "no")))
319 ; Classify the insns into those that take one cycle and those that take more
320 ; than one on the main cpu execution unit.
321 (define_attr "core_cycles" "single,multi"
322 (if_then_else (eq_attr "type"
323 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
324 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
325 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
326 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
327 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
328 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
329 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
330 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
331 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
332 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
333 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
334 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
335 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
336 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
337 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
338 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
339 (const_string "single")
340 (const_string "multi")))
342 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
343 ;; distant label. Only applicable to Thumb code.
344 (define_attr "far_jump" "yes,no" (const_string "no"))
347 ;; The number of machine instructions this pattern expands to.
348 ;; Used for Thumb-2 conditional execution.
349 (define_attr "ce_count" "" (const_int 1))
351 ;;---------------------------------------------------------------------------
354 (include "unspecs.md")
356 ;;---------------------------------------------------------------------------
359 (include "iterators.md")
361 ;;---------------------------------------------------------------------------
364 (include "predicates.md")
365 (include "constraints.md")
367 ;;---------------------------------------------------------------------------
368 ;; Pipeline descriptions
370 (define_attr "tune_cortexr4" "yes,no"
372 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
374 (const_string "no"))))
376 ;; True if the generic scheduling description should be used.
378 (define_attr "generic_sched" "yes,no"
380 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs,cortexa5,cortexa7,cortexa8,cortexa9,cortexa12,cortexa15,cortexa53,cortexm4,marvell_pj4")
381 (eq_attr "tune_cortexr4" "yes"))
383 (const_string "yes"))))
385 (define_attr "generic_vfp" "yes,no"
387 (and (eq_attr "fpu" "vfp")
388 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,cortexa8,cortexa9,cortexa53,cortexm4,marvell_pj4")
389 (eq_attr "tune_cortexr4" "no"))
391 (const_string "no"))))
393 (include "marvell-f-iwmmxt.md")
394 (include "arm-generic.md")
395 (include "arm926ejs.md")
396 (include "arm1020e.md")
397 (include "arm1026ejs.md")
398 (include "arm1136jfs.md")
400 (include "fa606te.md")
401 (include "fa626te.md")
402 (include "fmp626.md")
403 (include "fa726te.md")
404 (include "cortex-a5.md")
405 (include "cortex-a7.md")
406 (include "cortex-a8.md")
407 (include "cortex-a9.md")
408 (include "cortex-a15.md")
409 (include "cortex-a53.md")
410 (include "cortex-r4.md")
411 (include "cortex-r4f.md")
412 (include "cortex-m4.md")
413 (include "cortex-m4-fpu.md")
415 (include "marvell-pj4.md")
418 ;;---------------------------------------------------------------------------
423 ;; Note: For DImode insns, there is normally no reason why operands should
424 ;; not be in the same register, what we don't want is for something being
425 ;; written to partially overlap something that is an input.
427 (define_expand "adddi3"
429 [(set (match_operand:DI 0 "s_register_operand" "")
430 (plus:DI (match_operand:DI 1 "s_register_operand" "")
431 (match_operand:DI 2 "arm_adddi_operand" "")))
432 (clobber (reg:CC CC_REGNUM))])]
437 if (!REG_P (operands[1]))
438 operands[1] = force_reg (DImode, operands[1]);
439 if (!REG_P (operands[2]))
440 operands[2] = force_reg (DImode, operands[2]);
445 (define_insn_and_split "*arm_adddi3"
446 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
447 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
448 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
449 (clobber (reg:CC CC_REGNUM))]
450 "TARGET_32BIT && !TARGET_NEON"
452 "TARGET_32BIT && reload_completed
453 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
454 [(parallel [(set (reg:CC_C CC_REGNUM)
455 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
457 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
458 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
459 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
462 operands[3] = gen_highpart (SImode, operands[0]);
463 operands[0] = gen_lowpart (SImode, operands[0]);
464 operands[4] = gen_highpart (SImode, operands[1]);
465 operands[1] = gen_lowpart (SImode, operands[1]);
466 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
467 operands[2] = gen_lowpart (SImode, operands[2]);
469 [(set_attr "conds" "clob")
470 (set_attr "length" "8")
471 (set_attr "type" "multiple")]
474 (define_insn_and_split "*adddi_sesidi_di"
475 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
476 (plus:DI (sign_extend:DI
477 (match_operand:SI 2 "s_register_operand" "r,r"))
478 (match_operand:DI 1 "s_register_operand" "0,r")))
479 (clobber (reg:CC CC_REGNUM))]
482 "TARGET_32BIT && reload_completed"
483 [(parallel [(set (reg:CC_C CC_REGNUM)
484 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
486 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
487 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
490 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
493 operands[3] = gen_highpart (SImode, operands[0]);
494 operands[0] = gen_lowpart (SImode, operands[0]);
495 operands[4] = gen_highpart (SImode, operands[1]);
496 operands[1] = gen_lowpart (SImode, operands[1]);
497 operands[2] = gen_lowpart (SImode, operands[2]);
499 [(set_attr "conds" "clob")
500 (set_attr "length" "8")
501 (set_attr "type" "multiple")]
504 (define_insn_and_split "*adddi_zesidi_di"
505 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
506 (plus:DI (zero_extend:DI
507 (match_operand:SI 2 "s_register_operand" "r,r"))
508 (match_operand:DI 1 "s_register_operand" "0,r")))
509 (clobber (reg:CC CC_REGNUM))]
512 "TARGET_32BIT && reload_completed"
513 [(parallel [(set (reg:CC_C CC_REGNUM)
514 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
516 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
517 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
518 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
521 operands[3] = gen_highpart (SImode, operands[0]);
522 operands[0] = gen_lowpart (SImode, operands[0]);
523 operands[4] = gen_highpart (SImode, operands[1]);
524 operands[1] = gen_lowpart (SImode, operands[1]);
525 operands[2] = gen_lowpart (SImode, operands[2]);
527 [(set_attr "conds" "clob")
528 (set_attr "length" "8")
529 (set_attr "type" "multiple")]
532 (define_expand "addsi3"
533 [(set (match_operand:SI 0 "s_register_operand" "")
534 (plus:SI (match_operand:SI 1 "s_register_operand" "")
535 (match_operand:SI 2 "reg_or_int_operand" "")))]
538 if (TARGET_32BIT && CONST_INT_P (operands[2]))
540 arm_split_constant (PLUS, SImode, NULL_RTX,
541 INTVAL (operands[2]), operands[0], operands[1],
542 optimize && can_create_pseudo_p ());
548 ; If there is a scratch available, this will be faster than synthesizing the
551 [(match_scratch:SI 3 "r")
552 (set (match_operand:SI 0 "arm_general_register_operand" "")
553 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
554 (match_operand:SI 2 "const_int_operand" "")))]
556 !(const_ok_for_arm (INTVAL (operands[2]))
557 || const_ok_for_arm (-INTVAL (operands[2])))
558 && const_ok_for_arm (~INTVAL (operands[2]))"
559 [(set (match_dup 3) (match_dup 2))
560 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
564 ;; The r/r/k alternative is required when reloading the address
565 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
566 ;; put the duplicated register first, and not try the commutative version.
567 (define_insn_and_split "*arm_addsi3"
568 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
569 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
570 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
585 subw%?\\t%0, %1, #%n2
586 subw%?\\t%0, %1, #%n2
589 && CONST_INT_P (operands[2])
590 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
591 && (reload_completed || !arm_eliminable_register (operands[1]))"
592 [(clobber (const_int 0))]
594 arm_split_constant (PLUS, SImode, curr_insn,
595 INTVAL (operands[2]), operands[0],
599 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
600 (set_attr "predicable" "yes")
601 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
602 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
603 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
604 (const_string "alu_imm")
605 (const_string "alu_sreg")))
609 (define_insn "addsi3_compare0"
610 [(set (reg:CC_NOOV CC_REGNUM)
612 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
613 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
615 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
616 (plus:SI (match_dup 1) (match_dup 2)))]
622 [(set_attr "conds" "set")
623 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
626 (define_insn "*addsi3_compare0_scratch"
627 [(set (reg:CC_NOOV CC_REGNUM)
629 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
630 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
637 [(set_attr "conds" "set")
638 (set_attr "predicable" "yes")
639 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
642 (define_insn "*compare_negsi_si"
643 [(set (reg:CC_Z CC_REGNUM)
645 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
646 (match_operand:SI 1 "s_register_operand" "l,r")))]
649 [(set_attr "conds" "set")
650 (set_attr "predicable" "yes")
651 (set_attr "arch" "t2,*")
652 (set_attr "length" "2,4")
653 (set_attr "predicable_short_it" "yes,no")
654 (set_attr "type" "alus_sreg")]
657 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
658 ;; addend is a constant.
659 (define_insn "cmpsi2_addneg"
660 [(set (reg:CC CC_REGNUM)
662 (match_operand:SI 1 "s_register_operand" "r,r")
663 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
664 (set (match_operand:SI 0 "s_register_operand" "=r,r")
665 (plus:SI (match_dup 1)
666 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
667 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
670 sub%.\\t%0, %1, #%n3"
671 [(set_attr "conds" "set")
672 (set_attr "type" "alus_sreg")]
675 ;; Convert the sequence
677 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
681 ;; bcs dest ((unsigned)rn >= 1)
682 ;; similarly for the beq variant using bcc.
683 ;; This is a common looping idiom (while (n--))
685 [(set (match_operand:SI 0 "arm_general_register_operand" "")
686 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
688 (set (match_operand 2 "cc_register" "")
689 (compare (match_dup 0) (const_int -1)))
691 (if_then_else (match_operator 3 "equality_operator"
692 [(match_dup 2) (const_int 0)])
693 (match_operand 4 "" "")
694 (match_operand 5 "" "")))]
695 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
699 (match_dup 1) (const_int 1)))
700 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
702 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
705 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
706 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
709 operands[2], const0_rtx);"
712 ;; The next four insns work because they compare the result with one of
713 ;; the operands, and we know that the use of the condition code is
714 ;; either GEU or LTU, so we can use the carry flag from the addition
715 ;; instead of doing the compare a second time.
716 (define_insn "*addsi3_compare_op1"
717 [(set (reg:CC_C CC_REGNUM)
719 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
720 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
722 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
723 (plus:SI (match_dup 1) (match_dup 2)))]
729 [(set_attr "conds" "set")
730 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
733 (define_insn "*addsi3_compare_op2"
734 [(set (reg:CC_C CC_REGNUM)
736 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
737 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
739 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
740 (plus:SI (match_dup 1) (match_dup 2)))]
745 sub%.\\t%0, %1, #%n2"
746 [(set_attr "conds" "set")
747 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
750 (define_insn "*compare_addsi2_op0"
751 [(set (reg:CC_C CC_REGNUM)
753 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
754 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
763 [(set_attr "conds" "set")
764 (set_attr "predicable" "yes")
765 (set_attr "arch" "t2,t2,*,*,*")
766 (set_attr "predicable_short_it" "yes,yes,no,no,no")
767 (set_attr "length" "2,2,4,4,4")
768 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
771 (define_insn "*compare_addsi2_op1"
772 [(set (reg:CC_C CC_REGNUM)
774 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
775 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
784 [(set_attr "conds" "set")
785 (set_attr "predicable" "yes")
786 (set_attr "arch" "t2,t2,*,*,*")
787 (set_attr "predicable_short_it" "yes,yes,no,no,no")
788 (set_attr "length" "2,2,4,4,4")
789 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
792 (define_insn "*addsi3_carryin_<optab>"
793 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
794 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
795 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
796 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
801 sbc%?\\t%0, %1, #%B2"
802 [(set_attr "conds" "use")
803 (set_attr "predicable" "yes")
804 (set_attr "arch" "t2,*,*")
805 (set_attr "length" "4")
806 (set_attr "predicable_short_it" "yes,no,no")
807 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
810 (define_insn "*addsi3_carryin_alt2_<optab>"
811 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
812 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
813 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
814 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
819 sbc%?\\t%0, %1, #%B2"
820 [(set_attr "conds" "use")
821 (set_attr "predicable" "yes")
822 (set_attr "arch" "t2,*,*")
823 (set_attr "length" "4")
824 (set_attr "predicable_short_it" "yes,no,no")
825 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
828 (define_insn "*addsi3_carryin_shift_<optab>"
829 [(set (match_operand:SI 0 "s_register_operand" "=r")
831 (match_operator:SI 2 "shift_operator"
832 [(match_operand:SI 3 "s_register_operand" "r")
833 (match_operand:SI 4 "reg_or_int_operand" "rM")])
834 (match_operand:SI 1 "s_register_operand" "r"))
835 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
837 "adc%?\\t%0, %1, %3%S2"
838 [(set_attr "conds" "use")
839 (set_attr "predicable" "yes")
840 (set_attr "predicable_short_it" "no")
841 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
842 (const_string "alu_shift_imm")
843 (const_string "alu_shift_reg")))]
846 (define_insn "*addsi3_carryin_clobercc_<optab>"
847 [(set (match_operand:SI 0 "s_register_operand" "=r")
848 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
849 (match_operand:SI 2 "arm_rhs_operand" "rI"))
850 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
851 (clobber (reg:CC CC_REGNUM))]
854 [(set_attr "conds" "set")
855 (set_attr "type" "adcs_reg")]
858 (define_insn "*subsi3_carryin"
859 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
860 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
861 (match_operand:SI 2 "s_register_operand" "r,r"))
862 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
867 [(set_attr "conds" "use")
868 (set_attr "arch" "*,a")
869 (set_attr "predicable" "yes")
870 (set_attr "predicable_short_it" "no")
871 (set_attr "type" "adc_reg,adc_imm")]
874 (define_insn "*subsi3_carryin_const"
875 [(set (match_operand:SI 0 "s_register_operand" "=r")
876 (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
877 (match_operand:SI 2 "arm_not_operand" "K"))
878 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
881 [(set_attr "conds" "use")
882 (set_attr "type" "adc_imm")]
885 (define_insn "*subsi3_carryin_compare"
886 [(set (reg:CC CC_REGNUM)
887 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
888 (match_operand:SI 2 "s_register_operand" "r")))
889 (set (match_operand:SI 0 "s_register_operand" "=r")
890 (minus:SI (minus:SI (match_dup 1)
892 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
895 [(set_attr "conds" "set")
896 (set_attr "type" "adcs_reg")]
899 (define_insn "*subsi3_carryin_compare_const"
900 [(set (reg:CC CC_REGNUM)
901 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
902 (match_operand:SI 2 "arm_not_operand" "K")))
903 (set (match_operand:SI 0 "s_register_operand" "=r")
904 (minus:SI (plus:SI (match_dup 1)
906 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
908 "sbcs\\t%0, %1, #%B2"
909 [(set_attr "conds" "set")
910 (set_attr "type" "adcs_imm")]
913 (define_insn "*subsi3_carryin_shift"
914 [(set (match_operand:SI 0 "s_register_operand" "=r")
916 (match_operand:SI 1 "s_register_operand" "r")
917 (match_operator:SI 2 "shift_operator"
918 [(match_operand:SI 3 "s_register_operand" "r")
919 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
920 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
922 "sbc%?\\t%0, %1, %3%S2"
923 [(set_attr "conds" "use")
924 (set_attr "predicable" "yes")
925 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
926 (const_string "alu_shift_imm")
927 (const_string "alu_shift_reg")))]
930 (define_insn "*rsbsi3_carryin_shift"
931 [(set (match_operand:SI 0 "s_register_operand" "=r")
933 (match_operator:SI 2 "shift_operator"
934 [(match_operand:SI 3 "s_register_operand" "r")
935 (match_operand:SI 4 "reg_or_int_operand" "rM")])
936 (match_operand:SI 1 "s_register_operand" "r"))
937 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
939 "rsc%?\\t%0, %1, %3%S2"
940 [(set_attr "conds" "use")
941 (set_attr "predicable" "yes")
942 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
943 (const_string "alu_shift_imm")
944 (const_string "alu_shift_reg")))]
947 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
949 [(set (match_operand:SI 0 "s_register_operand" "")
950 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
951 (match_operand:SI 2 "s_register_operand" ""))
953 (clobber (match_operand:SI 3 "s_register_operand" ""))]
955 [(set (match_dup 3) (match_dup 1))
956 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
958 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
961 (define_expand "addsf3"
962 [(set (match_operand:SF 0 "s_register_operand" "")
963 (plus:SF (match_operand:SF 1 "s_register_operand" "")
964 (match_operand:SF 2 "s_register_operand" "")))]
965 "TARGET_32BIT && TARGET_HARD_FLOAT"
969 (define_expand "adddf3"
970 [(set (match_operand:DF 0 "s_register_operand" "")
971 (plus:DF (match_operand:DF 1 "s_register_operand" "")
972 (match_operand:DF 2 "s_register_operand" "")))]
973 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
977 (define_expand "subdi3"
979 [(set (match_operand:DI 0 "s_register_operand" "")
980 (minus:DI (match_operand:DI 1 "s_register_operand" "")
981 (match_operand:DI 2 "s_register_operand" "")))
982 (clobber (reg:CC CC_REGNUM))])]
987 if (!REG_P (operands[1]))
988 operands[1] = force_reg (DImode, operands[1]);
989 if (!REG_P (operands[2]))
990 operands[2] = force_reg (DImode, operands[2]);
995 (define_insn_and_split "*arm_subdi3"
996 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
997 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
998 (match_operand:DI 2 "s_register_operand" "r,0,0")))
999 (clobber (reg:CC CC_REGNUM))]
1000 "TARGET_32BIT && !TARGET_NEON"
1001 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1002 "&& reload_completed"
1003 [(parallel [(set (reg:CC CC_REGNUM)
1004 (compare:CC (match_dup 1) (match_dup 2)))
1005 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1006 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1007 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1009 operands[3] = gen_highpart (SImode, operands[0]);
1010 operands[0] = gen_lowpart (SImode, operands[0]);
1011 operands[4] = gen_highpart (SImode, operands[1]);
1012 operands[1] = gen_lowpart (SImode, operands[1]);
1013 operands[5] = gen_highpart (SImode, operands[2]);
1014 operands[2] = gen_lowpart (SImode, operands[2]);
1016 [(set_attr "conds" "clob")
1017 (set_attr "length" "8")
1018 (set_attr "type" "multiple")]
1021 (define_insn_and_split "*subdi_di_zesidi"
1022 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1023 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1025 (match_operand:SI 2 "s_register_operand" "r,r"))))
1026 (clobber (reg:CC CC_REGNUM))]
1028 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1029 "&& reload_completed"
1030 [(parallel [(set (reg:CC CC_REGNUM)
1031 (compare:CC (match_dup 1) (match_dup 2)))
1032 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1033 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1034 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1036 operands[3] = gen_highpart (SImode, operands[0]);
1037 operands[0] = gen_lowpart (SImode, operands[0]);
1038 operands[4] = gen_highpart (SImode, operands[1]);
1039 operands[1] = gen_lowpart (SImode, operands[1]);
1040 operands[5] = GEN_INT (~0);
1042 [(set_attr "conds" "clob")
1043 (set_attr "length" "8")
1044 (set_attr "type" "multiple")]
1047 (define_insn_and_split "*subdi_di_sesidi"
1048 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1049 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1051 (match_operand:SI 2 "s_register_operand" "r,r"))))
1052 (clobber (reg:CC CC_REGNUM))]
1054 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1055 "&& reload_completed"
1056 [(parallel [(set (reg:CC CC_REGNUM)
1057 (compare:CC (match_dup 1) (match_dup 2)))
1058 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1059 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1060 (ashiftrt:SI (match_dup 2)
1062 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1064 operands[3] = gen_highpart (SImode, operands[0]);
1065 operands[0] = gen_lowpart (SImode, operands[0]);
1066 operands[4] = gen_highpart (SImode, operands[1]);
1067 operands[1] = gen_lowpart (SImode, operands[1]);
1069 [(set_attr "conds" "clob")
1070 (set_attr "length" "8")
1071 (set_attr "type" "multiple")]
1074 (define_insn_and_split "*subdi_zesidi_di"
1075 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1076 (minus:DI (zero_extend:DI
1077 (match_operand:SI 2 "s_register_operand" "r,r"))
1078 (match_operand:DI 1 "s_register_operand" "0,r")))
1079 (clobber (reg:CC CC_REGNUM))]
1081 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1083 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1084 "&& reload_completed"
1085 [(parallel [(set (reg:CC CC_REGNUM)
1086 (compare:CC (match_dup 2) (match_dup 1)))
1087 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1088 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1089 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1091 operands[3] = gen_highpart (SImode, operands[0]);
1092 operands[0] = gen_lowpart (SImode, operands[0]);
1093 operands[4] = gen_highpart (SImode, operands[1]);
1094 operands[1] = gen_lowpart (SImode, operands[1]);
1096 [(set_attr "conds" "clob")
1097 (set_attr "length" "8")
1098 (set_attr "type" "multiple")]
1101 (define_insn_and_split "*subdi_sesidi_di"
1102 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1103 (minus:DI (sign_extend:DI
1104 (match_operand:SI 2 "s_register_operand" "r,r"))
1105 (match_operand:DI 1 "s_register_operand" "0,r")))
1106 (clobber (reg:CC CC_REGNUM))]
1108 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1110 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1111 "&& reload_completed"
1112 [(parallel [(set (reg:CC CC_REGNUM)
1113 (compare:CC (match_dup 2) (match_dup 1)))
1114 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1115 (set (match_dup 3) (minus:SI (minus:SI
1116 (ashiftrt:SI (match_dup 2)
1119 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1121 operands[3] = gen_highpart (SImode, operands[0]);
1122 operands[0] = gen_lowpart (SImode, operands[0]);
1123 operands[4] = gen_highpart (SImode, operands[1]);
1124 operands[1] = gen_lowpart (SImode, operands[1]);
1126 [(set_attr "conds" "clob")
1127 (set_attr "length" "8")
1128 (set_attr "type" "multiple")]
1131 (define_insn_and_split "*subdi_zesidi_zesidi"
1132 [(set (match_operand:DI 0 "s_register_operand" "=r")
1133 (minus:DI (zero_extend:DI
1134 (match_operand:SI 1 "s_register_operand" "r"))
1136 (match_operand:SI 2 "s_register_operand" "r"))))
1137 (clobber (reg:CC CC_REGNUM))]
1139 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1140 "&& reload_completed"
1141 [(parallel [(set (reg:CC CC_REGNUM)
1142 (compare:CC (match_dup 1) (match_dup 2)))
1143 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1144 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1145 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1147 operands[3] = gen_highpart (SImode, operands[0]);
1148 operands[0] = gen_lowpart (SImode, operands[0]);
1150 [(set_attr "conds" "clob")
1151 (set_attr "length" "8")
1152 (set_attr "type" "multiple")]
1155 (define_expand "subsi3"
1156 [(set (match_operand:SI 0 "s_register_operand" "")
1157 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1158 (match_operand:SI 2 "s_register_operand" "")))]
1161 if (CONST_INT_P (operands[1]))
1165 arm_split_constant (MINUS, SImode, NULL_RTX,
1166 INTVAL (operands[1]), operands[0],
1167 operands[2], optimize && can_create_pseudo_p ());
1170 else /* TARGET_THUMB1 */
1171 operands[1] = force_reg (SImode, operands[1]);
1176 ; ??? Check Thumb-2 split length
1177 (define_insn_and_split "*arm_subsi3_insn"
1178 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r ,r,r,rk,r")
1179 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,rI,r,r,k ,?n")
1180 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r ,I,r,r ,r")))]
1192 "&& (CONST_INT_P (operands[1])
1193 && !const_ok_for_arm (INTVAL (operands[1])))"
1194 [(clobber (const_int 0))]
1196 arm_split_constant (MINUS, SImode, curr_insn,
1197 INTVAL (operands[1]), operands[0], operands[2], 0);
1200 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1201 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1202 (set_attr "predicable" "yes")
1203 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1204 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1208 [(match_scratch:SI 3 "r")
1209 (set (match_operand:SI 0 "arm_general_register_operand" "")
1210 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1211 (match_operand:SI 2 "arm_general_register_operand" "")))]
1213 && !const_ok_for_arm (INTVAL (operands[1]))
1214 && const_ok_for_arm (~INTVAL (operands[1]))"
1215 [(set (match_dup 3) (match_dup 1))
1216 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1220 (define_insn "*subsi3_compare0"
1221 [(set (reg:CC_NOOV CC_REGNUM)
1223 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1224 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1226 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1227 (minus:SI (match_dup 1) (match_dup 2)))]
1233 [(set_attr "conds" "set")
1234 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1237 (define_insn "subsi3_compare"
1238 [(set (reg:CC CC_REGNUM)
1239 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1240 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1241 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1242 (minus:SI (match_dup 1) (match_dup 2)))]
1248 [(set_attr "conds" "set")
1249 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1252 (define_expand "subsf3"
1253 [(set (match_operand:SF 0 "s_register_operand" "")
1254 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1255 (match_operand:SF 2 "s_register_operand" "")))]
1256 "TARGET_32BIT && TARGET_HARD_FLOAT"
1260 (define_expand "subdf3"
1261 [(set (match_operand:DF 0 "s_register_operand" "")
1262 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1263 (match_operand:DF 2 "s_register_operand" "")))]
1264 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1269 ;; Multiplication insns
1271 (define_expand "mulhi3"
1272 [(set (match_operand:HI 0 "s_register_operand" "")
1273 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1274 (match_operand:HI 2 "s_register_operand" "")))]
1275 "TARGET_DSP_MULTIPLY"
1278 rtx result = gen_reg_rtx (SImode);
1279 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1280 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1285 (define_expand "mulsi3"
1286 [(set (match_operand:SI 0 "s_register_operand" "")
1287 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1288 (match_operand:SI 1 "s_register_operand" "")))]
1293 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1294 (define_insn "*arm_mulsi3"
1295 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1296 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1297 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1298 "TARGET_32BIT && !arm_arch6"
1299 "mul%?\\t%0, %2, %1"
1300 [(set_attr "type" "mul")
1301 (set_attr "predicable" "yes")]
1304 (define_insn "*arm_mulsi3_v6"
1305 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1306 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1307 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1308 "TARGET_32BIT && arm_arch6"
1309 "mul%?\\t%0, %1, %2"
1310 [(set_attr "type" "mul")
1311 (set_attr "predicable" "yes")
1312 (set_attr "arch" "t2,t2,*")
1313 (set_attr "length" "4")
1314 (set_attr "predicable_short_it" "yes,yes,no")]
1317 (define_insn "*mulsi3_compare0"
1318 [(set (reg:CC_NOOV CC_REGNUM)
1319 (compare:CC_NOOV (mult:SI
1320 (match_operand:SI 2 "s_register_operand" "r,r")
1321 (match_operand:SI 1 "s_register_operand" "%0,r"))
1323 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1324 (mult:SI (match_dup 2) (match_dup 1)))]
1325 "TARGET_ARM && !arm_arch6"
1326 "mul%.\\t%0, %2, %1"
1327 [(set_attr "conds" "set")
1328 (set_attr "type" "muls")]
1331 (define_insn "*mulsi3_compare0_v6"
1332 [(set (reg:CC_NOOV CC_REGNUM)
1333 (compare:CC_NOOV (mult:SI
1334 (match_operand:SI 2 "s_register_operand" "r")
1335 (match_operand:SI 1 "s_register_operand" "r"))
1337 (set (match_operand:SI 0 "s_register_operand" "=r")
1338 (mult:SI (match_dup 2) (match_dup 1)))]
1339 "TARGET_ARM && arm_arch6 && optimize_size"
1340 "mul%.\\t%0, %2, %1"
1341 [(set_attr "conds" "set")
1342 (set_attr "type" "muls")]
1345 (define_insn "*mulsi_compare0_scratch"
1346 [(set (reg:CC_NOOV CC_REGNUM)
1347 (compare:CC_NOOV (mult:SI
1348 (match_operand:SI 2 "s_register_operand" "r,r")
1349 (match_operand:SI 1 "s_register_operand" "%0,r"))
1351 (clobber (match_scratch:SI 0 "=&r,&r"))]
1352 "TARGET_ARM && !arm_arch6"
1353 "mul%.\\t%0, %2, %1"
1354 [(set_attr "conds" "set")
1355 (set_attr "type" "muls")]
1358 (define_insn "*mulsi_compare0_scratch_v6"
1359 [(set (reg:CC_NOOV CC_REGNUM)
1360 (compare:CC_NOOV (mult:SI
1361 (match_operand:SI 2 "s_register_operand" "r")
1362 (match_operand:SI 1 "s_register_operand" "r"))
1364 (clobber (match_scratch:SI 0 "=r"))]
1365 "TARGET_ARM && arm_arch6 && optimize_size"
1366 "mul%.\\t%0, %2, %1"
1367 [(set_attr "conds" "set")
1368 (set_attr "type" "muls")]
1371 ;; Unnamed templates to match MLA instruction.
1373 (define_insn "*mulsi3addsi"
1374 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1376 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1377 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1378 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1379 "TARGET_32BIT && !arm_arch6"
1380 "mla%?\\t%0, %2, %1, %3"
1381 [(set_attr "type" "mla")
1382 (set_attr "predicable" "yes")]
1385 (define_insn "*mulsi3addsi_v6"
1386 [(set (match_operand:SI 0 "s_register_operand" "=r")
1388 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1389 (match_operand:SI 1 "s_register_operand" "r"))
1390 (match_operand:SI 3 "s_register_operand" "r")))]
1391 "TARGET_32BIT && arm_arch6"
1392 "mla%?\\t%0, %2, %1, %3"
1393 [(set_attr "type" "mla")
1394 (set_attr "predicable" "yes")
1395 (set_attr "predicable_short_it" "no")]
1398 (define_insn "*mulsi3addsi_compare0"
1399 [(set (reg:CC_NOOV CC_REGNUM)
1402 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1403 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1404 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1406 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1407 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1409 "TARGET_ARM && arm_arch6"
1410 "mla%.\\t%0, %2, %1, %3"
1411 [(set_attr "conds" "set")
1412 (set_attr "type" "mlas")]
1415 (define_insn "*mulsi3addsi_compare0_v6"
1416 [(set (reg:CC_NOOV CC_REGNUM)
1419 (match_operand:SI 2 "s_register_operand" "r")
1420 (match_operand:SI 1 "s_register_operand" "r"))
1421 (match_operand:SI 3 "s_register_operand" "r"))
1423 (set (match_operand:SI 0 "s_register_operand" "=r")
1424 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1426 "TARGET_ARM && arm_arch6 && optimize_size"
1427 "mla%.\\t%0, %2, %1, %3"
1428 [(set_attr "conds" "set")
1429 (set_attr "type" "mlas")]
1432 (define_insn "*mulsi3addsi_compare0_scratch"
1433 [(set (reg:CC_NOOV CC_REGNUM)
1436 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1437 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1438 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1440 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1441 "TARGET_ARM && !arm_arch6"
1442 "mla%.\\t%0, %2, %1, %3"
1443 [(set_attr "conds" "set")
1444 (set_attr "type" "mlas")]
1447 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1448 [(set (reg:CC_NOOV CC_REGNUM)
1451 (match_operand:SI 2 "s_register_operand" "r")
1452 (match_operand:SI 1 "s_register_operand" "r"))
1453 (match_operand:SI 3 "s_register_operand" "r"))
1455 (clobber (match_scratch:SI 0 "=r"))]
1456 "TARGET_ARM && arm_arch6 && optimize_size"
1457 "mla%.\\t%0, %2, %1, %3"
1458 [(set_attr "conds" "set")
1459 (set_attr "type" "mlas")]
1462 (define_insn "*mulsi3subsi"
1463 [(set (match_operand:SI 0 "s_register_operand" "=r")
1465 (match_operand:SI 3 "s_register_operand" "r")
1466 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1467 (match_operand:SI 1 "s_register_operand" "r"))))]
1468 "TARGET_32BIT && arm_arch_thumb2"
1469 "mls%?\\t%0, %2, %1, %3"
1470 [(set_attr "type" "mla")
1471 (set_attr "predicable" "yes")
1472 (set_attr "predicable_short_it" "no")]
1475 (define_expand "maddsidi4"
1476 [(set (match_operand:DI 0 "s_register_operand" "")
1479 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1480 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1481 (match_operand:DI 3 "s_register_operand" "")))]
1482 "TARGET_32BIT && arm_arch3m"
1485 (define_insn "*mulsidi3adddi"
1486 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1489 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1490 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1491 (match_operand:DI 1 "s_register_operand" "0")))]
1492 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1493 "smlal%?\\t%Q0, %R0, %3, %2"
1494 [(set_attr "type" "smlal")
1495 (set_attr "predicable" "yes")]
1498 (define_insn "*mulsidi3adddi_v6"
1499 [(set (match_operand:DI 0 "s_register_operand" "=r")
1502 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1503 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1504 (match_operand:DI 1 "s_register_operand" "0")))]
1505 "TARGET_32BIT && arm_arch6"
1506 "smlal%?\\t%Q0, %R0, %3, %2"
1507 [(set_attr "type" "smlal")
1508 (set_attr "predicable" "yes")
1509 (set_attr "predicable_short_it" "no")]
1512 ;; 32x32->64 widening multiply.
1513 ;; As with mulsi3, the only difference between the v3-5 and v6+
1514 ;; versions of these patterns is the requirement that the output not
1515 ;; overlap the inputs, but that still means we have to have a named
1516 ;; expander and two different starred insns.
1518 (define_expand "mulsidi3"
1519 [(set (match_operand:DI 0 "s_register_operand" "")
1521 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1522 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1523 "TARGET_32BIT && arm_arch3m"
1527 (define_insn "*mulsidi3_nov6"
1528 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1530 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1531 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1532 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1533 "smull%?\\t%Q0, %R0, %1, %2"
1534 [(set_attr "type" "smull")
1535 (set_attr "predicable" "yes")]
1538 (define_insn "*mulsidi3_v6"
1539 [(set (match_operand:DI 0 "s_register_operand" "=r")
1541 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1542 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1543 "TARGET_32BIT && arm_arch6"
1544 "smull%?\\t%Q0, %R0, %1, %2"
1545 [(set_attr "type" "smull")
1546 (set_attr "predicable" "yes")
1547 (set_attr "predicable_short_it" "no")]
1550 (define_expand "umulsidi3"
1551 [(set (match_operand:DI 0 "s_register_operand" "")
1553 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1554 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1555 "TARGET_32BIT && arm_arch3m"
1559 (define_insn "*umulsidi3_nov6"
1560 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1562 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1563 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1564 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1565 "umull%?\\t%Q0, %R0, %1, %2"
1566 [(set_attr "type" "umull")
1567 (set_attr "predicable" "yes")]
1570 (define_insn "*umulsidi3_v6"
1571 [(set (match_operand:DI 0 "s_register_operand" "=r")
1573 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1574 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1575 "TARGET_32BIT && arm_arch6"
1576 "umull%?\\t%Q0, %R0, %1, %2"
1577 [(set_attr "type" "umull")
1578 (set_attr "predicable" "yes")
1579 (set_attr "predicable_short_it" "no")]
1582 (define_expand "umaddsidi4"
1583 [(set (match_operand:DI 0 "s_register_operand" "")
1586 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1587 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1588 (match_operand:DI 3 "s_register_operand" "")))]
1589 "TARGET_32BIT && arm_arch3m"
1592 (define_insn "*umulsidi3adddi"
1593 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1596 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1597 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1598 (match_operand:DI 1 "s_register_operand" "0")))]
1599 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1600 "umlal%?\\t%Q0, %R0, %3, %2"
1601 [(set_attr "type" "umlal")
1602 (set_attr "predicable" "yes")]
1605 (define_insn "*umulsidi3adddi_v6"
1606 [(set (match_operand:DI 0 "s_register_operand" "=r")
1609 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1610 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1611 (match_operand:DI 1 "s_register_operand" "0")))]
1612 "TARGET_32BIT && arm_arch6"
1613 "umlal%?\\t%Q0, %R0, %3, %2"
1614 [(set_attr "type" "umlal")
1615 (set_attr "predicable" "yes")
1616 (set_attr "predicable_short_it" "no")]
1619 (define_expand "smulsi3_highpart"
1621 [(set (match_operand:SI 0 "s_register_operand" "")
1625 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1626 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1628 (clobber (match_scratch:SI 3 ""))])]
1629 "TARGET_32BIT && arm_arch3m"
1633 (define_insn "*smulsi3_highpart_nov6"
1634 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1638 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1639 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1641 (clobber (match_scratch:SI 3 "=&r,&r"))]
1642 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1643 "smull%?\\t%3, %0, %2, %1"
1644 [(set_attr "type" "smull")
1645 (set_attr "predicable" "yes")]
1648 (define_insn "*smulsi3_highpart_v6"
1649 [(set (match_operand:SI 0 "s_register_operand" "=r")
1653 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1654 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1656 (clobber (match_scratch:SI 3 "=r"))]
1657 "TARGET_32BIT && arm_arch6"
1658 "smull%?\\t%3, %0, %2, %1"
1659 [(set_attr "type" "smull")
1660 (set_attr "predicable" "yes")
1661 (set_attr "predicable_short_it" "no")]
1664 (define_expand "umulsi3_highpart"
1666 [(set (match_operand:SI 0 "s_register_operand" "")
1670 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1671 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1673 (clobber (match_scratch:SI 3 ""))])]
1674 "TARGET_32BIT && arm_arch3m"
1678 (define_insn "*umulsi3_highpart_nov6"
1679 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1683 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1684 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1686 (clobber (match_scratch:SI 3 "=&r,&r"))]
1687 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1688 "umull%?\\t%3, %0, %2, %1"
1689 [(set_attr "type" "umull")
1690 (set_attr "predicable" "yes")]
1693 (define_insn "*umulsi3_highpart_v6"
1694 [(set (match_operand:SI 0 "s_register_operand" "=r")
1698 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1699 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1701 (clobber (match_scratch:SI 3 "=r"))]
1702 "TARGET_32BIT && arm_arch6"
1703 "umull%?\\t%3, %0, %2, %1"
1704 [(set_attr "type" "umull")
1705 (set_attr "predicable" "yes")
1706 (set_attr "predicable_short_it" "no")]
1709 (define_insn "mulhisi3"
1710 [(set (match_operand:SI 0 "s_register_operand" "=r")
1711 (mult:SI (sign_extend:SI
1712 (match_operand:HI 1 "s_register_operand" "%r"))
1714 (match_operand:HI 2 "s_register_operand" "r"))))]
1715 "TARGET_DSP_MULTIPLY"
1716 "smulbb%?\\t%0, %1, %2"
1717 [(set_attr "type" "smulxy")
1718 (set_attr "predicable" "yes")]
1721 (define_insn "*mulhisi3tb"
1722 [(set (match_operand:SI 0 "s_register_operand" "=r")
1723 (mult:SI (ashiftrt:SI
1724 (match_operand:SI 1 "s_register_operand" "r")
1727 (match_operand:HI 2 "s_register_operand" "r"))))]
1728 "TARGET_DSP_MULTIPLY"
1729 "smultb%?\\t%0, %1, %2"
1730 [(set_attr "type" "smulxy")
1731 (set_attr "predicable" "yes")
1732 (set_attr "predicable_short_it" "no")]
1735 (define_insn "*mulhisi3bt"
1736 [(set (match_operand:SI 0 "s_register_operand" "=r")
1737 (mult:SI (sign_extend:SI
1738 (match_operand:HI 1 "s_register_operand" "r"))
1740 (match_operand:SI 2 "s_register_operand" "r")
1742 "TARGET_DSP_MULTIPLY"
1743 "smulbt%?\\t%0, %1, %2"
1744 [(set_attr "type" "smulxy")
1745 (set_attr "predicable" "yes")
1746 (set_attr "predicable_short_it" "no")]
1749 (define_insn "*mulhisi3tt"
1750 [(set (match_operand:SI 0 "s_register_operand" "=r")
1751 (mult:SI (ashiftrt:SI
1752 (match_operand:SI 1 "s_register_operand" "r")
1755 (match_operand:SI 2 "s_register_operand" "r")
1757 "TARGET_DSP_MULTIPLY"
1758 "smultt%?\\t%0, %1, %2"
1759 [(set_attr "type" "smulxy")
1760 (set_attr "predicable" "yes")
1761 (set_attr "predicable_short_it" "no")]
1764 (define_insn "maddhisi4"
1765 [(set (match_operand:SI 0 "s_register_operand" "=r")
1766 (plus:SI (mult:SI (sign_extend:SI
1767 (match_operand:HI 1 "s_register_operand" "r"))
1769 (match_operand:HI 2 "s_register_operand" "r")))
1770 (match_operand:SI 3 "s_register_operand" "r")))]
1771 "TARGET_DSP_MULTIPLY"
1772 "smlabb%?\\t%0, %1, %2, %3"
1773 [(set_attr "type" "smlaxy")
1774 (set_attr "predicable" "yes")
1775 (set_attr "predicable_short_it" "no")]
1778 ;; Note: there is no maddhisi4ibt because this one is canonical form
1779 (define_insn "*maddhisi4tb"
1780 [(set (match_operand:SI 0 "s_register_operand" "=r")
1781 (plus:SI (mult:SI (ashiftrt:SI
1782 (match_operand:SI 1 "s_register_operand" "r")
1785 (match_operand:HI 2 "s_register_operand" "r")))
1786 (match_operand:SI 3 "s_register_operand" "r")))]
1787 "TARGET_DSP_MULTIPLY"
1788 "smlatb%?\\t%0, %1, %2, %3"
1789 [(set_attr "type" "smlaxy")
1790 (set_attr "predicable" "yes")
1791 (set_attr "predicable_short_it" "no")]
1794 (define_insn "*maddhisi4tt"
1795 [(set (match_operand:SI 0 "s_register_operand" "=r")
1796 (plus:SI (mult:SI (ashiftrt:SI
1797 (match_operand:SI 1 "s_register_operand" "r")
1800 (match_operand:SI 2 "s_register_operand" "r")
1802 (match_operand:SI 3 "s_register_operand" "r")))]
1803 "TARGET_DSP_MULTIPLY"
1804 "smlatt%?\\t%0, %1, %2, %3"
1805 [(set_attr "type" "smlaxy")
1806 (set_attr "predicable" "yes")
1807 (set_attr "predicable_short_it" "no")]
1810 (define_insn "maddhidi4"
1811 [(set (match_operand:DI 0 "s_register_operand" "=r")
1813 (mult:DI (sign_extend:DI
1814 (match_operand:HI 1 "s_register_operand" "r"))
1816 (match_operand:HI 2 "s_register_operand" "r")))
1817 (match_operand:DI 3 "s_register_operand" "0")))]
1818 "TARGET_DSP_MULTIPLY"
1819 "smlalbb%?\\t%Q0, %R0, %1, %2"
1820 [(set_attr "type" "smlalxy")
1821 (set_attr "predicable" "yes")
1822 (set_attr "predicable_short_it" "no")])
1824 ;; Note: there is no maddhidi4ibt because this one is canonical form
1825 (define_insn "*maddhidi4tb"
1826 [(set (match_operand:DI 0 "s_register_operand" "=r")
1828 (mult:DI (sign_extend:DI
1830 (match_operand:SI 1 "s_register_operand" "r")
1833 (match_operand:HI 2 "s_register_operand" "r")))
1834 (match_operand:DI 3 "s_register_operand" "0")))]
1835 "TARGET_DSP_MULTIPLY"
1836 "smlaltb%?\\t%Q0, %R0, %1, %2"
1837 [(set_attr "type" "smlalxy")
1838 (set_attr "predicable" "yes")
1839 (set_attr "predicable_short_it" "no")])
1841 (define_insn "*maddhidi4tt"
1842 [(set (match_operand:DI 0 "s_register_operand" "=r")
1844 (mult:DI (sign_extend:DI
1846 (match_operand:SI 1 "s_register_operand" "r")
1850 (match_operand:SI 2 "s_register_operand" "r")
1852 (match_operand:DI 3 "s_register_operand" "0")))]
1853 "TARGET_DSP_MULTIPLY"
1854 "smlaltt%?\\t%Q0, %R0, %1, %2"
1855 [(set_attr "type" "smlalxy")
1856 (set_attr "predicable" "yes")
1857 (set_attr "predicable_short_it" "no")])
1859 (define_expand "mulsf3"
1860 [(set (match_operand:SF 0 "s_register_operand" "")
1861 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1862 (match_operand:SF 2 "s_register_operand" "")))]
1863 "TARGET_32BIT && TARGET_HARD_FLOAT"
1867 (define_expand "muldf3"
1868 [(set (match_operand:DF 0 "s_register_operand" "")
1869 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1870 (match_operand:DF 2 "s_register_operand" "")))]
1871 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1877 (define_expand "divsf3"
1878 [(set (match_operand:SF 0 "s_register_operand" "")
1879 (div:SF (match_operand:SF 1 "s_register_operand" "")
1880 (match_operand:SF 2 "s_register_operand" "")))]
1881 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1884 (define_expand "divdf3"
1885 [(set (match_operand:DF 0 "s_register_operand" "")
1886 (div:DF (match_operand:DF 1 "s_register_operand" "")
1887 (match_operand:DF 2 "s_register_operand" "")))]
1888 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1891 ;; Boolean and,ior,xor insns
1893 ;; Split up double word logical operations
1895 ;; Split up simple DImode logical operations. Simply perform the logical
1896 ;; operation on the upper and lower halves of the registers.
1898 [(set (match_operand:DI 0 "s_register_operand" "")
1899 (match_operator:DI 6 "logical_binary_operator"
1900 [(match_operand:DI 1 "s_register_operand" "")
1901 (match_operand:DI 2 "s_register_operand" "")]))]
1902 "TARGET_32BIT && reload_completed
1903 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1904 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1905 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1906 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1909 operands[3] = gen_highpart (SImode, operands[0]);
1910 operands[0] = gen_lowpart (SImode, operands[0]);
1911 operands[4] = gen_highpart (SImode, operands[1]);
1912 operands[1] = gen_lowpart (SImode, operands[1]);
1913 operands[5] = gen_highpart (SImode, operands[2]);
1914 operands[2] = gen_lowpart (SImode, operands[2]);
1919 [(set (match_operand:DI 0 "s_register_operand" "")
1920 (match_operator:DI 6 "logical_binary_operator"
1921 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1922 (match_operand:DI 1 "s_register_operand" "")]))]
1923 "TARGET_32BIT && reload_completed"
1924 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1925 (set (match_dup 3) (match_op_dup:SI 6
1926 [(ashiftrt:SI (match_dup 2) (const_int 31))
1930 operands[3] = gen_highpart (SImode, operands[0]);
1931 operands[0] = gen_lowpart (SImode, operands[0]);
1932 operands[4] = gen_highpart (SImode, operands[1]);
1933 operands[1] = gen_lowpart (SImode, operands[1]);
1934 operands[5] = gen_highpart (SImode, operands[2]);
1935 operands[2] = gen_lowpart (SImode, operands[2]);
1939 ;; The zero extend of operand 2 means we can just copy the high part of
1940 ;; operand1 into operand0.
1942 [(set (match_operand:DI 0 "s_register_operand" "")
1944 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1945 (match_operand:DI 1 "s_register_operand" "")))]
1946 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1947 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1948 (set (match_dup 3) (match_dup 4))]
1951 operands[4] = gen_highpart (SImode, operands[1]);
1952 operands[3] = gen_highpart (SImode, operands[0]);
1953 operands[0] = gen_lowpart (SImode, operands[0]);
1954 operands[1] = gen_lowpart (SImode, operands[1]);
1958 ;; The zero extend of operand 2 means we can just copy the high part of
1959 ;; operand1 into operand0.
1961 [(set (match_operand:DI 0 "s_register_operand" "")
1963 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1964 (match_operand:DI 1 "s_register_operand" "")))]
1965 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1966 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1967 (set (match_dup 3) (match_dup 4))]
1970 operands[4] = gen_highpart (SImode, operands[1]);
1971 operands[3] = gen_highpart (SImode, operands[0]);
1972 operands[0] = gen_lowpart (SImode, operands[0]);
1973 operands[1] = gen_lowpart (SImode, operands[1]);
1977 (define_expand "anddi3"
1978 [(set (match_operand:DI 0 "s_register_operand" "")
1979 (and:DI (match_operand:DI 1 "s_register_operand" "")
1980 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
1985 (define_insn_and_split "*anddi3_insn"
1986 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
1987 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
1988 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
1989 "TARGET_32BIT && !TARGET_IWMMXT"
1991 switch (which_alternative)
1993 case 0: /* fall through */
1994 case 6: return "vand\t%P0, %P1, %P2";
1995 case 1: /* fall through */
1996 case 7: return neon_output_logic_immediate ("vand", &operands[2],
1997 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2001 case 5: /* fall through */
2003 default: gcc_unreachable ();
2006 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2007 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2008 [(set (match_dup 3) (match_dup 4))
2009 (set (match_dup 5) (match_dup 6))]
2012 operands[3] = gen_lowpart (SImode, operands[0]);
2013 operands[5] = gen_highpart (SImode, operands[0]);
2015 operands[4] = simplify_gen_binary (AND, SImode,
2016 gen_lowpart (SImode, operands[1]),
2017 gen_lowpart (SImode, operands[2]));
2018 operands[6] = simplify_gen_binary (AND, SImode,
2019 gen_highpart (SImode, operands[1]),
2020 gen_highpart_mode (SImode, DImode, operands[2]));
2023 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2024 multiple,multiple,neon_logic,neon_logic")
2025 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2026 avoid_neon_for_64bits,avoid_neon_for_64bits")
2027 (set_attr "length" "*,*,8,8,8,8,*,*")
2031 (define_insn_and_split "*anddi_zesidi_di"
2032 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2033 (and:DI (zero_extend:DI
2034 (match_operand:SI 2 "s_register_operand" "r,r"))
2035 (match_operand:DI 1 "s_register_operand" "0,r")))]
2038 "TARGET_32BIT && reload_completed"
2039 ; The zero extend of operand 2 clears the high word of the output
2041 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2042 (set (match_dup 3) (const_int 0))]
2045 operands[3] = gen_highpart (SImode, operands[0]);
2046 operands[0] = gen_lowpart (SImode, operands[0]);
2047 operands[1] = gen_lowpart (SImode, operands[1]);
2049 [(set_attr "length" "8")
2050 (set_attr "type" "multiple")]
2053 (define_insn "*anddi_sesdi_di"
2054 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2055 (and:DI (sign_extend:DI
2056 (match_operand:SI 2 "s_register_operand" "r,r"))
2057 (match_operand:DI 1 "s_register_operand" "0,r")))]
2060 [(set_attr "length" "8")
2061 (set_attr "type" "multiple")]
2064 (define_expand "andsi3"
2065 [(set (match_operand:SI 0 "s_register_operand" "")
2066 (and:SI (match_operand:SI 1 "s_register_operand" "")
2067 (match_operand:SI 2 "reg_or_int_operand" "")))]
2072 if (CONST_INT_P (operands[2]))
2074 if (INTVAL (operands[2]) == 255 && arm_arch6)
2076 operands[1] = convert_to_mode (QImode, operands[1], 1);
2077 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2081 arm_split_constant (AND, SImode, NULL_RTX,
2082 INTVAL (operands[2]), operands[0],
2084 optimize && can_create_pseudo_p ());
2089 else /* TARGET_THUMB1 */
2091 if (!CONST_INT_P (operands[2]))
2093 rtx tmp = force_reg (SImode, operands[2]);
2094 if (rtx_equal_p (operands[0], operands[1]))
2098 operands[2] = operands[1];
2106 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2108 operands[2] = force_reg (SImode,
2109 GEN_INT (~INTVAL (operands[2])));
2111 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2116 for (i = 9; i <= 31; i++)
2118 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2120 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2124 else if ((((HOST_WIDE_INT) 1) << i) - 1
2125 == ~INTVAL (operands[2]))
2127 rtx shift = GEN_INT (i);
2128 rtx reg = gen_reg_rtx (SImode);
2130 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2131 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2137 operands[2] = force_reg (SImode, operands[2]);
2143 ; ??? Check split length for Thumb-2
2144 (define_insn_and_split "*arm_andsi3_insn"
2145 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2146 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2147 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2152 bic%?\\t%0, %1, #%B2
2156 && CONST_INT_P (operands[2])
2157 && !(const_ok_for_arm (INTVAL (operands[2]))
2158 || const_ok_for_arm (~INTVAL (operands[2])))"
2159 [(clobber (const_int 0))]
2161 arm_split_constant (AND, SImode, curr_insn,
2162 INTVAL (operands[2]), operands[0], operands[1], 0);
2165 [(set_attr "length" "4,4,4,4,16")
2166 (set_attr "predicable" "yes")
2167 (set_attr "predicable_short_it" "no,yes,no,no,no")
2168 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2171 (define_insn "*andsi3_compare0"
2172 [(set (reg:CC_NOOV CC_REGNUM)
2174 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2175 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2177 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2178 (and:SI (match_dup 1) (match_dup 2)))]
2182 bic%.\\t%0, %1, #%B2
2184 [(set_attr "conds" "set")
2185 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2188 (define_insn "*andsi3_compare0_scratch"
2189 [(set (reg:CC_NOOV CC_REGNUM)
2191 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2192 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2194 (clobber (match_scratch:SI 2 "=X,r,X"))]
2198 bic%.\\t%2, %0, #%B1
2200 [(set_attr "conds" "set")
2201 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2204 (define_insn "*zeroextractsi_compare0_scratch"
2205 [(set (reg:CC_NOOV CC_REGNUM)
2206 (compare:CC_NOOV (zero_extract:SI
2207 (match_operand:SI 0 "s_register_operand" "r")
2208 (match_operand 1 "const_int_operand" "n")
2209 (match_operand 2 "const_int_operand" "n"))
2212 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2213 && INTVAL (operands[1]) > 0
2214 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2215 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2217 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2218 << INTVAL (operands[2]));
2219 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2222 [(set_attr "conds" "set")
2223 (set_attr "predicable" "yes")
2224 (set_attr "predicable_short_it" "no")
2225 (set_attr "type" "logics_imm")]
2228 (define_insn_and_split "*ne_zeroextractsi"
2229 [(set (match_operand:SI 0 "s_register_operand" "=r")
2230 (ne:SI (zero_extract:SI
2231 (match_operand:SI 1 "s_register_operand" "r")
2232 (match_operand:SI 2 "const_int_operand" "n")
2233 (match_operand:SI 3 "const_int_operand" "n"))
2235 (clobber (reg:CC CC_REGNUM))]
2237 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2238 && INTVAL (operands[2]) > 0
2239 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2240 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2243 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2244 && INTVAL (operands[2]) > 0
2245 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2246 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2247 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2248 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2250 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2252 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2253 (match_dup 0) (const_int 1)))]
2255 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2256 << INTVAL (operands[3]));
2258 [(set_attr "conds" "clob")
2259 (set (attr "length")
2260 (if_then_else (eq_attr "is_thumb" "yes")
2263 (set_attr "type" "multiple")]
2266 (define_insn_and_split "*ne_zeroextractsi_shifted"
2267 [(set (match_operand:SI 0 "s_register_operand" "=r")
2268 (ne:SI (zero_extract:SI
2269 (match_operand:SI 1 "s_register_operand" "r")
2270 (match_operand:SI 2 "const_int_operand" "n")
2273 (clobber (reg:CC CC_REGNUM))]
2277 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2278 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2280 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2282 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2283 (match_dup 0) (const_int 1)))]
2285 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2287 [(set_attr "conds" "clob")
2288 (set_attr "length" "8")
2289 (set_attr "type" "multiple")]
2292 (define_insn_and_split "*ite_ne_zeroextractsi"
2293 [(set (match_operand:SI 0 "s_register_operand" "=r")
2294 (if_then_else:SI (ne (zero_extract:SI
2295 (match_operand:SI 1 "s_register_operand" "r")
2296 (match_operand:SI 2 "const_int_operand" "n")
2297 (match_operand:SI 3 "const_int_operand" "n"))
2299 (match_operand:SI 4 "arm_not_operand" "rIK")
2301 (clobber (reg:CC CC_REGNUM))]
2303 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2304 && INTVAL (operands[2]) > 0
2305 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2306 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2307 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2310 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2311 && INTVAL (operands[2]) > 0
2312 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2313 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2314 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2315 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2316 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2318 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2320 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2321 (match_dup 0) (match_dup 4)))]
2323 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2324 << INTVAL (operands[3]));
2326 [(set_attr "conds" "clob")
2327 (set_attr "length" "8")
2328 (set_attr "type" "multiple")]
2331 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2332 [(set (match_operand:SI 0 "s_register_operand" "=r")
2333 (if_then_else:SI (ne (zero_extract:SI
2334 (match_operand:SI 1 "s_register_operand" "r")
2335 (match_operand:SI 2 "const_int_operand" "n")
2338 (match_operand:SI 3 "arm_not_operand" "rIK")
2340 (clobber (reg:CC CC_REGNUM))]
2341 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2343 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2344 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2345 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2347 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2349 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2350 (match_dup 0) (match_dup 3)))]
2352 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2354 [(set_attr "conds" "clob")
2355 (set_attr "length" "8")
2356 (set_attr "type" "multiple")]
2359 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2361 [(set (match_operand:SI 0 "s_register_operand" "")
2362 (match_operator:SI 1 "shiftable_operator"
2363 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2364 (match_operand:SI 3 "const_int_operand" "")
2365 (match_operand:SI 4 "const_int_operand" ""))
2366 (match_operand:SI 5 "s_register_operand" "")]))
2367 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2369 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2372 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2375 HOST_WIDE_INT temp = INTVAL (operands[3]);
2377 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2378 operands[4] = GEN_INT (32 - temp);
2383 [(set (match_operand:SI 0 "s_register_operand" "")
2384 (match_operator:SI 1 "shiftable_operator"
2385 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2386 (match_operand:SI 3 "const_int_operand" "")
2387 (match_operand:SI 4 "const_int_operand" ""))
2388 (match_operand:SI 5 "s_register_operand" "")]))
2389 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2391 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2394 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2397 HOST_WIDE_INT temp = INTVAL (operands[3]);
2399 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2400 operands[4] = GEN_INT (32 - temp);
2404 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2405 ;;; represented by the bitfield, then this will produce incorrect results.
2406 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2407 ;;; which have a real bit-field insert instruction, the truncation happens
2408 ;;; in the bit-field insert instruction itself. Since arm does not have a
2409 ;;; bit-field insert instruction, we would have to emit code here to truncate
2410 ;;; the value before we insert. This loses some of the advantage of having
2411 ;;; this insv pattern, so this pattern needs to be reevalutated.
2413 (define_expand "insv"
2414 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2415 (match_operand 1 "general_operand" "")
2416 (match_operand 2 "general_operand" ""))
2417 (match_operand 3 "reg_or_int_operand" ""))]
2418 "TARGET_ARM || arm_arch_thumb2"
2421 int start_bit = INTVAL (operands[2]);
2422 int width = INTVAL (operands[1]);
2423 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2424 rtx target, subtarget;
2426 if (arm_arch_thumb2)
2428 if (unaligned_access && MEM_P (operands[0])
2429 && s_register_operand (operands[3], GET_MODE (operands[3]))
2430 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2434 if (BYTES_BIG_ENDIAN)
2435 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2440 base_addr = adjust_address (operands[0], SImode,
2441 start_bit / BITS_PER_UNIT);
2442 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2446 rtx tmp = gen_reg_rtx (HImode);
2448 base_addr = adjust_address (operands[0], HImode,
2449 start_bit / BITS_PER_UNIT);
2450 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2451 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2455 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2457 bool use_bfi = TRUE;
2459 if (CONST_INT_P (operands[3]))
2461 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2465 emit_insn (gen_insv_zero (operands[0], operands[1],
2470 /* See if the set can be done with a single orr instruction. */
2471 if (val == mask && const_ok_for_arm (val << start_bit))
2477 if (!REG_P (operands[3]))
2478 operands[3] = force_reg (SImode, operands[3]);
2480 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2489 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2492 target = copy_rtx (operands[0]);
2493 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2494 subreg as the final target. */
2495 if (GET_CODE (target) == SUBREG)
2497 subtarget = gen_reg_rtx (SImode);
2498 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2499 < GET_MODE_SIZE (SImode))
2500 target = SUBREG_REG (target);
2505 if (CONST_INT_P (operands[3]))
2507 /* Since we are inserting a known constant, we may be able to
2508 reduce the number of bits that we have to clear so that
2509 the mask becomes simple. */
2510 /* ??? This code does not check to see if the new mask is actually
2511 simpler. It may not be. */
2512 rtx op1 = gen_reg_rtx (SImode);
2513 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2514 start of this pattern. */
2515 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2516 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2518 emit_insn (gen_andsi3 (op1, operands[0],
2519 gen_int_mode (~mask2, SImode)));
2520 emit_insn (gen_iorsi3 (subtarget, op1,
2521 gen_int_mode (op3_value << start_bit, SImode)));
2523 else if (start_bit == 0
2524 && !(const_ok_for_arm (mask)
2525 || const_ok_for_arm (~mask)))
2527 /* A Trick, since we are setting the bottom bits in the word,
2528 we can shift operand[3] up, operand[0] down, OR them together
2529 and rotate the result back again. This takes 3 insns, and
2530 the third might be mergeable into another op. */
2531 /* The shift up copes with the possibility that operand[3] is
2532 wider than the bitfield. */
2533 rtx op0 = gen_reg_rtx (SImode);
2534 rtx op1 = gen_reg_rtx (SImode);
2536 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2537 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2538 emit_insn (gen_iorsi3 (op1, op1, op0));
2539 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2541 else if ((width + start_bit == 32)
2542 && !(const_ok_for_arm (mask)
2543 || const_ok_for_arm (~mask)))
2545 /* Similar trick, but slightly less efficient. */
2547 rtx op0 = gen_reg_rtx (SImode);
2548 rtx op1 = gen_reg_rtx (SImode);
2550 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2551 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2552 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2553 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2557 rtx op0 = gen_int_mode (mask, SImode);
2558 rtx op1 = gen_reg_rtx (SImode);
2559 rtx op2 = gen_reg_rtx (SImode);
2561 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2563 rtx tmp = gen_reg_rtx (SImode);
2565 emit_insn (gen_movsi (tmp, op0));
2569 /* Mask out any bits in operand[3] that are not needed. */
2570 emit_insn (gen_andsi3 (op1, operands[3], op0));
2572 if (CONST_INT_P (op0)
2573 && (const_ok_for_arm (mask << start_bit)
2574 || const_ok_for_arm (~(mask << start_bit))))
2576 op0 = gen_int_mode (~(mask << start_bit), SImode);
2577 emit_insn (gen_andsi3 (op2, operands[0], op0));
2581 if (CONST_INT_P (op0))
2583 rtx tmp = gen_reg_rtx (SImode);
2585 emit_insn (gen_movsi (tmp, op0));
2590 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2592 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2596 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2598 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2601 if (subtarget != target)
2603 /* If TARGET is still a SUBREG, then it must be wider than a word,
2604 so we must be careful only to set the subword we were asked to. */
2605 if (GET_CODE (target) == SUBREG)
2606 emit_move_insn (target, subtarget);
2608 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2615 (define_insn "insv_zero"
2616 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2617 (match_operand:SI 1 "const_int_M_operand" "M")
2618 (match_operand:SI 2 "const_int_M_operand" "M"))
2622 [(set_attr "length" "4")
2623 (set_attr "predicable" "yes")
2624 (set_attr "predicable_short_it" "no")
2625 (set_attr "type" "bfm")]
2628 (define_insn "insv_t2"
2629 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2630 (match_operand:SI 1 "const_int_M_operand" "M")
2631 (match_operand:SI 2 "const_int_M_operand" "M"))
2632 (match_operand:SI 3 "s_register_operand" "r"))]
2634 "bfi%?\t%0, %3, %2, %1"
2635 [(set_attr "length" "4")
2636 (set_attr "predicable" "yes")
2637 (set_attr "predicable_short_it" "no")
2638 (set_attr "type" "bfm")]
2641 ; constants for op 2 will never be given to these patterns.
2642 (define_insn_and_split "*anddi_notdi_di"
2643 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2644 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2645 (match_operand:DI 2 "s_register_operand" "r,0")))]
2648 "TARGET_32BIT && reload_completed
2649 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2650 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2651 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2652 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2655 operands[3] = gen_highpart (SImode, operands[0]);
2656 operands[0] = gen_lowpart (SImode, operands[0]);
2657 operands[4] = gen_highpart (SImode, operands[1]);
2658 operands[1] = gen_lowpart (SImode, operands[1]);
2659 operands[5] = gen_highpart (SImode, operands[2]);
2660 operands[2] = gen_lowpart (SImode, operands[2]);
2662 [(set_attr "length" "8")
2663 (set_attr "predicable" "yes")
2664 (set_attr "type" "multiple")]
2667 (define_insn_and_split "*anddi_notzesidi_di"
2668 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2669 (and:DI (not:DI (zero_extend:DI
2670 (match_operand:SI 2 "s_register_operand" "r,r")))
2671 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2674 bic%?\\t%Q0, %Q1, %2
2676 ; (not (zero_extend ...)) allows us to just copy the high word from
2677 ; operand1 to operand0.
2680 && operands[0] != operands[1]"
2681 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2682 (set (match_dup 3) (match_dup 4))]
2685 operands[3] = gen_highpart (SImode, operands[0]);
2686 operands[0] = gen_lowpart (SImode, operands[0]);
2687 operands[4] = gen_highpart (SImode, operands[1]);
2688 operands[1] = gen_lowpart (SImode, operands[1]);
2690 [(set_attr "length" "4,8")
2691 (set_attr "predicable" "yes")
2692 (set_attr "predicable_short_it" "no")
2693 (set_attr "type" "multiple")]
2696 (define_insn_and_split "*anddi_notdi_zesidi"
2697 [(set (match_operand:DI 0 "s_register_operand" "=r")
2698 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2700 (match_operand:SI 1 "s_register_operand" "r"))))]
2703 "TARGET_32BIT && reload_completed"
2704 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2705 (set (match_dup 3) (const_int 0))]
2708 operands[3] = gen_highpart (SImode, operands[0]);
2709 operands[0] = gen_lowpart (SImode, operands[0]);
2710 operands[2] = gen_lowpart (SImode, operands[2]);
2712 [(set_attr "length" "8")
2713 (set_attr "predicable" "yes")
2714 (set_attr "predicable_short_it" "no")
2715 (set_attr "type" "multiple")]
2718 (define_insn_and_split "*anddi_notsesidi_di"
2719 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2720 (and:DI (not:DI (sign_extend:DI
2721 (match_operand:SI 2 "s_register_operand" "r,r")))
2722 (match_operand:DI 1 "s_register_operand" "0,r")))]
2725 "TARGET_32BIT && reload_completed"
2726 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2727 (set (match_dup 3) (and:SI (not:SI
2728 (ashiftrt:SI (match_dup 2) (const_int 31)))
2732 operands[3] = gen_highpart (SImode, operands[0]);
2733 operands[0] = gen_lowpart (SImode, operands[0]);
2734 operands[4] = gen_highpart (SImode, operands[1]);
2735 operands[1] = gen_lowpart (SImode, operands[1]);
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 "andsi_notsi_si"
2744 [(set (match_operand:SI 0 "s_register_operand" "=r")
2745 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2746 (match_operand:SI 1 "s_register_operand" "r")))]
2748 "bic%?\\t%0, %1, %2"
2749 [(set_attr "predicable" "yes")
2750 (set_attr "predicable_short_it" "no")
2751 (set_attr "type" "logic_reg")]
2754 (define_insn "andsi_not_shiftsi_si"
2755 [(set (match_operand:SI 0 "s_register_operand" "=r")
2756 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2757 [(match_operand:SI 2 "s_register_operand" "r")
2758 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2759 (match_operand:SI 1 "s_register_operand" "r")))]
2761 "bic%?\\t%0, %1, %2%S4"
2762 [(set_attr "predicable" "yes")
2763 (set_attr "shift" "2")
2764 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2765 (const_string "logic_shift_imm")
2766 (const_string "logic_shift_reg")))]
2769 (define_insn "*andsi_notsi_si_compare0"
2770 [(set (reg:CC_NOOV CC_REGNUM)
2772 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2773 (match_operand:SI 1 "s_register_operand" "r"))
2775 (set (match_operand:SI 0 "s_register_operand" "=r")
2776 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2778 "bic%.\\t%0, %1, %2"
2779 [(set_attr "conds" "set")
2780 (set_attr "type" "logics_shift_reg")]
2783 (define_insn "*andsi_notsi_si_compare0_scratch"
2784 [(set (reg:CC_NOOV CC_REGNUM)
2786 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2787 (match_operand:SI 1 "s_register_operand" "r"))
2789 (clobber (match_scratch:SI 0 "=r"))]
2791 "bic%.\\t%0, %1, %2"
2792 [(set_attr "conds" "set")
2793 (set_attr "type" "logics_shift_reg")]
2796 (define_expand "iordi3"
2797 [(set (match_operand:DI 0 "s_register_operand" "")
2798 (ior:DI (match_operand:DI 1 "s_register_operand" "")
2799 (match_operand:DI 2 "neon_logic_op2" "")))]
2804 (define_insn_and_split "*iordi3_insn"
2805 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2806 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2807 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
2808 "TARGET_32BIT && !TARGET_IWMMXT"
2810 switch (which_alternative)
2812 case 0: /* fall through */
2813 case 6: return "vorr\t%P0, %P1, %P2";
2814 case 1: /* fall through */
2815 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2816 DImode, 0, VALID_NEON_QREG_MODE (DImode));
2822 default: gcc_unreachable ();
2825 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2826 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2827 [(set (match_dup 3) (match_dup 4))
2828 (set (match_dup 5) (match_dup 6))]
2831 operands[3] = gen_lowpart (SImode, operands[0]);
2832 operands[5] = gen_highpart (SImode, operands[0]);
2834 operands[4] = simplify_gen_binary (IOR, SImode,
2835 gen_lowpart (SImode, operands[1]),
2836 gen_lowpart (SImode, operands[2]));
2837 operands[6] = simplify_gen_binary (IOR, SImode,
2838 gen_highpart (SImode, operands[1]),
2839 gen_highpart_mode (SImode, DImode, operands[2]));
2842 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2843 multiple,neon_logic,neon_logic")
2844 (set_attr "length" "*,*,8,8,8,8,*,*")
2845 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
2848 (define_insn "*iordi_zesidi_di"
2849 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2850 (ior:DI (zero_extend:DI
2851 (match_operand:SI 2 "s_register_operand" "r,r"))
2852 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2855 orr%?\\t%Q0, %Q1, %2
2857 [(set_attr "length" "4,8")
2858 (set_attr "predicable" "yes")
2859 (set_attr "predicable_short_it" "no")
2860 (set_attr "type" "logic_reg,multiple")]
2863 (define_insn "*iordi_sesidi_di"
2864 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2865 (ior:DI (sign_extend:DI
2866 (match_operand:SI 2 "s_register_operand" "r,r"))
2867 (match_operand:DI 1 "s_register_operand" "0,r")))]
2870 [(set_attr "length" "8")
2871 (set_attr "predicable" "yes")
2872 (set_attr "type" "multiple")]
2875 (define_expand "iorsi3"
2876 [(set (match_operand:SI 0 "s_register_operand" "")
2877 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2878 (match_operand:SI 2 "reg_or_int_operand" "")))]
2881 if (CONST_INT_P (operands[2]))
2885 arm_split_constant (IOR, SImode, NULL_RTX,
2886 INTVAL (operands[2]), operands[0], operands[1],
2887 optimize && can_create_pseudo_p ());
2890 else /* TARGET_THUMB1 */
2892 rtx tmp = force_reg (SImode, operands[2]);
2893 if (rtx_equal_p (operands[0], operands[1]))
2897 operands[2] = operands[1];
2905 (define_insn_and_split "*iorsi3_insn"
2906 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2907 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2908 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2913 orn%?\\t%0, %1, #%B2
2917 && CONST_INT_P (operands[2])
2918 && !(const_ok_for_arm (INTVAL (operands[2]))
2919 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
2920 [(clobber (const_int 0))]
2922 arm_split_constant (IOR, SImode, curr_insn,
2923 INTVAL (operands[2]), operands[0], operands[1], 0);
2926 [(set_attr "length" "4,4,4,4,16")
2927 (set_attr "arch" "32,t2,t2,32,32")
2928 (set_attr "predicable" "yes")
2929 (set_attr "predicable_short_it" "no,yes,no,no,no")
2930 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
2934 [(match_scratch:SI 3 "r")
2935 (set (match_operand:SI 0 "arm_general_register_operand" "")
2936 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2937 (match_operand:SI 2 "const_int_operand" "")))]
2939 && !const_ok_for_arm (INTVAL (operands[2]))
2940 && const_ok_for_arm (~INTVAL (operands[2]))"
2941 [(set (match_dup 3) (match_dup 2))
2942 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2946 (define_insn "*iorsi3_compare0"
2947 [(set (reg:CC_NOOV CC_REGNUM)
2948 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2949 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
2951 (set (match_operand:SI 0 "s_register_operand" "=r,r")
2952 (ior:SI (match_dup 1) (match_dup 2)))]
2954 "orr%.\\t%0, %1, %2"
2955 [(set_attr "conds" "set")
2956 (set_attr "type" "logics_imm,logics_reg")]
2959 (define_insn "*iorsi3_compare0_scratch"
2960 [(set (reg:CC_NOOV CC_REGNUM)
2961 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2962 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
2964 (clobber (match_scratch:SI 0 "=r,r"))]
2966 "orr%.\\t%0, %1, %2"
2967 [(set_attr "conds" "set")
2968 (set_attr "type" "logics_imm,logics_reg")]
2971 (define_expand "xordi3"
2972 [(set (match_operand:DI 0 "s_register_operand" "")
2973 (xor:DI (match_operand:DI 1 "s_register_operand" "")
2974 (match_operand:DI 2 "arm_xordi_operand" "")))]
2979 (define_insn_and_split "*xordi3_insn"
2980 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
2981 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
2982 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
2983 "TARGET_32BIT && !TARGET_IWMMXT"
2985 switch (which_alternative)
2990 case 4: /* fall through */
2992 case 0: /* fall through */
2993 case 5: return "veor\t%P0, %P1, %P2";
2994 default: gcc_unreachable ();
2997 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2998 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2999 [(set (match_dup 3) (match_dup 4))
3000 (set (match_dup 5) (match_dup 6))]
3003 operands[3] = gen_lowpart (SImode, operands[0]);
3004 operands[5] = gen_highpart (SImode, operands[0]);
3006 operands[4] = simplify_gen_binary (XOR, SImode,
3007 gen_lowpart (SImode, operands[1]),
3008 gen_lowpart (SImode, operands[2]));
3009 operands[6] = simplify_gen_binary (XOR, SImode,
3010 gen_highpart (SImode, operands[1]),
3011 gen_highpart_mode (SImode, DImode, operands[2]));
3014 [(set_attr "length" "*,8,8,8,8,*")
3015 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3016 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3019 (define_insn "*xordi_zesidi_di"
3020 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3021 (xor:DI (zero_extend:DI
3022 (match_operand:SI 2 "s_register_operand" "r,r"))
3023 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3026 eor%?\\t%Q0, %Q1, %2
3028 [(set_attr "length" "4,8")
3029 (set_attr "predicable" "yes")
3030 (set_attr "predicable_short_it" "no")
3031 (set_attr "type" "logic_reg")]
3034 (define_insn "*xordi_sesidi_di"
3035 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3036 (xor:DI (sign_extend:DI
3037 (match_operand:SI 2 "s_register_operand" "r,r"))
3038 (match_operand:DI 1 "s_register_operand" "0,r")))]
3041 [(set_attr "length" "8")
3042 (set_attr "predicable" "yes")
3043 (set_attr "type" "multiple")]
3046 (define_expand "xorsi3"
3047 [(set (match_operand:SI 0 "s_register_operand" "")
3048 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3049 (match_operand:SI 2 "reg_or_int_operand" "")))]
3051 "if (CONST_INT_P (operands[2]))
3055 arm_split_constant (XOR, SImode, NULL_RTX,
3056 INTVAL (operands[2]), operands[0], operands[1],
3057 optimize && can_create_pseudo_p ());
3060 else /* TARGET_THUMB1 */
3062 rtx tmp = force_reg (SImode, operands[2]);
3063 if (rtx_equal_p (operands[0], operands[1]))
3067 operands[2] = operands[1];
3074 (define_insn_and_split "*arm_xorsi3"
3075 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3076 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3077 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3085 && CONST_INT_P (operands[2])
3086 && !const_ok_for_arm (INTVAL (operands[2]))"
3087 [(clobber (const_int 0))]
3089 arm_split_constant (XOR, SImode, curr_insn,
3090 INTVAL (operands[2]), operands[0], operands[1], 0);
3093 [(set_attr "length" "4,4,4,16")
3094 (set_attr "predicable" "yes")
3095 (set_attr "predicable_short_it" "no,yes,no,no")
3096 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3099 (define_insn "*xorsi3_compare0"
3100 [(set (reg:CC_NOOV CC_REGNUM)
3101 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3102 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3104 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3105 (xor:SI (match_dup 1) (match_dup 2)))]
3107 "eor%.\\t%0, %1, %2"
3108 [(set_attr "conds" "set")
3109 (set_attr "type" "logics_imm,logics_reg")]
3112 (define_insn "*xorsi3_compare0_scratch"
3113 [(set (reg:CC_NOOV CC_REGNUM)
3114 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3115 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3119 [(set_attr "conds" "set")
3120 (set_attr "type" "logics_imm,logics_reg")]
3123 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3124 ; (NOT D) we can sometimes merge the final NOT into one of the following
3128 [(set (match_operand:SI 0 "s_register_operand" "")
3129 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3130 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3131 (match_operand:SI 3 "arm_rhs_operand" "")))
3132 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3134 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3135 (not:SI (match_dup 3))))
3136 (set (match_dup 0) (not:SI (match_dup 4)))]
3140 (define_insn_and_split "*andsi_iorsi3_notsi"
3141 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3142 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3143 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3144 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3146 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3147 "&& reload_completed"
3148 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3149 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3151 [(set_attr "length" "8")
3152 (set_attr "ce_count" "2")
3153 (set_attr "predicable" "yes")
3154 (set_attr "predicable_short_it" "no")
3155 (set_attr "type" "multiple")]
3158 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3159 ; insns are available?
3161 [(set (match_operand:SI 0 "s_register_operand" "")
3162 (match_operator:SI 1 "logical_binary_operator"
3163 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3164 (match_operand:SI 3 "const_int_operand" "")
3165 (match_operand:SI 4 "const_int_operand" ""))
3166 (match_operator:SI 9 "logical_binary_operator"
3167 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3168 (match_operand:SI 6 "const_int_operand" ""))
3169 (match_operand:SI 7 "s_register_operand" "")])]))
3170 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3172 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3173 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3176 [(ashift:SI (match_dup 2) (match_dup 4))
3180 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3183 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3187 [(set (match_operand:SI 0 "s_register_operand" "")
3188 (match_operator:SI 1 "logical_binary_operator"
3189 [(match_operator:SI 9 "logical_binary_operator"
3190 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3191 (match_operand:SI 6 "const_int_operand" ""))
3192 (match_operand:SI 7 "s_register_operand" "")])
3193 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3194 (match_operand:SI 3 "const_int_operand" "")
3195 (match_operand:SI 4 "const_int_operand" ""))]))
3196 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3198 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3199 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3202 [(ashift:SI (match_dup 2) (match_dup 4))
3206 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3209 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3213 [(set (match_operand:SI 0 "s_register_operand" "")
3214 (match_operator:SI 1 "logical_binary_operator"
3215 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3216 (match_operand:SI 3 "const_int_operand" "")
3217 (match_operand:SI 4 "const_int_operand" ""))
3218 (match_operator:SI 9 "logical_binary_operator"
3219 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3220 (match_operand:SI 6 "const_int_operand" ""))
3221 (match_operand:SI 7 "s_register_operand" "")])]))
3222 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3224 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3225 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3228 [(ashift:SI (match_dup 2) (match_dup 4))
3232 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3235 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3239 [(set (match_operand:SI 0 "s_register_operand" "")
3240 (match_operator:SI 1 "logical_binary_operator"
3241 [(match_operator:SI 9 "logical_binary_operator"
3242 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3243 (match_operand:SI 6 "const_int_operand" ""))
3244 (match_operand:SI 7 "s_register_operand" "")])
3245 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3246 (match_operand:SI 3 "const_int_operand" "")
3247 (match_operand:SI 4 "const_int_operand" ""))]))
3248 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3250 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3251 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3254 [(ashift:SI (match_dup 2) (match_dup 4))
3258 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3261 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3265 ;; Minimum and maximum insns
3267 (define_expand "smaxsi3"
3269 (set (match_operand:SI 0 "s_register_operand" "")
3270 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3271 (match_operand:SI 2 "arm_rhs_operand" "")))
3272 (clobber (reg:CC CC_REGNUM))])]
3275 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3277 /* No need for a clobber of the condition code register here. */
3278 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3279 gen_rtx_SMAX (SImode, operands[1],
3285 (define_insn "*smax_0"
3286 [(set (match_operand:SI 0 "s_register_operand" "=r")
3287 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3290 "bic%?\\t%0, %1, %1, asr #31"
3291 [(set_attr "predicable" "yes")
3292 (set_attr "predicable_short_it" "no")
3293 (set_attr "type" "logic_shift_reg")]
3296 (define_insn "*smax_m1"
3297 [(set (match_operand:SI 0 "s_register_operand" "=r")
3298 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3301 "orr%?\\t%0, %1, %1, asr #31"
3302 [(set_attr "predicable" "yes")
3303 (set_attr "predicable_short_it" "no")
3304 (set_attr "type" "logic_shift_reg")]
3307 (define_insn_and_split "*arm_smax_insn"
3308 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3309 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3310 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3311 (clobber (reg:CC CC_REGNUM))]
3314 ; cmp\\t%1, %2\;movlt\\t%0, %2
3315 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3317 [(set (reg:CC CC_REGNUM)
3318 (compare:CC (match_dup 1) (match_dup 2)))
3320 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3324 [(set_attr "conds" "clob")
3325 (set_attr "length" "8,12")
3326 (set_attr "type" "multiple")]
3329 (define_expand "sminsi3"
3331 (set (match_operand:SI 0 "s_register_operand" "")
3332 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3333 (match_operand:SI 2 "arm_rhs_operand" "")))
3334 (clobber (reg:CC CC_REGNUM))])]
3337 if (operands[2] == const0_rtx)
3339 /* No need for a clobber of the condition code register here. */
3340 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3341 gen_rtx_SMIN (SImode, operands[1],
3347 (define_insn "*smin_0"
3348 [(set (match_operand:SI 0 "s_register_operand" "=r")
3349 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3352 "and%?\\t%0, %1, %1, asr #31"
3353 [(set_attr "predicable" "yes")
3354 (set_attr "predicable_short_it" "no")
3355 (set_attr "type" "logic_shift_reg")]
3358 (define_insn_and_split "*arm_smin_insn"
3359 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3360 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3361 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3362 (clobber (reg:CC CC_REGNUM))]
3365 ; cmp\\t%1, %2\;movge\\t%0, %2
3366 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3368 [(set (reg:CC CC_REGNUM)
3369 (compare:CC (match_dup 1) (match_dup 2)))
3371 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3375 [(set_attr "conds" "clob")
3376 (set_attr "length" "8,12")
3377 (set_attr "type" "multiple,multiple")]
3380 (define_expand "umaxsi3"
3382 (set (match_operand:SI 0 "s_register_operand" "")
3383 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3384 (match_operand:SI 2 "arm_rhs_operand" "")))
3385 (clobber (reg:CC CC_REGNUM))])]
3390 (define_insn_and_split "*arm_umaxsi3"
3391 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3392 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3393 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3394 (clobber (reg:CC CC_REGNUM))]
3397 ; cmp\\t%1, %2\;movcc\\t%0, %2
3398 ; cmp\\t%1, %2\;movcs\\t%0, %1
3399 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3401 [(set (reg:CC CC_REGNUM)
3402 (compare:CC (match_dup 1) (match_dup 2)))
3404 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3408 [(set_attr "conds" "clob")
3409 (set_attr "length" "8,8,12")
3410 (set_attr "type" "store1")]
3413 (define_expand "uminsi3"
3415 (set (match_operand:SI 0 "s_register_operand" "")
3416 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3417 (match_operand:SI 2 "arm_rhs_operand" "")))
3418 (clobber (reg:CC CC_REGNUM))])]
3423 (define_insn_and_split "*arm_uminsi3"
3424 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3425 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3426 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3427 (clobber (reg:CC CC_REGNUM))]
3430 ; cmp\\t%1, %2\;movcs\\t%0, %2
3431 ; cmp\\t%1, %2\;movcc\\t%0, %1
3432 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3434 [(set (reg:CC CC_REGNUM)
3435 (compare:CC (match_dup 1) (match_dup 2)))
3437 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3441 [(set_attr "conds" "clob")
3442 (set_attr "length" "8,8,12")
3443 (set_attr "type" "store1")]
3446 (define_insn "*store_minmaxsi"
3447 [(set (match_operand:SI 0 "memory_operand" "=m")
3448 (match_operator:SI 3 "minmax_operator"
3449 [(match_operand:SI 1 "s_register_operand" "r")
3450 (match_operand:SI 2 "s_register_operand" "r")]))
3451 (clobber (reg:CC CC_REGNUM))]
3452 "TARGET_32BIT && optimize_function_for_size_p (cfun)"
3454 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3455 operands[1], operands[2]);
3456 output_asm_insn (\"cmp\\t%1, %2\", operands);
3458 output_asm_insn (\"ite\t%d3\", operands);
3459 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3460 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3463 [(set_attr "conds" "clob")
3464 (set (attr "length")
3465 (if_then_else (eq_attr "is_thumb" "yes")
3468 (set_attr "type" "store1")]
3471 ; Reject the frame pointer in operand[1], since reloading this after
3472 ; it has been eliminated can cause carnage.
3473 (define_insn "*minmax_arithsi"
3474 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3475 (match_operator:SI 4 "shiftable_operator"
3476 [(match_operator:SI 5 "minmax_operator"
3477 [(match_operand:SI 2 "s_register_operand" "r,r")
3478 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3479 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3480 (clobber (reg:CC CC_REGNUM))]
3481 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3484 enum rtx_code code = GET_CODE (operands[4]);
3487 if (which_alternative != 0 || operands[3] != const0_rtx
3488 || (code != PLUS && code != IOR && code != XOR))
3493 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3494 operands[2], operands[3]);
3495 output_asm_insn (\"cmp\\t%2, %3\", operands);
3499 output_asm_insn (\"ite\\t%d5\", operands);
3501 output_asm_insn (\"it\\t%d5\", operands);
3503 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3505 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3508 [(set_attr "conds" "clob")
3509 (set (attr "length")
3510 (if_then_else (eq_attr "is_thumb" "yes")
3513 (set_attr "type" "multiple")]
3516 ; Reject the frame pointer in operand[1], since reloading this after
3517 ; it has been eliminated can cause carnage.
3518 (define_insn_and_split "*minmax_arithsi_non_canon"
3519 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3521 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3522 (match_operator:SI 4 "minmax_operator"
3523 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3524 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3525 (clobber (reg:CC CC_REGNUM))]
3526 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3527 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3529 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3530 [(set (reg:CC CC_REGNUM)
3531 (compare:CC (match_dup 2) (match_dup 3)))
3533 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3535 (minus:SI (match_dup 1)
3537 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3541 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3542 operands[2], operands[3]);
3543 enum rtx_code rc = minmax_code (operands[4]);
3544 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3545 operands[2], operands[3]);
3547 if (mode == CCFPmode || mode == CCFPEmode)
3548 rc = reverse_condition_maybe_unordered (rc);
3550 rc = reverse_condition (rc);
3551 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3552 if (CONST_INT_P (operands[3]))
3553 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3555 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3557 [(set_attr "conds" "clob")
3558 (set (attr "length")
3559 (if_then_else (eq_attr "is_thumb" "yes")
3562 (set_attr "type" "multiple")]
3565 (define_code_iterator SAT [smin smax])
3566 (define_code_iterator SATrev [smin smax])
3567 (define_code_attr SATlo [(smin "1") (smax "2")])
3568 (define_code_attr SAThi [(smin "2") (smax "1")])
3570 (define_insn "*satsi_<SAT:code>"
3571 [(set (match_operand:SI 0 "s_register_operand" "=r")
3572 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3573 (match_operand:SI 1 "const_int_operand" "i"))
3574 (match_operand:SI 2 "const_int_operand" "i")))]
3575 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3576 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3580 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3581 &mask, &signed_sat))
3584 operands[1] = GEN_INT (mask);
3586 return "ssat%?\t%0, %1, %3";
3588 return "usat%?\t%0, %1, %3";
3590 [(set_attr "predicable" "yes")
3591 (set_attr "predicable_short_it" "no")
3592 (set_attr "type" "alus_imm")]
3595 (define_insn "*satsi_<SAT:code>_shift"
3596 [(set (match_operand:SI 0 "s_register_operand" "=r")
3597 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3598 [(match_operand:SI 4 "s_register_operand" "r")
3599 (match_operand:SI 5 "const_int_operand" "i")])
3600 (match_operand:SI 1 "const_int_operand" "i"))
3601 (match_operand:SI 2 "const_int_operand" "i")))]
3602 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3603 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3607 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3608 &mask, &signed_sat))
3611 operands[1] = GEN_INT (mask);
3613 return "ssat%?\t%0, %1, %4%S3";
3615 return "usat%?\t%0, %1, %4%S3";
3617 [(set_attr "predicable" "yes")
3618 (set_attr "predicable_short_it" "no")
3619 (set_attr "shift" "3")
3620 (set_attr "type" "logic_shift_reg")])
3622 ;; Shift and rotation insns
3624 (define_expand "ashldi3"
3625 [(set (match_operand:DI 0 "s_register_operand" "")
3626 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3627 (match_operand:SI 2 "general_operand" "")))]
3632 /* Delay the decision whether to use NEON or core-regs until
3633 register allocation. */
3634 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3639 /* Only the NEON case can handle in-memory shift counts. */
3640 if (!reg_or_int_operand (operands[2], SImode))
3641 operands[2] = force_reg (SImode, operands[2]);
3644 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3645 ; /* No special preparation statements; expand pattern as above. */
3648 rtx scratch1, scratch2;
3650 if (CONST_INT_P (operands[2])
3651 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3653 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3657 /* Ideally we should use iwmmxt here if we could know that operands[1]
3658 ends up already living in an iwmmxt register. Otherwise it's
3659 cheaper to have the alternate code being generated than moving
3660 values to iwmmxt regs and back. */
3662 /* If we're optimizing for size, we prefer the libgcc calls. */
3663 if (optimize_function_for_size_p (cfun))
3666 /* Expand operation using core-registers.
3667 'FAIL' would achieve the same thing, but this is a bit smarter. */
3668 scratch1 = gen_reg_rtx (SImode);
3669 scratch2 = gen_reg_rtx (SImode);
3670 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3671 operands[2], scratch1, scratch2);
3677 (define_insn "arm_ashldi3_1bit"
3678 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3679 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3681 (clobber (reg:CC CC_REGNUM))]
3683 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3684 [(set_attr "conds" "clob")
3685 (set_attr "length" "8")
3686 (set_attr "type" "multiple")]
3689 (define_expand "ashlsi3"
3690 [(set (match_operand:SI 0 "s_register_operand" "")
3691 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3692 (match_operand:SI 2 "arm_rhs_operand" "")))]
3695 if (CONST_INT_P (operands[2])
3696 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3698 emit_insn (gen_movsi (operands[0], const0_rtx));
3704 (define_expand "ashrdi3"
3705 [(set (match_operand:DI 0 "s_register_operand" "")
3706 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3707 (match_operand:SI 2 "reg_or_int_operand" "")))]
3712 /* Delay the decision whether to use NEON or core-regs until
3713 register allocation. */
3714 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3718 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3719 ; /* No special preparation statements; expand pattern as above. */
3722 rtx scratch1, scratch2;
3724 if (CONST_INT_P (operands[2])
3725 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3727 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3731 /* Ideally we should use iwmmxt here if we could know that operands[1]
3732 ends up already living in an iwmmxt register. Otherwise it's
3733 cheaper to have the alternate code being generated than moving
3734 values to iwmmxt regs and back. */
3736 /* If we're optimizing for size, we prefer the libgcc calls. */
3737 if (optimize_function_for_size_p (cfun))
3740 /* Expand operation using core-registers.
3741 'FAIL' would achieve the same thing, but this is a bit smarter. */
3742 scratch1 = gen_reg_rtx (SImode);
3743 scratch2 = gen_reg_rtx (SImode);
3744 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3745 operands[2], scratch1, scratch2);
3751 (define_insn "arm_ashrdi3_1bit"
3752 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3753 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3755 (clobber (reg:CC CC_REGNUM))]
3757 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3758 [(set_attr "conds" "clob")
3759 (set_attr "length" "8")
3760 (set_attr "type" "multiple")]
3763 (define_expand "ashrsi3"
3764 [(set (match_operand:SI 0 "s_register_operand" "")
3765 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3766 (match_operand:SI 2 "arm_rhs_operand" "")))]
3769 if (CONST_INT_P (operands[2])
3770 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3771 operands[2] = GEN_INT (31);
3775 (define_expand "lshrdi3"
3776 [(set (match_operand:DI 0 "s_register_operand" "")
3777 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3778 (match_operand:SI 2 "reg_or_int_operand" "")))]
3783 /* Delay the decision whether to use NEON or core-regs until
3784 register allocation. */
3785 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3789 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3790 ; /* No special preparation statements; expand pattern as above. */
3793 rtx scratch1, scratch2;
3795 if (CONST_INT_P (operands[2])
3796 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3798 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3802 /* Ideally we should use iwmmxt here if we could know that operands[1]
3803 ends up already living in an iwmmxt register. Otherwise it's
3804 cheaper to have the alternate code being generated than moving
3805 values to iwmmxt regs and back. */
3807 /* If we're optimizing for size, we prefer the libgcc calls. */
3808 if (optimize_function_for_size_p (cfun))
3811 /* Expand operation using core-registers.
3812 'FAIL' would achieve the same thing, but this is a bit smarter. */
3813 scratch1 = gen_reg_rtx (SImode);
3814 scratch2 = gen_reg_rtx (SImode);
3815 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3816 operands[2], scratch1, scratch2);
3822 (define_insn "arm_lshrdi3_1bit"
3823 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3824 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3826 (clobber (reg:CC CC_REGNUM))]
3828 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3829 [(set_attr "conds" "clob")
3830 (set_attr "length" "8")
3831 (set_attr "type" "multiple")]
3834 (define_expand "lshrsi3"
3835 [(set (match_operand:SI 0 "s_register_operand" "")
3836 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3837 (match_operand:SI 2 "arm_rhs_operand" "")))]
3840 if (CONST_INT_P (operands[2])
3841 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3843 emit_insn (gen_movsi (operands[0], const0_rtx));
3849 (define_expand "rotlsi3"
3850 [(set (match_operand:SI 0 "s_register_operand" "")
3851 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3852 (match_operand:SI 2 "reg_or_int_operand" "")))]
3855 if (CONST_INT_P (operands[2]))
3856 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3859 rtx reg = gen_reg_rtx (SImode);
3860 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3866 (define_expand "rotrsi3"
3867 [(set (match_operand:SI 0 "s_register_operand" "")
3868 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3869 (match_operand:SI 2 "arm_rhs_operand" "")))]
3874 if (CONST_INT_P (operands[2])
3875 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3876 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3878 else /* TARGET_THUMB1 */
3880 if (CONST_INT_P (operands [2]))
3881 operands [2] = force_reg (SImode, operands[2]);
3886 (define_insn "*arm_shiftsi3"
3887 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
3888 (match_operator:SI 3 "shift_operator"
3889 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
3890 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
3892 "* return arm_output_shift(operands, 0);"
3893 [(set_attr "predicable" "yes")
3894 (set_attr "arch" "t2,t2,*,*")
3895 (set_attr "predicable_short_it" "yes,yes,no,no")
3896 (set_attr "length" "4")
3897 (set_attr "shift" "1")
3898 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
3901 (define_insn "*shiftsi3_compare0"
3902 [(set (reg:CC_NOOV CC_REGNUM)
3903 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3904 [(match_operand:SI 1 "s_register_operand" "r,r")
3905 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3907 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3908 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
3910 "* return arm_output_shift(operands, 1);"
3911 [(set_attr "conds" "set")
3912 (set_attr "shift" "1")
3913 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
3916 (define_insn "*shiftsi3_compare0_scratch"
3917 [(set (reg:CC_NOOV CC_REGNUM)
3918 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3919 [(match_operand:SI 1 "s_register_operand" "r,r")
3920 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3922 (clobber (match_scratch:SI 0 "=r,r"))]
3924 "* return arm_output_shift(operands, 1);"
3925 [(set_attr "conds" "set")
3926 (set_attr "shift" "1")
3927 (set_attr "type" "shift_imm,shift_reg")]
3930 (define_insn "*not_shiftsi"
3931 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3932 (not:SI (match_operator:SI 3 "shift_operator"
3933 [(match_operand:SI 1 "s_register_operand" "r,r")
3934 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3937 [(set_attr "predicable" "yes")
3938 (set_attr "predicable_short_it" "no")
3939 (set_attr "shift" "1")
3940 (set_attr "arch" "32,a")
3941 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3943 (define_insn "*not_shiftsi_compare0"
3944 [(set (reg:CC_NOOV CC_REGNUM)
3946 (not:SI (match_operator:SI 3 "shift_operator"
3947 [(match_operand:SI 1 "s_register_operand" "r,r")
3948 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3950 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3951 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
3954 [(set_attr "conds" "set")
3955 (set_attr "shift" "1")
3956 (set_attr "arch" "32,a")
3957 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3959 (define_insn "*not_shiftsi_compare0_scratch"
3960 [(set (reg:CC_NOOV CC_REGNUM)
3962 (not:SI (match_operator:SI 3 "shift_operator"
3963 [(match_operand:SI 1 "s_register_operand" "r,r")
3964 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3966 (clobber (match_scratch:SI 0 "=r,r"))]
3969 [(set_attr "conds" "set")
3970 (set_attr "shift" "1")
3971 (set_attr "arch" "32,a")
3972 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3974 ;; We don't really have extzv, but defining this using shifts helps
3975 ;; to reduce register pressure later on.
3977 (define_expand "extzv"
3978 [(set (match_operand 0 "s_register_operand" "")
3979 (zero_extract (match_operand 1 "nonimmediate_operand" "")
3980 (match_operand 2 "const_int_operand" "")
3981 (match_operand 3 "const_int_operand" "")))]
3982 "TARGET_THUMB1 || arm_arch_thumb2"
3985 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3986 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3988 if (arm_arch_thumb2)
3990 HOST_WIDE_INT width = INTVAL (operands[2]);
3991 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3993 if (unaligned_access && MEM_P (operands[1])
3994 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
3998 if (BYTES_BIG_ENDIAN)
3999 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4004 base_addr = adjust_address (operands[1], SImode,
4005 bitpos / BITS_PER_UNIT);
4006 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4010 rtx dest = operands[0];
4011 rtx tmp = gen_reg_rtx (SImode);
4013 /* We may get a paradoxical subreg here. Strip it off. */
4014 if (GET_CODE (dest) == SUBREG
4015 && GET_MODE (dest) == SImode
4016 && GET_MODE (SUBREG_REG (dest)) == HImode)
4017 dest = SUBREG_REG (dest);
4019 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4022 base_addr = adjust_address (operands[1], HImode,
4023 bitpos / BITS_PER_UNIT);
4024 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4025 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4029 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4031 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4039 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4042 operands[3] = GEN_INT (rshift);
4046 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4050 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4051 operands[3], gen_reg_rtx (SImode)));
4056 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4058 (define_expand "extzv_t1"
4059 [(set (match_operand:SI 4 "s_register_operand" "")
4060 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4061 (match_operand:SI 2 "const_int_operand" "")))
4062 (set (match_operand:SI 0 "s_register_operand" "")
4063 (lshiftrt:SI (match_dup 4)
4064 (match_operand:SI 3 "const_int_operand" "")))]
4068 (define_expand "extv"
4069 [(set (match_operand 0 "s_register_operand" "")
4070 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4071 (match_operand 2 "const_int_operand" "")
4072 (match_operand 3 "const_int_operand" "")))]
4075 HOST_WIDE_INT width = INTVAL (operands[2]);
4076 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4078 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4079 && (bitpos % BITS_PER_UNIT) == 0)
4083 if (BYTES_BIG_ENDIAN)
4084 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4088 base_addr = adjust_address (operands[1], SImode,
4089 bitpos / BITS_PER_UNIT);
4090 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4094 rtx dest = operands[0];
4095 rtx tmp = gen_reg_rtx (SImode);
4097 /* We may get a paradoxical subreg here. Strip it off. */
4098 if (GET_CODE (dest) == SUBREG
4099 && GET_MODE (dest) == SImode
4100 && GET_MODE (SUBREG_REG (dest)) == HImode)
4101 dest = SUBREG_REG (dest);
4103 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4106 base_addr = adjust_address (operands[1], HImode,
4107 bitpos / BITS_PER_UNIT);
4108 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4109 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4114 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4116 else if (GET_MODE (operands[0]) == SImode
4117 && GET_MODE (operands[1]) == SImode)
4119 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4127 ; Helper to expand register forms of extv with the proper modes.
4129 (define_expand "extv_regsi"
4130 [(set (match_operand:SI 0 "s_register_operand" "")
4131 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4132 (match_operand 2 "const_int_operand" "")
4133 (match_operand 3 "const_int_operand" "")))]
4138 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4140 (define_insn "unaligned_loadsi"
4141 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4142 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4143 UNSPEC_UNALIGNED_LOAD))]
4144 "unaligned_access && TARGET_32BIT"
4145 "ldr%?\t%0, %1\t@ unaligned"
4146 [(set_attr "arch" "t2,any")
4147 (set_attr "length" "2,4")
4148 (set_attr "predicable" "yes")
4149 (set_attr "predicable_short_it" "yes,no")
4150 (set_attr "type" "load1")])
4152 (define_insn "unaligned_loadhis"
4153 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4155 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4156 UNSPEC_UNALIGNED_LOAD)))]
4157 "unaligned_access && TARGET_32BIT"
4158 "ldr%(sh%)\t%0, %1\t@ unaligned"
4159 [(set_attr "arch" "t2,any")
4160 (set_attr "length" "2,4")
4161 (set_attr "predicable" "yes")
4162 (set_attr "predicable_short_it" "yes,no")
4163 (set_attr "type" "load_byte")])
4165 (define_insn "unaligned_loadhiu"
4166 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4168 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4169 UNSPEC_UNALIGNED_LOAD)))]
4170 "unaligned_access && TARGET_32BIT"
4171 "ldr%(h%)\t%0, %1\t@ unaligned"
4172 [(set_attr "arch" "t2,any")
4173 (set_attr "length" "2,4")
4174 (set_attr "predicable" "yes")
4175 (set_attr "predicable_short_it" "yes,no")
4176 (set_attr "type" "load_byte")])
4178 (define_insn "unaligned_storesi"
4179 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4180 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4181 UNSPEC_UNALIGNED_STORE))]
4182 "unaligned_access && TARGET_32BIT"
4183 "str%?\t%1, %0\t@ unaligned"
4184 [(set_attr "arch" "t2,any")
4185 (set_attr "length" "2,4")
4186 (set_attr "predicable" "yes")
4187 (set_attr "predicable_short_it" "yes,no")
4188 (set_attr "type" "store1")])
4190 (define_insn "unaligned_storehi"
4191 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4192 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4193 UNSPEC_UNALIGNED_STORE))]
4194 "unaligned_access && TARGET_32BIT"
4195 "str%(h%)\t%1, %0\t@ unaligned"
4196 [(set_attr "arch" "t2,any")
4197 (set_attr "length" "2,4")
4198 (set_attr "predicable" "yes")
4199 (set_attr "predicable_short_it" "yes,no")
4200 (set_attr "type" "store1")])
4202 ;; Unaligned double-word load and store.
4203 ;; Split after reload into two unaligned single-word accesses.
4204 ;; It prevents lower_subreg from splitting some other aligned
4205 ;; double-word accesses too early. Used for internal memcpy.
4207 (define_insn_and_split "unaligned_loaddi"
4208 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4209 (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4210 UNSPEC_UNALIGNED_LOAD))]
4211 "unaligned_access && TARGET_32BIT"
4213 "&& reload_completed"
4214 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4215 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4217 operands[2] = gen_highpart (SImode, operands[0]);
4218 operands[0] = gen_lowpart (SImode, operands[0]);
4219 operands[3] = gen_highpart (SImode, operands[1]);
4220 operands[1] = gen_lowpart (SImode, operands[1]);
4222 /* If the first destination register overlaps with the base address,
4223 swap the order in which the loads are emitted. */
4224 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4226 rtx tmp = operands[1];
4227 operands[1] = operands[3];
4230 operands[0] = operands[2];
4234 [(set_attr "arch" "t2,any")
4235 (set_attr "length" "4,8")
4236 (set_attr "predicable" "yes")
4237 (set_attr "type" "load2")])
4239 (define_insn_and_split "unaligned_storedi"
4240 [(set (match_operand:DI 0 "memory_operand" "=o,o")
4241 (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4242 UNSPEC_UNALIGNED_STORE))]
4243 "unaligned_access && TARGET_32BIT"
4245 "&& reload_completed"
4246 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4247 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4249 operands[2] = gen_highpart (SImode, operands[0]);
4250 operands[0] = gen_lowpart (SImode, operands[0]);
4251 operands[3] = gen_highpart (SImode, operands[1]);
4252 operands[1] = gen_lowpart (SImode, operands[1]);
4254 [(set_attr "arch" "t2,any")
4255 (set_attr "length" "4,8")
4256 (set_attr "predicable" "yes")
4257 (set_attr "type" "store2")])
4260 (define_insn "*extv_reg"
4261 [(set (match_operand:SI 0 "s_register_operand" "=r")
4262 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4263 (match_operand:SI 2 "const_int_M_operand" "M")
4264 (match_operand:SI 3 "const_int_M_operand" "M")))]
4266 "sbfx%?\t%0, %1, %3, %2"
4267 [(set_attr "length" "4")
4268 (set_attr "predicable" "yes")
4269 (set_attr "predicable_short_it" "no")
4270 (set_attr "type" "bfm")]
4273 (define_insn "extzv_t2"
4274 [(set (match_operand:SI 0 "s_register_operand" "=r")
4275 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4276 (match_operand:SI 2 "const_int_M_operand" "M")
4277 (match_operand:SI 3 "const_int_M_operand" "M")))]
4279 "ubfx%?\t%0, %1, %3, %2"
4280 [(set_attr "length" "4")
4281 (set_attr "predicable" "yes")
4282 (set_attr "predicable_short_it" "no")
4283 (set_attr "type" "bfm")]
4287 ;; Division instructions
4288 (define_insn "divsi3"
4289 [(set (match_operand:SI 0 "s_register_operand" "=r")
4290 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4291 (match_operand:SI 2 "s_register_operand" "r")))]
4293 "sdiv%?\t%0, %1, %2"
4294 [(set_attr "predicable" "yes")
4295 (set_attr "predicable_short_it" "no")
4296 (set_attr "type" "sdiv")]
4299 (define_insn "udivsi3"
4300 [(set (match_operand:SI 0 "s_register_operand" "=r")
4301 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4302 (match_operand:SI 2 "s_register_operand" "r")))]
4304 "udiv%?\t%0, %1, %2"
4305 [(set_attr "predicable" "yes")
4306 (set_attr "predicable_short_it" "no")
4307 (set_attr "type" "udiv")]
4311 ;; Unary arithmetic insns
4313 (define_expand "negdi2"
4315 [(set (match_operand:DI 0 "s_register_operand" "")
4316 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4317 (clobber (reg:CC CC_REGNUM))])]
4322 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4328 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4329 ;; The first alternative allows the common case of a *full* overlap.
4330 (define_insn_and_split "*arm_negdi2"
4331 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4332 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4333 (clobber (reg:CC CC_REGNUM))]
4335 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4336 "&& reload_completed"
4337 [(parallel [(set (reg:CC CC_REGNUM)
4338 (compare:CC (const_int 0) (match_dup 1)))
4339 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4340 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4341 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4343 operands[2] = gen_highpart (SImode, operands[0]);
4344 operands[0] = gen_lowpart (SImode, operands[0]);
4345 operands[3] = gen_highpart (SImode, operands[1]);
4346 operands[1] = gen_lowpart (SImode, operands[1]);
4348 [(set_attr "conds" "clob")
4349 (set_attr "length" "8")
4350 (set_attr "type" "multiple")]
4353 (define_expand "negsi2"
4354 [(set (match_operand:SI 0 "s_register_operand" "")
4355 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4360 (define_insn "*arm_negsi2"
4361 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4362 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4364 "rsb%?\\t%0, %1, #0"
4365 [(set_attr "predicable" "yes")
4366 (set_attr "predicable_short_it" "yes,no")
4367 (set_attr "arch" "t2,*")
4368 (set_attr "length" "4")
4369 (set_attr "type" "alu_sreg")]
4372 (define_expand "negsf2"
4373 [(set (match_operand:SF 0 "s_register_operand" "")
4374 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4375 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4379 (define_expand "negdf2"
4380 [(set (match_operand:DF 0 "s_register_operand" "")
4381 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4382 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4385 (define_insn_and_split "*zextendsidi_negsi"
4386 [(set (match_operand:DI 0 "s_register_operand" "=r")
4387 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4392 (neg:SI (match_dup 1)))
4396 operands[2] = gen_lowpart (SImode, operands[0]);
4397 operands[3] = gen_highpart (SImode, operands[0]);
4399 [(set_attr "length" "8")
4400 (set_attr "type" "multiple")]
4403 ;; Negate an extended 32-bit value.
4404 (define_insn_and_split "*negdi_extendsidi"
4405 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4406 (neg:DI (sign_extend:DI
4407 (match_operand:SI 1 "s_register_operand" "l,r"))))
4408 (clobber (reg:CC CC_REGNUM))]
4411 "&& reload_completed"
4414 rtx low = gen_lowpart (SImode, operands[0]);
4415 rtx high = gen_highpart (SImode, operands[0]);
4417 if (reg_overlap_mentioned_p (low, operands[1]))
4419 /* Input overlaps the low word of the output. Use:
4422 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4423 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4425 emit_insn (gen_rtx_SET (VOIDmode, high,
4426 gen_rtx_ASHIFTRT (SImode, operands[1],
4429 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4431 emit_insn (gen_rtx_SET (VOIDmode, high,
4432 gen_rtx_MINUS (SImode,
4433 gen_rtx_MINUS (SImode,
4436 gen_rtx_LTU (SImode,
4441 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4442 emit_insn (gen_rtx_SET (VOIDmode, high,
4443 gen_rtx_MINUS (SImode,
4444 gen_rtx_MINUS (SImode,
4447 gen_rtx_LTU (SImode,
4454 /* No overlap, or overlap on high word. Use:
4458 Flags not needed for this sequence. */
4459 emit_insn (gen_rtx_SET (VOIDmode, low,
4460 gen_rtx_NEG (SImode, operands[1])));
4461 emit_insn (gen_rtx_SET (VOIDmode, high,
4462 gen_rtx_AND (SImode,
4463 gen_rtx_NOT (SImode, operands[1]),
4465 emit_insn (gen_rtx_SET (VOIDmode, high,
4466 gen_rtx_ASHIFTRT (SImode, high,
4471 [(set_attr "length" "12")
4472 (set_attr "arch" "t2,*")
4473 (set_attr "type" "multiple")]
4476 (define_insn_and_split "*negdi_zero_extendsidi"
4477 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4478 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4479 (clobber (reg:CC CC_REGNUM))]
4481 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4482 ;; Don't care what register is input to sbc,
4483 ;; since we just just need to propagate the carry.
4484 "&& reload_completed"
4485 [(parallel [(set (reg:CC CC_REGNUM)
4486 (compare:CC (const_int 0) (match_dup 1)))
4487 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4488 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4489 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4491 operands[2] = gen_highpart (SImode, operands[0]);
4492 operands[0] = gen_lowpart (SImode, operands[0]);
4494 [(set_attr "conds" "clob")
4495 (set_attr "length" "8")
4496 (set_attr "type" "multiple")] ;; length in thumb is 4
4499 ;; abssi2 doesn't really clobber the condition codes if a different register
4500 ;; is being set. To keep things simple, assume during rtl manipulations that
4501 ;; it does, but tell the final scan operator the truth. Similarly for
4504 (define_expand "abssi2"
4506 [(set (match_operand:SI 0 "s_register_operand" "")
4507 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4508 (clobber (match_dup 2))])]
4512 operands[2] = gen_rtx_SCRATCH (SImode);
4514 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4517 (define_insn_and_split "*arm_abssi2"
4518 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4519 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4520 (clobber (reg:CC CC_REGNUM))]
4523 "&& reload_completed"
4526 /* if (which_alternative == 0) */
4527 if (REGNO(operands[0]) == REGNO(operands[1]))
4529 /* Emit the pattern:
4530 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4531 [(set (reg:CC CC_REGNUM)
4532 (compare:CC (match_dup 0) (const_int 0)))
4533 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4534 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4536 emit_insn (gen_rtx_SET (VOIDmode,
4537 gen_rtx_REG (CCmode, CC_REGNUM),
4538 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4539 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4540 (gen_rtx_LT (SImode,
4541 gen_rtx_REG (CCmode, CC_REGNUM),
4543 (gen_rtx_SET (VOIDmode,
4545 (gen_rtx_MINUS (SImode,
4552 /* Emit the pattern:
4553 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4555 (xor:SI (match_dup 1)
4556 (ashiftrt:SI (match_dup 1) (const_int 31))))
4558 (minus:SI (match_dup 0)
4559 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4561 emit_insn (gen_rtx_SET (VOIDmode,
4563 gen_rtx_XOR (SImode,
4564 gen_rtx_ASHIFTRT (SImode,
4568 emit_insn (gen_rtx_SET (VOIDmode,
4570 gen_rtx_MINUS (SImode,
4572 gen_rtx_ASHIFTRT (SImode,
4578 [(set_attr "conds" "clob,*")
4579 (set_attr "shift" "1")
4580 (set_attr "predicable" "no, yes")
4581 (set_attr "length" "8")
4582 (set_attr "type" "multiple")]
4585 (define_insn_and_split "*arm_neg_abssi2"
4586 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4587 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4588 (clobber (reg:CC CC_REGNUM))]
4591 "&& reload_completed"
4594 /* if (which_alternative == 0) */
4595 if (REGNO (operands[0]) == REGNO (operands[1]))
4597 /* Emit the pattern:
4598 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4600 emit_insn (gen_rtx_SET (VOIDmode,
4601 gen_rtx_REG (CCmode, CC_REGNUM),
4602 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4603 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4605 gen_rtx_REG (CCmode, CC_REGNUM),
4607 gen_rtx_SET (VOIDmode,
4609 (gen_rtx_MINUS (SImode,
4615 /* Emit the pattern:
4616 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4618 emit_insn (gen_rtx_SET (VOIDmode,
4620 gen_rtx_XOR (SImode,
4621 gen_rtx_ASHIFTRT (SImode,
4625 emit_insn (gen_rtx_SET (VOIDmode,
4627 gen_rtx_MINUS (SImode,
4628 gen_rtx_ASHIFTRT (SImode,
4635 [(set_attr "conds" "clob,*")
4636 (set_attr "shift" "1")
4637 (set_attr "predicable" "no, yes")
4638 (set_attr "length" "8")
4639 (set_attr "type" "multiple")]
4642 (define_expand "abssf2"
4643 [(set (match_operand:SF 0 "s_register_operand" "")
4644 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4645 "TARGET_32BIT && TARGET_HARD_FLOAT"
4648 (define_expand "absdf2"
4649 [(set (match_operand:DF 0 "s_register_operand" "")
4650 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4651 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4654 (define_expand "sqrtsf2"
4655 [(set (match_operand:SF 0 "s_register_operand" "")
4656 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4657 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4660 (define_expand "sqrtdf2"
4661 [(set (match_operand:DF 0 "s_register_operand" "")
4662 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4663 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4666 (define_insn_and_split "one_cmpldi2"
4667 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4668 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4675 "TARGET_32BIT && reload_completed
4676 && arm_general_register_operand (operands[0], DImode)"
4677 [(set (match_dup 0) (not:SI (match_dup 1)))
4678 (set (match_dup 2) (not:SI (match_dup 3)))]
4681 operands[2] = gen_highpart (SImode, operands[0]);
4682 operands[0] = gen_lowpart (SImode, operands[0]);
4683 operands[3] = gen_highpart (SImode, operands[1]);
4684 operands[1] = gen_lowpart (SImode, operands[1]);
4686 [(set_attr "length" "*,8,8,*")
4687 (set_attr "predicable" "no,yes,yes,no")
4688 (set_attr "type" "neon_move,multiple,multiple,neon_move")
4689 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4692 (define_expand "one_cmplsi2"
4693 [(set (match_operand:SI 0 "s_register_operand" "")
4694 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4699 (define_insn "*arm_one_cmplsi2"
4700 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4701 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4704 [(set_attr "predicable" "yes")
4705 (set_attr "predicable_short_it" "yes,no")
4706 (set_attr "arch" "t2,*")
4707 (set_attr "length" "4")
4708 (set_attr "type" "mvn_reg")]
4711 (define_insn "*notsi_compare0"
4712 [(set (reg:CC_NOOV CC_REGNUM)
4713 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4715 (set (match_operand:SI 0 "s_register_operand" "=r")
4716 (not:SI (match_dup 1)))]
4719 [(set_attr "conds" "set")
4720 (set_attr "type" "mvn_reg")]
4723 (define_insn "*notsi_compare0_scratch"
4724 [(set (reg:CC_NOOV CC_REGNUM)
4725 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4727 (clobber (match_scratch:SI 0 "=r"))]
4730 [(set_attr "conds" "set")
4731 (set_attr "type" "mvn_reg")]
4734 ;; Fixed <--> Floating conversion insns
4736 (define_expand "floatsihf2"
4737 [(set (match_operand:HF 0 "general_operand" "")
4738 (float:HF (match_operand:SI 1 "general_operand" "")))]
4742 rtx op1 = gen_reg_rtx (SFmode);
4743 expand_float (op1, operands[1], 0);
4744 op1 = convert_to_mode (HFmode, op1, 0);
4745 emit_move_insn (operands[0], op1);
4750 (define_expand "floatdihf2"
4751 [(set (match_operand:HF 0 "general_operand" "")
4752 (float:HF (match_operand:DI 1 "general_operand" "")))]
4756 rtx op1 = gen_reg_rtx (SFmode);
4757 expand_float (op1, operands[1], 0);
4758 op1 = convert_to_mode (HFmode, op1, 0);
4759 emit_move_insn (operands[0], op1);
4764 (define_expand "floatsisf2"
4765 [(set (match_operand:SF 0 "s_register_operand" "")
4766 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
4767 "TARGET_32BIT && TARGET_HARD_FLOAT"
4771 (define_expand "floatsidf2"
4772 [(set (match_operand:DF 0 "s_register_operand" "")
4773 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
4774 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4778 (define_expand "fix_trunchfsi2"
4779 [(set (match_operand:SI 0 "general_operand" "")
4780 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4784 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4785 expand_fix (operands[0], op1, 0);
4790 (define_expand "fix_trunchfdi2"
4791 [(set (match_operand:DI 0 "general_operand" "")
4792 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4796 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4797 expand_fix (operands[0], op1, 0);
4802 (define_expand "fix_truncsfsi2"
4803 [(set (match_operand:SI 0 "s_register_operand" "")
4804 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
4805 "TARGET_32BIT && TARGET_HARD_FLOAT"
4809 (define_expand "fix_truncdfsi2"
4810 [(set (match_operand:SI 0 "s_register_operand" "")
4811 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
4812 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4818 (define_expand "truncdfsf2"
4819 [(set (match_operand:SF 0 "s_register_operand" "")
4821 (match_operand:DF 1 "s_register_operand" "")))]
4822 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4826 /* DFmode -> HFmode conversions have to go through SFmode. */
4827 (define_expand "truncdfhf2"
4828 [(set (match_operand:HF 0 "general_operand" "")
4830 (match_operand:DF 1 "general_operand" "")))]
4835 op1 = convert_to_mode (SFmode, operands[1], 0);
4836 op1 = convert_to_mode (HFmode, op1, 0);
4837 emit_move_insn (operands[0], op1);
4842 ;; Zero and sign extension instructions.
4844 (define_insn "zero_extend<mode>di2"
4845 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
4846 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4847 "<qhs_zextenddi_cstr>")))]
4848 "TARGET_32BIT <qhs_zextenddi_cond>"
4850 [(set_attr "length" "8,4,8,8")
4851 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
4852 (set_attr "ce_count" "2")
4853 (set_attr "predicable" "yes")
4854 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
4857 (define_insn "extend<mode>di2"
4858 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
4859 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4860 "<qhs_extenddi_cstr>")))]
4861 "TARGET_32BIT <qhs_sextenddi_cond>"
4863 [(set_attr "length" "8,4,8,8,8")
4864 (set_attr "ce_count" "2")
4865 (set_attr "shift" "1")
4866 (set_attr "predicable" "yes")
4867 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4868 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
4871 ;; Splits for all extensions to DImode
4873 [(set (match_operand:DI 0 "s_register_operand" "")
4874 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4875 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4876 [(set (match_dup 0) (match_dup 1))]
4878 rtx lo_part = gen_lowpart (SImode, operands[0]);
4879 enum machine_mode src_mode = GET_MODE (operands[1]);
4881 if (REG_P (operands[0])
4882 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4883 emit_clobber (operands[0]);
4884 if (!REG_P (lo_part) || src_mode != SImode
4885 || !rtx_equal_p (lo_part, operands[1]))
4887 if (src_mode == SImode)
4888 emit_move_insn (lo_part, operands[1]);
4890 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4891 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4892 operands[1] = lo_part;
4894 operands[0] = gen_highpart (SImode, operands[0]);
4895 operands[1] = const0_rtx;
4899 [(set (match_operand:DI 0 "s_register_operand" "")
4900 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4901 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4902 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4904 rtx lo_part = gen_lowpart (SImode, operands[0]);
4905 enum machine_mode src_mode = GET_MODE (operands[1]);
4907 if (REG_P (operands[0])
4908 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4909 emit_clobber (operands[0]);
4911 if (!REG_P (lo_part) || src_mode != SImode
4912 || !rtx_equal_p (lo_part, operands[1]))
4914 if (src_mode == SImode)
4915 emit_move_insn (lo_part, operands[1]);
4917 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4918 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4919 operands[1] = lo_part;
4921 operands[0] = gen_highpart (SImode, operands[0]);
4924 (define_expand "zero_extendhisi2"
4925 [(set (match_operand:SI 0 "s_register_operand" "")
4926 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4929 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4931 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4934 if (!arm_arch6 && !MEM_P (operands[1]))
4936 rtx t = gen_lowpart (SImode, operands[1]);
4937 rtx tmp = gen_reg_rtx (SImode);
4938 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4939 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4945 [(set (match_operand:SI 0 "s_register_operand" "")
4946 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4947 "!TARGET_THUMB2 && !arm_arch6"
4948 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4949 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4951 operands[2] = gen_lowpart (SImode, operands[1]);
4954 (define_insn "*arm_zero_extendhisi2"
4955 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4956 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4957 "TARGET_ARM && arm_arch4 && !arm_arch6"
4961 [(set_attr "type" "alu_shift_reg,load_byte")
4962 (set_attr "predicable" "yes")]
4965 (define_insn "*arm_zero_extendhisi2_v6"
4966 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4967 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4968 "TARGET_ARM && arm_arch6"
4972 [(set_attr "predicable" "yes")
4973 (set_attr "type" "extend,load_byte")]
4976 (define_insn "*arm_zero_extendhisi2addsi"
4977 [(set (match_operand:SI 0 "s_register_operand" "=r")
4978 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4979 (match_operand:SI 2 "s_register_operand" "r")))]
4981 "uxtah%?\\t%0, %2, %1"
4982 [(set_attr "type" "alu_shift_reg")
4983 (set_attr "predicable" "yes")
4984 (set_attr "predicable_short_it" "no")]
4987 (define_expand "zero_extendqisi2"
4988 [(set (match_operand:SI 0 "s_register_operand" "")
4989 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4992 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
4994 emit_insn (gen_andsi3 (operands[0],
4995 gen_lowpart (SImode, operands[1]),
4999 if (!arm_arch6 && !MEM_P (operands[1]))
5001 rtx t = gen_lowpart (SImode, operands[1]);
5002 rtx tmp = gen_reg_rtx (SImode);
5003 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5004 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5010 [(set (match_operand:SI 0 "s_register_operand" "")
5011 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5013 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5014 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5016 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5019 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5024 (define_insn "*arm_zero_extendqisi2"
5025 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5026 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5027 "TARGET_ARM && !arm_arch6"
5030 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5031 [(set_attr "length" "8,4")
5032 (set_attr "type" "alu_shift_reg,load_byte")
5033 (set_attr "predicable" "yes")]
5036 (define_insn "*arm_zero_extendqisi2_v6"
5037 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5038 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5039 "TARGET_ARM && arm_arch6"
5042 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5043 [(set_attr "type" "extend,load_byte")
5044 (set_attr "predicable" "yes")]
5047 (define_insn "*arm_zero_extendqisi2addsi"
5048 [(set (match_operand:SI 0 "s_register_operand" "=r")
5049 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5050 (match_operand:SI 2 "s_register_operand" "r")))]
5052 "uxtab%?\\t%0, %2, %1"
5053 [(set_attr "predicable" "yes")
5054 (set_attr "predicable_short_it" "no")
5055 (set_attr "type" "alu_shift_reg")]
5059 [(set (match_operand:SI 0 "s_register_operand" "")
5060 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5061 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5062 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5063 [(set (match_dup 2) (match_dup 1))
5064 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5069 [(set (match_operand:SI 0 "s_register_operand" "")
5070 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5071 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5072 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5073 [(set (match_dup 2) (match_dup 1))
5074 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5080 [(set (match_operand:SI 0 "s_register_operand" "")
5081 (ior_xor:SI (and:SI (ashift:SI
5082 (match_operand:SI 1 "s_register_operand" "")
5083 (match_operand:SI 2 "const_int_operand" ""))
5084 (match_operand:SI 3 "const_int_operand" ""))
5086 (match_operator 5 "subreg_lowpart_operator"
5087 [(match_operand:SI 4 "s_register_operand" "")]))))]
5089 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5090 == (GET_MODE_MASK (GET_MODE (operands[5]))
5091 & (GET_MODE_MASK (GET_MODE (operands[5]))
5092 << (INTVAL (operands[2])))))"
5093 [(set (match_dup 0) (ior_xor:SI (ashift:SI (match_dup 1) (match_dup 2))
5095 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5096 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5099 (define_insn "*compareqi_eq0"
5100 [(set (reg:CC_Z CC_REGNUM)
5101 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5105 [(set_attr "conds" "set")
5106 (set_attr "predicable" "yes")
5107 (set_attr "predicable_short_it" "no")
5108 (set_attr "type" "logic_imm")]
5111 (define_expand "extendhisi2"
5112 [(set (match_operand:SI 0 "s_register_operand" "")
5113 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5118 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5121 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5123 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5127 if (!arm_arch6 && !MEM_P (operands[1]))
5129 rtx t = gen_lowpart (SImode, operands[1]);
5130 rtx tmp = gen_reg_rtx (SImode);
5131 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5132 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5139 [(set (match_operand:SI 0 "register_operand" "")
5140 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5141 (clobber (match_scratch:SI 2 ""))])]
5143 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5144 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5146 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5149 ;; This pattern will only be used when ldsh is not available
5150 (define_expand "extendhisi2_mem"
5151 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5153 (zero_extend:SI (match_dup 7)))
5154 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5155 (set (match_operand:SI 0 "" "")
5156 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5161 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5163 mem1 = change_address (operands[1], QImode, addr);
5164 mem2 = change_address (operands[1], QImode,
5165 plus_constant (Pmode, addr, 1));
5166 operands[0] = gen_lowpart (SImode, operands[0]);
5168 operands[2] = gen_reg_rtx (SImode);
5169 operands[3] = gen_reg_rtx (SImode);
5170 operands[6] = gen_reg_rtx (SImode);
5173 if (BYTES_BIG_ENDIAN)
5175 operands[4] = operands[2];
5176 operands[5] = operands[3];
5180 operands[4] = operands[3];
5181 operands[5] = operands[2];
5187 [(set (match_operand:SI 0 "register_operand" "")
5188 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5190 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5191 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5193 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5196 (define_insn "*arm_extendhisi2"
5197 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5198 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5199 "TARGET_ARM && arm_arch4 && !arm_arch6"
5203 [(set_attr "length" "8,4")
5204 (set_attr "type" "alu_shift_reg,load_byte")
5205 (set_attr "predicable" "yes")]
5208 ;; ??? Check Thumb-2 pool range
5209 (define_insn "*arm_extendhisi2_v6"
5210 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5211 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5212 "TARGET_32BIT && arm_arch6"
5216 [(set_attr "type" "extend,load_byte")
5217 (set_attr "predicable" "yes")
5218 (set_attr "predicable_short_it" "no")]
5221 (define_insn "*arm_extendhisi2addsi"
5222 [(set (match_operand:SI 0 "s_register_operand" "=r")
5223 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5224 (match_operand:SI 2 "s_register_operand" "r")))]
5226 "sxtah%?\\t%0, %2, %1"
5227 [(set_attr "type" "alu_shift_reg")]
5230 (define_expand "extendqihi2"
5232 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5234 (set (match_operand:HI 0 "s_register_operand" "")
5235 (ashiftrt:SI (match_dup 2)
5240 if (arm_arch4 && MEM_P (operands[1]))
5242 emit_insn (gen_rtx_SET (VOIDmode,
5244 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5247 if (!s_register_operand (operands[1], QImode))
5248 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5249 operands[0] = gen_lowpart (SImode, operands[0]);
5250 operands[1] = gen_lowpart (SImode, operands[1]);
5251 operands[2] = gen_reg_rtx (SImode);
5255 (define_insn "*arm_extendqihi_insn"
5256 [(set (match_operand:HI 0 "s_register_operand" "=r")
5257 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5258 "TARGET_ARM && arm_arch4"
5259 "ldr%(sb%)\\t%0, %1"
5260 [(set_attr "type" "load_byte")
5261 (set_attr "predicable" "yes")]
5264 (define_expand "extendqisi2"
5265 [(set (match_operand:SI 0 "s_register_operand" "")
5266 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5269 if (!arm_arch4 && MEM_P (operands[1]))
5270 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5272 if (!arm_arch6 && !MEM_P (operands[1]))
5274 rtx t = gen_lowpart (SImode, operands[1]);
5275 rtx tmp = gen_reg_rtx (SImode);
5276 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5277 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5283 [(set (match_operand:SI 0 "register_operand" "")
5284 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5286 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5287 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5289 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5292 (define_insn "*arm_extendqisi"
5293 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5294 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5295 "TARGET_ARM && arm_arch4 && !arm_arch6"
5299 [(set_attr "length" "8,4")
5300 (set_attr "type" "alu_shift_reg,load_byte")
5301 (set_attr "predicable" "yes")]
5304 (define_insn "*arm_extendqisi_v6"
5305 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5307 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5308 "TARGET_ARM && arm_arch6"
5312 [(set_attr "type" "extend,load_byte")
5313 (set_attr "predicable" "yes")]
5316 (define_insn "*arm_extendqisi2addsi"
5317 [(set (match_operand:SI 0 "s_register_operand" "=r")
5318 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5319 (match_operand:SI 2 "s_register_operand" "r")))]
5321 "sxtab%?\\t%0, %2, %1"
5322 [(set_attr "type" "alu_shift_reg")
5323 (set_attr "predicable" "yes")
5324 (set_attr "predicable_short_it" "no")]
5327 (define_expand "extendsfdf2"
5328 [(set (match_operand:DF 0 "s_register_operand" "")
5329 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5330 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5334 /* HFmode -> DFmode conversions have to go through SFmode. */
5335 (define_expand "extendhfdf2"
5336 [(set (match_operand:DF 0 "general_operand" "")
5337 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5342 op1 = convert_to_mode (SFmode, operands[1], 0);
5343 op1 = convert_to_mode (DFmode, op1, 0);
5344 emit_insn (gen_movdf (operands[0], op1));
5349 ;; Move insns (including loads and stores)
5351 ;; XXX Just some ideas about movti.
5352 ;; I don't think these are a good idea on the arm, there just aren't enough
5354 ;;(define_expand "loadti"
5355 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5356 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5359 ;;(define_expand "storeti"
5360 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5361 ;; (match_operand:TI 1 "s_register_operand" ""))]
5364 ;;(define_expand "movti"
5365 ;; [(set (match_operand:TI 0 "general_operand" "")
5366 ;; (match_operand:TI 1 "general_operand" ""))]
5372 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5373 ;; operands[1] = copy_to_reg (operands[1]);
5374 ;; if (MEM_P (operands[0]))
5375 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5376 ;; else if (MEM_P (operands[1]))
5377 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5381 ;; emit_insn (insn);
5385 ;; Recognize garbage generated above.
5388 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5389 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5393 ;; register mem = (which_alternative < 3);
5394 ;; register const char *template;
5396 ;; operands[mem] = XEXP (operands[mem], 0);
5397 ;; switch (which_alternative)
5399 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5400 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5401 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5402 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5403 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5404 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5406 ;; output_asm_insn (template, operands);
5410 (define_expand "movdi"
5411 [(set (match_operand:DI 0 "general_operand" "")
5412 (match_operand:DI 1 "general_operand" ""))]
5415 if (can_create_pseudo_p ())
5417 if (!REG_P (operands[0]))
5418 operands[1] = force_reg (DImode, operands[1]);
5423 (define_insn "*arm_movdi"
5424 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5425 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5427 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5429 && ( register_operand (operands[0], DImode)
5430 || register_operand (operands[1], DImode))"
5432 switch (which_alternative)
5439 return output_move_double (operands, true, NULL);
5442 [(set_attr "length" "8,12,16,8,8")
5443 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5444 (set_attr "arm_pool_range" "*,*,*,1020,*")
5445 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5446 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5447 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5451 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5452 (match_operand:ANY64 1 "immediate_operand" ""))]
5455 && (arm_const_double_inline_cost (operands[1])
5456 <= arm_max_const_double_inline_cost ())"
5459 arm_split_constant (SET, SImode, curr_insn,
5460 INTVAL (gen_lowpart (SImode, operands[1])),
5461 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5462 arm_split_constant (SET, SImode, curr_insn,
5463 INTVAL (gen_highpart_mode (SImode,
5464 GET_MODE (operands[0]),
5466 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5471 ; If optimizing for size, or if we have load delay slots, then
5472 ; we want to split the constant into two separate operations.
5473 ; In both cases this may split a trivial part into a single data op
5474 ; leaving a single complex constant to load. We can also get longer
5475 ; offsets in a LDR which means we get better chances of sharing the pool
5476 ; entries. Finally, we can normally do a better job of scheduling
5477 ; LDR instructions than we can with LDM.
5478 ; This pattern will only match if the one above did not.
5480 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5481 (match_operand:ANY64 1 "const_double_operand" ""))]
5482 "TARGET_ARM && reload_completed
5483 && arm_const_double_by_parts (operands[1])"
5484 [(set (match_dup 0) (match_dup 1))
5485 (set (match_dup 2) (match_dup 3))]
5487 operands[2] = gen_highpart (SImode, operands[0]);
5488 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5490 operands[0] = gen_lowpart (SImode, operands[0]);
5491 operands[1] = gen_lowpart (SImode, operands[1]);
5496 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5497 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5498 "TARGET_EITHER && reload_completed"
5499 [(set (match_dup 0) (match_dup 1))
5500 (set (match_dup 2) (match_dup 3))]
5502 operands[2] = gen_highpart (SImode, operands[0]);
5503 operands[3] = gen_highpart (SImode, operands[1]);
5504 operands[0] = gen_lowpart (SImode, operands[0]);
5505 operands[1] = gen_lowpart (SImode, operands[1]);
5507 /* Handle a partial overlap. */
5508 if (rtx_equal_p (operands[0], operands[3]))
5510 rtx tmp0 = operands[0];
5511 rtx tmp1 = operands[1];
5513 operands[0] = operands[2];
5514 operands[1] = operands[3];
5521 ;; We can't actually do base+index doubleword loads if the index and
5522 ;; destination overlap. Split here so that we at least have chance to
5525 [(set (match_operand:DI 0 "s_register_operand" "")
5526 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5527 (match_operand:SI 2 "s_register_operand" ""))))]
5529 && reg_overlap_mentioned_p (operands[0], operands[1])
5530 && reg_overlap_mentioned_p (operands[0], operands[2])"
5532 (plus:SI (match_dup 1)
5535 (mem:DI (match_dup 4)))]
5537 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5541 (define_expand "movsi"
5542 [(set (match_operand:SI 0 "general_operand" "")
5543 (match_operand:SI 1 "general_operand" ""))]
5547 rtx base, offset, tmp;
5551 /* Everything except mem = const or mem = mem can be done easily. */
5552 if (MEM_P (operands[0]))
5553 operands[1] = force_reg (SImode, operands[1]);
5554 if (arm_general_register_operand (operands[0], SImode)
5555 && CONST_INT_P (operands[1])
5556 && !(const_ok_for_arm (INTVAL (operands[1]))
5557 || const_ok_for_arm (~INTVAL (operands[1]))))
5559 arm_split_constant (SET, SImode, NULL_RTX,
5560 INTVAL (operands[1]), operands[0], NULL_RTX,
5561 optimize && can_create_pseudo_p ());
5565 else /* TARGET_THUMB1... */
5567 if (can_create_pseudo_p ())
5569 if (!REG_P (operands[0]))
5570 operands[1] = force_reg (SImode, operands[1]);
5574 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5576 split_const (operands[1], &base, &offset);
5577 if (GET_CODE (base) == SYMBOL_REF
5578 && !offset_within_block_p (base, INTVAL (offset)))
5580 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5581 emit_move_insn (tmp, base);
5582 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5587 /* Recognize the case where operand[1] is a reference to thread-local
5588 data and load its address to a register. */
5589 if (arm_tls_referenced_p (operands[1]))
5591 rtx tmp = operands[1];
5594 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5596 addend = XEXP (XEXP (tmp, 0), 1);
5597 tmp = XEXP (XEXP (tmp, 0), 0);
5600 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5601 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5603 tmp = legitimize_tls_address (tmp,
5604 !can_create_pseudo_p () ? operands[0] : 0);
5607 tmp = gen_rtx_PLUS (SImode, tmp, addend);
5608 tmp = force_operand (tmp, operands[0]);
5613 && (CONSTANT_P (operands[1])
5614 || symbol_mentioned_p (operands[1])
5615 || label_mentioned_p (operands[1])))
5616 operands[1] = legitimize_pic_address (operands[1], SImode,
5617 (!can_create_pseudo_p ()
5624 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5625 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5626 ;; so this does not matter.
5627 (define_insn "*arm_movt"
5628 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5629 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5630 (match_operand:SI 2 "general_operand" "i")))]
5632 "movt%?\t%0, #:upper16:%c2"
5633 [(set_attr "predicable" "yes")
5634 (set_attr "predicable_short_it" "no")
5635 (set_attr "length" "4")
5636 (set_attr "type" "mov_imm")]
5639 (define_insn "*arm_movsi_insn"
5640 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5641 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
5642 "TARGET_ARM && ! TARGET_IWMMXT
5643 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5644 && ( register_operand (operands[0], SImode)
5645 || register_operand (operands[1], SImode))"
5653 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
5654 (set_attr "predicable" "yes")
5655 (set_attr "pool_range" "*,*,*,*,4096,*")
5656 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5660 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5661 (match_operand:SI 1 "const_int_operand" ""))]
5663 && (!(const_ok_for_arm (INTVAL (operands[1]))
5664 || const_ok_for_arm (~INTVAL (operands[1]))))"
5665 [(clobber (const_int 0))]
5667 arm_split_constant (SET, SImode, NULL_RTX,
5668 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5673 ;; A normal way to do (symbol + offset) requires three instructions at least
5674 ;; (depends on how big the offset is) as below:
5675 ;; movw r0, #:lower16:g
5676 ;; movw r0, #:upper16:g
5679 ;; A better way would be:
5680 ;; movw r0, #:lower16:g+4
5681 ;; movw r0, #:upper16:g+4
5683 ;; The limitation of this way is that the length of offset should be a 16-bit
5684 ;; signed value, because current assembler only supports REL type relocation for
5685 ;; such case. If the more powerful RELA type is supported in future, we should
5686 ;; update this pattern to go with better way.
5688 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5689 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5690 (match_operand:SI 2 "const_int_operand" ""))))]
5692 && arm_disable_literal_pool
5694 && GET_CODE (operands[1]) == SYMBOL_REF"
5695 [(clobber (const_int 0))]
5697 int offset = INTVAL (operands[2]);
5699 if (offset < -0x8000 || offset > 0x7fff)
5701 arm_emit_movpair (operands[0], operands[1]);
5702 emit_insn (gen_rtx_SET (SImode, operands[0],
5703 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5707 rtx op = gen_rtx_CONST (SImode,
5708 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5709 arm_emit_movpair (operands[0], op);
5714 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5715 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5716 ;; and lo_sum would be merged back into memory load at cprop. However,
5717 ;; if the default is to prefer movt/movw rather than a load from the constant
5718 ;; pool, the performance is better.
5720 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5721 (match_operand:SI 1 "general_operand" ""))]
5723 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5724 && !flag_pic && !target_word_relocations
5725 && !arm_tls_referenced_p (operands[1])"
5726 [(clobber (const_int 0))]
5728 arm_emit_movpair (operands[0], operands[1]);
5732 ;; When generating pic, we need to load the symbol offset into a register.
5733 ;; So that the optimizer does not confuse this with a normal symbol load
5734 ;; we use an unspec. The offset will be loaded from a constant pool entry,
5735 ;; since that is the only type of relocation we can use.
5737 ;; Wrap calculation of the whole PIC address in a single pattern for the
5738 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5739 ;; a PIC address involves two loads from memory, so we want to CSE it
5740 ;; as often as possible.
5741 ;; This pattern will be split into one of the pic_load_addr_* patterns
5742 ;; and a move after GCSE optimizations.
5744 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5745 (define_expand "calculate_pic_address"
5746 [(set (match_operand:SI 0 "register_operand" "")
5747 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5748 (unspec:SI [(match_operand:SI 2 "" "")]
5753 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5755 [(set (match_operand:SI 0 "register_operand" "")
5756 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5757 (unspec:SI [(match_operand:SI 2 "" "")]
5760 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5761 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5762 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5765 ;; operand1 is the memory address to go into
5766 ;; pic_load_addr_32bit.
5767 ;; operand2 is the PIC label to be emitted
5768 ;; from pic_add_dot_plus_eight.
5769 ;; We do this to allow hoisting of the entire insn.
5770 (define_insn_and_split "pic_load_addr_unified"
5771 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5772 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5773 (match_operand:SI 2 "" "")]
5774 UNSPEC_PIC_UNIFIED))]
5777 "&& reload_completed"
5778 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5779 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5780 (match_dup 2)] UNSPEC_PIC_BASE))]
5781 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5782 [(set_attr "type" "load1,load1,load1")
5783 (set_attr "pool_range" "4096,4094,1022")
5784 (set_attr "neg_pool_range" "4084,0,0")
5785 (set_attr "arch" "a,t2,t1")
5786 (set_attr "length" "8,6,4")]
5789 ;; The rather odd constraints on the following are to force reload to leave
5790 ;; the insn alone, and to force the minipool generation pass to then move
5791 ;; the GOT symbol to memory.
5793 (define_insn "pic_load_addr_32bit"
5794 [(set (match_operand:SI 0 "s_register_operand" "=r")
5795 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5796 "TARGET_32BIT && flag_pic"
5798 [(set_attr "type" "load1")
5799 (set (attr "pool_range")
5800 (if_then_else (eq_attr "is_thumb" "no")
5803 (set (attr "neg_pool_range")
5804 (if_then_else (eq_attr "is_thumb" "no")
5809 (define_insn "pic_load_addr_thumb1"
5810 [(set (match_operand:SI 0 "s_register_operand" "=l")
5811 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5812 "TARGET_THUMB1 && flag_pic"
5814 [(set_attr "type" "load1")
5815 (set (attr "pool_range") (const_int 1018))]
5818 (define_insn "pic_add_dot_plus_four"
5819 [(set (match_operand:SI 0 "register_operand" "=r")
5820 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5822 (match_operand 2 "" "")]
5826 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5827 INTVAL (operands[2]));
5828 return \"add\\t%0, %|pc\";
5830 [(set_attr "length" "2")
5831 (set_attr "type" "alu_sreg")]
5834 (define_insn "pic_add_dot_plus_eight"
5835 [(set (match_operand:SI 0 "register_operand" "=r")
5836 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5838 (match_operand 2 "" "")]
5842 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5843 INTVAL (operands[2]));
5844 return \"add%?\\t%0, %|pc, %1\";
5846 [(set_attr "predicable" "yes")
5847 (set_attr "type" "alu_sreg")]
5850 (define_insn "tls_load_dot_plus_eight"
5851 [(set (match_operand:SI 0 "register_operand" "=r")
5852 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5854 (match_operand 2 "" "")]
5858 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5859 INTVAL (operands[2]));
5860 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5862 [(set_attr "predicable" "yes")
5863 (set_attr "type" "load1")]
5866 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5867 ;; followed by a load. These sequences can be crunched down to
5868 ;; tls_load_dot_plus_eight by a peephole.
5871 [(set (match_operand:SI 0 "register_operand" "")
5872 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5874 (match_operand 1 "" "")]
5876 (set (match_operand:SI 2 "arm_general_register_operand" "")
5877 (mem:SI (match_dup 0)))]
5878 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5880 (mem:SI (unspec:SI [(match_dup 3)
5887 (define_insn "pic_offset_arm"
5888 [(set (match_operand:SI 0 "register_operand" "=r")
5889 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5890 (unspec:SI [(match_operand:SI 2 "" "X")]
5891 UNSPEC_PIC_OFFSET))))]
5892 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5893 "ldr%?\\t%0, [%1,%2]"
5894 [(set_attr "type" "load1")]
5897 (define_expand "builtin_setjmp_receiver"
5898 [(label_ref (match_operand 0 "" ""))]
5902 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5904 if (arm_pic_register != INVALID_REGNUM)
5905 arm_load_pic_register (1UL << 3);
5909 ;; If copying one reg to another we can set the condition codes according to
5910 ;; its value. Such a move is common after a return from subroutine and the
5911 ;; result is being tested against zero.
5913 (define_insn "*movsi_compare0"
5914 [(set (reg:CC CC_REGNUM)
5915 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5917 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5923 [(set_attr "conds" "set")
5924 (set_attr "type" "alus_imm,alus_imm")]
5927 ;; Subroutine to store a half word from a register into memory.
5928 ;; Operand 0 is the source register (HImode)
5929 ;; Operand 1 is the destination address in a register (SImode)
5931 ;; In both this routine and the next, we must be careful not to spill
5932 ;; a memory address of reg+large_const into a separate PLUS insn, since this
5933 ;; can generate unrecognizable rtl.
5935 (define_expand "storehi"
5936 [;; store the low byte
5937 (set (match_operand 1 "" "") (match_dup 3))
5938 ;; extract the high byte
5940 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5941 ;; store the high byte
5942 (set (match_dup 4) (match_dup 5))]
5946 rtx op1 = operands[1];
5947 rtx addr = XEXP (op1, 0);
5948 enum rtx_code code = GET_CODE (addr);
5950 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5952 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
5954 operands[4] = adjust_address (op1, QImode, 1);
5955 operands[1] = adjust_address (operands[1], QImode, 0);
5956 operands[3] = gen_lowpart (QImode, operands[0]);
5957 operands[0] = gen_lowpart (SImode, operands[0]);
5958 operands[2] = gen_reg_rtx (SImode);
5959 operands[5] = gen_lowpart (QImode, operands[2]);
5963 (define_expand "storehi_bigend"
5964 [(set (match_dup 4) (match_dup 3))
5966 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5967 (set (match_operand 1 "" "") (match_dup 5))]
5971 rtx op1 = operands[1];
5972 rtx addr = XEXP (op1, 0);
5973 enum rtx_code code = GET_CODE (addr);
5975 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5977 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
5979 operands[4] = adjust_address (op1, QImode, 1);
5980 operands[1] = adjust_address (operands[1], QImode, 0);
5981 operands[3] = gen_lowpart (QImode, operands[0]);
5982 operands[0] = gen_lowpart (SImode, operands[0]);
5983 operands[2] = gen_reg_rtx (SImode);
5984 operands[5] = gen_lowpart (QImode, operands[2]);
5988 ;; Subroutine to store a half word integer constant into memory.
5989 (define_expand "storeinthi"
5990 [(set (match_operand 0 "" "")
5991 (match_operand 1 "" ""))
5992 (set (match_dup 3) (match_dup 2))]
5996 HOST_WIDE_INT value = INTVAL (operands[1]);
5997 rtx addr = XEXP (operands[0], 0);
5998 rtx op0 = operands[0];
5999 enum rtx_code code = GET_CODE (addr);
6001 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6003 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6005 operands[1] = gen_reg_rtx (SImode);
6006 if (BYTES_BIG_ENDIAN)
6008 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6009 if ((value & 255) == ((value >> 8) & 255))
6010 operands[2] = operands[1];
6013 operands[2] = gen_reg_rtx (SImode);
6014 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6019 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6020 if ((value & 255) == ((value >> 8) & 255))
6021 operands[2] = operands[1];
6024 operands[2] = gen_reg_rtx (SImode);
6025 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6029 operands[3] = adjust_address (op0, QImode, 1);
6030 operands[0] = adjust_address (operands[0], QImode, 0);
6031 operands[2] = gen_lowpart (QImode, operands[2]);
6032 operands[1] = gen_lowpart (QImode, operands[1]);
6036 (define_expand "storehi_single_op"
6037 [(set (match_operand:HI 0 "memory_operand" "")
6038 (match_operand:HI 1 "general_operand" ""))]
6039 "TARGET_32BIT && arm_arch4"
6041 if (!s_register_operand (operands[1], HImode))
6042 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6046 (define_expand "movhi"
6047 [(set (match_operand:HI 0 "general_operand" "")
6048 (match_operand:HI 1 "general_operand" ""))]
6053 if (can_create_pseudo_p ())
6055 if (MEM_P (operands[0]))
6059 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6062 if (CONST_INT_P (operands[1]))
6063 emit_insn (gen_storeinthi (operands[0], operands[1]));
6066 if (MEM_P (operands[1]))
6067 operands[1] = force_reg (HImode, operands[1]);
6068 if (BYTES_BIG_ENDIAN)
6069 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6071 emit_insn (gen_storehi (operands[1], operands[0]));
6075 /* Sign extend a constant, and keep it in an SImode reg. */
6076 else if (CONST_INT_P (operands[1]))
6078 rtx reg = gen_reg_rtx (SImode);
6079 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6081 /* If the constant is already valid, leave it alone. */
6082 if (!const_ok_for_arm (val))
6084 /* If setting all the top bits will make the constant
6085 loadable in a single instruction, then set them.
6086 Otherwise, sign extend the number. */
6088 if (const_ok_for_arm (~(val | ~0xffff)))
6090 else if (val & 0x8000)
6094 emit_insn (gen_movsi (reg, GEN_INT (val)));
6095 operands[1] = gen_lowpart (HImode, reg);
6097 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6098 && MEM_P (operands[1]))
6100 rtx reg = gen_reg_rtx (SImode);
6102 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6103 operands[1] = gen_lowpart (HImode, reg);
6105 else if (!arm_arch4)
6107 if (MEM_P (operands[1]))
6110 rtx offset = const0_rtx;
6111 rtx reg = gen_reg_rtx (SImode);
6113 if ((REG_P (base = XEXP (operands[1], 0))
6114 || (GET_CODE (base) == PLUS
6115 && (CONST_INT_P (offset = XEXP (base, 1)))
6116 && ((INTVAL(offset) & 1) != 1)
6117 && REG_P (base = XEXP (base, 0))))
6118 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6122 new_rtx = widen_memory_access (operands[1], SImode,
6123 ((INTVAL (offset) & ~3)
6124 - INTVAL (offset)));
6125 emit_insn (gen_movsi (reg, new_rtx));
6126 if (((INTVAL (offset) & 2) != 0)
6127 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6129 rtx reg2 = gen_reg_rtx (SImode);
6131 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6136 emit_insn (gen_movhi_bytes (reg, operands[1]));
6138 operands[1] = gen_lowpart (HImode, reg);
6142 /* Handle loading a large integer during reload. */
6143 else if (CONST_INT_P (operands[1])
6144 && !const_ok_for_arm (INTVAL (operands[1]))
6145 && !const_ok_for_arm (~INTVAL (operands[1])))
6147 /* Writing a constant to memory needs a scratch, which should
6148 be handled with SECONDARY_RELOADs. */
6149 gcc_assert (REG_P (operands[0]));
6151 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6152 emit_insn (gen_movsi (operands[0], operands[1]));
6156 else if (TARGET_THUMB2)
6158 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6159 if (can_create_pseudo_p ())
6161 if (!REG_P (operands[0]))
6162 operands[1] = force_reg (HImode, operands[1]);
6163 /* Zero extend a constant, and keep it in an SImode reg. */
6164 else if (CONST_INT_P (operands[1]))
6166 rtx reg = gen_reg_rtx (SImode);
6167 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6169 emit_insn (gen_movsi (reg, GEN_INT (val)));
6170 operands[1] = gen_lowpart (HImode, reg);
6174 else /* TARGET_THUMB1 */
6176 if (can_create_pseudo_p ())
6178 if (CONST_INT_P (operands[1]))
6180 rtx reg = gen_reg_rtx (SImode);
6182 emit_insn (gen_movsi (reg, operands[1]));
6183 operands[1] = gen_lowpart (HImode, reg);
6186 /* ??? We shouldn't really get invalid addresses here, but this can
6187 happen if we are passed a SP (never OK for HImode/QImode) or
6188 virtual register (also rejected as illegitimate for HImode/QImode)
6189 relative address. */
6190 /* ??? This should perhaps be fixed elsewhere, for instance, in
6191 fixup_stack_1, by checking for other kinds of invalid addresses,
6192 e.g. a bare reference to a virtual register. This may confuse the
6193 alpha though, which must handle this case differently. */
6194 if (MEM_P (operands[0])
6195 && !memory_address_p (GET_MODE (operands[0]),
6196 XEXP (operands[0], 0)))
6198 = replace_equiv_address (operands[0],
6199 copy_to_reg (XEXP (operands[0], 0)));
6201 if (MEM_P (operands[1])
6202 && !memory_address_p (GET_MODE (operands[1]),
6203 XEXP (operands[1], 0)))
6205 = replace_equiv_address (operands[1],
6206 copy_to_reg (XEXP (operands[1], 0)));
6208 if (MEM_P (operands[1]) && optimize > 0)
6210 rtx reg = gen_reg_rtx (SImode);
6212 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6213 operands[1] = gen_lowpart (HImode, reg);
6216 if (MEM_P (operands[0]))
6217 operands[1] = force_reg (HImode, operands[1]);
6219 else if (CONST_INT_P (operands[1])
6220 && !satisfies_constraint_I (operands[1]))
6222 /* Handle loading a large integer during reload. */
6224 /* Writing a constant to memory needs a scratch, which should
6225 be handled with SECONDARY_RELOADs. */
6226 gcc_assert (REG_P (operands[0]));
6228 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6229 emit_insn (gen_movsi (operands[0], operands[1]));
6236 (define_expand "movhi_bytes"
6237 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6239 (zero_extend:SI (match_dup 6)))
6240 (set (match_operand:SI 0 "" "")
6241 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6246 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6248 mem1 = change_address (operands[1], QImode, addr);
6249 mem2 = change_address (operands[1], QImode,
6250 plus_constant (Pmode, addr, 1));
6251 operands[0] = gen_lowpart (SImode, operands[0]);
6253 operands[2] = gen_reg_rtx (SImode);
6254 operands[3] = gen_reg_rtx (SImode);
6257 if (BYTES_BIG_ENDIAN)
6259 operands[4] = operands[2];
6260 operands[5] = operands[3];
6264 operands[4] = operands[3];
6265 operands[5] = operands[2];
6270 (define_expand "movhi_bigend"
6272 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6275 (ashiftrt:SI (match_dup 2) (const_int 16)))
6276 (set (match_operand:HI 0 "s_register_operand" "")
6280 operands[2] = gen_reg_rtx (SImode);
6281 operands[3] = gen_reg_rtx (SImode);
6282 operands[4] = gen_lowpart (HImode, operands[3]);
6286 ;; Pattern to recognize insn generated default case above
6287 (define_insn "*movhi_insn_arch4"
6288 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
6289 (match_operand:HI 1 "general_operand" "rIk,K,r,mi"))]
6292 && (register_operand (operands[0], HImode)
6293 || register_operand (operands[1], HImode))"
6295 mov%?\\t%0, %1\\t%@ movhi
6296 mvn%?\\t%0, #%B1\\t%@ movhi
6297 str%(h%)\\t%1, %0\\t%@ movhi
6298 ldr%(h%)\\t%0, %1\\t%@ movhi"
6299 [(set_attr "predicable" "yes")
6300 (set_attr "pool_range" "*,*,*,256")
6301 (set_attr "neg_pool_range" "*,*,*,244")
6302 (set_attr_alternative "type"
6303 [(if_then_else (match_operand 1 "const_int_operand" "")
6304 (const_string "mov_imm" )
6305 (const_string "mov_reg"))
6306 (const_string "mvn_imm")
6307 (const_string "store1")
6308 (const_string "load1")])]
6311 (define_insn "*movhi_bytes"
6312 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6313 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6316 mov%?\\t%0, %1\\t%@ movhi
6317 mov%?\\t%0, %1\\t%@ movhi
6318 mvn%?\\t%0, #%B1\\t%@ movhi"
6319 [(set_attr "predicable" "yes")
6320 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6323 ;; We use a DImode scratch because we may occasionally need an additional
6324 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6325 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6326 (define_expand "reload_outhi"
6327 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6328 (match_operand:HI 1 "s_register_operand" "r")
6329 (match_operand:DI 2 "s_register_operand" "=&l")])]
6332 arm_reload_out_hi (operands);
6334 thumb_reload_out_hi (operands);
6339 (define_expand "reload_inhi"
6340 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6341 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6342 (match_operand:DI 2 "s_register_operand" "=&r")])]
6346 arm_reload_in_hi (operands);
6348 thumb_reload_out_hi (operands);
6352 (define_expand "movqi"
6353 [(set (match_operand:QI 0 "general_operand" "")
6354 (match_operand:QI 1 "general_operand" ""))]
6357 /* Everything except mem = const or mem = mem can be done easily */
6359 if (can_create_pseudo_p ())
6361 if (CONST_INT_P (operands[1]))
6363 rtx reg = gen_reg_rtx (SImode);
6365 /* For thumb we want an unsigned immediate, then we are more likely
6366 to be able to use a movs insn. */
6368 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6370 emit_insn (gen_movsi (reg, operands[1]));
6371 operands[1] = gen_lowpart (QImode, reg);
6376 /* ??? We shouldn't really get invalid addresses here, but this can
6377 happen if we are passed a SP (never OK for HImode/QImode) or
6378 virtual register (also rejected as illegitimate for HImode/QImode)
6379 relative address. */
6380 /* ??? This should perhaps be fixed elsewhere, for instance, in
6381 fixup_stack_1, by checking for other kinds of invalid addresses,
6382 e.g. a bare reference to a virtual register. This may confuse the
6383 alpha though, which must handle this case differently. */
6384 if (MEM_P (operands[0])
6385 && !memory_address_p (GET_MODE (operands[0]),
6386 XEXP (operands[0], 0)))
6388 = replace_equiv_address (operands[0],
6389 copy_to_reg (XEXP (operands[0], 0)));
6390 if (MEM_P (operands[1])
6391 && !memory_address_p (GET_MODE (operands[1]),
6392 XEXP (operands[1], 0)))
6394 = replace_equiv_address (operands[1],
6395 copy_to_reg (XEXP (operands[1], 0)));
6398 if (MEM_P (operands[1]) && optimize > 0)
6400 rtx reg = gen_reg_rtx (SImode);
6402 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6403 operands[1] = gen_lowpart (QImode, reg);
6406 if (MEM_P (operands[0]))
6407 operands[1] = force_reg (QImode, operands[1]);
6409 else if (TARGET_THUMB
6410 && CONST_INT_P (operands[1])
6411 && !satisfies_constraint_I (operands[1]))
6413 /* Handle loading a large integer during reload. */
6415 /* Writing a constant to memory needs a scratch, which should
6416 be handled with SECONDARY_RELOADs. */
6417 gcc_assert (REG_P (operands[0]));
6419 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6420 emit_insn (gen_movsi (operands[0], operands[1]));
6426 (define_insn "*arm_movqi_insn"
6427 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6428 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,m,r"))]
6430 && ( register_operand (operands[0], QImode)
6431 || register_operand (operands[1], QImode))"
6442 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6443 (set_attr "predicable" "yes")
6444 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6445 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6446 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6450 (define_expand "movhf"
6451 [(set (match_operand:HF 0 "general_operand" "")
6452 (match_operand:HF 1 "general_operand" ""))]
6457 if (MEM_P (operands[0]))
6458 operands[1] = force_reg (HFmode, operands[1]);
6460 else /* TARGET_THUMB1 */
6462 if (can_create_pseudo_p ())
6464 if (!REG_P (operands[0]))
6465 operands[1] = force_reg (HFmode, operands[1]);
6471 (define_insn "*arm32_movhf"
6472 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6473 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6474 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
6475 && ( s_register_operand (operands[0], HFmode)
6476 || s_register_operand (operands[1], HFmode))"
6478 switch (which_alternative)
6480 case 0: /* ARM register from memory */
6481 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6482 case 1: /* memory from ARM register */
6483 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6484 case 2: /* ARM register from ARM register */
6485 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6486 case 3: /* ARM register from constant */
6492 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6493 bits = real_to_target (NULL, &r, HFmode);
6494 ops[0] = operands[0];
6495 ops[1] = GEN_INT (bits);
6496 ops[2] = GEN_INT (bits & 0xff00);
6497 ops[3] = GEN_INT (bits & 0x00ff);
6499 if (arm_arch_thumb2)
6500 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6502 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6509 [(set_attr "conds" "unconditional")
6510 (set_attr "type" "load1,store1,mov_reg,multiple")
6511 (set_attr "length" "4,4,4,8")
6512 (set_attr "predicable" "yes")]
6515 (define_expand "movsf"
6516 [(set (match_operand:SF 0 "general_operand" "")
6517 (match_operand:SF 1 "general_operand" ""))]
6522 if (MEM_P (operands[0]))
6523 operands[1] = force_reg (SFmode, operands[1]);
6525 else /* TARGET_THUMB1 */
6527 if (can_create_pseudo_p ())
6529 if (!REG_P (operands[0]))
6530 operands[1] = force_reg (SFmode, operands[1]);
6536 ;; Transform a floating-point move of a constant into a core register into
6537 ;; an SImode operation.
6539 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6540 (match_operand:SF 1 "immediate_operand" ""))]
6543 && CONST_DOUBLE_P (operands[1])"
6544 [(set (match_dup 2) (match_dup 3))]
6546 operands[2] = gen_lowpart (SImode, operands[0]);
6547 operands[3] = gen_lowpart (SImode, operands[1]);
6548 if (operands[2] == 0 || operands[3] == 0)
6553 (define_insn "*arm_movsf_soft_insn"
6554 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6555 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6557 && TARGET_SOFT_FLOAT
6558 && (!MEM_P (operands[0])
6559 || register_operand (operands[1], SFmode))"
6562 ldr%?\\t%0, %1\\t%@ float
6563 str%?\\t%1, %0\\t%@ float"
6564 [(set_attr "predicable" "yes")
6565 (set_attr "predicable_short_it" "no")
6566 (set_attr "type" "mov_reg,load1,store1")
6567 (set_attr "arm_pool_range" "*,4096,*")
6568 (set_attr "thumb2_pool_range" "*,4094,*")
6569 (set_attr "arm_neg_pool_range" "*,4084,*")
6570 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6573 (define_expand "movdf"
6574 [(set (match_operand:DF 0 "general_operand" "")
6575 (match_operand:DF 1 "general_operand" ""))]
6580 if (MEM_P (operands[0]))
6581 operands[1] = force_reg (DFmode, operands[1]);
6583 else /* TARGET_THUMB */
6585 if (can_create_pseudo_p ())
6587 if (!REG_P (operands[0]))
6588 operands[1] = force_reg (DFmode, operands[1]);
6594 ;; Reloading a df mode value stored in integer regs to memory can require a
6596 (define_expand "reload_outdf"
6597 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6598 (match_operand:DF 1 "s_register_operand" "r")
6599 (match_operand:SI 2 "s_register_operand" "=&r")]
6603 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6606 operands[2] = XEXP (operands[0], 0);
6607 else if (code == POST_INC || code == PRE_DEC)
6609 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6610 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6611 emit_insn (gen_movdi (operands[0], operands[1]));
6614 else if (code == PRE_INC)
6616 rtx reg = XEXP (XEXP (operands[0], 0), 0);
6618 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6621 else if (code == POST_DEC)
6622 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6624 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6625 XEXP (XEXP (operands[0], 0), 1)));
6627 emit_insn (gen_rtx_SET (VOIDmode,
6628 replace_equiv_address (operands[0], operands[2]),
6631 if (code == POST_DEC)
6632 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6638 (define_insn "*movdf_soft_insn"
6639 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6640 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
6641 "TARGET_32BIT && TARGET_SOFT_FLOAT
6642 && ( register_operand (operands[0], DFmode)
6643 || register_operand (operands[1], DFmode))"
6645 switch (which_alternative)
6652 return output_move_double (operands, true, NULL);
6655 [(set_attr "length" "8,12,16,8,8")
6656 (set_attr "type" "multiple,multiple,multiple,load2,store2")
6657 (set_attr "arm_pool_range" "*,*,*,1020,*")
6658 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6659 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6660 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6664 ;; load- and store-multiple insns
6665 ;; The arm can load/store any set of registers, provided that they are in
6666 ;; ascending order, but these expanders assume a contiguous set.
6668 (define_expand "load_multiple"
6669 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6670 (match_operand:SI 1 "" ""))
6671 (use (match_operand:SI 2 "" ""))])]
6674 HOST_WIDE_INT offset = 0;
6676 /* Support only fixed point registers. */
6677 if (!CONST_INT_P (operands[2])
6678 || INTVAL (operands[2]) > 14
6679 || INTVAL (operands[2]) < 2
6680 || !MEM_P (operands[1])
6681 || !REG_P (operands[0])
6682 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6683 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6687 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6688 INTVAL (operands[2]),
6689 force_reg (SImode, XEXP (operands[1], 0)),
6690 FALSE, operands[1], &offset);
6693 (define_expand "store_multiple"
6694 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6695 (match_operand:SI 1 "" ""))
6696 (use (match_operand:SI 2 "" ""))])]
6699 HOST_WIDE_INT offset = 0;
6701 /* Support only fixed point registers. */
6702 if (!CONST_INT_P (operands[2])
6703 || INTVAL (operands[2]) > 14
6704 || INTVAL (operands[2]) < 2
6705 || !REG_P (operands[1])
6706 || !MEM_P (operands[0])
6707 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6708 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6712 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6713 INTVAL (operands[2]),
6714 force_reg (SImode, XEXP (operands[0], 0)),
6715 FALSE, operands[0], &offset);
6719 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6720 ;; We could let this apply for blocks of less than this, but it clobbers so
6721 ;; many registers that there is then probably a better way.
6723 (define_expand "movmemqi"
6724 [(match_operand:BLK 0 "general_operand" "")
6725 (match_operand:BLK 1 "general_operand" "")
6726 (match_operand:SI 2 "const_int_operand" "")
6727 (match_operand:SI 3 "const_int_operand" "")]
6732 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6733 && !optimize_function_for_size_p (cfun))
6735 if (gen_movmem_ldrd_strd (operands))
6740 if (arm_gen_movmemqi (operands))
6744 else /* TARGET_THUMB1 */
6746 if ( INTVAL (operands[3]) != 4
6747 || INTVAL (operands[2]) > 48)
6750 thumb_expand_movmemqi (operands);
6757 ;; Compare & branch insns
6758 ;; The range calculations are based as follows:
6759 ;; For forward branches, the address calculation returns the address of
6760 ;; the next instruction. This is 2 beyond the branch instruction.
6761 ;; For backward branches, the address calculation returns the address of
6762 ;; the first instruction in this pattern (cmp). This is 2 before the branch
6763 ;; instruction for the shortest sequence, and 4 before the branch instruction
6764 ;; if we have to jump around an unconditional branch.
6765 ;; To the basic branch range the PC offset must be added (this is +4).
6766 ;; So for forward branches we have
6767 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6768 ;; And for backward branches we have
6769 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6771 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6772 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
6774 (define_expand "cbranchsi4"
6775 [(set (pc) (if_then_else
6776 (match_operator 0 "expandable_comparison_operator"
6777 [(match_operand:SI 1 "s_register_operand" "")
6778 (match_operand:SI 2 "nonmemory_operand" "")])
6779 (label_ref (match_operand 3 "" ""))
6785 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6787 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6791 if (thumb1_cmpneg_operand (operands[2], SImode))
6793 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6794 operands[3], operands[0]));
6797 if (!thumb1_cmp_operand (operands[2], SImode))
6798 operands[2] = force_reg (SImode, operands[2]);
6801 (define_expand "cbranchsf4"
6802 [(set (pc) (if_then_else
6803 (match_operator 0 "expandable_comparison_operator"
6804 [(match_operand:SF 1 "s_register_operand" "")
6805 (match_operand:SF 2 "arm_float_compare_operand" "")])
6806 (label_ref (match_operand 3 "" ""))
6808 "TARGET_32BIT && TARGET_HARD_FLOAT"
6809 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6810 operands[3])); DONE;"
6813 (define_expand "cbranchdf4"
6814 [(set (pc) (if_then_else
6815 (match_operator 0 "expandable_comparison_operator"
6816 [(match_operand:DF 1 "s_register_operand" "")
6817 (match_operand:DF 2 "arm_float_compare_operand" "")])
6818 (label_ref (match_operand 3 "" ""))
6820 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6821 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6822 operands[3])); DONE;"
6825 (define_expand "cbranchdi4"
6826 [(set (pc) (if_then_else
6827 (match_operator 0 "expandable_comparison_operator"
6828 [(match_operand:DI 1 "s_register_operand" "")
6829 (match_operand:DI 2 "cmpdi_operand" "")])
6830 (label_ref (match_operand 3 "" ""))
6834 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6836 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6842 ;; Comparison and test insns
6844 (define_insn "*arm_cmpsi_insn"
6845 [(set (reg:CC CC_REGNUM)
6846 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6847 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
6855 [(set_attr "conds" "set")
6856 (set_attr "arch" "t2,t2,any,any,any")
6857 (set_attr "length" "2,2,4,4,4")
6858 (set_attr "predicable" "yes")
6859 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6860 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6863 (define_insn "*cmpsi_shiftsi"
6864 [(set (reg:CC CC_REGNUM)
6865 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
6866 (match_operator:SI 3 "shift_operator"
6867 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6868 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6871 [(set_attr "conds" "set")
6872 (set_attr "shift" "1")
6873 (set_attr "arch" "32,a,a")
6874 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
6876 (define_insn "*cmpsi_shiftsi_swp"
6877 [(set (reg:CC_SWP CC_REGNUM)
6878 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6879 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6880 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6881 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6884 [(set_attr "conds" "set")
6885 (set_attr "shift" "1")
6886 (set_attr "arch" "32,a,a")
6887 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
6889 (define_insn "*arm_cmpsi_negshiftsi_si"
6890 [(set (reg:CC_Z CC_REGNUM)
6892 (neg:SI (match_operator:SI 1 "shift_operator"
6893 [(match_operand:SI 2 "s_register_operand" "r")
6894 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6895 (match_operand:SI 0 "s_register_operand" "r")))]
6898 [(set_attr "conds" "set")
6899 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6900 (const_string "alus_shift_imm")
6901 (const_string "alus_shift_reg")))
6902 (set_attr "predicable" "yes")]
6905 ;; DImode comparisons. The generic code generates branches that
6906 ;; if-conversion can not reduce to a conditional compare, so we do
6909 (define_insn_and_split "*arm_cmpdi_insn"
6910 [(set (reg:CC_NCV CC_REGNUM)
6911 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6912 (match_operand:DI 1 "arm_di_operand" "rDi")))
6913 (clobber (match_scratch:SI 2 "=r"))]
6915 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6916 "&& reload_completed"
6917 [(set (reg:CC CC_REGNUM)
6918 (compare:CC (match_dup 0) (match_dup 1)))
6919 (parallel [(set (reg:CC CC_REGNUM)
6920 (compare:CC (match_dup 3) (match_dup 4)))
6922 (minus:SI (match_dup 5)
6923 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6925 operands[3] = gen_highpart (SImode, operands[0]);
6926 operands[0] = gen_lowpart (SImode, operands[0]);
6927 if (CONST_INT_P (operands[1]))
6929 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
6932 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
6936 operands[4] = gen_highpart (SImode, operands[1]);
6937 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6939 operands[1] = gen_lowpart (SImode, operands[1]);
6940 operands[2] = gen_lowpart (SImode, operands[2]);
6942 [(set_attr "conds" "set")
6943 (set_attr "length" "8")
6944 (set_attr "type" "multiple")]
6947 (define_insn_and_split "*arm_cmpdi_unsigned"
6948 [(set (reg:CC_CZ CC_REGNUM)
6949 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6950 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
6953 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6954 "&& reload_completed"
6955 [(set (reg:CC CC_REGNUM)
6956 (compare:CC (match_dup 2) (match_dup 3)))
6957 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6958 (set (reg:CC CC_REGNUM)
6959 (compare:CC (match_dup 0) (match_dup 1))))]
6961 operands[2] = gen_highpart (SImode, operands[0]);
6962 operands[0] = gen_lowpart (SImode, operands[0]);
6963 if (CONST_INT_P (operands[1]))
6964 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6966 operands[3] = gen_highpart (SImode, operands[1]);
6967 operands[1] = gen_lowpart (SImode, operands[1]);
6969 [(set_attr "conds" "set")
6970 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
6971 (set_attr "arch" "t2,t2,t2,a")
6972 (set_attr "length" "6,6,10,8")
6973 (set_attr "type" "multiple")]
6976 (define_insn "*arm_cmpdi_zero"
6977 [(set (reg:CC_Z CC_REGNUM)
6978 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6980 (clobber (match_scratch:SI 1 "=r"))]
6982 "orr%.\\t%1, %Q0, %R0"
6983 [(set_attr "conds" "set")
6984 (set_attr "type" "logics_reg")]
6987 ; This insn allows redundant compares to be removed by cse, nothing should
6988 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6989 ; is deleted later on. The match_dup will match the mode here, so that
6990 ; mode changes of the condition codes aren't lost by this even though we don't
6991 ; specify what they are.
6993 (define_insn "*deleted_compare"
6994 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6996 "\\t%@ deleted compare"
6997 [(set_attr "conds" "set")
6998 (set_attr "length" "0")
6999 (set_attr "type" "no_insn")]
7003 ;; Conditional branch insns
7005 (define_expand "cbranch_cc"
7007 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7008 (match_operand 2 "" "")])
7009 (label_ref (match_operand 3 "" ""))
7012 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7013 operands[1], operands[2], NULL_RTX);
7014 operands[2] = const0_rtx;"
7018 ;; Patterns to match conditional branch insns.
7021 (define_insn "arm_cond_branch"
7023 (if_then_else (match_operator 1 "arm_comparison_operator"
7024 [(match_operand 2 "cc_register" "") (const_int 0)])
7025 (label_ref (match_operand 0 "" ""))
7029 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7031 arm_ccfsm_state += 2;
7034 return \"b%d1\\t%l0\";
7036 [(set_attr "conds" "use")
7037 (set_attr "type" "branch")
7038 (set (attr "length")
7040 (and (match_test "TARGET_THUMB2")
7041 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7042 (le (minus (match_dup 0) (pc)) (const_int 256))))
7047 (define_insn "*arm_cond_branch_reversed"
7049 (if_then_else (match_operator 1 "arm_comparison_operator"
7050 [(match_operand 2 "cc_register" "") (const_int 0)])
7052 (label_ref (match_operand 0 "" ""))))]
7055 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7057 arm_ccfsm_state += 2;
7060 return \"b%D1\\t%l0\";
7062 [(set_attr "conds" "use")
7063 (set_attr "type" "branch")
7064 (set (attr "length")
7066 (and (match_test "TARGET_THUMB2")
7067 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7068 (le (minus (match_dup 0) (pc)) (const_int 256))))
7077 (define_expand "cstore_cc"
7078 [(set (match_operand:SI 0 "s_register_operand" "")
7079 (match_operator:SI 1 "" [(match_operand 2 "" "")
7080 (match_operand 3 "" "")]))]
7082 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7083 operands[2], operands[3], NULL_RTX);
7084 operands[3] = const0_rtx;"
7087 (define_insn_and_split "*mov_scc"
7088 [(set (match_operand:SI 0 "s_register_operand" "=r")
7089 (match_operator:SI 1 "arm_comparison_operator"
7090 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7092 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7095 (if_then_else:SI (match_dup 1)
7099 [(set_attr "conds" "use")
7100 (set_attr "length" "8")
7101 (set_attr "type" "multiple")]
7104 (define_insn_and_split "*mov_negscc"
7105 [(set (match_operand:SI 0 "s_register_operand" "=r")
7106 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7107 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7109 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7112 (if_then_else:SI (match_dup 1)
7116 operands[3] = GEN_INT (~0);
7118 [(set_attr "conds" "use")
7119 (set_attr "length" "8")
7120 (set_attr "type" "multiple")]
7123 (define_insn_and_split "*mov_notscc"
7124 [(set (match_operand:SI 0 "s_register_operand" "=r")
7125 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7126 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7128 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7131 (if_then_else:SI (match_dup 1)
7135 operands[3] = GEN_INT (~1);
7136 operands[4] = GEN_INT (~0);
7138 [(set_attr "conds" "use")
7139 (set_attr "length" "8")
7140 (set_attr "type" "multiple")]
7143 (define_expand "cstoresi4"
7144 [(set (match_operand:SI 0 "s_register_operand" "")
7145 (match_operator:SI 1 "expandable_comparison_operator"
7146 [(match_operand:SI 2 "s_register_operand" "")
7147 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7148 "TARGET_32BIT || TARGET_THUMB1"
7150 rtx op3, scratch, scratch2;
7154 if (!arm_add_operand (operands[3], SImode))
7155 operands[3] = force_reg (SImode, operands[3]);
7156 emit_insn (gen_cstore_cc (operands[0], operands[1],
7157 operands[2], operands[3]));
7161 if (operands[3] == const0_rtx)
7163 switch (GET_CODE (operands[1]))
7166 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7170 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7174 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7175 NULL_RTX, 0, OPTAB_WIDEN);
7176 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7177 NULL_RTX, 0, OPTAB_WIDEN);
7178 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7179 operands[0], 1, OPTAB_WIDEN);
7183 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7185 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7186 NULL_RTX, 1, OPTAB_WIDEN);
7190 scratch = expand_binop (SImode, ashr_optab, operands[2],
7191 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7192 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7193 NULL_RTX, 0, OPTAB_WIDEN);
7194 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7198 /* LT is handled by generic code. No need for unsigned with 0. */
7205 switch (GET_CODE (operands[1]))
7208 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7209 NULL_RTX, 0, OPTAB_WIDEN);
7210 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7214 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7215 NULL_RTX, 0, OPTAB_WIDEN);
7216 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7220 op3 = force_reg (SImode, operands[3]);
7222 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7223 NULL_RTX, 1, OPTAB_WIDEN);
7224 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7225 NULL_RTX, 0, OPTAB_WIDEN);
7226 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7232 if (!thumb1_cmp_operand (op3, SImode))
7233 op3 = force_reg (SImode, op3);
7234 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7235 NULL_RTX, 0, OPTAB_WIDEN);
7236 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7237 NULL_RTX, 1, OPTAB_WIDEN);
7238 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7243 op3 = force_reg (SImode, operands[3]);
7244 scratch = force_reg (SImode, const0_rtx);
7245 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7251 if (!thumb1_cmp_operand (op3, SImode))
7252 op3 = force_reg (SImode, op3);
7253 scratch = force_reg (SImode, const0_rtx);
7254 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7260 if (!thumb1_cmp_operand (op3, SImode))
7261 op3 = force_reg (SImode, op3);
7262 scratch = gen_reg_rtx (SImode);
7263 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7267 op3 = force_reg (SImode, operands[3]);
7268 scratch = gen_reg_rtx (SImode);
7269 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7272 /* No good sequences for GT, LT. */
7279 (define_expand "cstoresf4"
7280 [(set (match_operand:SI 0 "s_register_operand" "")
7281 (match_operator:SI 1 "expandable_comparison_operator"
7282 [(match_operand:SF 2 "s_register_operand" "")
7283 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7284 "TARGET_32BIT && TARGET_HARD_FLOAT"
7285 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7286 operands[2], operands[3])); DONE;"
7289 (define_expand "cstoredf4"
7290 [(set (match_operand:SI 0 "s_register_operand" "")
7291 (match_operator:SI 1 "expandable_comparison_operator"
7292 [(match_operand:DF 2 "s_register_operand" "")
7293 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7294 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7295 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7296 operands[2], operands[3])); DONE;"
7299 (define_expand "cstoredi4"
7300 [(set (match_operand:SI 0 "s_register_operand" "")
7301 (match_operator:SI 1 "expandable_comparison_operator"
7302 [(match_operand:DI 2 "s_register_operand" "")
7303 (match_operand:DI 3 "cmpdi_operand" "")]))]
7306 if (!arm_validize_comparison (&operands[1],
7310 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7317 ;; Conditional move insns
7319 (define_expand "movsicc"
7320 [(set (match_operand:SI 0 "s_register_operand" "")
7321 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7322 (match_operand:SI 2 "arm_not_operand" "")
7323 (match_operand:SI 3 "arm_not_operand" "")))]
7330 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7331 &XEXP (operands[1], 1)))
7334 code = GET_CODE (operands[1]);
7335 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7336 XEXP (operands[1], 1), NULL_RTX);
7337 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7341 (define_expand "movsfcc"
7342 [(set (match_operand:SF 0 "s_register_operand" "")
7343 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7344 (match_operand:SF 2 "s_register_operand" "")
7345 (match_operand:SF 3 "s_register_operand" "")))]
7346 "TARGET_32BIT && TARGET_HARD_FLOAT"
7349 enum rtx_code code = GET_CODE (operands[1]);
7352 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7353 &XEXP (operands[1], 1)))
7356 code = GET_CODE (operands[1]);
7357 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7358 XEXP (operands[1], 1), NULL_RTX);
7359 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7363 (define_expand "movdfcc"
7364 [(set (match_operand:DF 0 "s_register_operand" "")
7365 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7366 (match_operand:DF 2 "s_register_operand" "")
7367 (match_operand:DF 3 "s_register_operand" "")))]
7368 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7371 enum rtx_code code = GET_CODE (operands[1]);
7374 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7375 &XEXP (operands[1], 1)))
7377 code = GET_CODE (operands[1]);
7378 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7379 XEXP (operands[1], 1), NULL_RTX);
7380 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7384 (define_insn "*cmov<mode>"
7385 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7386 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7387 [(match_operand 2 "cc_register" "") (const_int 0)])
7388 (match_operand:SDF 3 "s_register_operand"
7390 (match_operand:SDF 4 "s_register_operand"
7391 "<F_constraint>")))]
7392 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7395 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7402 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7407 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7413 [(set_attr "conds" "use")
7414 (set_attr "type" "fcsel")]
7417 (define_insn_and_split "*movsicc_insn"
7418 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7420 (match_operator 3 "arm_comparison_operator"
7421 [(match_operand 4 "cc_register" "") (const_int 0)])
7422 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7423 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7434 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7435 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7436 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7437 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7438 "&& reload_completed"
7441 enum rtx_code rev_code;
7442 enum machine_mode mode;
7445 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7447 gen_rtx_SET (VOIDmode,
7451 rev_code = GET_CODE (operands[3]);
7452 mode = GET_MODE (operands[4]);
7453 if (mode == CCFPmode || mode == CCFPEmode)
7454 rev_code = reverse_condition_maybe_unordered (rev_code);
7456 rev_code = reverse_condition (rev_code);
7458 rev_cond = gen_rtx_fmt_ee (rev_code,
7462 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7464 gen_rtx_SET (VOIDmode,
7469 [(set_attr "length" "4,4,4,4,8,8,8,8")
7470 (set_attr "conds" "use")
7471 (set_attr_alternative "type"
7472 [(if_then_else (match_operand 2 "const_int_operand" "")
7473 (const_string "mov_imm")
7474 (const_string "mov_reg"))
7475 (const_string "mvn_imm")
7476 (if_then_else (match_operand 1 "const_int_operand" "")
7477 (const_string "mov_imm")
7478 (const_string "mov_reg"))
7479 (const_string "mvn_imm")
7480 (const_string "mov_reg")
7481 (const_string "mov_reg")
7482 (const_string "mov_reg")
7483 (const_string "mov_reg")])]
7486 (define_insn "*movsfcc_soft_insn"
7487 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7488 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7489 [(match_operand 4 "cc_register" "") (const_int 0)])
7490 (match_operand:SF 1 "s_register_operand" "0,r")
7491 (match_operand:SF 2 "s_register_operand" "r,0")))]
7492 "TARGET_ARM && TARGET_SOFT_FLOAT"
7496 [(set_attr "conds" "use")
7497 (set_attr "type" "mov_reg")]
7501 ;; Jump and linkage insns
7503 (define_expand "jump"
7505 (label_ref (match_operand 0 "" "")))]
7510 (define_insn "*arm_jump"
7512 (label_ref (match_operand 0 "" "")))]
7516 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7518 arm_ccfsm_state += 2;
7521 return \"b%?\\t%l0\";
7524 [(set_attr "predicable" "yes")
7525 (set (attr "length")
7527 (and (match_test "TARGET_THUMB2")
7528 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7529 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7532 (set_attr "type" "branch")]
7535 (define_expand "call"
7536 [(parallel [(call (match_operand 0 "memory_operand" "")
7537 (match_operand 1 "general_operand" ""))
7538 (use (match_operand 2 "" ""))
7539 (clobber (reg:SI LR_REGNUM))])]
7545 /* In an untyped call, we can get NULL for operand 2. */
7546 if (operands[2] == NULL_RTX)
7547 operands[2] = const0_rtx;
7549 /* Decide if we should generate indirect calls by loading the
7550 32-bit address of the callee into a register before performing the
7552 callee = XEXP (operands[0], 0);
7553 if (GET_CODE (callee) == SYMBOL_REF
7554 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7556 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7558 pat = gen_call_internal (operands[0], operands[1], operands[2]);
7559 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7564 (define_expand "call_internal"
7565 [(parallel [(call (match_operand 0 "memory_operand" "")
7566 (match_operand 1 "general_operand" ""))
7567 (use (match_operand 2 "" ""))
7568 (clobber (reg:SI LR_REGNUM))])])
7570 (define_insn "*call_reg_armv5"
7571 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7572 (match_operand 1 "" ""))
7573 (use (match_operand 2 "" ""))
7574 (clobber (reg:SI LR_REGNUM))]
7575 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7577 [(set_attr "type" "call")]
7580 (define_insn "*call_reg_arm"
7581 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7582 (match_operand 1 "" ""))
7583 (use (match_operand 2 "" ""))
7584 (clobber (reg:SI LR_REGNUM))]
7585 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7587 return output_call (operands);
7589 ;; length is worst case, normally it is only two
7590 [(set_attr "length" "12")
7591 (set_attr "type" "call")]
7595 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7596 ;; considered a function call by the branch predictor of some cores (PR40887).
7597 ;; Falls back to blx rN (*call_reg_armv5).
7599 (define_insn "*call_mem"
7600 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
7601 (match_operand 1 "" ""))
7602 (use (match_operand 2 "" ""))
7603 (clobber (reg:SI LR_REGNUM))]
7604 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7606 return output_call_mem (operands);
7608 [(set_attr "length" "12")
7609 (set_attr "type" "call")]
7612 (define_expand "call_value"
7613 [(parallel [(set (match_operand 0 "" "")
7614 (call (match_operand 1 "memory_operand" "")
7615 (match_operand 2 "general_operand" "")))
7616 (use (match_operand 3 "" ""))
7617 (clobber (reg:SI LR_REGNUM))])]
7623 /* In an untyped call, we can get NULL for operand 2. */
7624 if (operands[3] == 0)
7625 operands[3] = const0_rtx;
7627 /* Decide if we should generate indirect calls by loading the
7628 32-bit address of the callee into a register before performing the
7630 callee = XEXP (operands[1], 0);
7631 if (GET_CODE (callee) == SYMBOL_REF
7632 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7634 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7636 pat = gen_call_value_internal (operands[0], operands[1],
7637 operands[2], operands[3]);
7638 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7643 (define_expand "call_value_internal"
7644 [(parallel [(set (match_operand 0 "" "")
7645 (call (match_operand 1 "memory_operand" "")
7646 (match_operand 2 "general_operand" "")))
7647 (use (match_operand 3 "" ""))
7648 (clobber (reg:SI LR_REGNUM))])])
7650 (define_insn "*call_value_reg_armv5"
7651 [(set (match_operand 0 "" "")
7652 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7653 (match_operand 2 "" "")))
7654 (use (match_operand 3 "" ""))
7655 (clobber (reg:SI LR_REGNUM))]
7656 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7658 [(set_attr "type" "call")]
7661 (define_insn "*call_value_reg_arm"
7662 [(set (match_operand 0 "" "")
7663 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7664 (match_operand 2 "" "")))
7665 (use (match_operand 3 "" ""))
7666 (clobber (reg:SI LR_REGNUM))]
7667 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7669 return output_call (&operands[1]);
7671 [(set_attr "length" "12")
7672 (set_attr "type" "call")]
7675 ;; Note: see *call_mem
7677 (define_insn "*call_value_mem"
7678 [(set (match_operand 0 "" "")
7679 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
7680 (match_operand 2 "" "")))
7681 (use (match_operand 3 "" ""))
7682 (clobber (reg:SI LR_REGNUM))]
7683 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7684 && !SIBLING_CALL_P (insn)"
7686 return output_call_mem (&operands[1]);
7688 [(set_attr "length" "12")
7689 (set_attr "type" "call")]
7692 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7693 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7695 (define_insn "*call_symbol"
7696 [(call (mem:SI (match_operand:SI 0 "" ""))
7697 (match_operand 1 "" ""))
7698 (use (match_operand 2 "" ""))
7699 (clobber (reg:SI LR_REGNUM))]
7701 && !SIBLING_CALL_P (insn)
7702 && (GET_CODE (operands[0]) == SYMBOL_REF)
7703 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7706 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7708 [(set_attr "type" "call")]
7711 (define_insn "*call_value_symbol"
7712 [(set (match_operand 0 "" "")
7713 (call (mem:SI (match_operand:SI 1 "" ""))
7714 (match_operand:SI 2 "" "")))
7715 (use (match_operand 3 "" ""))
7716 (clobber (reg:SI LR_REGNUM))]
7718 && !SIBLING_CALL_P (insn)
7719 && (GET_CODE (operands[1]) == SYMBOL_REF)
7720 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7723 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7725 [(set_attr "type" "call")]
7728 (define_expand "sibcall_internal"
7729 [(parallel [(call (match_operand 0 "memory_operand" "")
7730 (match_operand 1 "general_operand" ""))
7732 (use (match_operand 2 "" ""))])])
7734 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7735 (define_expand "sibcall"
7736 [(parallel [(call (match_operand 0 "memory_operand" "")
7737 (match_operand 1 "general_operand" ""))
7739 (use (match_operand 2 "" ""))])]
7745 if ((!REG_P (XEXP (operands[0], 0))
7746 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7747 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7748 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7749 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7751 if (operands[2] == NULL_RTX)
7752 operands[2] = const0_rtx;
7754 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7755 arm_emit_call_insn (pat, operands[0], true);
7760 (define_expand "sibcall_value_internal"
7761 [(parallel [(set (match_operand 0 "" "")
7762 (call (match_operand 1 "memory_operand" "")
7763 (match_operand 2 "general_operand" "")))
7765 (use (match_operand 3 "" ""))])])
7767 (define_expand "sibcall_value"
7768 [(parallel [(set (match_operand 0 "" "")
7769 (call (match_operand 1 "memory_operand" "")
7770 (match_operand 2 "general_operand" "")))
7772 (use (match_operand 3 "" ""))])]
7778 if ((!REG_P (XEXP (operands[1], 0))
7779 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7780 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7781 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7782 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7784 if (operands[3] == NULL_RTX)
7785 operands[3] = const0_rtx;
7787 pat = gen_sibcall_value_internal (operands[0], operands[1],
7788 operands[2], operands[3]);
7789 arm_emit_call_insn (pat, operands[1], true);
7794 (define_insn "*sibcall_insn"
7795 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7796 (match_operand 1 "" ""))
7798 (use (match_operand 2 "" ""))]
7799 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7801 if (which_alternative == 1)
7802 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7805 if (arm_arch5 || arm_arch4t)
7806 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7808 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7811 [(set_attr "type" "call")]
7814 (define_insn "*sibcall_value_insn"
7815 [(set (match_operand 0 "" "")
7816 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7817 (match_operand 2 "" "")))
7819 (use (match_operand 3 "" ""))]
7820 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7822 if (which_alternative == 1)
7823 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7826 if (arm_arch5 || arm_arch4t)
7827 return \"bx%?\\t%1\";
7829 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7832 [(set_attr "type" "call")]
7835 (define_expand "<return_str>return"
7837 "(TARGET_ARM || (TARGET_THUMB2
7838 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7839 && !IS_STACKALIGN (arm_current_func_type ())))
7840 <return_cond_false>"
7845 thumb2_expand_return (<return_simple_p>);
7852 ;; Often the return insn will be the same as loading from memory, so set attr
7853 (define_insn "*arm_return"
7855 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7858 if (arm_ccfsm_state == 2)
7860 arm_ccfsm_state += 2;
7863 return output_return_instruction (const_true_rtx, true, false, false);
7865 [(set_attr "type" "load1")
7866 (set_attr "length" "12")
7867 (set_attr "predicable" "yes")]
7870 (define_insn "*cond_<return_str>return"
7872 (if_then_else (match_operator 0 "arm_comparison_operator"
7873 [(match_operand 1 "cc_register" "") (const_int 0)])
7876 "TARGET_ARM <return_cond_true>"
7879 if (arm_ccfsm_state == 2)
7881 arm_ccfsm_state += 2;
7884 return output_return_instruction (operands[0], true, false,
7887 [(set_attr "conds" "use")
7888 (set_attr "length" "12")
7889 (set_attr "type" "load1")]
7892 (define_insn "*cond_<return_str>return_inverted"
7894 (if_then_else (match_operator 0 "arm_comparison_operator"
7895 [(match_operand 1 "cc_register" "") (const_int 0)])
7898 "TARGET_ARM <return_cond_true>"
7901 if (arm_ccfsm_state == 2)
7903 arm_ccfsm_state += 2;
7906 return output_return_instruction (operands[0], true, true,
7909 [(set_attr "conds" "use")
7910 (set_attr "length" "12")
7911 (set_attr "type" "load1")]
7914 (define_insn "*arm_simple_return"
7919 if (arm_ccfsm_state == 2)
7921 arm_ccfsm_state += 2;
7924 return output_return_instruction (const_true_rtx, true, false, true);
7926 [(set_attr "type" "branch")
7927 (set_attr "length" "4")
7928 (set_attr "predicable" "yes")]
7931 ;; Generate a sequence of instructions to determine if the processor is
7932 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7935 (define_expand "return_addr_mask"
7937 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7939 (set (match_operand:SI 0 "s_register_operand" "")
7940 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7942 (const_int 67108860)))] ; 0x03fffffc
7945 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7948 (define_insn "*check_arch2"
7949 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7950 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7953 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7954 [(set_attr "length" "8")
7955 (set_attr "conds" "set")
7956 (set_attr "type" "multiple")]
7959 ;; Call subroutine returning any type.
7961 (define_expand "untyped_call"
7962 [(parallel [(call (match_operand 0 "" "")
7964 (match_operand 1 "" "")
7965 (match_operand 2 "" "")])]
7970 rtx par = gen_rtx_PARALLEL (VOIDmode,
7971 rtvec_alloc (XVECLEN (operands[2], 0)));
7972 rtx addr = gen_reg_rtx (Pmode);
7976 emit_move_insn (addr, XEXP (operands[1], 0));
7977 mem = change_address (operands[1], BLKmode, addr);
7979 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7981 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
7983 /* Default code only uses r0 as a return value, but we could
7984 be using anything up to 4 registers. */
7985 if (REGNO (src) == R0_REGNUM)
7986 src = gen_rtx_REG (TImode, R0_REGNUM);
7988 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
7990 size += GET_MODE_SIZE (GET_MODE (src));
7993 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
7998 for (i = 0; i < XVECLEN (par, 0); i++)
8000 HOST_WIDE_INT offset = 0;
8001 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8004 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8006 mem = change_address (mem, GET_MODE (reg), NULL);
8007 if (REGNO (reg) == R0_REGNUM)
8009 /* On thumb we have to use a write-back instruction. */
8010 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8011 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8012 size = TARGET_ARM ? 16 : 0;
8016 emit_move_insn (mem, reg);
8017 size = GET_MODE_SIZE (GET_MODE (reg));
8021 /* The optimizer does not know that the call sets the function value
8022 registers we stored in the result block. We avoid problems by
8023 claiming that all hard registers are used and clobbered at this
8025 emit_insn (gen_blockage ());
8031 (define_expand "untyped_return"
8032 [(match_operand:BLK 0 "memory_operand" "")
8033 (match_operand 1 "" "")]
8038 rtx addr = gen_reg_rtx (Pmode);
8042 emit_move_insn (addr, XEXP (operands[0], 0));
8043 mem = change_address (operands[0], BLKmode, addr);
8045 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8047 HOST_WIDE_INT offset = 0;
8048 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8051 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8053 mem = change_address (mem, GET_MODE (reg), NULL);
8054 if (REGNO (reg) == R0_REGNUM)
8056 /* On thumb we have to use a write-back instruction. */
8057 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8058 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8059 size = TARGET_ARM ? 16 : 0;
8063 emit_move_insn (reg, mem);
8064 size = GET_MODE_SIZE (GET_MODE (reg));
8068 /* Emit USE insns before the return. */
8069 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8070 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8072 /* Construct the return. */
8073 expand_naked_return ();
8079 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8080 ;; all of memory. This blocks insns from being moved across this point.
8082 (define_insn "blockage"
8083 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8086 [(set_attr "length" "0")
8087 (set_attr "type" "block")]
8090 (define_expand "casesi"
8091 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8092 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8093 (match_operand:SI 2 "const_int_operand" "") ; total range
8094 (match_operand:SI 3 "" "") ; table label
8095 (match_operand:SI 4 "" "")] ; Out of range label
8096 "TARGET_32BIT || optimize_size || flag_pic"
8099 enum insn_code code;
8100 if (operands[1] != const0_rtx)
8102 rtx reg = gen_reg_rtx (SImode);
8104 emit_insn (gen_addsi3 (reg, operands[0],
8105 gen_int_mode (-INTVAL (operands[1]),
8111 code = CODE_FOR_arm_casesi_internal;
8112 else if (TARGET_THUMB1)
8113 code = CODE_FOR_thumb1_casesi_internal_pic;
8115 code = CODE_FOR_thumb2_casesi_internal_pic;
8117 code = CODE_FOR_thumb2_casesi_internal;
8119 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8120 operands[2] = force_reg (SImode, operands[2]);
8122 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8123 operands[3], operands[4]));
8128 ;; The USE in this pattern is needed to tell flow analysis that this is
8129 ;; a CASESI insn. It has no other purpose.
8130 (define_insn "arm_casesi_internal"
8131 [(parallel [(set (pc)
8133 (leu (match_operand:SI 0 "s_register_operand" "r")
8134 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8135 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8136 (label_ref (match_operand 2 "" ""))))
8137 (label_ref (match_operand 3 "" ""))))
8138 (clobber (reg:CC CC_REGNUM))
8139 (use (label_ref (match_dup 2)))])]
8143 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8144 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8146 [(set_attr "conds" "clob")
8147 (set_attr "length" "12")
8148 (set_attr "type" "multiple")]
8151 (define_expand "indirect_jump"
8153 (match_operand:SI 0 "s_register_operand" ""))]
8156 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8157 address and use bx. */
8161 tmp = gen_reg_rtx (SImode);
8162 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8168 ;; NB Never uses BX.
8169 (define_insn "*arm_indirect_jump"
8171 (match_operand:SI 0 "s_register_operand" "r"))]
8173 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8174 [(set_attr "predicable" "yes")
8175 (set_attr "type" "branch")]
8178 (define_insn "*load_indirect_jump"
8180 (match_operand:SI 0 "memory_operand" "m"))]
8182 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8183 [(set_attr "type" "load1")
8184 (set_attr "pool_range" "4096")
8185 (set_attr "neg_pool_range" "4084")
8186 (set_attr "predicable" "yes")]
8196 if (TARGET_UNIFIED_ASM)
8199 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8200 return \"mov\\tr8, r8\";
8202 [(set (attr "length")
8203 (if_then_else (eq_attr "is_thumb" "yes")
8206 (set_attr "type" "mov_reg")]
8210 [(trap_if (const_int 1) (const_int 0))]
8214 return \".inst\\t0xe7f000f0\";
8216 return \".inst\\t0xdeff\";
8218 [(set (attr "length")
8219 (if_then_else (eq_attr "is_thumb" "yes")
8222 (set_attr "type" "trap")
8223 (set_attr "conds" "unconditional")]
8227 ;; Patterns to allow combination of arithmetic, cond code and shifts
8229 (define_insn "*<arith_shift_insn>_multsi"
8230 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8232 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8233 (match_operand:SI 3 "power_of_two_operand" ""))
8234 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8236 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8237 [(set_attr "predicable" "yes")
8238 (set_attr "predicable_short_it" "no")
8239 (set_attr "shift" "4")
8240 (set_attr "arch" "a,t2")
8241 (set_attr "type" "alu_shift_imm")])
8243 (define_insn "*<arith_shift_insn>_shiftsi"
8244 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8246 (match_operator:SI 2 "shift_nomul_operator"
8247 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8248 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8249 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8250 "TARGET_32BIT && GET_CODE (operands[3]) != MULT"
8251 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8252 [(set_attr "predicable" "yes")
8253 (set_attr "predicable_short_it" "no")
8254 (set_attr "shift" "4")
8255 (set_attr "arch" "a,t2,a")
8256 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8259 [(set (match_operand:SI 0 "s_register_operand" "")
8260 (match_operator:SI 1 "shiftable_operator"
8261 [(match_operator:SI 2 "shiftable_operator"
8262 [(match_operator:SI 3 "shift_operator"
8263 [(match_operand:SI 4 "s_register_operand" "")
8264 (match_operand:SI 5 "reg_or_int_operand" "")])
8265 (match_operand:SI 6 "s_register_operand" "")])
8266 (match_operand:SI 7 "arm_rhs_operand" "")]))
8267 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8270 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8273 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8276 (define_insn "*arith_shiftsi_compare0"
8277 [(set (reg:CC_NOOV CC_REGNUM)
8279 (match_operator:SI 1 "shiftable_operator"
8280 [(match_operator:SI 3 "shift_operator"
8281 [(match_operand:SI 4 "s_register_operand" "r,r")
8282 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8283 (match_operand:SI 2 "s_register_operand" "r,r")])
8285 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8286 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8289 "%i1%.\\t%0, %2, %4%S3"
8290 [(set_attr "conds" "set")
8291 (set_attr "shift" "4")
8292 (set_attr "arch" "32,a")
8293 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8295 (define_insn "*arith_shiftsi_compare0_scratch"
8296 [(set (reg:CC_NOOV CC_REGNUM)
8298 (match_operator:SI 1 "shiftable_operator"
8299 [(match_operator:SI 3 "shift_operator"
8300 [(match_operand:SI 4 "s_register_operand" "r,r")
8301 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8302 (match_operand:SI 2 "s_register_operand" "r,r")])
8304 (clobber (match_scratch:SI 0 "=r,r"))]
8306 "%i1%.\\t%0, %2, %4%S3"
8307 [(set_attr "conds" "set")
8308 (set_attr "shift" "4")
8309 (set_attr "arch" "32,a")
8310 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8312 (define_insn "*sub_shiftsi"
8313 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8314 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8315 (match_operator:SI 2 "shift_operator"
8316 [(match_operand:SI 3 "s_register_operand" "r,r")
8317 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8319 "sub%?\\t%0, %1, %3%S2"
8320 [(set_attr "predicable" "yes")
8321 (set_attr "shift" "3")
8322 (set_attr "arch" "32,a")
8323 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8325 (define_insn "*sub_shiftsi_compare0"
8326 [(set (reg:CC_NOOV CC_REGNUM)
8328 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8329 (match_operator:SI 2 "shift_operator"
8330 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8331 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8333 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8334 (minus:SI (match_dup 1)
8335 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8337 "sub%.\\t%0, %1, %3%S2"
8338 [(set_attr "conds" "set")
8339 (set_attr "shift" "3")
8340 (set_attr "arch" "32,a,a")
8341 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8343 (define_insn "*sub_shiftsi_compare0_scratch"
8344 [(set (reg:CC_NOOV CC_REGNUM)
8346 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8347 (match_operator:SI 2 "shift_operator"
8348 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8349 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8351 (clobber (match_scratch:SI 0 "=r,r,r"))]
8353 "sub%.\\t%0, %1, %3%S2"
8354 [(set_attr "conds" "set")
8355 (set_attr "shift" "3")
8356 (set_attr "arch" "32,a,a")
8357 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8360 (define_insn_and_split "*and_scc"
8361 [(set (match_operand:SI 0 "s_register_operand" "=r")
8362 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8363 [(match_operand 2 "cc_register" "") (const_int 0)])
8364 (match_operand:SI 3 "s_register_operand" "r")))]
8366 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8367 "&& reload_completed"
8368 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8369 (cond_exec (match_dup 4) (set (match_dup 0)
8370 (and:SI (match_dup 3) (const_int 1))))]
8372 enum machine_mode mode = GET_MODE (operands[2]);
8373 enum rtx_code rc = GET_CODE (operands[1]);
8375 /* Note that operands[4] is the same as operands[1],
8376 but with VOIDmode as the result. */
8377 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8378 if (mode == CCFPmode || mode == CCFPEmode)
8379 rc = reverse_condition_maybe_unordered (rc);
8381 rc = reverse_condition (rc);
8382 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8384 [(set_attr "conds" "use")
8385 (set_attr "type" "multiple")
8386 (set_attr "length" "8")]
8389 (define_insn_and_split "*ior_scc"
8390 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8391 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8392 [(match_operand 2 "cc_register" "") (const_int 0)])
8393 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8398 "&& reload_completed
8399 && REGNO (operands [0]) != REGNO (operands[3])"
8400 ;; && which_alternative == 1
8401 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8402 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8403 (cond_exec (match_dup 4) (set (match_dup 0)
8404 (ior:SI (match_dup 3) (const_int 1))))]
8406 enum machine_mode mode = GET_MODE (operands[2]);
8407 enum rtx_code rc = GET_CODE (operands[1]);
8409 /* Note that operands[4] is the same as operands[1],
8410 but with VOIDmode as the result. */
8411 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8412 if (mode == CCFPmode || mode == CCFPEmode)
8413 rc = reverse_condition_maybe_unordered (rc);
8415 rc = reverse_condition (rc);
8416 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8418 [(set_attr "conds" "use")
8419 (set_attr "length" "4,8")
8420 (set_attr "type" "logic_imm,multiple")]
8423 ; A series of splitters for the compare_scc pattern below. Note that
8424 ; order is important.
8426 [(set (match_operand:SI 0 "s_register_operand" "")
8427 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8429 (clobber (reg:CC CC_REGNUM))]
8430 "TARGET_32BIT && reload_completed"
8431 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8434 [(set (match_operand:SI 0 "s_register_operand" "")
8435 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8437 (clobber (reg:CC CC_REGNUM))]
8438 "TARGET_32BIT && reload_completed"
8439 [(set (match_dup 0) (not:SI (match_dup 1)))
8440 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8443 [(set (match_operand:SI 0 "s_register_operand" "")
8444 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8446 (clobber (reg:CC CC_REGNUM))]
8447 "arm_arch5 && TARGET_32BIT"
8448 [(set (match_dup 0) (clz:SI (match_dup 1)))
8449 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8453 [(set (match_operand:SI 0 "s_register_operand" "")
8454 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8456 (clobber (reg:CC CC_REGNUM))]
8457 "TARGET_32BIT && reload_completed"
8459 [(set (reg:CC CC_REGNUM)
8460 (compare:CC (const_int 1) (match_dup 1)))
8462 (minus:SI (const_int 1) (match_dup 1)))])
8463 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8464 (set (match_dup 0) (const_int 0)))])
8467 [(set (match_operand:SI 0 "s_register_operand" "")
8468 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8469 (match_operand:SI 2 "const_int_operand" "")))
8470 (clobber (reg:CC CC_REGNUM))]
8471 "TARGET_32BIT && reload_completed"
8473 [(set (reg:CC CC_REGNUM)
8474 (compare:CC (match_dup 1) (match_dup 2)))
8475 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8476 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8477 (set (match_dup 0) (const_int 1)))]
8479 operands[3] = GEN_INT (-INTVAL (operands[2]));
8483 [(set (match_operand:SI 0 "s_register_operand" "")
8484 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8485 (match_operand:SI 2 "arm_add_operand" "")))
8486 (clobber (reg:CC CC_REGNUM))]
8487 "TARGET_32BIT && reload_completed"
8489 [(set (reg:CC_NOOV CC_REGNUM)
8490 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8492 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8493 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8494 (set (match_dup 0) (const_int 1)))])
8496 (define_insn_and_split "*compare_scc"
8497 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8498 (match_operator:SI 1 "arm_comparison_operator"
8499 [(match_operand:SI 2 "s_register_operand" "r,r")
8500 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8501 (clobber (reg:CC CC_REGNUM))]
8504 "&& reload_completed"
8505 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8506 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8507 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8510 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8511 operands[2], operands[3]);
8512 enum rtx_code rc = GET_CODE (operands[1]);
8514 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8516 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8517 if (mode == CCFPmode || mode == CCFPEmode)
8518 rc = reverse_condition_maybe_unordered (rc);
8520 rc = reverse_condition (rc);
8521 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8523 [(set_attr "type" "multiple")]
8526 ;; Attempt to improve the sequence generated by the compare_scc splitters
8527 ;; not to use conditional execution.
8529 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
8533 [(set (reg:CC CC_REGNUM)
8534 (compare:CC (match_operand:SI 1 "register_operand" "")
8536 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8537 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8538 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8539 (set (match_dup 0) (const_int 1)))]
8540 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8541 [(set (match_dup 0) (clz:SI (match_dup 1)))
8542 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8545 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8549 [(set (reg:CC CC_REGNUM)
8550 (compare:CC (match_operand:SI 1 "register_operand" "")
8552 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8553 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8554 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8555 (set (match_dup 0) (const_int 1)))
8556 (match_scratch:SI 2 "r")]
8557 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8559 [(set (reg:CC CC_REGNUM)
8560 (compare:CC (const_int 0) (match_dup 1)))
8561 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8563 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8564 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8567 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
8568 ;; sub Rd, Reg1, reg2
8572 [(set (reg:CC CC_REGNUM)
8573 (compare:CC (match_operand:SI 1 "register_operand" "")
8574 (match_operand:SI 2 "arm_rhs_operand" "")))
8575 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8576 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8577 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8578 (set (match_dup 0) (const_int 1)))]
8579 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8580 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8581 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8582 (set (match_dup 0) (clz:SI (match_dup 0)))
8583 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8587 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
8588 ;; sub T1, Reg1, reg2
8592 [(set (reg:CC CC_REGNUM)
8593 (compare:CC (match_operand:SI 1 "register_operand" "")
8594 (match_operand:SI 2 "arm_rhs_operand" "")))
8595 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8596 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8597 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8598 (set (match_dup 0) (const_int 1)))
8599 (match_scratch:SI 3 "r")]
8600 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8601 [(set (match_dup 3) (match_dup 4))
8603 [(set (reg:CC CC_REGNUM)
8604 (compare:CC (const_int 0) (match_dup 3)))
8605 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8607 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8608 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8610 if (CONST_INT_P (operands[2]))
8611 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8613 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8616 (define_insn "*cond_move"
8617 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8618 (if_then_else:SI (match_operator 3 "equality_operator"
8619 [(match_operator 4 "arm_comparison_operator"
8620 [(match_operand 5 "cc_register" "") (const_int 0)])
8622 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8623 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8626 if (GET_CODE (operands[3]) == NE)
8628 if (which_alternative != 1)
8629 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8630 if (which_alternative != 0)
8631 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8634 if (which_alternative != 0)
8635 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8636 if (which_alternative != 1)
8637 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8640 [(set_attr "conds" "use")
8641 (set_attr "type" "mov_reg,mov_reg,multiple")
8642 (set_attr "length" "4,4,8")]
8645 (define_insn "*cond_arith"
8646 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8647 (match_operator:SI 5 "shiftable_operator"
8648 [(match_operator:SI 4 "arm_comparison_operator"
8649 [(match_operand:SI 2 "s_register_operand" "r,r")
8650 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8651 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8652 (clobber (reg:CC CC_REGNUM))]
8655 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8656 return \"%i5\\t%0, %1, %2, lsr #31\";
8658 output_asm_insn (\"cmp\\t%2, %3\", operands);
8659 if (GET_CODE (operands[5]) == AND)
8660 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8661 else if (GET_CODE (operands[5]) == MINUS)
8662 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8663 else if (which_alternative != 0)
8664 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8665 return \"%i5%d4\\t%0, %1, #1\";
8667 [(set_attr "conds" "clob")
8668 (set_attr "length" "12")
8669 (set_attr "type" "multiple")]
8672 (define_insn "*cond_sub"
8673 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8674 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8675 (match_operator:SI 4 "arm_comparison_operator"
8676 [(match_operand:SI 2 "s_register_operand" "r,r")
8677 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8678 (clobber (reg:CC CC_REGNUM))]
8681 output_asm_insn (\"cmp\\t%2, %3\", operands);
8682 if (which_alternative != 0)
8683 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8684 return \"sub%d4\\t%0, %1, #1\";
8686 [(set_attr "conds" "clob")
8687 (set_attr "length" "8,12")
8688 (set_attr "type" "multiple")]
8691 (define_insn "*cmp_ite0"
8692 [(set (match_operand 6 "dominant_cc_register" "")
8695 (match_operator 4 "arm_comparison_operator"
8696 [(match_operand:SI 0 "s_register_operand"
8697 "l,l,l,r,r,r,r,r,r")
8698 (match_operand:SI 1 "arm_add_operand"
8699 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8700 (match_operator:SI 5 "arm_comparison_operator"
8701 [(match_operand:SI 2 "s_register_operand"
8702 "l,r,r,l,l,r,r,r,r")
8703 (match_operand:SI 3 "arm_add_operand"
8704 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8710 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8712 {\"cmp%d5\\t%0, %1\",
8713 \"cmp%d4\\t%2, %3\"},
8714 {\"cmn%d5\\t%0, #%n1\",
8715 \"cmp%d4\\t%2, %3\"},
8716 {\"cmp%d5\\t%0, %1\",
8717 \"cmn%d4\\t%2, #%n3\"},
8718 {\"cmn%d5\\t%0, #%n1\",
8719 \"cmn%d4\\t%2, #%n3\"}
8721 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8726 \"cmn\\t%0, #%n1\"},
8727 {\"cmn\\t%2, #%n3\",
8729 {\"cmn\\t%2, #%n3\",
8732 static const char * const ite[2] =
8737 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8738 CMP_CMP, CMN_CMP, CMP_CMP,
8739 CMN_CMP, CMP_CMN, CMN_CMN};
8741 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8743 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8744 if (TARGET_THUMB2) {
8745 output_asm_insn (ite[swap], operands);
8747 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8750 [(set_attr "conds" "set")
8751 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8752 (set_attr "type" "multiple")
8753 (set_attr_alternative "length"
8759 (if_then_else (eq_attr "is_thumb" "no")
8762 (if_then_else (eq_attr "is_thumb" "no")
8765 (if_then_else (eq_attr "is_thumb" "no")
8768 (if_then_else (eq_attr "is_thumb" "no")
8773 (define_insn "*cmp_ite1"
8774 [(set (match_operand 6 "dominant_cc_register" "")
8777 (match_operator 4 "arm_comparison_operator"
8778 [(match_operand:SI 0 "s_register_operand"
8779 "l,l,l,r,r,r,r,r,r")
8780 (match_operand:SI 1 "arm_add_operand"
8781 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8782 (match_operator:SI 5 "arm_comparison_operator"
8783 [(match_operand:SI 2 "s_register_operand"
8784 "l,r,r,l,l,r,r,r,r")
8785 (match_operand:SI 3 "arm_add_operand"
8786 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8792 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8796 {\"cmn\\t%0, #%n1\",
8799 \"cmn\\t%2, #%n3\"},
8800 {\"cmn\\t%0, #%n1\",
8803 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8805 {\"cmp%d4\\t%2, %3\",
8806 \"cmp%D5\\t%0, %1\"},
8807 {\"cmp%d4\\t%2, %3\",
8808 \"cmn%D5\\t%0, #%n1\"},
8809 {\"cmn%d4\\t%2, #%n3\",
8810 \"cmp%D5\\t%0, %1\"},
8811 {\"cmn%d4\\t%2, #%n3\",
8812 \"cmn%D5\\t%0, #%n1\"}
8814 static const char * const ite[2] =
8819 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8820 CMP_CMP, CMN_CMP, CMP_CMP,
8821 CMN_CMP, CMP_CMN, CMN_CMN};
8823 comparison_dominates_p (GET_CODE (operands[5]),
8824 reverse_condition (GET_CODE (operands[4])));
8826 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8827 if (TARGET_THUMB2) {
8828 output_asm_insn (ite[swap], operands);
8830 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8833 [(set_attr "conds" "set")
8834 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8835 (set_attr_alternative "length"
8841 (if_then_else (eq_attr "is_thumb" "no")
8844 (if_then_else (eq_attr "is_thumb" "no")
8847 (if_then_else (eq_attr "is_thumb" "no")
8850 (if_then_else (eq_attr "is_thumb" "no")
8853 (set_attr "type" "multiple")]
8856 (define_insn "*cmp_and"
8857 [(set (match_operand 6 "dominant_cc_register" "")
8860 (match_operator 4 "arm_comparison_operator"
8861 [(match_operand:SI 0 "s_register_operand"
8862 "l,l,l,r,r,r,r,r,r")
8863 (match_operand:SI 1 "arm_add_operand"
8864 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8865 (match_operator:SI 5 "arm_comparison_operator"
8866 [(match_operand:SI 2 "s_register_operand"
8867 "l,r,r,l,l,r,r,r,r")
8868 (match_operand:SI 3 "arm_add_operand"
8869 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8874 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8876 {\"cmp%d5\\t%0, %1\",
8877 \"cmp%d4\\t%2, %3\"},
8878 {\"cmn%d5\\t%0, #%n1\",
8879 \"cmp%d4\\t%2, %3\"},
8880 {\"cmp%d5\\t%0, %1\",
8881 \"cmn%d4\\t%2, #%n3\"},
8882 {\"cmn%d5\\t%0, #%n1\",
8883 \"cmn%d4\\t%2, #%n3\"}
8885 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8890 \"cmn\\t%0, #%n1\"},
8891 {\"cmn\\t%2, #%n3\",
8893 {\"cmn\\t%2, #%n3\",
8896 static const char *const ite[2] =
8901 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8902 CMP_CMP, CMN_CMP, CMP_CMP,
8903 CMN_CMP, CMP_CMN, CMN_CMN};
8905 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8907 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8908 if (TARGET_THUMB2) {
8909 output_asm_insn (ite[swap], operands);
8911 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8914 [(set_attr "conds" "set")
8915 (set_attr "predicable" "no")
8916 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8917 (set_attr_alternative "length"
8923 (if_then_else (eq_attr "is_thumb" "no")
8926 (if_then_else (eq_attr "is_thumb" "no")
8929 (if_then_else (eq_attr "is_thumb" "no")
8932 (if_then_else (eq_attr "is_thumb" "no")
8935 (set_attr "type" "multiple")]
8938 (define_insn "*cmp_ior"
8939 [(set (match_operand 6 "dominant_cc_register" "")
8942 (match_operator 4 "arm_comparison_operator"
8943 [(match_operand:SI 0 "s_register_operand"
8944 "l,l,l,r,r,r,r,r,r")
8945 (match_operand:SI 1 "arm_add_operand"
8946 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8947 (match_operator:SI 5 "arm_comparison_operator"
8948 [(match_operand:SI 2 "s_register_operand"
8949 "l,r,r,l,l,r,r,r,r")
8950 (match_operand:SI 3 "arm_add_operand"
8951 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8956 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8960 {\"cmn\\t%0, #%n1\",
8963 \"cmn\\t%2, #%n3\"},
8964 {\"cmn\\t%0, #%n1\",
8967 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8969 {\"cmp%D4\\t%2, %3\",
8970 \"cmp%D5\\t%0, %1\"},
8971 {\"cmp%D4\\t%2, %3\",
8972 \"cmn%D5\\t%0, #%n1\"},
8973 {\"cmn%D4\\t%2, #%n3\",
8974 \"cmp%D5\\t%0, %1\"},
8975 {\"cmn%D4\\t%2, #%n3\",
8976 \"cmn%D5\\t%0, #%n1\"}
8978 static const char *const ite[2] =
8983 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8984 CMP_CMP, CMN_CMP, CMP_CMP,
8985 CMN_CMP, CMP_CMN, CMN_CMN};
8987 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8989 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8990 if (TARGET_THUMB2) {
8991 output_asm_insn (ite[swap], operands);
8993 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8997 [(set_attr "conds" "set")
8998 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8999 (set_attr_alternative "length"
9005 (if_then_else (eq_attr "is_thumb" "no")
9008 (if_then_else (eq_attr "is_thumb" "no")
9011 (if_then_else (eq_attr "is_thumb" "no")
9014 (if_then_else (eq_attr "is_thumb" "no")
9017 (set_attr "type" "multiple")]
9020 (define_insn_and_split "*ior_scc_scc"
9021 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9022 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9023 [(match_operand:SI 1 "s_register_operand" "r")
9024 (match_operand:SI 2 "arm_add_operand" "rIL")])
9025 (match_operator:SI 6 "arm_comparison_operator"
9026 [(match_operand:SI 4 "s_register_operand" "r")
9027 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9028 (clobber (reg:CC CC_REGNUM))]
9030 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9033 "TARGET_32BIT && reload_completed"
9037 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9038 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9040 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9042 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9045 [(set_attr "conds" "clob")
9046 (set_attr "length" "16")
9047 (set_attr "type" "multiple")]
9050 ; If the above pattern is followed by a CMP insn, then the compare is
9051 ; redundant, since we can rework the conditional instruction that follows.
9052 (define_insn_and_split "*ior_scc_scc_cmp"
9053 [(set (match_operand 0 "dominant_cc_register" "")
9054 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9055 [(match_operand:SI 1 "s_register_operand" "r")
9056 (match_operand:SI 2 "arm_add_operand" "rIL")])
9057 (match_operator:SI 6 "arm_comparison_operator"
9058 [(match_operand:SI 4 "s_register_operand" "r")
9059 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9061 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9062 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9063 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9066 "TARGET_32BIT && reload_completed"
9070 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9071 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9073 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9075 [(set_attr "conds" "set")
9076 (set_attr "length" "16")
9077 (set_attr "type" "multiple")]
9080 (define_insn_and_split "*and_scc_scc"
9081 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9082 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9083 [(match_operand:SI 1 "s_register_operand" "r")
9084 (match_operand:SI 2 "arm_add_operand" "rIL")])
9085 (match_operator:SI 6 "arm_comparison_operator"
9086 [(match_operand:SI 4 "s_register_operand" "r")
9087 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9088 (clobber (reg:CC CC_REGNUM))]
9090 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9093 "TARGET_32BIT && reload_completed
9094 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9099 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9100 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9102 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9104 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9107 [(set_attr "conds" "clob")
9108 (set_attr "length" "16")
9109 (set_attr "type" "multiple")]
9112 ; If the above pattern is followed by a CMP insn, then the compare is
9113 ; redundant, since we can rework the conditional instruction that follows.
9114 (define_insn_and_split "*and_scc_scc_cmp"
9115 [(set (match_operand 0 "dominant_cc_register" "")
9116 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9117 [(match_operand:SI 1 "s_register_operand" "r")
9118 (match_operand:SI 2 "arm_add_operand" "rIL")])
9119 (match_operator:SI 6 "arm_comparison_operator"
9120 [(match_operand:SI 4 "s_register_operand" "r")
9121 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9123 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9124 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9125 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9128 "TARGET_32BIT && reload_completed"
9132 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9133 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9135 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9137 [(set_attr "conds" "set")
9138 (set_attr "length" "16")
9139 (set_attr "type" "multiple")]
9142 ;; If there is no dominance in the comparison, then we can still save an
9143 ;; instruction in the AND case, since we can know that the second compare
9144 ;; need only zero the value if false (if true, then the value is already
9146 (define_insn_and_split "*and_scc_scc_nodom"
9147 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9148 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9149 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9150 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9151 (match_operator:SI 6 "arm_comparison_operator"
9152 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9153 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9154 (clobber (reg:CC CC_REGNUM))]
9156 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9159 "TARGET_32BIT && reload_completed"
9160 [(parallel [(set (match_dup 0)
9161 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9162 (clobber (reg:CC CC_REGNUM))])
9163 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9165 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9168 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9169 operands[4], operands[5]),
9171 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9173 [(set_attr "conds" "clob")
9174 (set_attr "length" "20")
9175 (set_attr "type" "multiple")]
9179 [(set (reg:CC_NOOV CC_REGNUM)
9180 (compare:CC_NOOV (ior:SI
9181 (and:SI (match_operand:SI 0 "s_register_operand" "")
9183 (match_operator:SI 1 "arm_comparison_operator"
9184 [(match_operand:SI 2 "s_register_operand" "")
9185 (match_operand:SI 3 "arm_add_operand" "")]))
9187 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9190 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9192 (set (reg:CC_NOOV CC_REGNUM)
9193 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9198 [(set (reg:CC_NOOV CC_REGNUM)
9199 (compare:CC_NOOV (ior:SI
9200 (match_operator:SI 1 "arm_comparison_operator"
9201 [(match_operand:SI 2 "s_register_operand" "")
9202 (match_operand:SI 3 "arm_add_operand" "")])
9203 (and:SI (match_operand:SI 0 "s_register_operand" "")
9206 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9209 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9211 (set (reg:CC_NOOV CC_REGNUM)
9212 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9215 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9217 (define_insn_and_split "*negscc"
9218 [(set (match_operand:SI 0 "s_register_operand" "=r")
9219 (neg:SI (match_operator 3 "arm_comparison_operator"
9220 [(match_operand:SI 1 "s_register_operand" "r")
9221 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9222 (clobber (reg:CC CC_REGNUM))]
9225 "&& reload_completed"
9228 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9230 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9232 /* Emit mov\\t%0, %1, asr #31 */
9233 emit_insn (gen_rtx_SET (VOIDmode,
9235 gen_rtx_ASHIFTRT (SImode,
9240 else if (GET_CODE (operands[3]) == NE)
9242 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9243 if (CONST_INT_P (operands[2]))
9244 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9245 GEN_INT (- INTVAL (operands[2]))));
9247 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9249 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9253 gen_rtx_SET (SImode,
9260 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9261 emit_insn (gen_rtx_SET (VOIDmode,
9263 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9264 enum rtx_code rc = GET_CODE (operands[3]);
9266 rc = reverse_condition (rc);
9267 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9272 gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
9273 rc = GET_CODE (operands[3]);
9274 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9279 gen_rtx_SET (VOIDmode,
9286 [(set_attr "conds" "clob")
9287 (set_attr "length" "12")
9288 (set_attr "type" "multiple")]
9291 (define_insn_and_split "movcond_addsi"
9292 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9294 (match_operator 5 "comparison_operator"
9295 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9296 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9298 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9299 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9300 (clobber (reg:CC CC_REGNUM))]
9303 "&& reload_completed"
9304 [(set (reg:CC_NOOV CC_REGNUM)
9306 (plus:SI (match_dup 3)
9309 (set (match_dup 0) (match_dup 1))
9310 (cond_exec (match_dup 6)
9311 (set (match_dup 0) (match_dup 2)))]
9314 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9315 operands[3], operands[4]);
9316 enum rtx_code rc = GET_CODE (operands[5]);
9318 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9319 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9320 rc = reverse_condition (rc);
9322 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9325 [(set_attr "conds" "clob")
9326 (set_attr "enabled_for_depr_it" "no,yes,yes")
9327 (set_attr "type" "multiple")]
9330 (define_insn "movcond"
9331 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9333 (match_operator 5 "arm_comparison_operator"
9334 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9335 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9336 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9337 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9338 (clobber (reg:CC CC_REGNUM))]
9341 if (GET_CODE (operands[5]) == LT
9342 && (operands[4] == const0_rtx))
9344 if (which_alternative != 1 && REG_P (operands[1]))
9346 if (operands[2] == const0_rtx)
9347 return \"and\\t%0, %1, %3, asr #31\";
9348 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9350 else if (which_alternative != 0 && REG_P (operands[2]))
9352 if (operands[1] == const0_rtx)
9353 return \"bic\\t%0, %2, %3, asr #31\";
9354 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9356 /* The only case that falls through to here is when both ops 1 & 2
9360 if (GET_CODE (operands[5]) == GE
9361 && (operands[4] == const0_rtx))
9363 if (which_alternative != 1 && REG_P (operands[1]))
9365 if (operands[2] == const0_rtx)
9366 return \"bic\\t%0, %1, %3, asr #31\";
9367 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9369 else if (which_alternative != 0 && REG_P (operands[2]))
9371 if (operands[1] == const0_rtx)
9372 return \"and\\t%0, %2, %3, asr #31\";
9373 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9375 /* The only case that falls through to here is when both ops 1 & 2
9378 if (CONST_INT_P (operands[4])
9379 && !const_ok_for_arm (INTVAL (operands[4])))
9380 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9382 output_asm_insn (\"cmp\\t%3, %4\", operands);
9383 if (which_alternative != 0)
9384 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9385 if (which_alternative != 1)
9386 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9389 [(set_attr "conds" "clob")
9390 (set_attr "length" "8,8,12")
9391 (set_attr "type" "multiple")]
9394 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9396 (define_insn "*ifcompare_plus_move"
9397 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9398 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9399 [(match_operand:SI 4 "s_register_operand" "r,r")
9400 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9402 (match_operand:SI 2 "s_register_operand" "r,r")
9403 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9404 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9405 (clobber (reg:CC CC_REGNUM))]
9408 [(set_attr "conds" "clob")
9409 (set_attr "length" "8,12")
9410 (set_attr "type" "multiple")]
9413 (define_insn "*if_plus_move"
9414 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9416 (match_operator 4 "arm_comparison_operator"
9417 [(match_operand 5 "cc_register" "") (const_int 0)])
9419 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9420 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9421 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9425 sub%d4\\t%0, %2, #%n3
9426 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9427 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9428 [(set_attr "conds" "use")
9429 (set_attr "length" "4,4,8,8")
9430 (set_attr_alternative "type"
9431 [(if_then_else (match_operand 3 "const_int_operand" "")
9432 (const_string "alu_imm" )
9433 (const_string "alu_sreg"))
9434 (const_string "alu_imm")
9435 (const_string "alu_sreg")
9436 (const_string "alu_sreg")])]
9439 (define_insn "*ifcompare_move_plus"
9440 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9441 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9442 [(match_operand:SI 4 "s_register_operand" "r,r")
9443 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9444 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9446 (match_operand:SI 2 "s_register_operand" "r,r")
9447 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9448 (clobber (reg:CC CC_REGNUM))]
9451 [(set_attr "conds" "clob")
9452 (set_attr "length" "8,12")
9453 (set_attr "type" "multiple")]
9456 (define_insn "*if_move_plus"
9457 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9459 (match_operator 4 "arm_comparison_operator"
9460 [(match_operand 5 "cc_register" "") (const_int 0)])
9461 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9463 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9464 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9468 sub%D4\\t%0, %2, #%n3
9469 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9470 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9471 [(set_attr "conds" "use")
9472 (set_attr "length" "4,4,8,8")
9473 (set_attr "type" "alu_sreg,alu_imm,multiple,multiple")]
9476 (define_insn "*ifcompare_arith_arith"
9477 [(set (match_operand:SI 0 "s_register_operand" "=r")
9478 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9479 [(match_operand:SI 5 "s_register_operand" "r")
9480 (match_operand:SI 6 "arm_add_operand" "rIL")])
9481 (match_operator:SI 8 "shiftable_operator"
9482 [(match_operand:SI 1 "s_register_operand" "r")
9483 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9484 (match_operator:SI 7 "shiftable_operator"
9485 [(match_operand:SI 3 "s_register_operand" "r")
9486 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9487 (clobber (reg:CC CC_REGNUM))]
9490 [(set_attr "conds" "clob")
9491 (set_attr "length" "12")
9492 (set_attr "type" "multiple")]
9495 (define_insn "*if_arith_arith"
9496 [(set (match_operand:SI 0 "s_register_operand" "=r")
9497 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9498 [(match_operand 8 "cc_register" "") (const_int 0)])
9499 (match_operator:SI 6 "shiftable_operator"
9500 [(match_operand:SI 1 "s_register_operand" "r")
9501 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9502 (match_operator:SI 7 "shiftable_operator"
9503 [(match_operand:SI 3 "s_register_operand" "r")
9504 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9506 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9507 [(set_attr "conds" "use")
9508 (set_attr "length" "8")
9509 (set_attr "type" "multiple")]
9512 (define_insn "*ifcompare_arith_move"
9513 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9514 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9515 [(match_operand:SI 2 "s_register_operand" "r,r")
9516 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9517 (match_operator:SI 7 "shiftable_operator"
9518 [(match_operand:SI 4 "s_register_operand" "r,r")
9519 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9520 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9521 (clobber (reg:CC CC_REGNUM))]
9524 /* If we have an operation where (op x 0) is the identity operation and
9525 the conditional operator is LT or GE and we are comparing against zero and
9526 everything is in registers then we can do this in two instructions. */
9527 if (operands[3] == const0_rtx
9528 && GET_CODE (operands[7]) != AND
9529 && REG_P (operands[5])
9530 && REG_P (operands[1])
9531 && REGNO (operands[1]) == REGNO (operands[4])
9532 && REGNO (operands[4]) != REGNO (operands[0]))
9534 if (GET_CODE (operands[6]) == LT)
9535 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9536 else if (GET_CODE (operands[6]) == GE)
9537 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9539 if (CONST_INT_P (operands[3])
9540 && !const_ok_for_arm (INTVAL (operands[3])))
9541 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9543 output_asm_insn (\"cmp\\t%2, %3\", operands);
9544 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9545 if (which_alternative != 0)
9546 return \"mov%D6\\t%0, %1\";
9549 [(set_attr "conds" "clob")
9550 (set_attr "length" "8,12")
9551 (set_attr "type" "multiple")]
9554 (define_insn "*if_arith_move"
9555 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9556 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9557 [(match_operand 6 "cc_register" "") (const_int 0)])
9558 (match_operator:SI 5 "shiftable_operator"
9559 [(match_operand:SI 2 "s_register_operand" "r,r")
9560 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9561 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9565 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9566 [(set_attr "conds" "use")
9567 (set_attr "length" "4,8")
9568 (set_attr "type" "alu_shift_reg,multiple")]
9571 (define_insn "*ifcompare_move_arith"
9572 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9573 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9574 [(match_operand:SI 4 "s_register_operand" "r,r")
9575 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9576 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9577 (match_operator:SI 7 "shiftable_operator"
9578 [(match_operand:SI 2 "s_register_operand" "r,r")
9579 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9580 (clobber (reg:CC CC_REGNUM))]
9583 /* If we have an operation where (op x 0) is the identity operation and
9584 the conditional operator is LT or GE and we are comparing against zero and
9585 everything is in registers then we can do this in two instructions */
9586 if (operands[5] == const0_rtx
9587 && GET_CODE (operands[7]) != AND
9588 && REG_P (operands[3])
9589 && REG_P (operands[1])
9590 && REGNO (operands[1]) == REGNO (operands[2])
9591 && REGNO (operands[2]) != REGNO (operands[0]))
9593 if (GET_CODE (operands[6]) == GE)
9594 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9595 else if (GET_CODE (operands[6]) == LT)
9596 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9599 if (CONST_INT_P (operands[5])
9600 && !const_ok_for_arm (INTVAL (operands[5])))
9601 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9603 output_asm_insn (\"cmp\\t%4, %5\", operands);
9605 if (which_alternative != 0)
9606 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9607 return \"%I7%D6\\t%0, %2, %3\";
9609 [(set_attr "conds" "clob")
9610 (set_attr "length" "8,12")
9611 (set_attr "type" "multiple")]
9614 (define_insn "*if_move_arith"
9615 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9617 (match_operator 4 "arm_comparison_operator"
9618 [(match_operand 6 "cc_register" "") (const_int 0)])
9619 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9620 (match_operator:SI 5 "shiftable_operator"
9621 [(match_operand:SI 2 "s_register_operand" "r,r")
9622 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9626 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9627 [(set_attr "conds" "use")
9628 (set_attr "length" "4,8")
9629 (set_attr "type" "alu_shift_reg,multiple")]
9632 (define_insn "*ifcompare_move_not"
9633 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9635 (match_operator 5 "arm_comparison_operator"
9636 [(match_operand:SI 3 "s_register_operand" "r,r")
9637 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9638 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9640 (match_operand:SI 2 "s_register_operand" "r,r"))))
9641 (clobber (reg:CC CC_REGNUM))]
9644 [(set_attr "conds" "clob")
9645 (set_attr "length" "8,12")
9646 (set_attr "type" "multiple")]
9649 (define_insn "*if_move_not"
9650 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9652 (match_operator 4 "arm_comparison_operator"
9653 [(match_operand 3 "cc_register" "") (const_int 0)])
9654 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9655 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9659 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9660 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9661 [(set_attr "conds" "use")
9662 (set_attr "type" "mvn_reg")
9663 (set_attr "length" "4,8,8")
9664 (set_attr "type" "mvn_reg,multiple,multiple")]
9667 (define_insn "*ifcompare_not_move"
9668 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9670 (match_operator 5 "arm_comparison_operator"
9671 [(match_operand:SI 3 "s_register_operand" "r,r")
9672 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9674 (match_operand:SI 2 "s_register_operand" "r,r"))
9675 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9676 (clobber (reg:CC CC_REGNUM))]
9679 [(set_attr "conds" "clob")
9680 (set_attr "length" "8,12")
9681 (set_attr "type" "multiple")]
9684 (define_insn "*if_not_move"
9685 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9687 (match_operator 4 "arm_comparison_operator"
9688 [(match_operand 3 "cc_register" "") (const_int 0)])
9689 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9690 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9694 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9695 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9696 [(set_attr "conds" "use")
9697 (set_attr "type" "mvn_reg,multiple,multiple")
9698 (set_attr "length" "4,8,8")]
9701 (define_insn "*ifcompare_shift_move"
9702 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9704 (match_operator 6 "arm_comparison_operator"
9705 [(match_operand:SI 4 "s_register_operand" "r,r")
9706 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9707 (match_operator:SI 7 "shift_operator"
9708 [(match_operand:SI 2 "s_register_operand" "r,r")
9709 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9710 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9711 (clobber (reg:CC CC_REGNUM))]
9714 [(set_attr "conds" "clob")
9715 (set_attr "length" "8,12")
9716 (set_attr "type" "multiple")]
9719 (define_insn "*if_shift_move"
9720 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9722 (match_operator 5 "arm_comparison_operator"
9723 [(match_operand 6 "cc_register" "") (const_int 0)])
9724 (match_operator:SI 4 "shift_operator"
9725 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9726 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9727 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9731 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9732 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9733 [(set_attr "conds" "use")
9734 (set_attr "shift" "2")
9735 (set_attr "length" "4,8,8")
9736 (set_attr "type" "mov_shift_reg,multiple,multiple")]
9739 (define_insn "*ifcompare_move_shift"
9740 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9742 (match_operator 6 "arm_comparison_operator"
9743 [(match_operand:SI 4 "s_register_operand" "r,r")
9744 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9745 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9746 (match_operator:SI 7 "shift_operator"
9747 [(match_operand:SI 2 "s_register_operand" "r,r")
9748 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9749 (clobber (reg:CC CC_REGNUM))]
9752 [(set_attr "conds" "clob")
9753 (set_attr "length" "8,12")
9754 (set_attr "type" "multiple")]
9757 (define_insn "*if_move_shift"
9758 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9760 (match_operator 5 "arm_comparison_operator"
9761 [(match_operand 6 "cc_register" "") (const_int 0)])
9762 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9763 (match_operator:SI 4 "shift_operator"
9764 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9765 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9769 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9770 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9771 [(set_attr "conds" "use")
9772 (set_attr "shift" "2")
9773 (set_attr "length" "4,8,8")
9774 (set_attr "type" "mov_shift_reg,multiple,multiple")]
9777 (define_insn "*ifcompare_shift_shift"
9778 [(set (match_operand:SI 0 "s_register_operand" "=r")
9780 (match_operator 7 "arm_comparison_operator"
9781 [(match_operand:SI 5 "s_register_operand" "r")
9782 (match_operand:SI 6 "arm_add_operand" "rIL")])
9783 (match_operator:SI 8 "shift_operator"
9784 [(match_operand:SI 1 "s_register_operand" "r")
9785 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9786 (match_operator:SI 9 "shift_operator"
9787 [(match_operand:SI 3 "s_register_operand" "r")
9788 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9789 (clobber (reg:CC CC_REGNUM))]
9792 [(set_attr "conds" "clob")
9793 (set_attr "length" "12")
9794 (set_attr "type" "multiple")]
9797 (define_insn "*if_shift_shift"
9798 [(set (match_operand:SI 0 "s_register_operand" "=r")
9800 (match_operator 5 "arm_comparison_operator"
9801 [(match_operand 8 "cc_register" "") (const_int 0)])
9802 (match_operator:SI 6 "shift_operator"
9803 [(match_operand:SI 1 "s_register_operand" "r")
9804 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9805 (match_operator:SI 7 "shift_operator"
9806 [(match_operand:SI 3 "s_register_operand" "r")
9807 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9809 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9810 [(set_attr "conds" "use")
9811 (set_attr "shift" "1")
9812 (set_attr "length" "8")
9813 (set (attr "type") (if_then_else
9814 (and (match_operand 2 "const_int_operand" "")
9815 (match_operand 4 "const_int_operand" ""))
9816 (const_string "mov_shift")
9817 (const_string "mov_shift_reg")))]
9820 (define_insn "*ifcompare_not_arith"
9821 [(set (match_operand:SI 0 "s_register_operand" "=r")
9823 (match_operator 6 "arm_comparison_operator"
9824 [(match_operand:SI 4 "s_register_operand" "r")
9825 (match_operand:SI 5 "arm_add_operand" "rIL")])
9826 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9827 (match_operator:SI 7 "shiftable_operator"
9828 [(match_operand:SI 2 "s_register_operand" "r")
9829 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9830 (clobber (reg:CC CC_REGNUM))]
9833 [(set_attr "conds" "clob")
9834 (set_attr "length" "12")
9835 (set_attr "type" "multiple")]
9838 (define_insn "*if_not_arith"
9839 [(set (match_operand:SI 0 "s_register_operand" "=r")
9841 (match_operator 5 "arm_comparison_operator"
9842 [(match_operand 4 "cc_register" "") (const_int 0)])
9843 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9844 (match_operator:SI 6 "shiftable_operator"
9845 [(match_operand:SI 2 "s_register_operand" "r")
9846 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9848 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9849 [(set_attr "conds" "use")
9850 (set_attr "type" "mvn_reg")
9851 (set_attr "length" "8")]
9854 (define_insn "*ifcompare_arith_not"
9855 [(set (match_operand:SI 0 "s_register_operand" "=r")
9857 (match_operator 6 "arm_comparison_operator"
9858 [(match_operand:SI 4 "s_register_operand" "r")
9859 (match_operand:SI 5 "arm_add_operand" "rIL")])
9860 (match_operator:SI 7 "shiftable_operator"
9861 [(match_operand:SI 2 "s_register_operand" "r")
9862 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9863 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9864 (clobber (reg:CC CC_REGNUM))]
9867 [(set_attr "conds" "clob")
9868 (set_attr "length" "12")
9869 (set_attr "type" "multiple")]
9872 (define_insn "*if_arith_not"
9873 [(set (match_operand:SI 0 "s_register_operand" "=r")
9875 (match_operator 5 "arm_comparison_operator"
9876 [(match_operand 4 "cc_register" "") (const_int 0)])
9877 (match_operator:SI 6 "shiftable_operator"
9878 [(match_operand:SI 2 "s_register_operand" "r")
9879 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9880 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9882 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9883 [(set_attr "conds" "use")
9884 (set_attr "type" "multiple")
9885 (set_attr "length" "8")]
9888 (define_insn "*ifcompare_neg_move"
9889 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9891 (match_operator 5 "arm_comparison_operator"
9892 [(match_operand:SI 3 "s_register_operand" "r,r")
9893 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9894 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9895 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9896 (clobber (reg:CC CC_REGNUM))]
9899 [(set_attr "conds" "clob")
9900 (set_attr "length" "8,12")
9901 (set_attr "type" "multiple")]
9904 (define_insn "*if_neg_move"
9905 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9907 (match_operator 4 "arm_comparison_operator"
9908 [(match_operand 3 "cc_register" "") (const_int 0)])
9909 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9910 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9914 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9915 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9916 [(set_attr "conds" "use")
9917 (set_attr "length" "4,8,8")
9918 (set_attr "type" "logic_shift_imm,multiple,multiple")]
9921 (define_insn "*ifcompare_move_neg"
9922 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9924 (match_operator 5 "arm_comparison_operator"
9925 [(match_operand:SI 3 "s_register_operand" "r,r")
9926 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9927 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9928 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9929 (clobber (reg:CC CC_REGNUM))]
9932 [(set_attr "conds" "clob")
9933 (set_attr "length" "8,12")
9934 (set_attr "type" "multiple")]
9937 (define_insn "*if_move_neg"
9938 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9940 (match_operator 4 "arm_comparison_operator"
9941 [(match_operand 3 "cc_register" "") (const_int 0)])
9942 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9943 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9947 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9948 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9949 [(set_attr "conds" "use")
9950 (set_attr "length" "4,8,8")
9951 (set_attr "type" "logic_shift_imm,multiple,multiple")]
9954 (define_insn "*arith_adjacentmem"
9955 [(set (match_operand:SI 0 "s_register_operand" "=r")
9956 (match_operator:SI 1 "shiftable_operator"
9957 [(match_operand:SI 2 "memory_operand" "m")
9958 (match_operand:SI 3 "memory_operand" "m")]))
9959 (clobber (match_scratch:SI 4 "=r"))]
9960 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9966 HOST_WIDE_INT val1 = 0, val2 = 0;
9968 if (REGNO (operands[0]) > REGNO (operands[4]))
9970 ldm[1] = operands[4];
9971 ldm[2] = operands[0];
9975 ldm[1] = operands[0];
9976 ldm[2] = operands[4];
9979 base_reg = XEXP (operands[2], 0);
9981 if (!REG_P (base_reg))
9983 val1 = INTVAL (XEXP (base_reg, 1));
9984 base_reg = XEXP (base_reg, 0);
9987 if (!REG_P (XEXP (operands[3], 0)))
9988 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
9990 arith[0] = operands[0];
9991 arith[3] = operands[1];
10005 if (val1 !=0 && val2 != 0)
10009 if (val1 == 4 || val2 == 4)
10010 /* Other val must be 8, since we know they are adjacent and neither
10012 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
10013 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10015 ldm[0] = ops[0] = operands[4];
10017 ops[2] = GEN_INT (val1);
10018 output_add_immediate (ops);
10020 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10022 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10026 /* Offset is out of range for a single add, so use two ldr. */
10029 ops[2] = GEN_INT (val1);
10030 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10032 ops[2] = GEN_INT (val2);
10033 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10036 else if (val1 != 0)
10039 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10041 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10046 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10048 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10050 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10053 [(set_attr "length" "12")
10054 (set_attr "predicable" "yes")
10055 (set_attr "type" "load1")]
10058 ; This pattern is never tried by combine, so do it as a peephole
10061 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10062 (match_operand:SI 1 "arm_general_register_operand" ""))
10063 (set (reg:CC CC_REGNUM)
10064 (compare:CC (match_dup 1) (const_int 0)))]
10066 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10067 (set (match_dup 0) (match_dup 1))])]
10072 [(set (match_operand:SI 0 "s_register_operand" "")
10073 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10075 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10076 [(match_operand:SI 3 "s_register_operand" "")
10077 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10078 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10080 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10081 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10086 ;; This split can be used because CC_Z mode implies that the following
10087 ;; branch will be an equality, or an unsigned inequality, so the sign
10088 ;; extension is not needed.
10091 [(set (reg:CC_Z CC_REGNUM)
10093 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10095 (match_operand 1 "const_int_operand" "")))
10096 (clobber (match_scratch:SI 2 ""))]
10098 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10099 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
10100 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10101 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10103 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10106 ;; ??? Check the patterns above for Thumb-2 usefulness
10108 (define_expand "prologue"
10109 [(clobber (const_int 0))]
10112 arm_expand_prologue ();
10114 thumb1_expand_prologue ();
10119 (define_expand "epilogue"
10120 [(clobber (const_int 0))]
10123 if (crtl->calls_eh_return)
10124 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10127 thumb1_expand_epilogue ();
10128 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10129 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10131 else if (HAVE_return)
10133 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10134 no need for explicit testing again. */
10135 emit_jump_insn (gen_return ());
10137 else if (TARGET_32BIT)
10139 arm_expand_epilogue (true);
10145 ;; Note - although unspec_volatile's USE all hard registers,
10146 ;; USEs are ignored after relaod has completed. Thus we need
10147 ;; to add an unspec of the link register to ensure that flow
10148 ;; does not think that it is unused by the sibcall branch that
10149 ;; will replace the standard function epilogue.
10150 (define_expand "sibcall_epilogue"
10151 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10152 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10155 arm_expand_epilogue (false);
10160 (define_expand "eh_epilogue"
10161 [(use (match_operand:SI 0 "register_operand" ""))
10162 (use (match_operand:SI 1 "register_operand" ""))
10163 (use (match_operand:SI 2 "register_operand" ""))]
10167 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10168 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10170 rtx ra = gen_rtx_REG (Pmode, 2);
10172 emit_move_insn (ra, operands[2]);
10175 /* This is a hack -- we may have crystalized the function type too
10177 cfun->machine->func_type = 0;
10181 ;; This split is only used during output to reduce the number of patterns
10182 ;; that need assembler instructions adding to them. We allowed the setting
10183 ;; of the conditions to be implicit during rtl generation so that
10184 ;; the conditional compare patterns would work. However this conflicts to
10185 ;; some extent with the conditional data operations, so we have to split them
10188 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10189 ;; conditional execution sufficient?
10192 [(set (match_operand:SI 0 "s_register_operand" "")
10193 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10194 [(match_operand 2 "" "") (match_operand 3 "" "")])
10196 (match_operand 4 "" "")))
10197 (clobber (reg:CC CC_REGNUM))]
10198 "TARGET_ARM && reload_completed"
10199 [(set (match_dup 5) (match_dup 6))
10200 (cond_exec (match_dup 7)
10201 (set (match_dup 0) (match_dup 4)))]
10204 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10205 operands[2], operands[3]);
10206 enum rtx_code rc = GET_CODE (operands[1]);
10208 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10209 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10210 if (mode == CCFPmode || mode == CCFPEmode)
10211 rc = reverse_condition_maybe_unordered (rc);
10213 rc = reverse_condition (rc);
10215 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10220 [(set (match_operand:SI 0 "s_register_operand" "")
10221 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10222 [(match_operand 2 "" "") (match_operand 3 "" "")])
10223 (match_operand 4 "" "")
10225 (clobber (reg:CC CC_REGNUM))]
10226 "TARGET_ARM && reload_completed"
10227 [(set (match_dup 5) (match_dup 6))
10228 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10229 (set (match_dup 0) (match_dup 4)))]
10232 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10233 operands[2], operands[3]);
10235 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10236 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10241 [(set (match_operand:SI 0 "s_register_operand" "")
10242 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10243 [(match_operand 2 "" "") (match_operand 3 "" "")])
10244 (match_operand 4 "" "")
10245 (match_operand 5 "" "")))
10246 (clobber (reg:CC CC_REGNUM))]
10247 "TARGET_ARM && reload_completed"
10248 [(set (match_dup 6) (match_dup 7))
10249 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10250 (set (match_dup 0) (match_dup 4)))
10251 (cond_exec (match_dup 8)
10252 (set (match_dup 0) (match_dup 5)))]
10255 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10256 operands[2], operands[3]);
10257 enum rtx_code rc = GET_CODE (operands[1]);
10259 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10260 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10261 if (mode == CCFPmode || mode == CCFPEmode)
10262 rc = reverse_condition_maybe_unordered (rc);
10264 rc = reverse_condition (rc);
10266 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10271 [(set (match_operand:SI 0 "s_register_operand" "")
10272 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10273 [(match_operand:SI 2 "s_register_operand" "")
10274 (match_operand:SI 3 "arm_add_operand" "")])
10275 (match_operand:SI 4 "arm_rhs_operand" "")
10277 (match_operand:SI 5 "s_register_operand" ""))))
10278 (clobber (reg:CC CC_REGNUM))]
10279 "TARGET_ARM && reload_completed"
10280 [(set (match_dup 6) (match_dup 7))
10281 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10282 (set (match_dup 0) (match_dup 4)))
10283 (cond_exec (match_dup 8)
10284 (set (match_dup 0) (not:SI (match_dup 5))))]
10287 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10288 operands[2], operands[3]);
10289 enum rtx_code rc = GET_CODE (operands[1]);
10291 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10292 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10293 if (mode == CCFPmode || mode == CCFPEmode)
10294 rc = reverse_condition_maybe_unordered (rc);
10296 rc = reverse_condition (rc);
10298 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10302 (define_insn "*cond_move_not"
10303 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10304 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10305 [(match_operand 3 "cc_register" "") (const_int 0)])
10306 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10308 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10312 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10313 [(set_attr "conds" "use")
10314 (set_attr "type" "mvn_reg,multiple")
10315 (set_attr "length" "4,8")]
10318 ;; The next two patterns occur when an AND operation is followed by a
10319 ;; scc insn sequence
10321 (define_insn "*sign_extract_onebit"
10322 [(set (match_operand:SI 0 "s_register_operand" "=r")
10323 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10325 (match_operand:SI 2 "const_int_operand" "n")))
10326 (clobber (reg:CC CC_REGNUM))]
10329 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10330 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10331 return \"mvnne\\t%0, #0\";
10333 [(set_attr "conds" "clob")
10334 (set_attr "length" "8")
10335 (set_attr "type" "multiple")]
10338 (define_insn "*not_signextract_onebit"
10339 [(set (match_operand:SI 0 "s_register_operand" "=r")
10341 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10343 (match_operand:SI 2 "const_int_operand" "n"))))
10344 (clobber (reg:CC CC_REGNUM))]
10347 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10348 output_asm_insn (\"tst\\t%1, %2\", operands);
10349 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10350 return \"movne\\t%0, #0\";
10352 [(set_attr "conds" "clob")
10353 (set_attr "length" "12")
10354 (set_attr "type" "multiple")]
10356 ;; ??? The above patterns need auditing for Thumb-2
10358 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10359 ;; expressions. For simplicity, the first register is also in the unspec
10361 ;; To avoid the usage of GNU extension, the length attribute is computed
10362 ;; in a C function arm_attr_length_push_multi.
10363 (define_insn "*push_multi"
10364 [(match_parallel 2 "multi_register_push"
10365 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10366 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10367 UNSPEC_PUSH_MULT))])]
10371 int num_saves = XVECLEN (operands[2], 0);
10373 /* For the StrongARM at least it is faster to
10374 use STR to store only a single register.
10375 In Thumb mode always use push, and the assembler will pick
10376 something appropriate. */
10377 if (num_saves == 1 && TARGET_ARM)
10378 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10385 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10386 else if (TARGET_THUMB2)
10387 strcpy (pattern, \"push%?\\t{%1\");
10389 strcpy (pattern, \"push\\t{%1\");
10391 for (i = 1; i < num_saves; i++)
10393 strcat (pattern, \", %|\");
10395 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10398 strcat (pattern, \"}\");
10399 output_asm_insn (pattern, operands);
10404 [(set_attr "type" "store4")
10405 (set (attr "length")
10406 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10409 (define_insn "stack_tie"
10410 [(set (mem:BLK (scratch))
10411 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10412 (match_operand:SI 1 "s_register_operand" "rk")]
10416 [(set_attr "length" "0")
10417 (set_attr "type" "block")]
10420 ;; Pop (as used in epilogue RTL)
10422 (define_insn "*load_multiple_with_writeback"
10423 [(match_parallel 0 "load_multiple_operation"
10424 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10425 (plus:SI (match_dup 1)
10426 (match_operand:SI 2 "const_int_I_operand" "I")))
10427 (set (match_operand:SI 3 "s_register_operand" "=rk")
10428 (mem:SI (match_dup 1)))
10430 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10433 arm_output_multireg_pop (operands, /*return_pc=*/false,
10434 /*cond=*/const_true_rtx,
10440 [(set_attr "type" "load4")
10441 (set_attr "predicable" "yes")]
10444 ;; Pop with return (as used in epilogue RTL)
10446 ;; This instruction is generated when the registers are popped at the end of
10447 ;; epilogue. Here, instead of popping the value into LR and then generating
10448 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10450 (define_insn "*pop_multiple_with_writeback_and_return"
10451 [(match_parallel 0 "pop_multiple_return"
10453 (set (match_operand:SI 1 "s_register_operand" "+rk")
10454 (plus:SI (match_dup 1)
10455 (match_operand:SI 2 "const_int_I_operand" "I")))
10456 (set (match_operand:SI 3 "s_register_operand" "=rk")
10457 (mem:SI (match_dup 1)))
10459 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10462 arm_output_multireg_pop (operands, /*return_pc=*/true,
10463 /*cond=*/const_true_rtx,
10469 [(set_attr "type" "load4")
10470 (set_attr "predicable" "yes")]
10473 (define_insn "*pop_multiple_with_return"
10474 [(match_parallel 0 "pop_multiple_return"
10476 (set (match_operand:SI 2 "s_register_operand" "=rk")
10477 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10479 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10482 arm_output_multireg_pop (operands, /*return_pc=*/true,
10483 /*cond=*/const_true_rtx,
10489 [(set_attr "type" "load4")
10490 (set_attr "predicable" "yes")]
10493 ;; Load into PC and return
10494 (define_insn "*ldr_with_return"
10496 (set (reg:SI PC_REGNUM)
10497 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10498 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10499 "ldr%?\t%|pc, [%0], #4"
10500 [(set_attr "type" "load1")
10501 (set_attr "predicable" "yes")]
10503 ;; Pop for floating point registers (as used in epilogue RTL)
10504 (define_insn "*vfp_pop_multiple_with_writeback"
10505 [(match_parallel 0 "pop_multiple_fp"
10506 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10507 (plus:SI (match_dup 1)
10508 (match_operand:SI 2 "const_int_I_operand" "I")))
10509 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10510 (mem:DF (match_dup 1)))])]
10511 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10514 int num_regs = XVECLEN (operands[0], 0);
10517 strcpy (pattern, \"fldmfdd\\t\");
10518 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10519 strcat (pattern, \"!, {\");
10520 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10521 strcat (pattern, \"%P0\");
10522 if ((num_regs - 1) > 1)
10524 strcat (pattern, \"-%P1\");
10525 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10528 strcat (pattern, \"}\");
10529 output_asm_insn (pattern, op_list);
10533 [(set_attr "type" "load4")
10534 (set_attr "conds" "unconditional")
10535 (set_attr "predicable" "no")]
10538 ;; Special patterns for dealing with the constant pool
10540 (define_insn "align_4"
10541 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10544 assemble_align (32);
10547 [(set_attr "type" "no_insn")]
10550 (define_insn "align_8"
10551 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10554 assemble_align (64);
10557 [(set_attr "type" "no_insn")]
10560 (define_insn "consttable_end"
10561 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10564 making_const_table = FALSE;
10567 [(set_attr "type" "no_insn")]
10570 (define_insn "consttable_4"
10571 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10575 rtx x = operands[0];
10576 making_const_table = TRUE;
10577 switch (GET_MODE_CLASS (GET_MODE (x)))
10580 if (GET_MODE (x) == HFmode)
10581 arm_emit_fp16_const (x);
10585 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10586 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10590 /* XXX: Sometimes gcc does something really dumb and ends up with
10591 a HIGH in a constant pool entry, usually because it's trying to
10592 load into a VFP register. We know this will always be used in
10593 combination with a LO_SUM which ignores the high bits, so just
10594 strip off the HIGH. */
10595 if (GET_CODE (x) == HIGH)
10597 assemble_integer (x, 4, BITS_PER_WORD, 1);
10598 mark_symbol_refs_as_used (x);
10603 [(set_attr "length" "4")
10604 (set_attr "type" "no_insn")]
10607 (define_insn "consttable_8"
10608 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10612 making_const_table = TRUE;
10613 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10618 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10619 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10623 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10628 [(set_attr "length" "8")
10629 (set_attr "type" "no_insn")]
10632 (define_insn "consttable_16"
10633 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10637 making_const_table = TRUE;
10638 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10643 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10644 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10648 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10653 [(set_attr "length" "16")
10654 (set_attr "type" "no_insn")]
10657 ;; V5 Instructions,
10659 (define_insn "clzsi2"
10660 [(set (match_operand:SI 0 "s_register_operand" "=r")
10661 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10662 "TARGET_32BIT && arm_arch5"
10664 [(set_attr "predicable" "yes")
10665 (set_attr "predicable_short_it" "no")
10666 (set_attr "type" "clz")])
10668 (define_insn "rbitsi2"
10669 [(set (match_operand:SI 0 "s_register_operand" "=r")
10670 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10671 "TARGET_32BIT && arm_arch_thumb2"
10673 [(set_attr "predicable" "yes")
10674 (set_attr "predicable_short_it" "no")
10675 (set_attr "type" "clz")])
10677 (define_expand "ctzsi2"
10678 [(set (match_operand:SI 0 "s_register_operand" "")
10679 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10680 "TARGET_32BIT && arm_arch_thumb2"
10683 rtx tmp = gen_reg_rtx (SImode);
10684 emit_insn (gen_rbitsi2 (tmp, operands[1]));
10685 emit_insn (gen_clzsi2 (operands[0], tmp));
10691 ;; V5E instructions.
10693 (define_insn "prefetch"
10694 [(prefetch (match_operand:SI 0 "address_operand" "p")
10695 (match_operand:SI 1 "" "")
10696 (match_operand:SI 2 "" ""))]
10697 "TARGET_32BIT && arm_arch5e"
10699 [(set_attr "type" "load1")]
10702 ;; General predication pattern
10705 [(match_operator 0 "arm_comparison_operator"
10706 [(match_operand 1 "cc_register" "")
10710 [(set_attr "predicated" "yes")]
10713 (define_insn "force_register_use"
10714 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10717 [(set_attr "length" "0")
10718 (set_attr "type" "no_insn")]
10722 ;; Patterns for exception handling
10724 (define_expand "eh_return"
10725 [(use (match_operand 0 "general_operand" ""))]
10730 emit_insn (gen_arm_eh_return (operands[0]));
10732 emit_insn (gen_thumb_eh_return (operands[0]));
10737 ;; We can't expand this before we know where the link register is stored.
10738 (define_insn_and_split "arm_eh_return"
10739 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10741 (clobber (match_scratch:SI 1 "=&r"))]
10744 "&& reload_completed"
10748 arm_set_return_address (operands[0], operands[1]);
10756 (define_insn "load_tp_hard"
10757 [(set (match_operand:SI 0 "register_operand" "=r")
10758 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10760 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
10761 [(set_attr "predicable" "yes")
10762 (set_attr "type" "mrs")]
10765 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
10766 (define_insn "load_tp_soft"
10767 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10768 (clobber (reg:SI LR_REGNUM))
10769 (clobber (reg:SI IP_REGNUM))
10770 (clobber (reg:CC CC_REGNUM))]
10772 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
10773 [(set_attr "conds" "clob")
10774 (set_attr "type" "branch")]
10777 ;; tls descriptor call
10778 (define_insn "tlscall"
10779 [(set (reg:SI R0_REGNUM)
10780 (unspec:SI [(reg:SI R0_REGNUM)
10781 (match_operand:SI 0 "" "X")
10782 (match_operand 1 "" "")] UNSPEC_TLS))
10783 (clobber (reg:SI R1_REGNUM))
10784 (clobber (reg:SI LR_REGNUM))
10785 (clobber (reg:SI CC_REGNUM))]
10788 targetm.asm_out.internal_label (asm_out_file, "LPIC",
10789 INTVAL (operands[1]));
10790 return "bl\\t%c0(tlscall)";
10792 [(set_attr "conds" "clob")
10793 (set_attr "length" "4")
10794 (set_attr "type" "branch")]
10797 ;; For thread pointer builtin
10798 (define_expand "get_thread_pointersi"
10799 [(match_operand:SI 0 "s_register_operand" "=r")]
10803 arm_load_tp (operands[0]);
10809 ;; We only care about the lower 16 bits of the constant
10810 ;; being inserted into the upper 16 bits of the register.
10811 (define_insn "*arm_movtas_ze"
10812 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10815 (match_operand:SI 1 "const_int_operand" ""))]
10818 [(set_attr "predicable" "yes")
10819 (set_attr "predicable_short_it" "no")
10820 (set_attr "length" "4")
10821 (set_attr "type" "mov_imm")]
10824 (define_insn "*arm_rev"
10825 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10826 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10832 [(set_attr "arch" "t1,t2,32")
10833 (set_attr "length" "2,2,4")
10834 (set_attr "predicable" "no,yes,yes")
10835 (set_attr "predicable_short_it" "no")
10836 (set_attr "type" "rev")]
10839 (define_expand "arm_legacy_rev"
10840 [(set (match_operand:SI 2 "s_register_operand" "")
10841 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
10845 (lshiftrt:SI (match_dup 2)
10847 (set (match_operand:SI 3 "s_register_operand" "")
10848 (rotatert:SI (match_dup 1)
10851 (and:SI (match_dup 2)
10852 (const_int -65281)))
10853 (set (match_operand:SI 0 "s_register_operand" "")
10854 (xor:SI (match_dup 3)
10860 ;; Reuse temporaries to keep register pressure down.
10861 (define_expand "thumb_legacy_rev"
10862 [(set (match_operand:SI 2 "s_register_operand" "")
10863 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
10865 (set (match_operand:SI 3 "s_register_operand" "")
10866 (lshiftrt:SI (match_dup 1)
10869 (ior:SI (match_dup 3)
10871 (set (match_operand:SI 4 "s_register_operand" "")
10873 (set (match_operand:SI 5 "s_register_operand" "")
10874 (rotatert:SI (match_dup 1)
10877 (ashift:SI (match_dup 5)
10880 (lshiftrt:SI (match_dup 5)
10883 (ior:SI (match_dup 5)
10886 (rotatert:SI (match_dup 5)
10888 (set (match_operand:SI 0 "s_register_operand" "")
10889 (ior:SI (match_dup 5)
10895 (define_expand "bswapsi2"
10896 [(set (match_operand:SI 0 "s_register_operand" "=r")
10897 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
10898 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
10902 rtx op2 = gen_reg_rtx (SImode);
10903 rtx op3 = gen_reg_rtx (SImode);
10907 rtx op4 = gen_reg_rtx (SImode);
10908 rtx op5 = gen_reg_rtx (SImode);
10910 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
10911 op2, op3, op4, op5));
10915 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
10924 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
10925 ;; and unsigned variants, respectively. For rev16, expose
10926 ;; byte-swapping in the lower 16 bits only.
10927 (define_insn "*arm_revsh"
10928 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10929 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
10935 [(set_attr "arch" "t1,t2,32")
10936 (set_attr "length" "2,2,4")
10937 (set_attr "type" "rev")]
10940 (define_insn "*arm_rev16"
10941 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
10942 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
10948 [(set_attr "arch" "t1,t2,32")
10949 (set_attr "length" "2,2,4")
10950 (set_attr "type" "rev")]
10953 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
10954 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
10955 ;; each valid permutation.
10957 (define_insn "arm_rev16si2"
10958 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10959 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
10961 (match_operand:SI 3 "const_int_operand" "n,n,n"))
10962 (and:SI (lshiftrt:SI (match_dup 1)
10964 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
10966 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
10967 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
10969 [(set_attr "arch" "t1,t2,32")
10970 (set_attr "length" "2,2,4")
10971 (set_attr "type" "rev")]
10974 (define_insn "arm_rev16si2_alt"
10975 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10976 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
10978 (match_operand:SI 2 "const_int_operand" "n,n,n"))
10979 (and:SI (ashift:SI (match_dup 1)
10981 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
10983 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
10984 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
10986 [(set_attr "arch" "t1,t2,32")
10987 (set_attr "length" "2,2,4")
10988 (set_attr "type" "rev")]
10991 (define_expand "bswaphi2"
10992 [(set (match_operand:HI 0 "s_register_operand" "=r")
10993 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
10998 ;; Patterns for LDRD/STRD in Thumb2 mode
11000 (define_insn "*thumb2_ldrd"
11001 [(set (match_operand:SI 0 "s_register_operand" "=r")
11002 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11003 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11004 (set (match_operand:SI 3 "s_register_operand" "=r")
11005 (mem:SI (plus:SI (match_dup 1)
11006 (match_operand:SI 4 "const_int_operand" ""))))]
11007 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11008 && current_tune->prefer_ldrd_strd
11009 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11010 && (operands_ok_ldrd_strd (operands[0], operands[3],
11011 operands[1], INTVAL (operands[2]),
11013 "ldrd%?\t%0, %3, [%1, %2]"
11014 [(set_attr "type" "load2")
11015 (set_attr "predicable" "yes")
11016 (set_attr "predicable_short_it" "no")])
11018 (define_insn "*thumb2_ldrd_base"
11019 [(set (match_operand:SI 0 "s_register_operand" "=r")
11020 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11021 (set (match_operand:SI 2 "s_register_operand" "=r")
11022 (mem:SI (plus:SI (match_dup 1)
11024 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11025 && current_tune->prefer_ldrd_strd
11026 && (operands_ok_ldrd_strd (operands[0], operands[2],
11027 operands[1], 0, false, true))"
11028 "ldrd%?\t%0, %2, [%1]"
11029 [(set_attr "type" "load2")
11030 (set_attr "predicable" "yes")
11031 (set_attr "predicable_short_it" "no")])
11033 (define_insn "*thumb2_ldrd_base_neg"
11034 [(set (match_operand:SI 0 "s_register_operand" "=r")
11035 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11037 (set (match_operand:SI 2 "s_register_operand" "=r")
11038 (mem:SI (match_dup 1)))]
11039 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11040 && current_tune->prefer_ldrd_strd
11041 && (operands_ok_ldrd_strd (operands[0], operands[2],
11042 operands[1], -4, false, true))"
11043 "ldrd%?\t%0, %2, [%1, #-4]"
11044 [(set_attr "type" "load2")
11045 (set_attr "predicable" "yes")
11046 (set_attr "predicable_short_it" "no")])
11048 (define_insn "*thumb2_strd"
11049 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11050 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11051 (match_operand:SI 2 "s_register_operand" "r"))
11052 (set (mem:SI (plus:SI (match_dup 0)
11053 (match_operand:SI 3 "const_int_operand" "")))
11054 (match_operand:SI 4 "s_register_operand" "r"))]
11055 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11056 && current_tune->prefer_ldrd_strd
11057 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11058 && (operands_ok_ldrd_strd (operands[2], operands[4],
11059 operands[0], INTVAL (operands[1]),
11061 "strd%?\t%2, %4, [%0, %1]"
11062 [(set_attr "type" "store2")
11063 (set_attr "predicable" "yes")
11064 (set_attr "predicable_short_it" "no")])
11066 (define_insn "*thumb2_strd_base"
11067 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11068 (match_operand:SI 1 "s_register_operand" "r"))
11069 (set (mem:SI (plus:SI (match_dup 0)
11071 (match_operand:SI 2 "s_register_operand" "r"))]
11072 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11073 && current_tune->prefer_ldrd_strd
11074 && (operands_ok_ldrd_strd (operands[1], operands[2],
11075 operands[0], 0, false, false))"
11076 "strd%?\t%1, %2, [%0]"
11077 [(set_attr "type" "store2")
11078 (set_attr "predicable" "yes")
11079 (set_attr "predicable_short_it" "no")])
11081 (define_insn "*thumb2_strd_base_neg"
11082 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11084 (match_operand:SI 1 "s_register_operand" "r"))
11085 (set (mem:SI (match_dup 0))
11086 (match_operand:SI 2 "s_register_operand" "r"))]
11087 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11088 && current_tune->prefer_ldrd_strd
11089 && (operands_ok_ldrd_strd (operands[1], operands[2],
11090 operands[0], -4, false, false))"
11091 "strd%?\t%1, %2, [%0, #-4]"
11092 [(set_attr "type" "store2")
11093 (set_attr "predicable" "yes")
11094 (set_attr "predicable_short_it" "no")])
11096 ;; ARMv8 CRC32 instructions.
11097 (define_insn "<crc_variant>"
11098 [(set (match_operand:SI 0 "s_register_operand" "=r")
11099 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11100 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11103 "<crc_variant>\\t%0, %1, %2"
11104 [(set_attr "type" "crc")
11105 (set_attr "conds" "unconditional")]
11108 ;; Load the load/store double peephole optimizations.
11109 (include "ldrdstrd.md")
11111 ;; Load the load/store multiple patterns
11112 (include "ldmstm.md")
11114 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11115 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11116 (define_insn "*load_multiple"
11117 [(match_parallel 0 "load_multiple_operation"
11118 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11119 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11124 arm_output_multireg_pop (operands, /*return_pc=*/false,
11125 /*cond=*/const_true_rtx,
11131 [(set_attr "predicable" "yes")]
11134 ;; Vector bits common to IWMMXT and Neon
11135 (include "vec-common.md")
11136 ;; Load the Intel Wireless Multimedia Extension patterns
11137 (include "iwmmxt.md")
11138 ;; Load the VFP co-processor patterns
11140 ;; Thumb-1 patterns
11141 (include "thumb1.md")
11142 ;; Thumb-2 patterns
11143 (include "thumb2.md")
11145 (include "neon.md")
11147 (include "crypto.md")
11148 ;; Synchronization Primitives
11149 (include "sync.md")
11150 ;; Fixed-point patterns
11151 (include "arm-fixed.md")