1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2015 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;---------------------------------------------------------------------------
29 ;; Register numbers -- All machine registers should be defined here
31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (IP_REGNUM 12) ; Scratch register
34 (SP_REGNUM 13) ; Stack pointer
35 (LR_REGNUM 14) ; Return address register
36 (PC_REGNUM 15) ; Program counter
37 (LAST_ARM_REGNUM 15) ;
38 (CC_REGNUM 100) ; Condition code pseudo register
39 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
42 ;; 3rd operand to select_dominance_cc_mode
49 ;; conditional compare combination
60 ;;---------------------------------------------------------------------------
63 ;; Processor type. This is created automatically from arm-cores.def.
64 (include "arm-tune.md")
66 ;; Instruction classification types
69 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70 ; generating ARM code. This is used to control the length of some insn
71 ; patterns that share the same RTL in both ARM and Thumb code.
72 (define_attr "is_thumb" "yes,no"
73 (const (if_then_else (symbol_ref "TARGET_THUMB")
74 (const_string "yes") (const_string "no"))))
76 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
79 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
80 (define_attr "is_thumb1" "yes,no"
81 (const (if_then_else (symbol_ref "TARGET_THUMB1")
82 (const_string "yes") (const_string "no"))))
84 ; We use this attribute to disable alternatives that can produce 32-bit
85 ; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
86 ; that contain 32-bit instructions.
87 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
89 ; This attribute is used to disable a predicated alternative when we have
91 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
93 ;; Operand number of an input operand that is shifted. Zero if the
94 ;; given instruction does not shift one of its input operands.
95 (define_attr "shift" "" (const_int 0))
97 ;; [For compatibility with AArch64 in pipeline models]
98 ;; Attribute that specifies whether or not the instruction touches fp
100 (define_attr "fp" "no,yes" (const_string "no"))
102 ; Floating Point Unit. If we only have floating point emulation, then there
103 ; is no point in scheduling the floating point insns. (Well, for best
104 ; performance we should try and group them together).
105 (define_attr "fpu" "none,vfp"
106 (const (symbol_ref "arm_fpu_attr")))
108 (define_attr "predicated" "yes,no" (const_string "no"))
110 ; LENGTH of an instruction (in bytes)
111 (define_attr "length" ""
114 ; The architecture which supports the instruction (or alternative).
115 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
116 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
117 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
118 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6. This attribute is
119 ; used to compute attribute "enabled", use type "any" to enable an
120 ; alternative in all cases.
121 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3"
122 (const_string "any"))
124 (define_attr "arch_enabled" "no,yes"
125 (cond [(eq_attr "arch" "any")
128 (and (eq_attr "arch" "a")
129 (match_test "TARGET_ARM"))
132 (and (eq_attr "arch" "t")
133 (match_test "TARGET_THUMB"))
136 (and (eq_attr "arch" "t1")
137 (match_test "TARGET_THUMB1"))
140 (and (eq_attr "arch" "t2")
141 (match_test "TARGET_THUMB2"))
144 (and (eq_attr "arch" "32")
145 (match_test "TARGET_32BIT"))
148 (and (eq_attr "arch" "v6")
149 (match_test "TARGET_32BIT && arm_arch6"))
152 (and (eq_attr "arch" "nov6")
153 (match_test "TARGET_32BIT && !arm_arch6"))
156 (and (eq_attr "arch" "v6t2")
157 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
160 (and (eq_attr "arch" "avoid_neon_for_64bits")
161 (match_test "TARGET_NEON")
162 (not (match_test "TARGET_PREFER_NEON_64BITS")))
165 (and (eq_attr "arch" "neon_for_64bits")
166 (match_test "TARGET_NEON")
167 (match_test "TARGET_PREFER_NEON_64BITS"))
170 (and (eq_attr "arch" "iwmmxt2")
171 (match_test "TARGET_REALLY_IWMMXT2"))
174 (and (eq_attr "arch" "armv6_or_vfpv3")
175 (match_test "arm_arch6 || TARGET_VFP3"))
179 (const_string "no")))
181 (define_attr "opt" "any,speed,size"
182 (const_string "any"))
184 (define_attr "opt_enabled" "no,yes"
185 (cond [(eq_attr "opt" "any")
188 (and (eq_attr "opt" "speed")
189 (match_test "optimize_function_for_speed_p (cfun)"))
192 (and (eq_attr "opt" "size")
193 (match_test "optimize_function_for_size_p (cfun)"))
194 (const_string "yes")]
195 (const_string "no")))
197 (define_attr "use_literal_pool" "no,yes"
198 (cond [(and (eq_attr "type" "f_loads,f_loadd")
199 (match_test "CONSTANT_P (operands[1])"))
200 (const_string "yes")]
201 (const_string "no")))
203 ; Enable all alternatives that are both arch_enabled and insn_enabled.
204 ; FIXME:: opt_enabled has been temporarily removed till the time we have
205 ; an attribute that allows the use of such alternatives.
206 ; This depends on caching of speed_p, size_p on a per
207 ; alternative basis. The problem is that the enabled attribute
208 ; cannot depend on any state that is not cached or is not constant
209 ; for a compilation unit. We probably need a generic "hot/cold"
210 ; alternative which if implemented can help with this. We disable this
211 ; until such a time as this is implemented and / or the improvements or
212 ; regressions with removing this attribute are double checked.
213 ; See ashldi3_neon and <shift>di3_neon in neon.md.
215 (define_attr "enabled" "no,yes"
216 (cond [(and (eq_attr "predicable_short_it" "no")
217 (and (eq_attr "predicated" "yes")
218 (match_test "arm_restrict_it")))
221 (and (eq_attr "enabled_for_depr_it" "no")
222 (match_test "arm_restrict_it"))
225 (and (eq_attr "use_literal_pool" "yes")
226 (match_test "arm_disable_literal_pool"))
229 (eq_attr "arch_enabled" "no")
231 (const_string "yes")))
233 ; POOL_RANGE is how far away from a constant pool entry that this insn
234 ; can be placed. If the distance is zero, then this insn will never
235 ; reference the pool.
236 ; Note that for Thumb constant pools the PC value is rounded down to the
237 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
238 ; Thumb insns) should be set to <max_range> - 2.
239 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
240 ; before its address. It is set to <max_range> - (8 + <data_size>).
241 (define_attr "arm_pool_range" "" (const_int 0))
242 (define_attr "thumb2_pool_range" "" (const_int 0))
243 (define_attr "arm_neg_pool_range" "" (const_int 0))
244 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
246 (define_attr "pool_range" ""
247 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
248 (attr "arm_pool_range")))
249 (define_attr "neg_pool_range" ""
250 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
251 (attr "arm_neg_pool_range")))
253 ; An assembler sequence may clobber the condition codes without us knowing.
254 ; If such an insn references the pool, then we have no way of knowing how,
255 ; so use the most conservative value for pool_range.
256 (define_asm_attributes
257 [(set_attr "conds" "clob")
258 (set_attr "length" "4")
259 (set_attr "pool_range" "250")])
261 ; Load scheduling, set from the arm_ld_sched variable
262 ; initialized by arm_option_override()
263 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
265 ; condition codes: this one is used by final_prescan_insn to speed up
266 ; conditionalizing instructions. It saves having to scan the rtl to see if
267 ; it uses or alters the condition codes.
269 ; USE means that the condition codes are used by the insn in the process of
270 ; outputting code, this means (at present) that we can't use the insn in
273 ; SET means that the purpose of the insn is to set the condition codes in a
274 ; well defined manner.
276 ; CLOB means that the condition codes are altered in an undefined manner, if
277 ; they are altered at all
279 ; UNCONDITIONAL means the instruction can not be conditionally executed and
280 ; that the instruction does not use or alter the condition codes.
282 ; NOCOND means that the instruction does not use or alter the condition
283 ; codes but can be converted into a conditionally exectuted instruction.
285 (define_attr "conds" "use,set,clob,unconditional,nocond"
287 (ior (eq_attr "is_thumb1" "yes")
288 (eq_attr "type" "call"))
289 (const_string "clob")
290 (if_then_else (eq_attr "is_neon_type" "no")
291 (const_string "nocond")
292 (const_string "unconditional"))))
294 ; Predicable means that the insn can be conditionally executed based on
295 ; an automatically added predicate (additional patterns are generated by
296 ; gen...). We default to 'no' because no Thumb patterns match this rule
297 ; and not all ARM patterns do.
298 (define_attr "predicable" "no,yes" (const_string "no"))
300 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
301 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
302 ; suffer blockages enough to warrant modelling this (and it can adversely
303 ; affect the schedule).
304 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
306 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
307 ; to stall the processor. Used with model_wbuf above.
308 (define_attr "write_conflict" "no,yes"
309 (if_then_else (eq_attr "type"
312 (const_string "no")))
314 ; Classify the insns into those that take one cycle and those that take more
315 ; than one on the main cpu execution unit.
316 (define_attr "core_cycles" "single,multi"
317 (if_then_else (eq_attr "type"
318 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
319 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
320 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
321 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
322 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
323 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
324 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
325 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
326 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
327 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
328 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
329 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
330 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
331 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
332 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
333 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
334 (const_string "single")
335 (const_string "multi")))
337 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
338 ;; distant label. Only applicable to Thumb code.
339 (define_attr "far_jump" "yes,no" (const_string "no"))
342 ;; The number of machine instructions this pattern expands to.
343 ;; Used for Thumb-2 conditional execution.
344 (define_attr "ce_count" "" (const_int 1))
346 ;;---------------------------------------------------------------------------
349 (include "unspecs.md")
351 ;;---------------------------------------------------------------------------
354 (include "iterators.md")
356 ;;---------------------------------------------------------------------------
359 (include "predicates.md")
360 (include "constraints.md")
362 ;;---------------------------------------------------------------------------
363 ;; Pipeline descriptions
365 (define_attr "tune_cortexr4" "yes,no"
367 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
369 (const_string "no"))))
371 ;; True if the generic scheduling description should be used.
373 (define_attr "generic_sched" "yes,no"
375 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
376 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
377 arm1136jfs,cortexa5,cortexa7,cortexa8,\
378 cortexa9,cortexa12,cortexa15,cortexa17,\
379 cortexa53,cortexa57,cortexm4,cortexm7,\
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,\
389 cortexa8,cortexa9,cortexa53,cortexm4,\
390 cortexm7,marvell_pj4,xgene1")
391 (eq_attr "tune_cortexr4" "no"))
393 (const_string "no"))))
395 (include "marvell-f-iwmmxt.md")
396 (include "arm-generic.md")
397 (include "arm926ejs.md")
398 (include "arm1020e.md")
399 (include "arm1026ejs.md")
400 (include "arm1136jfs.md")
402 (include "fa606te.md")
403 (include "fa626te.md")
404 (include "fmp626.md")
405 (include "fa726te.md")
406 (include "cortex-a5.md")
407 (include "cortex-a7.md")
408 (include "cortex-a8.md")
409 (include "cortex-a9.md")
410 (include "cortex-a15.md")
411 (include "cortex-a17.md")
412 (include "cortex-a53.md")
413 (include "cortex-a57.md")
414 (include "cortex-r4.md")
415 (include "cortex-r4f.md")
416 (include "cortex-m7.md")
417 (include "cortex-m4.md")
418 (include "cortex-m4-fpu.md")
420 (include "marvell-pj4.md")
421 (include "xgene1.md")
424 ;;---------------------------------------------------------------------------
429 ;; Note: For DImode insns, there is normally no reason why operands should
430 ;; not be in the same register, what we don't want is for something being
431 ;; written to partially overlap something that is an input.
433 (define_expand "adddi3"
435 [(set (match_operand:DI 0 "s_register_operand" "")
436 (plus:DI (match_operand:DI 1 "s_register_operand" "")
437 (match_operand:DI 2 "arm_adddi_operand" "")))
438 (clobber (reg:CC CC_REGNUM))])]
443 if (!REG_P (operands[1]))
444 operands[1] = force_reg (DImode, operands[1]);
445 if (!REG_P (operands[2]))
446 operands[2] = force_reg (DImode, operands[2]);
451 (define_insn_and_split "*arm_adddi3"
452 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
453 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
454 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
455 (clobber (reg:CC CC_REGNUM))]
456 "TARGET_32BIT && !TARGET_NEON"
458 "TARGET_32BIT && reload_completed
459 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
460 [(parallel [(set (reg:CC_C CC_REGNUM)
461 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
463 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
464 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
465 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
468 operands[3] = gen_highpart (SImode, operands[0]);
469 operands[0] = gen_lowpart (SImode, operands[0]);
470 operands[4] = gen_highpart (SImode, operands[1]);
471 operands[1] = gen_lowpart (SImode, operands[1]);
472 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
473 operands[2] = gen_lowpart (SImode, operands[2]);
475 [(set_attr "conds" "clob")
476 (set_attr "length" "8")
477 (set_attr "type" "multiple")]
480 (define_insn_and_split "*adddi_sesidi_di"
481 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
482 (plus:DI (sign_extend:DI
483 (match_operand:SI 2 "s_register_operand" "r,r"))
484 (match_operand:DI 1 "s_register_operand" "0,r")))
485 (clobber (reg:CC CC_REGNUM))]
488 "TARGET_32BIT && reload_completed"
489 [(parallel [(set (reg:CC_C CC_REGNUM)
490 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
492 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
493 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
496 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
499 operands[3] = gen_highpart (SImode, operands[0]);
500 operands[0] = gen_lowpart (SImode, operands[0]);
501 operands[4] = gen_highpart (SImode, operands[1]);
502 operands[1] = gen_lowpart (SImode, operands[1]);
503 operands[2] = gen_lowpart (SImode, operands[2]);
505 [(set_attr "conds" "clob")
506 (set_attr "length" "8")
507 (set_attr "type" "multiple")]
510 (define_insn_and_split "*adddi_zesidi_di"
511 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
512 (plus:DI (zero_extend:DI
513 (match_operand:SI 2 "s_register_operand" "r,r"))
514 (match_operand:DI 1 "s_register_operand" "0,r")))
515 (clobber (reg:CC CC_REGNUM))]
518 "TARGET_32BIT && reload_completed"
519 [(parallel [(set (reg:CC_C CC_REGNUM)
520 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
522 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
523 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
524 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
527 operands[3] = gen_highpart (SImode, operands[0]);
528 operands[0] = gen_lowpart (SImode, operands[0]);
529 operands[4] = gen_highpart (SImode, operands[1]);
530 operands[1] = gen_lowpart (SImode, operands[1]);
531 operands[2] = gen_lowpart (SImode, operands[2]);
533 [(set_attr "conds" "clob")
534 (set_attr "length" "8")
535 (set_attr "type" "multiple")]
538 (define_expand "addsi3"
539 [(set (match_operand:SI 0 "s_register_operand" "")
540 (plus:SI (match_operand:SI 1 "s_register_operand" "")
541 (match_operand:SI 2 "reg_or_int_operand" "")))]
544 if (TARGET_32BIT && CONST_INT_P (operands[2]))
546 arm_split_constant (PLUS, SImode, NULL_RTX,
547 INTVAL (operands[2]), operands[0], operands[1],
548 optimize && can_create_pseudo_p ());
554 ; If there is a scratch available, this will be faster than synthesizing the
557 [(match_scratch:SI 3 "r")
558 (set (match_operand:SI 0 "arm_general_register_operand" "")
559 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
560 (match_operand:SI 2 "const_int_operand" "")))]
562 !(const_ok_for_arm (INTVAL (operands[2]))
563 || const_ok_for_arm (-INTVAL (operands[2])))
564 && const_ok_for_arm (~INTVAL (operands[2]))"
565 [(set (match_dup 3) (match_dup 2))
566 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
570 ;; The r/r/k alternative is required when reloading the address
571 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
572 ;; put the duplicated register first, and not try the commutative version.
573 (define_insn_and_split "*arm_addsi3"
574 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
575 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
576 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
591 subw%?\\t%0, %1, #%n2
592 subw%?\\t%0, %1, #%n2
595 && CONST_INT_P (operands[2])
596 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
597 && (reload_completed || !arm_eliminable_register (operands[1]))"
598 [(clobber (const_int 0))]
600 arm_split_constant (PLUS, SImode, curr_insn,
601 INTVAL (operands[2]), operands[0],
605 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
606 (set_attr "predicable" "yes")
607 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
608 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
609 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
610 (const_string "alu_imm")
611 (const_string "alu_sreg")))
615 (define_insn "addsi3_compare0"
616 [(set (reg:CC_NOOV CC_REGNUM)
618 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
619 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
621 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
622 (plus:SI (match_dup 1) (match_dup 2)))]
628 [(set_attr "conds" "set")
629 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
632 (define_insn "*addsi3_compare0_scratch"
633 [(set (reg:CC_NOOV CC_REGNUM)
635 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
636 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
643 [(set_attr "conds" "set")
644 (set_attr "predicable" "yes")
645 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
648 (define_insn "*compare_negsi_si"
649 [(set (reg:CC_Z CC_REGNUM)
651 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
652 (match_operand:SI 1 "s_register_operand" "l,r")))]
655 [(set_attr "conds" "set")
656 (set_attr "predicable" "yes")
657 (set_attr "arch" "t2,*")
658 (set_attr "length" "2,4")
659 (set_attr "predicable_short_it" "yes,no")
660 (set_attr "type" "alus_sreg")]
663 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
664 ;; addend is a constant.
665 (define_insn "cmpsi2_addneg"
666 [(set (reg:CC CC_REGNUM)
668 (match_operand:SI 1 "s_register_operand" "r,r")
669 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
670 (set (match_operand:SI 0 "s_register_operand" "=r,r")
671 (plus:SI (match_dup 1)
672 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
673 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
676 sub%.\\t%0, %1, #%n3"
677 [(set_attr "conds" "set")
678 (set_attr "type" "alus_sreg")]
681 ;; Convert the sequence
683 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
687 ;; bcs dest ((unsigned)rn >= 1)
688 ;; similarly for the beq variant using bcc.
689 ;; This is a common looping idiom (while (n--))
691 [(set (match_operand:SI 0 "arm_general_register_operand" "")
692 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
694 (set (match_operand 2 "cc_register" "")
695 (compare (match_dup 0) (const_int -1)))
697 (if_then_else (match_operator 3 "equality_operator"
698 [(match_dup 2) (const_int 0)])
699 (match_operand 4 "" "")
700 (match_operand 5 "" "")))]
701 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
705 (match_dup 1) (const_int 1)))
706 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
708 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
711 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
712 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
715 operands[2], const0_rtx);"
718 ;; The next four insns work because they compare the result with one of
719 ;; the operands, and we know that the use of the condition code is
720 ;; either GEU or LTU, so we can use the carry flag from the addition
721 ;; instead of doing the compare a second time.
722 (define_insn "*addsi3_compare_op1"
723 [(set (reg:CC_C CC_REGNUM)
725 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
726 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
728 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
729 (plus:SI (match_dup 1) (match_dup 2)))]
735 [(set_attr "conds" "set")
736 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
739 (define_insn "*addsi3_compare_op2"
740 [(set (reg:CC_C CC_REGNUM)
742 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
743 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
745 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
746 (plus:SI (match_dup 1) (match_dup 2)))]
751 sub%.\\t%0, %1, #%n2"
752 [(set_attr "conds" "set")
753 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
756 (define_insn "*compare_addsi2_op0"
757 [(set (reg:CC_C CC_REGNUM)
759 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
760 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
769 [(set_attr "conds" "set")
770 (set_attr "predicable" "yes")
771 (set_attr "arch" "t2,t2,*,*,*")
772 (set_attr "predicable_short_it" "yes,yes,no,no,no")
773 (set_attr "length" "2,2,4,4,4")
774 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
777 (define_insn "*compare_addsi2_op1"
778 [(set (reg:CC_C CC_REGNUM)
780 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
781 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
790 [(set_attr "conds" "set")
791 (set_attr "predicable" "yes")
792 (set_attr "arch" "t2,t2,*,*,*")
793 (set_attr "predicable_short_it" "yes,yes,no,no,no")
794 (set_attr "length" "2,2,4,4,4")
795 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
798 (define_insn "*addsi3_carryin_<optab>"
799 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
800 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
801 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
802 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
807 sbc%?\\t%0, %1, #%B2"
808 [(set_attr "conds" "use")
809 (set_attr "predicable" "yes")
810 (set_attr "arch" "t2,*,*")
811 (set_attr "length" "4")
812 (set_attr "predicable_short_it" "yes,no,no")
813 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
816 (define_insn "*addsi3_carryin_alt2_<optab>"
817 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
818 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
819 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
820 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
825 sbc%?\\t%0, %1, #%B2"
826 [(set_attr "conds" "use")
827 (set_attr "predicable" "yes")
828 (set_attr "arch" "t2,*,*")
829 (set_attr "length" "4")
830 (set_attr "predicable_short_it" "yes,no,no")
831 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
834 (define_insn "*addsi3_carryin_shift_<optab>"
835 [(set (match_operand:SI 0 "s_register_operand" "=r")
837 (match_operator:SI 2 "shift_operator"
838 [(match_operand:SI 3 "s_register_operand" "r")
839 (match_operand:SI 4 "reg_or_int_operand" "rM")])
840 (match_operand:SI 1 "s_register_operand" "r"))
841 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
843 "adc%?\\t%0, %1, %3%S2"
844 [(set_attr "conds" "use")
845 (set_attr "predicable" "yes")
846 (set_attr "predicable_short_it" "no")
847 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
848 (const_string "alu_shift_imm")
849 (const_string "alu_shift_reg")))]
852 (define_insn "*addsi3_carryin_clobercc_<optab>"
853 [(set (match_operand:SI 0 "s_register_operand" "=r")
854 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
855 (match_operand:SI 2 "arm_rhs_operand" "rI"))
856 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
857 (clobber (reg:CC CC_REGNUM))]
860 [(set_attr "conds" "set")
861 (set_attr "type" "adcs_reg")]
864 (define_insn "*subsi3_carryin"
865 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
866 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
867 (match_operand:SI 2 "s_register_operand" "r,r"))
868 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
873 [(set_attr "conds" "use")
874 (set_attr "arch" "*,a")
875 (set_attr "predicable" "yes")
876 (set_attr "predicable_short_it" "no")
877 (set_attr "type" "adc_reg,adc_imm")]
880 (define_insn "*subsi3_carryin_const"
881 [(set (match_operand:SI 0 "s_register_operand" "=r")
882 (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
883 (match_operand:SI 2 "arm_not_operand" "K"))
884 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
887 [(set_attr "conds" "use")
888 (set_attr "type" "adc_imm")]
891 (define_insn "*subsi3_carryin_compare"
892 [(set (reg:CC CC_REGNUM)
893 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
894 (match_operand:SI 2 "s_register_operand" "r")))
895 (set (match_operand:SI 0 "s_register_operand" "=r")
896 (minus:SI (minus:SI (match_dup 1)
898 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
901 [(set_attr "conds" "set")
902 (set_attr "type" "adcs_reg")]
905 (define_insn "*subsi3_carryin_compare_const"
906 [(set (reg:CC CC_REGNUM)
907 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
908 (match_operand:SI 2 "arm_not_operand" "K")))
909 (set (match_operand:SI 0 "s_register_operand" "=r")
910 (minus:SI (plus:SI (match_dup 1)
912 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
914 "sbcs\\t%0, %1, #%B2"
915 [(set_attr "conds" "set")
916 (set_attr "type" "adcs_imm")]
919 (define_insn "*subsi3_carryin_shift"
920 [(set (match_operand:SI 0 "s_register_operand" "=r")
922 (match_operand:SI 1 "s_register_operand" "r")
923 (match_operator:SI 2 "shift_operator"
924 [(match_operand:SI 3 "s_register_operand" "r")
925 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
926 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
928 "sbc%?\\t%0, %1, %3%S2"
929 [(set_attr "conds" "use")
930 (set_attr "predicable" "yes")
931 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
932 (const_string "alu_shift_imm")
933 (const_string "alu_shift_reg")))]
936 (define_insn "*rsbsi3_carryin_shift"
937 [(set (match_operand:SI 0 "s_register_operand" "=r")
939 (match_operator:SI 2 "shift_operator"
940 [(match_operand:SI 3 "s_register_operand" "r")
941 (match_operand:SI 4 "reg_or_int_operand" "rM")])
942 (match_operand:SI 1 "s_register_operand" "r"))
943 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
945 "rsc%?\\t%0, %1, %3%S2"
946 [(set_attr "conds" "use")
947 (set_attr "predicable" "yes")
948 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
949 (const_string "alu_shift_imm")
950 (const_string "alu_shift_reg")))]
953 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
955 [(set (match_operand:SI 0 "s_register_operand" "")
956 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
957 (match_operand:SI 2 "s_register_operand" ""))
959 (clobber (match_operand:SI 3 "s_register_operand" ""))]
961 [(set (match_dup 3) (match_dup 1))
962 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
964 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
967 (define_expand "addsf3"
968 [(set (match_operand:SF 0 "s_register_operand" "")
969 (plus:SF (match_operand:SF 1 "s_register_operand" "")
970 (match_operand:SF 2 "s_register_operand" "")))]
971 "TARGET_32BIT && TARGET_HARD_FLOAT"
975 (define_expand "adddf3"
976 [(set (match_operand:DF 0 "s_register_operand" "")
977 (plus:DF (match_operand:DF 1 "s_register_operand" "")
978 (match_operand:DF 2 "s_register_operand" "")))]
979 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
983 (define_expand "subdi3"
985 [(set (match_operand:DI 0 "s_register_operand" "")
986 (minus:DI (match_operand:DI 1 "s_register_operand" "")
987 (match_operand:DI 2 "s_register_operand" "")))
988 (clobber (reg:CC CC_REGNUM))])]
993 if (!REG_P (operands[1]))
994 operands[1] = force_reg (DImode, operands[1]);
995 if (!REG_P (operands[2]))
996 operands[2] = force_reg (DImode, operands[2]);
1001 (define_insn_and_split "*arm_subdi3"
1002 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1003 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1004 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1005 (clobber (reg:CC CC_REGNUM))]
1006 "TARGET_32BIT && !TARGET_NEON"
1007 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1008 "&& reload_completed"
1009 [(parallel [(set (reg:CC CC_REGNUM)
1010 (compare:CC (match_dup 1) (match_dup 2)))
1011 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1012 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1013 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1015 operands[3] = gen_highpart (SImode, operands[0]);
1016 operands[0] = gen_lowpart (SImode, operands[0]);
1017 operands[4] = gen_highpart (SImode, operands[1]);
1018 operands[1] = gen_lowpart (SImode, operands[1]);
1019 operands[5] = gen_highpart (SImode, operands[2]);
1020 operands[2] = gen_lowpart (SImode, operands[2]);
1022 [(set_attr "conds" "clob")
1023 (set_attr "length" "8")
1024 (set_attr "type" "multiple")]
1027 (define_insn_and_split "*subdi_di_zesidi"
1028 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1029 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1031 (match_operand:SI 2 "s_register_operand" "r,r"))))
1032 (clobber (reg:CC CC_REGNUM))]
1034 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1035 "&& reload_completed"
1036 [(parallel [(set (reg:CC CC_REGNUM)
1037 (compare:CC (match_dup 1) (match_dup 2)))
1038 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1039 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1040 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1042 operands[3] = gen_highpart (SImode, operands[0]);
1043 operands[0] = gen_lowpart (SImode, operands[0]);
1044 operands[4] = gen_highpart (SImode, operands[1]);
1045 operands[1] = gen_lowpart (SImode, operands[1]);
1046 operands[5] = GEN_INT (~0);
1048 [(set_attr "conds" "clob")
1049 (set_attr "length" "8")
1050 (set_attr "type" "multiple")]
1053 (define_insn_and_split "*subdi_di_sesidi"
1054 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1055 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1057 (match_operand:SI 2 "s_register_operand" "r,r"))))
1058 (clobber (reg:CC CC_REGNUM))]
1060 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1061 "&& reload_completed"
1062 [(parallel [(set (reg:CC CC_REGNUM)
1063 (compare:CC (match_dup 1) (match_dup 2)))
1064 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1065 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1066 (ashiftrt:SI (match_dup 2)
1068 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1070 operands[3] = gen_highpart (SImode, operands[0]);
1071 operands[0] = gen_lowpart (SImode, operands[0]);
1072 operands[4] = gen_highpart (SImode, operands[1]);
1073 operands[1] = gen_lowpart (SImode, operands[1]);
1075 [(set_attr "conds" "clob")
1076 (set_attr "length" "8")
1077 (set_attr "type" "multiple")]
1080 (define_insn_and_split "*subdi_zesidi_di"
1081 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1082 (minus:DI (zero_extend:DI
1083 (match_operand:SI 2 "s_register_operand" "r,r"))
1084 (match_operand:DI 1 "s_register_operand" "0,r")))
1085 (clobber (reg:CC CC_REGNUM))]
1087 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1089 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1090 "&& reload_completed"
1091 [(parallel [(set (reg:CC CC_REGNUM)
1092 (compare:CC (match_dup 2) (match_dup 1)))
1093 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1094 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1095 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1097 operands[3] = gen_highpart (SImode, operands[0]);
1098 operands[0] = gen_lowpart (SImode, operands[0]);
1099 operands[4] = gen_highpart (SImode, operands[1]);
1100 operands[1] = gen_lowpart (SImode, operands[1]);
1102 [(set_attr "conds" "clob")
1103 (set_attr "length" "8")
1104 (set_attr "type" "multiple")]
1107 (define_insn_and_split "*subdi_sesidi_di"
1108 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1109 (minus:DI (sign_extend:DI
1110 (match_operand:SI 2 "s_register_operand" "r,r"))
1111 (match_operand:DI 1 "s_register_operand" "0,r")))
1112 (clobber (reg:CC CC_REGNUM))]
1114 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1116 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1117 "&& reload_completed"
1118 [(parallel [(set (reg:CC CC_REGNUM)
1119 (compare:CC (match_dup 2) (match_dup 1)))
1120 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1121 (set (match_dup 3) (minus:SI (minus:SI
1122 (ashiftrt:SI (match_dup 2)
1125 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1127 operands[3] = gen_highpart (SImode, operands[0]);
1128 operands[0] = gen_lowpart (SImode, operands[0]);
1129 operands[4] = gen_highpart (SImode, operands[1]);
1130 operands[1] = gen_lowpart (SImode, operands[1]);
1132 [(set_attr "conds" "clob")
1133 (set_attr "length" "8")
1134 (set_attr "type" "multiple")]
1137 (define_insn_and_split "*subdi_zesidi_zesidi"
1138 [(set (match_operand:DI 0 "s_register_operand" "=r")
1139 (minus:DI (zero_extend:DI
1140 (match_operand:SI 1 "s_register_operand" "r"))
1142 (match_operand:SI 2 "s_register_operand" "r"))))
1143 (clobber (reg:CC CC_REGNUM))]
1145 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1146 "&& reload_completed"
1147 [(parallel [(set (reg:CC CC_REGNUM)
1148 (compare:CC (match_dup 1) (match_dup 2)))
1149 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1150 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1151 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1153 operands[3] = gen_highpart (SImode, operands[0]);
1154 operands[0] = gen_lowpart (SImode, operands[0]);
1156 [(set_attr "conds" "clob")
1157 (set_attr "length" "8")
1158 (set_attr "type" "multiple")]
1161 (define_expand "subsi3"
1162 [(set (match_operand:SI 0 "s_register_operand" "")
1163 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1164 (match_operand:SI 2 "s_register_operand" "")))]
1167 if (CONST_INT_P (operands[1]))
1171 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1172 operands[1] = force_reg (SImode, operands[1]);
1175 arm_split_constant (MINUS, SImode, NULL_RTX,
1176 INTVAL (operands[1]), operands[0],
1178 optimize && can_create_pseudo_p ());
1182 else /* TARGET_THUMB1 */
1183 operands[1] = force_reg (SImode, operands[1]);
1188 ; ??? Check Thumb-2 split length
1189 (define_insn_and_split "*arm_subsi3_insn"
1190 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1191 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1192 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1204 "&& (CONST_INT_P (operands[1])
1205 && !const_ok_for_arm (INTVAL (operands[1])))"
1206 [(clobber (const_int 0))]
1208 arm_split_constant (MINUS, SImode, curr_insn,
1209 INTVAL (operands[1]), operands[0], operands[2], 0);
1212 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1213 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1214 (set_attr "predicable" "yes")
1215 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1216 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1220 [(match_scratch:SI 3 "r")
1221 (set (match_operand:SI 0 "arm_general_register_operand" "")
1222 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1223 (match_operand:SI 2 "arm_general_register_operand" "")))]
1225 && !const_ok_for_arm (INTVAL (operands[1]))
1226 && const_ok_for_arm (~INTVAL (operands[1]))"
1227 [(set (match_dup 3) (match_dup 1))
1228 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1232 (define_insn "subsi3_compare0"
1233 [(set (reg:CC_NOOV CC_REGNUM)
1235 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1236 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1238 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1239 (minus:SI (match_dup 1) (match_dup 2)))]
1245 [(set_attr "conds" "set")
1246 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1249 (define_insn "subsi3_compare"
1250 [(set (reg:CC CC_REGNUM)
1251 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1252 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1253 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1254 (minus:SI (match_dup 1) (match_dup 2)))]
1260 [(set_attr "conds" "set")
1261 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1264 (define_expand "subsf3"
1265 [(set (match_operand:SF 0 "s_register_operand" "")
1266 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1267 (match_operand:SF 2 "s_register_operand" "")))]
1268 "TARGET_32BIT && TARGET_HARD_FLOAT"
1272 (define_expand "subdf3"
1273 [(set (match_operand:DF 0 "s_register_operand" "")
1274 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1275 (match_operand:DF 2 "s_register_operand" "")))]
1276 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1281 ;; Multiplication insns
1283 (define_expand "mulhi3"
1284 [(set (match_operand:HI 0 "s_register_operand" "")
1285 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1286 (match_operand:HI 2 "s_register_operand" "")))]
1287 "TARGET_DSP_MULTIPLY"
1290 rtx result = gen_reg_rtx (SImode);
1291 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1292 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1297 (define_expand "mulsi3"
1298 [(set (match_operand:SI 0 "s_register_operand" "")
1299 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1300 (match_operand:SI 1 "s_register_operand" "")))]
1305 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1306 (define_insn "*arm_mulsi3"
1307 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1308 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1309 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1310 "TARGET_32BIT && !arm_arch6"
1311 "mul%?\\t%0, %2, %1"
1312 [(set_attr "type" "mul")
1313 (set_attr "predicable" "yes")]
1316 (define_insn "*arm_mulsi3_v6"
1317 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1318 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1319 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1320 "TARGET_32BIT && arm_arch6"
1321 "mul%?\\t%0, %1, %2"
1322 [(set_attr "type" "mul")
1323 (set_attr "predicable" "yes")
1324 (set_attr "arch" "t2,t2,*")
1325 (set_attr "length" "4")
1326 (set_attr "predicable_short_it" "yes,yes,no")]
1329 (define_insn "*mulsi3_compare0"
1330 [(set (reg:CC_NOOV CC_REGNUM)
1331 (compare:CC_NOOV (mult:SI
1332 (match_operand:SI 2 "s_register_operand" "r,r")
1333 (match_operand:SI 1 "s_register_operand" "%0,r"))
1335 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1336 (mult:SI (match_dup 2) (match_dup 1)))]
1337 "TARGET_ARM && !arm_arch6"
1338 "mul%.\\t%0, %2, %1"
1339 [(set_attr "conds" "set")
1340 (set_attr "type" "muls")]
1343 (define_insn "*mulsi3_compare0_v6"
1344 [(set (reg:CC_NOOV CC_REGNUM)
1345 (compare:CC_NOOV (mult:SI
1346 (match_operand:SI 2 "s_register_operand" "r")
1347 (match_operand:SI 1 "s_register_operand" "r"))
1349 (set (match_operand:SI 0 "s_register_operand" "=r")
1350 (mult:SI (match_dup 2) (match_dup 1)))]
1351 "TARGET_ARM && arm_arch6 && optimize_size"
1352 "mul%.\\t%0, %2, %1"
1353 [(set_attr "conds" "set")
1354 (set_attr "type" "muls")]
1357 (define_insn "*mulsi_compare0_scratch"
1358 [(set (reg:CC_NOOV CC_REGNUM)
1359 (compare:CC_NOOV (mult:SI
1360 (match_operand:SI 2 "s_register_operand" "r,r")
1361 (match_operand:SI 1 "s_register_operand" "%0,r"))
1363 (clobber (match_scratch:SI 0 "=&r,&r"))]
1364 "TARGET_ARM && !arm_arch6"
1365 "mul%.\\t%0, %2, %1"
1366 [(set_attr "conds" "set")
1367 (set_attr "type" "muls")]
1370 (define_insn "*mulsi_compare0_scratch_v6"
1371 [(set (reg:CC_NOOV CC_REGNUM)
1372 (compare:CC_NOOV (mult:SI
1373 (match_operand:SI 2 "s_register_operand" "r")
1374 (match_operand:SI 1 "s_register_operand" "r"))
1376 (clobber (match_scratch:SI 0 "=r"))]
1377 "TARGET_ARM && arm_arch6 && optimize_size"
1378 "mul%.\\t%0, %2, %1"
1379 [(set_attr "conds" "set")
1380 (set_attr "type" "muls")]
1383 ;; Unnamed templates to match MLA instruction.
1385 (define_insn "*mulsi3addsi"
1386 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1388 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1389 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1390 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1391 "TARGET_32BIT && !arm_arch6"
1392 "mla%?\\t%0, %2, %1, %3"
1393 [(set_attr "type" "mla")
1394 (set_attr "predicable" "yes")]
1397 (define_insn "*mulsi3addsi_v6"
1398 [(set (match_operand:SI 0 "s_register_operand" "=r")
1400 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1401 (match_operand:SI 1 "s_register_operand" "r"))
1402 (match_operand:SI 3 "s_register_operand" "r")))]
1403 "TARGET_32BIT && arm_arch6"
1404 "mla%?\\t%0, %2, %1, %3"
1405 [(set_attr "type" "mla")
1406 (set_attr "predicable" "yes")
1407 (set_attr "predicable_short_it" "no")]
1410 (define_insn "*mulsi3addsi_compare0"
1411 [(set (reg:CC_NOOV CC_REGNUM)
1414 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1415 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1416 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1418 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1419 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1421 "TARGET_ARM && arm_arch6"
1422 "mla%.\\t%0, %2, %1, %3"
1423 [(set_attr "conds" "set")
1424 (set_attr "type" "mlas")]
1427 (define_insn "*mulsi3addsi_compare0_v6"
1428 [(set (reg:CC_NOOV CC_REGNUM)
1431 (match_operand:SI 2 "s_register_operand" "r")
1432 (match_operand:SI 1 "s_register_operand" "r"))
1433 (match_operand:SI 3 "s_register_operand" "r"))
1435 (set (match_operand:SI 0 "s_register_operand" "=r")
1436 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1438 "TARGET_ARM && arm_arch6 && optimize_size"
1439 "mla%.\\t%0, %2, %1, %3"
1440 [(set_attr "conds" "set")
1441 (set_attr "type" "mlas")]
1444 (define_insn "*mulsi3addsi_compare0_scratch"
1445 [(set (reg:CC_NOOV CC_REGNUM)
1448 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1449 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1450 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1452 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1453 "TARGET_ARM && !arm_arch6"
1454 "mla%.\\t%0, %2, %1, %3"
1455 [(set_attr "conds" "set")
1456 (set_attr "type" "mlas")]
1459 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1460 [(set (reg:CC_NOOV CC_REGNUM)
1463 (match_operand:SI 2 "s_register_operand" "r")
1464 (match_operand:SI 1 "s_register_operand" "r"))
1465 (match_operand:SI 3 "s_register_operand" "r"))
1467 (clobber (match_scratch:SI 0 "=r"))]
1468 "TARGET_ARM && arm_arch6 && optimize_size"
1469 "mla%.\\t%0, %2, %1, %3"
1470 [(set_attr "conds" "set")
1471 (set_attr "type" "mlas")]
1474 (define_insn "*mulsi3subsi"
1475 [(set (match_operand:SI 0 "s_register_operand" "=r")
1477 (match_operand:SI 3 "s_register_operand" "r")
1478 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1479 (match_operand:SI 1 "s_register_operand" "r"))))]
1480 "TARGET_32BIT && arm_arch_thumb2"
1481 "mls%?\\t%0, %2, %1, %3"
1482 [(set_attr "type" "mla")
1483 (set_attr "predicable" "yes")
1484 (set_attr "predicable_short_it" "no")]
1487 (define_expand "maddsidi4"
1488 [(set (match_operand:DI 0 "s_register_operand" "")
1491 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1492 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1493 (match_operand:DI 3 "s_register_operand" "")))]
1494 "TARGET_32BIT && arm_arch3m"
1497 (define_insn "*mulsidi3adddi"
1498 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1501 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1502 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1503 (match_operand:DI 1 "s_register_operand" "0")))]
1504 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1505 "smlal%?\\t%Q0, %R0, %3, %2"
1506 [(set_attr "type" "smlal")
1507 (set_attr "predicable" "yes")]
1510 (define_insn "*mulsidi3adddi_v6"
1511 [(set (match_operand:DI 0 "s_register_operand" "=r")
1514 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1515 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1516 (match_operand:DI 1 "s_register_operand" "0")))]
1517 "TARGET_32BIT && arm_arch6"
1518 "smlal%?\\t%Q0, %R0, %3, %2"
1519 [(set_attr "type" "smlal")
1520 (set_attr "predicable" "yes")
1521 (set_attr "predicable_short_it" "no")]
1524 ;; 32x32->64 widening multiply.
1525 ;; As with mulsi3, the only difference between the v3-5 and v6+
1526 ;; versions of these patterns is the requirement that the output not
1527 ;; overlap the inputs, but that still means we have to have a named
1528 ;; expander and two different starred insns.
1530 (define_expand "mulsidi3"
1531 [(set (match_operand:DI 0 "s_register_operand" "")
1533 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1534 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1535 "TARGET_32BIT && arm_arch3m"
1539 (define_insn "*mulsidi3_nov6"
1540 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1542 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1543 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1544 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1545 "smull%?\\t%Q0, %R0, %1, %2"
1546 [(set_attr "type" "smull")
1547 (set_attr "predicable" "yes")]
1550 (define_insn "*mulsidi3_v6"
1551 [(set (match_operand:DI 0 "s_register_operand" "=r")
1553 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1554 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1555 "TARGET_32BIT && arm_arch6"
1556 "smull%?\\t%Q0, %R0, %1, %2"
1557 [(set_attr "type" "smull")
1558 (set_attr "predicable" "yes")
1559 (set_attr "predicable_short_it" "no")]
1562 (define_expand "umulsidi3"
1563 [(set (match_operand:DI 0 "s_register_operand" "")
1565 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1566 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1567 "TARGET_32BIT && arm_arch3m"
1571 (define_insn "*umulsidi3_nov6"
1572 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1574 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1575 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1576 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1577 "umull%?\\t%Q0, %R0, %1, %2"
1578 [(set_attr "type" "umull")
1579 (set_attr "predicable" "yes")]
1582 (define_insn "*umulsidi3_v6"
1583 [(set (match_operand:DI 0 "s_register_operand" "=r")
1585 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1586 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1587 "TARGET_32BIT && arm_arch6"
1588 "umull%?\\t%Q0, %R0, %1, %2"
1589 [(set_attr "type" "umull")
1590 (set_attr "predicable" "yes")
1591 (set_attr "predicable_short_it" "no")]
1594 (define_expand "umaddsidi4"
1595 [(set (match_operand:DI 0 "s_register_operand" "")
1598 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1599 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1600 (match_operand:DI 3 "s_register_operand" "")))]
1601 "TARGET_32BIT && arm_arch3m"
1604 (define_insn "*umulsidi3adddi"
1605 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1608 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1609 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1610 (match_operand:DI 1 "s_register_operand" "0")))]
1611 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1612 "umlal%?\\t%Q0, %R0, %3, %2"
1613 [(set_attr "type" "umlal")
1614 (set_attr "predicable" "yes")]
1617 (define_insn "*umulsidi3adddi_v6"
1618 [(set (match_operand:DI 0 "s_register_operand" "=r")
1621 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1622 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1623 (match_operand:DI 1 "s_register_operand" "0")))]
1624 "TARGET_32BIT && arm_arch6"
1625 "umlal%?\\t%Q0, %R0, %3, %2"
1626 [(set_attr "type" "umlal")
1627 (set_attr "predicable" "yes")
1628 (set_attr "predicable_short_it" "no")]
1631 (define_expand "smulsi3_highpart"
1633 [(set (match_operand:SI 0 "s_register_operand" "")
1637 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1638 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1640 (clobber (match_scratch:SI 3 ""))])]
1641 "TARGET_32BIT && arm_arch3m"
1645 (define_insn "*smulsi3_highpart_nov6"
1646 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1650 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1651 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1653 (clobber (match_scratch:SI 3 "=&r,&r"))]
1654 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1655 "smull%?\\t%3, %0, %2, %1"
1656 [(set_attr "type" "smull")
1657 (set_attr "predicable" "yes")]
1660 (define_insn "*smulsi3_highpart_v6"
1661 [(set (match_operand:SI 0 "s_register_operand" "=r")
1665 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1666 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1668 (clobber (match_scratch:SI 3 "=r"))]
1669 "TARGET_32BIT && arm_arch6"
1670 "smull%?\\t%3, %0, %2, %1"
1671 [(set_attr "type" "smull")
1672 (set_attr "predicable" "yes")
1673 (set_attr "predicable_short_it" "no")]
1676 (define_expand "umulsi3_highpart"
1678 [(set (match_operand:SI 0 "s_register_operand" "")
1682 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1683 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1685 (clobber (match_scratch:SI 3 ""))])]
1686 "TARGET_32BIT && arm_arch3m"
1690 (define_insn "*umulsi3_highpart_nov6"
1691 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1695 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1696 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1698 (clobber (match_scratch:SI 3 "=&r,&r"))]
1699 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1700 "umull%?\\t%3, %0, %2, %1"
1701 [(set_attr "type" "umull")
1702 (set_attr "predicable" "yes")]
1705 (define_insn "*umulsi3_highpart_v6"
1706 [(set (match_operand:SI 0 "s_register_operand" "=r")
1710 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1711 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1713 (clobber (match_scratch:SI 3 "=r"))]
1714 "TARGET_32BIT && arm_arch6"
1715 "umull%?\\t%3, %0, %2, %1"
1716 [(set_attr "type" "umull")
1717 (set_attr "predicable" "yes")
1718 (set_attr "predicable_short_it" "no")]
1721 (define_insn "mulhisi3"
1722 [(set (match_operand:SI 0 "s_register_operand" "=r")
1723 (mult:SI (sign_extend:SI
1724 (match_operand:HI 1 "s_register_operand" "%r"))
1726 (match_operand:HI 2 "s_register_operand" "r"))))]
1727 "TARGET_DSP_MULTIPLY"
1728 "smulbb%?\\t%0, %1, %2"
1729 [(set_attr "type" "smulxy")
1730 (set_attr "predicable" "yes")]
1733 (define_insn "*mulhisi3tb"
1734 [(set (match_operand:SI 0 "s_register_operand" "=r")
1735 (mult:SI (ashiftrt:SI
1736 (match_operand:SI 1 "s_register_operand" "r")
1739 (match_operand:HI 2 "s_register_operand" "r"))))]
1740 "TARGET_DSP_MULTIPLY"
1741 "smultb%?\\t%0, %1, %2"
1742 [(set_attr "type" "smulxy")
1743 (set_attr "predicable" "yes")
1744 (set_attr "predicable_short_it" "no")]
1747 (define_insn "*mulhisi3bt"
1748 [(set (match_operand:SI 0 "s_register_operand" "=r")
1749 (mult:SI (sign_extend:SI
1750 (match_operand:HI 1 "s_register_operand" "r"))
1752 (match_operand:SI 2 "s_register_operand" "r")
1754 "TARGET_DSP_MULTIPLY"
1755 "smulbt%?\\t%0, %1, %2"
1756 [(set_attr "type" "smulxy")
1757 (set_attr "predicable" "yes")
1758 (set_attr "predicable_short_it" "no")]
1761 (define_insn "*mulhisi3tt"
1762 [(set (match_operand:SI 0 "s_register_operand" "=r")
1763 (mult:SI (ashiftrt:SI
1764 (match_operand:SI 1 "s_register_operand" "r")
1767 (match_operand:SI 2 "s_register_operand" "r")
1769 "TARGET_DSP_MULTIPLY"
1770 "smultt%?\\t%0, %1, %2"
1771 [(set_attr "type" "smulxy")
1772 (set_attr "predicable" "yes")
1773 (set_attr "predicable_short_it" "no")]
1776 (define_insn "maddhisi4"
1777 [(set (match_operand:SI 0 "s_register_operand" "=r")
1778 (plus:SI (mult:SI (sign_extend:SI
1779 (match_operand:HI 1 "s_register_operand" "r"))
1781 (match_operand:HI 2 "s_register_operand" "r")))
1782 (match_operand:SI 3 "s_register_operand" "r")))]
1783 "TARGET_DSP_MULTIPLY"
1784 "smlabb%?\\t%0, %1, %2, %3"
1785 [(set_attr "type" "smlaxy")
1786 (set_attr "predicable" "yes")
1787 (set_attr "predicable_short_it" "no")]
1790 ;; Note: there is no maddhisi4ibt because this one is canonical form
1791 (define_insn "*maddhisi4tb"
1792 [(set (match_operand:SI 0 "s_register_operand" "=r")
1793 (plus:SI (mult:SI (ashiftrt:SI
1794 (match_operand:SI 1 "s_register_operand" "r")
1797 (match_operand:HI 2 "s_register_operand" "r")))
1798 (match_operand:SI 3 "s_register_operand" "r")))]
1799 "TARGET_DSP_MULTIPLY"
1800 "smlatb%?\\t%0, %1, %2, %3"
1801 [(set_attr "type" "smlaxy")
1802 (set_attr "predicable" "yes")
1803 (set_attr "predicable_short_it" "no")]
1806 (define_insn "*maddhisi4tt"
1807 [(set (match_operand:SI 0 "s_register_operand" "=r")
1808 (plus:SI (mult:SI (ashiftrt:SI
1809 (match_operand:SI 1 "s_register_operand" "r")
1812 (match_operand:SI 2 "s_register_operand" "r")
1814 (match_operand:SI 3 "s_register_operand" "r")))]
1815 "TARGET_DSP_MULTIPLY"
1816 "smlatt%?\\t%0, %1, %2, %3"
1817 [(set_attr "type" "smlaxy")
1818 (set_attr "predicable" "yes")
1819 (set_attr "predicable_short_it" "no")]
1822 (define_insn "maddhidi4"
1823 [(set (match_operand:DI 0 "s_register_operand" "=r")
1825 (mult:DI (sign_extend:DI
1826 (match_operand:HI 1 "s_register_operand" "r"))
1828 (match_operand:HI 2 "s_register_operand" "r")))
1829 (match_operand:DI 3 "s_register_operand" "0")))]
1830 "TARGET_DSP_MULTIPLY"
1831 "smlalbb%?\\t%Q0, %R0, %1, %2"
1832 [(set_attr "type" "smlalxy")
1833 (set_attr "predicable" "yes")
1834 (set_attr "predicable_short_it" "no")])
1836 ;; Note: there is no maddhidi4ibt because this one is canonical form
1837 (define_insn "*maddhidi4tb"
1838 [(set (match_operand:DI 0 "s_register_operand" "=r")
1840 (mult:DI (sign_extend:DI
1842 (match_operand:SI 1 "s_register_operand" "r")
1845 (match_operand:HI 2 "s_register_operand" "r")))
1846 (match_operand:DI 3 "s_register_operand" "0")))]
1847 "TARGET_DSP_MULTIPLY"
1848 "smlaltb%?\\t%Q0, %R0, %1, %2"
1849 [(set_attr "type" "smlalxy")
1850 (set_attr "predicable" "yes")
1851 (set_attr "predicable_short_it" "no")])
1853 (define_insn "*maddhidi4tt"
1854 [(set (match_operand:DI 0 "s_register_operand" "=r")
1856 (mult:DI (sign_extend:DI
1858 (match_operand:SI 1 "s_register_operand" "r")
1862 (match_operand:SI 2 "s_register_operand" "r")
1864 (match_operand:DI 3 "s_register_operand" "0")))]
1865 "TARGET_DSP_MULTIPLY"
1866 "smlaltt%?\\t%Q0, %R0, %1, %2"
1867 [(set_attr "type" "smlalxy")
1868 (set_attr "predicable" "yes")
1869 (set_attr "predicable_short_it" "no")])
1871 (define_expand "mulsf3"
1872 [(set (match_operand:SF 0 "s_register_operand" "")
1873 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1874 (match_operand:SF 2 "s_register_operand" "")))]
1875 "TARGET_32BIT && TARGET_HARD_FLOAT"
1879 (define_expand "muldf3"
1880 [(set (match_operand:DF 0 "s_register_operand" "")
1881 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1882 (match_operand:DF 2 "s_register_operand" "")))]
1883 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1889 (define_expand "divsf3"
1890 [(set (match_operand:SF 0 "s_register_operand" "")
1891 (div:SF (match_operand:SF 1 "s_register_operand" "")
1892 (match_operand:SF 2 "s_register_operand" "")))]
1893 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1896 (define_expand "divdf3"
1897 [(set (match_operand:DF 0 "s_register_operand" "")
1898 (div:DF (match_operand:DF 1 "s_register_operand" "")
1899 (match_operand:DF 2 "s_register_operand" "")))]
1900 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1903 ;; Boolean and,ior,xor insns
1905 ;; Split up double word logical operations
1907 ;; Split up simple DImode logical operations. Simply perform the logical
1908 ;; operation on the upper and lower halves of the registers.
1910 [(set (match_operand:DI 0 "s_register_operand" "")
1911 (match_operator:DI 6 "logical_binary_operator"
1912 [(match_operand:DI 1 "s_register_operand" "")
1913 (match_operand:DI 2 "s_register_operand" "")]))]
1914 "TARGET_32BIT && reload_completed
1915 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1916 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1917 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1918 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1921 operands[3] = gen_highpart (SImode, operands[0]);
1922 operands[0] = gen_lowpart (SImode, operands[0]);
1923 operands[4] = gen_highpart (SImode, operands[1]);
1924 operands[1] = gen_lowpart (SImode, operands[1]);
1925 operands[5] = gen_highpart (SImode, operands[2]);
1926 operands[2] = gen_lowpart (SImode, operands[2]);
1931 [(set (match_operand:DI 0 "s_register_operand" "")
1932 (match_operator:DI 6 "logical_binary_operator"
1933 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1934 (match_operand:DI 1 "s_register_operand" "")]))]
1935 "TARGET_32BIT && reload_completed"
1936 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1937 (set (match_dup 3) (match_op_dup:SI 6
1938 [(ashiftrt:SI (match_dup 2) (const_int 31))
1942 operands[3] = gen_highpart (SImode, operands[0]);
1943 operands[0] = gen_lowpart (SImode, operands[0]);
1944 operands[4] = gen_highpart (SImode, operands[1]);
1945 operands[1] = gen_lowpart (SImode, operands[1]);
1946 operands[5] = gen_highpart (SImode, operands[2]);
1947 operands[2] = gen_lowpart (SImode, operands[2]);
1951 ;; The zero extend of operand 2 means we can just copy the high part of
1952 ;; operand1 into operand0.
1954 [(set (match_operand:DI 0 "s_register_operand" "")
1956 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1957 (match_operand:DI 1 "s_register_operand" "")))]
1958 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1959 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1960 (set (match_dup 3) (match_dup 4))]
1963 operands[4] = gen_highpart (SImode, operands[1]);
1964 operands[3] = gen_highpart (SImode, operands[0]);
1965 operands[0] = gen_lowpart (SImode, operands[0]);
1966 operands[1] = gen_lowpart (SImode, operands[1]);
1970 ;; The zero extend of operand 2 means we can just copy the high part of
1971 ;; operand1 into operand0.
1973 [(set (match_operand:DI 0 "s_register_operand" "")
1975 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1976 (match_operand:DI 1 "s_register_operand" "")))]
1977 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1978 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1979 (set (match_dup 3) (match_dup 4))]
1982 operands[4] = gen_highpart (SImode, operands[1]);
1983 operands[3] = gen_highpart (SImode, operands[0]);
1984 operands[0] = gen_lowpart (SImode, operands[0]);
1985 operands[1] = gen_lowpart (SImode, operands[1]);
1989 (define_expand "anddi3"
1990 [(set (match_operand:DI 0 "s_register_operand" "")
1991 (and:DI (match_operand:DI 1 "s_register_operand" "")
1992 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
1997 (define_insn_and_split "*anddi3_insn"
1998 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
1999 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2000 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2001 "TARGET_32BIT && !TARGET_IWMMXT"
2003 switch (which_alternative)
2005 case 0: /* fall through */
2006 case 6: return "vand\t%P0, %P1, %P2";
2007 case 1: /* fall through */
2008 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2009 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2013 case 5: /* fall through */
2015 default: gcc_unreachable ();
2018 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2019 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2020 [(set (match_dup 3) (match_dup 4))
2021 (set (match_dup 5) (match_dup 6))]
2024 operands[3] = gen_lowpart (SImode, operands[0]);
2025 operands[5] = gen_highpart (SImode, operands[0]);
2027 operands[4] = simplify_gen_binary (AND, SImode,
2028 gen_lowpart (SImode, operands[1]),
2029 gen_lowpart (SImode, operands[2]));
2030 operands[6] = simplify_gen_binary (AND, SImode,
2031 gen_highpart (SImode, operands[1]),
2032 gen_highpart_mode (SImode, DImode, operands[2]));
2035 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2036 multiple,multiple,neon_logic,neon_logic")
2037 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2038 avoid_neon_for_64bits,avoid_neon_for_64bits")
2039 (set_attr "length" "*,*,8,8,8,8,*,*")
2043 (define_insn_and_split "*anddi_zesidi_di"
2044 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2045 (and:DI (zero_extend:DI
2046 (match_operand:SI 2 "s_register_operand" "r,r"))
2047 (match_operand:DI 1 "s_register_operand" "0,r")))]
2050 "TARGET_32BIT && reload_completed"
2051 ; The zero extend of operand 2 clears the high word of the output
2053 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2054 (set (match_dup 3) (const_int 0))]
2057 operands[3] = gen_highpart (SImode, operands[0]);
2058 operands[0] = gen_lowpart (SImode, operands[0]);
2059 operands[1] = gen_lowpart (SImode, operands[1]);
2061 [(set_attr "length" "8")
2062 (set_attr "type" "multiple")]
2065 (define_insn "*anddi_sesdi_di"
2066 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2067 (and:DI (sign_extend:DI
2068 (match_operand:SI 2 "s_register_operand" "r,r"))
2069 (match_operand:DI 1 "s_register_operand" "0,r")))]
2072 [(set_attr "length" "8")
2073 (set_attr "type" "multiple")]
2076 (define_expand "andsi3"
2077 [(set (match_operand:SI 0 "s_register_operand" "")
2078 (and:SI (match_operand:SI 1 "s_register_operand" "")
2079 (match_operand:SI 2 "reg_or_int_operand" "")))]
2084 if (CONST_INT_P (operands[2]))
2086 if (INTVAL (operands[2]) == 255 && arm_arch6)
2088 operands[1] = convert_to_mode (QImode, operands[1], 1);
2089 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2093 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2094 operands[2] = force_reg (SImode, operands[2]);
2097 arm_split_constant (AND, SImode, NULL_RTX,
2098 INTVAL (operands[2]), operands[0],
2100 optimize && can_create_pseudo_p ());
2106 else /* TARGET_THUMB1 */
2108 if (!CONST_INT_P (operands[2]))
2110 rtx tmp = force_reg (SImode, operands[2]);
2111 if (rtx_equal_p (operands[0], operands[1]))
2115 operands[2] = operands[1];
2123 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2125 operands[2] = force_reg (SImode,
2126 GEN_INT (~INTVAL (operands[2])));
2128 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2133 for (i = 9; i <= 31; i++)
2135 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2137 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2141 else if ((((HOST_WIDE_INT) 1) << i) - 1
2142 == ~INTVAL (operands[2]))
2144 rtx shift = GEN_INT (i);
2145 rtx reg = gen_reg_rtx (SImode);
2147 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2148 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2154 operands[2] = force_reg (SImode, operands[2]);
2160 ; ??? Check split length for Thumb-2
2161 (define_insn_and_split "*arm_andsi3_insn"
2162 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2163 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2164 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2169 bic%?\\t%0, %1, #%B2
2173 && CONST_INT_P (operands[2])
2174 && !(const_ok_for_arm (INTVAL (operands[2]))
2175 || const_ok_for_arm (~INTVAL (operands[2])))"
2176 [(clobber (const_int 0))]
2178 arm_split_constant (AND, SImode, curr_insn,
2179 INTVAL (operands[2]), operands[0], operands[1], 0);
2182 [(set_attr "length" "4,4,4,4,16")
2183 (set_attr "predicable" "yes")
2184 (set_attr "predicable_short_it" "no,yes,no,no,no")
2185 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2188 (define_insn "*andsi3_compare0"
2189 [(set (reg:CC_NOOV CC_REGNUM)
2191 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2192 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2194 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2195 (and:SI (match_dup 1) (match_dup 2)))]
2199 bic%.\\t%0, %1, #%B2
2201 [(set_attr "conds" "set")
2202 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2205 (define_insn "*andsi3_compare0_scratch"
2206 [(set (reg:CC_NOOV CC_REGNUM)
2208 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2209 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2211 (clobber (match_scratch:SI 2 "=X,r,X"))]
2215 bic%.\\t%2, %0, #%B1
2217 [(set_attr "conds" "set")
2218 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2221 (define_insn "*zeroextractsi_compare0_scratch"
2222 [(set (reg:CC_NOOV CC_REGNUM)
2223 (compare:CC_NOOV (zero_extract:SI
2224 (match_operand:SI 0 "s_register_operand" "r")
2225 (match_operand 1 "const_int_operand" "n")
2226 (match_operand 2 "const_int_operand" "n"))
2229 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2230 && INTVAL (operands[1]) > 0
2231 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2232 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2234 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2235 << INTVAL (operands[2]));
2236 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2239 [(set_attr "conds" "set")
2240 (set_attr "predicable" "yes")
2241 (set_attr "predicable_short_it" "no")
2242 (set_attr "type" "logics_imm")]
2245 (define_insn_and_split "*ne_zeroextractsi"
2246 [(set (match_operand:SI 0 "s_register_operand" "=r")
2247 (ne:SI (zero_extract:SI
2248 (match_operand:SI 1 "s_register_operand" "r")
2249 (match_operand:SI 2 "const_int_operand" "n")
2250 (match_operand:SI 3 "const_int_operand" "n"))
2252 (clobber (reg:CC CC_REGNUM))]
2254 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2255 && INTVAL (operands[2]) > 0
2256 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2257 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2260 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2261 && INTVAL (operands[2]) > 0
2262 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2263 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2264 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2265 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2267 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2269 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2270 (match_dup 0) (const_int 1)))]
2272 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2273 << INTVAL (operands[3]));
2275 [(set_attr "conds" "clob")
2276 (set (attr "length")
2277 (if_then_else (eq_attr "is_thumb" "yes")
2280 (set_attr "type" "multiple")]
2283 (define_insn_and_split "*ne_zeroextractsi_shifted"
2284 [(set (match_operand:SI 0 "s_register_operand" "=r")
2285 (ne:SI (zero_extract:SI
2286 (match_operand:SI 1 "s_register_operand" "r")
2287 (match_operand:SI 2 "const_int_operand" "n")
2290 (clobber (reg:CC CC_REGNUM))]
2294 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2295 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2297 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2299 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2300 (match_dup 0) (const_int 1)))]
2302 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2304 [(set_attr "conds" "clob")
2305 (set_attr "length" "8")
2306 (set_attr "type" "multiple")]
2309 (define_insn_and_split "*ite_ne_zeroextractsi"
2310 [(set (match_operand:SI 0 "s_register_operand" "=r")
2311 (if_then_else:SI (ne (zero_extract:SI
2312 (match_operand:SI 1 "s_register_operand" "r")
2313 (match_operand:SI 2 "const_int_operand" "n")
2314 (match_operand:SI 3 "const_int_operand" "n"))
2316 (match_operand:SI 4 "arm_not_operand" "rIK")
2318 (clobber (reg:CC CC_REGNUM))]
2320 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2321 && INTVAL (operands[2]) > 0
2322 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2323 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2324 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2327 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2328 && INTVAL (operands[2]) > 0
2329 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2330 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2331 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2332 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2333 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2335 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2337 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2338 (match_dup 0) (match_dup 4)))]
2340 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2341 << INTVAL (operands[3]));
2343 [(set_attr "conds" "clob")
2344 (set_attr "length" "8")
2345 (set_attr "type" "multiple")]
2348 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2349 [(set (match_operand:SI 0 "s_register_operand" "=r")
2350 (if_then_else:SI (ne (zero_extract:SI
2351 (match_operand:SI 1 "s_register_operand" "r")
2352 (match_operand:SI 2 "const_int_operand" "n")
2355 (match_operand:SI 3 "arm_not_operand" "rIK")
2357 (clobber (reg:CC CC_REGNUM))]
2358 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2360 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2361 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2362 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2364 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2366 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2367 (match_dup 0) (match_dup 3)))]
2369 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2371 [(set_attr "conds" "clob")
2372 (set_attr "length" "8")
2373 (set_attr "type" "multiple")]
2376 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2378 [(set (match_operand:SI 0 "s_register_operand" "")
2379 (match_operator:SI 1 "shiftable_operator"
2380 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2381 (match_operand:SI 3 "const_int_operand" "")
2382 (match_operand:SI 4 "const_int_operand" ""))
2383 (match_operand:SI 5 "s_register_operand" "")]))
2384 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2386 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2389 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2392 HOST_WIDE_INT temp = INTVAL (operands[3]);
2394 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2395 operands[4] = GEN_INT (32 - temp);
2400 [(set (match_operand:SI 0 "s_register_operand" "")
2401 (match_operator:SI 1 "shiftable_operator"
2402 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2403 (match_operand:SI 3 "const_int_operand" "")
2404 (match_operand:SI 4 "const_int_operand" ""))
2405 (match_operand:SI 5 "s_register_operand" "")]))
2406 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2408 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2411 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2414 HOST_WIDE_INT temp = INTVAL (operands[3]);
2416 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2417 operands[4] = GEN_INT (32 - temp);
2421 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2422 ;;; represented by the bitfield, then this will produce incorrect results.
2423 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2424 ;;; which have a real bit-field insert instruction, the truncation happens
2425 ;;; in the bit-field insert instruction itself. Since arm does not have a
2426 ;;; bit-field insert instruction, we would have to emit code here to truncate
2427 ;;; the value before we insert. This loses some of the advantage of having
2428 ;;; this insv pattern, so this pattern needs to be reevalutated.
2430 (define_expand "insv"
2431 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2432 (match_operand 1 "general_operand" "")
2433 (match_operand 2 "general_operand" ""))
2434 (match_operand 3 "reg_or_int_operand" ""))]
2435 "TARGET_ARM || arm_arch_thumb2"
2438 int start_bit = INTVAL (operands[2]);
2439 int width = INTVAL (operands[1]);
2440 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2441 rtx target, subtarget;
2443 if (arm_arch_thumb2)
2445 if (unaligned_access && MEM_P (operands[0])
2446 && s_register_operand (operands[3], GET_MODE (operands[3]))
2447 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2451 if (BYTES_BIG_ENDIAN)
2452 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2457 base_addr = adjust_address (operands[0], SImode,
2458 start_bit / BITS_PER_UNIT);
2459 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2463 rtx tmp = gen_reg_rtx (HImode);
2465 base_addr = adjust_address (operands[0], HImode,
2466 start_bit / BITS_PER_UNIT);
2467 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2468 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2472 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2474 bool use_bfi = TRUE;
2476 if (CONST_INT_P (operands[3]))
2478 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2482 emit_insn (gen_insv_zero (operands[0], operands[1],
2487 /* See if the set can be done with a single orr instruction. */
2488 if (val == mask && const_ok_for_arm (val << start_bit))
2494 if (!REG_P (operands[3]))
2495 operands[3] = force_reg (SImode, operands[3]);
2497 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2506 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2509 target = copy_rtx (operands[0]);
2510 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2511 subreg as the final target. */
2512 if (GET_CODE (target) == SUBREG)
2514 subtarget = gen_reg_rtx (SImode);
2515 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2516 < GET_MODE_SIZE (SImode))
2517 target = SUBREG_REG (target);
2522 if (CONST_INT_P (operands[3]))
2524 /* Since we are inserting a known constant, we may be able to
2525 reduce the number of bits that we have to clear so that
2526 the mask becomes simple. */
2527 /* ??? This code does not check to see if the new mask is actually
2528 simpler. It may not be. */
2529 rtx op1 = gen_reg_rtx (SImode);
2530 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2531 start of this pattern. */
2532 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2533 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2535 emit_insn (gen_andsi3 (op1, operands[0],
2536 gen_int_mode (~mask2, SImode)));
2537 emit_insn (gen_iorsi3 (subtarget, op1,
2538 gen_int_mode (op3_value << start_bit, SImode)));
2540 else if (start_bit == 0
2541 && !(const_ok_for_arm (mask)
2542 || const_ok_for_arm (~mask)))
2544 /* A Trick, since we are setting the bottom bits in the word,
2545 we can shift operand[3] up, operand[0] down, OR them together
2546 and rotate the result back again. This takes 3 insns, and
2547 the third might be mergeable into another op. */
2548 /* The shift up copes with the possibility that operand[3] is
2549 wider than the bitfield. */
2550 rtx op0 = gen_reg_rtx (SImode);
2551 rtx op1 = gen_reg_rtx (SImode);
2553 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2554 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2555 emit_insn (gen_iorsi3 (op1, op1, op0));
2556 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2558 else if ((width + start_bit == 32)
2559 && !(const_ok_for_arm (mask)
2560 || const_ok_for_arm (~mask)))
2562 /* Similar trick, but slightly less efficient. */
2564 rtx op0 = gen_reg_rtx (SImode);
2565 rtx op1 = gen_reg_rtx (SImode);
2567 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2568 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2569 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2570 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2574 rtx op0 = gen_int_mode (mask, SImode);
2575 rtx op1 = gen_reg_rtx (SImode);
2576 rtx op2 = gen_reg_rtx (SImode);
2578 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2580 rtx tmp = gen_reg_rtx (SImode);
2582 emit_insn (gen_movsi (tmp, op0));
2586 /* Mask out any bits in operand[3] that are not needed. */
2587 emit_insn (gen_andsi3 (op1, operands[3], op0));
2589 if (CONST_INT_P (op0)
2590 && (const_ok_for_arm (mask << start_bit)
2591 || const_ok_for_arm (~(mask << start_bit))))
2593 op0 = gen_int_mode (~(mask << start_bit), SImode);
2594 emit_insn (gen_andsi3 (op2, operands[0], op0));
2598 if (CONST_INT_P (op0))
2600 rtx tmp = gen_reg_rtx (SImode);
2602 emit_insn (gen_movsi (tmp, op0));
2607 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2609 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2613 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2615 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2618 if (subtarget != target)
2620 /* If TARGET is still a SUBREG, then it must be wider than a word,
2621 so we must be careful only to set the subword we were asked to. */
2622 if (GET_CODE (target) == SUBREG)
2623 emit_move_insn (target, subtarget);
2625 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2632 (define_insn "insv_zero"
2633 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2634 (match_operand:SI 1 "const_int_M_operand" "M")
2635 (match_operand:SI 2 "const_int_M_operand" "M"))
2639 [(set_attr "length" "4")
2640 (set_attr "predicable" "yes")
2641 (set_attr "predicable_short_it" "no")
2642 (set_attr "type" "bfm")]
2645 (define_insn "insv_t2"
2646 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2647 (match_operand:SI 1 "const_int_M_operand" "M")
2648 (match_operand:SI 2 "const_int_M_operand" "M"))
2649 (match_operand:SI 3 "s_register_operand" "r"))]
2651 "bfi%?\t%0, %3, %2, %1"
2652 [(set_attr "length" "4")
2653 (set_attr "predicable" "yes")
2654 (set_attr "predicable_short_it" "no")
2655 (set_attr "type" "bfm")]
2658 ; constants for op 2 will never be given to these patterns.
2659 (define_insn_and_split "*anddi_notdi_di"
2660 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2661 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2662 (match_operand:DI 2 "s_register_operand" "r,0")))]
2665 "TARGET_32BIT && reload_completed
2666 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2667 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2668 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2669 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2672 operands[3] = gen_highpart (SImode, operands[0]);
2673 operands[0] = gen_lowpart (SImode, operands[0]);
2674 operands[4] = gen_highpart (SImode, operands[1]);
2675 operands[1] = gen_lowpart (SImode, operands[1]);
2676 operands[5] = gen_highpart (SImode, operands[2]);
2677 operands[2] = gen_lowpart (SImode, operands[2]);
2679 [(set_attr "length" "8")
2680 (set_attr "predicable" "yes")
2681 (set_attr "type" "multiple")]
2684 (define_insn_and_split "*anddi_notzesidi_di"
2685 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2686 (and:DI (not:DI (zero_extend:DI
2687 (match_operand:SI 2 "s_register_operand" "r,r")))
2688 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2691 bic%?\\t%Q0, %Q1, %2
2693 ; (not (zero_extend ...)) allows us to just copy the high word from
2694 ; operand1 to operand0.
2697 && operands[0] != operands[1]"
2698 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2699 (set (match_dup 3) (match_dup 4))]
2702 operands[3] = gen_highpart (SImode, operands[0]);
2703 operands[0] = gen_lowpart (SImode, operands[0]);
2704 operands[4] = gen_highpart (SImode, operands[1]);
2705 operands[1] = gen_lowpart (SImode, operands[1]);
2707 [(set_attr "length" "4,8")
2708 (set_attr "predicable" "yes")
2709 (set_attr "predicable_short_it" "no")
2710 (set_attr "type" "multiple")]
2713 (define_insn_and_split "*anddi_notdi_zesidi"
2714 [(set (match_operand:DI 0 "s_register_operand" "=r")
2715 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2717 (match_operand:SI 1 "s_register_operand" "r"))))]
2720 "TARGET_32BIT && reload_completed"
2721 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2722 (set (match_dup 3) (const_int 0))]
2725 operands[3] = gen_highpart (SImode, operands[0]);
2726 operands[0] = gen_lowpart (SImode, operands[0]);
2727 operands[2] = gen_lowpart (SImode, operands[2]);
2729 [(set_attr "length" "8")
2730 (set_attr "predicable" "yes")
2731 (set_attr "predicable_short_it" "no")
2732 (set_attr "type" "multiple")]
2735 (define_insn_and_split "*anddi_notsesidi_di"
2736 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2737 (and:DI (not:DI (sign_extend:DI
2738 (match_operand:SI 2 "s_register_operand" "r,r")))
2739 (match_operand:DI 1 "s_register_operand" "0,r")))]
2742 "TARGET_32BIT && reload_completed"
2743 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2744 (set (match_dup 3) (and:SI (not:SI
2745 (ashiftrt:SI (match_dup 2) (const_int 31)))
2749 operands[3] = gen_highpart (SImode, operands[0]);
2750 operands[0] = gen_lowpart (SImode, operands[0]);
2751 operands[4] = gen_highpart (SImode, operands[1]);
2752 operands[1] = gen_lowpart (SImode, operands[1]);
2754 [(set_attr "length" "8")
2755 (set_attr "predicable" "yes")
2756 (set_attr "predicable_short_it" "no")
2757 (set_attr "type" "multiple")]
2760 (define_insn "andsi_notsi_si"
2761 [(set (match_operand:SI 0 "s_register_operand" "=r")
2762 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2763 (match_operand:SI 1 "s_register_operand" "r")))]
2765 "bic%?\\t%0, %1, %2"
2766 [(set_attr "predicable" "yes")
2767 (set_attr "predicable_short_it" "no")
2768 (set_attr "type" "logic_reg")]
2771 (define_insn "andsi_not_shiftsi_si"
2772 [(set (match_operand:SI 0 "s_register_operand" "=r")
2773 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2774 [(match_operand:SI 2 "s_register_operand" "r")
2775 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2776 (match_operand:SI 1 "s_register_operand" "r")))]
2778 "bic%?\\t%0, %1, %2%S4"
2779 [(set_attr "predicable" "yes")
2780 (set_attr "shift" "2")
2781 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2782 (const_string "logic_shift_imm")
2783 (const_string "logic_shift_reg")))]
2786 ;; Shifted bics pattern used to set up CC status register and not reusing
2787 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
2788 ;; does not support shift by register.
2789 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
2790 [(set (reg:CC_NOOV CC_REGNUM)
2792 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2793 [(match_operand:SI 1 "s_register_operand" "r")
2794 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2795 (match_operand:SI 3 "s_register_operand" "r"))
2797 (clobber (match_scratch:SI 4 "=r"))]
2798 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2799 "bic%.%?\\t%4, %3, %1%S0"
2800 [(set_attr "predicable" "yes")
2801 (set_attr "predicable_short_it" "no")
2802 (set_attr "conds" "set")
2803 (set_attr "shift" "1")
2804 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2805 (const_string "logic_shift_imm")
2806 (const_string "logic_shift_reg")))]
2809 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
2810 ;; getting reused later.
2811 (define_insn "andsi_not_shiftsi_si_scc"
2812 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2814 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2815 [(match_operand:SI 1 "s_register_operand" "r")
2816 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2817 (match_operand:SI 3 "s_register_operand" "r"))
2819 (set (match_operand:SI 4 "s_register_operand" "=r")
2820 (and:SI (not:SI (match_op_dup 0
2824 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2825 "bic%.%?\\t%4, %3, %1%S0"
2826 [(set_attr "predicable" "yes")
2827 (set_attr "predicable_short_it" "no")
2828 (set_attr "conds" "set")
2829 (set_attr "shift" "1")
2830 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2831 (const_string "logic_shift_imm")
2832 (const_string "logic_shift_reg")))]
2835 (define_insn "*andsi_notsi_si_compare0"
2836 [(set (reg:CC_NOOV CC_REGNUM)
2838 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2839 (match_operand:SI 1 "s_register_operand" "r"))
2841 (set (match_operand:SI 0 "s_register_operand" "=r")
2842 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2844 "bic%.\\t%0, %1, %2"
2845 [(set_attr "conds" "set")
2846 (set_attr "type" "logics_shift_reg")]
2849 (define_insn "*andsi_notsi_si_compare0_scratch"
2850 [(set (reg:CC_NOOV CC_REGNUM)
2852 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2853 (match_operand:SI 1 "s_register_operand" "r"))
2855 (clobber (match_scratch:SI 0 "=r"))]
2857 "bic%.\\t%0, %1, %2"
2858 [(set_attr "conds" "set")
2859 (set_attr "type" "logics_shift_reg")]
2862 (define_expand "iordi3"
2863 [(set (match_operand:DI 0 "s_register_operand" "")
2864 (ior:DI (match_operand:DI 1 "s_register_operand" "")
2865 (match_operand:DI 2 "neon_logic_op2" "")))]
2870 (define_insn_and_split "*iordi3_insn"
2871 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2872 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2873 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
2874 "TARGET_32BIT && !TARGET_IWMMXT"
2876 switch (which_alternative)
2878 case 0: /* fall through */
2879 case 6: return "vorr\t%P0, %P1, %P2";
2880 case 1: /* fall through */
2881 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2882 DImode, 0, VALID_NEON_QREG_MODE (DImode));
2888 default: gcc_unreachable ();
2891 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2892 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2893 [(set (match_dup 3) (match_dup 4))
2894 (set (match_dup 5) (match_dup 6))]
2897 operands[3] = gen_lowpart (SImode, operands[0]);
2898 operands[5] = gen_highpart (SImode, operands[0]);
2900 operands[4] = simplify_gen_binary (IOR, SImode,
2901 gen_lowpart (SImode, operands[1]),
2902 gen_lowpart (SImode, operands[2]));
2903 operands[6] = simplify_gen_binary (IOR, SImode,
2904 gen_highpart (SImode, operands[1]),
2905 gen_highpart_mode (SImode, DImode, operands[2]));
2908 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2909 multiple,neon_logic,neon_logic")
2910 (set_attr "length" "*,*,8,8,8,8,*,*")
2911 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
2914 (define_insn "*iordi_zesidi_di"
2915 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2916 (ior:DI (zero_extend:DI
2917 (match_operand:SI 2 "s_register_operand" "r,r"))
2918 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2921 orr%?\\t%Q0, %Q1, %2
2923 [(set_attr "length" "4,8")
2924 (set_attr "predicable" "yes")
2925 (set_attr "predicable_short_it" "no")
2926 (set_attr "type" "logic_reg,multiple")]
2929 (define_insn "*iordi_sesidi_di"
2930 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2931 (ior:DI (sign_extend:DI
2932 (match_operand:SI 2 "s_register_operand" "r,r"))
2933 (match_operand:DI 1 "s_register_operand" "0,r")))]
2936 [(set_attr "length" "8")
2937 (set_attr "predicable" "yes")
2938 (set_attr "type" "multiple")]
2941 (define_expand "iorsi3"
2942 [(set (match_operand:SI 0 "s_register_operand" "")
2943 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2944 (match_operand:SI 2 "reg_or_int_operand" "")))]
2947 if (CONST_INT_P (operands[2]))
2951 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
2952 operands[2] = force_reg (SImode, operands[2]);
2955 arm_split_constant (IOR, SImode, NULL_RTX,
2956 INTVAL (operands[2]), operands[0],
2958 optimize && can_create_pseudo_p ());
2962 else /* TARGET_THUMB1 */
2964 rtx tmp = force_reg (SImode, operands[2]);
2965 if (rtx_equal_p (operands[0], operands[1]))
2969 operands[2] = operands[1];
2977 (define_insn_and_split "*iorsi3_insn"
2978 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2979 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2980 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2985 orn%?\\t%0, %1, #%B2
2989 && CONST_INT_P (operands[2])
2990 && !(const_ok_for_arm (INTVAL (operands[2]))
2991 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
2992 [(clobber (const_int 0))]
2994 arm_split_constant (IOR, SImode, curr_insn,
2995 INTVAL (operands[2]), operands[0], operands[1], 0);
2998 [(set_attr "length" "4,4,4,4,16")
2999 (set_attr "arch" "32,t2,t2,32,32")
3000 (set_attr "predicable" "yes")
3001 (set_attr "predicable_short_it" "no,yes,no,no,no")
3002 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3006 [(match_scratch:SI 3 "r")
3007 (set (match_operand:SI 0 "arm_general_register_operand" "")
3008 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3009 (match_operand:SI 2 "const_int_operand" "")))]
3011 && !const_ok_for_arm (INTVAL (operands[2]))
3012 && const_ok_for_arm (~INTVAL (operands[2]))"
3013 [(set (match_dup 3) (match_dup 2))
3014 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3018 (define_insn "*iorsi3_compare0"
3019 [(set (reg:CC_NOOV CC_REGNUM)
3020 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3021 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3023 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3024 (ior:SI (match_dup 1) (match_dup 2)))]
3026 "orr%.\\t%0, %1, %2"
3027 [(set_attr "conds" "set")
3028 (set_attr "type" "logics_imm,logics_reg")]
3031 (define_insn "*iorsi3_compare0_scratch"
3032 [(set (reg:CC_NOOV CC_REGNUM)
3033 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3034 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3036 (clobber (match_scratch:SI 0 "=r,r"))]
3038 "orr%.\\t%0, %1, %2"
3039 [(set_attr "conds" "set")
3040 (set_attr "type" "logics_imm,logics_reg")]
3043 (define_expand "xordi3"
3044 [(set (match_operand:DI 0 "s_register_operand" "")
3045 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3046 (match_operand:DI 2 "arm_xordi_operand" "")))]
3051 (define_insn_and_split "*xordi3_insn"
3052 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3053 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3054 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3055 "TARGET_32BIT && !TARGET_IWMMXT"
3057 switch (which_alternative)
3062 case 4: /* fall through */
3064 case 0: /* fall through */
3065 case 5: return "veor\t%P0, %P1, %P2";
3066 default: gcc_unreachable ();
3069 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3070 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3071 [(set (match_dup 3) (match_dup 4))
3072 (set (match_dup 5) (match_dup 6))]
3075 operands[3] = gen_lowpart (SImode, operands[0]);
3076 operands[5] = gen_highpart (SImode, operands[0]);
3078 operands[4] = simplify_gen_binary (XOR, SImode,
3079 gen_lowpart (SImode, operands[1]),
3080 gen_lowpart (SImode, operands[2]));
3081 operands[6] = simplify_gen_binary (XOR, SImode,
3082 gen_highpart (SImode, operands[1]),
3083 gen_highpart_mode (SImode, DImode, operands[2]));
3086 [(set_attr "length" "*,8,8,8,8,*")
3087 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3088 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3091 (define_insn "*xordi_zesidi_di"
3092 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3093 (xor:DI (zero_extend:DI
3094 (match_operand:SI 2 "s_register_operand" "r,r"))
3095 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3098 eor%?\\t%Q0, %Q1, %2
3100 [(set_attr "length" "4,8")
3101 (set_attr "predicable" "yes")
3102 (set_attr "predicable_short_it" "no")
3103 (set_attr "type" "logic_reg")]
3106 (define_insn "*xordi_sesidi_di"
3107 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3108 (xor:DI (sign_extend:DI
3109 (match_operand:SI 2 "s_register_operand" "r,r"))
3110 (match_operand:DI 1 "s_register_operand" "0,r")))]
3113 [(set_attr "length" "8")
3114 (set_attr "predicable" "yes")
3115 (set_attr "type" "multiple")]
3118 (define_expand "xorsi3"
3119 [(set (match_operand:SI 0 "s_register_operand" "")
3120 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3121 (match_operand:SI 2 "reg_or_int_operand" "")))]
3123 "if (CONST_INT_P (operands[2]))
3127 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3128 operands[2] = force_reg (SImode, operands[2]);
3131 arm_split_constant (XOR, SImode, NULL_RTX,
3132 INTVAL (operands[2]), operands[0],
3134 optimize && can_create_pseudo_p ());
3138 else /* TARGET_THUMB1 */
3140 rtx tmp = force_reg (SImode, operands[2]);
3141 if (rtx_equal_p (operands[0], operands[1]))
3145 operands[2] = operands[1];
3152 (define_insn_and_split "*arm_xorsi3"
3153 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3154 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3155 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3163 && CONST_INT_P (operands[2])
3164 && !const_ok_for_arm (INTVAL (operands[2]))"
3165 [(clobber (const_int 0))]
3167 arm_split_constant (XOR, SImode, curr_insn,
3168 INTVAL (operands[2]), operands[0], operands[1], 0);
3171 [(set_attr "length" "4,4,4,16")
3172 (set_attr "predicable" "yes")
3173 (set_attr "predicable_short_it" "no,yes,no,no")
3174 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3177 (define_insn "*xorsi3_compare0"
3178 [(set (reg:CC_NOOV CC_REGNUM)
3179 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3180 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3182 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3183 (xor:SI (match_dup 1) (match_dup 2)))]
3185 "eor%.\\t%0, %1, %2"
3186 [(set_attr "conds" "set")
3187 (set_attr "type" "logics_imm,logics_reg")]
3190 (define_insn "*xorsi3_compare0_scratch"
3191 [(set (reg:CC_NOOV CC_REGNUM)
3192 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3193 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3197 [(set_attr "conds" "set")
3198 (set_attr "type" "logics_imm,logics_reg")]
3201 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3202 ; (NOT D) we can sometimes merge the final NOT into one of the following
3206 [(set (match_operand:SI 0 "s_register_operand" "")
3207 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3208 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3209 (match_operand:SI 3 "arm_rhs_operand" "")))
3210 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3212 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3213 (not:SI (match_dup 3))))
3214 (set (match_dup 0) (not:SI (match_dup 4)))]
3218 (define_insn_and_split "*andsi_iorsi3_notsi"
3219 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3220 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3221 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3222 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3224 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3225 "&& reload_completed"
3226 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3227 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3229 [(set_attr "length" "8")
3230 (set_attr "ce_count" "2")
3231 (set_attr "predicable" "yes")
3232 (set_attr "predicable_short_it" "no")
3233 (set_attr "type" "multiple")]
3236 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3237 ; insns are available?
3239 [(set (match_operand:SI 0 "s_register_operand" "")
3240 (match_operator:SI 1 "logical_binary_operator"
3241 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3242 (match_operand:SI 3 "const_int_operand" "")
3243 (match_operand:SI 4 "const_int_operand" ""))
3244 (match_operator:SI 9 "logical_binary_operator"
3245 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3246 (match_operand:SI 6 "const_int_operand" ""))
3247 (match_operand:SI 7 "s_register_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 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3261 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3265 [(set (match_operand:SI 0 "s_register_operand" "")
3266 (match_operator:SI 1 "logical_binary_operator"
3267 [(match_operator:SI 9 "logical_binary_operator"
3268 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3269 (match_operand:SI 6 "const_int_operand" ""))
3270 (match_operand:SI 7 "s_register_operand" "")])
3271 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3272 (match_operand:SI 3 "const_int_operand" "")
3273 (match_operand:SI 4 "const_int_operand" ""))]))
3274 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3276 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3277 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3280 [(ashift:SI (match_dup 2) (match_dup 4))
3284 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3287 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3291 [(set (match_operand:SI 0 "s_register_operand" "")
3292 (match_operator:SI 1 "logical_binary_operator"
3293 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3294 (match_operand:SI 3 "const_int_operand" "")
3295 (match_operand:SI 4 "const_int_operand" ""))
3296 (match_operator:SI 9 "logical_binary_operator"
3297 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3298 (match_operand:SI 6 "const_int_operand" ""))
3299 (match_operand:SI 7 "s_register_operand" "")])]))
3300 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3302 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3303 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3306 [(ashift:SI (match_dup 2) (match_dup 4))
3310 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3313 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3317 [(set (match_operand:SI 0 "s_register_operand" "")
3318 (match_operator:SI 1 "logical_binary_operator"
3319 [(match_operator:SI 9 "logical_binary_operator"
3320 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3321 (match_operand:SI 6 "const_int_operand" ""))
3322 (match_operand:SI 7 "s_register_operand" "")])
3323 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3324 (match_operand:SI 3 "const_int_operand" "")
3325 (match_operand:SI 4 "const_int_operand" ""))]))
3326 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3328 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3329 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3332 [(ashift:SI (match_dup 2) (match_dup 4))
3336 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3339 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3343 ;; Minimum and maximum insns
3345 (define_expand "smaxsi3"
3347 (set (match_operand:SI 0 "s_register_operand" "")
3348 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3349 (match_operand:SI 2 "arm_rhs_operand" "")))
3350 (clobber (reg:CC CC_REGNUM))])]
3353 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3355 /* No need for a clobber of the condition code register here. */
3356 emit_insn (gen_rtx_SET (operands[0],
3357 gen_rtx_SMAX (SImode, operands[1],
3363 (define_insn "*smax_0"
3364 [(set (match_operand:SI 0 "s_register_operand" "=r")
3365 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3368 "bic%?\\t%0, %1, %1, asr #31"
3369 [(set_attr "predicable" "yes")
3370 (set_attr "predicable_short_it" "no")
3371 (set_attr "type" "logic_shift_reg")]
3374 (define_insn "*smax_m1"
3375 [(set (match_operand:SI 0 "s_register_operand" "=r")
3376 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3379 "orr%?\\t%0, %1, %1, asr #31"
3380 [(set_attr "predicable" "yes")
3381 (set_attr "predicable_short_it" "no")
3382 (set_attr "type" "logic_shift_reg")]
3385 (define_insn_and_split "*arm_smax_insn"
3386 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3387 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3388 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3389 (clobber (reg:CC CC_REGNUM))]
3392 ; cmp\\t%1, %2\;movlt\\t%0, %2
3393 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3395 [(set (reg:CC CC_REGNUM)
3396 (compare:CC (match_dup 1) (match_dup 2)))
3398 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3402 [(set_attr "conds" "clob")
3403 (set_attr "length" "8,12")
3404 (set_attr "type" "multiple")]
3407 (define_expand "sminsi3"
3409 (set (match_operand:SI 0 "s_register_operand" "")
3410 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3411 (match_operand:SI 2 "arm_rhs_operand" "")))
3412 (clobber (reg:CC CC_REGNUM))])]
3415 if (operands[2] == const0_rtx)
3417 /* No need for a clobber of the condition code register here. */
3418 emit_insn (gen_rtx_SET (operands[0],
3419 gen_rtx_SMIN (SImode, operands[1],
3425 (define_insn "*smin_0"
3426 [(set (match_operand:SI 0 "s_register_operand" "=r")
3427 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3430 "and%?\\t%0, %1, %1, asr #31"
3431 [(set_attr "predicable" "yes")
3432 (set_attr "predicable_short_it" "no")
3433 (set_attr "type" "logic_shift_reg")]
3436 (define_insn_and_split "*arm_smin_insn"
3437 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3438 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3439 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3440 (clobber (reg:CC CC_REGNUM))]
3443 ; cmp\\t%1, %2\;movge\\t%0, %2
3444 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3446 [(set (reg:CC CC_REGNUM)
3447 (compare:CC (match_dup 1) (match_dup 2)))
3449 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3453 [(set_attr "conds" "clob")
3454 (set_attr "length" "8,12")
3455 (set_attr "type" "multiple,multiple")]
3458 ;; t = (s/u)min (x, y)
3464 (define_insn_and_split "*arm_smin_cmp"
3465 [(set (reg:CC CC_REGNUM)
3467 (smin:SI (match_operand:SI 0 "s_register_operand" "r")
3468 (match_operand:SI 1 "s_register_operand" "r"))
3469 (match_operand:SI 2 "s_register_operand" "r")))]
3472 "&& reload_completed"
3473 [(set (reg:CC CC_REGNUM)
3474 (compare:CC (match_dup 0) (match_dup 2)))
3475 (cond_exec (ge:CC (reg:CC CC_REGNUM) (const_int 0))
3476 (set (reg:CC CC_REGNUM)
3477 (compare:CC (match_dup 1) (match_dup 2))))]
3480 (define_insn_and_split "*arm_umin_cmp"
3481 [(set (reg:CC CC_REGNUM)
3483 (umin:SI (match_operand:SI 0 "s_register_operand" "r")
3484 (match_operand:SI 1 "s_register_operand" "r"))
3485 (match_operand:SI 2 "s_register_operand" "r")))]
3488 "&& reload_completed"
3489 [(set (reg:CC CC_REGNUM)
3490 (compare:CC (match_dup 0) (match_dup 2)))
3491 (cond_exec (geu:CC (reg:CC CC_REGNUM) (const_int 0))
3492 (set (reg:CC CC_REGNUM)
3493 (compare:CC (match_dup 1) (match_dup 2))))]
3496 (define_expand "umaxsi3"
3498 (set (match_operand:SI 0 "s_register_operand" "")
3499 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3500 (match_operand:SI 2 "arm_rhs_operand" "")))
3501 (clobber (reg:CC CC_REGNUM))])]
3506 (define_insn_and_split "*arm_umaxsi3"
3507 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3508 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3509 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3510 (clobber (reg:CC CC_REGNUM))]
3513 ; cmp\\t%1, %2\;movcc\\t%0, %2
3514 ; cmp\\t%1, %2\;movcs\\t%0, %1
3515 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3517 [(set (reg:CC CC_REGNUM)
3518 (compare:CC (match_dup 1) (match_dup 2)))
3520 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3524 [(set_attr "conds" "clob")
3525 (set_attr "length" "8,8,12")
3526 (set_attr "type" "store1")]
3529 (define_expand "uminsi3"
3531 (set (match_operand:SI 0 "s_register_operand" "")
3532 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3533 (match_operand:SI 2 "arm_rhs_operand" "")))
3534 (clobber (reg:CC CC_REGNUM))])]
3539 (define_insn_and_split "*arm_uminsi3"
3540 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3541 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3542 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3543 (clobber (reg:CC CC_REGNUM))]
3546 ; cmp\\t%1, %2\;movcs\\t%0, %2
3547 ; cmp\\t%1, %2\;movcc\\t%0, %1
3548 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3550 [(set (reg:CC CC_REGNUM)
3551 (compare:CC (match_dup 1) (match_dup 2)))
3553 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3557 [(set_attr "conds" "clob")
3558 (set_attr "length" "8,8,12")
3559 (set_attr "type" "store1")]
3562 (define_insn "*store_minmaxsi"
3563 [(set (match_operand:SI 0 "memory_operand" "=m")
3564 (match_operator:SI 3 "minmax_operator"
3565 [(match_operand:SI 1 "s_register_operand" "r")
3566 (match_operand:SI 2 "s_register_operand" "r")]))
3567 (clobber (reg:CC CC_REGNUM))]
3568 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3570 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3571 operands[1], operands[2]);
3572 output_asm_insn (\"cmp\\t%1, %2\", operands);
3574 output_asm_insn (\"ite\t%d3\", operands);
3575 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3576 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3579 [(set_attr "conds" "clob")
3580 (set (attr "length")
3581 (if_then_else (eq_attr "is_thumb" "yes")
3584 (set_attr "type" "store1")]
3587 ; Reject the frame pointer in operand[1], since reloading this after
3588 ; it has been eliminated can cause carnage.
3589 (define_insn "*minmax_arithsi"
3590 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3591 (match_operator:SI 4 "shiftable_operator"
3592 [(match_operator:SI 5 "minmax_operator"
3593 [(match_operand:SI 2 "s_register_operand" "r,r")
3594 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3595 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3596 (clobber (reg:CC CC_REGNUM))]
3597 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3600 enum rtx_code code = GET_CODE (operands[4]);
3603 if (which_alternative != 0 || operands[3] != const0_rtx
3604 || (code != PLUS && code != IOR && code != XOR))
3609 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3610 operands[2], operands[3]);
3611 output_asm_insn (\"cmp\\t%2, %3\", operands);
3615 output_asm_insn (\"ite\\t%d5\", operands);
3617 output_asm_insn (\"it\\t%d5\", operands);
3619 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3621 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3624 [(set_attr "conds" "clob")
3625 (set (attr "length")
3626 (if_then_else (eq_attr "is_thumb" "yes")
3629 (set_attr "type" "multiple")]
3632 ; Reject the frame pointer in operand[1], since reloading this after
3633 ; it has been eliminated can cause carnage.
3634 (define_insn_and_split "*minmax_arithsi_non_canon"
3635 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3637 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3638 (match_operator:SI 4 "minmax_operator"
3639 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3640 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3641 (clobber (reg:CC CC_REGNUM))]
3642 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3643 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3645 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3646 [(set (reg:CC CC_REGNUM)
3647 (compare:CC (match_dup 2) (match_dup 3)))
3649 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3651 (minus:SI (match_dup 1)
3653 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3657 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3658 operands[2], operands[3]);
3659 enum rtx_code rc = minmax_code (operands[4]);
3660 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3661 operands[2], operands[3]);
3663 if (mode == CCFPmode || mode == CCFPEmode)
3664 rc = reverse_condition_maybe_unordered (rc);
3666 rc = reverse_condition (rc);
3667 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3668 if (CONST_INT_P (operands[3]))
3669 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3671 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3673 [(set_attr "conds" "clob")
3674 (set (attr "length")
3675 (if_then_else (eq_attr "is_thumb" "yes")
3678 (set_attr "type" "multiple")]
3681 (define_code_iterator SAT [smin smax])
3682 (define_code_iterator SATrev [smin smax])
3683 (define_code_attr SATlo [(smin "1") (smax "2")])
3684 (define_code_attr SAThi [(smin "2") (smax "1")])
3686 (define_insn "*satsi_<SAT:code>"
3687 [(set (match_operand:SI 0 "s_register_operand" "=r")
3688 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3689 (match_operand:SI 1 "const_int_operand" "i"))
3690 (match_operand:SI 2 "const_int_operand" "i")))]
3691 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3692 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3696 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3697 &mask, &signed_sat))
3700 operands[1] = GEN_INT (mask);
3702 return "ssat%?\t%0, %1, %3";
3704 return "usat%?\t%0, %1, %3";
3706 [(set_attr "predicable" "yes")
3707 (set_attr "predicable_short_it" "no")
3708 (set_attr "type" "alus_imm")]
3711 (define_insn "*satsi_<SAT:code>_shift"
3712 [(set (match_operand:SI 0 "s_register_operand" "=r")
3713 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3714 [(match_operand:SI 4 "s_register_operand" "r")
3715 (match_operand:SI 5 "const_int_operand" "i")])
3716 (match_operand:SI 1 "const_int_operand" "i"))
3717 (match_operand:SI 2 "const_int_operand" "i")))]
3718 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3719 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3723 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3724 &mask, &signed_sat))
3727 operands[1] = GEN_INT (mask);
3729 return "ssat%?\t%0, %1, %4%S3";
3731 return "usat%?\t%0, %1, %4%S3";
3733 [(set_attr "predicable" "yes")
3734 (set_attr "predicable_short_it" "no")
3735 (set_attr "shift" "3")
3736 (set_attr "type" "logic_shift_reg")])
3738 ;; Shift and rotation insns
3740 (define_expand "ashldi3"
3741 [(set (match_operand:DI 0 "s_register_operand" "")
3742 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3743 (match_operand:SI 2 "general_operand" "")))]
3748 /* Delay the decision whether to use NEON or core-regs until
3749 register allocation. */
3750 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3755 /* Only the NEON case can handle in-memory shift counts. */
3756 if (!reg_or_int_operand (operands[2], SImode))
3757 operands[2] = force_reg (SImode, operands[2]);
3760 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3761 ; /* No special preparation statements; expand pattern as above. */
3764 rtx scratch1, scratch2;
3766 if (CONST_INT_P (operands[2])
3767 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3769 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3773 /* Ideally we should use iwmmxt here if we could know that operands[1]
3774 ends up already living in an iwmmxt register. Otherwise it's
3775 cheaper to have the alternate code being generated than moving
3776 values to iwmmxt regs and back. */
3778 /* If we're optimizing for size, we prefer the libgcc calls. */
3779 if (optimize_function_for_size_p (cfun))
3782 /* Expand operation using core-registers.
3783 'FAIL' would achieve the same thing, but this is a bit smarter. */
3784 scratch1 = gen_reg_rtx (SImode);
3785 scratch2 = gen_reg_rtx (SImode);
3786 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3787 operands[2], scratch1, scratch2);
3793 (define_insn "arm_ashldi3_1bit"
3794 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3795 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3797 (clobber (reg:CC CC_REGNUM))]
3799 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3800 [(set_attr "conds" "clob")
3801 (set_attr "length" "8")
3802 (set_attr "type" "multiple")]
3805 (define_expand "ashlsi3"
3806 [(set (match_operand:SI 0 "s_register_operand" "")
3807 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3808 (match_operand:SI 2 "arm_rhs_operand" "")))]
3811 if (CONST_INT_P (operands[2])
3812 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3814 emit_insn (gen_movsi (operands[0], const0_rtx));
3820 (define_expand "ashrdi3"
3821 [(set (match_operand:DI 0 "s_register_operand" "")
3822 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3823 (match_operand:SI 2 "reg_or_int_operand" "")))]
3828 /* Delay the decision whether to use NEON or core-regs until
3829 register allocation. */
3830 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3834 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3835 ; /* No special preparation statements; expand pattern as above. */
3838 rtx scratch1, scratch2;
3840 if (CONST_INT_P (operands[2])
3841 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3843 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3847 /* Ideally we should use iwmmxt here if we could know that operands[1]
3848 ends up already living in an iwmmxt register. Otherwise it's
3849 cheaper to have the alternate code being generated than moving
3850 values to iwmmxt regs and back. */
3852 /* If we're optimizing for size, we prefer the libgcc calls. */
3853 if (optimize_function_for_size_p (cfun))
3856 /* Expand operation using core-registers.
3857 'FAIL' would achieve the same thing, but this is a bit smarter. */
3858 scratch1 = gen_reg_rtx (SImode);
3859 scratch2 = gen_reg_rtx (SImode);
3860 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3861 operands[2], scratch1, scratch2);
3867 (define_insn "arm_ashrdi3_1bit"
3868 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3869 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3871 (clobber (reg:CC CC_REGNUM))]
3873 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3874 [(set_attr "conds" "clob")
3875 (set_attr "length" "8")
3876 (set_attr "type" "multiple")]
3879 (define_expand "ashrsi3"
3880 [(set (match_operand:SI 0 "s_register_operand" "")
3881 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3882 (match_operand:SI 2 "arm_rhs_operand" "")))]
3885 if (CONST_INT_P (operands[2])
3886 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3887 operands[2] = GEN_INT (31);
3891 (define_expand "lshrdi3"
3892 [(set (match_operand:DI 0 "s_register_operand" "")
3893 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3894 (match_operand:SI 2 "reg_or_int_operand" "")))]
3899 /* Delay the decision whether to use NEON or core-regs until
3900 register allocation. */
3901 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3905 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3906 ; /* No special preparation statements; expand pattern as above. */
3909 rtx scratch1, scratch2;
3911 if (CONST_INT_P (operands[2])
3912 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3914 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3918 /* Ideally we should use iwmmxt here if we could know that operands[1]
3919 ends up already living in an iwmmxt register. Otherwise it's
3920 cheaper to have the alternate code being generated than moving
3921 values to iwmmxt regs and back. */
3923 /* If we're optimizing for size, we prefer the libgcc calls. */
3924 if (optimize_function_for_size_p (cfun))
3927 /* Expand operation using core-registers.
3928 'FAIL' would achieve the same thing, but this is a bit smarter. */
3929 scratch1 = gen_reg_rtx (SImode);
3930 scratch2 = gen_reg_rtx (SImode);
3931 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3932 operands[2], scratch1, scratch2);
3938 (define_insn "arm_lshrdi3_1bit"
3939 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3940 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3942 (clobber (reg:CC CC_REGNUM))]
3944 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3945 [(set_attr "conds" "clob")
3946 (set_attr "length" "8")
3947 (set_attr "type" "multiple")]
3950 (define_expand "lshrsi3"
3951 [(set (match_operand:SI 0 "s_register_operand" "")
3952 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3953 (match_operand:SI 2 "arm_rhs_operand" "")))]
3956 if (CONST_INT_P (operands[2])
3957 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3959 emit_insn (gen_movsi (operands[0], const0_rtx));
3965 (define_expand "rotlsi3"
3966 [(set (match_operand:SI 0 "s_register_operand" "")
3967 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3968 (match_operand:SI 2 "reg_or_int_operand" "")))]
3971 if (CONST_INT_P (operands[2]))
3972 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3975 rtx reg = gen_reg_rtx (SImode);
3976 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3982 (define_expand "rotrsi3"
3983 [(set (match_operand:SI 0 "s_register_operand" "")
3984 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3985 (match_operand:SI 2 "arm_rhs_operand" "")))]
3990 if (CONST_INT_P (operands[2])
3991 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3992 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3994 else /* TARGET_THUMB1 */
3996 if (CONST_INT_P (operands [2]))
3997 operands [2] = force_reg (SImode, operands[2]);
4002 (define_insn "*arm_shiftsi3"
4003 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4004 (match_operator:SI 3 "shift_operator"
4005 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4006 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4008 "* return arm_output_shift(operands, 0);"
4009 [(set_attr "predicable" "yes")
4010 (set_attr "arch" "t2,t2,*,*")
4011 (set_attr "predicable_short_it" "yes,yes,no,no")
4012 (set_attr "length" "4")
4013 (set_attr "shift" "1")
4014 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4017 (define_insn "*shiftsi3_compare0"
4018 [(set (reg:CC_NOOV CC_REGNUM)
4019 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4020 [(match_operand:SI 1 "s_register_operand" "r,r")
4021 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4023 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4024 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4026 "* return arm_output_shift(operands, 1);"
4027 [(set_attr "conds" "set")
4028 (set_attr "shift" "1")
4029 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4032 (define_insn "*shiftsi3_compare0_scratch"
4033 [(set (reg:CC_NOOV CC_REGNUM)
4034 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4035 [(match_operand:SI 1 "s_register_operand" "r,r")
4036 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4038 (clobber (match_scratch:SI 0 "=r,r"))]
4040 "* return arm_output_shift(operands, 1);"
4041 [(set_attr "conds" "set")
4042 (set_attr "shift" "1")
4043 (set_attr "type" "shift_imm,shift_reg")]
4046 (define_insn "*not_shiftsi"
4047 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4048 (not:SI (match_operator:SI 3 "shift_operator"
4049 [(match_operand:SI 1 "s_register_operand" "r,r")
4050 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4053 [(set_attr "predicable" "yes")
4054 (set_attr "predicable_short_it" "no")
4055 (set_attr "shift" "1")
4056 (set_attr "arch" "32,a")
4057 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4059 (define_insn "*not_shiftsi_compare0"
4060 [(set (reg:CC_NOOV CC_REGNUM)
4062 (not:SI (match_operator:SI 3 "shift_operator"
4063 [(match_operand:SI 1 "s_register_operand" "r,r")
4064 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4066 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4067 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4070 [(set_attr "conds" "set")
4071 (set_attr "shift" "1")
4072 (set_attr "arch" "32,a")
4073 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4075 (define_insn "*not_shiftsi_compare0_scratch"
4076 [(set (reg:CC_NOOV CC_REGNUM)
4078 (not:SI (match_operator:SI 3 "shift_operator"
4079 [(match_operand:SI 1 "s_register_operand" "r,r")
4080 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4082 (clobber (match_scratch:SI 0 "=r,r"))]
4085 [(set_attr "conds" "set")
4086 (set_attr "shift" "1")
4087 (set_attr "arch" "32,a")
4088 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4090 ;; We don't really have extzv, but defining this using shifts helps
4091 ;; to reduce register pressure later on.
4093 (define_expand "extzv"
4094 [(set (match_operand 0 "s_register_operand" "")
4095 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4096 (match_operand 2 "const_int_operand" "")
4097 (match_operand 3 "const_int_operand" "")))]
4098 "TARGET_THUMB1 || arm_arch_thumb2"
4101 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4102 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4104 if (arm_arch_thumb2)
4106 HOST_WIDE_INT width = INTVAL (operands[2]);
4107 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4109 if (unaligned_access && MEM_P (operands[1])
4110 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4114 if (BYTES_BIG_ENDIAN)
4115 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4120 base_addr = adjust_address (operands[1], SImode,
4121 bitpos / BITS_PER_UNIT);
4122 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4126 rtx dest = operands[0];
4127 rtx tmp = gen_reg_rtx (SImode);
4129 /* We may get a paradoxical subreg here. Strip it off. */
4130 if (GET_CODE (dest) == SUBREG
4131 && GET_MODE (dest) == SImode
4132 && GET_MODE (SUBREG_REG (dest)) == HImode)
4133 dest = SUBREG_REG (dest);
4135 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4138 base_addr = adjust_address (operands[1], HImode,
4139 bitpos / BITS_PER_UNIT);
4140 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4141 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4145 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4147 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4155 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4158 operands[3] = GEN_INT (rshift);
4162 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4166 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4167 operands[3], gen_reg_rtx (SImode)));
4172 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4174 (define_expand "extzv_t1"
4175 [(set (match_operand:SI 4 "s_register_operand" "")
4176 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4177 (match_operand:SI 2 "const_int_operand" "")))
4178 (set (match_operand:SI 0 "s_register_operand" "")
4179 (lshiftrt:SI (match_dup 4)
4180 (match_operand:SI 3 "const_int_operand" "")))]
4184 (define_expand "extv"
4185 [(set (match_operand 0 "s_register_operand" "")
4186 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4187 (match_operand 2 "const_int_operand" "")
4188 (match_operand 3 "const_int_operand" "")))]
4191 HOST_WIDE_INT width = INTVAL (operands[2]);
4192 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4194 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4195 && (bitpos % BITS_PER_UNIT) == 0)
4199 if (BYTES_BIG_ENDIAN)
4200 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4204 base_addr = adjust_address (operands[1], SImode,
4205 bitpos / BITS_PER_UNIT);
4206 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4210 rtx dest = operands[0];
4211 rtx tmp = gen_reg_rtx (SImode);
4213 /* We may get a paradoxical subreg here. Strip it off. */
4214 if (GET_CODE (dest) == SUBREG
4215 && GET_MODE (dest) == SImode
4216 && GET_MODE (SUBREG_REG (dest)) == HImode)
4217 dest = SUBREG_REG (dest);
4219 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4222 base_addr = adjust_address (operands[1], HImode,
4223 bitpos / BITS_PER_UNIT);
4224 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4225 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4230 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4232 else if (GET_MODE (operands[0]) == SImode
4233 && GET_MODE (operands[1]) == SImode)
4235 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4243 ; Helper to expand register forms of extv with the proper modes.
4245 (define_expand "extv_regsi"
4246 [(set (match_operand:SI 0 "s_register_operand" "")
4247 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4248 (match_operand 2 "const_int_operand" "")
4249 (match_operand 3 "const_int_operand" "")))]
4254 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4256 (define_insn "unaligned_loadsi"
4257 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4258 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4259 UNSPEC_UNALIGNED_LOAD))]
4260 "unaligned_access && TARGET_32BIT"
4261 "ldr%?\t%0, %1\t@ unaligned"
4262 [(set_attr "arch" "t2,any")
4263 (set_attr "length" "2,4")
4264 (set_attr "predicable" "yes")
4265 (set_attr "predicable_short_it" "yes,no")
4266 (set_attr "type" "load1")])
4268 (define_insn "unaligned_loadhis"
4269 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4271 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4272 UNSPEC_UNALIGNED_LOAD)))]
4273 "unaligned_access && TARGET_32BIT"
4274 "ldr%(sh%)\t%0, %1\t@ unaligned"
4275 [(set_attr "arch" "t2,any")
4276 (set_attr "length" "2,4")
4277 (set_attr "predicable" "yes")
4278 (set_attr "predicable_short_it" "yes,no")
4279 (set_attr "type" "load_byte")])
4281 (define_insn "unaligned_loadhiu"
4282 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4284 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4285 UNSPEC_UNALIGNED_LOAD)))]
4286 "unaligned_access && TARGET_32BIT"
4287 "ldr%(h%)\t%0, %1\t@ unaligned"
4288 [(set_attr "arch" "t2,any")
4289 (set_attr "length" "2,4")
4290 (set_attr "predicable" "yes")
4291 (set_attr "predicable_short_it" "yes,no")
4292 (set_attr "type" "load_byte")])
4294 (define_insn "unaligned_storesi"
4295 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4296 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4297 UNSPEC_UNALIGNED_STORE))]
4298 "unaligned_access && TARGET_32BIT"
4299 "str%?\t%1, %0\t@ unaligned"
4300 [(set_attr "arch" "t2,any")
4301 (set_attr "length" "2,4")
4302 (set_attr "predicable" "yes")
4303 (set_attr "predicable_short_it" "yes,no")
4304 (set_attr "type" "store1")])
4306 (define_insn "unaligned_storehi"
4307 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4308 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4309 UNSPEC_UNALIGNED_STORE))]
4310 "unaligned_access && TARGET_32BIT"
4311 "str%(h%)\t%1, %0\t@ unaligned"
4312 [(set_attr "arch" "t2,any")
4313 (set_attr "length" "2,4")
4314 (set_attr "predicable" "yes")
4315 (set_attr "predicable_short_it" "yes,no")
4316 (set_attr "type" "store1")])
4318 ;; Unaligned double-word load and store.
4319 ;; Split after reload into two unaligned single-word accesses.
4320 ;; It prevents lower_subreg from splitting some other aligned
4321 ;; double-word accesses too early. Used for internal memcpy.
4323 (define_insn_and_split "unaligned_loaddi"
4324 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4325 (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4326 UNSPEC_UNALIGNED_LOAD))]
4327 "unaligned_access && TARGET_32BIT"
4329 "&& reload_completed"
4330 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4331 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4333 operands[2] = gen_highpart (SImode, operands[0]);
4334 operands[0] = gen_lowpart (SImode, operands[0]);
4335 operands[3] = gen_highpart (SImode, operands[1]);
4336 operands[1] = gen_lowpart (SImode, operands[1]);
4338 /* If the first destination register overlaps with the base address,
4339 swap the order in which the loads are emitted. */
4340 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4342 std::swap (operands[1], operands[3]);
4343 std::swap (operands[0], operands[2]);
4346 [(set_attr "arch" "t2,any")
4347 (set_attr "length" "4,8")
4348 (set_attr "predicable" "yes")
4349 (set_attr "type" "load2")])
4351 (define_insn_and_split "unaligned_storedi"
4352 [(set (match_operand:DI 0 "memory_operand" "=o,o")
4353 (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4354 UNSPEC_UNALIGNED_STORE))]
4355 "unaligned_access && TARGET_32BIT"
4357 "&& reload_completed"
4358 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4359 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4361 operands[2] = gen_highpart (SImode, operands[0]);
4362 operands[0] = gen_lowpart (SImode, operands[0]);
4363 operands[3] = gen_highpart (SImode, operands[1]);
4364 operands[1] = gen_lowpart (SImode, operands[1]);
4366 [(set_attr "arch" "t2,any")
4367 (set_attr "length" "4,8")
4368 (set_attr "predicable" "yes")
4369 (set_attr "type" "store2")])
4372 (define_insn "*extv_reg"
4373 [(set (match_operand:SI 0 "s_register_operand" "=r")
4374 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4375 (match_operand:SI 2 "const_int_M_operand" "M")
4376 (match_operand:SI 3 "const_int_M_operand" "M")))]
4378 "sbfx%?\t%0, %1, %3, %2"
4379 [(set_attr "length" "4")
4380 (set_attr "predicable" "yes")
4381 (set_attr "predicable_short_it" "no")
4382 (set_attr "type" "bfm")]
4385 (define_insn "extzv_t2"
4386 [(set (match_operand:SI 0 "s_register_operand" "=r")
4387 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4388 (match_operand:SI 2 "const_int_M_operand" "M")
4389 (match_operand:SI 3 "const_int_M_operand" "M")))]
4391 "ubfx%?\t%0, %1, %3, %2"
4392 [(set_attr "length" "4")
4393 (set_attr "predicable" "yes")
4394 (set_attr "predicable_short_it" "no")
4395 (set_attr "type" "bfm")]
4399 ;; Division instructions
4400 (define_insn "divsi3"
4401 [(set (match_operand:SI 0 "s_register_operand" "=r")
4402 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4403 (match_operand:SI 2 "s_register_operand" "r")))]
4405 "sdiv%?\t%0, %1, %2"
4406 [(set_attr "predicable" "yes")
4407 (set_attr "predicable_short_it" "no")
4408 (set_attr "type" "sdiv")]
4411 (define_insn "udivsi3"
4412 [(set (match_operand:SI 0 "s_register_operand" "=r")
4413 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4414 (match_operand:SI 2 "s_register_operand" "r")))]
4416 "udiv%?\t%0, %1, %2"
4417 [(set_attr "predicable" "yes")
4418 (set_attr "predicable_short_it" "no")
4419 (set_attr "type" "udiv")]
4423 ;; Unary arithmetic insns
4425 (define_expand "negdi2"
4427 [(set (match_operand:DI 0 "s_register_operand" "")
4428 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4429 (clobber (reg:CC CC_REGNUM))])]
4434 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4440 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4441 ;; The first alternative allows the common case of a *full* overlap.
4442 (define_insn_and_split "*arm_negdi2"
4443 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4444 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4445 (clobber (reg:CC CC_REGNUM))]
4447 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4448 "&& reload_completed"
4449 [(parallel [(set (reg:CC CC_REGNUM)
4450 (compare:CC (const_int 0) (match_dup 1)))
4451 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4452 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4453 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4455 operands[2] = gen_highpart (SImode, operands[0]);
4456 operands[0] = gen_lowpart (SImode, operands[0]);
4457 operands[3] = gen_highpart (SImode, operands[1]);
4458 operands[1] = gen_lowpart (SImode, operands[1]);
4460 [(set_attr "conds" "clob")
4461 (set_attr "length" "8")
4462 (set_attr "type" "multiple")]
4465 (define_expand "negsi2"
4466 [(set (match_operand:SI 0 "s_register_operand" "")
4467 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4472 (define_insn "*arm_negsi2"
4473 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4474 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4476 "rsb%?\\t%0, %1, #0"
4477 [(set_attr "predicable" "yes")
4478 (set_attr "predicable_short_it" "yes,no")
4479 (set_attr "arch" "t2,*")
4480 (set_attr "length" "4")
4481 (set_attr "type" "alu_sreg")]
4484 (define_expand "negsf2"
4485 [(set (match_operand:SF 0 "s_register_operand" "")
4486 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4487 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4491 (define_expand "negdf2"
4492 [(set (match_operand:DF 0 "s_register_operand" "")
4493 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4494 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4497 (define_insn_and_split "*zextendsidi_negsi"
4498 [(set (match_operand:DI 0 "s_register_operand" "=r")
4499 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4504 (neg:SI (match_dup 1)))
4508 operands[2] = gen_lowpart (SImode, operands[0]);
4509 operands[3] = gen_highpart (SImode, operands[0]);
4511 [(set_attr "length" "8")
4512 (set_attr "type" "multiple")]
4515 ;; Negate an extended 32-bit value.
4516 (define_insn_and_split "*negdi_extendsidi"
4517 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4518 (neg:DI (sign_extend:DI
4519 (match_operand:SI 1 "s_register_operand" "l,r"))))
4520 (clobber (reg:CC CC_REGNUM))]
4523 "&& reload_completed"
4526 rtx low = gen_lowpart (SImode, operands[0]);
4527 rtx high = gen_highpart (SImode, operands[0]);
4529 if (reg_overlap_mentioned_p (low, operands[1]))
4531 /* Input overlaps the low word of the output. Use:
4534 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4535 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4537 emit_insn (gen_rtx_SET (high,
4538 gen_rtx_ASHIFTRT (SImode, operands[1],
4541 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4543 emit_insn (gen_rtx_SET (high,
4544 gen_rtx_MINUS (SImode,
4545 gen_rtx_MINUS (SImode,
4548 gen_rtx_LTU (SImode,
4553 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4554 emit_insn (gen_rtx_SET (high,
4555 gen_rtx_MINUS (SImode,
4556 gen_rtx_MINUS (SImode,
4559 gen_rtx_LTU (SImode,
4566 /* No overlap, or overlap on high word. Use:
4570 Flags not needed for this sequence. */
4571 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4572 emit_insn (gen_rtx_SET (high,
4573 gen_rtx_AND (SImode,
4574 gen_rtx_NOT (SImode, operands[1]),
4576 emit_insn (gen_rtx_SET (high,
4577 gen_rtx_ASHIFTRT (SImode, high,
4582 [(set_attr "length" "12")
4583 (set_attr "arch" "t2,*")
4584 (set_attr "type" "multiple")]
4587 (define_insn_and_split "*negdi_zero_extendsidi"
4588 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4589 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4590 (clobber (reg:CC CC_REGNUM))]
4592 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4593 ;; Don't care what register is input to sbc,
4594 ;; since we just need to propagate the carry.
4595 "&& reload_completed"
4596 [(parallel [(set (reg:CC CC_REGNUM)
4597 (compare:CC (const_int 0) (match_dup 1)))
4598 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4599 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4600 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4602 operands[2] = gen_highpart (SImode, operands[0]);
4603 operands[0] = gen_lowpart (SImode, operands[0]);
4605 [(set_attr "conds" "clob")
4606 (set_attr "length" "8")
4607 (set_attr "type" "multiple")] ;; length in thumb is 4
4610 ;; abssi2 doesn't really clobber the condition codes if a different register
4611 ;; is being set. To keep things simple, assume during rtl manipulations that
4612 ;; it does, but tell the final scan operator the truth. Similarly for
4615 (define_expand "abssi2"
4617 [(set (match_operand:SI 0 "s_register_operand" "")
4618 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4619 (clobber (match_dup 2))])]
4623 operands[2] = gen_rtx_SCRATCH (SImode);
4625 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4628 (define_insn_and_split "*arm_abssi2"
4629 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4630 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4631 (clobber (reg:CC CC_REGNUM))]
4634 "&& reload_completed"
4637 /* if (which_alternative == 0) */
4638 if (REGNO(operands[0]) == REGNO(operands[1]))
4640 /* Emit the pattern:
4641 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4642 [(set (reg:CC CC_REGNUM)
4643 (compare:CC (match_dup 0) (const_int 0)))
4644 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4645 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4647 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4648 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4649 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4650 (gen_rtx_LT (SImode,
4651 gen_rtx_REG (CCmode, CC_REGNUM),
4653 (gen_rtx_SET (operands[0],
4654 (gen_rtx_MINUS (SImode,
4661 /* Emit the pattern:
4662 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4664 (xor:SI (match_dup 1)
4665 (ashiftrt:SI (match_dup 1) (const_int 31))))
4667 (minus:SI (match_dup 0)
4668 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4670 emit_insn (gen_rtx_SET (operands[0],
4671 gen_rtx_XOR (SImode,
4672 gen_rtx_ASHIFTRT (SImode,
4676 emit_insn (gen_rtx_SET (operands[0],
4677 gen_rtx_MINUS (SImode,
4679 gen_rtx_ASHIFTRT (SImode,
4685 [(set_attr "conds" "clob,*")
4686 (set_attr "shift" "1")
4687 (set_attr "predicable" "no, yes")
4688 (set_attr "length" "8")
4689 (set_attr "type" "multiple")]
4692 (define_insn_and_split "*arm_neg_abssi2"
4693 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4694 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4695 (clobber (reg:CC CC_REGNUM))]
4698 "&& reload_completed"
4701 /* if (which_alternative == 0) */
4702 if (REGNO (operands[0]) == REGNO (operands[1]))
4704 /* Emit the pattern:
4705 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4707 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4708 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4709 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4711 gen_rtx_REG (CCmode, CC_REGNUM),
4713 gen_rtx_SET (operands[0],
4714 (gen_rtx_MINUS (SImode,
4720 /* Emit the pattern:
4721 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4723 emit_insn (gen_rtx_SET (operands[0],
4724 gen_rtx_XOR (SImode,
4725 gen_rtx_ASHIFTRT (SImode,
4729 emit_insn (gen_rtx_SET (operands[0],
4730 gen_rtx_MINUS (SImode,
4731 gen_rtx_ASHIFTRT (SImode,
4738 [(set_attr "conds" "clob,*")
4739 (set_attr "shift" "1")
4740 (set_attr "predicable" "no, yes")
4741 (set_attr "length" "8")
4742 (set_attr "type" "multiple")]
4745 (define_expand "abssf2"
4746 [(set (match_operand:SF 0 "s_register_operand" "")
4747 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4748 "TARGET_32BIT && TARGET_HARD_FLOAT"
4751 (define_expand "absdf2"
4752 [(set (match_operand:DF 0 "s_register_operand" "")
4753 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4754 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4757 (define_expand "sqrtsf2"
4758 [(set (match_operand:SF 0 "s_register_operand" "")
4759 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4760 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4763 (define_expand "sqrtdf2"
4764 [(set (match_operand:DF 0 "s_register_operand" "")
4765 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4766 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4769 (define_insn_and_split "one_cmpldi2"
4770 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4771 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4778 "TARGET_32BIT && reload_completed
4779 && arm_general_register_operand (operands[0], DImode)"
4780 [(set (match_dup 0) (not:SI (match_dup 1)))
4781 (set (match_dup 2) (not:SI (match_dup 3)))]
4784 operands[2] = gen_highpart (SImode, operands[0]);
4785 operands[0] = gen_lowpart (SImode, operands[0]);
4786 operands[3] = gen_highpart (SImode, operands[1]);
4787 operands[1] = gen_lowpart (SImode, operands[1]);
4789 [(set_attr "length" "*,8,8,*")
4790 (set_attr "predicable" "no,yes,yes,no")
4791 (set_attr "type" "neon_move,multiple,multiple,neon_move")
4792 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4795 (define_expand "one_cmplsi2"
4796 [(set (match_operand:SI 0 "s_register_operand" "")
4797 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4802 (define_insn "*arm_one_cmplsi2"
4803 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4804 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4807 [(set_attr "predicable" "yes")
4808 (set_attr "predicable_short_it" "yes,no")
4809 (set_attr "arch" "t2,*")
4810 (set_attr "length" "4")
4811 (set_attr "type" "mvn_reg")]
4814 (define_insn "*notsi_compare0"
4815 [(set (reg:CC_NOOV CC_REGNUM)
4816 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4818 (set (match_operand:SI 0 "s_register_operand" "=r")
4819 (not:SI (match_dup 1)))]
4822 [(set_attr "conds" "set")
4823 (set_attr "type" "mvn_reg")]
4826 (define_insn "*notsi_compare0_scratch"
4827 [(set (reg:CC_NOOV CC_REGNUM)
4828 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4830 (clobber (match_scratch:SI 0 "=r"))]
4833 [(set_attr "conds" "set")
4834 (set_attr "type" "mvn_reg")]
4837 ;; Fixed <--> Floating conversion insns
4839 (define_expand "floatsihf2"
4840 [(set (match_operand:HF 0 "general_operand" "")
4841 (float:HF (match_operand:SI 1 "general_operand" "")))]
4845 rtx op1 = gen_reg_rtx (SFmode);
4846 expand_float (op1, operands[1], 0);
4847 op1 = convert_to_mode (HFmode, op1, 0);
4848 emit_move_insn (operands[0], op1);
4853 (define_expand "floatdihf2"
4854 [(set (match_operand:HF 0 "general_operand" "")
4855 (float:HF (match_operand:DI 1 "general_operand" "")))]
4859 rtx op1 = gen_reg_rtx (SFmode);
4860 expand_float (op1, operands[1], 0);
4861 op1 = convert_to_mode (HFmode, op1, 0);
4862 emit_move_insn (operands[0], op1);
4867 (define_expand "floatsisf2"
4868 [(set (match_operand:SF 0 "s_register_operand" "")
4869 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
4870 "TARGET_32BIT && TARGET_HARD_FLOAT"
4874 (define_expand "floatsidf2"
4875 [(set (match_operand:DF 0 "s_register_operand" "")
4876 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
4877 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4881 (define_expand "fix_trunchfsi2"
4882 [(set (match_operand:SI 0 "general_operand" "")
4883 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4887 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4888 expand_fix (operands[0], op1, 0);
4893 (define_expand "fix_trunchfdi2"
4894 [(set (match_operand:DI 0 "general_operand" "")
4895 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4899 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4900 expand_fix (operands[0], op1, 0);
4905 (define_expand "fix_truncsfsi2"
4906 [(set (match_operand:SI 0 "s_register_operand" "")
4907 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
4908 "TARGET_32BIT && TARGET_HARD_FLOAT"
4912 (define_expand "fix_truncdfsi2"
4913 [(set (match_operand:SI 0 "s_register_operand" "")
4914 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
4915 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4921 (define_expand "truncdfsf2"
4922 [(set (match_operand:SF 0 "s_register_operand" "")
4924 (match_operand:DF 1 "s_register_operand" "")))]
4925 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4929 /* DFmode -> HFmode conversions have to go through SFmode. */
4930 (define_expand "truncdfhf2"
4931 [(set (match_operand:HF 0 "general_operand" "")
4933 (match_operand:DF 1 "general_operand" "")))]
4938 op1 = convert_to_mode (SFmode, operands[1], 0);
4939 op1 = convert_to_mode (HFmode, op1, 0);
4940 emit_move_insn (operands[0], op1);
4945 ;; Zero and sign extension instructions.
4947 (define_insn "zero_extend<mode>di2"
4948 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
4949 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4950 "<qhs_zextenddi_cstr>")))]
4951 "TARGET_32BIT <qhs_zextenddi_cond>"
4953 [(set_attr "length" "8,4,8,8")
4954 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
4955 (set_attr "ce_count" "2")
4956 (set_attr "predicable" "yes")
4957 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
4960 (define_insn "extend<mode>di2"
4961 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
4962 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4963 "<qhs_extenddi_cstr>")))]
4964 "TARGET_32BIT <qhs_sextenddi_cond>"
4966 [(set_attr "length" "8,4,8,8,8")
4967 (set_attr "ce_count" "2")
4968 (set_attr "shift" "1")
4969 (set_attr "predicable" "yes")
4970 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4971 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
4974 ;; Splits for all extensions to DImode
4976 [(set (match_operand:DI 0 "s_register_operand" "")
4977 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4978 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4979 [(set (match_dup 0) (match_dup 1))]
4981 rtx lo_part = gen_lowpart (SImode, operands[0]);
4982 machine_mode src_mode = GET_MODE (operands[1]);
4984 if (REG_P (operands[0])
4985 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4986 emit_clobber (operands[0]);
4987 if (!REG_P (lo_part) || src_mode != SImode
4988 || !rtx_equal_p (lo_part, operands[1]))
4990 if (src_mode == SImode)
4991 emit_move_insn (lo_part, operands[1]);
4993 emit_insn (gen_rtx_SET (lo_part,
4994 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4995 operands[1] = lo_part;
4997 operands[0] = gen_highpart (SImode, operands[0]);
4998 operands[1] = const0_rtx;
5002 [(set (match_operand:DI 0 "s_register_operand" "")
5003 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5004 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5005 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5007 rtx lo_part = gen_lowpart (SImode, operands[0]);
5008 machine_mode src_mode = GET_MODE (operands[1]);
5010 if (REG_P (operands[0])
5011 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5012 emit_clobber (operands[0]);
5014 if (!REG_P (lo_part) || src_mode != SImode
5015 || !rtx_equal_p (lo_part, operands[1]))
5017 if (src_mode == SImode)
5018 emit_move_insn (lo_part, operands[1]);
5020 emit_insn (gen_rtx_SET (lo_part,
5021 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5022 operands[1] = lo_part;
5024 operands[0] = gen_highpart (SImode, operands[0]);
5027 (define_expand "zero_extendhisi2"
5028 [(set (match_operand:SI 0 "s_register_operand" "")
5029 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5032 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5034 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5037 if (!arm_arch6 && !MEM_P (operands[1]))
5039 rtx t = gen_lowpart (SImode, operands[1]);
5040 rtx tmp = gen_reg_rtx (SImode);
5041 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5042 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5048 [(set (match_operand:SI 0 "s_register_operand" "")
5049 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5050 "!TARGET_THUMB2 && !arm_arch6"
5051 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5052 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5054 operands[2] = gen_lowpart (SImode, operands[1]);
5057 (define_insn "*arm_zero_extendhisi2"
5058 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5059 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5060 "TARGET_ARM && arm_arch4 && !arm_arch6"
5064 [(set_attr "type" "alu_shift_reg,load_byte")
5065 (set_attr "predicable" "yes")]
5068 (define_insn "*arm_zero_extendhisi2_v6"
5069 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5070 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5071 "TARGET_ARM && arm_arch6"
5075 [(set_attr "predicable" "yes")
5076 (set_attr "type" "extend,load_byte")]
5079 (define_insn "*arm_zero_extendhisi2addsi"
5080 [(set (match_operand:SI 0 "s_register_operand" "=r")
5081 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5082 (match_operand:SI 2 "s_register_operand" "r")))]
5084 "uxtah%?\\t%0, %2, %1"
5085 [(set_attr "type" "alu_shift_reg")
5086 (set_attr "predicable" "yes")
5087 (set_attr "predicable_short_it" "no")]
5090 (define_expand "zero_extendqisi2"
5091 [(set (match_operand:SI 0 "s_register_operand" "")
5092 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5095 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5097 emit_insn (gen_andsi3 (operands[0],
5098 gen_lowpart (SImode, operands[1]),
5102 if (!arm_arch6 && !MEM_P (operands[1]))
5104 rtx t = gen_lowpart (SImode, operands[1]);
5105 rtx tmp = gen_reg_rtx (SImode);
5106 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5107 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5113 [(set (match_operand:SI 0 "s_register_operand" "")
5114 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5116 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5117 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5119 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5122 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5127 (define_insn "*arm_zero_extendqisi2"
5128 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5129 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5130 "TARGET_ARM && !arm_arch6"
5133 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5134 [(set_attr "length" "8,4")
5135 (set_attr "type" "alu_shift_reg,load_byte")
5136 (set_attr "predicable" "yes")]
5139 (define_insn "*arm_zero_extendqisi2_v6"
5140 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5141 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5142 "TARGET_ARM && arm_arch6"
5145 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5146 [(set_attr "type" "extend,load_byte")
5147 (set_attr "predicable" "yes")]
5150 (define_insn "*arm_zero_extendqisi2addsi"
5151 [(set (match_operand:SI 0 "s_register_operand" "=r")
5152 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5153 (match_operand:SI 2 "s_register_operand" "r")))]
5155 "uxtab%?\\t%0, %2, %1"
5156 [(set_attr "predicable" "yes")
5157 (set_attr "predicable_short_it" "no")
5158 (set_attr "type" "alu_shift_reg")]
5162 [(set (match_operand:SI 0 "s_register_operand" "")
5163 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5164 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5165 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5166 [(set (match_dup 2) (match_dup 1))
5167 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5172 [(set (match_operand:SI 0 "s_register_operand" "")
5173 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5174 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5175 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5176 [(set (match_dup 2) (match_dup 1))
5177 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5183 [(set (match_operand:SI 0 "s_register_operand" "")
5184 (IOR_XOR:SI (and:SI (ashift:SI
5185 (match_operand:SI 1 "s_register_operand" "")
5186 (match_operand:SI 2 "const_int_operand" ""))
5187 (match_operand:SI 3 "const_int_operand" ""))
5189 (match_operator 5 "subreg_lowpart_operator"
5190 [(match_operand:SI 4 "s_register_operand" "")]))))]
5192 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5193 == (GET_MODE_MASK (GET_MODE (operands[5]))
5194 & (GET_MODE_MASK (GET_MODE (operands[5]))
5195 << (INTVAL (operands[2])))))"
5196 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5198 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5199 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5202 (define_insn "*compareqi_eq0"
5203 [(set (reg:CC_Z CC_REGNUM)
5204 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5208 [(set_attr "conds" "set")
5209 (set_attr "predicable" "yes")
5210 (set_attr "predicable_short_it" "no")
5211 (set_attr "type" "logic_imm")]
5214 (define_expand "extendhisi2"
5215 [(set (match_operand:SI 0 "s_register_operand" "")
5216 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5221 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5224 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5226 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5230 if (!arm_arch6 && !MEM_P (operands[1]))
5232 rtx t = gen_lowpart (SImode, operands[1]);
5233 rtx tmp = gen_reg_rtx (SImode);
5234 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5235 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5242 [(set (match_operand:SI 0 "register_operand" "")
5243 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5244 (clobber (match_scratch:SI 2 ""))])]
5246 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5247 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5249 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5252 ;; This pattern will only be used when ldsh is not available
5253 (define_expand "extendhisi2_mem"
5254 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5256 (zero_extend:SI (match_dup 7)))
5257 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5258 (set (match_operand:SI 0 "" "")
5259 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5264 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5266 mem1 = change_address (operands[1], QImode, addr);
5267 mem2 = change_address (operands[1], QImode,
5268 plus_constant (Pmode, addr, 1));
5269 operands[0] = gen_lowpart (SImode, operands[0]);
5271 operands[2] = gen_reg_rtx (SImode);
5272 operands[3] = gen_reg_rtx (SImode);
5273 operands[6] = gen_reg_rtx (SImode);
5276 if (BYTES_BIG_ENDIAN)
5278 operands[4] = operands[2];
5279 operands[5] = operands[3];
5283 operands[4] = operands[3];
5284 operands[5] = operands[2];
5290 [(set (match_operand:SI 0 "register_operand" "")
5291 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5293 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5294 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5296 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5299 (define_insn "*arm_extendhisi2"
5300 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5301 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5302 "TARGET_ARM && arm_arch4 && !arm_arch6"
5306 [(set_attr "length" "8,4")
5307 (set_attr "type" "alu_shift_reg,load_byte")
5308 (set_attr "predicable" "yes")]
5311 ;; ??? Check Thumb-2 pool range
5312 (define_insn "*arm_extendhisi2_v6"
5313 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5314 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5315 "TARGET_32BIT && arm_arch6"
5319 [(set_attr "type" "extend,load_byte")
5320 (set_attr "predicable" "yes")
5321 (set_attr "predicable_short_it" "no")]
5324 (define_insn "*arm_extendhisi2addsi"
5325 [(set (match_operand:SI 0 "s_register_operand" "=r")
5326 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5327 (match_operand:SI 2 "s_register_operand" "r")))]
5329 "sxtah%?\\t%0, %2, %1"
5330 [(set_attr "type" "alu_shift_reg")]
5333 (define_expand "extendqihi2"
5335 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5337 (set (match_operand:HI 0 "s_register_operand" "")
5338 (ashiftrt:SI (match_dup 2)
5343 if (arm_arch4 && MEM_P (operands[1]))
5345 emit_insn (gen_rtx_SET (operands[0],
5346 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5349 if (!s_register_operand (operands[1], QImode))
5350 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5351 operands[0] = gen_lowpart (SImode, operands[0]);
5352 operands[1] = gen_lowpart (SImode, operands[1]);
5353 operands[2] = gen_reg_rtx (SImode);
5357 (define_insn "*arm_extendqihi_insn"
5358 [(set (match_operand:HI 0 "s_register_operand" "=r")
5359 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5360 "TARGET_ARM && arm_arch4"
5361 "ldr%(sb%)\\t%0, %1"
5362 [(set_attr "type" "load_byte")
5363 (set_attr "predicable" "yes")]
5366 (define_expand "extendqisi2"
5367 [(set (match_operand:SI 0 "s_register_operand" "")
5368 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5371 if (!arm_arch4 && MEM_P (operands[1]))
5372 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5374 if (!arm_arch6 && !MEM_P (operands[1]))
5376 rtx t = gen_lowpart (SImode, operands[1]);
5377 rtx tmp = gen_reg_rtx (SImode);
5378 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5379 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5385 [(set (match_operand:SI 0 "register_operand" "")
5386 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5388 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5389 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5391 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5394 (define_insn "*arm_extendqisi"
5395 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5396 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5397 "TARGET_ARM && arm_arch4 && !arm_arch6"
5401 [(set_attr "length" "8,4")
5402 (set_attr "type" "alu_shift_reg,load_byte")
5403 (set_attr "predicable" "yes")]
5406 (define_insn "*arm_extendqisi_v6"
5407 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5409 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5410 "TARGET_ARM && arm_arch6"
5414 [(set_attr "type" "extend,load_byte")
5415 (set_attr "predicable" "yes")]
5418 (define_insn "*arm_extendqisi2addsi"
5419 [(set (match_operand:SI 0 "s_register_operand" "=r")
5420 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5421 (match_operand:SI 2 "s_register_operand" "r")))]
5423 "sxtab%?\\t%0, %2, %1"
5424 [(set_attr "type" "alu_shift_reg")
5425 (set_attr "predicable" "yes")
5426 (set_attr "predicable_short_it" "no")]
5429 (define_expand "extendsfdf2"
5430 [(set (match_operand:DF 0 "s_register_operand" "")
5431 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5432 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5436 /* HFmode -> DFmode conversions have to go through SFmode. */
5437 (define_expand "extendhfdf2"
5438 [(set (match_operand:DF 0 "general_operand" "")
5439 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5444 op1 = convert_to_mode (SFmode, operands[1], 0);
5445 op1 = convert_to_mode (DFmode, op1, 0);
5446 emit_insn (gen_movdf (operands[0], op1));
5451 ;; Move insns (including loads and stores)
5453 ;; XXX Just some ideas about movti.
5454 ;; I don't think these are a good idea on the arm, there just aren't enough
5456 ;;(define_expand "loadti"
5457 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5458 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5461 ;;(define_expand "storeti"
5462 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5463 ;; (match_operand:TI 1 "s_register_operand" ""))]
5466 ;;(define_expand "movti"
5467 ;; [(set (match_operand:TI 0 "general_operand" "")
5468 ;; (match_operand:TI 1 "general_operand" ""))]
5474 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5475 ;; operands[1] = copy_to_reg (operands[1]);
5476 ;; if (MEM_P (operands[0]))
5477 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5478 ;; else if (MEM_P (operands[1]))
5479 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5483 ;; emit_insn (insn);
5487 ;; Recognize garbage generated above.
5490 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5491 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5495 ;; register mem = (which_alternative < 3);
5496 ;; register const char *template;
5498 ;; operands[mem] = XEXP (operands[mem], 0);
5499 ;; switch (which_alternative)
5501 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5502 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5503 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5504 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5505 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5506 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5508 ;; output_asm_insn (template, operands);
5512 (define_expand "movdi"
5513 [(set (match_operand:DI 0 "general_operand" "")
5514 (match_operand:DI 1 "general_operand" ""))]
5517 if (can_create_pseudo_p ())
5519 if (!REG_P (operands[0]))
5520 operands[1] = force_reg (DImode, operands[1]);
5522 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5523 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5525 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5526 when expanding function calls. */
5527 gcc_assert (can_create_pseudo_p ());
5528 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5530 /* Perform load into legal reg pair first, then move. */
5531 rtx reg = gen_reg_rtx (DImode);
5532 emit_insn (gen_movdi (reg, operands[1]));
5535 emit_move_insn (gen_lowpart (SImode, operands[0]),
5536 gen_lowpart (SImode, operands[1]));
5537 emit_move_insn (gen_highpart (SImode, operands[0]),
5538 gen_highpart (SImode, operands[1]));
5541 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5542 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5544 /* Avoid STRD's from an odd-numbered register pair in ARM state
5545 when expanding function prologue. */
5546 gcc_assert (can_create_pseudo_p ());
5547 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5548 ? gen_reg_rtx (DImode)
5550 emit_move_insn (gen_lowpart (SImode, split_dest),
5551 gen_lowpart (SImode, operands[1]));
5552 emit_move_insn (gen_highpart (SImode, split_dest),
5553 gen_highpart (SImode, operands[1]));
5554 if (split_dest != operands[0])
5555 emit_insn (gen_movdi (operands[0], split_dest));
5561 (define_insn "*arm_movdi"
5562 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5563 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5565 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5567 && ( register_operand (operands[0], DImode)
5568 || register_operand (operands[1], DImode))"
5570 switch (which_alternative)
5577 return output_move_double (operands, true, NULL);
5580 [(set_attr "length" "8,12,16,8,8")
5581 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5582 (set_attr "arm_pool_range" "*,*,*,1020,*")
5583 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5584 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5585 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5589 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5590 (match_operand:ANY64 1 "immediate_operand" ""))]
5593 && (arm_const_double_inline_cost (operands[1])
5594 <= arm_max_const_double_inline_cost ())"
5597 arm_split_constant (SET, SImode, curr_insn,
5598 INTVAL (gen_lowpart (SImode, operands[1])),
5599 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5600 arm_split_constant (SET, SImode, curr_insn,
5601 INTVAL (gen_highpart_mode (SImode,
5602 GET_MODE (operands[0]),
5604 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5609 ; If optimizing for size, or if we have load delay slots, then
5610 ; we want to split the constant into two separate operations.
5611 ; In both cases this may split a trivial part into a single data op
5612 ; leaving a single complex constant to load. We can also get longer
5613 ; offsets in a LDR which means we get better chances of sharing the pool
5614 ; entries. Finally, we can normally do a better job of scheduling
5615 ; LDR instructions than we can with LDM.
5616 ; This pattern will only match if the one above did not.
5618 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5619 (match_operand:ANY64 1 "const_double_operand" ""))]
5620 "TARGET_ARM && reload_completed
5621 && arm_const_double_by_parts (operands[1])"
5622 [(set (match_dup 0) (match_dup 1))
5623 (set (match_dup 2) (match_dup 3))]
5625 operands[2] = gen_highpart (SImode, operands[0]);
5626 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5628 operands[0] = gen_lowpart (SImode, operands[0]);
5629 operands[1] = gen_lowpart (SImode, operands[1]);
5634 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5635 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5636 "TARGET_EITHER && reload_completed"
5637 [(set (match_dup 0) (match_dup 1))
5638 (set (match_dup 2) (match_dup 3))]
5640 operands[2] = gen_highpart (SImode, operands[0]);
5641 operands[3] = gen_highpart (SImode, operands[1]);
5642 operands[0] = gen_lowpart (SImode, operands[0]);
5643 operands[1] = gen_lowpart (SImode, operands[1]);
5645 /* Handle a partial overlap. */
5646 if (rtx_equal_p (operands[0], operands[3]))
5648 rtx tmp0 = operands[0];
5649 rtx tmp1 = operands[1];
5651 operands[0] = operands[2];
5652 operands[1] = operands[3];
5659 ;; We can't actually do base+index doubleword loads if the index and
5660 ;; destination overlap. Split here so that we at least have chance to
5663 [(set (match_operand:DI 0 "s_register_operand" "")
5664 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5665 (match_operand:SI 2 "s_register_operand" ""))))]
5667 && reg_overlap_mentioned_p (operands[0], operands[1])
5668 && reg_overlap_mentioned_p (operands[0], operands[2])"
5670 (plus:SI (match_dup 1)
5673 (mem:DI (match_dup 4)))]
5675 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5679 (define_expand "movsi"
5680 [(set (match_operand:SI 0 "general_operand" "")
5681 (match_operand:SI 1 "general_operand" ""))]
5685 rtx base, offset, tmp;
5689 /* Everything except mem = const or mem = mem can be done easily. */
5690 if (MEM_P (operands[0]))
5691 operands[1] = force_reg (SImode, operands[1]);
5692 if (arm_general_register_operand (operands[0], SImode)
5693 && CONST_INT_P (operands[1])
5694 && !(const_ok_for_arm (INTVAL (operands[1]))
5695 || const_ok_for_arm (~INTVAL (operands[1]))))
5697 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5699 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5704 arm_split_constant (SET, SImode, NULL_RTX,
5705 INTVAL (operands[1]), operands[0], NULL_RTX,
5706 optimize && can_create_pseudo_p ());
5711 else /* TARGET_THUMB1... */
5713 if (can_create_pseudo_p ())
5715 if (!REG_P (operands[0]))
5716 operands[1] = force_reg (SImode, operands[1]);
5720 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5722 split_const (operands[1], &base, &offset);
5723 if (GET_CODE (base) == SYMBOL_REF
5724 && !offset_within_block_p (base, INTVAL (offset)))
5726 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5727 emit_move_insn (tmp, base);
5728 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5733 /* Recognize the case where operand[1] is a reference to thread-local
5734 data and load its address to a register. */
5735 if (arm_tls_referenced_p (operands[1]))
5737 rtx tmp = operands[1];
5740 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5742 addend = XEXP (XEXP (tmp, 0), 1);
5743 tmp = XEXP (XEXP (tmp, 0), 0);
5746 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5747 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5749 tmp = legitimize_tls_address (tmp,
5750 !can_create_pseudo_p () ? operands[0] : 0);
5753 tmp = gen_rtx_PLUS (SImode, tmp, addend);
5754 tmp = force_operand (tmp, operands[0]);
5759 && (CONSTANT_P (operands[1])
5760 || symbol_mentioned_p (operands[1])
5761 || label_mentioned_p (operands[1])))
5762 operands[1] = legitimize_pic_address (operands[1], SImode,
5763 (!can_create_pseudo_p ()
5770 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5771 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5772 ;; so this does not matter.
5773 (define_insn "*arm_movt"
5774 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5775 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5776 (match_operand:SI 2 "general_operand" "i")))]
5777 "arm_arch_thumb2 && arm_valid_symbolic_address_p (operands[2])"
5778 "movt%?\t%0, #:upper16:%c2"
5779 [(set_attr "predicable" "yes")
5780 (set_attr "predicable_short_it" "no")
5781 (set_attr "length" "4")
5782 (set_attr "type" "alu_sreg")]
5785 (define_insn "*arm_movsi_insn"
5786 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5787 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
5788 "TARGET_ARM && ! TARGET_IWMMXT
5789 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5790 && ( register_operand (operands[0], SImode)
5791 || register_operand (operands[1], SImode))"
5799 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
5800 (set_attr "predicable" "yes")
5801 (set_attr "pool_range" "*,*,*,*,4096,*")
5802 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5806 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5807 (match_operand:SI 1 "const_int_operand" ""))]
5809 && (!(const_ok_for_arm (INTVAL (operands[1]))
5810 || const_ok_for_arm (~INTVAL (operands[1]))))"
5811 [(clobber (const_int 0))]
5813 arm_split_constant (SET, SImode, NULL_RTX,
5814 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5819 ;; A normal way to do (symbol + offset) requires three instructions at least
5820 ;; (depends on how big the offset is) as below:
5821 ;; movw r0, #:lower16:g
5822 ;; movw r0, #:upper16:g
5825 ;; A better way would be:
5826 ;; movw r0, #:lower16:g+4
5827 ;; movw r0, #:upper16:g+4
5829 ;; The limitation of this way is that the length of offset should be a 16-bit
5830 ;; signed value, because current assembler only supports REL type relocation for
5831 ;; such case. If the more powerful RELA type is supported in future, we should
5832 ;; update this pattern to go with better way.
5834 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5835 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5836 (match_operand:SI 2 "const_int_operand" ""))))]
5838 && arm_disable_literal_pool
5840 && GET_CODE (operands[1]) == SYMBOL_REF"
5841 [(clobber (const_int 0))]
5843 int offset = INTVAL (operands[2]);
5845 if (offset < -0x8000 || offset > 0x7fff)
5847 arm_emit_movpair (operands[0], operands[1]);
5848 emit_insn (gen_rtx_SET (operands[0],
5849 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5853 rtx op = gen_rtx_CONST (SImode,
5854 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5855 arm_emit_movpair (operands[0], op);
5860 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5861 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5862 ;; and lo_sum would be merged back into memory load at cprop. However,
5863 ;; if the default is to prefer movt/movw rather than a load from the constant
5864 ;; pool, the performance is better.
5866 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5867 (match_operand:SI 1 "general_operand" ""))]
5869 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5870 && !flag_pic && !target_word_relocations
5871 && !arm_tls_referenced_p (operands[1])"
5872 [(clobber (const_int 0))]
5874 arm_emit_movpair (operands[0], operands[1]);
5878 ;; When generating pic, we need to load the symbol offset into a register.
5879 ;; So that the optimizer does not confuse this with a normal symbol load
5880 ;; we use an unspec. The offset will be loaded from a constant pool entry,
5881 ;; since that is the only type of relocation we can use.
5883 ;; Wrap calculation of the whole PIC address in a single pattern for the
5884 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5885 ;; a PIC address involves two loads from memory, so we want to CSE it
5886 ;; as often as possible.
5887 ;; This pattern will be split into one of the pic_load_addr_* patterns
5888 ;; and a move after GCSE optimizations.
5890 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5891 (define_expand "calculate_pic_address"
5892 [(set (match_operand:SI 0 "register_operand" "")
5893 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5894 (unspec:SI [(match_operand:SI 2 "" "")]
5899 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5901 [(set (match_operand:SI 0 "register_operand" "")
5902 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5903 (unspec:SI [(match_operand:SI 2 "" "")]
5906 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5907 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5908 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5911 ;; operand1 is the memory address to go into
5912 ;; pic_load_addr_32bit.
5913 ;; operand2 is the PIC label to be emitted
5914 ;; from pic_add_dot_plus_eight.
5915 ;; We do this to allow hoisting of the entire insn.
5916 (define_insn_and_split "pic_load_addr_unified"
5917 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5918 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5919 (match_operand:SI 2 "" "")]
5920 UNSPEC_PIC_UNIFIED))]
5923 "&& reload_completed"
5924 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5925 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5926 (match_dup 2)] UNSPEC_PIC_BASE))]
5927 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5928 [(set_attr "type" "load1,load1,load1")
5929 (set_attr "pool_range" "4096,4094,1022")
5930 (set_attr "neg_pool_range" "4084,0,0")
5931 (set_attr "arch" "a,t2,t1")
5932 (set_attr "length" "8,6,4")]
5935 ;; The rather odd constraints on the following are to force reload to leave
5936 ;; the insn alone, and to force the minipool generation pass to then move
5937 ;; the GOT symbol to memory.
5939 (define_insn "pic_load_addr_32bit"
5940 [(set (match_operand:SI 0 "s_register_operand" "=r")
5941 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5942 "TARGET_32BIT && flag_pic"
5944 [(set_attr "type" "load1")
5945 (set (attr "pool_range")
5946 (if_then_else (eq_attr "is_thumb" "no")
5949 (set (attr "neg_pool_range")
5950 (if_then_else (eq_attr "is_thumb" "no")
5955 (define_insn "pic_load_addr_thumb1"
5956 [(set (match_operand:SI 0 "s_register_operand" "=l")
5957 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5958 "TARGET_THUMB1 && flag_pic"
5960 [(set_attr "type" "load1")
5961 (set (attr "pool_range") (const_int 1018))]
5964 (define_insn "pic_add_dot_plus_four"
5965 [(set (match_operand:SI 0 "register_operand" "=r")
5966 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5968 (match_operand 2 "" "")]
5972 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5973 INTVAL (operands[2]));
5974 return \"add\\t%0, %|pc\";
5976 [(set_attr "length" "2")
5977 (set_attr "type" "alu_sreg")]
5980 (define_insn "pic_add_dot_plus_eight"
5981 [(set (match_operand:SI 0 "register_operand" "=r")
5982 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5984 (match_operand 2 "" "")]
5988 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5989 INTVAL (operands[2]));
5990 return \"add%?\\t%0, %|pc, %1\";
5992 [(set_attr "predicable" "yes")
5993 (set_attr "type" "alu_sreg")]
5996 (define_insn "tls_load_dot_plus_eight"
5997 [(set (match_operand:SI 0 "register_operand" "=r")
5998 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6000 (match_operand 2 "" "")]
6004 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6005 INTVAL (operands[2]));
6006 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6008 [(set_attr "predicable" "yes")
6009 (set_attr "type" "load1")]
6012 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6013 ;; followed by a load. These sequences can be crunched down to
6014 ;; tls_load_dot_plus_eight by a peephole.
6017 [(set (match_operand:SI 0 "register_operand" "")
6018 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6020 (match_operand 1 "" "")]
6022 (set (match_operand:SI 2 "arm_general_register_operand" "")
6023 (mem:SI (match_dup 0)))]
6024 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6026 (mem:SI (unspec:SI [(match_dup 3)
6033 (define_insn "pic_offset_arm"
6034 [(set (match_operand:SI 0 "register_operand" "=r")
6035 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6036 (unspec:SI [(match_operand:SI 2 "" "X")]
6037 UNSPEC_PIC_OFFSET))))]
6038 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6039 "ldr%?\\t%0, [%1,%2]"
6040 [(set_attr "type" "load1")]
6043 (define_expand "builtin_setjmp_receiver"
6044 [(label_ref (match_operand 0 "" ""))]
6048 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6050 if (arm_pic_register != INVALID_REGNUM)
6051 arm_load_pic_register (1UL << 3);
6055 ;; If copying one reg to another we can set the condition codes according to
6056 ;; its value. Such a move is common after a return from subroutine and the
6057 ;; result is being tested against zero.
6059 (define_insn "*movsi_compare0"
6060 [(set (reg:CC CC_REGNUM)
6061 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6063 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6069 [(set_attr "conds" "set")
6070 (set_attr "type" "alus_imm,alus_imm")]
6073 ;; Subroutine to store a half word from a register into memory.
6074 ;; Operand 0 is the source register (HImode)
6075 ;; Operand 1 is the destination address in a register (SImode)
6077 ;; In both this routine and the next, we must be careful not to spill
6078 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6079 ;; can generate unrecognizable rtl.
6081 (define_expand "storehi"
6082 [;; store the low byte
6083 (set (match_operand 1 "" "") (match_dup 3))
6084 ;; extract the high byte
6086 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6087 ;; store the high byte
6088 (set (match_dup 4) (match_dup 5))]
6092 rtx op1 = operands[1];
6093 rtx addr = XEXP (op1, 0);
6094 enum rtx_code code = GET_CODE (addr);
6096 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6098 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6100 operands[4] = adjust_address (op1, QImode, 1);
6101 operands[1] = adjust_address (operands[1], QImode, 0);
6102 operands[3] = gen_lowpart (QImode, operands[0]);
6103 operands[0] = gen_lowpart (SImode, operands[0]);
6104 operands[2] = gen_reg_rtx (SImode);
6105 operands[5] = gen_lowpart (QImode, operands[2]);
6109 (define_expand "storehi_bigend"
6110 [(set (match_dup 4) (match_dup 3))
6112 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6113 (set (match_operand 1 "" "") (match_dup 5))]
6117 rtx op1 = operands[1];
6118 rtx addr = XEXP (op1, 0);
6119 enum rtx_code code = GET_CODE (addr);
6121 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6123 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6125 operands[4] = adjust_address (op1, QImode, 1);
6126 operands[1] = adjust_address (operands[1], QImode, 0);
6127 operands[3] = gen_lowpart (QImode, operands[0]);
6128 operands[0] = gen_lowpart (SImode, operands[0]);
6129 operands[2] = gen_reg_rtx (SImode);
6130 operands[5] = gen_lowpart (QImode, operands[2]);
6134 ;; Subroutine to store a half word integer constant into memory.
6135 (define_expand "storeinthi"
6136 [(set (match_operand 0 "" "")
6137 (match_operand 1 "" ""))
6138 (set (match_dup 3) (match_dup 2))]
6142 HOST_WIDE_INT value = INTVAL (operands[1]);
6143 rtx addr = XEXP (operands[0], 0);
6144 rtx op0 = operands[0];
6145 enum rtx_code code = GET_CODE (addr);
6147 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6149 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6151 operands[1] = gen_reg_rtx (SImode);
6152 if (BYTES_BIG_ENDIAN)
6154 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6155 if ((value & 255) == ((value >> 8) & 255))
6156 operands[2] = operands[1];
6159 operands[2] = gen_reg_rtx (SImode);
6160 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6165 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6166 if ((value & 255) == ((value >> 8) & 255))
6167 operands[2] = operands[1];
6170 operands[2] = gen_reg_rtx (SImode);
6171 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6175 operands[3] = adjust_address (op0, QImode, 1);
6176 operands[0] = adjust_address (operands[0], QImode, 0);
6177 operands[2] = gen_lowpart (QImode, operands[2]);
6178 operands[1] = gen_lowpart (QImode, operands[1]);
6182 (define_expand "storehi_single_op"
6183 [(set (match_operand:HI 0 "memory_operand" "")
6184 (match_operand:HI 1 "general_operand" ""))]
6185 "TARGET_32BIT && arm_arch4"
6187 if (!s_register_operand (operands[1], HImode))
6188 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6192 (define_expand "movhi"
6193 [(set (match_operand:HI 0 "general_operand" "")
6194 (match_operand:HI 1 "general_operand" ""))]
6199 if (can_create_pseudo_p ())
6201 if (MEM_P (operands[0]))
6205 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6208 if (CONST_INT_P (operands[1]))
6209 emit_insn (gen_storeinthi (operands[0], operands[1]));
6212 if (MEM_P (operands[1]))
6213 operands[1] = force_reg (HImode, operands[1]);
6214 if (BYTES_BIG_ENDIAN)
6215 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6217 emit_insn (gen_storehi (operands[1], operands[0]));
6221 /* Sign extend a constant, and keep it in an SImode reg. */
6222 else if (CONST_INT_P (operands[1]))
6224 rtx reg = gen_reg_rtx (SImode);
6225 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6227 /* If the constant is already valid, leave it alone. */
6228 if (!const_ok_for_arm (val))
6230 /* If setting all the top bits will make the constant
6231 loadable in a single instruction, then set them.
6232 Otherwise, sign extend the number. */
6234 if (const_ok_for_arm (~(val | ~0xffff)))
6236 else if (val & 0x8000)
6240 emit_insn (gen_movsi (reg, GEN_INT (val)));
6241 operands[1] = gen_lowpart (HImode, reg);
6243 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6244 && MEM_P (operands[1]))
6246 rtx reg = gen_reg_rtx (SImode);
6248 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6249 operands[1] = gen_lowpart (HImode, reg);
6251 else if (!arm_arch4)
6253 if (MEM_P (operands[1]))
6256 rtx offset = const0_rtx;
6257 rtx reg = gen_reg_rtx (SImode);
6259 if ((REG_P (base = XEXP (operands[1], 0))
6260 || (GET_CODE (base) == PLUS
6261 && (CONST_INT_P (offset = XEXP (base, 1)))
6262 && ((INTVAL(offset) & 1) != 1)
6263 && REG_P (base = XEXP (base, 0))))
6264 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6268 new_rtx = widen_memory_access (operands[1], SImode,
6269 ((INTVAL (offset) & ~3)
6270 - INTVAL (offset)));
6271 emit_insn (gen_movsi (reg, new_rtx));
6272 if (((INTVAL (offset) & 2) != 0)
6273 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6275 rtx reg2 = gen_reg_rtx (SImode);
6277 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6282 emit_insn (gen_movhi_bytes (reg, operands[1]));
6284 operands[1] = gen_lowpart (HImode, reg);
6288 /* Handle loading a large integer during reload. */
6289 else if (CONST_INT_P (operands[1])
6290 && !const_ok_for_arm (INTVAL (operands[1]))
6291 && !const_ok_for_arm (~INTVAL (operands[1])))
6293 /* Writing a constant to memory needs a scratch, which should
6294 be handled with SECONDARY_RELOADs. */
6295 gcc_assert (REG_P (operands[0]));
6297 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6298 emit_insn (gen_movsi (operands[0], operands[1]));
6302 else if (TARGET_THUMB2)
6304 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6305 if (can_create_pseudo_p ())
6307 if (!REG_P (operands[0]))
6308 operands[1] = force_reg (HImode, operands[1]);
6309 /* Zero extend a constant, and keep it in an SImode reg. */
6310 else if (CONST_INT_P (operands[1]))
6312 rtx reg = gen_reg_rtx (SImode);
6313 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6315 emit_insn (gen_movsi (reg, GEN_INT (val)));
6316 operands[1] = gen_lowpart (HImode, reg);
6320 else /* TARGET_THUMB1 */
6322 if (can_create_pseudo_p ())
6324 if (CONST_INT_P (operands[1]))
6326 rtx reg = gen_reg_rtx (SImode);
6328 emit_insn (gen_movsi (reg, operands[1]));
6329 operands[1] = gen_lowpart (HImode, reg);
6332 /* ??? We shouldn't really get invalid addresses here, but this can
6333 happen if we are passed a SP (never OK for HImode/QImode) or
6334 virtual register (also rejected as illegitimate for HImode/QImode)
6335 relative address. */
6336 /* ??? This should perhaps be fixed elsewhere, for instance, in
6337 fixup_stack_1, by checking for other kinds of invalid addresses,
6338 e.g. a bare reference to a virtual register. This may confuse the
6339 alpha though, which must handle this case differently. */
6340 if (MEM_P (operands[0])
6341 && !memory_address_p (GET_MODE (operands[0]),
6342 XEXP (operands[0], 0)))
6344 = replace_equiv_address (operands[0],
6345 copy_to_reg (XEXP (operands[0], 0)));
6347 if (MEM_P (operands[1])
6348 && !memory_address_p (GET_MODE (operands[1]),
6349 XEXP (operands[1], 0)))
6351 = replace_equiv_address (operands[1],
6352 copy_to_reg (XEXP (operands[1], 0)));
6354 if (MEM_P (operands[1]) && optimize > 0)
6356 rtx reg = gen_reg_rtx (SImode);
6358 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6359 operands[1] = gen_lowpart (HImode, reg);
6362 if (MEM_P (operands[0]))
6363 operands[1] = force_reg (HImode, operands[1]);
6365 else if (CONST_INT_P (operands[1])
6366 && !satisfies_constraint_I (operands[1]))
6368 /* Handle loading a large integer during reload. */
6370 /* Writing a constant to memory needs a scratch, which should
6371 be handled with SECONDARY_RELOADs. */
6372 gcc_assert (REG_P (operands[0]));
6374 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6375 emit_insn (gen_movsi (operands[0], operands[1]));
6382 (define_expand "movhi_bytes"
6383 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6385 (zero_extend:SI (match_dup 6)))
6386 (set (match_operand:SI 0 "" "")
6387 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6392 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6394 mem1 = change_address (operands[1], QImode, addr);
6395 mem2 = change_address (operands[1], QImode,
6396 plus_constant (Pmode, addr, 1));
6397 operands[0] = gen_lowpart (SImode, operands[0]);
6399 operands[2] = gen_reg_rtx (SImode);
6400 operands[3] = gen_reg_rtx (SImode);
6403 if (BYTES_BIG_ENDIAN)
6405 operands[4] = operands[2];
6406 operands[5] = operands[3];
6410 operands[4] = operands[3];
6411 operands[5] = operands[2];
6416 (define_expand "movhi_bigend"
6418 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6421 (ashiftrt:SI (match_dup 2) (const_int 16)))
6422 (set (match_operand:HI 0 "s_register_operand" "")
6426 operands[2] = gen_reg_rtx (SImode);
6427 operands[3] = gen_reg_rtx (SImode);
6428 operands[4] = gen_lowpart (HImode, operands[3]);
6432 ;; Pattern to recognize insn generated default case above
6433 (define_insn "*movhi_insn_arch4"
6434 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6435 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6438 && (register_operand (operands[0], HImode)
6439 || register_operand (operands[1], HImode))"
6441 mov%?\\t%0, %1\\t%@ movhi
6442 mvn%?\\t%0, #%B1\\t%@ movhi
6443 movw%?\\t%0, %L1\\t%@ movhi
6444 str%(h%)\\t%1, %0\\t%@ movhi
6445 ldr%(h%)\\t%0, %1\\t%@ movhi"
6446 [(set_attr "predicable" "yes")
6447 (set_attr "pool_range" "*,*,*,*,256")
6448 (set_attr "neg_pool_range" "*,*,*,*,244")
6449 (set_attr "arch" "*,*,v6t2,*,*")
6450 (set_attr_alternative "type"
6451 [(if_then_else (match_operand 1 "const_int_operand" "")
6452 (const_string "mov_imm" )
6453 (const_string "mov_reg"))
6454 (const_string "mvn_imm")
6455 (const_string "mov_imm")
6456 (const_string "store1")
6457 (const_string "load1")])]
6460 (define_insn "*movhi_bytes"
6461 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6462 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6465 mov%?\\t%0, %1\\t%@ movhi
6466 mov%?\\t%0, %1\\t%@ movhi
6467 mvn%?\\t%0, #%B1\\t%@ movhi"
6468 [(set_attr "predicable" "yes")
6469 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6472 ;; We use a DImode scratch because we may occasionally need an additional
6473 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6474 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6475 (define_expand "reload_outhi"
6476 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6477 (match_operand:HI 1 "s_register_operand" "r")
6478 (match_operand:DI 2 "s_register_operand" "=&l")])]
6481 arm_reload_out_hi (operands);
6483 thumb_reload_out_hi (operands);
6488 (define_expand "reload_inhi"
6489 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6490 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6491 (match_operand:DI 2 "s_register_operand" "=&r")])]
6495 arm_reload_in_hi (operands);
6497 thumb_reload_out_hi (operands);
6501 (define_expand "movqi"
6502 [(set (match_operand:QI 0 "general_operand" "")
6503 (match_operand:QI 1 "general_operand" ""))]
6506 /* Everything except mem = const or mem = mem can be done easily */
6508 if (can_create_pseudo_p ())
6510 if (CONST_INT_P (operands[1]))
6512 rtx reg = gen_reg_rtx (SImode);
6514 /* For thumb we want an unsigned immediate, then we are more likely
6515 to be able to use a movs insn. */
6517 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6519 emit_insn (gen_movsi (reg, operands[1]));
6520 operands[1] = gen_lowpart (QImode, reg);
6525 /* ??? We shouldn't really get invalid addresses here, but this can
6526 happen if we are passed a SP (never OK for HImode/QImode) or
6527 virtual register (also rejected as illegitimate for HImode/QImode)
6528 relative address. */
6529 /* ??? This should perhaps be fixed elsewhere, for instance, in
6530 fixup_stack_1, by checking for other kinds of invalid addresses,
6531 e.g. a bare reference to a virtual register. This may confuse the
6532 alpha though, which must handle this case differently. */
6533 if (MEM_P (operands[0])
6534 && !memory_address_p (GET_MODE (operands[0]),
6535 XEXP (operands[0], 0)))
6537 = replace_equiv_address (operands[0],
6538 copy_to_reg (XEXP (operands[0], 0)));
6539 if (MEM_P (operands[1])
6540 && !memory_address_p (GET_MODE (operands[1]),
6541 XEXP (operands[1], 0)))
6543 = replace_equiv_address (operands[1],
6544 copy_to_reg (XEXP (operands[1], 0)));
6547 if (MEM_P (operands[1]) && optimize > 0)
6549 rtx reg = gen_reg_rtx (SImode);
6551 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6552 operands[1] = gen_lowpart (QImode, reg);
6555 if (MEM_P (operands[0]))
6556 operands[1] = force_reg (QImode, operands[1]);
6558 else if (TARGET_THUMB
6559 && CONST_INT_P (operands[1])
6560 && !satisfies_constraint_I (operands[1]))
6562 /* Handle loading a large integer during reload. */
6564 /* Writing a constant to memory needs a scratch, which should
6565 be handled with SECONDARY_RELOADs. */
6566 gcc_assert (REG_P (operands[0]));
6568 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6569 emit_insn (gen_movsi (operands[0], operands[1]));
6575 (define_insn "*arm_movqi_insn"
6576 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6577 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6579 && ( register_operand (operands[0], QImode)
6580 || register_operand (operands[1], QImode))"
6591 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6592 (set_attr "predicable" "yes")
6593 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6594 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6595 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6599 (define_expand "movhf"
6600 [(set (match_operand:HF 0 "general_operand" "")
6601 (match_operand:HF 1 "general_operand" ""))]
6606 if (MEM_P (operands[0]))
6607 operands[1] = force_reg (HFmode, operands[1]);
6609 else /* TARGET_THUMB1 */
6611 if (can_create_pseudo_p ())
6613 if (!REG_P (operands[0]))
6614 operands[1] = force_reg (HFmode, operands[1]);
6620 (define_insn "*arm32_movhf"
6621 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6622 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6623 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16)
6624 && ( s_register_operand (operands[0], HFmode)
6625 || s_register_operand (operands[1], HFmode))"
6627 switch (which_alternative)
6629 case 0: /* ARM register from memory */
6630 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6631 case 1: /* memory from ARM register */
6632 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6633 case 2: /* ARM register from ARM register */
6634 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6635 case 3: /* ARM register from constant */
6641 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6642 bits = real_to_target (NULL, &r, HFmode);
6643 ops[0] = operands[0];
6644 ops[1] = GEN_INT (bits);
6645 ops[2] = GEN_INT (bits & 0xff00);
6646 ops[3] = GEN_INT (bits & 0x00ff);
6648 if (arm_arch_thumb2)
6649 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6651 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6658 [(set_attr "conds" "unconditional")
6659 (set_attr "type" "load1,store1,mov_reg,multiple")
6660 (set_attr "length" "4,4,4,8")
6661 (set_attr "predicable" "yes")
6662 (set_attr "predicable_short_it" "no")]
6665 (define_expand "movsf"
6666 [(set (match_operand:SF 0 "general_operand" "")
6667 (match_operand:SF 1 "general_operand" ""))]
6672 if (MEM_P (operands[0]))
6673 operands[1] = force_reg (SFmode, operands[1]);
6675 else /* TARGET_THUMB1 */
6677 if (can_create_pseudo_p ())
6679 if (!REG_P (operands[0]))
6680 operands[1] = force_reg (SFmode, operands[1]);
6686 ;; Transform a floating-point move of a constant into a core register into
6687 ;; an SImode operation.
6689 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6690 (match_operand:SF 1 "immediate_operand" ""))]
6693 && CONST_DOUBLE_P (operands[1])"
6694 [(set (match_dup 2) (match_dup 3))]
6696 operands[2] = gen_lowpart (SImode, operands[0]);
6697 operands[3] = gen_lowpart (SImode, operands[1]);
6698 if (operands[2] == 0 || operands[3] == 0)
6703 (define_insn "*arm_movsf_soft_insn"
6704 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6705 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6707 && TARGET_SOFT_FLOAT
6708 && (!MEM_P (operands[0])
6709 || register_operand (operands[1], SFmode))"
6712 ldr%?\\t%0, %1\\t%@ float
6713 str%?\\t%1, %0\\t%@ float"
6714 [(set_attr "predicable" "yes")
6715 (set_attr "predicable_short_it" "no")
6716 (set_attr "type" "mov_reg,load1,store1")
6717 (set_attr "arm_pool_range" "*,4096,*")
6718 (set_attr "thumb2_pool_range" "*,4094,*")
6719 (set_attr "arm_neg_pool_range" "*,4084,*")
6720 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6723 (define_expand "movdf"
6724 [(set (match_operand:DF 0 "general_operand" "")
6725 (match_operand:DF 1 "general_operand" ""))]
6730 if (MEM_P (operands[0]))
6731 operands[1] = force_reg (DFmode, operands[1]);
6733 else /* TARGET_THUMB */
6735 if (can_create_pseudo_p ())
6737 if (!REG_P (operands[0]))
6738 operands[1] = force_reg (DFmode, operands[1]);
6744 ;; Reloading a df mode value stored in integer regs to memory can require a
6746 (define_expand "reload_outdf"
6747 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6748 (match_operand:DF 1 "s_register_operand" "r")
6749 (match_operand:SI 2 "s_register_operand" "=&r")]
6753 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6756 operands[2] = XEXP (operands[0], 0);
6757 else if (code == POST_INC || code == PRE_DEC)
6759 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6760 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6761 emit_insn (gen_movdi (operands[0], operands[1]));
6764 else if (code == PRE_INC)
6766 rtx reg = XEXP (XEXP (operands[0], 0), 0);
6768 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6771 else if (code == POST_DEC)
6772 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6774 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6775 XEXP (XEXP (operands[0], 0), 1)));
6777 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
6780 if (code == POST_DEC)
6781 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6787 (define_insn "*movdf_soft_insn"
6788 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6789 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
6790 "TARGET_32BIT && TARGET_SOFT_FLOAT
6791 && ( register_operand (operands[0], DFmode)
6792 || register_operand (operands[1], DFmode))"
6794 switch (which_alternative)
6801 return output_move_double (operands, true, NULL);
6804 [(set_attr "length" "8,12,16,8,8")
6805 (set_attr "type" "multiple,multiple,multiple,load2,store2")
6806 (set_attr "arm_pool_range" "*,*,*,1020,*")
6807 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6808 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6809 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6813 ;; load- and store-multiple insns
6814 ;; The arm can load/store any set of registers, provided that they are in
6815 ;; ascending order, but these expanders assume a contiguous set.
6817 (define_expand "load_multiple"
6818 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6819 (match_operand:SI 1 "" ""))
6820 (use (match_operand:SI 2 "" ""))])]
6823 HOST_WIDE_INT offset = 0;
6825 /* Support only fixed point registers. */
6826 if (!CONST_INT_P (operands[2])
6827 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6828 || INTVAL (operands[2]) < 2
6829 || !MEM_P (operands[1])
6830 || !REG_P (operands[0])
6831 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6832 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6836 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6837 INTVAL (operands[2]),
6838 force_reg (SImode, XEXP (operands[1], 0)),
6839 FALSE, operands[1], &offset);
6842 (define_expand "store_multiple"
6843 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6844 (match_operand:SI 1 "" ""))
6845 (use (match_operand:SI 2 "" ""))])]
6848 HOST_WIDE_INT offset = 0;
6850 /* Support only fixed point registers. */
6851 if (!CONST_INT_P (operands[2])
6852 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6853 || INTVAL (operands[2]) < 2
6854 || !REG_P (operands[1])
6855 || !MEM_P (operands[0])
6856 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6857 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6861 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6862 INTVAL (operands[2]),
6863 force_reg (SImode, XEXP (operands[0], 0)),
6864 FALSE, operands[0], &offset);
6868 (define_expand "setmemsi"
6869 [(match_operand:BLK 0 "general_operand" "")
6870 (match_operand:SI 1 "const_int_operand" "")
6871 (match_operand:SI 2 "const_int_operand" "")
6872 (match_operand:SI 3 "const_int_operand" "")]
6875 if (arm_gen_setmem (operands))
6882 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6883 ;; We could let this apply for blocks of less than this, but it clobbers so
6884 ;; many registers that there is then probably a better way.
6886 (define_expand "movmemqi"
6887 [(match_operand:BLK 0 "general_operand" "")
6888 (match_operand:BLK 1 "general_operand" "")
6889 (match_operand:SI 2 "const_int_operand" "")
6890 (match_operand:SI 3 "const_int_operand" "")]
6895 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6896 && !optimize_function_for_size_p (cfun))
6898 if (gen_movmem_ldrd_strd (operands))
6903 if (arm_gen_movmemqi (operands))
6907 else /* TARGET_THUMB1 */
6909 if ( INTVAL (operands[3]) != 4
6910 || INTVAL (operands[2]) > 48)
6913 thumb_expand_movmemqi (operands);
6920 ;; Compare & branch insns
6921 ;; The range calculations are based as follows:
6922 ;; For forward branches, the address calculation returns the address of
6923 ;; the next instruction. This is 2 beyond the branch instruction.
6924 ;; For backward branches, the address calculation returns the address of
6925 ;; the first instruction in this pattern (cmp). This is 2 before the branch
6926 ;; instruction for the shortest sequence, and 4 before the branch instruction
6927 ;; if we have to jump around an unconditional branch.
6928 ;; To the basic branch range the PC offset must be added (this is +4).
6929 ;; So for forward branches we have
6930 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6931 ;; And for backward branches we have
6932 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6934 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6935 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
6937 (define_expand "cbranchsi4"
6938 [(set (pc) (if_then_else
6939 (match_operator 0 "expandable_comparison_operator"
6940 [(match_operand:SI 1 "s_register_operand" "")
6941 (match_operand:SI 2 "nonmemory_operand" "")])
6942 (label_ref (match_operand 3 "" ""))
6948 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6950 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6954 if (thumb1_cmpneg_operand (operands[2], SImode))
6956 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6957 operands[3], operands[0]));
6960 if (!thumb1_cmp_operand (operands[2], SImode))
6961 operands[2] = force_reg (SImode, operands[2]);
6964 (define_expand "cbranchsf4"
6965 [(set (pc) (if_then_else
6966 (match_operator 0 "expandable_comparison_operator"
6967 [(match_operand:SF 1 "s_register_operand" "")
6968 (match_operand:SF 2 "arm_float_compare_operand" "")])
6969 (label_ref (match_operand 3 "" ""))
6971 "TARGET_32BIT && TARGET_HARD_FLOAT"
6972 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6973 operands[3])); DONE;"
6976 (define_expand "cbranchdf4"
6977 [(set (pc) (if_then_else
6978 (match_operator 0 "expandable_comparison_operator"
6979 [(match_operand:DF 1 "s_register_operand" "")
6980 (match_operand:DF 2 "arm_float_compare_operand" "")])
6981 (label_ref (match_operand 3 "" ""))
6983 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6984 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6985 operands[3])); DONE;"
6988 (define_expand "cbranchdi4"
6989 [(set (pc) (if_then_else
6990 (match_operator 0 "expandable_comparison_operator"
6991 [(match_operand:DI 1 "s_register_operand" "")
6992 (match_operand:DI 2 "cmpdi_operand" "")])
6993 (label_ref (match_operand 3 "" ""))
6997 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6999 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7005 ;; Comparison and test insns
7007 (define_insn "*arm_cmpsi_insn"
7008 [(set (reg:CC CC_REGNUM)
7009 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7010 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7018 [(set_attr "conds" "set")
7019 (set_attr "arch" "t2,t2,any,any,any")
7020 (set_attr "length" "2,2,4,4,4")
7021 (set_attr "predicable" "yes")
7022 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7023 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7026 (define_insn "*cmpsi_shiftsi"
7027 [(set (reg:CC CC_REGNUM)
7028 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7029 (match_operator:SI 3 "shift_operator"
7030 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7031 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7034 [(set_attr "conds" "set")
7035 (set_attr "shift" "1")
7036 (set_attr "arch" "32,a,a")
7037 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7039 (define_insn "*cmpsi_shiftsi_swp"
7040 [(set (reg:CC_SWP CC_REGNUM)
7041 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7042 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7043 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7044 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7047 [(set_attr "conds" "set")
7048 (set_attr "shift" "1")
7049 (set_attr "arch" "32,a,a")
7050 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7052 (define_insn "*arm_cmpsi_negshiftsi_si"
7053 [(set (reg:CC_Z CC_REGNUM)
7055 (neg:SI (match_operator:SI 1 "shift_operator"
7056 [(match_operand:SI 2 "s_register_operand" "r")
7057 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7058 (match_operand:SI 0 "s_register_operand" "r")))]
7061 [(set_attr "conds" "set")
7062 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7063 (const_string "alus_shift_imm")
7064 (const_string "alus_shift_reg")))
7065 (set_attr "predicable" "yes")]
7068 ;; DImode comparisons. The generic code generates branches that
7069 ;; if-conversion can not reduce to a conditional compare, so we do
7072 (define_insn_and_split "*arm_cmpdi_insn"
7073 [(set (reg:CC_NCV CC_REGNUM)
7074 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7075 (match_operand:DI 1 "arm_di_operand" "rDi")))
7076 (clobber (match_scratch:SI 2 "=r"))]
7078 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7079 "&& reload_completed"
7080 [(set (reg:CC CC_REGNUM)
7081 (compare:CC (match_dup 0) (match_dup 1)))
7082 (parallel [(set (reg:CC CC_REGNUM)
7083 (compare:CC (match_dup 3) (match_dup 4)))
7085 (minus:SI (match_dup 5)
7086 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7088 operands[3] = gen_highpart (SImode, operands[0]);
7089 operands[0] = gen_lowpart (SImode, operands[0]);
7090 if (CONST_INT_P (operands[1]))
7092 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7095 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7099 operands[4] = gen_highpart (SImode, operands[1]);
7100 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7102 operands[1] = gen_lowpart (SImode, operands[1]);
7103 operands[2] = gen_lowpart (SImode, operands[2]);
7105 [(set_attr "conds" "set")
7106 (set_attr "length" "8")
7107 (set_attr "type" "multiple")]
7110 (define_insn_and_split "*arm_cmpdi_unsigned"
7111 [(set (reg:CC_CZ CC_REGNUM)
7112 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7113 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7116 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7117 "&& reload_completed"
7118 [(set (reg:CC CC_REGNUM)
7119 (compare:CC (match_dup 2) (match_dup 3)))
7120 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7121 (set (reg:CC CC_REGNUM)
7122 (compare:CC (match_dup 0) (match_dup 1))))]
7124 operands[2] = gen_highpart (SImode, operands[0]);
7125 operands[0] = gen_lowpart (SImode, operands[0]);
7126 if (CONST_INT_P (operands[1]))
7127 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7129 operands[3] = gen_highpart (SImode, operands[1]);
7130 operands[1] = gen_lowpart (SImode, operands[1]);
7132 [(set_attr "conds" "set")
7133 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7134 (set_attr "arch" "t2,t2,t2,a")
7135 (set_attr "length" "6,6,10,8")
7136 (set_attr "type" "multiple")]
7139 (define_insn "*arm_cmpdi_zero"
7140 [(set (reg:CC_Z CC_REGNUM)
7141 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7143 (clobber (match_scratch:SI 1 "=r"))]
7145 "orr%.\\t%1, %Q0, %R0"
7146 [(set_attr "conds" "set")
7147 (set_attr "type" "logics_reg")]
7150 ; This insn allows redundant compares to be removed by cse, nothing should
7151 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7152 ; is deleted later on. The match_dup will match the mode here, so that
7153 ; mode changes of the condition codes aren't lost by this even though we don't
7154 ; specify what they are.
7156 (define_insn "*deleted_compare"
7157 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7159 "\\t%@ deleted compare"
7160 [(set_attr "conds" "set")
7161 (set_attr "length" "0")
7162 (set_attr "type" "no_insn")]
7166 ;; Conditional branch insns
7168 (define_expand "cbranch_cc"
7170 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7171 (match_operand 2 "" "")])
7172 (label_ref (match_operand 3 "" ""))
7175 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7176 operands[1], operands[2], NULL_RTX);
7177 operands[2] = const0_rtx;"
7181 ;; Patterns to match conditional branch insns.
7184 (define_insn "arm_cond_branch"
7186 (if_then_else (match_operator 1 "arm_comparison_operator"
7187 [(match_operand 2 "cc_register" "") (const_int 0)])
7188 (label_ref (match_operand 0 "" ""))
7192 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7194 arm_ccfsm_state += 2;
7197 return \"b%d1\\t%l0\";
7199 [(set_attr "conds" "use")
7200 (set_attr "type" "branch")
7201 (set (attr "length")
7203 (and (match_test "TARGET_THUMB2")
7204 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7205 (le (minus (match_dup 0) (pc)) (const_int 256))))
7210 (define_insn "*arm_cond_branch_reversed"
7212 (if_then_else (match_operator 1 "arm_comparison_operator"
7213 [(match_operand 2 "cc_register" "") (const_int 0)])
7215 (label_ref (match_operand 0 "" ""))))]
7218 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7220 arm_ccfsm_state += 2;
7223 return \"b%D1\\t%l0\";
7225 [(set_attr "conds" "use")
7226 (set_attr "type" "branch")
7227 (set (attr "length")
7229 (and (match_test "TARGET_THUMB2")
7230 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7231 (le (minus (match_dup 0) (pc)) (const_int 256))))
7240 (define_expand "cstore_cc"
7241 [(set (match_operand:SI 0 "s_register_operand" "")
7242 (match_operator:SI 1 "" [(match_operand 2 "" "")
7243 (match_operand 3 "" "")]))]
7245 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7246 operands[2], operands[3], NULL_RTX);
7247 operands[3] = const0_rtx;"
7250 (define_insn_and_split "*mov_scc"
7251 [(set (match_operand:SI 0 "s_register_operand" "=r")
7252 (match_operator:SI 1 "arm_comparison_operator"
7253 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7255 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7258 (if_then_else:SI (match_dup 1)
7262 [(set_attr "conds" "use")
7263 (set_attr "length" "8")
7264 (set_attr "type" "multiple")]
7267 (define_insn_and_split "*mov_negscc"
7268 [(set (match_operand:SI 0 "s_register_operand" "=r")
7269 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7270 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7272 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7275 (if_then_else:SI (match_dup 1)
7279 operands[3] = GEN_INT (~0);
7281 [(set_attr "conds" "use")
7282 (set_attr "length" "8")
7283 (set_attr "type" "multiple")]
7286 (define_insn_and_split "*mov_notscc"
7287 [(set (match_operand:SI 0 "s_register_operand" "=r")
7288 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7289 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7291 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7294 (if_then_else:SI (match_dup 1)
7298 operands[3] = GEN_INT (~1);
7299 operands[4] = GEN_INT (~0);
7301 [(set_attr "conds" "use")
7302 (set_attr "length" "8")
7303 (set_attr "type" "multiple")]
7306 (define_expand "cstoresi4"
7307 [(set (match_operand:SI 0 "s_register_operand" "")
7308 (match_operator:SI 1 "expandable_comparison_operator"
7309 [(match_operand:SI 2 "s_register_operand" "")
7310 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7311 "TARGET_32BIT || TARGET_THUMB1"
7313 rtx op3, scratch, scratch2;
7317 if (!arm_add_operand (operands[3], SImode))
7318 operands[3] = force_reg (SImode, operands[3]);
7319 emit_insn (gen_cstore_cc (operands[0], operands[1],
7320 operands[2], operands[3]));
7324 if (operands[3] == const0_rtx)
7326 switch (GET_CODE (operands[1]))
7329 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7333 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7337 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7338 NULL_RTX, 0, OPTAB_WIDEN);
7339 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7340 NULL_RTX, 0, OPTAB_WIDEN);
7341 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7342 operands[0], 1, OPTAB_WIDEN);
7346 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7348 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7349 NULL_RTX, 1, OPTAB_WIDEN);
7353 scratch = expand_binop (SImode, ashr_optab, operands[2],
7354 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7355 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7356 NULL_RTX, 0, OPTAB_WIDEN);
7357 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7361 /* LT is handled by generic code. No need for unsigned with 0. */
7368 switch (GET_CODE (operands[1]))
7371 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7372 NULL_RTX, 0, OPTAB_WIDEN);
7373 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7377 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7378 NULL_RTX, 0, OPTAB_WIDEN);
7379 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7383 op3 = force_reg (SImode, operands[3]);
7385 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7386 NULL_RTX, 1, OPTAB_WIDEN);
7387 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7388 NULL_RTX, 0, OPTAB_WIDEN);
7389 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7395 if (!thumb1_cmp_operand (op3, SImode))
7396 op3 = force_reg (SImode, op3);
7397 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7398 NULL_RTX, 0, OPTAB_WIDEN);
7399 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7400 NULL_RTX, 1, OPTAB_WIDEN);
7401 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7406 op3 = force_reg (SImode, operands[3]);
7407 scratch = force_reg (SImode, const0_rtx);
7408 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7414 if (!thumb1_cmp_operand (op3, SImode))
7415 op3 = force_reg (SImode, op3);
7416 scratch = force_reg (SImode, const0_rtx);
7417 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7423 if (!thumb1_cmp_operand (op3, SImode))
7424 op3 = force_reg (SImode, op3);
7425 scratch = gen_reg_rtx (SImode);
7426 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7430 op3 = force_reg (SImode, operands[3]);
7431 scratch = gen_reg_rtx (SImode);
7432 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7435 /* No good sequences for GT, LT. */
7442 (define_expand "cstoresf4"
7443 [(set (match_operand:SI 0 "s_register_operand" "")
7444 (match_operator:SI 1 "expandable_comparison_operator"
7445 [(match_operand:SF 2 "s_register_operand" "")
7446 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7447 "TARGET_32BIT && TARGET_HARD_FLOAT"
7448 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7449 operands[2], operands[3])); DONE;"
7452 (define_expand "cstoredf4"
7453 [(set (match_operand:SI 0 "s_register_operand" "")
7454 (match_operator:SI 1 "expandable_comparison_operator"
7455 [(match_operand:DF 2 "s_register_operand" "")
7456 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7457 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7458 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7459 operands[2], operands[3])); DONE;"
7462 (define_expand "cstoredi4"
7463 [(set (match_operand:SI 0 "s_register_operand" "")
7464 (match_operator:SI 1 "expandable_comparison_operator"
7465 [(match_operand:DI 2 "s_register_operand" "")
7466 (match_operand:DI 3 "cmpdi_operand" "")]))]
7469 if (!arm_validize_comparison (&operands[1],
7473 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7480 ;; Conditional move insns
7482 (define_expand "movsicc"
7483 [(set (match_operand:SI 0 "s_register_operand" "")
7484 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7485 (match_operand:SI 2 "arm_not_operand" "")
7486 (match_operand:SI 3 "arm_not_operand" "")))]
7493 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7494 &XEXP (operands[1], 1)))
7497 code = GET_CODE (operands[1]);
7498 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7499 XEXP (operands[1], 1), NULL_RTX);
7500 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7504 (define_expand "movsfcc"
7505 [(set (match_operand:SF 0 "s_register_operand" "")
7506 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7507 (match_operand:SF 2 "s_register_operand" "")
7508 (match_operand:SF 3 "s_register_operand" "")))]
7509 "TARGET_32BIT && TARGET_HARD_FLOAT"
7512 enum rtx_code code = GET_CODE (operands[1]);
7515 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7516 &XEXP (operands[1], 1)))
7519 code = GET_CODE (operands[1]);
7520 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7521 XEXP (operands[1], 1), NULL_RTX);
7522 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7526 (define_expand "movdfcc"
7527 [(set (match_operand:DF 0 "s_register_operand" "")
7528 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7529 (match_operand:DF 2 "s_register_operand" "")
7530 (match_operand:DF 3 "s_register_operand" "")))]
7531 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7534 enum rtx_code code = GET_CODE (operands[1]);
7537 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7538 &XEXP (operands[1], 1)))
7540 code = GET_CODE (operands[1]);
7541 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7542 XEXP (operands[1], 1), NULL_RTX);
7543 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7547 (define_insn "*cmov<mode>"
7548 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7549 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7550 [(match_operand 2 "cc_register" "") (const_int 0)])
7551 (match_operand:SDF 3 "s_register_operand"
7553 (match_operand:SDF 4 "s_register_operand"
7554 "<F_constraint>")))]
7555 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7558 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7565 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7570 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7576 [(set_attr "conds" "use")
7577 (set_attr "type" "fcsel")]
7580 (define_insn_and_split "*movsicc_insn"
7581 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7583 (match_operator 3 "arm_comparison_operator"
7584 [(match_operand 4 "cc_register" "") (const_int 0)])
7585 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7586 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7597 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7598 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7599 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7600 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7601 "&& reload_completed"
7604 enum rtx_code rev_code;
7608 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7610 gen_rtx_SET (operands[0], operands[1])));
7612 rev_code = GET_CODE (operands[3]);
7613 mode = GET_MODE (operands[4]);
7614 if (mode == CCFPmode || mode == CCFPEmode)
7615 rev_code = reverse_condition_maybe_unordered (rev_code);
7617 rev_code = reverse_condition (rev_code);
7619 rev_cond = gen_rtx_fmt_ee (rev_code,
7623 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7625 gen_rtx_SET (operands[0], operands[2])));
7628 [(set_attr "length" "4,4,4,4,8,8,8,8")
7629 (set_attr "conds" "use")
7630 (set_attr_alternative "type"
7631 [(if_then_else (match_operand 2 "const_int_operand" "")
7632 (const_string "mov_imm")
7633 (const_string "mov_reg"))
7634 (const_string "mvn_imm")
7635 (if_then_else (match_operand 1 "const_int_operand" "")
7636 (const_string "mov_imm")
7637 (const_string "mov_reg"))
7638 (const_string "mvn_imm")
7639 (const_string "multiple")
7640 (const_string "multiple")
7641 (const_string "multiple")
7642 (const_string "multiple")])]
7645 (define_insn "*movsfcc_soft_insn"
7646 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7647 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7648 [(match_operand 4 "cc_register" "") (const_int 0)])
7649 (match_operand:SF 1 "s_register_operand" "0,r")
7650 (match_operand:SF 2 "s_register_operand" "r,0")))]
7651 "TARGET_ARM && TARGET_SOFT_FLOAT"
7655 [(set_attr "conds" "use")
7656 (set_attr "type" "mov_reg")]
7660 ;; Jump and linkage insns
7662 (define_expand "jump"
7664 (label_ref (match_operand 0 "" "")))]
7669 (define_insn "*arm_jump"
7671 (label_ref (match_operand 0 "" "")))]
7675 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7677 arm_ccfsm_state += 2;
7680 return \"b%?\\t%l0\";
7683 [(set_attr "predicable" "yes")
7684 (set (attr "length")
7686 (and (match_test "TARGET_THUMB2")
7687 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7688 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7691 (set_attr "type" "branch")]
7694 (define_expand "call"
7695 [(parallel [(call (match_operand 0 "memory_operand" "")
7696 (match_operand 1 "general_operand" ""))
7697 (use (match_operand 2 "" ""))
7698 (clobber (reg:SI LR_REGNUM))])]
7704 /* In an untyped call, we can get NULL for operand 2. */
7705 if (operands[2] == NULL_RTX)
7706 operands[2] = const0_rtx;
7708 /* Decide if we should generate indirect calls by loading the
7709 32-bit address of the callee into a register before performing the
7711 callee = XEXP (operands[0], 0);
7712 if (GET_CODE (callee) == SYMBOL_REF
7713 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7715 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7717 pat = gen_call_internal (operands[0], operands[1], operands[2]);
7718 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7723 (define_expand "call_internal"
7724 [(parallel [(call (match_operand 0 "memory_operand" "")
7725 (match_operand 1 "general_operand" ""))
7726 (use (match_operand 2 "" ""))
7727 (clobber (reg:SI LR_REGNUM))])])
7729 (define_insn "*call_reg_armv5"
7730 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7731 (match_operand 1 "" ""))
7732 (use (match_operand 2 "" ""))
7733 (clobber (reg:SI LR_REGNUM))]
7734 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7736 [(set_attr "type" "call")]
7739 (define_insn "*call_reg_arm"
7740 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7741 (match_operand 1 "" ""))
7742 (use (match_operand 2 "" ""))
7743 (clobber (reg:SI LR_REGNUM))]
7744 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7746 return output_call (operands);
7748 ;; length is worst case, normally it is only two
7749 [(set_attr "length" "12")
7750 (set_attr "type" "call")]
7754 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7755 ;; considered a function call by the branch predictor of some cores (PR40887).
7756 ;; Falls back to blx rN (*call_reg_armv5).
7758 (define_insn "*call_mem"
7759 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
7760 (match_operand 1 "" ""))
7761 (use (match_operand 2 "" ""))
7762 (clobber (reg:SI LR_REGNUM))]
7763 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7765 return output_call_mem (operands);
7767 [(set_attr "length" "12")
7768 (set_attr "type" "call")]
7771 (define_expand "call_value"
7772 [(parallel [(set (match_operand 0 "" "")
7773 (call (match_operand 1 "memory_operand" "")
7774 (match_operand 2 "general_operand" "")))
7775 (use (match_operand 3 "" ""))
7776 (clobber (reg:SI LR_REGNUM))])]
7782 /* In an untyped call, we can get NULL for operand 2. */
7783 if (operands[3] == 0)
7784 operands[3] = const0_rtx;
7786 /* Decide if we should generate indirect calls by loading the
7787 32-bit address of the callee into a register before performing the
7789 callee = XEXP (operands[1], 0);
7790 if (GET_CODE (callee) == SYMBOL_REF
7791 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7793 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7795 pat = gen_call_value_internal (operands[0], operands[1],
7796 operands[2], operands[3]);
7797 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7802 (define_expand "call_value_internal"
7803 [(parallel [(set (match_operand 0 "" "")
7804 (call (match_operand 1 "memory_operand" "")
7805 (match_operand 2 "general_operand" "")))
7806 (use (match_operand 3 "" ""))
7807 (clobber (reg:SI LR_REGNUM))])])
7809 (define_insn "*call_value_reg_armv5"
7810 [(set (match_operand 0 "" "")
7811 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7812 (match_operand 2 "" "")))
7813 (use (match_operand 3 "" ""))
7814 (clobber (reg:SI LR_REGNUM))]
7815 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7817 [(set_attr "type" "call")]
7820 (define_insn "*call_value_reg_arm"
7821 [(set (match_operand 0 "" "")
7822 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7823 (match_operand 2 "" "")))
7824 (use (match_operand 3 "" ""))
7825 (clobber (reg:SI LR_REGNUM))]
7826 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7828 return output_call (&operands[1]);
7830 [(set_attr "length" "12")
7831 (set_attr "type" "call")]
7834 ;; Note: see *call_mem
7836 (define_insn "*call_value_mem"
7837 [(set (match_operand 0 "" "")
7838 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
7839 (match_operand 2 "" "")))
7840 (use (match_operand 3 "" ""))
7841 (clobber (reg:SI LR_REGNUM))]
7842 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7843 && !SIBLING_CALL_P (insn)"
7845 return output_call_mem (&operands[1]);
7847 [(set_attr "length" "12")
7848 (set_attr "type" "call")]
7851 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7852 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7854 (define_insn "*call_symbol"
7855 [(call (mem:SI (match_operand:SI 0 "" ""))
7856 (match_operand 1 "" ""))
7857 (use (match_operand 2 "" ""))
7858 (clobber (reg:SI LR_REGNUM))]
7860 && !SIBLING_CALL_P (insn)
7861 && (GET_CODE (operands[0]) == SYMBOL_REF)
7862 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7865 rtx op = operands[0];
7867 /* Switch mode now when possible. */
7868 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7869 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7870 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7872 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7874 [(set_attr "type" "call")]
7877 (define_insn "*call_value_symbol"
7878 [(set (match_operand 0 "" "")
7879 (call (mem:SI (match_operand:SI 1 "" ""))
7880 (match_operand:SI 2 "" "")))
7881 (use (match_operand 3 "" ""))
7882 (clobber (reg:SI LR_REGNUM))]
7884 && !SIBLING_CALL_P (insn)
7885 && (GET_CODE (operands[1]) == SYMBOL_REF)
7886 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7889 rtx op = operands[1];
7891 /* Switch mode now when possible. */
7892 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7893 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7894 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
7896 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7898 [(set_attr "type" "call")]
7901 (define_expand "sibcall_internal"
7902 [(parallel [(call (match_operand 0 "memory_operand" "")
7903 (match_operand 1 "general_operand" ""))
7905 (use (match_operand 2 "" ""))])])
7907 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7908 (define_expand "sibcall"
7909 [(parallel [(call (match_operand 0 "memory_operand" "")
7910 (match_operand 1 "general_operand" ""))
7912 (use (match_operand 2 "" ""))])]
7918 if ((!REG_P (XEXP (operands[0], 0))
7919 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7920 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7921 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7922 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7924 if (operands[2] == NULL_RTX)
7925 operands[2] = const0_rtx;
7927 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7928 arm_emit_call_insn (pat, operands[0], true);
7933 (define_expand "sibcall_value_internal"
7934 [(parallel [(set (match_operand 0 "" "")
7935 (call (match_operand 1 "memory_operand" "")
7936 (match_operand 2 "general_operand" "")))
7938 (use (match_operand 3 "" ""))])])
7940 (define_expand "sibcall_value"
7941 [(parallel [(set (match_operand 0 "" "")
7942 (call (match_operand 1 "memory_operand" "")
7943 (match_operand 2 "general_operand" "")))
7945 (use (match_operand 3 "" ""))])]
7951 if ((!REG_P (XEXP (operands[1], 0))
7952 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7953 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7954 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7955 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7957 if (operands[3] == NULL_RTX)
7958 operands[3] = const0_rtx;
7960 pat = gen_sibcall_value_internal (operands[0], operands[1],
7961 operands[2], operands[3]);
7962 arm_emit_call_insn (pat, operands[1], true);
7967 (define_insn "*sibcall_insn"
7968 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7969 (match_operand 1 "" ""))
7971 (use (match_operand 2 "" ""))]
7972 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7974 if (which_alternative == 1)
7975 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7978 if (arm_arch5 || arm_arch4t)
7979 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7981 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7984 [(set_attr "type" "call")]
7987 (define_insn "*sibcall_value_insn"
7988 [(set (match_operand 0 "" "")
7989 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7990 (match_operand 2 "" "")))
7992 (use (match_operand 3 "" ""))]
7993 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7995 if (which_alternative == 1)
7996 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7999 if (arm_arch5 || arm_arch4t)
8000 return \"bx%?\\t%1\";
8002 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8005 [(set_attr "type" "call")]
8008 (define_expand "<return_str>return"
8010 "(TARGET_ARM || (TARGET_THUMB2
8011 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8012 && !IS_STACKALIGN (arm_current_func_type ())))
8013 <return_cond_false>"
8018 thumb2_expand_return (<return_simple_p>);
8025 ;; Often the return insn will be the same as loading from memory, so set attr
8026 (define_insn "*arm_return"
8028 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8031 if (arm_ccfsm_state == 2)
8033 arm_ccfsm_state += 2;
8036 return output_return_instruction (const_true_rtx, true, false, false);
8038 [(set_attr "type" "load1")
8039 (set_attr "length" "12")
8040 (set_attr "predicable" "yes")]
8043 (define_insn "*cond_<return_str>return"
8045 (if_then_else (match_operator 0 "arm_comparison_operator"
8046 [(match_operand 1 "cc_register" "") (const_int 0)])
8049 "TARGET_ARM <return_cond_true>"
8052 if (arm_ccfsm_state == 2)
8054 arm_ccfsm_state += 2;
8057 return output_return_instruction (operands[0], true, false,
8060 [(set_attr "conds" "use")
8061 (set_attr "length" "12")
8062 (set_attr "type" "load1")]
8065 (define_insn "*cond_<return_str>return_inverted"
8067 (if_then_else (match_operator 0 "arm_comparison_operator"
8068 [(match_operand 1 "cc_register" "") (const_int 0)])
8071 "TARGET_ARM <return_cond_true>"
8074 if (arm_ccfsm_state == 2)
8076 arm_ccfsm_state += 2;
8079 return output_return_instruction (operands[0], true, true,
8082 [(set_attr "conds" "use")
8083 (set_attr "length" "12")
8084 (set_attr "type" "load1")]
8087 (define_insn "*arm_simple_return"
8092 if (arm_ccfsm_state == 2)
8094 arm_ccfsm_state += 2;
8097 return output_return_instruction (const_true_rtx, true, false, true);
8099 [(set_attr "type" "branch")
8100 (set_attr "length" "4")
8101 (set_attr "predicable" "yes")]
8104 ;; Generate a sequence of instructions to determine if the processor is
8105 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8108 (define_expand "return_addr_mask"
8110 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8112 (set (match_operand:SI 0 "s_register_operand" "")
8113 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8115 (const_int 67108860)))] ; 0x03fffffc
8118 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8121 (define_insn "*check_arch2"
8122 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8123 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8126 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8127 [(set_attr "length" "8")
8128 (set_attr "conds" "set")
8129 (set_attr "type" "multiple")]
8132 ;; Call subroutine returning any type.
8134 (define_expand "untyped_call"
8135 [(parallel [(call (match_operand 0 "" "")
8137 (match_operand 1 "" "")
8138 (match_operand 2 "" "")])]
8143 rtx par = gen_rtx_PARALLEL (VOIDmode,
8144 rtvec_alloc (XVECLEN (operands[2], 0)));
8145 rtx addr = gen_reg_rtx (Pmode);
8149 emit_move_insn (addr, XEXP (operands[1], 0));
8150 mem = change_address (operands[1], BLKmode, addr);
8152 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8154 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8156 /* Default code only uses r0 as a return value, but we could
8157 be using anything up to 4 registers. */
8158 if (REGNO (src) == R0_REGNUM)
8159 src = gen_rtx_REG (TImode, R0_REGNUM);
8161 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8163 size += GET_MODE_SIZE (GET_MODE (src));
8166 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8170 for (i = 0; i < XVECLEN (par, 0); i++)
8172 HOST_WIDE_INT offset = 0;
8173 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8176 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8178 mem = change_address (mem, GET_MODE (reg), NULL);
8179 if (REGNO (reg) == R0_REGNUM)
8181 /* On thumb we have to use a write-back instruction. */
8182 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8183 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8184 size = TARGET_ARM ? 16 : 0;
8188 emit_move_insn (mem, reg);
8189 size = GET_MODE_SIZE (GET_MODE (reg));
8193 /* The optimizer does not know that the call sets the function value
8194 registers we stored in the result block. We avoid problems by
8195 claiming that all hard registers are used and clobbered at this
8197 emit_insn (gen_blockage ());
8203 (define_expand "untyped_return"
8204 [(match_operand:BLK 0 "memory_operand" "")
8205 (match_operand 1 "" "")]
8210 rtx addr = gen_reg_rtx (Pmode);
8214 emit_move_insn (addr, XEXP (operands[0], 0));
8215 mem = change_address (operands[0], BLKmode, addr);
8217 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8219 HOST_WIDE_INT offset = 0;
8220 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8223 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8225 mem = change_address (mem, GET_MODE (reg), NULL);
8226 if (REGNO (reg) == R0_REGNUM)
8228 /* On thumb we have to use a write-back instruction. */
8229 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8230 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8231 size = TARGET_ARM ? 16 : 0;
8235 emit_move_insn (reg, mem);
8236 size = GET_MODE_SIZE (GET_MODE (reg));
8240 /* Emit USE insns before the return. */
8241 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8242 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8244 /* Construct the return. */
8245 expand_naked_return ();
8251 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8252 ;; all of memory. This blocks insns from being moved across this point.
8254 (define_insn "blockage"
8255 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8258 [(set_attr "length" "0")
8259 (set_attr "type" "block")]
8262 (define_insn "probe_stack"
8263 [(set (match_operand 0 "memory_operand" "=m")
8264 (unspec [(const_int 0)] UNSPEC_PROBE_STACK))]
8267 return "str%?\\tr0, %0";
8269 [(set_attr "type" "store1")
8270 (set_attr "predicable" "yes")]
8273 (define_insn "probe_stack_range"
8274 [(set (match_operand:SI 0 "register_operand" "=r")
8275 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8276 (match_operand:SI 2 "register_operand" "r")]
8277 UNSPEC_PROBE_STACK_RANGE))]
8280 return output_probe_stack_range (operands[0], operands[2]);
8282 [(set_attr "type" "multiple")
8283 (set_attr "conds" "clob")]
8286 (define_expand "casesi"
8287 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8288 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8289 (match_operand:SI 2 "const_int_operand" "") ; total range
8290 (match_operand:SI 3 "" "") ; table label
8291 (match_operand:SI 4 "" "")] ; Out of range label
8292 "TARGET_32BIT || optimize_size || flag_pic"
8295 enum insn_code code;
8296 if (operands[1] != const0_rtx)
8298 rtx reg = gen_reg_rtx (SImode);
8300 emit_insn (gen_addsi3 (reg, operands[0],
8301 gen_int_mode (-INTVAL (operands[1]),
8307 code = CODE_FOR_arm_casesi_internal;
8308 else if (TARGET_THUMB1)
8309 code = CODE_FOR_thumb1_casesi_internal_pic;
8311 code = CODE_FOR_thumb2_casesi_internal_pic;
8313 code = CODE_FOR_thumb2_casesi_internal;
8315 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8316 operands[2] = force_reg (SImode, operands[2]);
8318 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8319 operands[3], operands[4]));
8324 ;; The USE in this pattern is needed to tell flow analysis that this is
8325 ;; a CASESI insn. It has no other purpose.
8326 (define_insn "arm_casesi_internal"
8327 [(parallel [(set (pc)
8329 (leu (match_operand:SI 0 "s_register_operand" "r")
8330 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8331 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8332 (label_ref (match_operand 2 "" ""))))
8333 (label_ref (match_operand 3 "" ""))))
8334 (clobber (reg:CC CC_REGNUM))
8335 (use (label_ref (match_dup 2)))])]
8339 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8340 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8342 [(set_attr "conds" "clob")
8343 (set_attr "length" "12")
8344 (set_attr "type" "multiple")]
8347 (define_expand "indirect_jump"
8349 (match_operand:SI 0 "s_register_operand" ""))]
8352 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8353 address and use bx. */
8357 tmp = gen_reg_rtx (SImode);
8358 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8364 ;; NB Never uses BX.
8365 (define_insn "*arm_indirect_jump"
8367 (match_operand:SI 0 "s_register_operand" "r"))]
8369 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8370 [(set_attr "predicable" "yes")
8371 (set_attr "type" "branch")]
8374 (define_insn "*load_indirect_jump"
8376 (match_operand:SI 0 "memory_operand" "m"))]
8378 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8379 [(set_attr "type" "load1")
8380 (set_attr "pool_range" "4096")
8381 (set_attr "neg_pool_range" "4084")
8382 (set_attr "predicable" "yes")]
8392 if (TARGET_UNIFIED_ASM)
8395 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8396 return \"mov\\tr8, r8\";
8398 [(set (attr "length")
8399 (if_then_else (eq_attr "is_thumb" "yes")
8402 (set_attr "type" "mov_reg")]
8406 [(trap_if (const_int 1) (const_int 0))]
8410 return \".inst\\t0xe7f000f0\";
8412 return \".inst\\t0xdeff\";
8414 [(set (attr "length")
8415 (if_then_else (eq_attr "is_thumb" "yes")
8418 (set_attr "type" "trap")
8419 (set_attr "conds" "unconditional")]
8423 ;; Patterns to allow combination of arithmetic, cond code and shifts
8425 (define_insn "*<arith_shift_insn>_multsi"
8426 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8428 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8429 (match_operand:SI 3 "power_of_two_operand" ""))
8430 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8432 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8433 [(set_attr "predicable" "yes")
8434 (set_attr "predicable_short_it" "no")
8435 (set_attr "shift" "2")
8436 (set_attr "arch" "a,t2")
8437 (set_attr "type" "alu_shift_imm")])
8439 (define_insn "*<arith_shift_insn>_shiftsi"
8440 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8442 (match_operator:SI 2 "shift_nomul_operator"
8443 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8444 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8445 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8446 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8447 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8448 [(set_attr "predicable" "yes")
8449 (set_attr "predicable_short_it" "no")
8450 (set_attr "shift" "3")
8451 (set_attr "arch" "a,t2,a")
8452 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8455 [(set (match_operand:SI 0 "s_register_operand" "")
8456 (match_operator:SI 1 "shiftable_operator"
8457 [(match_operator:SI 2 "shiftable_operator"
8458 [(match_operator:SI 3 "shift_operator"
8459 [(match_operand:SI 4 "s_register_operand" "")
8460 (match_operand:SI 5 "reg_or_int_operand" "")])
8461 (match_operand:SI 6 "s_register_operand" "")])
8462 (match_operand:SI 7 "arm_rhs_operand" "")]))
8463 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8466 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8469 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8472 (define_insn "*arith_shiftsi_compare0"
8473 [(set (reg:CC_NOOV CC_REGNUM)
8475 (match_operator:SI 1 "shiftable_operator"
8476 [(match_operator:SI 3 "shift_operator"
8477 [(match_operand:SI 4 "s_register_operand" "r,r")
8478 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8479 (match_operand:SI 2 "s_register_operand" "r,r")])
8481 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8482 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8485 "%i1%.\\t%0, %2, %4%S3"
8486 [(set_attr "conds" "set")
8487 (set_attr "shift" "4")
8488 (set_attr "arch" "32,a")
8489 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8491 (define_insn "*arith_shiftsi_compare0_scratch"
8492 [(set (reg:CC_NOOV CC_REGNUM)
8494 (match_operator:SI 1 "shiftable_operator"
8495 [(match_operator:SI 3 "shift_operator"
8496 [(match_operand:SI 4 "s_register_operand" "r,r")
8497 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8498 (match_operand:SI 2 "s_register_operand" "r,r")])
8500 (clobber (match_scratch:SI 0 "=r,r"))]
8502 "%i1%.\\t%0, %2, %4%S3"
8503 [(set_attr "conds" "set")
8504 (set_attr "shift" "4")
8505 (set_attr "arch" "32,a")
8506 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8508 (define_insn "*sub_shiftsi"
8509 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8510 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8511 (match_operator:SI 2 "shift_operator"
8512 [(match_operand:SI 3 "s_register_operand" "r,r")
8513 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8515 "sub%?\\t%0, %1, %3%S2"
8516 [(set_attr "predicable" "yes")
8517 (set_attr "shift" "3")
8518 (set_attr "arch" "32,a")
8519 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8521 (define_insn "*sub_shiftsi_compare0"
8522 [(set (reg:CC_NOOV CC_REGNUM)
8524 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8525 (match_operator:SI 2 "shift_operator"
8526 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8527 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8529 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8530 (minus:SI (match_dup 1)
8531 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8533 "sub%.\\t%0, %1, %3%S2"
8534 [(set_attr "conds" "set")
8535 (set_attr "shift" "3")
8536 (set_attr "arch" "32,a,a")
8537 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8539 (define_insn "*sub_shiftsi_compare0_scratch"
8540 [(set (reg:CC_NOOV CC_REGNUM)
8542 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8543 (match_operator:SI 2 "shift_operator"
8544 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8545 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8547 (clobber (match_scratch:SI 0 "=r,r,r"))]
8549 "sub%.\\t%0, %1, %3%S2"
8550 [(set_attr "conds" "set")
8551 (set_attr "shift" "3")
8552 (set_attr "arch" "32,a,a")
8553 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8556 (define_insn_and_split "*and_scc"
8557 [(set (match_operand:SI 0 "s_register_operand" "=r")
8558 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8559 [(match_operand 2 "cc_register" "") (const_int 0)])
8560 (match_operand:SI 3 "s_register_operand" "r")))]
8562 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8563 "&& reload_completed"
8564 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8565 (cond_exec (match_dup 4) (set (match_dup 0)
8566 (and:SI (match_dup 3) (const_int 1))))]
8568 machine_mode mode = GET_MODE (operands[2]);
8569 enum rtx_code rc = GET_CODE (operands[1]);
8571 /* Note that operands[4] is the same as operands[1],
8572 but with VOIDmode as the result. */
8573 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8574 if (mode == CCFPmode || mode == CCFPEmode)
8575 rc = reverse_condition_maybe_unordered (rc);
8577 rc = reverse_condition (rc);
8578 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8580 [(set_attr "conds" "use")
8581 (set_attr "type" "multiple")
8582 (set_attr "length" "8")]
8585 (define_insn_and_split "*ior_scc"
8586 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8587 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8588 [(match_operand 2 "cc_register" "") (const_int 0)])
8589 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8594 "&& reload_completed
8595 && REGNO (operands [0]) != REGNO (operands[3])"
8596 ;; && which_alternative == 1
8597 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8598 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8599 (cond_exec (match_dup 4) (set (match_dup 0)
8600 (ior:SI (match_dup 3) (const_int 1))))]
8602 machine_mode mode = GET_MODE (operands[2]);
8603 enum rtx_code rc = GET_CODE (operands[1]);
8605 /* Note that operands[4] is the same as operands[1],
8606 but with VOIDmode as the result. */
8607 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8608 if (mode == CCFPmode || mode == CCFPEmode)
8609 rc = reverse_condition_maybe_unordered (rc);
8611 rc = reverse_condition (rc);
8612 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8614 [(set_attr "conds" "use")
8615 (set_attr "length" "4,8")
8616 (set_attr "type" "logic_imm,multiple")]
8619 ; A series of splitters for the compare_scc pattern below. Note that
8620 ; order is important.
8622 [(set (match_operand:SI 0 "s_register_operand" "")
8623 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8625 (clobber (reg:CC CC_REGNUM))]
8626 "TARGET_32BIT && reload_completed"
8627 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8630 [(set (match_operand:SI 0 "s_register_operand" "")
8631 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8633 (clobber (reg:CC CC_REGNUM))]
8634 "TARGET_32BIT && reload_completed"
8635 [(set (match_dup 0) (not:SI (match_dup 1)))
8636 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8639 [(set (match_operand:SI 0 "s_register_operand" "")
8640 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8642 (clobber (reg:CC CC_REGNUM))]
8643 "arm_arch5 && TARGET_32BIT"
8644 [(set (match_dup 0) (clz:SI (match_dup 1)))
8645 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8649 [(set (match_operand:SI 0 "s_register_operand" "")
8650 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8652 (clobber (reg:CC CC_REGNUM))]
8653 "TARGET_32BIT && reload_completed"
8655 [(set (reg:CC CC_REGNUM)
8656 (compare:CC (const_int 1) (match_dup 1)))
8658 (minus:SI (const_int 1) (match_dup 1)))])
8659 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8660 (set (match_dup 0) (const_int 0)))])
8663 [(set (match_operand:SI 0 "s_register_operand" "")
8664 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8665 (match_operand:SI 2 "const_int_operand" "")))
8666 (clobber (reg:CC CC_REGNUM))]
8667 "TARGET_32BIT && reload_completed"
8669 [(set (reg:CC CC_REGNUM)
8670 (compare:CC (match_dup 1) (match_dup 2)))
8671 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8672 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8673 (set (match_dup 0) (const_int 1)))]
8675 operands[3] = GEN_INT (-INTVAL (operands[2]));
8679 [(set (match_operand:SI 0 "s_register_operand" "")
8680 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8681 (match_operand:SI 2 "arm_add_operand" "")))
8682 (clobber (reg:CC CC_REGNUM))]
8683 "TARGET_32BIT && reload_completed"
8685 [(set (reg:CC_NOOV CC_REGNUM)
8686 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8688 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8689 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8690 (set (match_dup 0) (const_int 1)))])
8692 (define_insn_and_split "*compare_scc"
8693 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8694 (match_operator:SI 1 "arm_comparison_operator"
8695 [(match_operand:SI 2 "s_register_operand" "r,r")
8696 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8697 (clobber (reg:CC CC_REGNUM))]
8700 "&& reload_completed"
8701 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8702 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8703 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8706 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8707 operands[2], operands[3]);
8708 enum rtx_code rc = GET_CODE (operands[1]);
8710 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8712 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8713 if (mode == CCFPmode || mode == CCFPEmode)
8714 rc = reverse_condition_maybe_unordered (rc);
8716 rc = reverse_condition (rc);
8717 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8719 [(set_attr "type" "multiple")]
8722 ;; Attempt to improve the sequence generated by the compare_scc splitters
8723 ;; not to use conditional execution.
8725 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
8729 [(set (reg:CC CC_REGNUM)
8730 (compare:CC (match_operand:SI 1 "register_operand" "")
8732 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8733 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8734 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8735 (set (match_dup 0) (const_int 1)))]
8736 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8737 [(set (match_dup 0) (clz:SI (match_dup 1)))
8738 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8741 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8745 [(set (reg:CC CC_REGNUM)
8746 (compare:CC (match_operand:SI 1 "register_operand" "")
8748 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8749 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8750 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8751 (set (match_dup 0) (const_int 1)))
8752 (match_scratch:SI 2 "r")]
8753 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8755 [(set (reg:CC CC_REGNUM)
8756 (compare:CC (const_int 0) (match_dup 1)))
8757 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8759 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8760 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8763 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
8764 ;; sub Rd, Reg1, reg2
8768 [(set (reg:CC CC_REGNUM)
8769 (compare:CC (match_operand:SI 1 "register_operand" "")
8770 (match_operand:SI 2 "arm_rhs_operand" "")))
8771 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8772 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8773 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8774 (set (match_dup 0) (const_int 1)))]
8775 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8776 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8777 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8778 (set (match_dup 0) (clz:SI (match_dup 0)))
8779 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8783 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
8784 ;; sub T1, Reg1, reg2
8788 [(set (reg:CC CC_REGNUM)
8789 (compare:CC (match_operand:SI 1 "register_operand" "")
8790 (match_operand:SI 2 "arm_rhs_operand" "")))
8791 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8792 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8793 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8794 (set (match_dup 0) (const_int 1)))
8795 (match_scratch:SI 3 "r")]
8796 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8797 [(set (match_dup 3) (match_dup 4))
8799 [(set (reg:CC CC_REGNUM)
8800 (compare:CC (const_int 0) (match_dup 3)))
8801 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8803 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8804 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8806 if (CONST_INT_P (operands[2]))
8807 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8809 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8812 (define_insn "*cond_move"
8813 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8814 (if_then_else:SI (match_operator 3 "equality_operator"
8815 [(match_operator 4 "arm_comparison_operator"
8816 [(match_operand 5 "cc_register" "") (const_int 0)])
8818 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8819 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8822 if (GET_CODE (operands[3]) == NE)
8824 if (which_alternative != 1)
8825 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8826 if (which_alternative != 0)
8827 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8830 if (which_alternative != 0)
8831 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8832 if (which_alternative != 1)
8833 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8836 [(set_attr "conds" "use")
8837 (set_attr_alternative "type"
8838 [(if_then_else (match_operand 2 "const_int_operand" "")
8839 (const_string "mov_imm")
8840 (const_string "mov_reg"))
8841 (if_then_else (match_operand 1 "const_int_operand" "")
8842 (const_string "mov_imm")
8843 (const_string "mov_reg"))
8844 (const_string "multiple")])
8845 (set_attr "length" "4,4,8")]
8848 (define_insn "*cond_arith"
8849 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8850 (match_operator:SI 5 "shiftable_operator"
8851 [(match_operator:SI 4 "arm_comparison_operator"
8852 [(match_operand:SI 2 "s_register_operand" "r,r")
8853 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8854 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8855 (clobber (reg:CC CC_REGNUM))]
8858 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8859 return \"%i5\\t%0, %1, %2, lsr #31\";
8861 output_asm_insn (\"cmp\\t%2, %3\", operands);
8862 if (GET_CODE (operands[5]) == AND)
8863 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8864 else if (GET_CODE (operands[5]) == MINUS)
8865 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8866 else if (which_alternative != 0)
8867 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8868 return \"%i5%d4\\t%0, %1, #1\";
8870 [(set_attr "conds" "clob")
8871 (set_attr "length" "12")
8872 (set_attr "type" "multiple")]
8875 (define_insn "*cond_sub"
8876 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8877 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8878 (match_operator:SI 4 "arm_comparison_operator"
8879 [(match_operand:SI 2 "s_register_operand" "r,r")
8880 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8881 (clobber (reg:CC CC_REGNUM))]
8884 output_asm_insn (\"cmp\\t%2, %3\", operands);
8885 if (which_alternative != 0)
8886 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8887 return \"sub%d4\\t%0, %1, #1\";
8889 [(set_attr "conds" "clob")
8890 (set_attr "length" "8,12")
8891 (set_attr "type" "multiple")]
8894 (define_insn "*cmp_ite0"
8895 [(set (match_operand 6 "dominant_cc_register" "")
8898 (match_operator 4 "arm_comparison_operator"
8899 [(match_operand:SI 0 "s_register_operand"
8900 "l,l,l,r,r,r,r,r,r")
8901 (match_operand:SI 1 "arm_add_operand"
8902 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8903 (match_operator:SI 5 "arm_comparison_operator"
8904 [(match_operand:SI 2 "s_register_operand"
8905 "l,r,r,l,l,r,r,r,r")
8906 (match_operand:SI 3 "arm_add_operand"
8907 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8913 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8915 {\"cmp%d5\\t%0, %1\",
8916 \"cmp%d4\\t%2, %3\"},
8917 {\"cmn%d5\\t%0, #%n1\",
8918 \"cmp%d4\\t%2, %3\"},
8919 {\"cmp%d5\\t%0, %1\",
8920 \"cmn%d4\\t%2, #%n3\"},
8921 {\"cmn%d5\\t%0, #%n1\",
8922 \"cmn%d4\\t%2, #%n3\"}
8924 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8929 \"cmn\\t%0, #%n1\"},
8930 {\"cmn\\t%2, #%n3\",
8932 {\"cmn\\t%2, #%n3\",
8935 static const char * const ite[2] =
8940 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8941 CMP_CMP, CMN_CMP, CMP_CMP,
8942 CMN_CMP, CMP_CMN, CMN_CMN};
8944 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8946 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8947 if (TARGET_THUMB2) {
8948 output_asm_insn (ite[swap], operands);
8950 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8953 [(set_attr "conds" "set")
8954 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8955 (set_attr "type" "multiple")
8956 (set_attr_alternative "length"
8962 (if_then_else (eq_attr "is_thumb" "no")
8965 (if_then_else (eq_attr "is_thumb" "no")
8968 (if_then_else (eq_attr "is_thumb" "no")
8971 (if_then_else (eq_attr "is_thumb" "no")
8976 (define_insn "*cmp_ite1"
8977 [(set (match_operand 6 "dominant_cc_register" "")
8980 (match_operator 4 "arm_comparison_operator"
8981 [(match_operand:SI 0 "s_register_operand"
8982 "l,l,l,r,r,r,r,r,r")
8983 (match_operand:SI 1 "arm_add_operand"
8984 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8985 (match_operator:SI 5 "arm_comparison_operator"
8986 [(match_operand:SI 2 "s_register_operand"
8987 "l,r,r,l,l,r,r,r,r")
8988 (match_operand:SI 3 "arm_add_operand"
8989 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8995 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8999 {\"cmn\\t%0, #%n1\",
9002 \"cmn\\t%2, #%n3\"},
9003 {\"cmn\\t%0, #%n1\",
9006 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9008 {\"cmp%d4\\t%2, %3\",
9009 \"cmp%D5\\t%0, %1\"},
9010 {\"cmp%d4\\t%2, %3\",
9011 \"cmn%D5\\t%0, #%n1\"},
9012 {\"cmn%d4\\t%2, #%n3\",
9013 \"cmp%D5\\t%0, %1\"},
9014 {\"cmn%d4\\t%2, #%n3\",
9015 \"cmn%D5\\t%0, #%n1\"}
9017 static const char * const ite[2] =
9022 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9023 CMP_CMP, CMN_CMP, CMP_CMP,
9024 CMN_CMP, CMP_CMN, CMN_CMN};
9026 comparison_dominates_p (GET_CODE (operands[5]),
9027 reverse_condition (GET_CODE (operands[4])));
9029 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9030 if (TARGET_THUMB2) {
9031 output_asm_insn (ite[swap], operands);
9033 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9036 [(set_attr "conds" "set")
9037 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9038 (set_attr_alternative "length"
9044 (if_then_else (eq_attr "is_thumb" "no")
9047 (if_then_else (eq_attr "is_thumb" "no")
9050 (if_then_else (eq_attr "is_thumb" "no")
9053 (if_then_else (eq_attr "is_thumb" "no")
9056 (set_attr "type" "multiple")]
9059 (define_insn "*cmp_and"
9060 [(set (match_operand 6 "dominant_cc_register" "")
9063 (match_operator 4 "arm_comparison_operator"
9064 [(match_operand:SI 0 "s_register_operand"
9065 "l,l,l,r,r,r,r,r,r")
9066 (match_operand:SI 1 "arm_add_operand"
9067 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9068 (match_operator:SI 5 "arm_comparison_operator"
9069 [(match_operand:SI 2 "s_register_operand"
9070 "l,r,r,l,l,r,r,r,r")
9071 (match_operand:SI 3 "arm_add_operand"
9072 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9077 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9079 {\"cmp%d5\\t%0, %1\",
9080 \"cmp%d4\\t%2, %3\"},
9081 {\"cmn%d5\\t%0, #%n1\",
9082 \"cmp%d4\\t%2, %3\"},
9083 {\"cmp%d5\\t%0, %1\",
9084 \"cmn%d4\\t%2, #%n3\"},
9085 {\"cmn%d5\\t%0, #%n1\",
9086 \"cmn%d4\\t%2, #%n3\"}
9088 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9093 \"cmn\\t%0, #%n1\"},
9094 {\"cmn\\t%2, #%n3\",
9096 {\"cmn\\t%2, #%n3\",
9099 static const char *const ite[2] =
9104 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9105 CMP_CMP, CMN_CMP, CMP_CMP,
9106 CMN_CMP, CMP_CMN, CMN_CMN};
9108 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9110 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9111 if (TARGET_THUMB2) {
9112 output_asm_insn (ite[swap], operands);
9114 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9117 [(set_attr "conds" "set")
9118 (set_attr "predicable" "no")
9119 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9120 (set_attr_alternative "length"
9126 (if_then_else (eq_attr "is_thumb" "no")
9129 (if_then_else (eq_attr "is_thumb" "no")
9132 (if_then_else (eq_attr "is_thumb" "no")
9135 (if_then_else (eq_attr "is_thumb" "no")
9138 (set_attr "type" "multiple")]
9141 (define_insn "*cmp_ior"
9142 [(set (match_operand 6 "dominant_cc_register" "")
9145 (match_operator 4 "arm_comparison_operator"
9146 [(match_operand:SI 0 "s_register_operand"
9147 "l,l,l,r,r,r,r,r,r")
9148 (match_operand:SI 1 "arm_add_operand"
9149 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9150 (match_operator:SI 5 "arm_comparison_operator"
9151 [(match_operand:SI 2 "s_register_operand"
9152 "l,r,r,l,l,r,r,r,r")
9153 (match_operand:SI 3 "arm_add_operand"
9154 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9159 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9163 {\"cmn\\t%0, #%n1\",
9166 \"cmn\\t%2, #%n3\"},
9167 {\"cmn\\t%0, #%n1\",
9170 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9172 {\"cmp%D4\\t%2, %3\",
9173 \"cmp%D5\\t%0, %1\"},
9174 {\"cmp%D4\\t%2, %3\",
9175 \"cmn%D5\\t%0, #%n1\"},
9176 {\"cmn%D4\\t%2, #%n3\",
9177 \"cmp%D5\\t%0, %1\"},
9178 {\"cmn%D4\\t%2, #%n3\",
9179 \"cmn%D5\\t%0, #%n1\"}
9181 static const char *const ite[2] =
9186 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9187 CMP_CMP, CMN_CMP, CMP_CMP,
9188 CMN_CMP, CMP_CMN, CMN_CMN};
9190 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9192 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9193 if (TARGET_THUMB2) {
9194 output_asm_insn (ite[swap], operands);
9196 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9200 [(set_attr "conds" "set")
9201 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9202 (set_attr_alternative "length"
9208 (if_then_else (eq_attr "is_thumb" "no")
9211 (if_then_else (eq_attr "is_thumb" "no")
9214 (if_then_else (eq_attr "is_thumb" "no")
9217 (if_then_else (eq_attr "is_thumb" "no")
9220 (set_attr "type" "multiple")]
9223 (define_insn_and_split "*ior_scc_scc"
9224 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9225 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9226 [(match_operand:SI 1 "s_register_operand" "r")
9227 (match_operand:SI 2 "arm_add_operand" "rIL")])
9228 (match_operator:SI 6 "arm_comparison_operator"
9229 [(match_operand:SI 4 "s_register_operand" "r")
9230 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9231 (clobber (reg:CC CC_REGNUM))]
9233 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9236 "TARGET_32BIT && reload_completed"
9240 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9241 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9243 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9245 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9248 [(set_attr "conds" "clob")
9249 (set_attr "length" "16")
9250 (set_attr "type" "multiple")]
9253 ; If the above pattern is followed by a CMP insn, then the compare is
9254 ; redundant, since we can rework the conditional instruction that follows.
9255 (define_insn_and_split "*ior_scc_scc_cmp"
9256 [(set (match_operand 0 "dominant_cc_register" "")
9257 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9258 [(match_operand:SI 1 "s_register_operand" "r")
9259 (match_operand:SI 2 "arm_add_operand" "rIL")])
9260 (match_operator:SI 6 "arm_comparison_operator"
9261 [(match_operand:SI 4 "s_register_operand" "r")
9262 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9264 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9265 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9266 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9269 "TARGET_32BIT && reload_completed"
9273 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9274 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9276 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9278 [(set_attr "conds" "set")
9279 (set_attr "length" "16")
9280 (set_attr "type" "multiple")]
9283 (define_insn_and_split "*and_scc_scc"
9284 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9285 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9286 [(match_operand:SI 1 "s_register_operand" "r")
9287 (match_operand:SI 2 "arm_add_operand" "rIL")])
9288 (match_operator:SI 6 "arm_comparison_operator"
9289 [(match_operand:SI 4 "s_register_operand" "r")
9290 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9291 (clobber (reg:CC CC_REGNUM))]
9293 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9296 "TARGET_32BIT && reload_completed
9297 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9302 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9303 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9305 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9307 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9310 [(set_attr "conds" "clob")
9311 (set_attr "length" "16")
9312 (set_attr "type" "multiple")]
9315 ; If the above pattern is followed by a CMP insn, then the compare is
9316 ; redundant, since we can rework the conditional instruction that follows.
9317 (define_insn_and_split "*and_scc_scc_cmp"
9318 [(set (match_operand 0 "dominant_cc_register" "")
9319 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9320 [(match_operand:SI 1 "s_register_operand" "r")
9321 (match_operand:SI 2 "arm_add_operand" "rIL")])
9322 (match_operator:SI 6 "arm_comparison_operator"
9323 [(match_operand:SI 4 "s_register_operand" "r")
9324 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9326 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9327 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9328 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9331 "TARGET_32BIT && reload_completed"
9335 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9336 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9338 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9340 [(set_attr "conds" "set")
9341 (set_attr "length" "16")
9342 (set_attr "type" "multiple")]
9345 ;; If there is no dominance in the comparison, then we can still save an
9346 ;; instruction in the AND case, since we can know that the second compare
9347 ;; need only zero the value if false (if true, then the value is already
9349 (define_insn_and_split "*and_scc_scc_nodom"
9350 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9351 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9352 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9353 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9354 (match_operator:SI 6 "arm_comparison_operator"
9355 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9356 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9357 (clobber (reg:CC CC_REGNUM))]
9359 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9362 "TARGET_32BIT && reload_completed"
9363 [(parallel [(set (match_dup 0)
9364 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9365 (clobber (reg:CC CC_REGNUM))])
9366 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9368 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9371 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9372 operands[4], operands[5]),
9374 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9376 [(set_attr "conds" "clob")
9377 (set_attr "length" "20")
9378 (set_attr "type" "multiple")]
9382 [(set (reg:CC_NOOV CC_REGNUM)
9383 (compare:CC_NOOV (ior:SI
9384 (and:SI (match_operand:SI 0 "s_register_operand" "")
9386 (match_operator:SI 1 "arm_comparison_operator"
9387 [(match_operand:SI 2 "s_register_operand" "")
9388 (match_operand:SI 3 "arm_add_operand" "")]))
9390 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9393 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9395 (set (reg:CC_NOOV CC_REGNUM)
9396 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9401 [(set (reg:CC_NOOV CC_REGNUM)
9402 (compare:CC_NOOV (ior:SI
9403 (match_operator:SI 1 "arm_comparison_operator"
9404 [(match_operand:SI 2 "s_register_operand" "")
9405 (match_operand:SI 3 "arm_add_operand" "")])
9406 (and:SI (match_operand:SI 0 "s_register_operand" "")
9409 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9412 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9414 (set (reg:CC_NOOV CC_REGNUM)
9415 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9418 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9420 (define_insn_and_split "*negscc"
9421 [(set (match_operand:SI 0 "s_register_operand" "=r")
9422 (neg:SI (match_operator 3 "arm_comparison_operator"
9423 [(match_operand:SI 1 "s_register_operand" "r")
9424 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9425 (clobber (reg:CC CC_REGNUM))]
9428 "&& reload_completed"
9431 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9433 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9435 /* Emit mov\\t%0, %1, asr #31 */
9436 emit_insn (gen_rtx_SET (operands[0],
9437 gen_rtx_ASHIFTRT (SImode,
9442 else if (GET_CODE (operands[3]) == NE)
9444 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9445 if (CONST_INT_P (operands[2]))
9446 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9447 GEN_INT (- INTVAL (operands[2]))));
9449 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9451 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9455 gen_rtx_SET (operands[0],
9461 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9462 emit_insn (gen_rtx_SET (cc_reg,
9463 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9464 enum rtx_code rc = GET_CODE (operands[3]);
9466 rc = reverse_condition (rc);
9467 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9472 gen_rtx_SET (operands[0], const0_rtx)));
9473 rc = GET_CODE (operands[3]);
9474 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9479 gen_rtx_SET (operands[0],
9485 [(set_attr "conds" "clob")
9486 (set_attr "length" "12")
9487 (set_attr "type" "multiple")]
9490 (define_insn_and_split "movcond_addsi"
9491 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9493 (match_operator 5 "comparison_operator"
9494 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9495 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9497 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9498 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9499 (clobber (reg:CC CC_REGNUM))]
9502 "&& reload_completed"
9503 [(set (reg:CC_NOOV CC_REGNUM)
9505 (plus:SI (match_dup 3)
9508 (set (match_dup 0) (match_dup 1))
9509 (cond_exec (match_dup 6)
9510 (set (match_dup 0) (match_dup 2)))]
9513 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9514 operands[3], operands[4]);
9515 enum rtx_code rc = GET_CODE (operands[5]);
9516 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9517 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9518 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9519 rc = reverse_condition (rc);
9521 std::swap (operands[1], operands[2]);
9523 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9526 [(set_attr "conds" "clob")
9527 (set_attr "enabled_for_depr_it" "no,yes,yes")
9528 (set_attr "type" "multiple")]
9531 (define_insn "movcond"
9532 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9534 (match_operator 5 "arm_comparison_operator"
9535 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9536 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9537 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9538 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9539 (clobber (reg:CC CC_REGNUM))]
9542 if (GET_CODE (operands[5]) == LT
9543 && (operands[4] == const0_rtx))
9545 if (which_alternative != 1 && REG_P (operands[1]))
9547 if (operands[2] == const0_rtx)
9548 return \"and\\t%0, %1, %3, asr #31\";
9549 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9551 else if (which_alternative != 0 && REG_P (operands[2]))
9553 if (operands[1] == const0_rtx)
9554 return \"bic\\t%0, %2, %3, asr #31\";
9555 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9557 /* The only case that falls through to here is when both ops 1 & 2
9561 if (GET_CODE (operands[5]) == GE
9562 && (operands[4] == const0_rtx))
9564 if (which_alternative != 1 && REG_P (operands[1]))
9566 if (operands[2] == const0_rtx)
9567 return \"bic\\t%0, %1, %3, asr #31\";
9568 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9570 else if (which_alternative != 0 && REG_P (operands[2]))
9572 if (operands[1] == const0_rtx)
9573 return \"and\\t%0, %2, %3, asr #31\";
9574 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9576 /* The only case that falls through to here is when both ops 1 & 2
9579 if (CONST_INT_P (operands[4])
9580 && !const_ok_for_arm (INTVAL (operands[4])))
9581 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9583 output_asm_insn (\"cmp\\t%3, %4\", operands);
9584 if (which_alternative != 0)
9585 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9586 if (which_alternative != 1)
9587 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9590 [(set_attr "conds" "clob")
9591 (set_attr "length" "8,8,12")
9592 (set_attr "type" "multiple")]
9595 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9597 (define_insn "*ifcompare_plus_move"
9598 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9599 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9600 [(match_operand:SI 4 "s_register_operand" "r,r")
9601 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9603 (match_operand:SI 2 "s_register_operand" "r,r")
9604 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9605 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9606 (clobber (reg:CC CC_REGNUM))]
9609 [(set_attr "conds" "clob")
9610 (set_attr "length" "8,12")
9611 (set_attr "type" "multiple")]
9614 (define_insn "*if_plus_move"
9615 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9617 (match_operator 4 "arm_comparison_operator"
9618 [(match_operand 5 "cc_register" "") (const_int 0)])
9620 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9621 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9622 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9626 sub%d4\\t%0, %2, #%n3
9627 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9628 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9629 [(set_attr "conds" "use")
9630 (set_attr "length" "4,4,8,8")
9631 (set_attr_alternative "type"
9632 [(if_then_else (match_operand 3 "const_int_operand" "")
9633 (const_string "alu_imm" )
9634 (const_string "alu_sreg"))
9635 (const_string "alu_imm")
9636 (const_string "multiple")
9637 (const_string "multiple")])]
9640 (define_insn "*ifcompare_move_plus"
9641 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9642 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9643 [(match_operand:SI 4 "s_register_operand" "r,r")
9644 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9645 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9647 (match_operand:SI 2 "s_register_operand" "r,r")
9648 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9649 (clobber (reg:CC CC_REGNUM))]
9652 [(set_attr "conds" "clob")
9653 (set_attr "length" "8,12")
9654 (set_attr "type" "multiple")]
9657 (define_insn "*if_move_plus"
9658 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9660 (match_operator 4 "arm_comparison_operator"
9661 [(match_operand 5 "cc_register" "") (const_int 0)])
9662 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9664 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9665 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9669 sub%D4\\t%0, %2, #%n3
9670 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9671 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9672 [(set_attr "conds" "use")
9673 (set_attr "length" "4,4,8,8")
9674 (set_attr_alternative "type"
9675 [(if_then_else (match_operand 3 "const_int_operand" "")
9676 (const_string "alu_imm" )
9677 (const_string "alu_sreg"))
9678 (const_string "alu_imm")
9679 (const_string "multiple")
9680 (const_string "multiple")])]
9683 (define_insn "*ifcompare_arith_arith"
9684 [(set (match_operand:SI 0 "s_register_operand" "=r")
9685 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9686 [(match_operand:SI 5 "s_register_operand" "r")
9687 (match_operand:SI 6 "arm_add_operand" "rIL")])
9688 (match_operator:SI 8 "shiftable_operator"
9689 [(match_operand:SI 1 "s_register_operand" "r")
9690 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9691 (match_operator:SI 7 "shiftable_operator"
9692 [(match_operand:SI 3 "s_register_operand" "r")
9693 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9694 (clobber (reg:CC CC_REGNUM))]
9697 [(set_attr "conds" "clob")
9698 (set_attr "length" "12")
9699 (set_attr "type" "multiple")]
9702 (define_insn "*if_arith_arith"
9703 [(set (match_operand:SI 0 "s_register_operand" "=r")
9704 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9705 [(match_operand 8 "cc_register" "") (const_int 0)])
9706 (match_operator:SI 6 "shiftable_operator"
9707 [(match_operand:SI 1 "s_register_operand" "r")
9708 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9709 (match_operator:SI 7 "shiftable_operator"
9710 [(match_operand:SI 3 "s_register_operand" "r")
9711 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9713 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9714 [(set_attr "conds" "use")
9715 (set_attr "length" "8")
9716 (set_attr "type" "multiple")]
9719 (define_insn "*ifcompare_arith_move"
9720 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9721 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9722 [(match_operand:SI 2 "s_register_operand" "r,r")
9723 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9724 (match_operator:SI 7 "shiftable_operator"
9725 [(match_operand:SI 4 "s_register_operand" "r,r")
9726 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9727 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9728 (clobber (reg:CC CC_REGNUM))]
9731 /* If we have an operation where (op x 0) is the identity operation and
9732 the conditional operator is LT or GE and we are comparing against zero and
9733 everything is in registers then we can do this in two instructions. */
9734 if (operands[3] == const0_rtx
9735 && GET_CODE (operands[7]) != AND
9736 && REG_P (operands[5])
9737 && REG_P (operands[1])
9738 && REGNO (operands[1]) == REGNO (operands[4])
9739 && REGNO (operands[4]) != REGNO (operands[0]))
9741 if (GET_CODE (operands[6]) == LT)
9742 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9743 else if (GET_CODE (operands[6]) == GE)
9744 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9746 if (CONST_INT_P (operands[3])
9747 && !const_ok_for_arm (INTVAL (operands[3])))
9748 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9750 output_asm_insn (\"cmp\\t%2, %3\", operands);
9751 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9752 if (which_alternative != 0)
9753 return \"mov%D6\\t%0, %1\";
9756 [(set_attr "conds" "clob")
9757 (set_attr "length" "8,12")
9758 (set_attr "type" "multiple")]
9761 (define_insn "*if_arith_move"
9762 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9763 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9764 [(match_operand 6 "cc_register" "") (const_int 0)])
9765 (match_operator:SI 5 "shiftable_operator"
9766 [(match_operand:SI 2 "s_register_operand" "r,r")
9767 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9768 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9772 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9773 [(set_attr "conds" "use")
9774 (set_attr "length" "4,8")
9775 (set_attr_alternative "type"
9776 [(if_then_else (match_operand 3 "const_int_operand" "")
9777 (const_string "alu_shift_imm" )
9778 (const_string "alu_shift_reg"))
9779 (const_string "multiple")])]
9782 (define_insn "*ifcompare_move_arith"
9783 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9784 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9785 [(match_operand:SI 4 "s_register_operand" "r,r")
9786 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9787 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9788 (match_operator:SI 7 "shiftable_operator"
9789 [(match_operand:SI 2 "s_register_operand" "r,r")
9790 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9791 (clobber (reg:CC CC_REGNUM))]
9794 /* If we have an operation where (op x 0) is the identity operation and
9795 the conditional operator is LT or GE and we are comparing against zero and
9796 everything is in registers then we can do this in two instructions */
9797 if (operands[5] == const0_rtx
9798 && GET_CODE (operands[7]) != AND
9799 && REG_P (operands[3])
9800 && REG_P (operands[1])
9801 && REGNO (operands[1]) == REGNO (operands[2])
9802 && REGNO (operands[2]) != REGNO (operands[0]))
9804 if (GET_CODE (operands[6]) == GE)
9805 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9806 else if (GET_CODE (operands[6]) == LT)
9807 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9810 if (CONST_INT_P (operands[5])
9811 && !const_ok_for_arm (INTVAL (operands[5])))
9812 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9814 output_asm_insn (\"cmp\\t%4, %5\", operands);
9816 if (which_alternative != 0)
9817 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9818 return \"%I7%D6\\t%0, %2, %3\";
9820 [(set_attr "conds" "clob")
9821 (set_attr "length" "8,12")
9822 (set_attr "type" "multiple")]
9825 (define_insn "*if_move_arith"
9826 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9828 (match_operator 4 "arm_comparison_operator"
9829 [(match_operand 6 "cc_register" "") (const_int 0)])
9830 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9831 (match_operator:SI 5 "shiftable_operator"
9832 [(match_operand:SI 2 "s_register_operand" "r,r")
9833 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9837 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9838 [(set_attr "conds" "use")
9839 (set_attr "length" "4,8")
9840 (set_attr_alternative "type"
9841 [(if_then_else (match_operand 3 "const_int_operand" "")
9842 (const_string "alu_shift_imm" )
9843 (const_string "alu_shift_reg"))
9844 (const_string "multiple")])]
9847 (define_insn "*ifcompare_move_not"
9848 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9850 (match_operator 5 "arm_comparison_operator"
9851 [(match_operand:SI 3 "s_register_operand" "r,r")
9852 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9853 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9855 (match_operand:SI 2 "s_register_operand" "r,r"))))
9856 (clobber (reg:CC CC_REGNUM))]
9859 [(set_attr "conds" "clob")
9860 (set_attr "length" "8,12")
9861 (set_attr "type" "multiple")]
9864 (define_insn "*if_move_not"
9865 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9867 (match_operator 4 "arm_comparison_operator"
9868 [(match_operand 3 "cc_register" "") (const_int 0)])
9869 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9870 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9874 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9875 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9876 [(set_attr "conds" "use")
9877 (set_attr "type" "mvn_reg")
9878 (set_attr "length" "4,8,8")
9879 (set_attr "type" "mvn_reg,multiple,multiple")]
9882 (define_insn "*ifcompare_not_move"
9883 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9885 (match_operator 5 "arm_comparison_operator"
9886 [(match_operand:SI 3 "s_register_operand" "r,r")
9887 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9889 (match_operand:SI 2 "s_register_operand" "r,r"))
9890 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9891 (clobber (reg:CC CC_REGNUM))]
9894 [(set_attr "conds" "clob")
9895 (set_attr "length" "8,12")
9896 (set_attr "type" "multiple")]
9899 (define_insn "*if_not_move"
9900 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9902 (match_operator 4 "arm_comparison_operator"
9903 [(match_operand 3 "cc_register" "") (const_int 0)])
9904 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9905 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9909 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9910 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9911 [(set_attr "conds" "use")
9912 (set_attr "type" "mvn_reg,multiple,multiple")
9913 (set_attr "length" "4,8,8")]
9916 (define_insn "*ifcompare_shift_move"
9917 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9919 (match_operator 6 "arm_comparison_operator"
9920 [(match_operand:SI 4 "s_register_operand" "r,r")
9921 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9922 (match_operator:SI 7 "shift_operator"
9923 [(match_operand:SI 2 "s_register_operand" "r,r")
9924 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9925 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9926 (clobber (reg:CC CC_REGNUM))]
9929 [(set_attr "conds" "clob")
9930 (set_attr "length" "8,12")
9931 (set_attr "type" "multiple")]
9934 (define_insn "*if_shift_move"
9935 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9937 (match_operator 5 "arm_comparison_operator"
9938 [(match_operand 6 "cc_register" "") (const_int 0)])
9939 (match_operator:SI 4 "shift_operator"
9940 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9941 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9942 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9946 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9947 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9948 [(set_attr "conds" "use")
9949 (set_attr "shift" "2")
9950 (set_attr "length" "4,8,8")
9951 (set_attr_alternative "type"
9952 [(if_then_else (match_operand 3 "const_int_operand" "")
9953 (const_string "mov_shift" )
9954 (const_string "mov_shift_reg"))
9955 (const_string "multiple")
9956 (const_string "multiple")])]
9959 (define_insn "*ifcompare_move_shift"
9960 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9962 (match_operator 6 "arm_comparison_operator"
9963 [(match_operand:SI 4 "s_register_operand" "r,r")
9964 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9965 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9966 (match_operator:SI 7 "shift_operator"
9967 [(match_operand:SI 2 "s_register_operand" "r,r")
9968 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9969 (clobber (reg:CC CC_REGNUM))]
9972 [(set_attr "conds" "clob")
9973 (set_attr "length" "8,12")
9974 (set_attr "type" "multiple")]
9977 (define_insn "*if_move_shift"
9978 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9980 (match_operator 5 "arm_comparison_operator"
9981 [(match_operand 6 "cc_register" "") (const_int 0)])
9982 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9983 (match_operator:SI 4 "shift_operator"
9984 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9985 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9989 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9990 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9991 [(set_attr "conds" "use")
9992 (set_attr "shift" "2")
9993 (set_attr "length" "4,8,8")
9994 (set_attr_alternative "type"
9995 [(if_then_else (match_operand 3 "const_int_operand" "")
9996 (const_string "mov_shift" )
9997 (const_string "mov_shift_reg"))
9998 (const_string "multiple")
9999 (const_string "multiple")])]
10002 (define_insn "*ifcompare_shift_shift"
10003 [(set (match_operand:SI 0 "s_register_operand" "=r")
10005 (match_operator 7 "arm_comparison_operator"
10006 [(match_operand:SI 5 "s_register_operand" "r")
10007 (match_operand:SI 6 "arm_add_operand" "rIL")])
10008 (match_operator:SI 8 "shift_operator"
10009 [(match_operand:SI 1 "s_register_operand" "r")
10010 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10011 (match_operator:SI 9 "shift_operator"
10012 [(match_operand:SI 3 "s_register_operand" "r")
10013 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10014 (clobber (reg:CC CC_REGNUM))]
10017 [(set_attr "conds" "clob")
10018 (set_attr "length" "12")
10019 (set_attr "type" "multiple")]
10022 (define_insn "*if_shift_shift"
10023 [(set (match_operand:SI 0 "s_register_operand" "=r")
10025 (match_operator 5 "arm_comparison_operator"
10026 [(match_operand 8 "cc_register" "") (const_int 0)])
10027 (match_operator:SI 6 "shift_operator"
10028 [(match_operand:SI 1 "s_register_operand" "r")
10029 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10030 (match_operator:SI 7 "shift_operator"
10031 [(match_operand:SI 3 "s_register_operand" "r")
10032 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10034 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10035 [(set_attr "conds" "use")
10036 (set_attr "shift" "1")
10037 (set_attr "length" "8")
10038 (set (attr "type") (if_then_else
10039 (and (match_operand 2 "const_int_operand" "")
10040 (match_operand 4 "const_int_operand" ""))
10041 (const_string "mov_shift")
10042 (const_string "mov_shift_reg")))]
10045 (define_insn "*ifcompare_not_arith"
10046 [(set (match_operand:SI 0 "s_register_operand" "=r")
10048 (match_operator 6 "arm_comparison_operator"
10049 [(match_operand:SI 4 "s_register_operand" "r")
10050 (match_operand:SI 5 "arm_add_operand" "rIL")])
10051 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10052 (match_operator:SI 7 "shiftable_operator"
10053 [(match_operand:SI 2 "s_register_operand" "r")
10054 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10055 (clobber (reg:CC CC_REGNUM))]
10058 [(set_attr "conds" "clob")
10059 (set_attr "length" "12")
10060 (set_attr "type" "multiple")]
10063 (define_insn "*if_not_arith"
10064 [(set (match_operand:SI 0 "s_register_operand" "=r")
10066 (match_operator 5 "arm_comparison_operator"
10067 [(match_operand 4 "cc_register" "") (const_int 0)])
10068 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10069 (match_operator:SI 6 "shiftable_operator"
10070 [(match_operand:SI 2 "s_register_operand" "r")
10071 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10073 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10074 [(set_attr "conds" "use")
10075 (set_attr "type" "mvn_reg")
10076 (set_attr "length" "8")]
10079 (define_insn "*ifcompare_arith_not"
10080 [(set (match_operand:SI 0 "s_register_operand" "=r")
10082 (match_operator 6 "arm_comparison_operator"
10083 [(match_operand:SI 4 "s_register_operand" "r")
10084 (match_operand:SI 5 "arm_add_operand" "rIL")])
10085 (match_operator:SI 7 "shiftable_operator"
10086 [(match_operand:SI 2 "s_register_operand" "r")
10087 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10088 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10089 (clobber (reg:CC CC_REGNUM))]
10092 [(set_attr "conds" "clob")
10093 (set_attr "length" "12")
10094 (set_attr "type" "multiple")]
10097 (define_insn "*if_arith_not"
10098 [(set (match_operand:SI 0 "s_register_operand" "=r")
10100 (match_operator 5 "arm_comparison_operator"
10101 [(match_operand 4 "cc_register" "") (const_int 0)])
10102 (match_operator:SI 6 "shiftable_operator"
10103 [(match_operand:SI 2 "s_register_operand" "r")
10104 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10105 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10107 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10108 [(set_attr "conds" "use")
10109 (set_attr "type" "multiple")
10110 (set_attr "length" "8")]
10113 (define_insn "*ifcompare_neg_move"
10114 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10116 (match_operator 5 "arm_comparison_operator"
10117 [(match_operand:SI 3 "s_register_operand" "r,r")
10118 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10119 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10120 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10121 (clobber (reg:CC CC_REGNUM))]
10124 [(set_attr "conds" "clob")
10125 (set_attr "length" "8,12")
10126 (set_attr "type" "multiple")]
10129 (define_insn_and_split "*if_neg_move"
10130 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10132 (match_operator 4 "arm_comparison_operator"
10133 [(match_operand 3 "cc_register" "") (const_int 0)])
10134 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10135 (match_operand:SI 1 "s_register_operand" "0,0")))]
10138 "&& reload_completed"
10139 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10140 (set (match_dup 0) (neg:SI (match_dup 2))))]
10142 [(set_attr "conds" "use")
10143 (set_attr "length" "4")
10144 (set_attr "arch" "t2,32")
10145 (set_attr "enabled_for_depr_it" "yes,no")
10146 (set_attr "type" "logic_shift_imm")]
10149 (define_insn "*ifcompare_move_neg"
10150 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10152 (match_operator 5 "arm_comparison_operator"
10153 [(match_operand:SI 3 "s_register_operand" "r,r")
10154 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10155 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10156 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10157 (clobber (reg:CC CC_REGNUM))]
10160 [(set_attr "conds" "clob")
10161 (set_attr "length" "8,12")
10162 (set_attr "type" "multiple")]
10165 (define_insn_and_split "*if_move_neg"
10166 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10168 (match_operator 4 "arm_comparison_operator"
10169 [(match_operand 3 "cc_register" "") (const_int 0)])
10170 (match_operand:SI 1 "s_register_operand" "0,0")
10171 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10174 "&& reload_completed"
10175 [(cond_exec (match_dup 5)
10176 (set (match_dup 0) (neg:SI (match_dup 2))))]
10178 machine_mode mode = GET_MODE (operands[3]);
10179 rtx_code rc = GET_CODE (operands[4]);
10181 if (mode == CCFPmode || mode == CCFPEmode)
10182 rc = reverse_condition_maybe_unordered (rc);
10184 rc = reverse_condition (rc);
10186 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10188 [(set_attr "conds" "use")
10189 (set_attr "length" "4")
10190 (set_attr "arch" "t2,32")
10191 (set_attr "enabled_for_depr_it" "yes,no")
10192 (set_attr "type" "logic_shift_imm")]
10195 (define_insn "*arith_adjacentmem"
10196 [(set (match_operand:SI 0 "s_register_operand" "=r")
10197 (match_operator:SI 1 "shiftable_operator"
10198 [(match_operand:SI 2 "memory_operand" "m")
10199 (match_operand:SI 3 "memory_operand" "m")]))
10200 (clobber (match_scratch:SI 4 "=r"))]
10201 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10207 HOST_WIDE_INT val1 = 0, val2 = 0;
10209 if (REGNO (operands[0]) > REGNO (operands[4]))
10211 ldm[1] = operands[4];
10212 ldm[2] = operands[0];
10216 ldm[1] = operands[0];
10217 ldm[2] = operands[4];
10220 base_reg = XEXP (operands[2], 0);
10222 if (!REG_P (base_reg))
10224 val1 = INTVAL (XEXP (base_reg, 1));
10225 base_reg = XEXP (base_reg, 0);
10228 if (!REG_P (XEXP (operands[3], 0)))
10229 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10231 arith[0] = operands[0];
10232 arith[3] = operands[1];
10246 if (val1 !=0 && val2 != 0)
10250 if (val1 == 4 || val2 == 4)
10251 /* Other val must be 8, since we know they are adjacent and neither
10253 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
10254 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10256 ldm[0] = ops[0] = operands[4];
10258 ops[2] = GEN_INT (val1);
10259 output_add_immediate (ops);
10261 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10263 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10267 /* Offset is out of range for a single add, so use two ldr. */
10270 ops[2] = GEN_INT (val1);
10271 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10273 ops[2] = GEN_INT (val2);
10274 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10277 else if (val1 != 0)
10280 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10282 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10287 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10289 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10291 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10294 [(set_attr "length" "12")
10295 (set_attr "predicable" "yes")
10296 (set_attr "type" "load1")]
10299 ; This pattern is never tried by combine, so do it as a peephole
10302 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10303 (match_operand:SI 1 "arm_general_register_operand" ""))
10304 (set (reg:CC CC_REGNUM)
10305 (compare:CC (match_dup 1) (const_int 0)))]
10307 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10308 (set (match_dup 0) (match_dup 1))])]
10313 [(set (match_operand:SI 0 "s_register_operand" "")
10314 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10316 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10317 [(match_operand:SI 3 "s_register_operand" "")
10318 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10319 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10321 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10322 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10327 ;; This split can be used because CC_Z mode implies that the following
10328 ;; branch will be an equality, or an unsigned inequality, so the sign
10329 ;; extension is not needed.
10332 [(set (reg:CC_Z CC_REGNUM)
10334 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10336 (match_operand 1 "const_int_operand" "")))
10337 (clobber (match_scratch:SI 2 ""))]
10339 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10340 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
10341 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10342 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10344 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10347 ;; ??? Check the patterns above for Thumb-2 usefulness
10349 (define_expand "prologue"
10350 [(clobber (const_int 0))]
10353 arm_expand_prologue ();
10355 thumb1_expand_prologue ();
10360 (define_expand "epilogue"
10361 [(clobber (const_int 0))]
10364 if (crtl->calls_eh_return)
10365 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10368 thumb1_expand_epilogue ();
10369 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10370 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10372 else if (HAVE_return)
10374 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10375 no need for explicit testing again. */
10376 emit_jump_insn (gen_return ());
10378 else if (TARGET_32BIT)
10380 arm_expand_epilogue (true);
10386 ;; Note - although unspec_volatile's USE all hard registers,
10387 ;; USEs are ignored after relaod has completed. Thus we need
10388 ;; to add an unspec of the link register to ensure that flow
10389 ;; does not think that it is unused by the sibcall branch that
10390 ;; will replace the standard function epilogue.
10391 (define_expand "sibcall_epilogue"
10392 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10393 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10396 arm_expand_epilogue (false);
10401 (define_expand "eh_epilogue"
10402 [(use (match_operand:SI 0 "register_operand" ""))
10403 (use (match_operand:SI 1 "register_operand" ""))
10404 (use (match_operand:SI 2 "register_operand" ""))]
10408 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10409 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10411 rtx ra = gen_rtx_REG (Pmode, 2);
10413 emit_move_insn (ra, operands[2]);
10416 /* This is a hack -- we may have crystalized the function type too
10418 cfun->machine->func_type = 0;
10422 ;; This split is only used during output to reduce the number of patterns
10423 ;; that need assembler instructions adding to them. We allowed the setting
10424 ;; of the conditions to be implicit during rtl generation so that
10425 ;; the conditional compare patterns would work. However this conflicts to
10426 ;; some extent with the conditional data operations, so we have to split them
10429 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10430 ;; conditional execution sufficient?
10433 [(set (match_operand:SI 0 "s_register_operand" "")
10434 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10435 [(match_operand 2 "" "") (match_operand 3 "" "")])
10437 (match_operand 4 "" "")))
10438 (clobber (reg:CC CC_REGNUM))]
10439 "TARGET_ARM && reload_completed"
10440 [(set (match_dup 5) (match_dup 6))
10441 (cond_exec (match_dup 7)
10442 (set (match_dup 0) (match_dup 4)))]
10445 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10446 operands[2], operands[3]);
10447 enum rtx_code rc = GET_CODE (operands[1]);
10449 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10450 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10451 if (mode == CCFPmode || mode == CCFPEmode)
10452 rc = reverse_condition_maybe_unordered (rc);
10454 rc = reverse_condition (rc);
10456 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10461 [(set (match_operand:SI 0 "s_register_operand" "")
10462 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10463 [(match_operand 2 "" "") (match_operand 3 "" "")])
10464 (match_operand 4 "" "")
10466 (clobber (reg:CC CC_REGNUM))]
10467 "TARGET_ARM && reload_completed"
10468 [(set (match_dup 5) (match_dup 6))
10469 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10470 (set (match_dup 0) (match_dup 4)))]
10473 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10474 operands[2], operands[3]);
10476 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10477 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10482 [(set (match_operand:SI 0 "s_register_operand" "")
10483 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10484 [(match_operand 2 "" "") (match_operand 3 "" "")])
10485 (match_operand 4 "" "")
10486 (match_operand 5 "" "")))
10487 (clobber (reg:CC CC_REGNUM))]
10488 "TARGET_ARM && reload_completed"
10489 [(set (match_dup 6) (match_dup 7))
10490 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10491 (set (match_dup 0) (match_dup 4)))
10492 (cond_exec (match_dup 8)
10493 (set (match_dup 0) (match_dup 5)))]
10496 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10497 operands[2], operands[3]);
10498 enum rtx_code rc = GET_CODE (operands[1]);
10500 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10501 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10502 if (mode == CCFPmode || mode == CCFPEmode)
10503 rc = reverse_condition_maybe_unordered (rc);
10505 rc = reverse_condition (rc);
10507 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10512 [(set (match_operand:SI 0 "s_register_operand" "")
10513 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10514 [(match_operand:SI 2 "s_register_operand" "")
10515 (match_operand:SI 3 "arm_add_operand" "")])
10516 (match_operand:SI 4 "arm_rhs_operand" "")
10518 (match_operand:SI 5 "s_register_operand" ""))))
10519 (clobber (reg:CC CC_REGNUM))]
10520 "TARGET_ARM && reload_completed"
10521 [(set (match_dup 6) (match_dup 7))
10522 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10523 (set (match_dup 0) (match_dup 4)))
10524 (cond_exec (match_dup 8)
10525 (set (match_dup 0) (not:SI (match_dup 5))))]
10528 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10529 operands[2], operands[3]);
10530 enum rtx_code rc = GET_CODE (operands[1]);
10532 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10533 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10534 if (mode == CCFPmode || mode == CCFPEmode)
10535 rc = reverse_condition_maybe_unordered (rc);
10537 rc = reverse_condition (rc);
10539 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10543 (define_insn "*cond_move_not"
10544 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10545 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10546 [(match_operand 3 "cc_register" "") (const_int 0)])
10547 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10549 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10553 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10554 [(set_attr "conds" "use")
10555 (set_attr "type" "mvn_reg,multiple")
10556 (set_attr "length" "4,8")]
10559 ;; The next two patterns occur when an AND operation is followed by a
10560 ;; scc insn sequence
10562 (define_insn "*sign_extract_onebit"
10563 [(set (match_operand:SI 0 "s_register_operand" "=r")
10564 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10566 (match_operand:SI 2 "const_int_operand" "n")))
10567 (clobber (reg:CC CC_REGNUM))]
10570 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10571 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10572 return \"mvnne\\t%0, #0\";
10574 [(set_attr "conds" "clob")
10575 (set_attr "length" "8")
10576 (set_attr "type" "multiple")]
10579 (define_insn "*not_signextract_onebit"
10580 [(set (match_operand:SI 0 "s_register_operand" "=r")
10582 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10584 (match_operand:SI 2 "const_int_operand" "n"))))
10585 (clobber (reg:CC CC_REGNUM))]
10588 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10589 output_asm_insn (\"tst\\t%1, %2\", operands);
10590 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10591 return \"movne\\t%0, #0\";
10593 [(set_attr "conds" "clob")
10594 (set_attr "length" "12")
10595 (set_attr "type" "multiple")]
10597 ;; ??? The above patterns need auditing for Thumb-2
10599 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10600 ;; expressions. For simplicity, the first register is also in the unspec
10602 ;; To avoid the usage of GNU extension, the length attribute is computed
10603 ;; in a C function arm_attr_length_push_multi.
10604 (define_insn "*push_multi"
10605 [(match_parallel 2 "multi_register_push"
10606 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10607 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10608 UNSPEC_PUSH_MULT))])]
10612 int num_saves = XVECLEN (operands[2], 0);
10614 /* For the StrongARM at least it is faster to
10615 use STR to store only a single register.
10616 In Thumb mode always use push, and the assembler will pick
10617 something appropriate. */
10618 if (num_saves == 1 && TARGET_ARM)
10619 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10626 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10627 else if (TARGET_THUMB2)
10628 strcpy (pattern, \"push%?\\t{%1\");
10630 strcpy (pattern, \"push\\t{%1\");
10632 for (i = 1; i < num_saves; i++)
10634 strcat (pattern, \", %|\");
10636 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10639 strcat (pattern, \"}\");
10640 output_asm_insn (pattern, operands);
10645 [(set_attr "type" "store4")
10646 (set (attr "length")
10647 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10650 (define_insn "stack_tie"
10651 [(set (mem:BLK (scratch))
10652 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10653 (match_operand:SI 1 "s_register_operand" "rk")]
10657 [(set_attr "length" "0")
10658 (set_attr "type" "block")]
10661 ;; Pop (as used in epilogue RTL)
10663 (define_insn "*load_multiple_with_writeback"
10664 [(match_parallel 0 "load_multiple_operation"
10665 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10666 (plus:SI (match_dup 1)
10667 (match_operand:SI 2 "const_int_I_operand" "I")))
10668 (set (match_operand:SI 3 "s_register_operand" "=rk")
10669 (mem:SI (match_dup 1)))
10671 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10674 arm_output_multireg_pop (operands, /*return_pc=*/false,
10675 /*cond=*/const_true_rtx,
10681 [(set_attr "type" "load4")
10682 (set_attr "predicable" "yes")]
10685 ;; Pop with return (as used in epilogue RTL)
10687 ;; This instruction is generated when the registers are popped at the end of
10688 ;; epilogue. Here, instead of popping the value into LR and then generating
10689 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10691 (define_insn "*pop_multiple_with_writeback_and_return"
10692 [(match_parallel 0 "pop_multiple_return"
10694 (set (match_operand:SI 1 "s_register_operand" "+rk")
10695 (plus:SI (match_dup 1)
10696 (match_operand:SI 2 "const_int_I_operand" "I")))
10697 (set (match_operand:SI 3 "s_register_operand" "=rk")
10698 (mem:SI (match_dup 1)))
10700 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10703 arm_output_multireg_pop (operands, /*return_pc=*/true,
10704 /*cond=*/const_true_rtx,
10710 [(set_attr "type" "load4")
10711 (set_attr "predicable" "yes")]
10714 (define_insn "*pop_multiple_with_return"
10715 [(match_parallel 0 "pop_multiple_return"
10717 (set (match_operand:SI 2 "s_register_operand" "=rk")
10718 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10720 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10723 arm_output_multireg_pop (operands, /*return_pc=*/true,
10724 /*cond=*/const_true_rtx,
10730 [(set_attr "type" "load4")
10731 (set_attr "predicable" "yes")]
10734 ;; Load into PC and return
10735 (define_insn "*ldr_with_return"
10737 (set (reg:SI PC_REGNUM)
10738 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10739 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10740 "ldr%?\t%|pc, [%0], #4"
10741 [(set_attr "type" "load1")
10742 (set_attr "predicable" "yes")]
10744 ;; Pop for floating point registers (as used in epilogue RTL)
10745 (define_insn "*vfp_pop_multiple_with_writeback"
10746 [(match_parallel 0 "pop_multiple_fp"
10747 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10748 (plus:SI (match_dup 1)
10749 (match_operand:SI 2 "const_int_I_operand" "I")))
10750 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10751 (mem:DF (match_dup 1)))])]
10752 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10755 int num_regs = XVECLEN (operands[0], 0);
10758 strcpy (pattern, \"vldm\\t\");
10759 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10760 strcat (pattern, \"!, {\");
10761 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10762 strcat (pattern, \"%P0\");
10763 if ((num_regs - 1) > 1)
10765 strcat (pattern, \"-%P1\");
10766 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10769 strcat (pattern, \"}\");
10770 output_asm_insn (pattern, op_list);
10774 [(set_attr "type" "load4")
10775 (set_attr "conds" "unconditional")
10776 (set_attr "predicable" "no")]
10779 ;; Special patterns for dealing with the constant pool
10781 (define_insn "align_4"
10782 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10785 assemble_align (32);
10788 [(set_attr "type" "no_insn")]
10791 (define_insn "align_8"
10792 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10795 assemble_align (64);
10798 [(set_attr "type" "no_insn")]
10801 (define_insn "consttable_end"
10802 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10805 making_const_table = FALSE;
10808 [(set_attr "type" "no_insn")]
10811 (define_insn "consttable_1"
10812 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10815 making_const_table = TRUE;
10816 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10817 assemble_zeros (3);
10820 [(set_attr "length" "4")
10821 (set_attr "type" "no_insn")]
10824 (define_insn "consttable_2"
10825 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10829 rtx x = operands[0];
10830 making_const_table = TRUE;
10831 switch (GET_MODE_CLASS (GET_MODE (x)))
10834 arm_emit_fp16_const (x);
10837 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10838 assemble_zeros (2);
10843 [(set_attr "length" "4")
10844 (set_attr "type" "no_insn")]
10847 (define_insn "consttable_4"
10848 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10852 rtx x = operands[0];
10853 making_const_table = TRUE;
10854 switch (GET_MODE_CLASS (GET_MODE (x)))
10859 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10860 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10864 /* XXX: Sometimes gcc does something really dumb and ends up with
10865 a HIGH in a constant pool entry, usually because it's trying to
10866 load into a VFP register. We know this will always be used in
10867 combination with a LO_SUM which ignores the high bits, so just
10868 strip off the HIGH. */
10869 if (GET_CODE (x) == HIGH)
10871 assemble_integer (x, 4, BITS_PER_WORD, 1);
10872 mark_symbol_refs_as_used (x);
10877 [(set_attr "length" "4")
10878 (set_attr "type" "no_insn")]
10881 (define_insn "consttable_8"
10882 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10886 making_const_table = TRUE;
10887 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10892 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10893 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10897 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10902 [(set_attr "length" "8")
10903 (set_attr "type" "no_insn")]
10906 (define_insn "consttable_16"
10907 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10911 making_const_table = TRUE;
10912 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10917 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10918 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10922 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10927 [(set_attr "length" "16")
10928 (set_attr "type" "no_insn")]
10931 ;; V5 Instructions,
10933 (define_insn "clzsi2"
10934 [(set (match_operand:SI 0 "s_register_operand" "=r")
10935 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10936 "TARGET_32BIT && arm_arch5"
10938 [(set_attr "predicable" "yes")
10939 (set_attr "predicable_short_it" "no")
10940 (set_attr "type" "clz")])
10942 (define_insn "rbitsi2"
10943 [(set (match_operand:SI 0 "s_register_operand" "=r")
10944 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10945 "TARGET_32BIT && arm_arch_thumb2"
10947 [(set_attr "predicable" "yes")
10948 (set_attr "predicable_short_it" "no")
10949 (set_attr "type" "clz")])
10951 (define_expand "ctzsi2"
10952 [(set (match_operand:SI 0 "s_register_operand" "")
10953 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10954 "TARGET_32BIT && arm_arch_thumb2"
10957 rtx tmp = gen_reg_rtx (SImode);
10958 emit_insn (gen_rbitsi2 (tmp, operands[1]));
10959 emit_insn (gen_clzsi2 (operands[0], tmp));
10965 ;; V5E instructions.
10967 (define_insn "prefetch"
10968 [(prefetch (match_operand:SI 0 "address_operand" "p")
10969 (match_operand:SI 1 "" "")
10970 (match_operand:SI 2 "" ""))]
10971 "TARGET_32BIT && arm_arch5e"
10973 [(set_attr "type" "load1")]
10976 ;; General predication pattern
10979 [(match_operator 0 "arm_comparison_operator"
10980 [(match_operand 1 "cc_register" "")
10983 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
10985 [(set_attr "predicated" "yes")]
10988 (define_insn "force_register_use"
10989 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10992 [(set_attr "length" "0")
10993 (set_attr "type" "no_insn")]
10997 ;; Patterns for exception handling
10999 (define_expand "eh_return"
11000 [(use (match_operand 0 "general_operand" ""))]
11005 emit_insn (gen_arm_eh_return (operands[0]));
11007 emit_insn (gen_thumb_eh_return (operands[0]));
11012 ;; We can't expand this before we know where the link register is stored.
11013 (define_insn_and_split "arm_eh_return"
11014 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11016 (clobber (match_scratch:SI 1 "=&r"))]
11019 "&& reload_completed"
11023 arm_set_return_address (operands[0], operands[1]);
11031 (define_insn "load_tp_hard"
11032 [(set (match_operand:SI 0 "register_operand" "=r")
11033 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11035 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11036 [(set_attr "predicable" "yes")
11037 (set_attr "type" "mrs")]
11040 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11041 (define_insn "load_tp_soft"
11042 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11043 (clobber (reg:SI LR_REGNUM))
11044 (clobber (reg:SI IP_REGNUM))
11045 (clobber (reg:CC CC_REGNUM))]
11047 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11048 [(set_attr "conds" "clob")
11049 (set_attr "type" "branch")]
11052 ;; tls descriptor call
11053 (define_insn "tlscall"
11054 [(set (reg:SI R0_REGNUM)
11055 (unspec:SI [(reg:SI R0_REGNUM)
11056 (match_operand:SI 0 "" "X")
11057 (match_operand 1 "" "")] UNSPEC_TLS))
11058 (clobber (reg:SI R1_REGNUM))
11059 (clobber (reg:SI LR_REGNUM))
11060 (clobber (reg:SI CC_REGNUM))]
11063 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11064 INTVAL (operands[1]));
11065 return "bl\\t%c0(tlscall)";
11067 [(set_attr "conds" "clob")
11068 (set_attr "length" "4")
11069 (set_attr "type" "branch")]
11072 ;; For thread pointer builtin
11073 (define_expand "get_thread_pointersi"
11074 [(match_operand:SI 0 "s_register_operand" "=r")]
11078 arm_load_tp (operands[0]);
11084 ;; We only care about the lower 16 bits of the constant
11085 ;; being inserted into the upper 16 bits of the register.
11086 (define_insn "*arm_movtas_ze"
11087 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
11090 (match_operand:SI 1 "const_int_operand" ""))]
11093 [(set_attr "predicable" "yes")
11094 (set_attr "predicable_short_it" "no")
11095 (set_attr "length" "4")
11096 (set_attr "type" "alu_sreg")]
11099 (define_insn "*arm_rev"
11100 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11101 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11107 [(set_attr "arch" "t1,t2,32")
11108 (set_attr "length" "2,2,4")
11109 (set_attr "predicable" "no,yes,yes")
11110 (set_attr "predicable_short_it" "no")
11111 (set_attr "type" "rev")]
11114 (define_expand "arm_legacy_rev"
11115 [(set (match_operand:SI 2 "s_register_operand" "")
11116 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11120 (lshiftrt:SI (match_dup 2)
11122 (set (match_operand:SI 3 "s_register_operand" "")
11123 (rotatert:SI (match_dup 1)
11126 (and:SI (match_dup 2)
11127 (const_int -65281)))
11128 (set (match_operand:SI 0 "s_register_operand" "")
11129 (xor:SI (match_dup 3)
11135 ;; Reuse temporaries to keep register pressure down.
11136 (define_expand "thumb_legacy_rev"
11137 [(set (match_operand:SI 2 "s_register_operand" "")
11138 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11140 (set (match_operand:SI 3 "s_register_operand" "")
11141 (lshiftrt:SI (match_dup 1)
11144 (ior:SI (match_dup 3)
11146 (set (match_operand:SI 4 "s_register_operand" "")
11148 (set (match_operand:SI 5 "s_register_operand" "")
11149 (rotatert:SI (match_dup 1)
11152 (ashift:SI (match_dup 5)
11155 (lshiftrt:SI (match_dup 5)
11158 (ior:SI (match_dup 5)
11161 (rotatert:SI (match_dup 5)
11163 (set (match_operand:SI 0 "s_register_operand" "")
11164 (ior:SI (match_dup 5)
11170 ;; ARM-specific expansion of signed mod by power of 2
11171 ;; using conditional negate.
11172 ;; For r0 % n where n is a power of 2 produce:
11174 ;; and r0, r0, #(n - 1)
11175 ;; and r1, r1, #(n - 1)
11176 ;; rsbpl r0, r1, #0
11178 (define_expand "modsi3"
11179 [(match_operand:SI 0 "register_operand" "")
11180 (match_operand:SI 1 "register_operand" "")
11181 (match_operand:SI 2 "const_int_operand" "")]
11184 HOST_WIDE_INT val = INTVAL (operands[2]);
11187 || exact_log2 (val) <= 0)
11190 rtx mask = GEN_INT (val - 1);
11192 /* In the special case of x0 % 2 we can do the even shorter:
11195 rsblt r0, r0, #0. */
11199 rtx cc_reg = arm_gen_compare_reg (LT,
11200 operands[1], const0_rtx, NULL_RTX);
11201 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11202 rtx masked = gen_reg_rtx (SImode);
11204 emit_insn (gen_andsi3 (masked, operands[1], mask));
11205 emit_move_insn (operands[0],
11206 gen_rtx_IF_THEN_ELSE (SImode, cond,
11207 gen_rtx_NEG (SImode,
11213 rtx neg_op = gen_reg_rtx (SImode);
11214 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11217 /* Extract the condition register and mode. */
11218 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11219 rtx cc_reg = SET_DEST (cmp);
11220 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11222 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11224 rtx masked_neg = gen_reg_rtx (SImode);
11225 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11227 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11228 during expand does not always work. Do an IF_THEN_ELSE instead. */
11229 emit_move_insn (operands[0],
11230 gen_rtx_IF_THEN_ELSE (SImode, cond,
11231 gen_rtx_NEG (SImode, masked_neg),
11239 (define_expand "bswapsi2"
11240 [(set (match_operand:SI 0 "s_register_operand" "=r")
11241 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11242 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11246 rtx op2 = gen_reg_rtx (SImode);
11247 rtx op3 = gen_reg_rtx (SImode);
11251 rtx op4 = gen_reg_rtx (SImode);
11252 rtx op5 = gen_reg_rtx (SImode);
11254 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11255 op2, op3, op4, op5));
11259 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11268 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11269 ;; and unsigned variants, respectively. For rev16, expose
11270 ;; byte-swapping in the lower 16 bits only.
11271 (define_insn "*arm_revsh"
11272 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11273 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11279 [(set_attr "arch" "t1,t2,32")
11280 (set_attr "length" "2,2,4")
11281 (set_attr "type" "rev")]
11284 (define_insn "*arm_rev16"
11285 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11286 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11292 [(set_attr "arch" "t1,t2,32")
11293 (set_attr "length" "2,2,4")
11294 (set_attr "type" "rev")]
11297 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11298 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11299 ;; each valid permutation.
11301 (define_insn "arm_rev16si2"
11302 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11303 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11305 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11306 (and:SI (lshiftrt:SI (match_dup 1)
11308 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11310 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11311 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11313 [(set_attr "arch" "t1,t2,32")
11314 (set_attr "length" "2,2,4")
11315 (set_attr "type" "rev")]
11318 (define_insn "arm_rev16si2_alt"
11319 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11320 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11322 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11323 (and:SI (ashift:SI (match_dup 1)
11325 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11327 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11328 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11330 [(set_attr "arch" "t1,t2,32")
11331 (set_attr "length" "2,2,4")
11332 (set_attr "type" "rev")]
11335 (define_expand "bswaphi2"
11336 [(set (match_operand:HI 0 "s_register_operand" "=r")
11337 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11342 ;; Patterns for LDRD/STRD in Thumb2 mode
11344 (define_insn "*thumb2_ldrd"
11345 [(set (match_operand:SI 0 "s_register_operand" "=r")
11346 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11347 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11348 (set (match_operand:SI 3 "s_register_operand" "=r")
11349 (mem:SI (plus:SI (match_dup 1)
11350 (match_operand:SI 4 "const_int_operand" ""))))]
11351 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11352 && current_tune->prefer_ldrd_strd
11353 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11354 && (operands_ok_ldrd_strd (operands[0], operands[3],
11355 operands[1], INTVAL (operands[2]),
11357 "ldrd%?\t%0, %3, [%1, %2]"
11358 [(set_attr "type" "load2")
11359 (set_attr "predicable" "yes")
11360 (set_attr "predicable_short_it" "no")])
11362 (define_insn "*thumb2_ldrd_base"
11363 [(set (match_operand:SI 0 "s_register_operand" "=r")
11364 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11365 (set (match_operand:SI 2 "s_register_operand" "=r")
11366 (mem:SI (plus:SI (match_dup 1)
11368 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11369 && current_tune->prefer_ldrd_strd
11370 && (operands_ok_ldrd_strd (operands[0], operands[2],
11371 operands[1], 0, false, true))"
11372 "ldrd%?\t%0, %2, [%1]"
11373 [(set_attr "type" "load2")
11374 (set_attr "predicable" "yes")
11375 (set_attr "predicable_short_it" "no")])
11377 (define_insn "*thumb2_ldrd_base_neg"
11378 [(set (match_operand:SI 0 "s_register_operand" "=r")
11379 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11381 (set (match_operand:SI 2 "s_register_operand" "=r")
11382 (mem:SI (match_dup 1)))]
11383 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11384 && current_tune->prefer_ldrd_strd
11385 && (operands_ok_ldrd_strd (operands[0], operands[2],
11386 operands[1], -4, false, true))"
11387 "ldrd%?\t%0, %2, [%1, #-4]"
11388 [(set_attr "type" "load2")
11389 (set_attr "predicable" "yes")
11390 (set_attr "predicable_short_it" "no")])
11392 (define_insn "*thumb2_strd"
11393 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11394 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11395 (match_operand:SI 2 "s_register_operand" "r"))
11396 (set (mem:SI (plus:SI (match_dup 0)
11397 (match_operand:SI 3 "const_int_operand" "")))
11398 (match_operand:SI 4 "s_register_operand" "r"))]
11399 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11400 && current_tune->prefer_ldrd_strd
11401 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11402 && (operands_ok_ldrd_strd (operands[2], operands[4],
11403 operands[0], INTVAL (operands[1]),
11405 "strd%?\t%2, %4, [%0, %1]"
11406 [(set_attr "type" "store2")
11407 (set_attr "predicable" "yes")
11408 (set_attr "predicable_short_it" "no")])
11410 (define_insn "*thumb2_strd_base"
11411 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11412 (match_operand:SI 1 "s_register_operand" "r"))
11413 (set (mem:SI (plus:SI (match_dup 0)
11415 (match_operand:SI 2 "s_register_operand" "r"))]
11416 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11417 && current_tune->prefer_ldrd_strd
11418 && (operands_ok_ldrd_strd (operands[1], operands[2],
11419 operands[0], 0, false, false))"
11420 "strd%?\t%1, %2, [%0]"
11421 [(set_attr "type" "store2")
11422 (set_attr "predicable" "yes")
11423 (set_attr "predicable_short_it" "no")])
11425 (define_insn "*thumb2_strd_base_neg"
11426 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11428 (match_operand:SI 1 "s_register_operand" "r"))
11429 (set (mem:SI (match_dup 0))
11430 (match_operand:SI 2 "s_register_operand" "r"))]
11431 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11432 && current_tune->prefer_ldrd_strd
11433 && (operands_ok_ldrd_strd (operands[1], operands[2],
11434 operands[0], -4, false, false))"
11435 "strd%?\t%1, %2, [%0, #-4]"
11436 [(set_attr "type" "store2")
11437 (set_attr "predicable" "yes")
11438 (set_attr "predicable_short_it" "no")])
11440 ;; ARMv8 CRC32 instructions.
11441 (define_insn "<crc_variant>"
11442 [(set (match_operand:SI 0 "s_register_operand" "=r")
11443 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11444 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11447 "<crc_variant>\\t%0, %1, %2"
11448 [(set_attr "type" "crc")
11449 (set_attr "conds" "unconditional")]
11452 ;; Load the load/store double peephole optimizations.
11453 (include "ldrdstrd.md")
11455 ;; Load the load/store multiple patterns
11456 (include "ldmstm.md")
11458 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11459 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11460 (define_insn "*load_multiple"
11461 [(match_parallel 0 "load_multiple_operation"
11462 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11463 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11468 arm_output_multireg_pop (operands, /*return_pc=*/false,
11469 /*cond=*/const_true_rtx,
11475 [(set_attr "predicable" "yes")]
11478 (define_expand "copysignsf3"
11479 [(match_operand:SF 0 "register_operand")
11480 (match_operand:SF 1 "register_operand")
11481 (match_operand:SF 2 "register_operand")]
11482 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11484 emit_move_insn (operands[0], operands[2]);
11485 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11486 GEN_INT (31), GEN_INT (0),
11487 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11492 (define_expand "copysigndf3"
11493 [(match_operand:DF 0 "register_operand")
11494 (match_operand:DF 1 "register_operand")
11495 (match_operand:DF 2 "register_operand")]
11496 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11498 rtx op0_low = gen_lowpart (SImode, operands[0]);
11499 rtx op0_high = gen_highpart (SImode, operands[0]);
11500 rtx op1_low = gen_lowpart (SImode, operands[1]);
11501 rtx op1_high = gen_highpart (SImode, operands[1]);
11502 rtx op2_high = gen_highpart (SImode, operands[2]);
11504 rtx scratch1 = gen_reg_rtx (SImode);
11505 rtx scratch2 = gen_reg_rtx (SImode);
11506 emit_move_insn (scratch1, op2_high);
11507 emit_move_insn (scratch2, op1_high);
11509 emit_insn(gen_rtx_SET(scratch1,
11510 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11511 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11512 emit_move_insn (op0_low, op1_low);
11513 emit_move_insn (op0_high, scratch2);
11519 ;; Vector bits common to IWMMXT and Neon
11520 (include "vec-common.md")
11521 ;; Load the Intel Wireless Multimedia Extension patterns
11522 (include "iwmmxt.md")
11523 ;; Load the VFP co-processor patterns
11525 ;; Thumb-1 patterns
11526 (include "thumb1.md")
11527 ;; Thumb-2 patterns
11528 (include "thumb2.md")
11530 (include "neon.md")
11532 (include "crypto.md")
11533 ;; Synchronization Primitives
11534 (include "sync.md")
11535 ;; Fixed-point patterns
11536 (include "arm-fixed.md")