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) && !arm_restrict_it"
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 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 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 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,Uh,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 (define_expand "setmemsi"
6720 [(match_operand:BLK 0 "general_operand" "")
6721 (match_operand:SI 1 "const_int_operand" "")
6722 (match_operand:SI 2 "const_int_operand" "")
6723 (match_operand:SI 3 "const_int_operand" "")]
6726 if (arm_gen_setmem (operands))
6733 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6734 ;; We could let this apply for blocks of less than this, but it clobbers so
6735 ;; many registers that there is then probably a better way.
6737 (define_expand "movmemqi"
6738 [(match_operand:BLK 0 "general_operand" "")
6739 (match_operand:BLK 1 "general_operand" "")
6740 (match_operand:SI 2 "const_int_operand" "")
6741 (match_operand:SI 3 "const_int_operand" "")]
6746 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6747 && !optimize_function_for_size_p (cfun))
6749 if (gen_movmem_ldrd_strd (operands))
6754 if (arm_gen_movmemqi (operands))
6758 else /* TARGET_THUMB1 */
6760 if ( INTVAL (operands[3]) != 4
6761 || INTVAL (operands[2]) > 48)
6764 thumb_expand_movmemqi (operands);
6771 ;; Compare & branch insns
6772 ;; The range calculations are based as follows:
6773 ;; For forward branches, the address calculation returns the address of
6774 ;; the next instruction. This is 2 beyond the branch instruction.
6775 ;; For backward branches, the address calculation returns the address of
6776 ;; the first instruction in this pattern (cmp). This is 2 before the branch
6777 ;; instruction for the shortest sequence, and 4 before the branch instruction
6778 ;; if we have to jump around an unconditional branch.
6779 ;; To the basic branch range the PC offset must be added (this is +4).
6780 ;; So for forward branches we have
6781 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6782 ;; And for backward branches we have
6783 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6785 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6786 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
6788 (define_expand "cbranchsi4"
6789 [(set (pc) (if_then_else
6790 (match_operator 0 "expandable_comparison_operator"
6791 [(match_operand:SI 1 "s_register_operand" "")
6792 (match_operand:SI 2 "nonmemory_operand" "")])
6793 (label_ref (match_operand 3 "" ""))
6799 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6801 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6805 if (thumb1_cmpneg_operand (operands[2], SImode))
6807 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6808 operands[3], operands[0]));
6811 if (!thumb1_cmp_operand (operands[2], SImode))
6812 operands[2] = force_reg (SImode, operands[2]);
6815 (define_expand "cbranchsf4"
6816 [(set (pc) (if_then_else
6817 (match_operator 0 "expandable_comparison_operator"
6818 [(match_operand:SF 1 "s_register_operand" "")
6819 (match_operand:SF 2 "arm_float_compare_operand" "")])
6820 (label_ref (match_operand 3 "" ""))
6822 "TARGET_32BIT && TARGET_HARD_FLOAT"
6823 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6824 operands[3])); DONE;"
6827 (define_expand "cbranchdf4"
6828 [(set (pc) (if_then_else
6829 (match_operator 0 "expandable_comparison_operator"
6830 [(match_operand:DF 1 "s_register_operand" "")
6831 (match_operand:DF 2 "arm_float_compare_operand" "")])
6832 (label_ref (match_operand 3 "" ""))
6834 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6835 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6836 operands[3])); DONE;"
6839 (define_expand "cbranchdi4"
6840 [(set (pc) (if_then_else
6841 (match_operator 0 "expandable_comparison_operator"
6842 [(match_operand:DI 1 "s_register_operand" "")
6843 (match_operand:DI 2 "cmpdi_operand" "")])
6844 (label_ref (match_operand 3 "" ""))
6848 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6850 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6856 ;; Comparison and test insns
6858 (define_insn "*arm_cmpsi_insn"
6859 [(set (reg:CC CC_REGNUM)
6860 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6861 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
6869 [(set_attr "conds" "set")
6870 (set_attr "arch" "t2,t2,any,any,any")
6871 (set_attr "length" "2,2,4,4,4")
6872 (set_attr "predicable" "yes")
6873 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6874 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6877 (define_insn "*cmpsi_shiftsi"
6878 [(set (reg:CC CC_REGNUM)
6879 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
6880 (match_operator:SI 3 "shift_operator"
6881 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6882 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6885 [(set_attr "conds" "set")
6886 (set_attr "shift" "1")
6887 (set_attr "arch" "32,a,a")
6888 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
6890 (define_insn "*cmpsi_shiftsi_swp"
6891 [(set (reg:CC_SWP CC_REGNUM)
6892 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6893 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6894 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6895 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6898 [(set_attr "conds" "set")
6899 (set_attr "shift" "1")
6900 (set_attr "arch" "32,a,a")
6901 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
6903 (define_insn "*arm_cmpsi_negshiftsi_si"
6904 [(set (reg:CC_Z CC_REGNUM)
6906 (neg:SI (match_operator:SI 1 "shift_operator"
6907 [(match_operand:SI 2 "s_register_operand" "r")
6908 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6909 (match_operand:SI 0 "s_register_operand" "r")))]
6912 [(set_attr "conds" "set")
6913 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6914 (const_string "alus_shift_imm")
6915 (const_string "alus_shift_reg")))
6916 (set_attr "predicable" "yes")]
6919 ;; DImode comparisons. The generic code generates branches that
6920 ;; if-conversion can not reduce to a conditional compare, so we do
6923 (define_insn_and_split "*arm_cmpdi_insn"
6924 [(set (reg:CC_NCV CC_REGNUM)
6925 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6926 (match_operand:DI 1 "arm_di_operand" "rDi")))
6927 (clobber (match_scratch:SI 2 "=r"))]
6929 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6930 "&& reload_completed"
6931 [(set (reg:CC CC_REGNUM)
6932 (compare:CC (match_dup 0) (match_dup 1)))
6933 (parallel [(set (reg:CC CC_REGNUM)
6934 (compare:CC (match_dup 3) (match_dup 4)))
6936 (minus:SI (match_dup 5)
6937 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6939 operands[3] = gen_highpart (SImode, operands[0]);
6940 operands[0] = gen_lowpart (SImode, operands[0]);
6941 if (CONST_INT_P (operands[1]))
6943 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
6946 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
6950 operands[4] = gen_highpart (SImode, operands[1]);
6951 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6953 operands[1] = gen_lowpart (SImode, operands[1]);
6954 operands[2] = gen_lowpart (SImode, operands[2]);
6956 [(set_attr "conds" "set")
6957 (set_attr "length" "8")
6958 (set_attr "type" "multiple")]
6961 (define_insn_and_split "*arm_cmpdi_unsigned"
6962 [(set (reg:CC_CZ CC_REGNUM)
6963 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6964 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
6967 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6968 "&& reload_completed"
6969 [(set (reg:CC CC_REGNUM)
6970 (compare:CC (match_dup 2) (match_dup 3)))
6971 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6972 (set (reg:CC CC_REGNUM)
6973 (compare:CC (match_dup 0) (match_dup 1))))]
6975 operands[2] = gen_highpart (SImode, operands[0]);
6976 operands[0] = gen_lowpart (SImode, operands[0]);
6977 if (CONST_INT_P (operands[1]))
6978 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6980 operands[3] = gen_highpart (SImode, operands[1]);
6981 operands[1] = gen_lowpart (SImode, operands[1]);
6983 [(set_attr "conds" "set")
6984 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
6985 (set_attr "arch" "t2,t2,t2,a")
6986 (set_attr "length" "6,6,10,8")
6987 (set_attr "type" "multiple")]
6990 (define_insn "*arm_cmpdi_zero"
6991 [(set (reg:CC_Z CC_REGNUM)
6992 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6994 (clobber (match_scratch:SI 1 "=r"))]
6996 "orr%.\\t%1, %Q0, %R0"
6997 [(set_attr "conds" "set")
6998 (set_attr "type" "logics_reg")]
7001 ; This insn allows redundant compares to be removed by cse, nothing should
7002 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7003 ; is deleted later on. The match_dup will match the mode here, so that
7004 ; mode changes of the condition codes aren't lost by this even though we don't
7005 ; specify what they are.
7007 (define_insn "*deleted_compare"
7008 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7010 "\\t%@ deleted compare"
7011 [(set_attr "conds" "set")
7012 (set_attr "length" "0")
7013 (set_attr "type" "no_insn")]
7017 ;; Conditional branch insns
7019 (define_expand "cbranch_cc"
7021 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7022 (match_operand 2 "" "")])
7023 (label_ref (match_operand 3 "" ""))
7026 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7027 operands[1], operands[2], NULL_RTX);
7028 operands[2] = const0_rtx;"
7032 ;; Patterns to match conditional branch insns.
7035 (define_insn "arm_cond_branch"
7037 (if_then_else (match_operator 1 "arm_comparison_operator"
7038 [(match_operand 2 "cc_register" "") (const_int 0)])
7039 (label_ref (match_operand 0 "" ""))
7043 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7045 arm_ccfsm_state += 2;
7048 return \"b%d1\\t%l0\";
7050 [(set_attr "conds" "use")
7051 (set_attr "type" "branch")
7052 (set (attr "length")
7054 (and (match_test "TARGET_THUMB2")
7055 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7056 (le (minus (match_dup 0) (pc)) (const_int 256))))
7061 (define_insn "*arm_cond_branch_reversed"
7063 (if_then_else (match_operator 1 "arm_comparison_operator"
7064 [(match_operand 2 "cc_register" "") (const_int 0)])
7066 (label_ref (match_operand 0 "" ""))))]
7069 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7071 arm_ccfsm_state += 2;
7074 return \"b%D1\\t%l0\";
7076 [(set_attr "conds" "use")
7077 (set_attr "type" "branch")
7078 (set (attr "length")
7080 (and (match_test "TARGET_THUMB2")
7081 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7082 (le (minus (match_dup 0) (pc)) (const_int 256))))
7091 (define_expand "cstore_cc"
7092 [(set (match_operand:SI 0 "s_register_operand" "")
7093 (match_operator:SI 1 "" [(match_operand 2 "" "")
7094 (match_operand 3 "" "")]))]
7096 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7097 operands[2], operands[3], NULL_RTX);
7098 operands[3] = const0_rtx;"
7101 (define_insn_and_split "*mov_scc"
7102 [(set (match_operand:SI 0 "s_register_operand" "=r")
7103 (match_operator:SI 1 "arm_comparison_operator"
7104 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7106 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7109 (if_then_else:SI (match_dup 1)
7113 [(set_attr "conds" "use")
7114 (set_attr "length" "8")
7115 (set_attr "type" "multiple")]
7118 (define_insn_and_split "*mov_negscc"
7119 [(set (match_operand:SI 0 "s_register_operand" "=r")
7120 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7121 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7123 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7126 (if_then_else:SI (match_dup 1)
7130 operands[3] = GEN_INT (~0);
7132 [(set_attr "conds" "use")
7133 (set_attr "length" "8")
7134 (set_attr "type" "multiple")]
7137 (define_insn_and_split "*mov_notscc"
7138 [(set (match_operand:SI 0 "s_register_operand" "=r")
7139 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7140 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7142 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7145 (if_then_else:SI (match_dup 1)
7149 operands[3] = GEN_INT (~1);
7150 operands[4] = GEN_INT (~0);
7152 [(set_attr "conds" "use")
7153 (set_attr "length" "8")
7154 (set_attr "type" "multiple")]
7157 (define_expand "cstoresi4"
7158 [(set (match_operand:SI 0 "s_register_operand" "")
7159 (match_operator:SI 1 "expandable_comparison_operator"
7160 [(match_operand:SI 2 "s_register_operand" "")
7161 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7162 "TARGET_32BIT || TARGET_THUMB1"
7164 rtx op3, scratch, scratch2;
7168 if (!arm_add_operand (operands[3], SImode))
7169 operands[3] = force_reg (SImode, operands[3]);
7170 emit_insn (gen_cstore_cc (operands[0], operands[1],
7171 operands[2], operands[3]));
7175 if (operands[3] == const0_rtx)
7177 switch (GET_CODE (operands[1]))
7180 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7184 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7188 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7189 NULL_RTX, 0, OPTAB_WIDEN);
7190 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7191 NULL_RTX, 0, OPTAB_WIDEN);
7192 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7193 operands[0], 1, OPTAB_WIDEN);
7197 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7199 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7200 NULL_RTX, 1, OPTAB_WIDEN);
7204 scratch = expand_binop (SImode, ashr_optab, operands[2],
7205 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7206 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7207 NULL_RTX, 0, OPTAB_WIDEN);
7208 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7212 /* LT is handled by generic code. No need for unsigned with 0. */
7219 switch (GET_CODE (operands[1]))
7222 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7223 NULL_RTX, 0, OPTAB_WIDEN);
7224 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7228 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7229 NULL_RTX, 0, OPTAB_WIDEN);
7230 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7234 op3 = force_reg (SImode, operands[3]);
7236 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7237 NULL_RTX, 1, OPTAB_WIDEN);
7238 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7239 NULL_RTX, 0, OPTAB_WIDEN);
7240 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7246 if (!thumb1_cmp_operand (op3, SImode))
7247 op3 = force_reg (SImode, op3);
7248 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7249 NULL_RTX, 0, OPTAB_WIDEN);
7250 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7251 NULL_RTX, 1, OPTAB_WIDEN);
7252 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7257 op3 = force_reg (SImode, operands[3]);
7258 scratch = force_reg (SImode, const0_rtx);
7259 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7265 if (!thumb1_cmp_operand (op3, SImode))
7266 op3 = force_reg (SImode, op3);
7267 scratch = force_reg (SImode, const0_rtx);
7268 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7274 if (!thumb1_cmp_operand (op3, SImode))
7275 op3 = force_reg (SImode, op3);
7276 scratch = gen_reg_rtx (SImode);
7277 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7281 op3 = force_reg (SImode, operands[3]);
7282 scratch = gen_reg_rtx (SImode);
7283 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7286 /* No good sequences for GT, LT. */
7293 (define_expand "cstoresf4"
7294 [(set (match_operand:SI 0 "s_register_operand" "")
7295 (match_operator:SI 1 "expandable_comparison_operator"
7296 [(match_operand:SF 2 "s_register_operand" "")
7297 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7298 "TARGET_32BIT && TARGET_HARD_FLOAT"
7299 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7300 operands[2], operands[3])); DONE;"
7303 (define_expand "cstoredf4"
7304 [(set (match_operand:SI 0 "s_register_operand" "")
7305 (match_operator:SI 1 "expandable_comparison_operator"
7306 [(match_operand:DF 2 "s_register_operand" "")
7307 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7308 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7309 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7310 operands[2], operands[3])); DONE;"
7313 (define_expand "cstoredi4"
7314 [(set (match_operand:SI 0 "s_register_operand" "")
7315 (match_operator:SI 1 "expandable_comparison_operator"
7316 [(match_operand:DI 2 "s_register_operand" "")
7317 (match_operand:DI 3 "cmpdi_operand" "")]))]
7320 if (!arm_validize_comparison (&operands[1],
7324 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7331 ;; Conditional move insns
7333 (define_expand "movsicc"
7334 [(set (match_operand:SI 0 "s_register_operand" "")
7335 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7336 (match_operand:SI 2 "arm_not_operand" "")
7337 (match_operand:SI 3 "arm_not_operand" "")))]
7344 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7345 &XEXP (operands[1], 1)))
7348 code = GET_CODE (operands[1]);
7349 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7350 XEXP (operands[1], 1), NULL_RTX);
7351 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7355 (define_expand "movsfcc"
7356 [(set (match_operand:SF 0 "s_register_operand" "")
7357 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7358 (match_operand:SF 2 "s_register_operand" "")
7359 (match_operand:SF 3 "s_register_operand" "")))]
7360 "TARGET_32BIT && TARGET_HARD_FLOAT"
7363 enum rtx_code code = GET_CODE (operands[1]);
7366 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7367 &XEXP (operands[1], 1)))
7370 code = GET_CODE (operands[1]);
7371 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7372 XEXP (operands[1], 1), NULL_RTX);
7373 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7377 (define_expand "movdfcc"
7378 [(set (match_operand:DF 0 "s_register_operand" "")
7379 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7380 (match_operand:DF 2 "s_register_operand" "")
7381 (match_operand:DF 3 "s_register_operand" "")))]
7382 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7385 enum rtx_code code = GET_CODE (operands[1]);
7388 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7389 &XEXP (operands[1], 1)))
7391 code = GET_CODE (operands[1]);
7392 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7393 XEXP (operands[1], 1), NULL_RTX);
7394 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7398 (define_insn "*cmov<mode>"
7399 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7400 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7401 [(match_operand 2 "cc_register" "") (const_int 0)])
7402 (match_operand:SDF 3 "s_register_operand"
7404 (match_operand:SDF 4 "s_register_operand"
7405 "<F_constraint>")))]
7406 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7409 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7416 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7421 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7427 [(set_attr "conds" "use")
7428 (set_attr "type" "fcsel")]
7431 (define_insn_and_split "*movsicc_insn"
7432 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7434 (match_operator 3 "arm_comparison_operator"
7435 [(match_operand 4 "cc_register" "") (const_int 0)])
7436 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7437 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7448 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7449 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7450 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7451 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7452 "&& reload_completed"
7455 enum rtx_code rev_code;
7459 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7461 gen_rtx_SET (VOIDmode,
7465 rev_code = GET_CODE (operands[3]);
7466 mode = GET_MODE (operands[4]);
7467 if (mode == CCFPmode || mode == CCFPEmode)
7468 rev_code = reverse_condition_maybe_unordered (rev_code);
7470 rev_code = reverse_condition (rev_code);
7472 rev_cond = gen_rtx_fmt_ee (rev_code,
7476 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7478 gen_rtx_SET (VOIDmode,
7483 [(set_attr "length" "4,4,4,4,8,8,8,8")
7484 (set_attr "conds" "use")
7485 (set_attr_alternative "type"
7486 [(if_then_else (match_operand 2 "const_int_operand" "")
7487 (const_string "mov_imm")
7488 (const_string "mov_reg"))
7489 (const_string "mvn_imm")
7490 (if_then_else (match_operand 1 "const_int_operand" "")
7491 (const_string "mov_imm")
7492 (const_string "mov_reg"))
7493 (const_string "mvn_imm")
7494 (const_string "mov_reg")
7495 (const_string "mov_reg")
7496 (const_string "mov_reg")
7497 (const_string "mov_reg")])]
7500 (define_insn "*movsfcc_soft_insn"
7501 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7502 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7503 [(match_operand 4 "cc_register" "") (const_int 0)])
7504 (match_operand:SF 1 "s_register_operand" "0,r")
7505 (match_operand:SF 2 "s_register_operand" "r,0")))]
7506 "TARGET_ARM && TARGET_SOFT_FLOAT"
7510 [(set_attr "conds" "use")
7511 (set_attr "type" "mov_reg")]
7515 ;; Jump and linkage insns
7517 (define_expand "jump"
7519 (label_ref (match_operand 0 "" "")))]
7524 (define_insn "*arm_jump"
7526 (label_ref (match_operand 0 "" "")))]
7530 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7532 arm_ccfsm_state += 2;
7535 return \"b%?\\t%l0\";
7538 [(set_attr "predicable" "yes")
7539 (set (attr "length")
7541 (and (match_test "TARGET_THUMB2")
7542 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7543 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7546 (set_attr "type" "branch")]
7549 (define_expand "call"
7550 [(parallel [(call (match_operand 0 "memory_operand" "")
7551 (match_operand 1 "general_operand" ""))
7552 (use (match_operand 2 "" ""))
7553 (clobber (reg:SI LR_REGNUM))])]
7559 /* In an untyped call, we can get NULL for operand 2. */
7560 if (operands[2] == NULL_RTX)
7561 operands[2] = const0_rtx;
7563 /* Decide if we should generate indirect calls by loading the
7564 32-bit address of the callee into a register before performing the
7566 callee = XEXP (operands[0], 0);
7567 if (GET_CODE (callee) == SYMBOL_REF
7568 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7570 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7572 pat = gen_call_internal (operands[0], operands[1], operands[2]);
7573 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7578 (define_expand "call_internal"
7579 [(parallel [(call (match_operand 0 "memory_operand" "")
7580 (match_operand 1 "general_operand" ""))
7581 (use (match_operand 2 "" ""))
7582 (clobber (reg:SI LR_REGNUM))])])
7584 (define_insn "*call_reg_armv5"
7585 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7586 (match_operand 1 "" ""))
7587 (use (match_operand 2 "" ""))
7588 (clobber (reg:SI LR_REGNUM))]
7589 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7591 [(set_attr "type" "call")]
7594 (define_insn "*call_reg_arm"
7595 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7596 (match_operand 1 "" ""))
7597 (use (match_operand 2 "" ""))
7598 (clobber (reg:SI LR_REGNUM))]
7599 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7601 return output_call (operands);
7603 ;; length is worst case, normally it is only two
7604 [(set_attr "length" "12")
7605 (set_attr "type" "call")]
7609 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7610 ;; considered a function call by the branch predictor of some cores (PR40887).
7611 ;; Falls back to blx rN (*call_reg_armv5).
7613 (define_insn "*call_mem"
7614 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
7615 (match_operand 1 "" ""))
7616 (use (match_operand 2 "" ""))
7617 (clobber (reg:SI LR_REGNUM))]
7618 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7620 return output_call_mem (operands);
7622 [(set_attr "length" "12")
7623 (set_attr "type" "call")]
7626 (define_expand "call_value"
7627 [(parallel [(set (match_operand 0 "" "")
7628 (call (match_operand 1 "memory_operand" "")
7629 (match_operand 2 "general_operand" "")))
7630 (use (match_operand 3 "" ""))
7631 (clobber (reg:SI LR_REGNUM))])]
7637 /* In an untyped call, we can get NULL for operand 2. */
7638 if (operands[3] == 0)
7639 operands[3] = const0_rtx;
7641 /* Decide if we should generate indirect calls by loading the
7642 32-bit address of the callee into a register before performing the
7644 callee = XEXP (operands[1], 0);
7645 if (GET_CODE (callee) == SYMBOL_REF
7646 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7648 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7650 pat = gen_call_value_internal (operands[0], operands[1],
7651 operands[2], operands[3]);
7652 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7657 (define_expand "call_value_internal"
7658 [(parallel [(set (match_operand 0 "" "")
7659 (call (match_operand 1 "memory_operand" "")
7660 (match_operand 2 "general_operand" "")))
7661 (use (match_operand 3 "" ""))
7662 (clobber (reg:SI LR_REGNUM))])])
7664 (define_insn "*call_value_reg_armv5"
7665 [(set (match_operand 0 "" "")
7666 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7667 (match_operand 2 "" "")))
7668 (use (match_operand 3 "" ""))
7669 (clobber (reg:SI LR_REGNUM))]
7670 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7672 [(set_attr "type" "call")]
7675 (define_insn "*call_value_reg_arm"
7676 [(set (match_operand 0 "" "")
7677 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7678 (match_operand 2 "" "")))
7679 (use (match_operand 3 "" ""))
7680 (clobber (reg:SI LR_REGNUM))]
7681 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7683 return output_call (&operands[1]);
7685 [(set_attr "length" "12")
7686 (set_attr "type" "call")]
7689 ;; Note: see *call_mem
7691 (define_insn "*call_value_mem"
7692 [(set (match_operand 0 "" "")
7693 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
7694 (match_operand 2 "" "")))
7695 (use (match_operand 3 "" ""))
7696 (clobber (reg:SI LR_REGNUM))]
7697 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7698 && !SIBLING_CALL_P (insn)"
7700 return output_call_mem (&operands[1]);
7702 [(set_attr "length" "12")
7703 (set_attr "type" "call")]
7706 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7707 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7709 (define_insn "*call_symbol"
7710 [(call (mem:SI (match_operand:SI 0 "" ""))
7711 (match_operand 1 "" ""))
7712 (use (match_operand 2 "" ""))
7713 (clobber (reg:SI LR_REGNUM))]
7715 && !SIBLING_CALL_P (insn)
7716 && (GET_CODE (operands[0]) == SYMBOL_REF)
7717 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7720 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7722 [(set_attr "type" "call")]
7725 (define_insn "*call_value_symbol"
7726 [(set (match_operand 0 "" "")
7727 (call (mem:SI (match_operand:SI 1 "" ""))
7728 (match_operand:SI 2 "" "")))
7729 (use (match_operand 3 "" ""))
7730 (clobber (reg:SI LR_REGNUM))]
7732 && !SIBLING_CALL_P (insn)
7733 && (GET_CODE (operands[1]) == SYMBOL_REF)
7734 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7737 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7739 [(set_attr "type" "call")]
7742 (define_expand "sibcall_internal"
7743 [(parallel [(call (match_operand 0 "memory_operand" "")
7744 (match_operand 1 "general_operand" ""))
7746 (use (match_operand 2 "" ""))])])
7748 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7749 (define_expand "sibcall"
7750 [(parallel [(call (match_operand 0 "memory_operand" "")
7751 (match_operand 1 "general_operand" ""))
7753 (use (match_operand 2 "" ""))])]
7759 if ((!REG_P (XEXP (operands[0], 0))
7760 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7761 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7762 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7763 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7765 if (operands[2] == NULL_RTX)
7766 operands[2] = const0_rtx;
7768 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7769 arm_emit_call_insn (pat, operands[0], true);
7774 (define_expand "sibcall_value_internal"
7775 [(parallel [(set (match_operand 0 "" "")
7776 (call (match_operand 1 "memory_operand" "")
7777 (match_operand 2 "general_operand" "")))
7779 (use (match_operand 3 "" ""))])])
7781 (define_expand "sibcall_value"
7782 [(parallel [(set (match_operand 0 "" "")
7783 (call (match_operand 1 "memory_operand" "")
7784 (match_operand 2 "general_operand" "")))
7786 (use (match_operand 3 "" ""))])]
7792 if ((!REG_P (XEXP (operands[1], 0))
7793 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7794 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7795 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7796 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7798 if (operands[3] == NULL_RTX)
7799 operands[3] = const0_rtx;
7801 pat = gen_sibcall_value_internal (operands[0], operands[1],
7802 operands[2], operands[3]);
7803 arm_emit_call_insn (pat, operands[1], true);
7808 (define_insn "*sibcall_insn"
7809 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7810 (match_operand 1 "" ""))
7812 (use (match_operand 2 "" ""))]
7813 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7815 if (which_alternative == 1)
7816 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7819 if (arm_arch5 || arm_arch4t)
7820 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7822 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7825 [(set_attr "type" "call")]
7828 (define_insn "*sibcall_value_insn"
7829 [(set (match_operand 0 "" "")
7830 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7831 (match_operand 2 "" "")))
7833 (use (match_operand 3 "" ""))]
7834 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7836 if (which_alternative == 1)
7837 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7840 if (arm_arch5 || arm_arch4t)
7841 return \"bx%?\\t%1\";
7843 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7846 [(set_attr "type" "call")]
7849 (define_expand "<return_str>return"
7851 "(TARGET_ARM || (TARGET_THUMB2
7852 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7853 && !IS_STACKALIGN (arm_current_func_type ())))
7854 <return_cond_false>"
7859 thumb2_expand_return (<return_simple_p>);
7866 ;; Often the return insn will be the same as loading from memory, so set attr
7867 (define_insn "*arm_return"
7869 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7872 if (arm_ccfsm_state == 2)
7874 arm_ccfsm_state += 2;
7877 return output_return_instruction (const_true_rtx, true, false, false);
7879 [(set_attr "type" "load1")
7880 (set_attr "length" "12")
7881 (set_attr "predicable" "yes")]
7884 (define_insn "*cond_<return_str>return"
7886 (if_then_else (match_operator 0 "arm_comparison_operator"
7887 [(match_operand 1 "cc_register" "") (const_int 0)])
7890 "TARGET_ARM <return_cond_true>"
7893 if (arm_ccfsm_state == 2)
7895 arm_ccfsm_state += 2;
7898 return output_return_instruction (operands[0], true, false,
7901 [(set_attr "conds" "use")
7902 (set_attr "length" "12")
7903 (set_attr "type" "load1")]
7906 (define_insn "*cond_<return_str>return_inverted"
7908 (if_then_else (match_operator 0 "arm_comparison_operator"
7909 [(match_operand 1 "cc_register" "") (const_int 0)])
7912 "TARGET_ARM <return_cond_true>"
7915 if (arm_ccfsm_state == 2)
7917 arm_ccfsm_state += 2;
7920 return output_return_instruction (operands[0], true, true,
7923 [(set_attr "conds" "use")
7924 (set_attr "length" "12")
7925 (set_attr "type" "load1")]
7928 (define_insn "*arm_simple_return"
7933 if (arm_ccfsm_state == 2)
7935 arm_ccfsm_state += 2;
7938 return output_return_instruction (const_true_rtx, true, false, true);
7940 [(set_attr "type" "branch")
7941 (set_attr "length" "4")
7942 (set_attr "predicable" "yes")]
7945 ;; Generate a sequence of instructions to determine if the processor is
7946 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7949 (define_expand "return_addr_mask"
7951 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7953 (set (match_operand:SI 0 "s_register_operand" "")
7954 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7956 (const_int 67108860)))] ; 0x03fffffc
7959 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7962 (define_insn "*check_arch2"
7963 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7964 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7967 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7968 [(set_attr "length" "8")
7969 (set_attr "conds" "set")
7970 (set_attr "type" "multiple")]
7973 ;; Call subroutine returning any type.
7975 (define_expand "untyped_call"
7976 [(parallel [(call (match_operand 0 "" "")
7978 (match_operand 1 "" "")
7979 (match_operand 2 "" "")])]
7984 rtx par = gen_rtx_PARALLEL (VOIDmode,
7985 rtvec_alloc (XVECLEN (operands[2], 0)));
7986 rtx addr = gen_reg_rtx (Pmode);
7990 emit_move_insn (addr, XEXP (operands[1], 0));
7991 mem = change_address (operands[1], BLKmode, addr);
7993 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7995 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
7997 /* Default code only uses r0 as a return value, but we could
7998 be using anything up to 4 registers. */
7999 if (REGNO (src) == R0_REGNUM)
8000 src = gen_rtx_REG (TImode, R0_REGNUM);
8002 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8004 size += GET_MODE_SIZE (GET_MODE (src));
8007 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
8012 for (i = 0; i < XVECLEN (par, 0); i++)
8014 HOST_WIDE_INT offset = 0;
8015 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8018 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8020 mem = change_address (mem, GET_MODE (reg), NULL);
8021 if (REGNO (reg) == R0_REGNUM)
8023 /* On thumb we have to use a write-back instruction. */
8024 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8025 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8026 size = TARGET_ARM ? 16 : 0;
8030 emit_move_insn (mem, reg);
8031 size = GET_MODE_SIZE (GET_MODE (reg));
8035 /* The optimizer does not know that the call sets the function value
8036 registers we stored in the result block. We avoid problems by
8037 claiming that all hard registers are used and clobbered at this
8039 emit_insn (gen_blockage ());
8045 (define_expand "untyped_return"
8046 [(match_operand:BLK 0 "memory_operand" "")
8047 (match_operand 1 "" "")]
8052 rtx addr = gen_reg_rtx (Pmode);
8056 emit_move_insn (addr, XEXP (operands[0], 0));
8057 mem = change_address (operands[0], BLKmode, addr);
8059 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8061 HOST_WIDE_INT offset = 0;
8062 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8065 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8067 mem = change_address (mem, GET_MODE (reg), NULL);
8068 if (REGNO (reg) == R0_REGNUM)
8070 /* On thumb we have to use a write-back instruction. */
8071 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8072 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8073 size = TARGET_ARM ? 16 : 0;
8077 emit_move_insn (reg, mem);
8078 size = GET_MODE_SIZE (GET_MODE (reg));
8082 /* Emit USE insns before the return. */
8083 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8084 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8086 /* Construct the return. */
8087 expand_naked_return ();
8093 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8094 ;; all of memory. This blocks insns from being moved across this point.
8096 (define_insn "blockage"
8097 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8100 [(set_attr "length" "0")
8101 (set_attr "type" "block")]
8104 (define_expand "casesi"
8105 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8106 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8107 (match_operand:SI 2 "const_int_operand" "") ; total range
8108 (match_operand:SI 3 "" "") ; table label
8109 (match_operand:SI 4 "" "")] ; Out of range label
8110 "TARGET_32BIT || optimize_size || flag_pic"
8113 enum insn_code code;
8114 if (operands[1] != const0_rtx)
8116 rtx reg = gen_reg_rtx (SImode);
8118 emit_insn (gen_addsi3 (reg, operands[0],
8119 gen_int_mode (-INTVAL (operands[1]),
8125 code = CODE_FOR_arm_casesi_internal;
8126 else if (TARGET_THUMB1)
8127 code = CODE_FOR_thumb1_casesi_internal_pic;
8129 code = CODE_FOR_thumb2_casesi_internal_pic;
8131 code = CODE_FOR_thumb2_casesi_internal;
8133 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8134 operands[2] = force_reg (SImode, operands[2]);
8136 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8137 operands[3], operands[4]));
8142 ;; The USE in this pattern is needed to tell flow analysis that this is
8143 ;; a CASESI insn. It has no other purpose.
8144 (define_insn "arm_casesi_internal"
8145 [(parallel [(set (pc)
8147 (leu (match_operand:SI 0 "s_register_operand" "r")
8148 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8149 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8150 (label_ref (match_operand 2 "" ""))))
8151 (label_ref (match_operand 3 "" ""))))
8152 (clobber (reg:CC CC_REGNUM))
8153 (use (label_ref (match_dup 2)))])]
8157 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8158 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8160 [(set_attr "conds" "clob")
8161 (set_attr "length" "12")
8162 (set_attr "type" "multiple")]
8165 (define_expand "indirect_jump"
8167 (match_operand:SI 0 "s_register_operand" ""))]
8170 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8171 address and use bx. */
8175 tmp = gen_reg_rtx (SImode);
8176 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8182 ;; NB Never uses BX.
8183 (define_insn "*arm_indirect_jump"
8185 (match_operand:SI 0 "s_register_operand" "r"))]
8187 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8188 [(set_attr "predicable" "yes")
8189 (set_attr "type" "branch")]
8192 (define_insn "*load_indirect_jump"
8194 (match_operand:SI 0 "memory_operand" "m"))]
8196 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8197 [(set_attr "type" "load1")
8198 (set_attr "pool_range" "4096")
8199 (set_attr "neg_pool_range" "4084")
8200 (set_attr "predicable" "yes")]
8210 if (TARGET_UNIFIED_ASM)
8213 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8214 return \"mov\\tr8, r8\";
8216 [(set (attr "length")
8217 (if_then_else (eq_attr "is_thumb" "yes")
8220 (set_attr "type" "mov_reg")]
8224 [(trap_if (const_int 1) (const_int 0))]
8228 return \".inst\\t0xe7f000f0\";
8230 return \".inst\\t0xdeff\";
8232 [(set (attr "length")
8233 (if_then_else (eq_attr "is_thumb" "yes")
8236 (set_attr "type" "trap")
8237 (set_attr "conds" "unconditional")]
8241 ;; Patterns to allow combination of arithmetic, cond code and shifts
8243 (define_insn "*<arith_shift_insn>_multsi"
8244 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8246 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8247 (match_operand:SI 3 "power_of_two_operand" ""))
8248 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8250 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8251 [(set_attr "predicable" "yes")
8252 (set_attr "predicable_short_it" "no")
8253 (set_attr "shift" "4")
8254 (set_attr "arch" "a,t2")
8255 (set_attr "type" "alu_shift_imm")])
8257 (define_insn "*<arith_shift_insn>_shiftsi"
8258 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8260 (match_operator:SI 2 "shift_nomul_operator"
8261 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8262 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8263 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8264 "TARGET_32BIT && GET_CODE (operands[3]) != MULT"
8265 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8266 [(set_attr "predicable" "yes")
8267 (set_attr "predicable_short_it" "no")
8268 (set_attr "shift" "4")
8269 (set_attr "arch" "a,t2,a")
8270 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8273 [(set (match_operand:SI 0 "s_register_operand" "")
8274 (match_operator:SI 1 "shiftable_operator"
8275 [(match_operator:SI 2 "shiftable_operator"
8276 [(match_operator:SI 3 "shift_operator"
8277 [(match_operand:SI 4 "s_register_operand" "")
8278 (match_operand:SI 5 "reg_or_int_operand" "")])
8279 (match_operand:SI 6 "s_register_operand" "")])
8280 (match_operand:SI 7 "arm_rhs_operand" "")]))
8281 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8284 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8287 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8290 (define_insn "*arith_shiftsi_compare0"
8291 [(set (reg:CC_NOOV CC_REGNUM)
8293 (match_operator:SI 1 "shiftable_operator"
8294 [(match_operator:SI 3 "shift_operator"
8295 [(match_operand:SI 4 "s_register_operand" "r,r")
8296 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8297 (match_operand:SI 2 "s_register_operand" "r,r")])
8299 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8300 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8303 "%i1%.\\t%0, %2, %4%S3"
8304 [(set_attr "conds" "set")
8305 (set_attr "shift" "4")
8306 (set_attr "arch" "32,a")
8307 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8309 (define_insn "*arith_shiftsi_compare0_scratch"
8310 [(set (reg:CC_NOOV CC_REGNUM)
8312 (match_operator:SI 1 "shiftable_operator"
8313 [(match_operator:SI 3 "shift_operator"
8314 [(match_operand:SI 4 "s_register_operand" "r,r")
8315 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8316 (match_operand:SI 2 "s_register_operand" "r,r")])
8318 (clobber (match_scratch:SI 0 "=r,r"))]
8320 "%i1%.\\t%0, %2, %4%S3"
8321 [(set_attr "conds" "set")
8322 (set_attr "shift" "4")
8323 (set_attr "arch" "32,a")
8324 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8326 (define_insn "*sub_shiftsi"
8327 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8328 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8329 (match_operator:SI 2 "shift_operator"
8330 [(match_operand:SI 3 "s_register_operand" "r,r")
8331 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8333 "sub%?\\t%0, %1, %3%S2"
8334 [(set_attr "predicable" "yes")
8335 (set_attr "shift" "3")
8336 (set_attr "arch" "32,a")
8337 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8339 (define_insn "*sub_shiftsi_compare0"
8340 [(set (reg:CC_NOOV CC_REGNUM)
8342 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8343 (match_operator:SI 2 "shift_operator"
8344 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8345 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8347 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8348 (minus:SI (match_dup 1)
8349 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8351 "sub%.\\t%0, %1, %3%S2"
8352 [(set_attr "conds" "set")
8353 (set_attr "shift" "3")
8354 (set_attr "arch" "32,a,a")
8355 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8357 (define_insn "*sub_shiftsi_compare0_scratch"
8358 [(set (reg:CC_NOOV CC_REGNUM)
8360 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8361 (match_operator:SI 2 "shift_operator"
8362 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8363 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8365 (clobber (match_scratch:SI 0 "=r,r,r"))]
8367 "sub%.\\t%0, %1, %3%S2"
8368 [(set_attr "conds" "set")
8369 (set_attr "shift" "3")
8370 (set_attr "arch" "32,a,a")
8371 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8374 (define_insn_and_split "*and_scc"
8375 [(set (match_operand:SI 0 "s_register_operand" "=r")
8376 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8377 [(match_operand 2 "cc_register" "") (const_int 0)])
8378 (match_operand:SI 3 "s_register_operand" "r")))]
8380 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8381 "&& reload_completed"
8382 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8383 (cond_exec (match_dup 4) (set (match_dup 0)
8384 (and:SI (match_dup 3) (const_int 1))))]
8386 machine_mode mode = GET_MODE (operands[2]);
8387 enum rtx_code rc = GET_CODE (operands[1]);
8389 /* Note that operands[4] is the same as operands[1],
8390 but with VOIDmode as the result. */
8391 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8392 if (mode == CCFPmode || mode == CCFPEmode)
8393 rc = reverse_condition_maybe_unordered (rc);
8395 rc = reverse_condition (rc);
8396 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8398 [(set_attr "conds" "use")
8399 (set_attr "type" "multiple")
8400 (set_attr "length" "8")]
8403 (define_insn_and_split "*ior_scc"
8404 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8405 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8406 [(match_operand 2 "cc_register" "") (const_int 0)])
8407 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8412 "&& reload_completed
8413 && REGNO (operands [0]) != REGNO (operands[3])"
8414 ;; && which_alternative == 1
8415 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8416 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8417 (cond_exec (match_dup 4) (set (match_dup 0)
8418 (ior:SI (match_dup 3) (const_int 1))))]
8420 machine_mode mode = GET_MODE (operands[2]);
8421 enum rtx_code rc = GET_CODE (operands[1]);
8423 /* Note that operands[4] is the same as operands[1],
8424 but with VOIDmode as the result. */
8425 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8426 if (mode == CCFPmode || mode == CCFPEmode)
8427 rc = reverse_condition_maybe_unordered (rc);
8429 rc = reverse_condition (rc);
8430 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8432 [(set_attr "conds" "use")
8433 (set_attr "length" "4,8")
8434 (set_attr "type" "logic_imm,multiple")]
8437 ; A series of splitters for the compare_scc pattern below. Note that
8438 ; order is important.
8440 [(set (match_operand:SI 0 "s_register_operand" "")
8441 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8443 (clobber (reg:CC CC_REGNUM))]
8444 "TARGET_32BIT && reload_completed"
8445 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8448 [(set (match_operand:SI 0 "s_register_operand" "")
8449 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8451 (clobber (reg:CC CC_REGNUM))]
8452 "TARGET_32BIT && reload_completed"
8453 [(set (match_dup 0) (not:SI (match_dup 1)))
8454 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8457 [(set (match_operand:SI 0 "s_register_operand" "")
8458 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8460 (clobber (reg:CC CC_REGNUM))]
8461 "arm_arch5 && TARGET_32BIT"
8462 [(set (match_dup 0) (clz:SI (match_dup 1)))
8463 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8467 [(set (match_operand:SI 0 "s_register_operand" "")
8468 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8470 (clobber (reg:CC CC_REGNUM))]
8471 "TARGET_32BIT && reload_completed"
8473 [(set (reg:CC CC_REGNUM)
8474 (compare:CC (const_int 1) (match_dup 1)))
8476 (minus:SI (const_int 1) (match_dup 1)))])
8477 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8478 (set (match_dup 0) (const_int 0)))])
8481 [(set (match_operand:SI 0 "s_register_operand" "")
8482 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8483 (match_operand:SI 2 "const_int_operand" "")))
8484 (clobber (reg:CC CC_REGNUM))]
8485 "TARGET_32BIT && reload_completed"
8487 [(set (reg:CC CC_REGNUM)
8488 (compare:CC (match_dup 1) (match_dup 2)))
8489 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8490 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8491 (set (match_dup 0) (const_int 1)))]
8493 operands[3] = GEN_INT (-INTVAL (operands[2]));
8497 [(set (match_operand:SI 0 "s_register_operand" "")
8498 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8499 (match_operand:SI 2 "arm_add_operand" "")))
8500 (clobber (reg:CC CC_REGNUM))]
8501 "TARGET_32BIT && reload_completed"
8503 [(set (reg:CC_NOOV CC_REGNUM)
8504 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8506 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8507 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8508 (set (match_dup 0) (const_int 1)))])
8510 (define_insn_and_split "*compare_scc"
8511 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8512 (match_operator:SI 1 "arm_comparison_operator"
8513 [(match_operand:SI 2 "s_register_operand" "r,r")
8514 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8515 (clobber (reg:CC CC_REGNUM))]
8518 "&& reload_completed"
8519 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8520 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8521 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8524 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8525 operands[2], operands[3]);
8526 enum rtx_code rc = GET_CODE (operands[1]);
8528 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8530 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8531 if (mode == CCFPmode || mode == CCFPEmode)
8532 rc = reverse_condition_maybe_unordered (rc);
8534 rc = reverse_condition (rc);
8535 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8537 [(set_attr "type" "multiple")]
8540 ;; Attempt to improve the sequence generated by the compare_scc splitters
8541 ;; not to use conditional execution.
8543 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
8547 [(set (reg:CC CC_REGNUM)
8548 (compare:CC (match_operand:SI 1 "register_operand" "")
8550 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8551 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8552 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8553 (set (match_dup 0) (const_int 1)))]
8554 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8555 [(set (match_dup 0) (clz:SI (match_dup 1)))
8556 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8559 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8563 [(set (reg:CC CC_REGNUM)
8564 (compare:CC (match_operand:SI 1 "register_operand" "")
8566 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8567 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8568 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8569 (set (match_dup 0) (const_int 1)))
8570 (match_scratch:SI 2 "r")]
8571 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8573 [(set (reg:CC CC_REGNUM)
8574 (compare:CC (const_int 0) (match_dup 1)))
8575 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8577 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8578 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8581 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
8582 ;; sub Rd, Reg1, reg2
8586 [(set (reg:CC CC_REGNUM)
8587 (compare:CC (match_operand:SI 1 "register_operand" "")
8588 (match_operand:SI 2 "arm_rhs_operand" "")))
8589 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8590 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8591 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8592 (set (match_dup 0) (const_int 1)))]
8593 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8594 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8595 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8596 (set (match_dup 0) (clz:SI (match_dup 0)))
8597 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8601 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
8602 ;; sub T1, Reg1, reg2
8606 [(set (reg:CC CC_REGNUM)
8607 (compare:CC (match_operand:SI 1 "register_operand" "")
8608 (match_operand:SI 2 "arm_rhs_operand" "")))
8609 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8610 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8611 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8612 (set (match_dup 0) (const_int 1)))
8613 (match_scratch:SI 3 "r")]
8614 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8615 [(set (match_dup 3) (match_dup 4))
8617 [(set (reg:CC CC_REGNUM)
8618 (compare:CC (const_int 0) (match_dup 3)))
8619 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8621 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8622 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8624 if (CONST_INT_P (operands[2]))
8625 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8627 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8630 (define_insn "*cond_move"
8631 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8632 (if_then_else:SI (match_operator 3 "equality_operator"
8633 [(match_operator 4 "arm_comparison_operator"
8634 [(match_operand 5 "cc_register" "") (const_int 0)])
8636 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8637 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8640 if (GET_CODE (operands[3]) == NE)
8642 if (which_alternative != 1)
8643 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8644 if (which_alternative != 0)
8645 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8648 if (which_alternative != 0)
8649 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8650 if (which_alternative != 1)
8651 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8654 [(set_attr "conds" "use")
8655 (set_attr "type" "mov_reg,mov_reg,multiple")
8656 (set_attr "length" "4,4,8")]
8659 (define_insn "*cond_arith"
8660 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8661 (match_operator:SI 5 "shiftable_operator"
8662 [(match_operator:SI 4 "arm_comparison_operator"
8663 [(match_operand:SI 2 "s_register_operand" "r,r")
8664 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8665 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8666 (clobber (reg:CC CC_REGNUM))]
8669 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8670 return \"%i5\\t%0, %1, %2, lsr #31\";
8672 output_asm_insn (\"cmp\\t%2, %3\", operands);
8673 if (GET_CODE (operands[5]) == AND)
8674 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8675 else if (GET_CODE (operands[5]) == MINUS)
8676 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8677 else if (which_alternative != 0)
8678 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8679 return \"%i5%d4\\t%0, %1, #1\";
8681 [(set_attr "conds" "clob")
8682 (set_attr "length" "12")
8683 (set_attr "type" "multiple")]
8686 (define_insn "*cond_sub"
8687 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8688 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8689 (match_operator:SI 4 "arm_comparison_operator"
8690 [(match_operand:SI 2 "s_register_operand" "r,r")
8691 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8692 (clobber (reg:CC CC_REGNUM))]
8695 output_asm_insn (\"cmp\\t%2, %3\", operands);
8696 if (which_alternative != 0)
8697 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8698 return \"sub%d4\\t%0, %1, #1\";
8700 [(set_attr "conds" "clob")
8701 (set_attr "length" "8,12")
8702 (set_attr "type" "multiple")]
8705 (define_insn "*cmp_ite0"
8706 [(set (match_operand 6 "dominant_cc_register" "")
8709 (match_operator 4 "arm_comparison_operator"
8710 [(match_operand:SI 0 "s_register_operand"
8711 "l,l,l,r,r,r,r,r,r")
8712 (match_operand:SI 1 "arm_add_operand"
8713 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8714 (match_operator:SI 5 "arm_comparison_operator"
8715 [(match_operand:SI 2 "s_register_operand"
8716 "l,r,r,l,l,r,r,r,r")
8717 (match_operand:SI 3 "arm_add_operand"
8718 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8724 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8726 {\"cmp%d5\\t%0, %1\",
8727 \"cmp%d4\\t%2, %3\"},
8728 {\"cmn%d5\\t%0, #%n1\",
8729 \"cmp%d4\\t%2, %3\"},
8730 {\"cmp%d5\\t%0, %1\",
8731 \"cmn%d4\\t%2, #%n3\"},
8732 {\"cmn%d5\\t%0, #%n1\",
8733 \"cmn%d4\\t%2, #%n3\"}
8735 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8740 \"cmn\\t%0, #%n1\"},
8741 {\"cmn\\t%2, #%n3\",
8743 {\"cmn\\t%2, #%n3\",
8746 static const char * const ite[2] =
8751 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8752 CMP_CMP, CMN_CMP, CMP_CMP,
8753 CMN_CMP, CMP_CMN, CMN_CMN};
8755 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8757 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8758 if (TARGET_THUMB2) {
8759 output_asm_insn (ite[swap], operands);
8761 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8764 [(set_attr "conds" "set")
8765 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8766 (set_attr "type" "multiple")
8767 (set_attr_alternative "length"
8773 (if_then_else (eq_attr "is_thumb" "no")
8776 (if_then_else (eq_attr "is_thumb" "no")
8779 (if_then_else (eq_attr "is_thumb" "no")
8782 (if_then_else (eq_attr "is_thumb" "no")
8787 (define_insn "*cmp_ite1"
8788 [(set (match_operand 6 "dominant_cc_register" "")
8791 (match_operator 4 "arm_comparison_operator"
8792 [(match_operand:SI 0 "s_register_operand"
8793 "l,l,l,r,r,r,r,r,r")
8794 (match_operand:SI 1 "arm_add_operand"
8795 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8796 (match_operator:SI 5 "arm_comparison_operator"
8797 [(match_operand:SI 2 "s_register_operand"
8798 "l,r,r,l,l,r,r,r,r")
8799 (match_operand:SI 3 "arm_add_operand"
8800 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8806 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8810 {\"cmn\\t%0, #%n1\",
8813 \"cmn\\t%2, #%n3\"},
8814 {\"cmn\\t%0, #%n1\",
8817 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8819 {\"cmp%d4\\t%2, %3\",
8820 \"cmp%D5\\t%0, %1\"},
8821 {\"cmp%d4\\t%2, %3\",
8822 \"cmn%D5\\t%0, #%n1\"},
8823 {\"cmn%d4\\t%2, #%n3\",
8824 \"cmp%D5\\t%0, %1\"},
8825 {\"cmn%d4\\t%2, #%n3\",
8826 \"cmn%D5\\t%0, #%n1\"}
8828 static const char * const ite[2] =
8833 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8834 CMP_CMP, CMN_CMP, CMP_CMP,
8835 CMN_CMP, CMP_CMN, CMN_CMN};
8837 comparison_dominates_p (GET_CODE (operands[5]),
8838 reverse_condition (GET_CODE (operands[4])));
8840 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8841 if (TARGET_THUMB2) {
8842 output_asm_insn (ite[swap], operands);
8844 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8847 [(set_attr "conds" "set")
8848 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8849 (set_attr_alternative "length"
8855 (if_then_else (eq_attr "is_thumb" "no")
8858 (if_then_else (eq_attr "is_thumb" "no")
8861 (if_then_else (eq_attr "is_thumb" "no")
8864 (if_then_else (eq_attr "is_thumb" "no")
8867 (set_attr "type" "multiple")]
8870 (define_insn "*cmp_and"
8871 [(set (match_operand 6 "dominant_cc_register" "")
8874 (match_operator 4 "arm_comparison_operator"
8875 [(match_operand:SI 0 "s_register_operand"
8876 "l,l,l,r,r,r,r,r,r")
8877 (match_operand:SI 1 "arm_add_operand"
8878 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8879 (match_operator:SI 5 "arm_comparison_operator"
8880 [(match_operand:SI 2 "s_register_operand"
8881 "l,r,r,l,l,r,r,r,r")
8882 (match_operand:SI 3 "arm_add_operand"
8883 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8888 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8890 {\"cmp%d5\\t%0, %1\",
8891 \"cmp%d4\\t%2, %3\"},
8892 {\"cmn%d5\\t%0, #%n1\",
8893 \"cmp%d4\\t%2, %3\"},
8894 {\"cmp%d5\\t%0, %1\",
8895 \"cmn%d4\\t%2, #%n3\"},
8896 {\"cmn%d5\\t%0, #%n1\",
8897 \"cmn%d4\\t%2, #%n3\"}
8899 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8904 \"cmn\\t%0, #%n1\"},
8905 {\"cmn\\t%2, #%n3\",
8907 {\"cmn\\t%2, #%n3\",
8910 static const char *const ite[2] =
8915 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8916 CMP_CMP, CMN_CMP, CMP_CMP,
8917 CMN_CMP, CMP_CMN, CMN_CMN};
8919 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8921 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8922 if (TARGET_THUMB2) {
8923 output_asm_insn (ite[swap], operands);
8925 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8928 [(set_attr "conds" "set")
8929 (set_attr "predicable" "no")
8930 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8931 (set_attr_alternative "length"
8937 (if_then_else (eq_attr "is_thumb" "no")
8940 (if_then_else (eq_attr "is_thumb" "no")
8943 (if_then_else (eq_attr "is_thumb" "no")
8946 (if_then_else (eq_attr "is_thumb" "no")
8949 (set_attr "type" "multiple")]
8952 (define_insn "*cmp_ior"
8953 [(set (match_operand 6 "dominant_cc_register" "")
8956 (match_operator 4 "arm_comparison_operator"
8957 [(match_operand:SI 0 "s_register_operand"
8958 "l,l,l,r,r,r,r,r,r")
8959 (match_operand:SI 1 "arm_add_operand"
8960 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8961 (match_operator:SI 5 "arm_comparison_operator"
8962 [(match_operand:SI 2 "s_register_operand"
8963 "l,r,r,l,l,r,r,r,r")
8964 (match_operand:SI 3 "arm_add_operand"
8965 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8970 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8974 {\"cmn\\t%0, #%n1\",
8977 \"cmn\\t%2, #%n3\"},
8978 {\"cmn\\t%0, #%n1\",
8981 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8983 {\"cmp%D4\\t%2, %3\",
8984 \"cmp%D5\\t%0, %1\"},
8985 {\"cmp%D4\\t%2, %3\",
8986 \"cmn%D5\\t%0, #%n1\"},
8987 {\"cmn%D4\\t%2, #%n3\",
8988 \"cmp%D5\\t%0, %1\"},
8989 {\"cmn%D4\\t%2, #%n3\",
8990 \"cmn%D5\\t%0, #%n1\"}
8992 static const char *const ite[2] =
8997 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8998 CMP_CMP, CMN_CMP, CMP_CMP,
8999 CMN_CMP, CMP_CMN, CMN_CMN};
9001 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9003 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9004 if (TARGET_THUMB2) {
9005 output_asm_insn (ite[swap], operands);
9007 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9011 [(set_attr "conds" "set")
9012 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9013 (set_attr_alternative "length"
9019 (if_then_else (eq_attr "is_thumb" "no")
9022 (if_then_else (eq_attr "is_thumb" "no")
9025 (if_then_else (eq_attr "is_thumb" "no")
9028 (if_then_else (eq_attr "is_thumb" "no")
9031 (set_attr "type" "multiple")]
9034 (define_insn_and_split "*ior_scc_scc"
9035 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9036 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9037 [(match_operand:SI 1 "s_register_operand" "r")
9038 (match_operand:SI 2 "arm_add_operand" "rIL")])
9039 (match_operator:SI 6 "arm_comparison_operator"
9040 [(match_operand:SI 4 "s_register_operand" "r")
9041 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9042 (clobber (reg:CC CC_REGNUM))]
9044 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9047 "TARGET_32BIT && reload_completed"
9051 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9052 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9054 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9056 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9059 [(set_attr "conds" "clob")
9060 (set_attr "length" "16")
9061 (set_attr "type" "multiple")]
9064 ; If the above pattern is followed by a CMP insn, then the compare is
9065 ; redundant, since we can rework the conditional instruction that follows.
9066 (define_insn_and_split "*ior_scc_scc_cmp"
9067 [(set (match_operand 0 "dominant_cc_register" "")
9068 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9069 [(match_operand:SI 1 "s_register_operand" "r")
9070 (match_operand:SI 2 "arm_add_operand" "rIL")])
9071 (match_operator:SI 6 "arm_comparison_operator"
9072 [(match_operand:SI 4 "s_register_operand" "r")
9073 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9075 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9076 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9077 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9080 "TARGET_32BIT && reload_completed"
9084 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9085 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9087 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9089 [(set_attr "conds" "set")
9090 (set_attr "length" "16")
9091 (set_attr "type" "multiple")]
9094 (define_insn_and_split "*and_scc_scc"
9095 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9096 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9097 [(match_operand:SI 1 "s_register_operand" "r")
9098 (match_operand:SI 2 "arm_add_operand" "rIL")])
9099 (match_operator:SI 6 "arm_comparison_operator"
9100 [(match_operand:SI 4 "s_register_operand" "r")
9101 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9102 (clobber (reg:CC CC_REGNUM))]
9104 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9107 "TARGET_32BIT && reload_completed
9108 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9113 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9114 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9116 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9118 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9121 [(set_attr "conds" "clob")
9122 (set_attr "length" "16")
9123 (set_attr "type" "multiple")]
9126 ; If the above pattern is followed by a CMP insn, then the compare is
9127 ; redundant, since we can rework the conditional instruction that follows.
9128 (define_insn_and_split "*and_scc_scc_cmp"
9129 [(set (match_operand 0 "dominant_cc_register" "")
9130 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9131 [(match_operand:SI 1 "s_register_operand" "r")
9132 (match_operand:SI 2 "arm_add_operand" "rIL")])
9133 (match_operator:SI 6 "arm_comparison_operator"
9134 [(match_operand:SI 4 "s_register_operand" "r")
9135 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9137 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9138 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9139 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9142 "TARGET_32BIT && reload_completed"
9146 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9147 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9149 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9151 [(set_attr "conds" "set")
9152 (set_attr "length" "16")
9153 (set_attr "type" "multiple")]
9156 ;; If there is no dominance in the comparison, then we can still save an
9157 ;; instruction in the AND case, since we can know that the second compare
9158 ;; need only zero the value if false (if true, then the value is already
9160 (define_insn_and_split "*and_scc_scc_nodom"
9161 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9162 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9163 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9164 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9165 (match_operator:SI 6 "arm_comparison_operator"
9166 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9167 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9168 (clobber (reg:CC CC_REGNUM))]
9170 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9173 "TARGET_32BIT && reload_completed"
9174 [(parallel [(set (match_dup 0)
9175 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9176 (clobber (reg:CC CC_REGNUM))])
9177 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9179 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9182 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9183 operands[4], operands[5]),
9185 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9187 [(set_attr "conds" "clob")
9188 (set_attr "length" "20")
9189 (set_attr "type" "multiple")]
9193 [(set (reg:CC_NOOV CC_REGNUM)
9194 (compare:CC_NOOV (ior:SI
9195 (and:SI (match_operand:SI 0 "s_register_operand" "")
9197 (match_operator:SI 1 "arm_comparison_operator"
9198 [(match_operand:SI 2 "s_register_operand" "")
9199 (match_operand:SI 3 "arm_add_operand" "")]))
9201 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9204 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9206 (set (reg:CC_NOOV CC_REGNUM)
9207 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9212 [(set (reg:CC_NOOV CC_REGNUM)
9213 (compare:CC_NOOV (ior:SI
9214 (match_operator:SI 1 "arm_comparison_operator"
9215 [(match_operand:SI 2 "s_register_operand" "")
9216 (match_operand:SI 3 "arm_add_operand" "")])
9217 (and:SI (match_operand:SI 0 "s_register_operand" "")
9220 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9223 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9225 (set (reg:CC_NOOV CC_REGNUM)
9226 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9229 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9231 (define_insn_and_split "*negscc"
9232 [(set (match_operand:SI 0 "s_register_operand" "=r")
9233 (neg:SI (match_operator 3 "arm_comparison_operator"
9234 [(match_operand:SI 1 "s_register_operand" "r")
9235 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9236 (clobber (reg:CC CC_REGNUM))]
9239 "&& reload_completed"
9242 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9244 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9246 /* Emit mov\\t%0, %1, asr #31 */
9247 emit_insn (gen_rtx_SET (VOIDmode,
9249 gen_rtx_ASHIFTRT (SImode,
9254 else if (GET_CODE (operands[3]) == NE)
9256 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9257 if (CONST_INT_P (operands[2]))
9258 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9259 GEN_INT (- INTVAL (operands[2]))));
9261 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9263 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9267 gen_rtx_SET (SImode,
9274 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9275 emit_insn (gen_rtx_SET (VOIDmode,
9277 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9278 enum rtx_code rc = GET_CODE (operands[3]);
9280 rc = reverse_condition (rc);
9281 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9286 gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
9287 rc = GET_CODE (operands[3]);
9288 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9293 gen_rtx_SET (VOIDmode,
9300 [(set_attr "conds" "clob")
9301 (set_attr "length" "12")
9302 (set_attr "type" "multiple")]
9305 (define_insn_and_split "movcond_addsi"
9306 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9308 (match_operator 5 "comparison_operator"
9309 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9310 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9312 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9313 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9314 (clobber (reg:CC CC_REGNUM))]
9317 "&& reload_completed"
9318 [(set (reg:CC_NOOV CC_REGNUM)
9320 (plus:SI (match_dup 3)
9323 (set (match_dup 0) (match_dup 1))
9324 (cond_exec (match_dup 6)
9325 (set (match_dup 0) (match_dup 2)))]
9328 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9329 operands[3], operands[4]);
9330 enum rtx_code rc = GET_CODE (operands[5]);
9331 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9332 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9333 if (REGNO (operands[2]) != REGNO (operands[0]))
9334 rc = reverse_condition (rc);
9337 rtx tmp = operands[1];
9338 operands[1] = operands[2];
9342 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9345 [(set_attr "conds" "clob")
9346 (set_attr "enabled_for_depr_it" "no,yes,yes")
9347 (set_attr "type" "multiple")]
9350 (define_insn "movcond"
9351 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9353 (match_operator 5 "arm_comparison_operator"
9354 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9355 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9356 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9357 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9358 (clobber (reg:CC CC_REGNUM))]
9361 if (GET_CODE (operands[5]) == LT
9362 && (operands[4] == const0_rtx))
9364 if (which_alternative != 1 && REG_P (operands[1]))
9366 if (operands[2] == const0_rtx)
9367 return \"and\\t%0, %1, %3, asr #31\";
9368 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9370 else if (which_alternative != 0 && REG_P (operands[2]))
9372 if (operands[1] == const0_rtx)
9373 return \"bic\\t%0, %2, %3, asr #31\";
9374 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9376 /* The only case that falls through to here is when both ops 1 & 2
9380 if (GET_CODE (operands[5]) == GE
9381 && (operands[4] == const0_rtx))
9383 if (which_alternative != 1 && REG_P (operands[1]))
9385 if (operands[2] == const0_rtx)
9386 return \"bic\\t%0, %1, %3, asr #31\";
9387 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9389 else if (which_alternative != 0 && REG_P (operands[2]))
9391 if (operands[1] == const0_rtx)
9392 return \"and\\t%0, %2, %3, asr #31\";
9393 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9395 /* The only case that falls through to here is when both ops 1 & 2
9398 if (CONST_INT_P (operands[4])
9399 && !const_ok_for_arm (INTVAL (operands[4])))
9400 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9402 output_asm_insn (\"cmp\\t%3, %4\", operands);
9403 if (which_alternative != 0)
9404 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9405 if (which_alternative != 1)
9406 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9409 [(set_attr "conds" "clob")
9410 (set_attr "length" "8,8,12")
9411 (set_attr "type" "multiple")]
9414 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9416 (define_insn "*ifcompare_plus_move"
9417 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9418 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9419 [(match_operand:SI 4 "s_register_operand" "r,r")
9420 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9422 (match_operand:SI 2 "s_register_operand" "r,r")
9423 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9424 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9425 (clobber (reg:CC CC_REGNUM))]
9428 [(set_attr "conds" "clob")
9429 (set_attr "length" "8,12")
9430 (set_attr "type" "multiple")]
9433 (define_insn "*if_plus_move"
9434 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9436 (match_operator 4 "arm_comparison_operator"
9437 [(match_operand 5 "cc_register" "") (const_int 0)])
9439 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9440 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9441 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9445 sub%d4\\t%0, %2, #%n3
9446 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9447 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9448 [(set_attr "conds" "use")
9449 (set_attr "length" "4,4,8,8")
9450 (set_attr_alternative "type"
9451 [(if_then_else (match_operand 3 "const_int_operand" "")
9452 (const_string "alu_imm" )
9453 (const_string "alu_sreg"))
9454 (const_string "alu_imm")
9455 (const_string "alu_sreg")
9456 (const_string "alu_sreg")])]
9459 (define_insn "*ifcompare_move_plus"
9460 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9461 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9462 [(match_operand:SI 4 "s_register_operand" "r,r")
9463 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9464 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9466 (match_operand:SI 2 "s_register_operand" "r,r")
9467 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9468 (clobber (reg:CC CC_REGNUM))]
9471 [(set_attr "conds" "clob")
9472 (set_attr "length" "8,12")
9473 (set_attr "type" "multiple")]
9476 (define_insn "*if_move_plus"
9477 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9479 (match_operator 4 "arm_comparison_operator"
9480 [(match_operand 5 "cc_register" "") (const_int 0)])
9481 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9483 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9484 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9488 sub%D4\\t%0, %2, #%n3
9489 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9490 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9491 [(set_attr "conds" "use")
9492 (set_attr "length" "4,4,8,8")
9493 (set_attr "type" "alu_sreg,alu_imm,multiple,multiple")]
9496 (define_insn "*ifcompare_arith_arith"
9497 [(set (match_operand:SI 0 "s_register_operand" "=r")
9498 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9499 [(match_operand:SI 5 "s_register_operand" "r")
9500 (match_operand:SI 6 "arm_add_operand" "rIL")])
9501 (match_operator:SI 8 "shiftable_operator"
9502 [(match_operand:SI 1 "s_register_operand" "r")
9503 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9504 (match_operator:SI 7 "shiftable_operator"
9505 [(match_operand:SI 3 "s_register_operand" "r")
9506 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9507 (clobber (reg:CC CC_REGNUM))]
9510 [(set_attr "conds" "clob")
9511 (set_attr "length" "12")
9512 (set_attr "type" "multiple")]
9515 (define_insn "*if_arith_arith"
9516 [(set (match_operand:SI 0 "s_register_operand" "=r")
9517 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9518 [(match_operand 8 "cc_register" "") (const_int 0)])
9519 (match_operator:SI 6 "shiftable_operator"
9520 [(match_operand:SI 1 "s_register_operand" "r")
9521 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9522 (match_operator:SI 7 "shiftable_operator"
9523 [(match_operand:SI 3 "s_register_operand" "r")
9524 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9526 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9527 [(set_attr "conds" "use")
9528 (set_attr "length" "8")
9529 (set_attr "type" "multiple")]
9532 (define_insn "*ifcompare_arith_move"
9533 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9534 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9535 [(match_operand:SI 2 "s_register_operand" "r,r")
9536 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9537 (match_operator:SI 7 "shiftable_operator"
9538 [(match_operand:SI 4 "s_register_operand" "r,r")
9539 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9540 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9541 (clobber (reg:CC CC_REGNUM))]
9544 /* If we have an operation where (op x 0) is the identity operation and
9545 the conditional operator is LT or GE and we are comparing against zero and
9546 everything is in registers then we can do this in two instructions. */
9547 if (operands[3] == const0_rtx
9548 && GET_CODE (operands[7]) != AND
9549 && REG_P (operands[5])
9550 && REG_P (operands[1])
9551 && REGNO (operands[1]) == REGNO (operands[4])
9552 && REGNO (operands[4]) != REGNO (operands[0]))
9554 if (GET_CODE (operands[6]) == LT)
9555 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9556 else if (GET_CODE (operands[6]) == GE)
9557 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9559 if (CONST_INT_P (operands[3])
9560 && !const_ok_for_arm (INTVAL (operands[3])))
9561 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9563 output_asm_insn (\"cmp\\t%2, %3\", operands);
9564 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9565 if (which_alternative != 0)
9566 return \"mov%D6\\t%0, %1\";
9569 [(set_attr "conds" "clob")
9570 (set_attr "length" "8,12")
9571 (set_attr "type" "multiple")]
9574 (define_insn "*if_arith_move"
9575 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9576 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9577 [(match_operand 6 "cc_register" "") (const_int 0)])
9578 (match_operator:SI 5 "shiftable_operator"
9579 [(match_operand:SI 2 "s_register_operand" "r,r")
9580 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9581 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9585 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9586 [(set_attr "conds" "use")
9587 (set_attr "length" "4,8")
9588 (set_attr "type" "alu_shift_reg,multiple")]
9591 (define_insn "*ifcompare_move_arith"
9592 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9593 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9594 [(match_operand:SI 4 "s_register_operand" "r,r")
9595 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9596 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9597 (match_operator:SI 7 "shiftable_operator"
9598 [(match_operand:SI 2 "s_register_operand" "r,r")
9599 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9600 (clobber (reg:CC CC_REGNUM))]
9603 /* If we have an operation where (op x 0) is the identity operation and
9604 the conditional operator is LT or GE and we are comparing against zero and
9605 everything is in registers then we can do this in two instructions */
9606 if (operands[5] == const0_rtx
9607 && GET_CODE (operands[7]) != AND
9608 && REG_P (operands[3])
9609 && REG_P (operands[1])
9610 && REGNO (operands[1]) == REGNO (operands[2])
9611 && REGNO (operands[2]) != REGNO (operands[0]))
9613 if (GET_CODE (operands[6]) == GE)
9614 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9615 else if (GET_CODE (operands[6]) == LT)
9616 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9619 if (CONST_INT_P (operands[5])
9620 && !const_ok_for_arm (INTVAL (operands[5])))
9621 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9623 output_asm_insn (\"cmp\\t%4, %5\", operands);
9625 if (which_alternative != 0)
9626 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9627 return \"%I7%D6\\t%0, %2, %3\";
9629 [(set_attr "conds" "clob")
9630 (set_attr "length" "8,12")
9631 (set_attr "type" "multiple")]
9634 (define_insn "*if_move_arith"
9635 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9637 (match_operator 4 "arm_comparison_operator"
9638 [(match_operand 6 "cc_register" "") (const_int 0)])
9639 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9640 (match_operator:SI 5 "shiftable_operator"
9641 [(match_operand:SI 2 "s_register_operand" "r,r")
9642 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9646 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9647 [(set_attr "conds" "use")
9648 (set_attr "length" "4,8")
9649 (set_attr "type" "alu_shift_reg,multiple")]
9652 (define_insn "*ifcompare_move_not"
9653 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9655 (match_operator 5 "arm_comparison_operator"
9656 [(match_operand:SI 3 "s_register_operand" "r,r")
9657 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9658 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9660 (match_operand:SI 2 "s_register_operand" "r,r"))))
9661 (clobber (reg:CC CC_REGNUM))]
9664 [(set_attr "conds" "clob")
9665 (set_attr "length" "8,12")
9666 (set_attr "type" "multiple")]
9669 (define_insn "*if_move_not"
9670 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9672 (match_operator 4 "arm_comparison_operator"
9673 [(match_operand 3 "cc_register" "") (const_int 0)])
9674 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9675 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9679 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9680 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9681 [(set_attr "conds" "use")
9682 (set_attr "type" "mvn_reg")
9683 (set_attr "length" "4,8,8")
9684 (set_attr "type" "mvn_reg,multiple,multiple")]
9687 (define_insn "*ifcompare_not_move"
9688 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9690 (match_operator 5 "arm_comparison_operator"
9691 [(match_operand:SI 3 "s_register_operand" "r,r")
9692 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9694 (match_operand:SI 2 "s_register_operand" "r,r"))
9695 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9696 (clobber (reg:CC CC_REGNUM))]
9699 [(set_attr "conds" "clob")
9700 (set_attr "length" "8,12")
9701 (set_attr "type" "multiple")]
9704 (define_insn "*if_not_move"
9705 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9707 (match_operator 4 "arm_comparison_operator"
9708 [(match_operand 3 "cc_register" "") (const_int 0)])
9709 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9710 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9714 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9715 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9716 [(set_attr "conds" "use")
9717 (set_attr "type" "mvn_reg,multiple,multiple")
9718 (set_attr "length" "4,8,8")]
9721 (define_insn "*ifcompare_shift_move"
9722 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9724 (match_operator 6 "arm_comparison_operator"
9725 [(match_operand:SI 4 "s_register_operand" "r,r")
9726 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9727 (match_operator:SI 7 "shift_operator"
9728 [(match_operand:SI 2 "s_register_operand" "r,r")
9729 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9730 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9731 (clobber (reg:CC CC_REGNUM))]
9734 [(set_attr "conds" "clob")
9735 (set_attr "length" "8,12")
9736 (set_attr "type" "multiple")]
9739 (define_insn "*if_shift_move"
9740 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9742 (match_operator 5 "arm_comparison_operator"
9743 [(match_operand 6 "cc_register" "") (const_int 0)])
9744 (match_operator:SI 4 "shift_operator"
9745 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9746 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9747 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9751 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9752 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9753 [(set_attr "conds" "use")
9754 (set_attr "shift" "2")
9755 (set_attr "length" "4,8,8")
9756 (set_attr "type" "mov_shift_reg,multiple,multiple")]
9759 (define_insn "*ifcompare_move_shift"
9760 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9762 (match_operator 6 "arm_comparison_operator"
9763 [(match_operand:SI 4 "s_register_operand" "r,r")
9764 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9765 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9766 (match_operator:SI 7 "shift_operator"
9767 [(match_operand:SI 2 "s_register_operand" "r,r")
9768 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9769 (clobber (reg:CC CC_REGNUM))]
9772 [(set_attr "conds" "clob")
9773 (set_attr "length" "8,12")
9774 (set_attr "type" "multiple")]
9777 (define_insn "*if_move_shift"
9778 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9780 (match_operator 5 "arm_comparison_operator"
9781 [(match_operand 6 "cc_register" "") (const_int 0)])
9782 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9783 (match_operator:SI 4 "shift_operator"
9784 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9785 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9789 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9790 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9791 [(set_attr "conds" "use")
9792 (set_attr "shift" "2")
9793 (set_attr "length" "4,8,8")
9794 (set_attr "type" "mov_shift_reg,multiple,multiple")]
9797 (define_insn "*ifcompare_shift_shift"
9798 [(set (match_operand:SI 0 "s_register_operand" "=r")
9800 (match_operator 7 "arm_comparison_operator"
9801 [(match_operand:SI 5 "s_register_operand" "r")
9802 (match_operand:SI 6 "arm_add_operand" "rIL")])
9803 (match_operator:SI 8 "shift_operator"
9804 [(match_operand:SI 1 "s_register_operand" "r")
9805 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9806 (match_operator:SI 9 "shift_operator"
9807 [(match_operand:SI 3 "s_register_operand" "r")
9808 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9809 (clobber (reg:CC CC_REGNUM))]
9812 [(set_attr "conds" "clob")
9813 (set_attr "length" "12")
9814 (set_attr "type" "multiple")]
9817 (define_insn "*if_shift_shift"
9818 [(set (match_operand:SI 0 "s_register_operand" "=r")
9820 (match_operator 5 "arm_comparison_operator"
9821 [(match_operand 8 "cc_register" "") (const_int 0)])
9822 (match_operator:SI 6 "shift_operator"
9823 [(match_operand:SI 1 "s_register_operand" "r")
9824 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9825 (match_operator:SI 7 "shift_operator"
9826 [(match_operand:SI 3 "s_register_operand" "r")
9827 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9829 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9830 [(set_attr "conds" "use")
9831 (set_attr "shift" "1")
9832 (set_attr "length" "8")
9833 (set (attr "type") (if_then_else
9834 (and (match_operand 2 "const_int_operand" "")
9835 (match_operand 4 "const_int_operand" ""))
9836 (const_string "mov_shift")
9837 (const_string "mov_shift_reg")))]
9840 (define_insn "*ifcompare_not_arith"
9841 [(set (match_operand:SI 0 "s_register_operand" "=r")
9843 (match_operator 6 "arm_comparison_operator"
9844 [(match_operand:SI 4 "s_register_operand" "r")
9845 (match_operand:SI 5 "arm_add_operand" "rIL")])
9846 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9847 (match_operator:SI 7 "shiftable_operator"
9848 [(match_operand:SI 2 "s_register_operand" "r")
9849 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9850 (clobber (reg:CC CC_REGNUM))]
9853 [(set_attr "conds" "clob")
9854 (set_attr "length" "12")
9855 (set_attr "type" "multiple")]
9858 (define_insn "*if_not_arith"
9859 [(set (match_operand:SI 0 "s_register_operand" "=r")
9861 (match_operator 5 "arm_comparison_operator"
9862 [(match_operand 4 "cc_register" "") (const_int 0)])
9863 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9864 (match_operator:SI 6 "shiftable_operator"
9865 [(match_operand:SI 2 "s_register_operand" "r")
9866 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9868 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9869 [(set_attr "conds" "use")
9870 (set_attr "type" "mvn_reg")
9871 (set_attr "length" "8")]
9874 (define_insn "*ifcompare_arith_not"
9875 [(set (match_operand:SI 0 "s_register_operand" "=r")
9877 (match_operator 6 "arm_comparison_operator"
9878 [(match_operand:SI 4 "s_register_operand" "r")
9879 (match_operand:SI 5 "arm_add_operand" "rIL")])
9880 (match_operator:SI 7 "shiftable_operator"
9881 [(match_operand:SI 2 "s_register_operand" "r")
9882 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9883 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9884 (clobber (reg:CC CC_REGNUM))]
9887 [(set_attr "conds" "clob")
9888 (set_attr "length" "12")
9889 (set_attr "type" "multiple")]
9892 (define_insn "*if_arith_not"
9893 [(set (match_operand:SI 0 "s_register_operand" "=r")
9895 (match_operator 5 "arm_comparison_operator"
9896 [(match_operand 4 "cc_register" "") (const_int 0)])
9897 (match_operator:SI 6 "shiftable_operator"
9898 [(match_operand:SI 2 "s_register_operand" "r")
9899 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9900 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9902 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9903 [(set_attr "conds" "use")
9904 (set_attr "type" "multiple")
9905 (set_attr "length" "8")]
9908 (define_insn "*ifcompare_neg_move"
9909 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9911 (match_operator 5 "arm_comparison_operator"
9912 [(match_operand:SI 3 "s_register_operand" "r,r")
9913 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9914 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9915 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9916 (clobber (reg:CC CC_REGNUM))]
9919 [(set_attr "conds" "clob")
9920 (set_attr "length" "8,12")
9921 (set_attr "type" "multiple")]
9924 (define_insn "*if_neg_move"
9925 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9927 (match_operator 4 "arm_comparison_operator"
9928 [(match_operand 3 "cc_register" "") (const_int 0)])
9929 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9930 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9934 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9935 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9936 [(set_attr "conds" "use")
9937 (set_attr "length" "4,8,8")
9938 (set_attr "type" "logic_shift_imm,multiple,multiple")]
9941 (define_insn "*ifcompare_move_neg"
9942 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9944 (match_operator 5 "arm_comparison_operator"
9945 [(match_operand:SI 3 "s_register_operand" "r,r")
9946 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9947 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9948 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9949 (clobber (reg:CC CC_REGNUM))]
9952 [(set_attr "conds" "clob")
9953 (set_attr "length" "8,12")
9954 (set_attr "type" "multiple")]
9957 (define_insn "*if_move_neg"
9958 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9960 (match_operator 4 "arm_comparison_operator"
9961 [(match_operand 3 "cc_register" "") (const_int 0)])
9962 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9963 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9967 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9968 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9969 [(set_attr "conds" "use")
9970 (set_attr "length" "4,8,8")
9971 (set_attr "type" "logic_shift_imm,multiple,multiple")]
9974 (define_insn "*arith_adjacentmem"
9975 [(set (match_operand:SI 0 "s_register_operand" "=r")
9976 (match_operator:SI 1 "shiftable_operator"
9977 [(match_operand:SI 2 "memory_operand" "m")
9978 (match_operand:SI 3 "memory_operand" "m")]))
9979 (clobber (match_scratch:SI 4 "=r"))]
9980 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9986 HOST_WIDE_INT val1 = 0, val2 = 0;
9988 if (REGNO (operands[0]) > REGNO (operands[4]))
9990 ldm[1] = operands[4];
9991 ldm[2] = operands[0];
9995 ldm[1] = operands[0];
9996 ldm[2] = operands[4];
9999 base_reg = XEXP (operands[2], 0);
10001 if (!REG_P (base_reg))
10003 val1 = INTVAL (XEXP (base_reg, 1));
10004 base_reg = XEXP (base_reg, 0);
10007 if (!REG_P (XEXP (operands[3], 0)))
10008 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10010 arith[0] = operands[0];
10011 arith[3] = operands[1];
10025 if (val1 !=0 && val2 != 0)
10029 if (val1 == 4 || val2 == 4)
10030 /* Other val must be 8, since we know they are adjacent and neither
10032 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
10033 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10035 ldm[0] = ops[0] = operands[4];
10037 ops[2] = GEN_INT (val1);
10038 output_add_immediate (ops);
10040 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10042 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10046 /* Offset is out of range for a single add, so use two ldr. */
10049 ops[2] = GEN_INT (val1);
10050 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10052 ops[2] = GEN_INT (val2);
10053 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10056 else if (val1 != 0)
10059 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10061 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10066 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10068 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10070 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10073 [(set_attr "length" "12")
10074 (set_attr "predicable" "yes")
10075 (set_attr "type" "load1")]
10078 ; This pattern is never tried by combine, so do it as a peephole
10081 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10082 (match_operand:SI 1 "arm_general_register_operand" ""))
10083 (set (reg:CC CC_REGNUM)
10084 (compare:CC (match_dup 1) (const_int 0)))]
10086 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10087 (set (match_dup 0) (match_dup 1))])]
10092 [(set (match_operand:SI 0 "s_register_operand" "")
10093 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10095 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10096 [(match_operand:SI 3 "s_register_operand" "")
10097 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10098 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10100 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10101 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10106 ;; This split can be used because CC_Z mode implies that the following
10107 ;; branch will be an equality, or an unsigned inequality, so the sign
10108 ;; extension is not needed.
10111 [(set (reg:CC_Z CC_REGNUM)
10113 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10115 (match_operand 1 "const_int_operand" "")))
10116 (clobber (match_scratch:SI 2 ""))]
10118 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10119 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
10120 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10121 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10123 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10126 ;; ??? Check the patterns above for Thumb-2 usefulness
10128 (define_expand "prologue"
10129 [(clobber (const_int 0))]
10132 arm_expand_prologue ();
10134 thumb1_expand_prologue ();
10139 (define_expand "epilogue"
10140 [(clobber (const_int 0))]
10143 if (crtl->calls_eh_return)
10144 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10147 thumb1_expand_epilogue ();
10148 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10149 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10151 else if (HAVE_return)
10153 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10154 no need for explicit testing again. */
10155 emit_jump_insn (gen_return ());
10157 else if (TARGET_32BIT)
10159 arm_expand_epilogue (true);
10165 ;; Note - although unspec_volatile's USE all hard registers,
10166 ;; USEs are ignored after relaod has completed. Thus we need
10167 ;; to add an unspec of the link register to ensure that flow
10168 ;; does not think that it is unused by the sibcall branch that
10169 ;; will replace the standard function epilogue.
10170 (define_expand "sibcall_epilogue"
10171 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10172 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10175 arm_expand_epilogue (false);
10180 (define_expand "eh_epilogue"
10181 [(use (match_operand:SI 0 "register_operand" ""))
10182 (use (match_operand:SI 1 "register_operand" ""))
10183 (use (match_operand:SI 2 "register_operand" ""))]
10187 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10188 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10190 rtx ra = gen_rtx_REG (Pmode, 2);
10192 emit_move_insn (ra, operands[2]);
10195 /* This is a hack -- we may have crystalized the function type too
10197 cfun->machine->func_type = 0;
10201 ;; This split is only used during output to reduce the number of patterns
10202 ;; that need assembler instructions adding to them. We allowed the setting
10203 ;; of the conditions to be implicit during rtl generation so that
10204 ;; the conditional compare patterns would work. However this conflicts to
10205 ;; some extent with the conditional data operations, so we have to split them
10208 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10209 ;; conditional execution sufficient?
10212 [(set (match_operand:SI 0 "s_register_operand" "")
10213 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10214 [(match_operand 2 "" "") (match_operand 3 "" "")])
10216 (match_operand 4 "" "")))
10217 (clobber (reg:CC CC_REGNUM))]
10218 "TARGET_ARM && reload_completed"
10219 [(set (match_dup 5) (match_dup 6))
10220 (cond_exec (match_dup 7)
10221 (set (match_dup 0) (match_dup 4)))]
10224 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10225 operands[2], operands[3]);
10226 enum rtx_code rc = GET_CODE (operands[1]);
10228 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10229 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10230 if (mode == CCFPmode || mode == CCFPEmode)
10231 rc = reverse_condition_maybe_unordered (rc);
10233 rc = reverse_condition (rc);
10235 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10240 [(set (match_operand:SI 0 "s_register_operand" "")
10241 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10242 [(match_operand 2 "" "") (match_operand 3 "" "")])
10243 (match_operand 4 "" "")
10245 (clobber (reg:CC CC_REGNUM))]
10246 "TARGET_ARM && reload_completed"
10247 [(set (match_dup 5) (match_dup 6))
10248 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10249 (set (match_dup 0) (match_dup 4)))]
10252 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10253 operands[2], operands[3]);
10255 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10256 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10261 [(set (match_operand:SI 0 "s_register_operand" "")
10262 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10263 [(match_operand 2 "" "") (match_operand 3 "" "")])
10264 (match_operand 4 "" "")
10265 (match_operand 5 "" "")))
10266 (clobber (reg:CC CC_REGNUM))]
10267 "TARGET_ARM && reload_completed"
10268 [(set (match_dup 6) (match_dup 7))
10269 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10270 (set (match_dup 0) (match_dup 4)))
10271 (cond_exec (match_dup 8)
10272 (set (match_dup 0) (match_dup 5)))]
10275 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10276 operands[2], operands[3]);
10277 enum rtx_code rc = GET_CODE (operands[1]);
10279 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10280 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10281 if (mode == CCFPmode || mode == CCFPEmode)
10282 rc = reverse_condition_maybe_unordered (rc);
10284 rc = reverse_condition (rc);
10286 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10291 [(set (match_operand:SI 0 "s_register_operand" "")
10292 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10293 [(match_operand:SI 2 "s_register_operand" "")
10294 (match_operand:SI 3 "arm_add_operand" "")])
10295 (match_operand:SI 4 "arm_rhs_operand" "")
10297 (match_operand:SI 5 "s_register_operand" ""))))
10298 (clobber (reg:CC CC_REGNUM))]
10299 "TARGET_ARM && reload_completed"
10300 [(set (match_dup 6) (match_dup 7))
10301 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10302 (set (match_dup 0) (match_dup 4)))
10303 (cond_exec (match_dup 8)
10304 (set (match_dup 0) (not:SI (match_dup 5))))]
10307 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10308 operands[2], operands[3]);
10309 enum rtx_code rc = GET_CODE (operands[1]);
10311 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10312 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10313 if (mode == CCFPmode || mode == CCFPEmode)
10314 rc = reverse_condition_maybe_unordered (rc);
10316 rc = reverse_condition (rc);
10318 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10322 (define_insn "*cond_move_not"
10323 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10324 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10325 [(match_operand 3 "cc_register" "") (const_int 0)])
10326 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10328 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10332 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10333 [(set_attr "conds" "use")
10334 (set_attr "type" "mvn_reg,multiple")
10335 (set_attr "length" "4,8")]
10338 ;; The next two patterns occur when an AND operation is followed by a
10339 ;; scc insn sequence
10341 (define_insn "*sign_extract_onebit"
10342 [(set (match_operand:SI 0 "s_register_operand" "=r")
10343 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10345 (match_operand:SI 2 "const_int_operand" "n")))
10346 (clobber (reg:CC CC_REGNUM))]
10349 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10350 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10351 return \"mvnne\\t%0, #0\";
10353 [(set_attr "conds" "clob")
10354 (set_attr "length" "8")
10355 (set_attr "type" "multiple")]
10358 (define_insn "*not_signextract_onebit"
10359 [(set (match_operand:SI 0 "s_register_operand" "=r")
10361 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10363 (match_operand:SI 2 "const_int_operand" "n"))))
10364 (clobber (reg:CC CC_REGNUM))]
10367 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10368 output_asm_insn (\"tst\\t%1, %2\", operands);
10369 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10370 return \"movne\\t%0, #0\";
10372 [(set_attr "conds" "clob")
10373 (set_attr "length" "12")
10374 (set_attr "type" "multiple")]
10376 ;; ??? The above patterns need auditing for Thumb-2
10378 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10379 ;; expressions. For simplicity, the first register is also in the unspec
10381 ;; To avoid the usage of GNU extension, the length attribute is computed
10382 ;; in a C function arm_attr_length_push_multi.
10383 (define_insn "*push_multi"
10384 [(match_parallel 2 "multi_register_push"
10385 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10386 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10387 UNSPEC_PUSH_MULT))])]
10391 int num_saves = XVECLEN (operands[2], 0);
10393 /* For the StrongARM at least it is faster to
10394 use STR to store only a single register.
10395 In Thumb mode always use push, and the assembler will pick
10396 something appropriate. */
10397 if (num_saves == 1 && TARGET_ARM)
10398 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10405 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10406 else if (TARGET_THUMB2)
10407 strcpy (pattern, \"push%?\\t{%1\");
10409 strcpy (pattern, \"push\\t{%1\");
10411 for (i = 1; i < num_saves; i++)
10413 strcat (pattern, \", %|\");
10415 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10418 strcat (pattern, \"}\");
10419 output_asm_insn (pattern, operands);
10424 [(set_attr "type" "store4")
10425 (set (attr "length")
10426 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10429 (define_insn "stack_tie"
10430 [(set (mem:BLK (scratch))
10431 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10432 (match_operand:SI 1 "s_register_operand" "rk")]
10436 [(set_attr "length" "0")
10437 (set_attr "type" "block")]
10440 ;; Pop (as used in epilogue RTL)
10442 (define_insn "*load_multiple_with_writeback"
10443 [(match_parallel 0 "load_multiple_operation"
10444 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10445 (plus:SI (match_dup 1)
10446 (match_operand:SI 2 "const_int_I_operand" "I")))
10447 (set (match_operand:SI 3 "s_register_operand" "=rk")
10448 (mem:SI (match_dup 1)))
10450 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10453 arm_output_multireg_pop (operands, /*return_pc=*/false,
10454 /*cond=*/const_true_rtx,
10460 [(set_attr "type" "load4")
10461 (set_attr "predicable" "yes")]
10464 ;; Pop with return (as used in epilogue RTL)
10466 ;; This instruction is generated when the registers are popped at the end of
10467 ;; epilogue. Here, instead of popping the value into LR and then generating
10468 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10470 (define_insn "*pop_multiple_with_writeback_and_return"
10471 [(match_parallel 0 "pop_multiple_return"
10473 (set (match_operand:SI 1 "s_register_operand" "+rk")
10474 (plus:SI (match_dup 1)
10475 (match_operand:SI 2 "const_int_I_operand" "I")))
10476 (set (match_operand:SI 3 "s_register_operand" "=rk")
10477 (mem:SI (match_dup 1)))
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 (define_insn "*pop_multiple_with_return"
10494 [(match_parallel 0 "pop_multiple_return"
10496 (set (match_operand:SI 2 "s_register_operand" "=rk")
10497 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10499 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10502 arm_output_multireg_pop (operands, /*return_pc=*/true,
10503 /*cond=*/const_true_rtx,
10509 [(set_attr "type" "load4")
10510 (set_attr "predicable" "yes")]
10513 ;; Load into PC and return
10514 (define_insn "*ldr_with_return"
10516 (set (reg:SI PC_REGNUM)
10517 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10518 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10519 "ldr%?\t%|pc, [%0], #4"
10520 [(set_attr "type" "load1")
10521 (set_attr "predicable" "yes")]
10523 ;; Pop for floating point registers (as used in epilogue RTL)
10524 (define_insn "*vfp_pop_multiple_with_writeback"
10525 [(match_parallel 0 "pop_multiple_fp"
10526 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10527 (plus:SI (match_dup 1)
10528 (match_operand:SI 2 "const_int_I_operand" "I")))
10529 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10530 (mem:DF (match_dup 1)))])]
10531 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10534 int num_regs = XVECLEN (operands[0], 0);
10537 strcpy (pattern, \"vldm\\t\");
10538 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10539 strcat (pattern, \"!, {\");
10540 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10541 strcat (pattern, \"%P0\");
10542 if ((num_regs - 1) > 1)
10544 strcat (pattern, \"-%P1\");
10545 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10548 strcat (pattern, \"}\");
10549 output_asm_insn (pattern, op_list);
10553 [(set_attr "type" "load4")
10554 (set_attr "conds" "unconditional")
10555 (set_attr "predicable" "no")]
10558 ;; Special patterns for dealing with the constant pool
10560 (define_insn "align_4"
10561 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10564 assemble_align (32);
10567 [(set_attr "type" "no_insn")]
10570 (define_insn "align_8"
10571 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10574 assemble_align (64);
10577 [(set_attr "type" "no_insn")]
10580 (define_insn "consttable_end"
10581 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10584 making_const_table = FALSE;
10587 [(set_attr "type" "no_insn")]
10590 (define_insn "consttable_4"
10591 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10595 rtx x = operands[0];
10596 making_const_table = TRUE;
10597 switch (GET_MODE_CLASS (GET_MODE (x)))
10600 if (GET_MODE (x) == HFmode)
10601 arm_emit_fp16_const (x);
10605 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10606 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10610 /* XXX: Sometimes gcc does something really dumb and ends up with
10611 a HIGH in a constant pool entry, usually because it's trying to
10612 load into a VFP register. We know this will always be used in
10613 combination with a LO_SUM which ignores the high bits, so just
10614 strip off the HIGH. */
10615 if (GET_CODE (x) == HIGH)
10617 assemble_integer (x, 4, BITS_PER_WORD, 1);
10618 mark_symbol_refs_as_used (x);
10623 [(set_attr "length" "4")
10624 (set_attr "type" "no_insn")]
10627 (define_insn "consttable_8"
10628 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10632 making_const_table = TRUE;
10633 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10638 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10639 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10643 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10648 [(set_attr "length" "8")
10649 (set_attr "type" "no_insn")]
10652 (define_insn "consttable_16"
10653 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10657 making_const_table = TRUE;
10658 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10663 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10664 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10668 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10673 [(set_attr "length" "16")
10674 (set_attr "type" "no_insn")]
10677 ;; V5 Instructions,
10679 (define_insn "clzsi2"
10680 [(set (match_operand:SI 0 "s_register_operand" "=r")
10681 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10682 "TARGET_32BIT && arm_arch5"
10684 [(set_attr "predicable" "yes")
10685 (set_attr "predicable_short_it" "no")
10686 (set_attr "type" "clz")])
10688 (define_insn "rbitsi2"
10689 [(set (match_operand:SI 0 "s_register_operand" "=r")
10690 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10691 "TARGET_32BIT && arm_arch_thumb2"
10693 [(set_attr "predicable" "yes")
10694 (set_attr "predicable_short_it" "no")
10695 (set_attr "type" "clz")])
10697 (define_expand "ctzsi2"
10698 [(set (match_operand:SI 0 "s_register_operand" "")
10699 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10700 "TARGET_32BIT && arm_arch_thumb2"
10703 rtx tmp = gen_reg_rtx (SImode);
10704 emit_insn (gen_rbitsi2 (tmp, operands[1]));
10705 emit_insn (gen_clzsi2 (operands[0], tmp));
10711 ;; V5E instructions.
10713 (define_insn "prefetch"
10714 [(prefetch (match_operand:SI 0 "address_operand" "p")
10715 (match_operand:SI 1 "" "")
10716 (match_operand:SI 2 "" ""))]
10717 "TARGET_32BIT && arm_arch5e"
10719 [(set_attr "type" "load1")]
10722 ;; General predication pattern
10725 [(match_operator 0 "arm_comparison_operator"
10726 [(match_operand 1 "cc_register" "")
10730 [(set_attr "predicated" "yes")]
10733 (define_insn "force_register_use"
10734 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10737 [(set_attr "length" "0")
10738 (set_attr "type" "no_insn")]
10742 ;; Patterns for exception handling
10744 (define_expand "eh_return"
10745 [(use (match_operand 0 "general_operand" ""))]
10750 emit_insn (gen_arm_eh_return (operands[0]));
10752 emit_insn (gen_thumb_eh_return (operands[0]));
10757 ;; We can't expand this before we know where the link register is stored.
10758 (define_insn_and_split "arm_eh_return"
10759 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10761 (clobber (match_scratch:SI 1 "=&r"))]
10764 "&& reload_completed"
10768 arm_set_return_address (operands[0], operands[1]);
10776 (define_insn "load_tp_hard"
10777 [(set (match_operand:SI 0 "register_operand" "=r")
10778 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10780 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
10781 [(set_attr "predicable" "yes")
10782 (set_attr "type" "mrs")]
10785 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
10786 (define_insn "load_tp_soft"
10787 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10788 (clobber (reg:SI LR_REGNUM))
10789 (clobber (reg:SI IP_REGNUM))
10790 (clobber (reg:CC CC_REGNUM))]
10792 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
10793 [(set_attr "conds" "clob")
10794 (set_attr "type" "branch")]
10797 ;; tls descriptor call
10798 (define_insn "tlscall"
10799 [(set (reg:SI R0_REGNUM)
10800 (unspec:SI [(reg:SI R0_REGNUM)
10801 (match_operand:SI 0 "" "X")
10802 (match_operand 1 "" "")] UNSPEC_TLS))
10803 (clobber (reg:SI R1_REGNUM))
10804 (clobber (reg:SI LR_REGNUM))
10805 (clobber (reg:SI CC_REGNUM))]
10808 targetm.asm_out.internal_label (asm_out_file, "LPIC",
10809 INTVAL (operands[1]));
10810 return "bl\\t%c0(tlscall)";
10812 [(set_attr "conds" "clob")
10813 (set_attr "length" "4")
10814 (set_attr "type" "branch")]
10817 ;; For thread pointer builtin
10818 (define_expand "get_thread_pointersi"
10819 [(match_operand:SI 0 "s_register_operand" "=r")]
10823 arm_load_tp (operands[0]);
10829 ;; We only care about the lower 16 bits of the constant
10830 ;; being inserted into the upper 16 bits of the register.
10831 (define_insn "*arm_movtas_ze"
10832 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10835 (match_operand:SI 1 "const_int_operand" ""))]
10838 [(set_attr "predicable" "yes")
10839 (set_attr "predicable_short_it" "no")
10840 (set_attr "length" "4")
10841 (set_attr "type" "mov_imm")]
10844 (define_insn "*arm_rev"
10845 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10846 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10852 [(set_attr "arch" "t1,t2,32")
10853 (set_attr "length" "2,2,4")
10854 (set_attr "predicable" "no,yes,yes")
10855 (set_attr "predicable_short_it" "no")
10856 (set_attr "type" "rev")]
10859 (define_expand "arm_legacy_rev"
10860 [(set (match_operand:SI 2 "s_register_operand" "")
10861 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
10865 (lshiftrt:SI (match_dup 2)
10867 (set (match_operand:SI 3 "s_register_operand" "")
10868 (rotatert:SI (match_dup 1)
10871 (and:SI (match_dup 2)
10872 (const_int -65281)))
10873 (set (match_operand:SI 0 "s_register_operand" "")
10874 (xor:SI (match_dup 3)
10880 ;; Reuse temporaries to keep register pressure down.
10881 (define_expand "thumb_legacy_rev"
10882 [(set (match_operand:SI 2 "s_register_operand" "")
10883 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
10885 (set (match_operand:SI 3 "s_register_operand" "")
10886 (lshiftrt:SI (match_dup 1)
10889 (ior:SI (match_dup 3)
10891 (set (match_operand:SI 4 "s_register_operand" "")
10893 (set (match_operand:SI 5 "s_register_operand" "")
10894 (rotatert:SI (match_dup 1)
10897 (ashift:SI (match_dup 5)
10900 (lshiftrt:SI (match_dup 5)
10903 (ior:SI (match_dup 5)
10906 (rotatert:SI (match_dup 5)
10908 (set (match_operand:SI 0 "s_register_operand" "")
10909 (ior:SI (match_dup 5)
10915 (define_expand "bswapsi2"
10916 [(set (match_operand:SI 0 "s_register_operand" "=r")
10917 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
10918 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
10922 rtx op2 = gen_reg_rtx (SImode);
10923 rtx op3 = gen_reg_rtx (SImode);
10927 rtx op4 = gen_reg_rtx (SImode);
10928 rtx op5 = gen_reg_rtx (SImode);
10930 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
10931 op2, op3, op4, op5));
10935 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
10944 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
10945 ;; and unsigned variants, respectively. For rev16, expose
10946 ;; byte-swapping in the lower 16 bits only.
10947 (define_insn "*arm_revsh"
10948 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10949 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
10955 [(set_attr "arch" "t1,t2,32")
10956 (set_attr "length" "2,2,4")
10957 (set_attr "type" "rev")]
10960 (define_insn "*arm_rev16"
10961 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
10962 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
10968 [(set_attr "arch" "t1,t2,32")
10969 (set_attr "length" "2,2,4")
10970 (set_attr "type" "rev")]
10973 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
10974 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
10975 ;; each valid permutation.
10977 (define_insn "arm_rev16si2"
10978 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10979 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
10981 (match_operand:SI 3 "const_int_operand" "n,n,n"))
10982 (and:SI (lshiftrt:SI (match_dup 1)
10984 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
10986 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
10987 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
10989 [(set_attr "arch" "t1,t2,32")
10990 (set_attr "length" "2,2,4")
10991 (set_attr "type" "rev")]
10994 (define_insn "arm_rev16si2_alt"
10995 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
10996 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
10998 (match_operand:SI 2 "const_int_operand" "n,n,n"))
10999 (and:SI (ashift:SI (match_dup 1)
11001 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11003 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11004 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11006 [(set_attr "arch" "t1,t2,32")
11007 (set_attr "length" "2,2,4")
11008 (set_attr "type" "rev")]
11011 (define_expand "bswaphi2"
11012 [(set (match_operand:HI 0 "s_register_operand" "=r")
11013 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11018 ;; Patterns for LDRD/STRD in Thumb2 mode
11020 (define_insn "*thumb2_ldrd"
11021 [(set (match_operand:SI 0 "s_register_operand" "=r")
11022 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11023 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11024 (set (match_operand:SI 3 "s_register_operand" "=r")
11025 (mem:SI (plus:SI (match_dup 1)
11026 (match_operand:SI 4 "const_int_operand" ""))))]
11027 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11028 && current_tune->prefer_ldrd_strd
11029 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11030 && (operands_ok_ldrd_strd (operands[0], operands[3],
11031 operands[1], INTVAL (operands[2]),
11033 "ldrd%?\t%0, %3, [%1, %2]"
11034 [(set_attr "type" "load2")
11035 (set_attr "predicable" "yes")
11036 (set_attr "predicable_short_it" "no")])
11038 (define_insn "*thumb2_ldrd_base"
11039 [(set (match_operand:SI 0 "s_register_operand" "=r")
11040 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11041 (set (match_operand:SI 2 "s_register_operand" "=r")
11042 (mem:SI (plus:SI (match_dup 1)
11044 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11045 && current_tune->prefer_ldrd_strd
11046 && (operands_ok_ldrd_strd (operands[0], operands[2],
11047 operands[1], 0, false, true))"
11048 "ldrd%?\t%0, %2, [%1]"
11049 [(set_attr "type" "load2")
11050 (set_attr "predicable" "yes")
11051 (set_attr "predicable_short_it" "no")])
11053 (define_insn "*thumb2_ldrd_base_neg"
11054 [(set (match_operand:SI 0 "s_register_operand" "=r")
11055 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11057 (set (match_operand:SI 2 "s_register_operand" "=r")
11058 (mem:SI (match_dup 1)))]
11059 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11060 && current_tune->prefer_ldrd_strd
11061 && (operands_ok_ldrd_strd (operands[0], operands[2],
11062 operands[1], -4, false, true))"
11063 "ldrd%?\t%0, %2, [%1, #-4]"
11064 [(set_attr "type" "load2")
11065 (set_attr "predicable" "yes")
11066 (set_attr "predicable_short_it" "no")])
11068 (define_insn "*thumb2_strd"
11069 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11070 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11071 (match_operand:SI 2 "s_register_operand" "r"))
11072 (set (mem:SI (plus:SI (match_dup 0)
11073 (match_operand:SI 3 "const_int_operand" "")))
11074 (match_operand:SI 4 "s_register_operand" "r"))]
11075 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11076 && current_tune->prefer_ldrd_strd
11077 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11078 && (operands_ok_ldrd_strd (operands[2], operands[4],
11079 operands[0], INTVAL (operands[1]),
11081 "strd%?\t%2, %4, [%0, %1]"
11082 [(set_attr "type" "store2")
11083 (set_attr "predicable" "yes")
11084 (set_attr "predicable_short_it" "no")])
11086 (define_insn "*thumb2_strd_base"
11087 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11088 (match_operand:SI 1 "s_register_operand" "r"))
11089 (set (mem:SI (plus:SI (match_dup 0)
11091 (match_operand:SI 2 "s_register_operand" "r"))]
11092 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11093 && current_tune->prefer_ldrd_strd
11094 && (operands_ok_ldrd_strd (operands[1], operands[2],
11095 operands[0], 0, false, false))"
11096 "strd%?\t%1, %2, [%0]"
11097 [(set_attr "type" "store2")
11098 (set_attr "predicable" "yes")
11099 (set_attr "predicable_short_it" "no")])
11101 (define_insn "*thumb2_strd_base_neg"
11102 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11104 (match_operand:SI 1 "s_register_operand" "r"))
11105 (set (mem:SI (match_dup 0))
11106 (match_operand:SI 2 "s_register_operand" "r"))]
11107 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11108 && current_tune->prefer_ldrd_strd
11109 && (operands_ok_ldrd_strd (operands[1], operands[2],
11110 operands[0], -4, false, false))"
11111 "strd%?\t%1, %2, [%0, #-4]"
11112 [(set_attr "type" "store2")
11113 (set_attr "predicable" "yes")
11114 (set_attr "predicable_short_it" "no")])
11116 ;; ARMv8 CRC32 instructions.
11117 (define_insn "<crc_variant>"
11118 [(set (match_operand:SI 0 "s_register_operand" "=r")
11119 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11120 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11123 "<crc_variant>\\t%0, %1, %2"
11124 [(set_attr "type" "crc")
11125 (set_attr "conds" "unconditional")]
11128 ;; Load the load/store double peephole optimizations.
11129 (include "ldrdstrd.md")
11131 ;; Load the load/store multiple patterns
11132 (include "ldmstm.md")
11134 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11135 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11136 (define_insn "*load_multiple"
11137 [(match_parallel 0 "load_multiple_operation"
11138 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11139 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11144 arm_output_multireg_pop (operands, /*return_pc=*/false,
11145 /*cond=*/const_true_rtx,
11151 [(set_attr "predicable" "yes")]
11154 ;; Vector bits common to IWMMXT and Neon
11155 (include "vec-common.md")
11156 ;; Load the Intel Wireless Multimedia Extension patterns
11157 (include "iwmmxt.md")
11158 ;; Load the VFP co-processor patterns
11160 ;; Thumb-1 patterns
11161 (include "thumb1.md")
11162 ;; Thumb-2 patterns
11163 (include "thumb2.md")
11165 (include "neon.md")
11167 (include "crypto.md")
11168 ;; Synchronization Primitives
11169 (include "sync.md")
11170 ;; Fixed-point patterns
11171 (include "arm-fixed.md")