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" "no,yes" (const (symbol_ref "thumb_code")))
74 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
75 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
77 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
78 (define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
80 ; We use this attribute to disable alternatives that can produce 32-bit
81 ; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
82 ; that contain 32-bit instructions.
83 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
85 ; This attribute is used to disable a predicated alternative when we have
87 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
89 ;; Operand number of an input operand that is shifted. Zero if the
90 ;; given instruction does not shift one of its input operands.
91 (define_attr "shift" "" (const_int 0))
93 ;; [For compatibility with AArch64 in pipeline models]
94 ;; Attribute that specifies whether or not the instruction touches fp
96 (define_attr "fp" "no,yes" (const_string "no"))
98 ; Floating Point Unit. If we only have floating point emulation, then there
99 ; is no point in scheduling the floating point insns. (Well, for best
100 ; performance we should try and group them together).
101 (define_attr "fpu" "none,vfp"
102 (const (symbol_ref "arm_fpu_attr")))
104 (define_attr "predicated" "yes,no" (const_string "no"))
106 ; LENGTH of an instruction (in bytes)
107 (define_attr "length" ""
110 ; The architecture which supports the instruction (or alternative).
111 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
112 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
113 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
114 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6. This attribute is
115 ; used to compute attribute "enabled", use type "any" to enable an
116 ; alternative in all cases.
117 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3"
118 (const_string "any"))
120 (define_attr "arch_enabled" "no,yes"
121 (cond [(eq_attr "arch" "any")
124 (and (eq_attr "arch" "a")
125 (match_test "TARGET_ARM"))
128 (and (eq_attr "arch" "t")
129 (match_test "TARGET_THUMB"))
132 (and (eq_attr "arch" "t1")
133 (match_test "TARGET_THUMB1"))
136 (and (eq_attr "arch" "t2")
137 (match_test "TARGET_THUMB2"))
140 (and (eq_attr "arch" "32")
141 (match_test "TARGET_32BIT"))
144 (and (eq_attr "arch" "v6")
145 (match_test "TARGET_32BIT && arm_arch6"))
148 (and (eq_attr "arch" "nov6")
149 (match_test "TARGET_32BIT && !arm_arch6"))
152 (and (eq_attr "arch" "v6t2")
153 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
156 (and (eq_attr "arch" "avoid_neon_for_64bits")
157 (match_test "TARGET_NEON")
158 (not (match_test "TARGET_PREFER_NEON_64BITS")))
161 (and (eq_attr "arch" "neon_for_64bits")
162 (match_test "TARGET_NEON")
163 (match_test "TARGET_PREFER_NEON_64BITS"))
166 (and (eq_attr "arch" "iwmmxt2")
167 (match_test "TARGET_REALLY_IWMMXT2"))
170 (and (eq_attr "arch" "armv6_or_vfpv3")
171 (match_test "arm_arch6 || TARGET_VFP3"))
175 (const_string "no")))
177 (define_attr "opt" "any,speed,size"
178 (const_string "any"))
180 (define_attr "opt_enabled" "no,yes"
181 (cond [(eq_attr "opt" "any")
184 (and (eq_attr "opt" "speed")
185 (match_test "optimize_function_for_speed_p (cfun)"))
188 (and (eq_attr "opt" "size")
189 (match_test "optimize_function_for_size_p (cfun)"))
190 (const_string "yes")]
191 (const_string "no")))
193 (define_attr "use_literal_pool" "no,yes"
194 (cond [(and (eq_attr "type" "f_loads,f_loadd")
195 (match_test "CONSTANT_P (operands[1])"))
196 (const_string "yes")]
197 (const_string "no")))
199 ; Enable all alternatives that are both arch_enabled and insn_enabled.
200 ; FIXME:: opt_enabled has been temporarily removed till the time we have
201 ; an attribute that allows the use of such alternatives.
202 ; This depends on caching of speed_p, size_p on a per
203 ; alternative basis. The problem is that the enabled attribute
204 ; cannot depend on any state that is not cached or is not constant
205 ; for a compilation unit. We probably need a generic "hot/cold"
206 ; alternative which if implemented can help with this. We disable this
207 ; until such a time as this is implemented and / or the improvements or
208 ; regressions with removing this attribute are double checked.
209 ; See ashldi3_neon and <shift>di3_neon in neon.md.
211 (define_attr "enabled" "no,yes"
212 (cond [(and (eq_attr "predicable_short_it" "no")
213 (and (eq_attr "predicated" "yes")
214 (match_test "arm_restrict_it")))
217 (and (eq_attr "enabled_for_depr_it" "no")
218 (match_test "arm_restrict_it"))
221 (and (eq_attr "use_literal_pool" "yes")
222 (match_test "arm_disable_literal_pool"))
225 (eq_attr "arch_enabled" "no")
227 (const_string "yes")))
229 ; POOL_RANGE is how far away from a constant pool entry that this insn
230 ; can be placed. If the distance is zero, then this insn will never
231 ; reference the pool.
232 ; Note that for Thumb constant pools the PC value is rounded down to the
233 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
234 ; Thumb insns) should be set to <max_range> - 2.
235 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
236 ; before its address. It is set to <max_range> - (8 + <data_size>).
237 (define_attr "arm_pool_range" "" (const_int 0))
238 (define_attr "thumb2_pool_range" "" (const_int 0))
239 (define_attr "arm_neg_pool_range" "" (const_int 0))
240 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
242 (define_attr "pool_range" ""
243 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
244 (attr "arm_pool_range")))
245 (define_attr "neg_pool_range" ""
246 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
247 (attr "arm_neg_pool_range")))
249 ; An assembler sequence may clobber the condition codes without us knowing.
250 ; If such an insn references the pool, then we have no way of knowing how,
251 ; so use the most conservative value for pool_range.
252 (define_asm_attributes
253 [(set_attr "conds" "clob")
254 (set_attr "length" "4")
255 (set_attr "pool_range" "250")])
257 ; Load scheduling, set from the arm_ld_sched variable
258 ; initialized by arm_option_override()
259 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
261 ; condition codes: this one is used by final_prescan_insn to speed up
262 ; conditionalizing instructions. It saves having to scan the rtl to see if
263 ; it uses or alters the condition codes.
265 ; USE means that the condition codes are used by the insn in the process of
266 ; outputting code, this means (at present) that we can't use the insn in
269 ; SET means that the purpose of the insn is to set the condition codes in a
270 ; well defined manner.
272 ; CLOB means that the condition codes are altered in an undefined manner, if
273 ; they are altered at all
275 ; UNCONDITIONAL means the instruction can not be conditionally executed and
276 ; that the instruction does not use or alter the condition codes.
278 ; NOCOND means that the instruction does not use or alter the condition
279 ; codes but can be converted into a conditionally exectuted instruction.
281 (define_attr "conds" "use,set,clob,unconditional,nocond"
283 (ior (eq_attr "is_thumb1" "yes")
284 (eq_attr "type" "call"))
285 (const_string "clob")
286 (if_then_else (eq_attr "is_neon_type" "no")
287 (const_string "nocond")
288 (const_string "unconditional"))))
290 ; Predicable means that the insn can be conditionally executed based on
291 ; an automatically added predicate (additional patterns are generated by
292 ; gen...). We default to 'no' because no Thumb patterns match this rule
293 ; and not all ARM patterns do.
294 (define_attr "predicable" "no,yes" (const_string "no"))
296 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
297 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
298 ; suffer blockages enough to warrant modelling this (and it can adversely
299 ; affect the schedule).
300 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
302 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
303 ; to stall the processor. Used with model_wbuf above.
304 (define_attr "write_conflict" "no,yes"
305 (if_then_else (eq_attr "type"
308 (const_string "no")))
310 ; Classify the insns into those that take one cycle and those that take more
311 ; than one on the main cpu execution unit.
312 (define_attr "core_cycles" "single,multi"
313 (if_then_else (eq_attr "type"
314 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
315 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
316 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
317 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
318 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
319 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
320 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
321 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
322 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
323 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
324 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
325 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
326 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
327 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
328 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
329 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
330 (const_string "single")
331 (const_string "multi")))
333 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
334 ;; distant label. Only applicable to Thumb code.
335 (define_attr "far_jump" "yes,no" (const_string "no"))
338 ;; The number of machine instructions this pattern expands to.
339 ;; Used for Thumb-2 conditional execution.
340 (define_attr "ce_count" "" (const_int 1))
342 ;;---------------------------------------------------------------------------
345 (include "unspecs.md")
347 ;;---------------------------------------------------------------------------
350 (include "iterators.md")
352 ;;---------------------------------------------------------------------------
355 (include "predicates.md")
356 (include "constraints.md")
358 ;;---------------------------------------------------------------------------
359 ;; Pipeline descriptions
361 (define_attr "tune_cortexr4" "yes,no"
363 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
365 (const_string "no"))))
367 ;; True if the generic scheduling description should be used.
369 (define_attr "generic_sched" "yes,no"
371 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
372 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
373 arm1136jfs,cortexa5,cortexa7,cortexa8,\
374 cortexa9,cortexa12,cortexa15,cortexa17,\
375 cortexa53,cortexa57,cortexm4,cortexm7,\
377 (eq_attr "tune_cortexr4" "yes"))
379 (const_string "yes"))))
381 (define_attr "generic_vfp" "yes,no"
383 (and (eq_attr "fpu" "vfp")
384 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
385 cortexa8,cortexa9,cortexa53,cortexm4,\
386 cortexm7,marvell_pj4,xgene1")
387 (eq_attr "tune_cortexr4" "no"))
389 (const_string "no"))))
391 (include "marvell-f-iwmmxt.md")
392 (include "arm-generic.md")
393 (include "arm926ejs.md")
394 (include "arm1020e.md")
395 (include "arm1026ejs.md")
396 (include "arm1136jfs.md")
398 (include "fa606te.md")
399 (include "fa626te.md")
400 (include "fmp626.md")
401 (include "fa726te.md")
402 (include "cortex-a5.md")
403 (include "cortex-a7.md")
404 (include "cortex-a8.md")
405 (include "cortex-a9.md")
406 (include "cortex-a15.md")
407 (include "cortex-a17.md")
408 (include "cortex-a53.md")
409 (include "cortex-a57.md")
410 (include "cortex-r4.md")
411 (include "cortex-r4f.md")
412 (include "cortex-m7.md")
413 (include "cortex-m4.md")
414 (include "cortex-m4-fpu.md")
416 (include "marvell-pj4.md")
417 (include "xgene1.md")
420 ;;---------------------------------------------------------------------------
425 ;; Note: For DImode insns, there is normally no reason why operands should
426 ;; not be in the same register, what we don't want is for something being
427 ;; written to partially overlap something that is an input.
429 (define_expand "adddi3"
431 [(set (match_operand:DI 0 "s_register_operand" "")
432 (plus:DI (match_operand:DI 1 "s_register_operand" "")
433 (match_operand:DI 2 "arm_adddi_operand" "")))
434 (clobber (reg:CC CC_REGNUM))])]
439 if (!REG_P (operands[1]))
440 operands[1] = force_reg (DImode, operands[1]);
441 if (!REG_P (operands[2]))
442 operands[2] = force_reg (DImode, operands[2]);
447 (define_insn_and_split "*arm_adddi3"
448 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
449 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
450 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
451 (clobber (reg:CC CC_REGNUM))]
452 "TARGET_32BIT && !TARGET_NEON"
454 "TARGET_32BIT && reload_completed
455 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
456 [(parallel [(set (reg:CC_C CC_REGNUM)
457 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
459 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
460 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
461 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
464 operands[3] = gen_highpart (SImode, operands[0]);
465 operands[0] = gen_lowpart (SImode, operands[0]);
466 operands[4] = gen_highpart (SImode, operands[1]);
467 operands[1] = gen_lowpart (SImode, operands[1]);
468 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
469 operands[2] = gen_lowpart (SImode, operands[2]);
471 [(set_attr "conds" "clob")
472 (set_attr "length" "8")
473 (set_attr "type" "multiple")]
476 (define_insn_and_split "*adddi_sesidi_di"
477 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
478 (plus:DI (sign_extend:DI
479 (match_operand:SI 2 "s_register_operand" "r,r"))
480 (match_operand:DI 1 "s_register_operand" "0,r")))
481 (clobber (reg:CC CC_REGNUM))]
484 "TARGET_32BIT && reload_completed"
485 [(parallel [(set (reg:CC_C CC_REGNUM)
486 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
488 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
489 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
492 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
495 operands[3] = gen_highpart (SImode, operands[0]);
496 operands[0] = gen_lowpart (SImode, operands[0]);
497 operands[4] = gen_highpart (SImode, operands[1]);
498 operands[1] = gen_lowpart (SImode, operands[1]);
499 operands[2] = gen_lowpart (SImode, operands[2]);
501 [(set_attr "conds" "clob")
502 (set_attr "length" "8")
503 (set_attr "type" "multiple")]
506 (define_insn_and_split "*adddi_zesidi_di"
507 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
508 (plus:DI (zero_extend:DI
509 (match_operand:SI 2 "s_register_operand" "r,r"))
510 (match_operand:DI 1 "s_register_operand" "0,r")))
511 (clobber (reg:CC CC_REGNUM))]
514 "TARGET_32BIT && reload_completed"
515 [(parallel [(set (reg:CC_C CC_REGNUM)
516 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
518 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
519 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
520 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
523 operands[3] = gen_highpart (SImode, operands[0]);
524 operands[0] = gen_lowpart (SImode, operands[0]);
525 operands[4] = gen_highpart (SImode, operands[1]);
526 operands[1] = gen_lowpart (SImode, operands[1]);
527 operands[2] = gen_lowpart (SImode, operands[2]);
529 [(set_attr "conds" "clob")
530 (set_attr "length" "8")
531 (set_attr "type" "multiple")]
534 (define_expand "addsi3"
535 [(set (match_operand:SI 0 "s_register_operand" "")
536 (plus:SI (match_operand:SI 1 "s_register_operand" "")
537 (match_operand:SI 2 "reg_or_int_operand" "")))]
540 if (TARGET_32BIT && CONST_INT_P (operands[2]))
542 arm_split_constant (PLUS, SImode, NULL_RTX,
543 INTVAL (operands[2]), operands[0], operands[1],
544 optimize && can_create_pseudo_p ());
550 ; If there is a scratch available, this will be faster than synthesizing the
553 [(match_scratch:SI 3 "r")
554 (set (match_operand:SI 0 "arm_general_register_operand" "")
555 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
556 (match_operand:SI 2 "const_int_operand" "")))]
558 !(const_ok_for_arm (INTVAL (operands[2]))
559 || const_ok_for_arm (-INTVAL (operands[2])))
560 && const_ok_for_arm (~INTVAL (operands[2]))"
561 [(set (match_dup 3) (match_dup 2))
562 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
566 ;; The r/r/k alternative is required when reloading the address
567 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
568 ;; put the duplicated register first, and not try the commutative version.
569 (define_insn_and_split "*arm_addsi3"
570 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
571 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
572 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
587 subw%?\\t%0, %1, #%n2
588 subw%?\\t%0, %1, #%n2
591 && CONST_INT_P (operands[2])
592 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
593 && (reload_completed || !arm_eliminable_register (operands[1]))"
594 [(clobber (const_int 0))]
596 arm_split_constant (PLUS, SImode, curr_insn,
597 INTVAL (operands[2]), operands[0],
601 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
602 (set_attr "predicable" "yes")
603 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
604 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
605 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
606 (const_string "alu_imm")
607 (const_string "alu_sreg")))
611 (define_insn "addsi3_compare0"
612 [(set (reg:CC_NOOV CC_REGNUM)
614 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
615 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
617 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
618 (plus:SI (match_dup 1) (match_dup 2)))]
624 [(set_attr "conds" "set")
625 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
628 (define_insn "*addsi3_compare0_scratch"
629 [(set (reg:CC_NOOV CC_REGNUM)
631 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
632 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
639 [(set_attr "conds" "set")
640 (set_attr "predicable" "yes")
641 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
644 (define_insn "*compare_negsi_si"
645 [(set (reg:CC_Z CC_REGNUM)
647 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
648 (match_operand:SI 1 "s_register_operand" "l,r")))]
651 [(set_attr "conds" "set")
652 (set_attr "predicable" "yes")
653 (set_attr "arch" "t2,*")
654 (set_attr "length" "2,4")
655 (set_attr "predicable_short_it" "yes,no")
656 (set_attr "type" "alus_sreg")]
659 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
660 ;; addend is a constant.
661 (define_insn "cmpsi2_addneg"
662 [(set (reg:CC CC_REGNUM)
664 (match_operand:SI 1 "s_register_operand" "r,r")
665 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
666 (set (match_operand:SI 0 "s_register_operand" "=r,r")
667 (plus:SI (match_dup 1)
668 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
669 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
672 sub%.\\t%0, %1, #%n3"
673 [(set_attr "conds" "set")
674 (set_attr "type" "alus_sreg")]
677 ;; Convert the sequence
679 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
683 ;; bcs dest ((unsigned)rn >= 1)
684 ;; similarly for the beq variant using bcc.
685 ;; This is a common looping idiom (while (n--))
687 [(set (match_operand:SI 0 "arm_general_register_operand" "")
688 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
690 (set (match_operand 2 "cc_register" "")
691 (compare (match_dup 0) (const_int -1)))
693 (if_then_else (match_operator 3 "equality_operator"
694 [(match_dup 2) (const_int 0)])
695 (match_operand 4 "" "")
696 (match_operand 5 "" "")))]
697 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
701 (match_dup 1) (const_int 1)))
702 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
704 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
707 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
708 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
711 operands[2], const0_rtx);"
714 ;; The next four insns work because they compare the result with one of
715 ;; the operands, and we know that the use of the condition code is
716 ;; either GEU or LTU, so we can use the carry flag from the addition
717 ;; instead of doing the compare a second time.
718 (define_insn "*addsi3_compare_op1"
719 [(set (reg:CC_C CC_REGNUM)
721 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
722 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
724 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
725 (plus:SI (match_dup 1) (match_dup 2)))]
731 [(set_attr "conds" "set")
732 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
735 (define_insn "*addsi3_compare_op2"
736 [(set (reg:CC_C CC_REGNUM)
738 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
739 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
741 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
742 (plus:SI (match_dup 1) (match_dup 2)))]
747 sub%.\\t%0, %1, #%n2"
748 [(set_attr "conds" "set")
749 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
752 (define_insn "*compare_addsi2_op0"
753 [(set (reg:CC_C CC_REGNUM)
755 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
756 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
765 [(set_attr "conds" "set")
766 (set_attr "predicable" "yes")
767 (set_attr "arch" "t2,t2,*,*,*")
768 (set_attr "predicable_short_it" "yes,yes,no,no,no")
769 (set_attr "length" "2,2,4,4,4")
770 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
773 (define_insn "*compare_addsi2_op1"
774 [(set (reg:CC_C CC_REGNUM)
776 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
777 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
786 [(set_attr "conds" "set")
787 (set_attr "predicable" "yes")
788 (set_attr "arch" "t2,t2,*,*,*")
789 (set_attr "predicable_short_it" "yes,yes,no,no,no")
790 (set_attr "length" "2,2,4,4,4")
791 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
794 (define_insn "*addsi3_carryin_<optab>"
795 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
796 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
797 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
798 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
803 sbc%?\\t%0, %1, #%B2"
804 [(set_attr "conds" "use")
805 (set_attr "predicable" "yes")
806 (set_attr "arch" "t2,*,*")
807 (set_attr "length" "4")
808 (set_attr "predicable_short_it" "yes,no,no")
809 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
812 (define_insn "*addsi3_carryin_alt2_<optab>"
813 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
814 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
815 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
816 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
821 sbc%?\\t%0, %1, #%B2"
822 [(set_attr "conds" "use")
823 (set_attr "predicable" "yes")
824 (set_attr "arch" "t2,*,*")
825 (set_attr "length" "4")
826 (set_attr "predicable_short_it" "yes,no,no")
827 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
830 (define_insn "*addsi3_carryin_shift_<optab>"
831 [(set (match_operand:SI 0 "s_register_operand" "=r")
833 (match_operator:SI 2 "shift_operator"
834 [(match_operand:SI 3 "s_register_operand" "r")
835 (match_operand:SI 4 "reg_or_int_operand" "rM")])
836 (match_operand:SI 1 "s_register_operand" "r"))
837 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
839 "adc%?\\t%0, %1, %3%S2"
840 [(set_attr "conds" "use")
841 (set_attr "predicable" "yes")
842 (set_attr "predicable_short_it" "no")
843 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
844 (const_string "alu_shift_imm")
845 (const_string "alu_shift_reg")))]
848 (define_insn "*addsi3_carryin_clobercc_<optab>"
849 [(set (match_operand:SI 0 "s_register_operand" "=r")
850 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
851 (match_operand:SI 2 "arm_rhs_operand" "rI"))
852 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
853 (clobber (reg:CC CC_REGNUM))]
856 [(set_attr "conds" "set")
857 (set_attr "type" "adcs_reg")]
860 (define_insn "*subsi3_carryin"
861 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
862 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
863 (match_operand:SI 2 "s_register_operand" "r,r"))
864 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
869 [(set_attr "conds" "use")
870 (set_attr "arch" "*,a")
871 (set_attr "predicable" "yes")
872 (set_attr "predicable_short_it" "no")
873 (set_attr "type" "adc_reg,adc_imm")]
876 (define_insn "*subsi3_carryin_const"
877 [(set (match_operand:SI 0 "s_register_operand" "=r")
878 (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
879 (match_operand:SI 2 "arm_not_operand" "K"))
880 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
883 [(set_attr "conds" "use")
884 (set_attr "type" "adc_imm")]
887 (define_insn "*subsi3_carryin_compare"
888 [(set (reg:CC CC_REGNUM)
889 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
890 (match_operand:SI 2 "s_register_operand" "r")))
891 (set (match_operand:SI 0 "s_register_operand" "=r")
892 (minus:SI (minus:SI (match_dup 1)
894 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
897 [(set_attr "conds" "set")
898 (set_attr "type" "adcs_reg")]
901 (define_insn "*subsi3_carryin_compare_const"
902 [(set (reg:CC CC_REGNUM)
903 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
904 (match_operand:SI 2 "arm_not_operand" "K")))
905 (set (match_operand:SI 0 "s_register_operand" "=r")
906 (minus:SI (plus:SI (match_dup 1)
908 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
910 "sbcs\\t%0, %1, #%B2"
911 [(set_attr "conds" "set")
912 (set_attr "type" "adcs_imm")]
915 (define_insn "*subsi3_carryin_shift"
916 [(set (match_operand:SI 0 "s_register_operand" "=r")
918 (match_operand:SI 1 "s_register_operand" "r")
919 (match_operator:SI 2 "shift_operator"
920 [(match_operand:SI 3 "s_register_operand" "r")
921 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
922 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
924 "sbc%?\\t%0, %1, %3%S2"
925 [(set_attr "conds" "use")
926 (set_attr "predicable" "yes")
927 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
928 (const_string "alu_shift_imm")
929 (const_string "alu_shift_reg")))]
932 (define_insn "*rsbsi3_carryin_shift"
933 [(set (match_operand:SI 0 "s_register_operand" "=r")
935 (match_operator:SI 2 "shift_operator"
936 [(match_operand:SI 3 "s_register_operand" "r")
937 (match_operand:SI 4 "reg_or_int_operand" "rM")])
938 (match_operand:SI 1 "s_register_operand" "r"))
939 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
941 "rsc%?\\t%0, %1, %3%S2"
942 [(set_attr "conds" "use")
943 (set_attr "predicable" "yes")
944 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
945 (const_string "alu_shift_imm")
946 (const_string "alu_shift_reg")))]
949 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
951 [(set (match_operand:SI 0 "s_register_operand" "")
952 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
953 (match_operand:SI 2 "s_register_operand" ""))
955 (clobber (match_operand:SI 3 "s_register_operand" ""))]
957 [(set (match_dup 3) (match_dup 1))
958 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
960 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
963 (define_expand "addsf3"
964 [(set (match_operand:SF 0 "s_register_operand" "")
965 (plus:SF (match_operand:SF 1 "s_register_operand" "")
966 (match_operand:SF 2 "s_register_operand" "")))]
967 "TARGET_32BIT && TARGET_HARD_FLOAT"
971 (define_expand "adddf3"
972 [(set (match_operand:DF 0 "s_register_operand" "")
973 (plus:DF (match_operand:DF 1 "s_register_operand" "")
974 (match_operand:DF 2 "s_register_operand" "")))]
975 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
979 (define_expand "subdi3"
981 [(set (match_operand:DI 0 "s_register_operand" "")
982 (minus:DI (match_operand:DI 1 "s_register_operand" "")
983 (match_operand:DI 2 "s_register_operand" "")))
984 (clobber (reg:CC CC_REGNUM))])]
989 if (!REG_P (operands[1]))
990 operands[1] = force_reg (DImode, operands[1]);
991 if (!REG_P (operands[2]))
992 operands[2] = force_reg (DImode, operands[2]);
997 (define_insn_and_split "*arm_subdi3"
998 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
999 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1000 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1001 (clobber (reg:CC CC_REGNUM))]
1002 "TARGET_32BIT && !TARGET_NEON"
1003 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1004 "&& reload_completed"
1005 [(parallel [(set (reg:CC CC_REGNUM)
1006 (compare:CC (match_dup 1) (match_dup 2)))
1007 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1008 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1009 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1011 operands[3] = gen_highpart (SImode, operands[0]);
1012 operands[0] = gen_lowpart (SImode, operands[0]);
1013 operands[4] = gen_highpart (SImode, operands[1]);
1014 operands[1] = gen_lowpart (SImode, operands[1]);
1015 operands[5] = gen_highpart (SImode, operands[2]);
1016 operands[2] = gen_lowpart (SImode, operands[2]);
1018 [(set_attr "conds" "clob")
1019 (set_attr "length" "8")
1020 (set_attr "type" "multiple")]
1023 (define_insn_and_split "*subdi_di_zesidi"
1024 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1025 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1027 (match_operand:SI 2 "s_register_operand" "r,r"))))
1028 (clobber (reg:CC CC_REGNUM))]
1030 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1031 "&& reload_completed"
1032 [(parallel [(set (reg:CC CC_REGNUM)
1033 (compare:CC (match_dup 1) (match_dup 2)))
1034 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1035 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1036 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1038 operands[3] = gen_highpart (SImode, operands[0]);
1039 operands[0] = gen_lowpart (SImode, operands[0]);
1040 operands[4] = gen_highpart (SImode, operands[1]);
1041 operands[1] = gen_lowpart (SImode, operands[1]);
1042 operands[5] = GEN_INT (~0);
1044 [(set_attr "conds" "clob")
1045 (set_attr "length" "8")
1046 (set_attr "type" "multiple")]
1049 (define_insn_and_split "*subdi_di_sesidi"
1050 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1051 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1053 (match_operand:SI 2 "s_register_operand" "r,r"))))
1054 (clobber (reg:CC CC_REGNUM))]
1056 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1057 "&& reload_completed"
1058 [(parallel [(set (reg:CC CC_REGNUM)
1059 (compare:CC (match_dup 1) (match_dup 2)))
1060 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1061 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1062 (ashiftrt:SI (match_dup 2)
1064 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1066 operands[3] = gen_highpart (SImode, operands[0]);
1067 operands[0] = gen_lowpart (SImode, operands[0]);
1068 operands[4] = gen_highpart (SImode, operands[1]);
1069 operands[1] = gen_lowpart (SImode, operands[1]);
1071 [(set_attr "conds" "clob")
1072 (set_attr "length" "8")
1073 (set_attr "type" "multiple")]
1076 (define_insn_and_split "*subdi_zesidi_di"
1077 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1078 (minus:DI (zero_extend:DI
1079 (match_operand:SI 2 "s_register_operand" "r,r"))
1080 (match_operand:DI 1 "s_register_operand" "0,r")))
1081 (clobber (reg:CC CC_REGNUM))]
1083 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1085 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1086 "&& reload_completed"
1087 [(parallel [(set (reg:CC CC_REGNUM)
1088 (compare:CC (match_dup 2) (match_dup 1)))
1089 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1090 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1091 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1093 operands[3] = gen_highpart (SImode, operands[0]);
1094 operands[0] = gen_lowpart (SImode, operands[0]);
1095 operands[4] = gen_highpart (SImode, operands[1]);
1096 operands[1] = gen_lowpart (SImode, operands[1]);
1098 [(set_attr "conds" "clob")
1099 (set_attr "length" "8")
1100 (set_attr "type" "multiple")]
1103 (define_insn_and_split "*subdi_sesidi_di"
1104 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1105 (minus:DI (sign_extend:DI
1106 (match_operand:SI 2 "s_register_operand" "r,r"))
1107 (match_operand:DI 1 "s_register_operand" "0,r")))
1108 (clobber (reg:CC CC_REGNUM))]
1110 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1112 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1113 "&& reload_completed"
1114 [(parallel [(set (reg:CC CC_REGNUM)
1115 (compare:CC (match_dup 2) (match_dup 1)))
1116 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1117 (set (match_dup 3) (minus:SI (minus:SI
1118 (ashiftrt:SI (match_dup 2)
1121 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1123 operands[3] = gen_highpart (SImode, operands[0]);
1124 operands[0] = gen_lowpart (SImode, operands[0]);
1125 operands[4] = gen_highpart (SImode, operands[1]);
1126 operands[1] = gen_lowpart (SImode, operands[1]);
1128 [(set_attr "conds" "clob")
1129 (set_attr "length" "8")
1130 (set_attr "type" "multiple")]
1133 (define_insn_and_split "*subdi_zesidi_zesidi"
1134 [(set (match_operand:DI 0 "s_register_operand" "=r")
1135 (minus:DI (zero_extend:DI
1136 (match_operand:SI 1 "s_register_operand" "r"))
1138 (match_operand:SI 2 "s_register_operand" "r"))))
1139 (clobber (reg:CC CC_REGNUM))]
1141 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1142 "&& reload_completed"
1143 [(parallel [(set (reg:CC CC_REGNUM)
1144 (compare:CC (match_dup 1) (match_dup 2)))
1145 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1146 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1147 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1149 operands[3] = gen_highpart (SImode, operands[0]);
1150 operands[0] = gen_lowpart (SImode, operands[0]);
1152 [(set_attr "conds" "clob")
1153 (set_attr "length" "8")
1154 (set_attr "type" "multiple")]
1157 (define_expand "subsi3"
1158 [(set (match_operand:SI 0 "s_register_operand" "")
1159 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1160 (match_operand:SI 2 "s_register_operand" "")))]
1163 if (CONST_INT_P (operands[1]))
1167 arm_split_constant (MINUS, SImode, NULL_RTX,
1168 INTVAL (operands[1]), operands[0],
1169 operands[2], optimize && can_create_pseudo_p ());
1172 else /* TARGET_THUMB1 */
1173 operands[1] = force_reg (SImode, operands[1]);
1178 ; ??? Check Thumb-2 split length
1179 (define_insn_and_split "*arm_subsi3_insn"
1180 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1181 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1182 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1194 "&& (CONST_INT_P (operands[1])
1195 && !const_ok_for_arm (INTVAL (operands[1])))"
1196 [(clobber (const_int 0))]
1198 arm_split_constant (MINUS, SImode, curr_insn,
1199 INTVAL (operands[1]), operands[0], operands[2], 0);
1202 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1203 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1204 (set_attr "predicable" "yes")
1205 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1206 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1210 [(match_scratch:SI 3 "r")
1211 (set (match_operand:SI 0 "arm_general_register_operand" "")
1212 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1213 (match_operand:SI 2 "arm_general_register_operand" "")))]
1215 && !const_ok_for_arm (INTVAL (operands[1]))
1216 && const_ok_for_arm (~INTVAL (operands[1]))"
1217 [(set (match_dup 3) (match_dup 1))
1218 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1222 (define_insn "*subsi3_compare0"
1223 [(set (reg:CC_NOOV CC_REGNUM)
1225 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1226 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1228 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1229 (minus:SI (match_dup 1) (match_dup 2)))]
1235 [(set_attr "conds" "set")
1236 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1239 (define_insn "subsi3_compare"
1240 [(set (reg:CC CC_REGNUM)
1241 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1242 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1243 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1244 (minus:SI (match_dup 1) (match_dup 2)))]
1250 [(set_attr "conds" "set")
1251 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1254 (define_expand "subsf3"
1255 [(set (match_operand:SF 0 "s_register_operand" "")
1256 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1257 (match_operand:SF 2 "s_register_operand" "")))]
1258 "TARGET_32BIT && TARGET_HARD_FLOAT"
1262 (define_expand "subdf3"
1263 [(set (match_operand:DF 0 "s_register_operand" "")
1264 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1265 (match_operand:DF 2 "s_register_operand" "")))]
1266 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1271 ;; Multiplication insns
1273 (define_expand "mulhi3"
1274 [(set (match_operand:HI 0 "s_register_operand" "")
1275 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1276 (match_operand:HI 2 "s_register_operand" "")))]
1277 "TARGET_DSP_MULTIPLY"
1280 rtx result = gen_reg_rtx (SImode);
1281 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1282 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1287 (define_expand "mulsi3"
1288 [(set (match_operand:SI 0 "s_register_operand" "")
1289 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1290 (match_operand:SI 1 "s_register_operand" "")))]
1295 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1296 (define_insn "*arm_mulsi3"
1297 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1298 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1299 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1300 "TARGET_32BIT && !arm_arch6"
1301 "mul%?\\t%0, %2, %1"
1302 [(set_attr "type" "mul")
1303 (set_attr "predicable" "yes")]
1306 (define_insn "*arm_mulsi3_v6"
1307 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1308 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1309 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1310 "TARGET_32BIT && arm_arch6"
1311 "mul%?\\t%0, %1, %2"
1312 [(set_attr "type" "mul")
1313 (set_attr "predicable" "yes")
1314 (set_attr "arch" "t2,t2,*")
1315 (set_attr "length" "4")
1316 (set_attr "predicable_short_it" "yes,yes,no")]
1319 (define_insn "*mulsi3_compare0"
1320 [(set (reg:CC_NOOV CC_REGNUM)
1321 (compare:CC_NOOV (mult:SI
1322 (match_operand:SI 2 "s_register_operand" "r,r")
1323 (match_operand:SI 1 "s_register_operand" "%0,r"))
1325 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1326 (mult:SI (match_dup 2) (match_dup 1)))]
1327 "TARGET_ARM && !arm_arch6"
1328 "mul%.\\t%0, %2, %1"
1329 [(set_attr "conds" "set")
1330 (set_attr "type" "muls")]
1333 (define_insn "*mulsi3_compare0_v6"
1334 [(set (reg:CC_NOOV CC_REGNUM)
1335 (compare:CC_NOOV (mult:SI
1336 (match_operand:SI 2 "s_register_operand" "r")
1337 (match_operand:SI 1 "s_register_operand" "r"))
1339 (set (match_operand:SI 0 "s_register_operand" "=r")
1340 (mult:SI (match_dup 2) (match_dup 1)))]
1341 "TARGET_ARM && arm_arch6 && optimize_size"
1342 "mul%.\\t%0, %2, %1"
1343 [(set_attr "conds" "set")
1344 (set_attr "type" "muls")]
1347 (define_insn "*mulsi_compare0_scratch"
1348 [(set (reg:CC_NOOV CC_REGNUM)
1349 (compare:CC_NOOV (mult:SI
1350 (match_operand:SI 2 "s_register_operand" "r,r")
1351 (match_operand:SI 1 "s_register_operand" "%0,r"))
1353 (clobber (match_scratch:SI 0 "=&r,&r"))]
1354 "TARGET_ARM && !arm_arch6"
1355 "mul%.\\t%0, %2, %1"
1356 [(set_attr "conds" "set")
1357 (set_attr "type" "muls")]
1360 (define_insn "*mulsi_compare0_scratch_v6"
1361 [(set (reg:CC_NOOV CC_REGNUM)
1362 (compare:CC_NOOV (mult:SI
1363 (match_operand:SI 2 "s_register_operand" "r")
1364 (match_operand:SI 1 "s_register_operand" "r"))
1366 (clobber (match_scratch:SI 0 "=r"))]
1367 "TARGET_ARM && arm_arch6 && optimize_size"
1368 "mul%.\\t%0, %2, %1"
1369 [(set_attr "conds" "set")
1370 (set_attr "type" "muls")]
1373 ;; Unnamed templates to match MLA instruction.
1375 (define_insn "*mulsi3addsi"
1376 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1378 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1379 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1380 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1381 "TARGET_32BIT && !arm_arch6"
1382 "mla%?\\t%0, %2, %1, %3"
1383 [(set_attr "type" "mla")
1384 (set_attr "predicable" "yes")]
1387 (define_insn "*mulsi3addsi_v6"
1388 [(set (match_operand:SI 0 "s_register_operand" "=r")
1390 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1391 (match_operand:SI 1 "s_register_operand" "r"))
1392 (match_operand:SI 3 "s_register_operand" "r")))]
1393 "TARGET_32BIT && arm_arch6"
1394 "mla%?\\t%0, %2, %1, %3"
1395 [(set_attr "type" "mla")
1396 (set_attr "predicable" "yes")
1397 (set_attr "predicable_short_it" "no")]
1400 (define_insn "*mulsi3addsi_compare0"
1401 [(set (reg:CC_NOOV CC_REGNUM)
1404 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1405 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1406 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1408 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1409 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1411 "TARGET_ARM && arm_arch6"
1412 "mla%.\\t%0, %2, %1, %3"
1413 [(set_attr "conds" "set")
1414 (set_attr "type" "mlas")]
1417 (define_insn "*mulsi3addsi_compare0_v6"
1418 [(set (reg:CC_NOOV CC_REGNUM)
1421 (match_operand:SI 2 "s_register_operand" "r")
1422 (match_operand:SI 1 "s_register_operand" "r"))
1423 (match_operand:SI 3 "s_register_operand" "r"))
1425 (set (match_operand:SI 0 "s_register_operand" "=r")
1426 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1428 "TARGET_ARM && arm_arch6 && optimize_size"
1429 "mla%.\\t%0, %2, %1, %3"
1430 [(set_attr "conds" "set")
1431 (set_attr "type" "mlas")]
1434 (define_insn "*mulsi3addsi_compare0_scratch"
1435 [(set (reg:CC_NOOV CC_REGNUM)
1438 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1439 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1440 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1442 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1443 "TARGET_ARM && !arm_arch6"
1444 "mla%.\\t%0, %2, %1, %3"
1445 [(set_attr "conds" "set")
1446 (set_attr "type" "mlas")]
1449 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1450 [(set (reg:CC_NOOV CC_REGNUM)
1453 (match_operand:SI 2 "s_register_operand" "r")
1454 (match_operand:SI 1 "s_register_operand" "r"))
1455 (match_operand:SI 3 "s_register_operand" "r"))
1457 (clobber (match_scratch:SI 0 "=r"))]
1458 "TARGET_ARM && arm_arch6 && optimize_size"
1459 "mla%.\\t%0, %2, %1, %3"
1460 [(set_attr "conds" "set")
1461 (set_attr "type" "mlas")]
1464 (define_insn "*mulsi3subsi"
1465 [(set (match_operand:SI 0 "s_register_operand" "=r")
1467 (match_operand:SI 3 "s_register_operand" "r")
1468 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1469 (match_operand:SI 1 "s_register_operand" "r"))))]
1470 "TARGET_32BIT && arm_arch_thumb2"
1471 "mls%?\\t%0, %2, %1, %3"
1472 [(set_attr "type" "mla")
1473 (set_attr "predicable" "yes")
1474 (set_attr "predicable_short_it" "no")]
1477 (define_expand "maddsidi4"
1478 [(set (match_operand:DI 0 "s_register_operand" "")
1481 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1482 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1483 (match_operand:DI 3 "s_register_operand" "")))]
1484 "TARGET_32BIT && arm_arch3m"
1487 (define_insn "*mulsidi3adddi"
1488 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1491 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1492 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1493 (match_operand:DI 1 "s_register_operand" "0")))]
1494 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1495 "smlal%?\\t%Q0, %R0, %3, %2"
1496 [(set_attr "type" "smlal")
1497 (set_attr "predicable" "yes")]
1500 (define_insn "*mulsidi3adddi_v6"
1501 [(set (match_operand:DI 0 "s_register_operand" "=r")
1504 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1505 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1506 (match_operand:DI 1 "s_register_operand" "0")))]
1507 "TARGET_32BIT && arm_arch6"
1508 "smlal%?\\t%Q0, %R0, %3, %2"
1509 [(set_attr "type" "smlal")
1510 (set_attr "predicable" "yes")
1511 (set_attr "predicable_short_it" "no")]
1514 ;; 32x32->64 widening multiply.
1515 ;; As with mulsi3, the only difference between the v3-5 and v6+
1516 ;; versions of these patterns is the requirement that the output not
1517 ;; overlap the inputs, but that still means we have to have a named
1518 ;; expander and two different starred insns.
1520 (define_expand "mulsidi3"
1521 [(set (match_operand:DI 0 "s_register_operand" "")
1523 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1524 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1525 "TARGET_32BIT && arm_arch3m"
1529 (define_insn "*mulsidi3_nov6"
1530 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1532 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1533 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1534 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1535 "smull%?\\t%Q0, %R0, %1, %2"
1536 [(set_attr "type" "smull")
1537 (set_attr "predicable" "yes")]
1540 (define_insn "*mulsidi3_v6"
1541 [(set (match_operand:DI 0 "s_register_operand" "=r")
1543 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1544 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1545 "TARGET_32BIT && arm_arch6"
1546 "smull%?\\t%Q0, %R0, %1, %2"
1547 [(set_attr "type" "smull")
1548 (set_attr "predicable" "yes")
1549 (set_attr "predicable_short_it" "no")]
1552 (define_expand "umulsidi3"
1553 [(set (match_operand:DI 0 "s_register_operand" "")
1555 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1556 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1557 "TARGET_32BIT && arm_arch3m"
1561 (define_insn "*umulsidi3_nov6"
1562 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1564 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1565 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1566 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1567 "umull%?\\t%Q0, %R0, %1, %2"
1568 [(set_attr "type" "umull")
1569 (set_attr "predicable" "yes")]
1572 (define_insn "*umulsidi3_v6"
1573 [(set (match_operand:DI 0 "s_register_operand" "=r")
1575 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1576 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1577 "TARGET_32BIT && arm_arch6"
1578 "umull%?\\t%Q0, %R0, %1, %2"
1579 [(set_attr "type" "umull")
1580 (set_attr "predicable" "yes")
1581 (set_attr "predicable_short_it" "no")]
1584 (define_expand "umaddsidi4"
1585 [(set (match_operand:DI 0 "s_register_operand" "")
1588 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1589 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1590 (match_operand:DI 3 "s_register_operand" "")))]
1591 "TARGET_32BIT && arm_arch3m"
1594 (define_insn "*umulsidi3adddi"
1595 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1598 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1599 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1600 (match_operand:DI 1 "s_register_operand" "0")))]
1601 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1602 "umlal%?\\t%Q0, %R0, %3, %2"
1603 [(set_attr "type" "umlal")
1604 (set_attr "predicable" "yes")]
1607 (define_insn "*umulsidi3adddi_v6"
1608 [(set (match_operand:DI 0 "s_register_operand" "=r")
1611 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1612 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1613 (match_operand:DI 1 "s_register_operand" "0")))]
1614 "TARGET_32BIT && arm_arch6"
1615 "umlal%?\\t%Q0, %R0, %3, %2"
1616 [(set_attr "type" "umlal")
1617 (set_attr "predicable" "yes")
1618 (set_attr "predicable_short_it" "no")]
1621 (define_expand "smulsi3_highpart"
1623 [(set (match_operand:SI 0 "s_register_operand" "")
1627 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1628 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1630 (clobber (match_scratch:SI 3 ""))])]
1631 "TARGET_32BIT && arm_arch3m"
1635 (define_insn "*smulsi3_highpart_nov6"
1636 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1640 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1641 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1643 (clobber (match_scratch:SI 3 "=&r,&r"))]
1644 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1645 "smull%?\\t%3, %0, %2, %1"
1646 [(set_attr "type" "smull")
1647 (set_attr "predicable" "yes")]
1650 (define_insn "*smulsi3_highpart_v6"
1651 [(set (match_operand:SI 0 "s_register_operand" "=r")
1655 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1656 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1658 (clobber (match_scratch:SI 3 "=r"))]
1659 "TARGET_32BIT && arm_arch6"
1660 "smull%?\\t%3, %0, %2, %1"
1661 [(set_attr "type" "smull")
1662 (set_attr "predicable" "yes")
1663 (set_attr "predicable_short_it" "no")]
1666 (define_expand "umulsi3_highpart"
1668 [(set (match_operand:SI 0 "s_register_operand" "")
1672 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1673 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1675 (clobber (match_scratch:SI 3 ""))])]
1676 "TARGET_32BIT && arm_arch3m"
1680 (define_insn "*umulsi3_highpart_nov6"
1681 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1685 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1686 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1688 (clobber (match_scratch:SI 3 "=&r,&r"))]
1689 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1690 "umull%?\\t%3, %0, %2, %1"
1691 [(set_attr "type" "umull")
1692 (set_attr "predicable" "yes")]
1695 (define_insn "*umulsi3_highpart_v6"
1696 [(set (match_operand:SI 0 "s_register_operand" "=r")
1700 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1701 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1703 (clobber (match_scratch:SI 3 "=r"))]
1704 "TARGET_32BIT && arm_arch6"
1705 "umull%?\\t%3, %0, %2, %1"
1706 [(set_attr "type" "umull")
1707 (set_attr "predicable" "yes")
1708 (set_attr "predicable_short_it" "no")]
1711 (define_insn "mulhisi3"
1712 [(set (match_operand:SI 0 "s_register_operand" "=r")
1713 (mult:SI (sign_extend:SI
1714 (match_operand:HI 1 "s_register_operand" "%r"))
1716 (match_operand:HI 2 "s_register_operand" "r"))))]
1717 "TARGET_DSP_MULTIPLY"
1718 "smulbb%?\\t%0, %1, %2"
1719 [(set_attr "type" "smulxy")
1720 (set_attr "predicable" "yes")]
1723 (define_insn "*mulhisi3tb"
1724 [(set (match_operand:SI 0 "s_register_operand" "=r")
1725 (mult:SI (ashiftrt:SI
1726 (match_operand:SI 1 "s_register_operand" "r")
1729 (match_operand:HI 2 "s_register_operand" "r"))))]
1730 "TARGET_DSP_MULTIPLY"
1731 "smultb%?\\t%0, %1, %2"
1732 [(set_attr "type" "smulxy")
1733 (set_attr "predicable" "yes")
1734 (set_attr "predicable_short_it" "no")]
1737 (define_insn "*mulhisi3bt"
1738 [(set (match_operand:SI 0 "s_register_operand" "=r")
1739 (mult:SI (sign_extend:SI
1740 (match_operand:HI 1 "s_register_operand" "r"))
1742 (match_operand:SI 2 "s_register_operand" "r")
1744 "TARGET_DSP_MULTIPLY"
1745 "smulbt%?\\t%0, %1, %2"
1746 [(set_attr "type" "smulxy")
1747 (set_attr "predicable" "yes")
1748 (set_attr "predicable_short_it" "no")]
1751 (define_insn "*mulhisi3tt"
1752 [(set (match_operand:SI 0 "s_register_operand" "=r")
1753 (mult:SI (ashiftrt:SI
1754 (match_operand:SI 1 "s_register_operand" "r")
1757 (match_operand:SI 2 "s_register_operand" "r")
1759 "TARGET_DSP_MULTIPLY"
1760 "smultt%?\\t%0, %1, %2"
1761 [(set_attr "type" "smulxy")
1762 (set_attr "predicable" "yes")
1763 (set_attr "predicable_short_it" "no")]
1766 (define_insn "maddhisi4"
1767 [(set (match_operand:SI 0 "s_register_operand" "=r")
1768 (plus:SI (mult:SI (sign_extend:SI
1769 (match_operand:HI 1 "s_register_operand" "r"))
1771 (match_operand:HI 2 "s_register_operand" "r")))
1772 (match_operand:SI 3 "s_register_operand" "r")))]
1773 "TARGET_DSP_MULTIPLY"
1774 "smlabb%?\\t%0, %1, %2, %3"
1775 [(set_attr "type" "smlaxy")
1776 (set_attr "predicable" "yes")
1777 (set_attr "predicable_short_it" "no")]
1780 ;; Note: there is no maddhisi4ibt because this one is canonical form
1781 (define_insn "*maddhisi4tb"
1782 [(set (match_operand:SI 0 "s_register_operand" "=r")
1783 (plus:SI (mult:SI (ashiftrt:SI
1784 (match_operand:SI 1 "s_register_operand" "r")
1787 (match_operand:HI 2 "s_register_operand" "r")))
1788 (match_operand:SI 3 "s_register_operand" "r")))]
1789 "TARGET_DSP_MULTIPLY"
1790 "smlatb%?\\t%0, %1, %2, %3"
1791 [(set_attr "type" "smlaxy")
1792 (set_attr "predicable" "yes")
1793 (set_attr "predicable_short_it" "no")]
1796 (define_insn "*maddhisi4tt"
1797 [(set (match_operand:SI 0 "s_register_operand" "=r")
1798 (plus:SI (mult:SI (ashiftrt:SI
1799 (match_operand:SI 1 "s_register_operand" "r")
1802 (match_operand:SI 2 "s_register_operand" "r")
1804 (match_operand:SI 3 "s_register_operand" "r")))]
1805 "TARGET_DSP_MULTIPLY"
1806 "smlatt%?\\t%0, %1, %2, %3"
1807 [(set_attr "type" "smlaxy")
1808 (set_attr "predicable" "yes")
1809 (set_attr "predicable_short_it" "no")]
1812 (define_insn "maddhidi4"
1813 [(set (match_operand:DI 0 "s_register_operand" "=r")
1815 (mult:DI (sign_extend:DI
1816 (match_operand:HI 1 "s_register_operand" "r"))
1818 (match_operand:HI 2 "s_register_operand" "r")))
1819 (match_operand:DI 3 "s_register_operand" "0")))]
1820 "TARGET_DSP_MULTIPLY"
1821 "smlalbb%?\\t%Q0, %R0, %1, %2"
1822 [(set_attr "type" "smlalxy")
1823 (set_attr "predicable" "yes")
1824 (set_attr "predicable_short_it" "no")])
1826 ;; Note: there is no maddhidi4ibt because this one is canonical form
1827 (define_insn "*maddhidi4tb"
1828 [(set (match_operand:DI 0 "s_register_operand" "=r")
1830 (mult:DI (sign_extend:DI
1832 (match_operand:SI 1 "s_register_operand" "r")
1835 (match_operand:HI 2 "s_register_operand" "r")))
1836 (match_operand:DI 3 "s_register_operand" "0")))]
1837 "TARGET_DSP_MULTIPLY"
1838 "smlaltb%?\\t%Q0, %R0, %1, %2"
1839 [(set_attr "type" "smlalxy")
1840 (set_attr "predicable" "yes")
1841 (set_attr "predicable_short_it" "no")])
1843 (define_insn "*maddhidi4tt"
1844 [(set (match_operand:DI 0 "s_register_operand" "=r")
1846 (mult:DI (sign_extend:DI
1848 (match_operand:SI 1 "s_register_operand" "r")
1852 (match_operand:SI 2 "s_register_operand" "r")
1854 (match_operand:DI 3 "s_register_operand" "0")))]
1855 "TARGET_DSP_MULTIPLY"
1856 "smlaltt%?\\t%Q0, %R0, %1, %2"
1857 [(set_attr "type" "smlalxy")
1858 (set_attr "predicable" "yes")
1859 (set_attr "predicable_short_it" "no")])
1861 (define_expand "mulsf3"
1862 [(set (match_operand:SF 0 "s_register_operand" "")
1863 (mult:SF (match_operand:SF 1 "s_register_operand" "")
1864 (match_operand:SF 2 "s_register_operand" "")))]
1865 "TARGET_32BIT && TARGET_HARD_FLOAT"
1869 (define_expand "muldf3"
1870 [(set (match_operand:DF 0 "s_register_operand" "")
1871 (mult:DF (match_operand:DF 1 "s_register_operand" "")
1872 (match_operand:DF 2 "s_register_operand" "")))]
1873 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1879 (define_expand "divsf3"
1880 [(set (match_operand:SF 0 "s_register_operand" "")
1881 (div:SF (match_operand:SF 1 "s_register_operand" "")
1882 (match_operand:SF 2 "s_register_operand" "")))]
1883 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1886 (define_expand "divdf3"
1887 [(set (match_operand:DF 0 "s_register_operand" "")
1888 (div:DF (match_operand:DF 1 "s_register_operand" "")
1889 (match_operand:DF 2 "s_register_operand" "")))]
1890 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1893 ;; Boolean and,ior,xor insns
1895 ;; Split up double word logical operations
1897 ;; Split up simple DImode logical operations. Simply perform the logical
1898 ;; operation on the upper and lower halves of the registers.
1900 [(set (match_operand:DI 0 "s_register_operand" "")
1901 (match_operator:DI 6 "logical_binary_operator"
1902 [(match_operand:DI 1 "s_register_operand" "")
1903 (match_operand:DI 2 "s_register_operand" "")]))]
1904 "TARGET_32BIT && reload_completed
1905 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
1906 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
1907 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1908 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
1911 operands[3] = gen_highpart (SImode, operands[0]);
1912 operands[0] = gen_lowpart (SImode, operands[0]);
1913 operands[4] = gen_highpart (SImode, operands[1]);
1914 operands[1] = gen_lowpart (SImode, operands[1]);
1915 operands[5] = gen_highpart (SImode, operands[2]);
1916 operands[2] = gen_lowpart (SImode, operands[2]);
1921 [(set (match_operand:DI 0 "s_register_operand" "")
1922 (match_operator:DI 6 "logical_binary_operator"
1923 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1924 (match_operand:DI 1 "s_register_operand" "")]))]
1925 "TARGET_32BIT && reload_completed"
1926 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
1927 (set (match_dup 3) (match_op_dup:SI 6
1928 [(ashiftrt:SI (match_dup 2) (const_int 31))
1932 operands[3] = gen_highpart (SImode, operands[0]);
1933 operands[0] = gen_lowpart (SImode, operands[0]);
1934 operands[4] = gen_highpart (SImode, operands[1]);
1935 operands[1] = gen_lowpart (SImode, operands[1]);
1936 operands[5] = gen_highpart (SImode, operands[2]);
1937 operands[2] = gen_lowpart (SImode, operands[2]);
1941 ;; The zero extend of operand 2 means we can just copy the high part of
1942 ;; operand1 into operand0.
1944 [(set (match_operand:DI 0 "s_register_operand" "")
1946 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1947 (match_operand:DI 1 "s_register_operand" "")))]
1948 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1949 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
1950 (set (match_dup 3) (match_dup 4))]
1953 operands[4] = gen_highpart (SImode, operands[1]);
1954 operands[3] = gen_highpart (SImode, operands[0]);
1955 operands[0] = gen_lowpart (SImode, operands[0]);
1956 operands[1] = gen_lowpart (SImode, operands[1]);
1960 ;; The zero extend of operand 2 means we can just copy the high part of
1961 ;; operand1 into operand0.
1963 [(set (match_operand:DI 0 "s_register_operand" "")
1965 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
1966 (match_operand:DI 1 "s_register_operand" "")))]
1967 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
1968 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
1969 (set (match_dup 3) (match_dup 4))]
1972 operands[4] = gen_highpart (SImode, operands[1]);
1973 operands[3] = gen_highpart (SImode, operands[0]);
1974 operands[0] = gen_lowpart (SImode, operands[0]);
1975 operands[1] = gen_lowpart (SImode, operands[1]);
1979 (define_expand "anddi3"
1980 [(set (match_operand:DI 0 "s_register_operand" "")
1981 (and:DI (match_operand:DI 1 "s_register_operand" "")
1982 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
1987 (define_insn_and_split "*anddi3_insn"
1988 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
1989 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
1990 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
1991 "TARGET_32BIT && !TARGET_IWMMXT"
1993 switch (which_alternative)
1995 case 0: /* fall through */
1996 case 6: return "vand\t%P0, %P1, %P2";
1997 case 1: /* fall through */
1998 case 7: return neon_output_logic_immediate ("vand", &operands[2],
1999 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2003 case 5: /* fall through */
2005 default: gcc_unreachable ();
2008 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2009 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2010 [(set (match_dup 3) (match_dup 4))
2011 (set (match_dup 5) (match_dup 6))]
2014 operands[3] = gen_lowpart (SImode, operands[0]);
2015 operands[5] = gen_highpart (SImode, operands[0]);
2017 operands[4] = simplify_gen_binary (AND, SImode,
2018 gen_lowpart (SImode, operands[1]),
2019 gen_lowpart (SImode, operands[2]));
2020 operands[6] = simplify_gen_binary (AND, SImode,
2021 gen_highpart (SImode, operands[1]),
2022 gen_highpart_mode (SImode, DImode, operands[2]));
2025 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2026 multiple,multiple,neon_logic,neon_logic")
2027 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2028 avoid_neon_for_64bits,avoid_neon_for_64bits")
2029 (set_attr "length" "*,*,8,8,8,8,*,*")
2033 (define_insn_and_split "*anddi_zesidi_di"
2034 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2035 (and:DI (zero_extend:DI
2036 (match_operand:SI 2 "s_register_operand" "r,r"))
2037 (match_operand:DI 1 "s_register_operand" "0,r")))]
2040 "TARGET_32BIT && reload_completed"
2041 ; The zero extend of operand 2 clears the high word of the output
2043 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2044 (set (match_dup 3) (const_int 0))]
2047 operands[3] = gen_highpart (SImode, operands[0]);
2048 operands[0] = gen_lowpart (SImode, operands[0]);
2049 operands[1] = gen_lowpart (SImode, operands[1]);
2051 [(set_attr "length" "8")
2052 (set_attr "type" "multiple")]
2055 (define_insn "*anddi_sesdi_di"
2056 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2057 (and:DI (sign_extend:DI
2058 (match_operand:SI 2 "s_register_operand" "r,r"))
2059 (match_operand:DI 1 "s_register_operand" "0,r")))]
2062 [(set_attr "length" "8")
2063 (set_attr "type" "multiple")]
2066 (define_expand "andsi3"
2067 [(set (match_operand:SI 0 "s_register_operand" "")
2068 (and:SI (match_operand:SI 1 "s_register_operand" "")
2069 (match_operand:SI 2 "reg_or_int_operand" "")))]
2074 if (CONST_INT_P (operands[2]))
2076 if (INTVAL (operands[2]) == 255 && arm_arch6)
2078 operands[1] = convert_to_mode (QImode, operands[1], 1);
2079 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2083 arm_split_constant (AND, SImode, NULL_RTX,
2084 INTVAL (operands[2]), operands[0],
2086 optimize && can_create_pseudo_p ());
2091 else /* TARGET_THUMB1 */
2093 if (!CONST_INT_P (operands[2]))
2095 rtx tmp = force_reg (SImode, operands[2]);
2096 if (rtx_equal_p (operands[0], operands[1]))
2100 operands[2] = operands[1];
2108 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2110 operands[2] = force_reg (SImode,
2111 GEN_INT (~INTVAL (operands[2])));
2113 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2118 for (i = 9; i <= 31; i++)
2120 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2122 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2126 else if ((((HOST_WIDE_INT) 1) << i) - 1
2127 == ~INTVAL (operands[2]))
2129 rtx shift = GEN_INT (i);
2130 rtx reg = gen_reg_rtx (SImode);
2132 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2133 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2139 operands[2] = force_reg (SImode, operands[2]);
2145 ; ??? Check split length for Thumb-2
2146 (define_insn_and_split "*arm_andsi3_insn"
2147 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2148 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2149 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2154 bic%?\\t%0, %1, #%B2
2158 && CONST_INT_P (operands[2])
2159 && !(const_ok_for_arm (INTVAL (operands[2]))
2160 || const_ok_for_arm (~INTVAL (operands[2])))"
2161 [(clobber (const_int 0))]
2163 arm_split_constant (AND, SImode, curr_insn,
2164 INTVAL (operands[2]), operands[0], operands[1], 0);
2167 [(set_attr "length" "4,4,4,4,16")
2168 (set_attr "predicable" "yes")
2169 (set_attr "predicable_short_it" "no,yes,no,no,no")
2170 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2173 (define_insn "*andsi3_compare0"
2174 [(set (reg:CC_NOOV CC_REGNUM)
2176 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2177 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2179 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2180 (and:SI (match_dup 1) (match_dup 2)))]
2184 bic%.\\t%0, %1, #%B2
2186 [(set_attr "conds" "set")
2187 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2190 (define_insn "*andsi3_compare0_scratch"
2191 [(set (reg:CC_NOOV CC_REGNUM)
2193 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2194 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2196 (clobber (match_scratch:SI 2 "=X,r,X"))]
2200 bic%.\\t%2, %0, #%B1
2202 [(set_attr "conds" "set")
2203 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2206 (define_insn "*zeroextractsi_compare0_scratch"
2207 [(set (reg:CC_NOOV CC_REGNUM)
2208 (compare:CC_NOOV (zero_extract:SI
2209 (match_operand:SI 0 "s_register_operand" "r")
2210 (match_operand 1 "const_int_operand" "n")
2211 (match_operand 2 "const_int_operand" "n"))
2214 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2215 && INTVAL (operands[1]) > 0
2216 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2217 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2219 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2220 << INTVAL (operands[2]));
2221 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2224 [(set_attr "conds" "set")
2225 (set_attr "predicable" "yes")
2226 (set_attr "predicable_short_it" "no")
2227 (set_attr "type" "logics_imm")]
2230 (define_insn_and_split "*ne_zeroextractsi"
2231 [(set (match_operand:SI 0 "s_register_operand" "=r")
2232 (ne:SI (zero_extract:SI
2233 (match_operand:SI 1 "s_register_operand" "r")
2234 (match_operand:SI 2 "const_int_operand" "n")
2235 (match_operand:SI 3 "const_int_operand" "n"))
2237 (clobber (reg:CC CC_REGNUM))]
2239 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2240 && INTVAL (operands[2]) > 0
2241 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2242 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2245 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2246 && INTVAL (operands[2]) > 0
2247 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2248 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2249 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2250 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2252 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2254 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2255 (match_dup 0) (const_int 1)))]
2257 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2258 << INTVAL (operands[3]));
2260 [(set_attr "conds" "clob")
2261 (set (attr "length")
2262 (if_then_else (eq_attr "is_thumb" "yes")
2265 (set_attr "type" "multiple")]
2268 (define_insn_and_split "*ne_zeroextractsi_shifted"
2269 [(set (match_operand:SI 0 "s_register_operand" "=r")
2270 (ne:SI (zero_extract:SI
2271 (match_operand:SI 1 "s_register_operand" "r")
2272 (match_operand:SI 2 "const_int_operand" "n")
2275 (clobber (reg:CC CC_REGNUM))]
2279 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2280 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2282 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2284 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2285 (match_dup 0) (const_int 1)))]
2287 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2289 [(set_attr "conds" "clob")
2290 (set_attr "length" "8")
2291 (set_attr "type" "multiple")]
2294 (define_insn_and_split "*ite_ne_zeroextractsi"
2295 [(set (match_operand:SI 0 "s_register_operand" "=r")
2296 (if_then_else:SI (ne (zero_extract:SI
2297 (match_operand:SI 1 "s_register_operand" "r")
2298 (match_operand:SI 2 "const_int_operand" "n")
2299 (match_operand:SI 3 "const_int_operand" "n"))
2301 (match_operand:SI 4 "arm_not_operand" "rIK")
2303 (clobber (reg:CC CC_REGNUM))]
2305 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2306 && INTVAL (operands[2]) > 0
2307 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2308 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2309 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2312 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2313 && INTVAL (operands[2]) > 0
2314 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2315 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2316 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2317 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2318 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2320 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2322 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2323 (match_dup 0) (match_dup 4)))]
2325 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2326 << INTVAL (operands[3]));
2328 [(set_attr "conds" "clob")
2329 (set_attr "length" "8")
2330 (set_attr "type" "multiple")]
2333 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2334 [(set (match_operand:SI 0 "s_register_operand" "=r")
2335 (if_then_else:SI (ne (zero_extract:SI
2336 (match_operand:SI 1 "s_register_operand" "r")
2337 (match_operand:SI 2 "const_int_operand" "n")
2340 (match_operand:SI 3 "arm_not_operand" "rIK")
2342 (clobber (reg:CC CC_REGNUM))]
2343 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2345 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2346 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2347 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2349 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2351 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2352 (match_dup 0) (match_dup 3)))]
2354 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2356 [(set_attr "conds" "clob")
2357 (set_attr "length" "8")
2358 (set_attr "type" "multiple")]
2361 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2363 [(set (match_operand:SI 0 "s_register_operand" "")
2364 (match_operator:SI 1 "shiftable_operator"
2365 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2366 (match_operand:SI 3 "const_int_operand" "")
2367 (match_operand:SI 4 "const_int_operand" ""))
2368 (match_operand:SI 5 "s_register_operand" "")]))
2369 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2371 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2374 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2377 HOST_WIDE_INT temp = INTVAL (operands[3]);
2379 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2380 operands[4] = GEN_INT (32 - temp);
2385 [(set (match_operand:SI 0 "s_register_operand" "")
2386 (match_operator:SI 1 "shiftable_operator"
2387 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2388 (match_operand:SI 3 "const_int_operand" "")
2389 (match_operand:SI 4 "const_int_operand" ""))
2390 (match_operand:SI 5 "s_register_operand" "")]))
2391 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2393 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2396 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2399 HOST_WIDE_INT temp = INTVAL (operands[3]);
2401 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2402 operands[4] = GEN_INT (32 - temp);
2406 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2407 ;;; represented by the bitfield, then this will produce incorrect results.
2408 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2409 ;;; which have a real bit-field insert instruction, the truncation happens
2410 ;;; in the bit-field insert instruction itself. Since arm does not have a
2411 ;;; bit-field insert instruction, we would have to emit code here to truncate
2412 ;;; the value before we insert. This loses some of the advantage of having
2413 ;;; this insv pattern, so this pattern needs to be reevalutated.
2415 (define_expand "insv"
2416 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2417 (match_operand 1 "general_operand" "")
2418 (match_operand 2 "general_operand" ""))
2419 (match_operand 3 "reg_or_int_operand" ""))]
2420 "TARGET_ARM || arm_arch_thumb2"
2423 int start_bit = INTVAL (operands[2]);
2424 int width = INTVAL (operands[1]);
2425 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2426 rtx target, subtarget;
2428 if (arm_arch_thumb2)
2430 if (unaligned_access && MEM_P (operands[0])
2431 && s_register_operand (operands[3], GET_MODE (operands[3]))
2432 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2436 if (BYTES_BIG_ENDIAN)
2437 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2442 base_addr = adjust_address (operands[0], SImode,
2443 start_bit / BITS_PER_UNIT);
2444 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2448 rtx tmp = gen_reg_rtx (HImode);
2450 base_addr = adjust_address (operands[0], HImode,
2451 start_bit / BITS_PER_UNIT);
2452 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2453 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2457 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2459 bool use_bfi = TRUE;
2461 if (CONST_INT_P (operands[3]))
2463 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2467 emit_insn (gen_insv_zero (operands[0], operands[1],
2472 /* See if the set can be done with a single orr instruction. */
2473 if (val == mask && const_ok_for_arm (val << start_bit))
2479 if (!REG_P (operands[3]))
2480 operands[3] = force_reg (SImode, operands[3]);
2482 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2491 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2494 target = copy_rtx (operands[0]);
2495 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2496 subreg as the final target. */
2497 if (GET_CODE (target) == SUBREG)
2499 subtarget = gen_reg_rtx (SImode);
2500 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2501 < GET_MODE_SIZE (SImode))
2502 target = SUBREG_REG (target);
2507 if (CONST_INT_P (operands[3]))
2509 /* Since we are inserting a known constant, we may be able to
2510 reduce the number of bits that we have to clear so that
2511 the mask becomes simple. */
2512 /* ??? This code does not check to see if the new mask is actually
2513 simpler. It may not be. */
2514 rtx op1 = gen_reg_rtx (SImode);
2515 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2516 start of this pattern. */
2517 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2518 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2520 emit_insn (gen_andsi3 (op1, operands[0],
2521 gen_int_mode (~mask2, SImode)));
2522 emit_insn (gen_iorsi3 (subtarget, op1,
2523 gen_int_mode (op3_value << start_bit, SImode)));
2525 else if (start_bit == 0
2526 && !(const_ok_for_arm (mask)
2527 || const_ok_for_arm (~mask)))
2529 /* A Trick, since we are setting the bottom bits in the word,
2530 we can shift operand[3] up, operand[0] down, OR them together
2531 and rotate the result back again. This takes 3 insns, and
2532 the third might be mergeable into another op. */
2533 /* The shift up copes with the possibility that operand[3] is
2534 wider than the bitfield. */
2535 rtx op0 = gen_reg_rtx (SImode);
2536 rtx op1 = gen_reg_rtx (SImode);
2538 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2539 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2540 emit_insn (gen_iorsi3 (op1, op1, op0));
2541 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2543 else if ((width + start_bit == 32)
2544 && !(const_ok_for_arm (mask)
2545 || const_ok_for_arm (~mask)))
2547 /* Similar trick, but slightly less efficient. */
2549 rtx op0 = gen_reg_rtx (SImode);
2550 rtx op1 = gen_reg_rtx (SImode);
2552 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2553 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2554 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2555 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2559 rtx op0 = gen_int_mode (mask, SImode);
2560 rtx op1 = gen_reg_rtx (SImode);
2561 rtx op2 = gen_reg_rtx (SImode);
2563 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2565 rtx tmp = gen_reg_rtx (SImode);
2567 emit_insn (gen_movsi (tmp, op0));
2571 /* Mask out any bits in operand[3] that are not needed. */
2572 emit_insn (gen_andsi3 (op1, operands[3], op0));
2574 if (CONST_INT_P (op0)
2575 && (const_ok_for_arm (mask << start_bit)
2576 || const_ok_for_arm (~(mask << start_bit))))
2578 op0 = gen_int_mode (~(mask << start_bit), SImode);
2579 emit_insn (gen_andsi3 (op2, operands[0], op0));
2583 if (CONST_INT_P (op0))
2585 rtx tmp = gen_reg_rtx (SImode);
2587 emit_insn (gen_movsi (tmp, op0));
2592 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2594 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2598 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2600 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2603 if (subtarget != target)
2605 /* If TARGET is still a SUBREG, then it must be wider than a word,
2606 so we must be careful only to set the subword we were asked to. */
2607 if (GET_CODE (target) == SUBREG)
2608 emit_move_insn (target, subtarget);
2610 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2617 (define_insn "insv_zero"
2618 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2619 (match_operand:SI 1 "const_int_M_operand" "M")
2620 (match_operand:SI 2 "const_int_M_operand" "M"))
2624 [(set_attr "length" "4")
2625 (set_attr "predicable" "yes")
2626 (set_attr "predicable_short_it" "no")
2627 (set_attr "type" "bfm")]
2630 (define_insn "insv_t2"
2631 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2632 (match_operand:SI 1 "const_int_M_operand" "M")
2633 (match_operand:SI 2 "const_int_M_operand" "M"))
2634 (match_operand:SI 3 "s_register_operand" "r"))]
2636 "bfi%?\t%0, %3, %2, %1"
2637 [(set_attr "length" "4")
2638 (set_attr "predicable" "yes")
2639 (set_attr "predicable_short_it" "no")
2640 (set_attr "type" "bfm")]
2643 ; constants for op 2 will never be given to these patterns.
2644 (define_insn_and_split "*anddi_notdi_di"
2645 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2646 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2647 (match_operand:DI 2 "s_register_operand" "r,0")))]
2650 "TARGET_32BIT && reload_completed
2651 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2652 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2653 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2654 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2657 operands[3] = gen_highpart (SImode, operands[0]);
2658 operands[0] = gen_lowpart (SImode, operands[0]);
2659 operands[4] = gen_highpart (SImode, operands[1]);
2660 operands[1] = gen_lowpart (SImode, operands[1]);
2661 operands[5] = gen_highpart (SImode, operands[2]);
2662 operands[2] = gen_lowpart (SImode, operands[2]);
2664 [(set_attr "length" "8")
2665 (set_attr "predicable" "yes")
2666 (set_attr "type" "multiple")]
2669 (define_insn_and_split "*anddi_notzesidi_di"
2670 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2671 (and:DI (not:DI (zero_extend:DI
2672 (match_operand:SI 2 "s_register_operand" "r,r")))
2673 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2676 bic%?\\t%Q0, %Q1, %2
2678 ; (not (zero_extend ...)) allows us to just copy the high word from
2679 ; operand1 to operand0.
2682 && operands[0] != operands[1]"
2683 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2684 (set (match_dup 3) (match_dup 4))]
2687 operands[3] = gen_highpart (SImode, operands[0]);
2688 operands[0] = gen_lowpart (SImode, operands[0]);
2689 operands[4] = gen_highpart (SImode, operands[1]);
2690 operands[1] = gen_lowpart (SImode, operands[1]);
2692 [(set_attr "length" "4,8")
2693 (set_attr "predicable" "yes")
2694 (set_attr "predicable_short_it" "no")
2695 (set_attr "type" "multiple")]
2698 (define_insn_and_split "*anddi_notdi_zesidi"
2699 [(set (match_operand:DI 0 "s_register_operand" "=r")
2700 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2702 (match_operand:SI 1 "s_register_operand" "r"))))]
2705 "TARGET_32BIT && reload_completed"
2706 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2707 (set (match_dup 3) (const_int 0))]
2710 operands[3] = gen_highpart (SImode, operands[0]);
2711 operands[0] = gen_lowpart (SImode, operands[0]);
2712 operands[2] = gen_lowpart (SImode, operands[2]);
2714 [(set_attr "length" "8")
2715 (set_attr "predicable" "yes")
2716 (set_attr "predicable_short_it" "no")
2717 (set_attr "type" "multiple")]
2720 (define_insn_and_split "*anddi_notsesidi_di"
2721 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2722 (and:DI (not:DI (sign_extend:DI
2723 (match_operand:SI 2 "s_register_operand" "r,r")))
2724 (match_operand:DI 1 "s_register_operand" "0,r")))]
2727 "TARGET_32BIT && reload_completed"
2728 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2729 (set (match_dup 3) (and:SI (not:SI
2730 (ashiftrt:SI (match_dup 2) (const_int 31)))
2734 operands[3] = gen_highpart (SImode, operands[0]);
2735 operands[0] = gen_lowpart (SImode, operands[0]);
2736 operands[4] = gen_highpart (SImode, operands[1]);
2737 operands[1] = gen_lowpart (SImode, operands[1]);
2739 [(set_attr "length" "8")
2740 (set_attr "predicable" "yes")
2741 (set_attr "predicable_short_it" "no")
2742 (set_attr "type" "multiple")]
2745 (define_insn "andsi_notsi_si"
2746 [(set (match_operand:SI 0 "s_register_operand" "=r")
2747 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2748 (match_operand:SI 1 "s_register_operand" "r")))]
2750 "bic%?\\t%0, %1, %2"
2751 [(set_attr "predicable" "yes")
2752 (set_attr "predicable_short_it" "no")
2753 (set_attr "type" "logic_reg")]
2756 (define_insn "andsi_not_shiftsi_si"
2757 [(set (match_operand:SI 0 "s_register_operand" "=r")
2758 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2759 [(match_operand:SI 2 "s_register_operand" "r")
2760 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2761 (match_operand:SI 1 "s_register_operand" "r")))]
2763 "bic%?\\t%0, %1, %2%S4"
2764 [(set_attr "predicable" "yes")
2765 (set_attr "shift" "2")
2766 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2767 (const_string "logic_shift_imm")
2768 (const_string "logic_shift_reg")))]
2771 (define_insn "*andsi_notsi_si_compare0"
2772 [(set (reg:CC_NOOV CC_REGNUM)
2774 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2775 (match_operand:SI 1 "s_register_operand" "r"))
2777 (set (match_operand:SI 0 "s_register_operand" "=r")
2778 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2780 "bic%.\\t%0, %1, %2"
2781 [(set_attr "conds" "set")
2782 (set_attr "type" "logics_shift_reg")]
2785 (define_insn "*andsi_notsi_si_compare0_scratch"
2786 [(set (reg:CC_NOOV CC_REGNUM)
2788 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2789 (match_operand:SI 1 "s_register_operand" "r"))
2791 (clobber (match_scratch:SI 0 "=r"))]
2793 "bic%.\\t%0, %1, %2"
2794 [(set_attr "conds" "set")
2795 (set_attr "type" "logics_shift_reg")]
2798 (define_expand "iordi3"
2799 [(set (match_operand:DI 0 "s_register_operand" "")
2800 (ior:DI (match_operand:DI 1 "s_register_operand" "")
2801 (match_operand:DI 2 "neon_logic_op2" "")))]
2806 (define_insn_and_split "*iordi3_insn"
2807 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2808 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2809 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
2810 "TARGET_32BIT && !TARGET_IWMMXT"
2812 switch (which_alternative)
2814 case 0: /* fall through */
2815 case 6: return "vorr\t%P0, %P1, %P2";
2816 case 1: /* fall through */
2817 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
2818 DImode, 0, VALID_NEON_QREG_MODE (DImode));
2824 default: gcc_unreachable ();
2827 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2828 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2829 [(set (match_dup 3) (match_dup 4))
2830 (set (match_dup 5) (match_dup 6))]
2833 operands[3] = gen_lowpart (SImode, operands[0]);
2834 operands[5] = gen_highpart (SImode, operands[0]);
2836 operands[4] = simplify_gen_binary (IOR, SImode,
2837 gen_lowpart (SImode, operands[1]),
2838 gen_lowpart (SImode, operands[2]));
2839 operands[6] = simplify_gen_binary (IOR, SImode,
2840 gen_highpart (SImode, operands[1]),
2841 gen_highpart_mode (SImode, DImode, operands[2]));
2844 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
2845 multiple,neon_logic,neon_logic")
2846 (set_attr "length" "*,*,8,8,8,8,*,*")
2847 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
2850 (define_insn "*iordi_zesidi_di"
2851 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2852 (ior:DI (zero_extend:DI
2853 (match_operand:SI 2 "s_register_operand" "r,r"))
2854 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2857 orr%?\\t%Q0, %Q1, %2
2859 [(set_attr "length" "4,8")
2860 (set_attr "predicable" "yes")
2861 (set_attr "predicable_short_it" "no")
2862 (set_attr "type" "logic_reg,multiple")]
2865 (define_insn "*iordi_sesidi_di"
2866 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2867 (ior:DI (sign_extend:DI
2868 (match_operand:SI 2 "s_register_operand" "r,r"))
2869 (match_operand:DI 1 "s_register_operand" "0,r")))]
2872 [(set_attr "length" "8")
2873 (set_attr "predicable" "yes")
2874 (set_attr "type" "multiple")]
2877 (define_expand "iorsi3"
2878 [(set (match_operand:SI 0 "s_register_operand" "")
2879 (ior:SI (match_operand:SI 1 "s_register_operand" "")
2880 (match_operand:SI 2 "reg_or_int_operand" "")))]
2883 if (CONST_INT_P (operands[2]))
2887 arm_split_constant (IOR, SImode, NULL_RTX,
2888 INTVAL (operands[2]), operands[0], operands[1],
2889 optimize && can_create_pseudo_p ());
2892 else /* TARGET_THUMB1 */
2894 rtx tmp = force_reg (SImode, operands[2]);
2895 if (rtx_equal_p (operands[0], operands[1]))
2899 operands[2] = operands[1];
2907 (define_insn_and_split "*iorsi3_insn"
2908 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2909 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2910 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2915 orn%?\\t%0, %1, #%B2
2919 && CONST_INT_P (operands[2])
2920 && !(const_ok_for_arm (INTVAL (operands[2]))
2921 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
2922 [(clobber (const_int 0))]
2924 arm_split_constant (IOR, SImode, curr_insn,
2925 INTVAL (operands[2]), operands[0], operands[1], 0);
2928 [(set_attr "length" "4,4,4,4,16")
2929 (set_attr "arch" "32,t2,t2,32,32")
2930 (set_attr "predicable" "yes")
2931 (set_attr "predicable_short_it" "no,yes,no,no,no")
2932 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
2936 [(match_scratch:SI 3 "r")
2937 (set (match_operand:SI 0 "arm_general_register_operand" "")
2938 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2939 (match_operand:SI 2 "const_int_operand" "")))]
2941 && !const_ok_for_arm (INTVAL (operands[2]))
2942 && const_ok_for_arm (~INTVAL (operands[2]))"
2943 [(set (match_dup 3) (match_dup 2))
2944 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2948 (define_insn "*iorsi3_compare0"
2949 [(set (reg:CC_NOOV CC_REGNUM)
2950 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2951 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
2953 (set (match_operand:SI 0 "s_register_operand" "=r,r")
2954 (ior:SI (match_dup 1) (match_dup 2)))]
2956 "orr%.\\t%0, %1, %2"
2957 [(set_attr "conds" "set")
2958 (set_attr "type" "logics_imm,logics_reg")]
2961 (define_insn "*iorsi3_compare0_scratch"
2962 [(set (reg:CC_NOOV CC_REGNUM)
2963 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
2964 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
2966 (clobber (match_scratch:SI 0 "=r,r"))]
2968 "orr%.\\t%0, %1, %2"
2969 [(set_attr "conds" "set")
2970 (set_attr "type" "logics_imm,logics_reg")]
2973 (define_expand "xordi3"
2974 [(set (match_operand:DI 0 "s_register_operand" "")
2975 (xor:DI (match_operand:DI 1 "s_register_operand" "")
2976 (match_operand:DI 2 "arm_xordi_operand" "")))]
2981 (define_insn_and_split "*xordi3_insn"
2982 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
2983 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
2984 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
2985 "TARGET_32BIT && !TARGET_IWMMXT"
2987 switch (which_alternative)
2992 case 4: /* fall through */
2994 case 0: /* fall through */
2995 case 5: return "veor\t%P0, %P1, %P2";
2996 default: gcc_unreachable ();
2999 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3000 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3001 [(set (match_dup 3) (match_dup 4))
3002 (set (match_dup 5) (match_dup 6))]
3005 operands[3] = gen_lowpart (SImode, operands[0]);
3006 operands[5] = gen_highpart (SImode, operands[0]);
3008 operands[4] = simplify_gen_binary (XOR, SImode,
3009 gen_lowpart (SImode, operands[1]),
3010 gen_lowpart (SImode, operands[2]));
3011 operands[6] = simplify_gen_binary (XOR, SImode,
3012 gen_highpart (SImode, operands[1]),
3013 gen_highpart_mode (SImode, DImode, operands[2]));
3016 [(set_attr "length" "*,8,8,8,8,*")
3017 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3018 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3021 (define_insn "*xordi_zesidi_di"
3022 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3023 (xor:DI (zero_extend:DI
3024 (match_operand:SI 2 "s_register_operand" "r,r"))
3025 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3028 eor%?\\t%Q0, %Q1, %2
3030 [(set_attr "length" "4,8")
3031 (set_attr "predicable" "yes")
3032 (set_attr "predicable_short_it" "no")
3033 (set_attr "type" "logic_reg")]
3036 (define_insn "*xordi_sesidi_di"
3037 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3038 (xor:DI (sign_extend:DI
3039 (match_operand:SI 2 "s_register_operand" "r,r"))
3040 (match_operand:DI 1 "s_register_operand" "0,r")))]
3043 [(set_attr "length" "8")
3044 (set_attr "predicable" "yes")
3045 (set_attr "type" "multiple")]
3048 (define_expand "xorsi3"
3049 [(set (match_operand:SI 0 "s_register_operand" "")
3050 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3051 (match_operand:SI 2 "reg_or_int_operand" "")))]
3053 "if (CONST_INT_P (operands[2]))
3057 arm_split_constant (XOR, SImode, NULL_RTX,
3058 INTVAL (operands[2]), operands[0], operands[1],
3059 optimize && can_create_pseudo_p ());
3062 else /* TARGET_THUMB1 */
3064 rtx tmp = force_reg (SImode, operands[2]);
3065 if (rtx_equal_p (operands[0], operands[1]))
3069 operands[2] = operands[1];
3076 (define_insn_and_split "*arm_xorsi3"
3077 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3078 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3079 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3087 && CONST_INT_P (operands[2])
3088 && !const_ok_for_arm (INTVAL (operands[2]))"
3089 [(clobber (const_int 0))]
3091 arm_split_constant (XOR, SImode, curr_insn,
3092 INTVAL (operands[2]), operands[0], operands[1], 0);
3095 [(set_attr "length" "4,4,4,16")
3096 (set_attr "predicable" "yes")
3097 (set_attr "predicable_short_it" "no,yes,no,no")
3098 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3101 (define_insn "*xorsi3_compare0"
3102 [(set (reg:CC_NOOV CC_REGNUM)
3103 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3104 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3106 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3107 (xor:SI (match_dup 1) (match_dup 2)))]
3109 "eor%.\\t%0, %1, %2"
3110 [(set_attr "conds" "set")
3111 (set_attr "type" "logics_imm,logics_reg")]
3114 (define_insn "*xorsi3_compare0_scratch"
3115 [(set (reg:CC_NOOV CC_REGNUM)
3116 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3117 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3121 [(set_attr "conds" "set")
3122 (set_attr "type" "logics_imm,logics_reg")]
3125 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3126 ; (NOT D) we can sometimes merge the final NOT into one of the following
3130 [(set (match_operand:SI 0 "s_register_operand" "")
3131 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3132 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3133 (match_operand:SI 3 "arm_rhs_operand" "")))
3134 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3136 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3137 (not:SI (match_dup 3))))
3138 (set (match_dup 0) (not:SI (match_dup 4)))]
3142 (define_insn_and_split "*andsi_iorsi3_notsi"
3143 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3144 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3145 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3146 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3148 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3149 "&& reload_completed"
3150 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3151 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3153 [(set_attr "length" "8")
3154 (set_attr "ce_count" "2")
3155 (set_attr "predicable" "yes")
3156 (set_attr "predicable_short_it" "no")
3157 (set_attr "type" "multiple")]
3160 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3161 ; insns are available?
3163 [(set (match_operand:SI 0 "s_register_operand" "")
3164 (match_operator:SI 1 "logical_binary_operator"
3165 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3166 (match_operand:SI 3 "const_int_operand" "")
3167 (match_operand:SI 4 "const_int_operand" ""))
3168 (match_operator:SI 9 "logical_binary_operator"
3169 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3170 (match_operand:SI 6 "const_int_operand" ""))
3171 (match_operand:SI 7 "s_register_operand" "")])]))
3172 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3174 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3175 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3178 [(ashift:SI (match_dup 2) (match_dup 4))
3182 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3185 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3189 [(set (match_operand:SI 0 "s_register_operand" "")
3190 (match_operator:SI 1 "logical_binary_operator"
3191 [(match_operator:SI 9 "logical_binary_operator"
3192 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3193 (match_operand:SI 6 "const_int_operand" ""))
3194 (match_operand:SI 7 "s_register_operand" "")])
3195 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3196 (match_operand:SI 3 "const_int_operand" "")
3197 (match_operand:SI 4 "const_int_operand" ""))]))
3198 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3200 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3201 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3204 [(ashift:SI (match_dup 2) (match_dup 4))
3208 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3211 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3215 [(set (match_operand:SI 0 "s_register_operand" "")
3216 (match_operator:SI 1 "logical_binary_operator"
3217 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3218 (match_operand:SI 3 "const_int_operand" "")
3219 (match_operand:SI 4 "const_int_operand" ""))
3220 (match_operator:SI 9 "logical_binary_operator"
3221 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3222 (match_operand:SI 6 "const_int_operand" ""))
3223 (match_operand:SI 7 "s_register_operand" "")])]))
3224 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3226 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3227 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3230 [(ashift:SI (match_dup 2) (match_dup 4))
3234 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3237 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3241 [(set (match_operand:SI 0 "s_register_operand" "")
3242 (match_operator:SI 1 "logical_binary_operator"
3243 [(match_operator:SI 9 "logical_binary_operator"
3244 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3245 (match_operand:SI 6 "const_int_operand" ""))
3246 (match_operand:SI 7 "s_register_operand" "")])
3247 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3248 (match_operand:SI 3 "const_int_operand" "")
3249 (match_operand:SI 4 "const_int_operand" ""))]))
3250 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3252 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3253 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3256 [(ashift:SI (match_dup 2) (match_dup 4))
3260 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3263 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3267 ;; Minimum and maximum insns
3269 (define_expand "smaxsi3"
3271 (set (match_operand:SI 0 "s_register_operand" "")
3272 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3273 (match_operand:SI 2 "arm_rhs_operand" "")))
3274 (clobber (reg:CC CC_REGNUM))])]
3277 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3279 /* No need for a clobber of the condition code register here. */
3280 emit_insn (gen_rtx_SET (operands[0],
3281 gen_rtx_SMAX (SImode, operands[1],
3287 (define_insn "*smax_0"
3288 [(set (match_operand:SI 0 "s_register_operand" "=r")
3289 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3292 "bic%?\\t%0, %1, %1, asr #31"
3293 [(set_attr "predicable" "yes")
3294 (set_attr "predicable_short_it" "no")
3295 (set_attr "type" "logic_shift_reg")]
3298 (define_insn "*smax_m1"
3299 [(set (match_operand:SI 0 "s_register_operand" "=r")
3300 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3303 "orr%?\\t%0, %1, %1, asr #31"
3304 [(set_attr "predicable" "yes")
3305 (set_attr "predicable_short_it" "no")
3306 (set_attr "type" "logic_shift_reg")]
3309 (define_insn_and_split "*arm_smax_insn"
3310 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3311 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3312 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3313 (clobber (reg:CC CC_REGNUM))]
3316 ; cmp\\t%1, %2\;movlt\\t%0, %2
3317 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3319 [(set (reg:CC CC_REGNUM)
3320 (compare:CC (match_dup 1) (match_dup 2)))
3322 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3326 [(set_attr "conds" "clob")
3327 (set_attr "length" "8,12")
3328 (set_attr "type" "multiple")]
3331 (define_expand "sminsi3"
3333 (set (match_operand:SI 0 "s_register_operand" "")
3334 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3335 (match_operand:SI 2 "arm_rhs_operand" "")))
3336 (clobber (reg:CC CC_REGNUM))])]
3339 if (operands[2] == const0_rtx)
3341 /* No need for a clobber of the condition code register here. */
3342 emit_insn (gen_rtx_SET (operands[0],
3343 gen_rtx_SMIN (SImode, operands[1],
3349 (define_insn "*smin_0"
3350 [(set (match_operand:SI 0 "s_register_operand" "=r")
3351 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3354 "and%?\\t%0, %1, %1, asr #31"
3355 [(set_attr "predicable" "yes")
3356 (set_attr "predicable_short_it" "no")
3357 (set_attr "type" "logic_shift_reg")]
3360 (define_insn_and_split "*arm_smin_insn"
3361 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3362 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3363 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3364 (clobber (reg:CC CC_REGNUM))]
3367 ; cmp\\t%1, %2\;movge\\t%0, %2
3368 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3370 [(set (reg:CC CC_REGNUM)
3371 (compare:CC (match_dup 1) (match_dup 2)))
3373 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3377 [(set_attr "conds" "clob")
3378 (set_attr "length" "8,12")
3379 (set_attr "type" "multiple,multiple")]
3382 (define_expand "umaxsi3"
3384 (set (match_operand:SI 0 "s_register_operand" "")
3385 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3386 (match_operand:SI 2 "arm_rhs_operand" "")))
3387 (clobber (reg:CC CC_REGNUM))])]
3392 (define_insn_and_split "*arm_umaxsi3"
3393 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3394 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3395 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3396 (clobber (reg:CC CC_REGNUM))]
3399 ; cmp\\t%1, %2\;movcc\\t%0, %2
3400 ; cmp\\t%1, %2\;movcs\\t%0, %1
3401 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3403 [(set (reg:CC CC_REGNUM)
3404 (compare:CC (match_dup 1) (match_dup 2)))
3406 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3410 [(set_attr "conds" "clob")
3411 (set_attr "length" "8,8,12")
3412 (set_attr "type" "store1")]
3415 (define_expand "uminsi3"
3417 (set (match_operand:SI 0 "s_register_operand" "")
3418 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3419 (match_operand:SI 2 "arm_rhs_operand" "")))
3420 (clobber (reg:CC CC_REGNUM))])]
3425 (define_insn_and_split "*arm_uminsi3"
3426 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3427 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3428 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3429 (clobber (reg:CC CC_REGNUM))]
3432 ; cmp\\t%1, %2\;movcs\\t%0, %2
3433 ; cmp\\t%1, %2\;movcc\\t%0, %1
3434 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3436 [(set (reg:CC CC_REGNUM)
3437 (compare:CC (match_dup 1) (match_dup 2)))
3439 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3443 [(set_attr "conds" "clob")
3444 (set_attr "length" "8,8,12")
3445 (set_attr "type" "store1")]
3448 (define_insn "*store_minmaxsi"
3449 [(set (match_operand:SI 0 "memory_operand" "=m")
3450 (match_operator:SI 3 "minmax_operator"
3451 [(match_operand:SI 1 "s_register_operand" "r")
3452 (match_operand:SI 2 "s_register_operand" "r")]))
3453 (clobber (reg:CC CC_REGNUM))]
3454 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3456 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3457 operands[1], operands[2]);
3458 output_asm_insn (\"cmp\\t%1, %2\", operands);
3460 output_asm_insn (\"ite\t%d3\", operands);
3461 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3462 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3465 [(set_attr "conds" "clob")
3466 (set (attr "length")
3467 (if_then_else (eq_attr "is_thumb" "yes")
3470 (set_attr "type" "store1")]
3473 ; Reject the frame pointer in operand[1], since reloading this after
3474 ; it has been eliminated can cause carnage.
3475 (define_insn "*minmax_arithsi"
3476 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3477 (match_operator:SI 4 "shiftable_operator"
3478 [(match_operator:SI 5 "minmax_operator"
3479 [(match_operand:SI 2 "s_register_operand" "r,r")
3480 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3481 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3482 (clobber (reg:CC CC_REGNUM))]
3483 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3486 enum rtx_code code = GET_CODE (operands[4]);
3489 if (which_alternative != 0 || operands[3] != const0_rtx
3490 || (code != PLUS && code != IOR && code != XOR))
3495 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3496 operands[2], operands[3]);
3497 output_asm_insn (\"cmp\\t%2, %3\", operands);
3501 output_asm_insn (\"ite\\t%d5\", operands);
3503 output_asm_insn (\"it\\t%d5\", operands);
3505 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3507 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3510 [(set_attr "conds" "clob")
3511 (set (attr "length")
3512 (if_then_else (eq_attr "is_thumb" "yes")
3515 (set_attr "type" "multiple")]
3518 ; Reject the frame pointer in operand[1], since reloading this after
3519 ; it has been eliminated can cause carnage.
3520 (define_insn_and_split "*minmax_arithsi_non_canon"
3521 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3523 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3524 (match_operator:SI 4 "minmax_operator"
3525 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3526 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3527 (clobber (reg:CC CC_REGNUM))]
3528 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3529 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3531 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3532 [(set (reg:CC CC_REGNUM)
3533 (compare:CC (match_dup 2) (match_dup 3)))
3535 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3537 (minus:SI (match_dup 1)
3539 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3543 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3544 operands[2], operands[3]);
3545 enum rtx_code rc = minmax_code (operands[4]);
3546 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3547 operands[2], operands[3]);
3549 if (mode == CCFPmode || mode == CCFPEmode)
3550 rc = reverse_condition_maybe_unordered (rc);
3552 rc = reverse_condition (rc);
3553 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3554 if (CONST_INT_P (operands[3]))
3555 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3557 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3559 [(set_attr "conds" "clob")
3560 (set (attr "length")
3561 (if_then_else (eq_attr "is_thumb" "yes")
3564 (set_attr "type" "multiple")]
3567 (define_code_iterator SAT [smin smax])
3568 (define_code_iterator SATrev [smin smax])
3569 (define_code_attr SATlo [(smin "1") (smax "2")])
3570 (define_code_attr SAThi [(smin "2") (smax "1")])
3572 (define_insn "*satsi_<SAT:code>"
3573 [(set (match_operand:SI 0 "s_register_operand" "=r")
3574 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3575 (match_operand:SI 1 "const_int_operand" "i"))
3576 (match_operand:SI 2 "const_int_operand" "i")))]
3577 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3578 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3582 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3583 &mask, &signed_sat))
3586 operands[1] = GEN_INT (mask);
3588 return "ssat%?\t%0, %1, %3";
3590 return "usat%?\t%0, %1, %3";
3592 [(set_attr "predicable" "yes")
3593 (set_attr "predicable_short_it" "no")
3594 (set_attr "type" "alus_imm")]
3597 (define_insn "*satsi_<SAT:code>_shift"
3598 [(set (match_operand:SI 0 "s_register_operand" "=r")
3599 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3600 [(match_operand:SI 4 "s_register_operand" "r")
3601 (match_operand:SI 5 "const_int_operand" "i")])
3602 (match_operand:SI 1 "const_int_operand" "i"))
3603 (match_operand:SI 2 "const_int_operand" "i")))]
3604 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3605 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3609 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3610 &mask, &signed_sat))
3613 operands[1] = GEN_INT (mask);
3615 return "ssat%?\t%0, %1, %4%S3";
3617 return "usat%?\t%0, %1, %4%S3";
3619 [(set_attr "predicable" "yes")
3620 (set_attr "predicable_short_it" "no")
3621 (set_attr "shift" "3")
3622 (set_attr "type" "logic_shift_reg")])
3624 ;; Shift and rotation insns
3626 (define_expand "ashldi3"
3627 [(set (match_operand:DI 0 "s_register_operand" "")
3628 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3629 (match_operand:SI 2 "general_operand" "")))]
3634 /* Delay the decision whether to use NEON or core-regs until
3635 register allocation. */
3636 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3641 /* Only the NEON case can handle in-memory shift counts. */
3642 if (!reg_or_int_operand (operands[2], SImode))
3643 operands[2] = force_reg (SImode, operands[2]);
3646 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3647 ; /* No special preparation statements; expand pattern as above. */
3650 rtx scratch1, scratch2;
3652 if (CONST_INT_P (operands[2])
3653 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3655 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3659 /* Ideally we should use iwmmxt here if we could know that operands[1]
3660 ends up already living in an iwmmxt register. Otherwise it's
3661 cheaper to have the alternate code being generated than moving
3662 values to iwmmxt regs and back. */
3664 /* If we're optimizing for size, we prefer the libgcc calls. */
3665 if (optimize_function_for_size_p (cfun))
3668 /* Expand operation using core-registers.
3669 'FAIL' would achieve the same thing, but this is a bit smarter. */
3670 scratch1 = gen_reg_rtx (SImode);
3671 scratch2 = gen_reg_rtx (SImode);
3672 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3673 operands[2], scratch1, scratch2);
3679 (define_insn "arm_ashldi3_1bit"
3680 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3681 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3683 (clobber (reg:CC CC_REGNUM))]
3685 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3686 [(set_attr "conds" "clob")
3687 (set_attr "length" "8")
3688 (set_attr "type" "multiple")]
3691 (define_expand "ashlsi3"
3692 [(set (match_operand:SI 0 "s_register_operand" "")
3693 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3694 (match_operand:SI 2 "arm_rhs_operand" "")))]
3697 if (CONST_INT_P (operands[2])
3698 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3700 emit_insn (gen_movsi (operands[0], const0_rtx));
3706 (define_expand "ashrdi3"
3707 [(set (match_operand:DI 0 "s_register_operand" "")
3708 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3709 (match_operand:SI 2 "reg_or_int_operand" "")))]
3714 /* Delay the decision whether to use NEON or core-regs until
3715 register allocation. */
3716 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3720 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3721 ; /* No special preparation statements; expand pattern as above. */
3724 rtx scratch1, scratch2;
3726 if (CONST_INT_P (operands[2])
3727 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3729 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3733 /* Ideally we should use iwmmxt here if we could know that operands[1]
3734 ends up already living in an iwmmxt register. Otherwise it's
3735 cheaper to have the alternate code being generated than moving
3736 values to iwmmxt regs and back. */
3738 /* If we're optimizing for size, we prefer the libgcc calls. */
3739 if (optimize_function_for_size_p (cfun))
3742 /* Expand operation using core-registers.
3743 'FAIL' would achieve the same thing, but this is a bit smarter. */
3744 scratch1 = gen_reg_rtx (SImode);
3745 scratch2 = gen_reg_rtx (SImode);
3746 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3747 operands[2], scratch1, scratch2);
3753 (define_insn "arm_ashrdi3_1bit"
3754 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3755 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3757 (clobber (reg:CC CC_REGNUM))]
3759 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3760 [(set_attr "conds" "clob")
3761 (set_attr "length" "8")
3762 (set_attr "type" "multiple")]
3765 (define_expand "ashrsi3"
3766 [(set (match_operand:SI 0 "s_register_operand" "")
3767 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3768 (match_operand:SI 2 "arm_rhs_operand" "")))]
3771 if (CONST_INT_P (operands[2])
3772 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3773 operands[2] = GEN_INT (31);
3777 (define_expand "lshrdi3"
3778 [(set (match_operand:DI 0 "s_register_operand" "")
3779 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3780 (match_operand:SI 2 "reg_or_int_operand" "")))]
3785 /* Delay the decision whether to use NEON or core-regs until
3786 register allocation. */
3787 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
3791 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3792 ; /* No special preparation statements; expand pattern as above. */
3795 rtx scratch1, scratch2;
3797 if (CONST_INT_P (operands[2])
3798 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3800 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
3804 /* Ideally we should use iwmmxt here if we could know that operands[1]
3805 ends up already living in an iwmmxt register. Otherwise it's
3806 cheaper to have the alternate code being generated than moving
3807 values to iwmmxt regs and back. */
3809 /* If we're optimizing for size, we prefer the libgcc calls. */
3810 if (optimize_function_for_size_p (cfun))
3813 /* Expand operation using core-registers.
3814 'FAIL' would achieve the same thing, but this is a bit smarter. */
3815 scratch1 = gen_reg_rtx (SImode);
3816 scratch2 = gen_reg_rtx (SImode);
3817 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3818 operands[2], scratch1, scratch2);
3824 (define_insn "arm_lshrdi3_1bit"
3825 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3826 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3828 (clobber (reg:CC CC_REGNUM))]
3830 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
3831 [(set_attr "conds" "clob")
3832 (set_attr "length" "8")
3833 (set_attr "type" "multiple")]
3836 (define_expand "lshrsi3"
3837 [(set (match_operand:SI 0 "s_register_operand" "")
3838 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3839 (match_operand:SI 2 "arm_rhs_operand" "")))]
3842 if (CONST_INT_P (operands[2])
3843 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3845 emit_insn (gen_movsi (operands[0], const0_rtx));
3851 (define_expand "rotlsi3"
3852 [(set (match_operand:SI 0 "s_register_operand" "")
3853 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3854 (match_operand:SI 2 "reg_or_int_operand" "")))]
3857 if (CONST_INT_P (operands[2]))
3858 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3861 rtx reg = gen_reg_rtx (SImode);
3862 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3868 (define_expand "rotrsi3"
3869 [(set (match_operand:SI 0 "s_register_operand" "")
3870 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
3871 (match_operand:SI 2 "arm_rhs_operand" "")))]
3876 if (CONST_INT_P (operands[2])
3877 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3878 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3880 else /* TARGET_THUMB1 */
3882 if (CONST_INT_P (operands [2]))
3883 operands [2] = force_reg (SImode, operands[2]);
3888 (define_insn "*arm_shiftsi3"
3889 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
3890 (match_operator:SI 3 "shift_operator"
3891 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
3892 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
3894 "* return arm_output_shift(operands, 0);"
3895 [(set_attr "predicable" "yes")
3896 (set_attr "arch" "t2,t2,*,*")
3897 (set_attr "predicable_short_it" "yes,yes,no,no")
3898 (set_attr "length" "4")
3899 (set_attr "shift" "1")
3900 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
3903 (define_insn "*shiftsi3_compare0"
3904 [(set (reg:CC_NOOV CC_REGNUM)
3905 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3906 [(match_operand:SI 1 "s_register_operand" "r,r")
3907 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3909 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3910 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
3912 "* return arm_output_shift(operands, 1);"
3913 [(set_attr "conds" "set")
3914 (set_attr "shift" "1")
3915 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
3918 (define_insn "*shiftsi3_compare0_scratch"
3919 [(set (reg:CC_NOOV CC_REGNUM)
3920 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3921 [(match_operand:SI 1 "s_register_operand" "r,r")
3922 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3924 (clobber (match_scratch:SI 0 "=r,r"))]
3926 "* return arm_output_shift(operands, 1);"
3927 [(set_attr "conds" "set")
3928 (set_attr "shift" "1")
3929 (set_attr "type" "shift_imm,shift_reg")]
3932 (define_insn "*not_shiftsi"
3933 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3934 (not:SI (match_operator:SI 3 "shift_operator"
3935 [(match_operand:SI 1 "s_register_operand" "r,r")
3936 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3939 [(set_attr "predicable" "yes")
3940 (set_attr "predicable_short_it" "no")
3941 (set_attr "shift" "1")
3942 (set_attr "arch" "32,a")
3943 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3945 (define_insn "*not_shiftsi_compare0"
3946 [(set (reg:CC_NOOV CC_REGNUM)
3948 (not:SI (match_operator:SI 3 "shift_operator"
3949 [(match_operand:SI 1 "s_register_operand" "r,r")
3950 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3952 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3953 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
3956 [(set_attr "conds" "set")
3957 (set_attr "shift" "1")
3958 (set_attr "arch" "32,a")
3959 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3961 (define_insn "*not_shiftsi_compare0_scratch"
3962 [(set (reg:CC_NOOV CC_REGNUM)
3964 (not:SI (match_operator:SI 3 "shift_operator"
3965 [(match_operand:SI 1 "s_register_operand" "r,r")
3966 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3968 (clobber (match_scratch:SI 0 "=r,r"))]
3971 [(set_attr "conds" "set")
3972 (set_attr "shift" "1")
3973 (set_attr "arch" "32,a")
3974 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3976 ;; We don't really have extzv, but defining this using shifts helps
3977 ;; to reduce register pressure later on.
3979 (define_expand "extzv"
3980 [(set (match_operand 0 "s_register_operand" "")
3981 (zero_extract (match_operand 1 "nonimmediate_operand" "")
3982 (match_operand 2 "const_int_operand" "")
3983 (match_operand 3 "const_int_operand" "")))]
3984 "TARGET_THUMB1 || arm_arch_thumb2"
3987 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3988 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3990 if (arm_arch_thumb2)
3992 HOST_WIDE_INT width = INTVAL (operands[2]);
3993 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3995 if (unaligned_access && MEM_P (operands[1])
3996 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4000 if (BYTES_BIG_ENDIAN)
4001 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4006 base_addr = adjust_address (operands[1], SImode,
4007 bitpos / BITS_PER_UNIT);
4008 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4012 rtx dest = operands[0];
4013 rtx tmp = gen_reg_rtx (SImode);
4015 /* We may get a paradoxical subreg here. Strip it off. */
4016 if (GET_CODE (dest) == SUBREG
4017 && GET_MODE (dest) == SImode
4018 && GET_MODE (SUBREG_REG (dest)) == HImode)
4019 dest = SUBREG_REG (dest);
4021 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4024 base_addr = adjust_address (operands[1], HImode,
4025 bitpos / BITS_PER_UNIT);
4026 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4027 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4031 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4033 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4041 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4044 operands[3] = GEN_INT (rshift);
4048 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4052 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4053 operands[3], gen_reg_rtx (SImode)));
4058 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4060 (define_expand "extzv_t1"
4061 [(set (match_operand:SI 4 "s_register_operand" "")
4062 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4063 (match_operand:SI 2 "const_int_operand" "")))
4064 (set (match_operand:SI 0 "s_register_operand" "")
4065 (lshiftrt:SI (match_dup 4)
4066 (match_operand:SI 3 "const_int_operand" "")))]
4070 (define_expand "extv"
4071 [(set (match_operand 0 "s_register_operand" "")
4072 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4073 (match_operand 2 "const_int_operand" "")
4074 (match_operand 3 "const_int_operand" "")))]
4077 HOST_WIDE_INT width = INTVAL (operands[2]);
4078 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4080 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4081 && (bitpos % BITS_PER_UNIT) == 0)
4085 if (BYTES_BIG_ENDIAN)
4086 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4090 base_addr = adjust_address (operands[1], SImode,
4091 bitpos / BITS_PER_UNIT);
4092 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4096 rtx dest = operands[0];
4097 rtx tmp = gen_reg_rtx (SImode);
4099 /* We may get a paradoxical subreg here. Strip it off. */
4100 if (GET_CODE (dest) == SUBREG
4101 && GET_MODE (dest) == SImode
4102 && GET_MODE (SUBREG_REG (dest)) == HImode)
4103 dest = SUBREG_REG (dest);
4105 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4108 base_addr = adjust_address (operands[1], HImode,
4109 bitpos / BITS_PER_UNIT);
4110 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4111 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4116 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4118 else if (GET_MODE (operands[0]) == SImode
4119 && GET_MODE (operands[1]) == SImode)
4121 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4129 ; Helper to expand register forms of extv with the proper modes.
4131 (define_expand "extv_regsi"
4132 [(set (match_operand:SI 0 "s_register_operand" "")
4133 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4134 (match_operand 2 "const_int_operand" "")
4135 (match_operand 3 "const_int_operand" "")))]
4140 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4142 (define_insn "unaligned_loadsi"
4143 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4144 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4145 UNSPEC_UNALIGNED_LOAD))]
4146 "unaligned_access && TARGET_32BIT"
4147 "ldr%?\t%0, %1\t@ unaligned"
4148 [(set_attr "arch" "t2,any")
4149 (set_attr "length" "2,4")
4150 (set_attr "predicable" "yes")
4151 (set_attr "predicable_short_it" "yes,no")
4152 (set_attr "type" "load1")])
4154 (define_insn "unaligned_loadhis"
4155 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4157 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4158 UNSPEC_UNALIGNED_LOAD)))]
4159 "unaligned_access && TARGET_32BIT"
4160 "ldr%(sh%)\t%0, %1\t@ unaligned"
4161 [(set_attr "arch" "t2,any")
4162 (set_attr "length" "2,4")
4163 (set_attr "predicable" "yes")
4164 (set_attr "predicable_short_it" "yes,no")
4165 (set_attr "type" "load_byte")])
4167 (define_insn "unaligned_loadhiu"
4168 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4170 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4171 UNSPEC_UNALIGNED_LOAD)))]
4172 "unaligned_access && TARGET_32BIT"
4173 "ldr%(h%)\t%0, %1\t@ unaligned"
4174 [(set_attr "arch" "t2,any")
4175 (set_attr "length" "2,4")
4176 (set_attr "predicable" "yes")
4177 (set_attr "predicable_short_it" "yes,no")
4178 (set_attr "type" "load_byte")])
4180 (define_insn "unaligned_storesi"
4181 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4182 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4183 UNSPEC_UNALIGNED_STORE))]
4184 "unaligned_access && TARGET_32BIT"
4185 "str%?\t%1, %0\t@ unaligned"
4186 [(set_attr "arch" "t2,any")
4187 (set_attr "length" "2,4")
4188 (set_attr "predicable" "yes")
4189 (set_attr "predicable_short_it" "yes,no")
4190 (set_attr "type" "store1")])
4192 (define_insn "unaligned_storehi"
4193 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4194 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4195 UNSPEC_UNALIGNED_STORE))]
4196 "unaligned_access && TARGET_32BIT"
4197 "str%(h%)\t%1, %0\t@ unaligned"
4198 [(set_attr "arch" "t2,any")
4199 (set_attr "length" "2,4")
4200 (set_attr "predicable" "yes")
4201 (set_attr "predicable_short_it" "yes,no")
4202 (set_attr "type" "store1")])
4204 ;; Unaligned double-word load and store.
4205 ;; Split after reload into two unaligned single-word accesses.
4206 ;; It prevents lower_subreg from splitting some other aligned
4207 ;; double-word accesses too early. Used for internal memcpy.
4209 (define_insn_and_split "unaligned_loaddi"
4210 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4211 (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4212 UNSPEC_UNALIGNED_LOAD))]
4213 "unaligned_access && TARGET_32BIT"
4215 "&& reload_completed"
4216 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4217 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4219 operands[2] = gen_highpart (SImode, operands[0]);
4220 operands[0] = gen_lowpart (SImode, operands[0]);
4221 operands[3] = gen_highpart (SImode, operands[1]);
4222 operands[1] = gen_lowpart (SImode, operands[1]);
4224 /* If the first destination register overlaps with the base address,
4225 swap the order in which the loads are emitted. */
4226 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4228 std::swap (operands[1], operands[3]);
4229 std::swap (operands[0], operands[2]);
4232 [(set_attr "arch" "t2,any")
4233 (set_attr "length" "4,8")
4234 (set_attr "predicable" "yes")
4235 (set_attr "type" "load2")])
4237 (define_insn_and_split "unaligned_storedi"
4238 [(set (match_operand:DI 0 "memory_operand" "=o,o")
4239 (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4240 UNSPEC_UNALIGNED_STORE))]
4241 "unaligned_access && TARGET_32BIT"
4243 "&& reload_completed"
4244 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4245 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4247 operands[2] = gen_highpart (SImode, operands[0]);
4248 operands[0] = gen_lowpart (SImode, operands[0]);
4249 operands[3] = gen_highpart (SImode, operands[1]);
4250 operands[1] = gen_lowpart (SImode, operands[1]);
4252 [(set_attr "arch" "t2,any")
4253 (set_attr "length" "4,8")
4254 (set_attr "predicable" "yes")
4255 (set_attr "type" "store2")])
4258 (define_insn "*extv_reg"
4259 [(set (match_operand:SI 0 "s_register_operand" "=r")
4260 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4261 (match_operand:SI 2 "const_int_M_operand" "M")
4262 (match_operand:SI 3 "const_int_M_operand" "M")))]
4264 "sbfx%?\t%0, %1, %3, %2"
4265 [(set_attr "length" "4")
4266 (set_attr "predicable" "yes")
4267 (set_attr "predicable_short_it" "no")
4268 (set_attr "type" "bfm")]
4271 (define_insn "extzv_t2"
4272 [(set (match_operand:SI 0 "s_register_operand" "=r")
4273 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4274 (match_operand:SI 2 "const_int_M_operand" "M")
4275 (match_operand:SI 3 "const_int_M_operand" "M")))]
4277 "ubfx%?\t%0, %1, %3, %2"
4278 [(set_attr "length" "4")
4279 (set_attr "predicable" "yes")
4280 (set_attr "predicable_short_it" "no")
4281 (set_attr "type" "bfm")]
4285 ;; Division instructions
4286 (define_insn "divsi3"
4287 [(set (match_operand:SI 0 "s_register_operand" "=r")
4288 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4289 (match_operand:SI 2 "s_register_operand" "r")))]
4291 "sdiv%?\t%0, %1, %2"
4292 [(set_attr "predicable" "yes")
4293 (set_attr "predicable_short_it" "no")
4294 (set_attr "type" "sdiv")]
4297 (define_insn "udivsi3"
4298 [(set (match_operand:SI 0 "s_register_operand" "=r")
4299 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4300 (match_operand:SI 2 "s_register_operand" "r")))]
4302 "udiv%?\t%0, %1, %2"
4303 [(set_attr "predicable" "yes")
4304 (set_attr "predicable_short_it" "no")
4305 (set_attr "type" "udiv")]
4309 ;; Unary arithmetic insns
4311 (define_expand "negdi2"
4313 [(set (match_operand:DI 0 "s_register_operand" "")
4314 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4315 (clobber (reg:CC CC_REGNUM))])]
4320 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4326 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4327 ;; The first alternative allows the common case of a *full* overlap.
4328 (define_insn_and_split "*arm_negdi2"
4329 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4330 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4331 (clobber (reg:CC CC_REGNUM))]
4333 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4334 "&& reload_completed"
4335 [(parallel [(set (reg:CC CC_REGNUM)
4336 (compare:CC (const_int 0) (match_dup 1)))
4337 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4338 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4339 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4341 operands[2] = gen_highpart (SImode, operands[0]);
4342 operands[0] = gen_lowpart (SImode, operands[0]);
4343 operands[3] = gen_highpart (SImode, operands[1]);
4344 operands[1] = gen_lowpart (SImode, operands[1]);
4346 [(set_attr "conds" "clob")
4347 (set_attr "length" "8")
4348 (set_attr "type" "multiple")]
4351 (define_expand "negsi2"
4352 [(set (match_operand:SI 0 "s_register_operand" "")
4353 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4358 (define_insn "*arm_negsi2"
4359 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4360 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4362 "rsb%?\\t%0, %1, #0"
4363 [(set_attr "predicable" "yes")
4364 (set_attr "predicable_short_it" "yes,no")
4365 (set_attr "arch" "t2,*")
4366 (set_attr "length" "4")
4367 (set_attr "type" "alu_sreg")]
4370 (define_expand "negsf2"
4371 [(set (match_operand:SF 0 "s_register_operand" "")
4372 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4373 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4377 (define_expand "negdf2"
4378 [(set (match_operand:DF 0 "s_register_operand" "")
4379 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4380 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4383 (define_insn_and_split "*zextendsidi_negsi"
4384 [(set (match_operand:DI 0 "s_register_operand" "=r")
4385 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4390 (neg:SI (match_dup 1)))
4394 operands[2] = gen_lowpart (SImode, operands[0]);
4395 operands[3] = gen_highpart (SImode, operands[0]);
4397 [(set_attr "length" "8")
4398 (set_attr "type" "multiple")]
4401 ;; Negate an extended 32-bit value.
4402 (define_insn_and_split "*negdi_extendsidi"
4403 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4404 (neg:DI (sign_extend:DI
4405 (match_operand:SI 1 "s_register_operand" "l,r"))))
4406 (clobber (reg:CC CC_REGNUM))]
4409 "&& reload_completed"
4412 rtx low = gen_lowpart (SImode, operands[0]);
4413 rtx high = gen_highpart (SImode, operands[0]);
4415 if (reg_overlap_mentioned_p (low, operands[1]))
4417 /* Input overlaps the low word of the output. Use:
4420 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4421 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4423 emit_insn (gen_rtx_SET (high,
4424 gen_rtx_ASHIFTRT (SImode, operands[1],
4427 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4429 emit_insn (gen_rtx_SET (high,
4430 gen_rtx_MINUS (SImode,
4431 gen_rtx_MINUS (SImode,
4434 gen_rtx_LTU (SImode,
4439 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4440 emit_insn (gen_rtx_SET (high,
4441 gen_rtx_MINUS (SImode,
4442 gen_rtx_MINUS (SImode,
4445 gen_rtx_LTU (SImode,
4452 /* No overlap, or overlap on high word. Use:
4456 Flags not needed for this sequence. */
4457 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4458 emit_insn (gen_rtx_SET (high,
4459 gen_rtx_AND (SImode,
4460 gen_rtx_NOT (SImode, operands[1]),
4462 emit_insn (gen_rtx_SET (high,
4463 gen_rtx_ASHIFTRT (SImode, high,
4468 [(set_attr "length" "12")
4469 (set_attr "arch" "t2,*")
4470 (set_attr "type" "multiple")]
4473 (define_insn_and_split "*negdi_zero_extendsidi"
4474 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4475 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4476 (clobber (reg:CC CC_REGNUM))]
4478 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4479 ;; Don't care what register is input to sbc,
4480 ;; since we just just need to propagate the carry.
4481 "&& reload_completed"
4482 [(parallel [(set (reg:CC CC_REGNUM)
4483 (compare:CC (const_int 0) (match_dup 1)))
4484 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4485 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4486 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4488 operands[2] = gen_highpart (SImode, operands[0]);
4489 operands[0] = gen_lowpart (SImode, operands[0]);
4491 [(set_attr "conds" "clob")
4492 (set_attr "length" "8")
4493 (set_attr "type" "multiple")] ;; length in thumb is 4
4496 ;; abssi2 doesn't really clobber the condition codes if a different register
4497 ;; is being set. To keep things simple, assume during rtl manipulations that
4498 ;; it does, but tell the final scan operator the truth. Similarly for
4501 (define_expand "abssi2"
4503 [(set (match_operand:SI 0 "s_register_operand" "")
4504 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4505 (clobber (match_dup 2))])]
4509 operands[2] = gen_rtx_SCRATCH (SImode);
4511 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4514 (define_insn_and_split "*arm_abssi2"
4515 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4516 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4517 (clobber (reg:CC CC_REGNUM))]
4520 "&& reload_completed"
4523 /* if (which_alternative == 0) */
4524 if (REGNO(operands[0]) == REGNO(operands[1]))
4526 /* Emit the pattern:
4527 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4528 [(set (reg:CC CC_REGNUM)
4529 (compare:CC (match_dup 0) (const_int 0)))
4530 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4531 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4533 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4534 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4535 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4536 (gen_rtx_LT (SImode,
4537 gen_rtx_REG (CCmode, CC_REGNUM),
4539 (gen_rtx_SET (operands[0],
4540 (gen_rtx_MINUS (SImode,
4547 /* Emit the pattern:
4548 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4550 (xor:SI (match_dup 1)
4551 (ashiftrt:SI (match_dup 1) (const_int 31))))
4553 (minus:SI (match_dup 0)
4554 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4556 emit_insn (gen_rtx_SET (operands[0],
4557 gen_rtx_XOR (SImode,
4558 gen_rtx_ASHIFTRT (SImode,
4562 emit_insn (gen_rtx_SET (operands[0],
4563 gen_rtx_MINUS (SImode,
4565 gen_rtx_ASHIFTRT (SImode,
4571 [(set_attr "conds" "clob,*")
4572 (set_attr "shift" "1")
4573 (set_attr "predicable" "no, yes")
4574 (set_attr "length" "8")
4575 (set_attr "type" "multiple")]
4578 (define_insn_and_split "*arm_neg_abssi2"
4579 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4580 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4581 (clobber (reg:CC CC_REGNUM))]
4584 "&& reload_completed"
4587 /* if (which_alternative == 0) */
4588 if (REGNO (operands[0]) == REGNO (operands[1]))
4590 /* Emit the pattern:
4591 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4593 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4594 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4595 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4597 gen_rtx_REG (CCmode, CC_REGNUM),
4599 gen_rtx_SET (operands[0],
4600 (gen_rtx_MINUS (SImode,
4606 /* Emit the pattern:
4607 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4609 emit_insn (gen_rtx_SET (operands[0],
4610 gen_rtx_XOR (SImode,
4611 gen_rtx_ASHIFTRT (SImode,
4615 emit_insn (gen_rtx_SET (operands[0],
4616 gen_rtx_MINUS (SImode,
4617 gen_rtx_ASHIFTRT (SImode,
4624 [(set_attr "conds" "clob,*")
4625 (set_attr "shift" "1")
4626 (set_attr "predicable" "no, yes")
4627 (set_attr "length" "8")
4628 (set_attr "type" "multiple")]
4631 (define_expand "abssf2"
4632 [(set (match_operand:SF 0 "s_register_operand" "")
4633 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4634 "TARGET_32BIT && TARGET_HARD_FLOAT"
4637 (define_expand "absdf2"
4638 [(set (match_operand:DF 0 "s_register_operand" "")
4639 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4640 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4643 (define_expand "sqrtsf2"
4644 [(set (match_operand:SF 0 "s_register_operand" "")
4645 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4646 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4649 (define_expand "sqrtdf2"
4650 [(set (match_operand:DF 0 "s_register_operand" "")
4651 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4652 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4655 (define_insn_and_split "one_cmpldi2"
4656 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4657 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4664 "TARGET_32BIT && reload_completed
4665 && arm_general_register_operand (operands[0], DImode)"
4666 [(set (match_dup 0) (not:SI (match_dup 1)))
4667 (set (match_dup 2) (not:SI (match_dup 3)))]
4670 operands[2] = gen_highpart (SImode, operands[0]);
4671 operands[0] = gen_lowpart (SImode, operands[0]);
4672 operands[3] = gen_highpart (SImode, operands[1]);
4673 operands[1] = gen_lowpart (SImode, operands[1]);
4675 [(set_attr "length" "*,8,8,*")
4676 (set_attr "predicable" "no,yes,yes,no")
4677 (set_attr "type" "neon_move,multiple,multiple,neon_move")
4678 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4681 (define_expand "one_cmplsi2"
4682 [(set (match_operand:SI 0 "s_register_operand" "")
4683 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4688 (define_insn "*arm_one_cmplsi2"
4689 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4690 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4693 [(set_attr "predicable" "yes")
4694 (set_attr "predicable_short_it" "yes,no")
4695 (set_attr "arch" "t2,*")
4696 (set_attr "length" "4")
4697 (set_attr "type" "mvn_reg")]
4700 (define_insn "*notsi_compare0"
4701 [(set (reg:CC_NOOV CC_REGNUM)
4702 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4704 (set (match_operand:SI 0 "s_register_operand" "=r")
4705 (not:SI (match_dup 1)))]
4708 [(set_attr "conds" "set")
4709 (set_attr "type" "mvn_reg")]
4712 (define_insn "*notsi_compare0_scratch"
4713 [(set (reg:CC_NOOV CC_REGNUM)
4714 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4716 (clobber (match_scratch:SI 0 "=r"))]
4719 [(set_attr "conds" "set")
4720 (set_attr "type" "mvn_reg")]
4723 ;; Fixed <--> Floating conversion insns
4725 (define_expand "floatsihf2"
4726 [(set (match_operand:HF 0 "general_operand" "")
4727 (float:HF (match_operand:SI 1 "general_operand" "")))]
4731 rtx op1 = gen_reg_rtx (SFmode);
4732 expand_float (op1, operands[1], 0);
4733 op1 = convert_to_mode (HFmode, op1, 0);
4734 emit_move_insn (operands[0], op1);
4739 (define_expand "floatdihf2"
4740 [(set (match_operand:HF 0 "general_operand" "")
4741 (float:HF (match_operand:DI 1 "general_operand" "")))]
4745 rtx op1 = gen_reg_rtx (SFmode);
4746 expand_float (op1, operands[1], 0);
4747 op1 = convert_to_mode (HFmode, op1, 0);
4748 emit_move_insn (operands[0], op1);
4753 (define_expand "floatsisf2"
4754 [(set (match_operand:SF 0 "s_register_operand" "")
4755 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
4756 "TARGET_32BIT && TARGET_HARD_FLOAT"
4760 (define_expand "floatsidf2"
4761 [(set (match_operand:DF 0 "s_register_operand" "")
4762 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
4763 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4767 (define_expand "fix_trunchfsi2"
4768 [(set (match_operand:SI 0 "general_operand" "")
4769 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4773 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4774 expand_fix (operands[0], op1, 0);
4779 (define_expand "fix_trunchfdi2"
4780 [(set (match_operand:DI 0 "general_operand" "")
4781 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4785 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4786 expand_fix (operands[0], op1, 0);
4791 (define_expand "fix_truncsfsi2"
4792 [(set (match_operand:SI 0 "s_register_operand" "")
4793 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
4794 "TARGET_32BIT && TARGET_HARD_FLOAT"
4798 (define_expand "fix_truncdfsi2"
4799 [(set (match_operand:SI 0 "s_register_operand" "")
4800 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
4801 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4807 (define_expand "truncdfsf2"
4808 [(set (match_operand:SF 0 "s_register_operand" "")
4810 (match_operand:DF 1 "s_register_operand" "")))]
4811 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4815 /* DFmode -> HFmode conversions have to go through SFmode. */
4816 (define_expand "truncdfhf2"
4817 [(set (match_operand:HF 0 "general_operand" "")
4819 (match_operand:DF 1 "general_operand" "")))]
4824 op1 = convert_to_mode (SFmode, operands[1], 0);
4825 op1 = convert_to_mode (HFmode, op1, 0);
4826 emit_move_insn (operands[0], op1);
4831 ;; Zero and sign extension instructions.
4833 (define_insn "zero_extend<mode>di2"
4834 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
4835 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4836 "<qhs_zextenddi_cstr>")))]
4837 "TARGET_32BIT <qhs_zextenddi_cond>"
4839 [(set_attr "length" "8,4,8,8")
4840 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
4841 (set_attr "ce_count" "2")
4842 (set_attr "predicable" "yes")
4843 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
4846 (define_insn "extend<mode>di2"
4847 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
4848 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4849 "<qhs_extenddi_cstr>")))]
4850 "TARGET_32BIT <qhs_sextenddi_cond>"
4852 [(set_attr "length" "8,4,8,8,8")
4853 (set_attr "ce_count" "2")
4854 (set_attr "shift" "1")
4855 (set_attr "predicable" "yes")
4856 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4857 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
4860 ;; Splits for all extensions to DImode
4862 [(set (match_operand:DI 0 "s_register_operand" "")
4863 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4864 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4865 [(set (match_dup 0) (match_dup 1))]
4867 rtx lo_part = gen_lowpart (SImode, operands[0]);
4868 machine_mode src_mode = GET_MODE (operands[1]);
4870 if (REG_P (operands[0])
4871 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4872 emit_clobber (operands[0]);
4873 if (!REG_P (lo_part) || src_mode != SImode
4874 || !rtx_equal_p (lo_part, operands[1]))
4876 if (src_mode == SImode)
4877 emit_move_insn (lo_part, operands[1]);
4879 emit_insn (gen_rtx_SET (lo_part,
4880 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4881 operands[1] = lo_part;
4883 operands[0] = gen_highpart (SImode, operands[0]);
4884 operands[1] = const0_rtx;
4888 [(set (match_operand:DI 0 "s_register_operand" "")
4889 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4890 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4891 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4893 rtx lo_part = gen_lowpart (SImode, operands[0]);
4894 machine_mode src_mode = GET_MODE (operands[1]);
4896 if (REG_P (operands[0])
4897 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4898 emit_clobber (operands[0]);
4900 if (!REG_P (lo_part) || src_mode != SImode
4901 || !rtx_equal_p (lo_part, operands[1]))
4903 if (src_mode == SImode)
4904 emit_move_insn (lo_part, operands[1]);
4906 emit_insn (gen_rtx_SET (lo_part,
4907 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4908 operands[1] = lo_part;
4910 operands[0] = gen_highpart (SImode, operands[0]);
4913 (define_expand "zero_extendhisi2"
4914 [(set (match_operand:SI 0 "s_register_operand" "")
4915 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4918 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4920 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4923 if (!arm_arch6 && !MEM_P (operands[1]))
4925 rtx t = gen_lowpart (SImode, operands[1]);
4926 rtx tmp = gen_reg_rtx (SImode);
4927 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4928 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4934 [(set (match_operand:SI 0 "s_register_operand" "")
4935 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4936 "!TARGET_THUMB2 && !arm_arch6"
4937 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4938 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4940 operands[2] = gen_lowpart (SImode, operands[1]);
4943 (define_insn "*arm_zero_extendhisi2"
4944 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4945 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4946 "TARGET_ARM && arm_arch4 && !arm_arch6"
4950 [(set_attr "type" "alu_shift_reg,load_byte")
4951 (set_attr "predicable" "yes")]
4954 (define_insn "*arm_zero_extendhisi2_v6"
4955 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4956 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4957 "TARGET_ARM && arm_arch6"
4961 [(set_attr "predicable" "yes")
4962 (set_attr "type" "extend,load_byte")]
4965 (define_insn "*arm_zero_extendhisi2addsi"
4966 [(set (match_operand:SI 0 "s_register_operand" "=r")
4967 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4968 (match_operand:SI 2 "s_register_operand" "r")))]
4970 "uxtah%?\\t%0, %2, %1"
4971 [(set_attr "type" "alu_shift_reg")
4972 (set_attr "predicable" "yes")
4973 (set_attr "predicable_short_it" "no")]
4976 (define_expand "zero_extendqisi2"
4977 [(set (match_operand:SI 0 "s_register_operand" "")
4978 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4981 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
4983 emit_insn (gen_andsi3 (operands[0],
4984 gen_lowpart (SImode, operands[1]),
4988 if (!arm_arch6 && !MEM_P (operands[1]))
4990 rtx t = gen_lowpart (SImode, operands[1]);
4991 rtx tmp = gen_reg_rtx (SImode);
4992 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
4993 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
4999 [(set (match_operand:SI 0 "s_register_operand" "")
5000 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5002 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5003 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5005 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5008 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5013 (define_insn "*arm_zero_extendqisi2"
5014 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5015 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5016 "TARGET_ARM && !arm_arch6"
5019 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5020 [(set_attr "length" "8,4")
5021 (set_attr "type" "alu_shift_reg,load_byte")
5022 (set_attr "predicable" "yes")]
5025 (define_insn "*arm_zero_extendqisi2_v6"
5026 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5027 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5028 "TARGET_ARM && arm_arch6"
5031 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5032 [(set_attr "type" "extend,load_byte")
5033 (set_attr "predicable" "yes")]
5036 (define_insn "*arm_zero_extendqisi2addsi"
5037 [(set (match_operand:SI 0 "s_register_operand" "=r")
5038 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5039 (match_operand:SI 2 "s_register_operand" "r")))]
5041 "uxtab%?\\t%0, %2, %1"
5042 [(set_attr "predicable" "yes")
5043 (set_attr "predicable_short_it" "no")
5044 (set_attr "type" "alu_shift_reg")]
5048 [(set (match_operand:SI 0 "s_register_operand" "")
5049 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5050 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5051 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5052 [(set (match_dup 2) (match_dup 1))
5053 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5058 [(set (match_operand:SI 0 "s_register_operand" "")
5059 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5060 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5061 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5062 [(set (match_dup 2) (match_dup 1))
5063 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5069 [(set (match_operand:SI 0 "s_register_operand" "")
5070 (IOR_XOR:SI (and:SI (ashift:SI
5071 (match_operand:SI 1 "s_register_operand" "")
5072 (match_operand:SI 2 "const_int_operand" ""))
5073 (match_operand:SI 3 "const_int_operand" ""))
5075 (match_operator 5 "subreg_lowpart_operator"
5076 [(match_operand:SI 4 "s_register_operand" "")]))))]
5078 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5079 == (GET_MODE_MASK (GET_MODE (operands[5]))
5080 & (GET_MODE_MASK (GET_MODE (operands[5]))
5081 << (INTVAL (operands[2])))))"
5082 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5084 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5085 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5088 (define_insn "*compareqi_eq0"
5089 [(set (reg:CC_Z CC_REGNUM)
5090 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5094 [(set_attr "conds" "set")
5095 (set_attr "predicable" "yes")
5096 (set_attr "predicable_short_it" "no")
5097 (set_attr "type" "logic_imm")]
5100 (define_expand "extendhisi2"
5101 [(set (match_operand:SI 0 "s_register_operand" "")
5102 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5107 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5110 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5112 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5116 if (!arm_arch6 && !MEM_P (operands[1]))
5118 rtx t = gen_lowpart (SImode, operands[1]);
5119 rtx tmp = gen_reg_rtx (SImode);
5120 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5121 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5128 [(set (match_operand:SI 0 "register_operand" "")
5129 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5130 (clobber (match_scratch:SI 2 ""))])]
5132 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5133 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5135 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5138 ;; This pattern will only be used when ldsh is not available
5139 (define_expand "extendhisi2_mem"
5140 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5142 (zero_extend:SI (match_dup 7)))
5143 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5144 (set (match_operand:SI 0 "" "")
5145 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5150 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5152 mem1 = change_address (operands[1], QImode, addr);
5153 mem2 = change_address (operands[1], QImode,
5154 plus_constant (Pmode, addr, 1));
5155 operands[0] = gen_lowpart (SImode, operands[0]);
5157 operands[2] = gen_reg_rtx (SImode);
5158 operands[3] = gen_reg_rtx (SImode);
5159 operands[6] = gen_reg_rtx (SImode);
5162 if (BYTES_BIG_ENDIAN)
5164 operands[4] = operands[2];
5165 operands[5] = operands[3];
5169 operands[4] = operands[3];
5170 operands[5] = operands[2];
5176 [(set (match_operand:SI 0 "register_operand" "")
5177 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5179 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5180 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5182 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5185 (define_insn "*arm_extendhisi2"
5186 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5187 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5188 "TARGET_ARM && arm_arch4 && !arm_arch6"
5192 [(set_attr "length" "8,4")
5193 (set_attr "type" "alu_shift_reg,load_byte")
5194 (set_attr "predicable" "yes")]
5197 ;; ??? Check Thumb-2 pool range
5198 (define_insn "*arm_extendhisi2_v6"
5199 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5200 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5201 "TARGET_32BIT && arm_arch6"
5205 [(set_attr "type" "extend,load_byte")
5206 (set_attr "predicable" "yes")
5207 (set_attr "predicable_short_it" "no")]
5210 (define_insn "*arm_extendhisi2addsi"
5211 [(set (match_operand:SI 0 "s_register_operand" "=r")
5212 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5213 (match_operand:SI 2 "s_register_operand" "r")))]
5215 "sxtah%?\\t%0, %2, %1"
5216 [(set_attr "type" "alu_shift_reg")]
5219 (define_expand "extendqihi2"
5221 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5223 (set (match_operand:HI 0 "s_register_operand" "")
5224 (ashiftrt:SI (match_dup 2)
5229 if (arm_arch4 && MEM_P (operands[1]))
5231 emit_insn (gen_rtx_SET (operands[0],
5232 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5235 if (!s_register_operand (operands[1], QImode))
5236 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5237 operands[0] = gen_lowpart (SImode, operands[0]);
5238 operands[1] = gen_lowpart (SImode, operands[1]);
5239 operands[2] = gen_reg_rtx (SImode);
5243 (define_insn "*arm_extendqihi_insn"
5244 [(set (match_operand:HI 0 "s_register_operand" "=r")
5245 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5246 "TARGET_ARM && arm_arch4"
5247 "ldr%(sb%)\\t%0, %1"
5248 [(set_attr "type" "load_byte")
5249 (set_attr "predicable" "yes")]
5252 (define_expand "extendqisi2"
5253 [(set (match_operand:SI 0 "s_register_operand" "")
5254 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5257 if (!arm_arch4 && MEM_P (operands[1]))
5258 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5260 if (!arm_arch6 && !MEM_P (operands[1]))
5262 rtx t = gen_lowpart (SImode, operands[1]);
5263 rtx tmp = gen_reg_rtx (SImode);
5264 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5265 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5271 [(set (match_operand:SI 0 "register_operand" "")
5272 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5274 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5275 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5277 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5280 (define_insn "*arm_extendqisi"
5281 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5282 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5283 "TARGET_ARM && arm_arch4 && !arm_arch6"
5287 [(set_attr "length" "8,4")
5288 (set_attr "type" "alu_shift_reg,load_byte")
5289 (set_attr "predicable" "yes")]
5292 (define_insn "*arm_extendqisi_v6"
5293 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5295 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5296 "TARGET_ARM && arm_arch6"
5300 [(set_attr "type" "extend,load_byte")
5301 (set_attr "predicable" "yes")]
5304 (define_insn "*arm_extendqisi2addsi"
5305 [(set (match_operand:SI 0 "s_register_operand" "=r")
5306 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5307 (match_operand:SI 2 "s_register_operand" "r")))]
5309 "sxtab%?\\t%0, %2, %1"
5310 [(set_attr "type" "alu_shift_reg")
5311 (set_attr "predicable" "yes")
5312 (set_attr "predicable_short_it" "no")]
5315 (define_expand "extendsfdf2"
5316 [(set (match_operand:DF 0 "s_register_operand" "")
5317 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5318 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5322 /* HFmode -> DFmode conversions have to go through SFmode. */
5323 (define_expand "extendhfdf2"
5324 [(set (match_operand:DF 0 "general_operand" "")
5325 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5330 op1 = convert_to_mode (SFmode, operands[1], 0);
5331 op1 = convert_to_mode (DFmode, op1, 0);
5332 emit_insn (gen_movdf (operands[0], op1));
5337 ;; Move insns (including loads and stores)
5339 ;; XXX Just some ideas about movti.
5340 ;; I don't think these are a good idea on the arm, there just aren't enough
5342 ;;(define_expand "loadti"
5343 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5344 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5347 ;;(define_expand "storeti"
5348 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5349 ;; (match_operand:TI 1 "s_register_operand" ""))]
5352 ;;(define_expand "movti"
5353 ;; [(set (match_operand:TI 0 "general_operand" "")
5354 ;; (match_operand:TI 1 "general_operand" ""))]
5360 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5361 ;; operands[1] = copy_to_reg (operands[1]);
5362 ;; if (MEM_P (operands[0]))
5363 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5364 ;; else if (MEM_P (operands[1]))
5365 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5369 ;; emit_insn (insn);
5373 ;; Recognize garbage generated above.
5376 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5377 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5381 ;; register mem = (which_alternative < 3);
5382 ;; register const char *template;
5384 ;; operands[mem] = XEXP (operands[mem], 0);
5385 ;; switch (which_alternative)
5387 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5388 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5389 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5390 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5391 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5392 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5394 ;; output_asm_insn (template, operands);
5398 (define_expand "movdi"
5399 [(set (match_operand:DI 0 "general_operand" "")
5400 (match_operand:DI 1 "general_operand" ""))]
5403 if (can_create_pseudo_p ())
5405 if (!REG_P (operands[0]))
5406 operands[1] = force_reg (DImode, operands[1]);
5411 (define_insn "*arm_movdi"
5412 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5413 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5415 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5417 && ( register_operand (operands[0], DImode)
5418 || register_operand (operands[1], DImode))"
5420 switch (which_alternative)
5427 return output_move_double (operands, true, NULL);
5430 [(set_attr "length" "8,12,16,8,8")
5431 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5432 (set_attr "arm_pool_range" "*,*,*,1020,*")
5433 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5434 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5435 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5439 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5440 (match_operand:ANY64 1 "immediate_operand" ""))]
5443 && (arm_const_double_inline_cost (operands[1])
5444 <= arm_max_const_double_inline_cost ())"
5447 arm_split_constant (SET, SImode, curr_insn,
5448 INTVAL (gen_lowpart (SImode, operands[1])),
5449 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5450 arm_split_constant (SET, SImode, curr_insn,
5451 INTVAL (gen_highpart_mode (SImode,
5452 GET_MODE (operands[0]),
5454 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5459 ; If optimizing for size, or if we have load delay slots, then
5460 ; we want to split the constant into two separate operations.
5461 ; In both cases this may split a trivial part into a single data op
5462 ; leaving a single complex constant to load. We can also get longer
5463 ; offsets in a LDR which means we get better chances of sharing the pool
5464 ; entries. Finally, we can normally do a better job of scheduling
5465 ; LDR instructions than we can with LDM.
5466 ; This pattern will only match if the one above did not.
5468 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5469 (match_operand:ANY64 1 "const_double_operand" ""))]
5470 "TARGET_ARM && reload_completed
5471 && arm_const_double_by_parts (operands[1])"
5472 [(set (match_dup 0) (match_dup 1))
5473 (set (match_dup 2) (match_dup 3))]
5475 operands[2] = gen_highpart (SImode, operands[0]);
5476 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5478 operands[0] = gen_lowpart (SImode, operands[0]);
5479 operands[1] = gen_lowpart (SImode, operands[1]);
5484 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5485 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5486 "TARGET_EITHER && reload_completed"
5487 [(set (match_dup 0) (match_dup 1))
5488 (set (match_dup 2) (match_dup 3))]
5490 operands[2] = gen_highpart (SImode, operands[0]);
5491 operands[3] = gen_highpart (SImode, operands[1]);
5492 operands[0] = gen_lowpart (SImode, operands[0]);
5493 operands[1] = gen_lowpart (SImode, operands[1]);
5495 /* Handle a partial overlap. */
5496 if (rtx_equal_p (operands[0], operands[3]))
5498 rtx tmp0 = operands[0];
5499 rtx tmp1 = operands[1];
5501 operands[0] = operands[2];
5502 operands[1] = operands[3];
5509 ;; We can't actually do base+index doubleword loads if the index and
5510 ;; destination overlap. Split here so that we at least have chance to
5513 [(set (match_operand:DI 0 "s_register_operand" "")
5514 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5515 (match_operand:SI 2 "s_register_operand" ""))))]
5517 && reg_overlap_mentioned_p (operands[0], operands[1])
5518 && reg_overlap_mentioned_p (operands[0], operands[2])"
5520 (plus:SI (match_dup 1)
5523 (mem:DI (match_dup 4)))]
5525 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5529 (define_expand "movsi"
5530 [(set (match_operand:SI 0 "general_operand" "")
5531 (match_operand:SI 1 "general_operand" ""))]
5535 rtx base, offset, tmp;
5539 /* Everything except mem = const or mem = mem can be done easily. */
5540 if (MEM_P (operands[0]))
5541 operands[1] = force_reg (SImode, operands[1]);
5542 if (arm_general_register_operand (operands[0], SImode)
5543 && CONST_INT_P (operands[1])
5544 && !(const_ok_for_arm (INTVAL (operands[1]))
5545 || const_ok_for_arm (~INTVAL (operands[1]))))
5547 arm_split_constant (SET, SImode, NULL_RTX,
5548 INTVAL (operands[1]), operands[0], NULL_RTX,
5549 optimize && can_create_pseudo_p ());
5553 else /* TARGET_THUMB1... */
5555 if (can_create_pseudo_p ())
5557 if (!REG_P (operands[0]))
5558 operands[1] = force_reg (SImode, operands[1]);
5562 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5564 split_const (operands[1], &base, &offset);
5565 if (GET_CODE (base) == SYMBOL_REF
5566 && !offset_within_block_p (base, INTVAL (offset)))
5568 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5569 emit_move_insn (tmp, base);
5570 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5575 /* Recognize the case where operand[1] is a reference to thread-local
5576 data and load its address to a register. */
5577 if (arm_tls_referenced_p (operands[1]))
5579 rtx tmp = operands[1];
5582 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5584 addend = XEXP (XEXP (tmp, 0), 1);
5585 tmp = XEXP (XEXP (tmp, 0), 0);
5588 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5589 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5591 tmp = legitimize_tls_address (tmp,
5592 !can_create_pseudo_p () ? operands[0] : 0);
5595 tmp = gen_rtx_PLUS (SImode, tmp, addend);
5596 tmp = force_operand (tmp, operands[0]);
5601 && (CONSTANT_P (operands[1])
5602 || symbol_mentioned_p (operands[1])
5603 || label_mentioned_p (operands[1])))
5604 operands[1] = legitimize_pic_address (operands[1], SImode,
5605 (!can_create_pseudo_p ()
5612 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5613 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5614 ;; so this does not matter.
5615 (define_insn "*arm_movt"
5616 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5617 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5618 (match_operand:SI 2 "general_operand" "i")))]
5620 "movt%?\t%0, #:upper16:%c2"
5621 [(set_attr "predicable" "yes")
5622 (set_attr "predicable_short_it" "no")
5623 (set_attr "length" "4")
5624 (set_attr "type" "alu_sreg")]
5627 (define_insn "*arm_movsi_insn"
5628 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5629 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
5630 "TARGET_ARM && ! TARGET_IWMMXT
5631 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5632 && ( register_operand (operands[0], SImode)
5633 || register_operand (operands[1], SImode))"
5641 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
5642 (set_attr "predicable" "yes")
5643 (set_attr "pool_range" "*,*,*,*,4096,*")
5644 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5648 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5649 (match_operand:SI 1 "const_int_operand" ""))]
5651 && (!(const_ok_for_arm (INTVAL (operands[1]))
5652 || const_ok_for_arm (~INTVAL (operands[1]))))"
5653 [(clobber (const_int 0))]
5655 arm_split_constant (SET, SImode, NULL_RTX,
5656 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5661 ;; A normal way to do (symbol + offset) requires three instructions at least
5662 ;; (depends on how big the offset is) as below:
5663 ;; movw r0, #:lower16:g
5664 ;; movw r0, #:upper16:g
5667 ;; A better way would be:
5668 ;; movw r0, #:lower16:g+4
5669 ;; movw r0, #:upper16:g+4
5671 ;; The limitation of this way is that the length of offset should be a 16-bit
5672 ;; signed value, because current assembler only supports REL type relocation for
5673 ;; such case. If the more powerful RELA type is supported in future, we should
5674 ;; update this pattern to go with better way.
5676 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5677 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5678 (match_operand:SI 2 "const_int_operand" ""))))]
5680 && arm_disable_literal_pool
5682 && GET_CODE (operands[1]) == SYMBOL_REF"
5683 [(clobber (const_int 0))]
5685 int offset = INTVAL (operands[2]);
5687 if (offset < -0x8000 || offset > 0x7fff)
5689 arm_emit_movpair (operands[0], operands[1]);
5690 emit_insn (gen_rtx_SET (operands[0],
5691 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5695 rtx op = gen_rtx_CONST (SImode,
5696 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5697 arm_emit_movpair (operands[0], op);
5702 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5703 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5704 ;; and lo_sum would be merged back into memory load at cprop. However,
5705 ;; if the default is to prefer movt/movw rather than a load from the constant
5706 ;; pool, the performance is better.
5708 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5709 (match_operand:SI 1 "general_operand" ""))]
5711 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5712 && !flag_pic && !target_word_relocations
5713 && !arm_tls_referenced_p (operands[1])"
5714 [(clobber (const_int 0))]
5716 arm_emit_movpair (operands[0], operands[1]);
5720 ;; When generating pic, we need to load the symbol offset into a register.
5721 ;; So that the optimizer does not confuse this with a normal symbol load
5722 ;; we use an unspec. The offset will be loaded from a constant pool entry,
5723 ;; since that is the only type of relocation we can use.
5725 ;; Wrap calculation of the whole PIC address in a single pattern for the
5726 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5727 ;; a PIC address involves two loads from memory, so we want to CSE it
5728 ;; as often as possible.
5729 ;; This pattern will be split into one of the pic_load_addr_* patterns
5730 ;; and a move after GCSE optimizations.
5732 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5733 (define_expand "calculate_pic_address"
5734 [(set (match_operand:SI 0 "register_operand" "")
5735 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5736 (unspec:SI [(match_operand:SI 2 "" "")]
5741 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5743 [(set (match_operand:SI 0 "register_operand" "")
5744 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5745 (unspec:SI [(match_operand:SI 2 "" "")]
5748 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5749 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5750 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5753 ;; operand1 is the memory address to go into
5754 ;; pic_load_addr_32bit.
5755 ;; operand2 is the PIC label to be emitted
5756 ;; from pic_add_dot_plus_eight.
5757 ;; We do this to allow hoisting of the entire insn.
5758 (define_insn_and_split "pic_load_addr_unified"
5759 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5760 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5761 (match_operand:SI 2 "" "")]
5762 UNSPEC_PIC_UNIFIED))]
5765 "&& reload_completed"
5766 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5767 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5768 (match_dup 2)] UNSPEC_PIC_BASE))]
5769 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5770 [(set_attr "type" "load1,load1,load1")
5771 (set_attr "pool_range" "4096,4094,1022")
5772 (set_attr "neg_pool_range" "4084,0,0")
5773 (set_attr "arch" "a,t2,t1")
5774 (set_attr "length" "8,6,4")]
5777 ;; The rather odd constraints on the following are to force reload to leave
5778 ;; the insn alone, and to force the minipool generation pass to then move
5779 ;; the GOT symbol to memory.
5781 (define_insn "pic_load_addr_32bit"
5782 [(set (match_operand:SI 0 "s_register_operand" "=r")
5783 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5784 "TARGET_32BIT && flag_pic"
5786 [(set_attr "type" "load1")
5787 (set (attr "pool_range")
5788 (if_then_else (eq_attr "is_thumb" "no")
5791 (set (attr "neg_pool_range")
5792 (if_then_else (eq_attr "is_thumb" "no")
5797 (define_insn "pic_load_addr_thumb1"
5798 [(set (match_operand:SI 0 "s_register_operand" "=l")
5799 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5800 "TARGET_THUMB1 && flag_pic"
5802 [(set_attr "type" "load1")
5803 (set (attr "pool_range") (const_int 1018))]
5806 (define_insn "pic_add_dot_plus_four"
5807 [(set (match_operand:SI 0 "register_operand" "=r")
5808 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5810 (match_operand 2 "" "")]
5814 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5815 INTVAL (operands[2]));
5816 return \"add\\t%0, %|pc\";
5818 [(set_attr "length" "2")
5819 (set_attr "type" "alu_sreg")]
5822 (define_insn "pic_add_dot_plus_eight"
5823 [(set (match_operand:SI 0 "register_operand" "=r")
5824 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5826 (match_operand 2 "" "")]
5830 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5831 INTVAL (operands[2]));
5832 return \"add%?\\t%0, %|pc, %1\";
5834 [(set_attr "predicable" "yes")
5835 (set_attr "type" "alu_sreg")]
5838 (define_insn "tls_load_dot_plus_eight"
5839 [(set (match_operand:SI 0 "register_operand" "=r")
5840 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5842 (match_operand 2 "" "")]
5846 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5847 INTVAL (operands[2]));
5848 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5850 [(set_attr "predicable" "yes")
5851 (set_attr "type" "load1")]
5854 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5855 ;; followed by a load. These sequences can be crunched down to
5856 ;; tls_load_dot_plus_eight by a peephole.
5859 [(set (match_operand:SI 0 "register_operand" "")
5860 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5862 (match_operand 1 "" "")]
5864 (set (match_operand:SI 2 "arm_general_register_operand" "")
5865 (mem:SI (match_dup 0)))]
5866 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5868 (mem:SI (unspec:SI [(match_dup 3)
5875 (define_insn "pic_offset_arm"
5876 [(set (match_operand:SI 0 "register_operand" "=r")
5877 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5878 (unspec:SI [(match_operand:SI 2 "" "X")]
5879 UNSPEC_PIC_OFFSET))))]
5880 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5881 "ldr%?\\t%0, [%1,%2]"
5882 [(set_attr "type" "load1")]
5885 (define_expand "builtin_setjmp_receiver"
5886 [(label_ref (match_operand 0 "" ""))]
5890 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5892 if (arm_pic_register != INVALID_REGNUM)
5893 arm_load_pic_register (1UL << 3);
5897 ;; If copying one reg to another we can set the condition codes according to
5898 ;; its value. Such a move is common after a return from subroutine and the
5899 ;; result is being tested against zero.
5901 (define_insn "*movsi_compare0"
5902 [(set (reg:CC CC_REGNUM)
5903 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5905 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5911 [(set_attr "conds" "set")
5912 (set_attr "type" "alus_imm,alus_imm")]
5915 ;; Subroutine to store a half word from a register into memory.
5916 ;; Operand 0 is the source register (HImode)
5917 ;; Operand 1 is the destination address in a register (SImode)
5919 ;; In both this routine and the next, we must be careful not to spill
5920 ;; a memory address of reg+large_const into a separate PLUS insn, since this
5921 ;; can generate unrecognizable rtl.
5923 (define_expand "storehi"
5924 [;; store the low byte
5925 (set (match_operand 1 "" "") (match_dup 3))
5926 ;; extract the high byte
5928 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5929 ;; store the high byte
5930 (set (match_dup 4) (match_dup 5))]
5934 rtx op1 = operands[1];
5935 rtx addr = XEXP (op1, 0);
5936 enum rtx_code code = GET_CODE (addr);
5938 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5940 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
5942 operands[4] = adjust_address (op1, QImode, 1);
5943 operands[1] = adjust_address (operands[1], QImode, 0);
5944 operands[3] = gen_lowpart (QImode, operands[0]);
5945 operands[0] = gen_lowpart (SImode, operands[0]);
5946 operands[2] = gen_reg_rtx (SImode);
5947 operands[5] = gen_lowpart (QImode, operands[2]);
5951 (define_expand "storehi_bigend"
5952 [(set (match_dup 4) (match_dup 3))
5954 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5955 (set (match_operand 1 "" "") (match_dup 5))]
5959 rtx op1 = operands[1];
5960 rtx addr = XEXP (op1, 0);
5961 enum rtx_code code = GET_CODE (addr);
5963 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5965 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
5967 operands[4] = adjust_address (op1, QImode, 1);
5968 operands[1] = adjust_address (operands[1], QImode, 0);
5969 operands[3] = gen_lowpart (QImode, operands[0]);
5970 operands[0] = gen_lowpart (SImode, operands[0]);
5971 operands[2] = gen_reg_rtx (SImode);
5972 operands[5] = gen_lowpart (QImode, operands[2]);
5976 ;; Subroutine to store a half word integer constant into memory.
5977 (define_expand "storeinthi"
5978 [(set (match_operand 0 "" "")
5979 (match_operand 1 "" ""))
5980 (set (match_dup 3) (match_dup 2))]
5984 HOST_WIDE_INT value = INTVAL (operands[1]);
5985 rtx addr = XEXP (operands[0], 0);
5986 rtx op0 = operands[0];
5987 enum rtx_code code = GET_CODE (addr);
5989 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5991 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
5993 operands[1] = gen_reg_rtx (SImode);
5994 if (BYTES_BIG_ENDIAN)
5996 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
5997 if ((value & 255) == ((value >> 8) & 255))
5998 operands[2] = operands[1];
6001 operands[2] = gen_reg_rtx (SImode);
6002 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6007 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6008 if ((value & 255) == ((value >> 8) & 255))
6009 operands[2] = operands[1];
6012 operands[2] = gen_reg_rtx (SImode);
6013 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6017 operands[3] = adjust_address (op0, QImode, 1);
6018 operands[0] = adjust_address (operands[0], QImode, 0);
6019 operands[2] = gen_lowpart (QImode, operands[2]);
6020 operands[1] = gen_lowpart (QImode, operands[1]);
6024 (define_expand "storehi_single_op"
6025 [(set (match_operand:HI 0 "memory_operand" "")
6026 (match_operand:HI 1 "general_operand" ""))]
6027 "TARGET_32BIT && arm_arch4"
6029 if (!s_register_operand (operands[1], HImode))
6030 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6034 (define_expand "movhi"
6035 [(set (match_operand:HI 0 "general_operand" "")
6036 (match_operand:HI 1 "general_operand" ""))]
6041 if (can_create_pseudo_p ())
6043 if (MEM_P (operands[0]))
6047 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6050 if (CONST_INT_P (operands[1]))
6051 emit_insn (gen_storeinthi (operands[0], operands[1]));
6054 if (MEM_P (operands[1]))
6055 operands[1] = force_reg (HImode, operands[1]);
6056 if (BYTES_BIG_ENDIAN)
6057 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6059 emit_insn (gen_storehi (operands[1], operands[0]));
6063 /* Sign extend a constant, and keep it in an SImode reg. */
6064 else if (CONST_INT_P (operands[1]))
6066 rtx reg = gen_reg_rtx (SImode);
6067 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6069 /* If the constant is already valid, leave it alone. */
6070 if (!const_ok_for_arm (val))
6072 /* If setting all the top bits will make the constant
6073 loadable in a single instruction, then set them.
6074 Otherwise, sign extend the number. */
6076 if (const_ok_for_arm (~(val | ~0xffff)))
6078 else if (val & 0x8000)
6082 emit_insn (gen_movsi (reg, GEN_INT (val)));
6083 operands[1] = gen_lowpart (HImode, reg);
6085 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6086 && MEM_P (operands[1]))
6088 rtx reg = gen_reg_rtx (SImode);
6090 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6091 operands[1] = gen_lowpart (HImode, reg);
6093 else if (!arm_arch4)
6095 if (MEM_P (operands[1]))
6098 rtx offset = const0_rtx;
6099 rtx reg = gen_reg_rtx (SImode);
6101 if ((REG_P (base = XEXP (operands[1], 0))
6102 || (GET_CODE (base) == PLUS
6103 && (CONST_INT_P (offset = XEXP (base, 1)))
6104 && ((INTVAL(offset) & 1) != 1)
6105 && REG_P (base = XEXP (base, 0))))
6106 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6110 new_rtx = widen_memory_access (operands[1], SImode,
6111 ((INTVAL (offset) & ~3)
6112 - INTVAL (offset)));
6113 emit_insn (gen_movsi (reg, new_rtx));
6114 if (((INTVAL (offset) & 2) != 0)
6115 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6117 rtx reg2 = gen_reg_rtx (SImode);
6119 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6124 emit_insn (gen_movhi_bytes (reg, operands[1]));
6126 operands[1] = gen_lowpart (HImode, reg);
6130 /* Handle loading a large integer during reload. */
6131 else if (CONST_INT_P (operands[1])
6132 && !const_ok_for_arm (INTVAL (operands[1]))
6133 && !const_ok_for_arm (~INTVAL (operands[1])))
6135 /* Writing a constant to memory needs a scratch, which should
6136 be handled with SECONDARY_RELOADs. */
6137 gcc_assert (REG_P (operands[0]));
6139 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6140 emit_insn (gen_movsi (operands[0], operands[1]));
6144 else if (TARGET_THUMB2)
6146 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6147 if (can_create_pseudo_p ())
6149 if (!REG_P (operands[0]))
6150 operands[1] = force_reg (HImode, operands[1]);
6151 /* Zero extend a constant, and keep it in an SImode reg. */
6152 else if (CONST_INT_P (operands[1]))
6154 rtx reg = gen_reg_rtx (SImode);
6155 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6157 emit_insn (gen_movsi (reg, GEN_INT (val)));
6158 operands[1] = gen_lowpart (HImode, reg);
6162 else /* TARGET_THUMB1 */
6164 if (can_create_pseudo_p ())
6166 if (CONST_INT_P (operands[1]))
6168 rtx reg = gen_reg_rtx (SImode);
6170 emit_insn (gen_movsi (reg, operands[1]));
6171 operands[1] = gen_lowpart (HImode, reg);
6174 /* ??? We shouldn't really get invalid addresses here, but this can
6175 happen if we are passed a SP (never OK for HImode/QImode) or
6176 virtual register (also rejected as illegitimate for HImode/QImode)
6177 relative address. */
6178 /* ??? This should perhaps be fixed elsewhere, for instance, in
6179 fixup_stack_1, by checking for other kinds of invalid addresses,
6180 e.g. a bare reference to a virtual register. This may confuse the
6181 alpha though, which must handle this case differently. */
6182 if (MEM_P (operands[0])
6183 && !memory_address_p (GET_MODE (operands[0]),
6184 XEXP (operands[0], 0)))
6186 = replace_equiv_address (operands[0],
6187 copy_to_reg (XEXP (operands[0], 0)));
6189 if (MEM_P (operands[1])
6190 && !memory_address_p (GET_MODE (operands[1]),
6191 XEXP (operands[1], 0)))
6193 = replace_equiv_address (operands[1],
6194 copy_to_reg (XEXP (operands[1], 0)));
6196 if (MEM_P (operands[1]) && optimize > 0)
6198 rtx reg = gen_reg_rtx (SImode);
6200 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6201 operands[1] = gen_lowpart (HImode, reg);
6204 if (MEM_P (operands[0]))
6205 operands[1] = force_reg (HImode, operands[1]);
6207 else if (CONST_INT_P (operands[1])
6208 && !satisfies_constraint_I (operands[1]))
6210 /* Handle loading a large integer during reload. */
6212 /* Writing a constant to memory needs a scratch, which should
6213 be handled with SECONDARY_RELOADs. */
6214 gcc_assert (REG_P (operands[0]));
6216 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6217 emit_insn (gen_movsi (operands[0], operands[1]));
6224 (define_expand "movhi_bytes"
6225 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6227 (zero_extend:SI (match_dup 6)))
6228 (set (match_operand:SI 0 "" "")
6229 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6234 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6236 mem1 = change_address (operands[1], QImode, addr);
6237 mem2 = change_address (operands[1], QImode,
6238 plus_constant (Pmode, addr, 1));
6239 operands[0] = gen_lowpart (SImode, operands[0]);
6241 operands[2] = gen_reg_rtx (SImode);
6242 operands[3] = gen_reg_rtx (SImode);
6245 if (BYTES_BIG_ENDIAN)
6247 operands[4] = operands[2];
6248 operands[5] = operands[3];
6252 operands[4] = operands[3];
6253 operands[5] = operands[2];
6258 (define_expand "movhi_bigend"
6260 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6263 (ashiftrt:SI (match_dup 2) (const_int 16)))
6264 (set (match_operand:HI 0 "s_register_operand" "")
6268 operands[2] = gen_reg_rtx (SImode);
6269 operands[3] = gen_reg_rtx (SImode);
6270 operands[4] = gen_lowpart (HImode, operands[3]);
6274 ;; Pattern to recognize insn generated default case above
6275 (define_insn "*movhi_insn_arch4"
6276 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6277 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6280 && (register_operand (operands[0], HImode)
6281 || register_operand (operands[1], HImode))"
6283 mov%?\\t%0, %1\\t%@ movhi
6284 mvn%?\\t%0, #%B1\\t%@ movhi
6285 movw%?\\t%0, %L1\\t%@ movhi
6286 str%(h%)\\t%1, %0\\t%@ movhi
6287 ldr%(h%)\\t%0, %1\\t%@ movhi"
6288 [(set_attr "predicable" "yes")
6289 (set_attr "pool_range" "*,*,*,*,256")
6290 (set_attr "neg_pool_range" "*,*,*,*,244")
6291 (set_attr "arch" "*,*,v6t2,*,*")
6292 (set_attr_alternative "type"
6293 [(if_then_else (match_operand 1 "const_int_operand" "")
6294 (const_string "mov_imm" )
6295 (const_string "mov_reg"))
6296 (const_string "mvn_imm")
6297 (const_string "mov_imm")
6298 (const_string "store1")
6299 (const_string "load1")])]
6302 (define_insn "*movhi_bytes"
6303 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6304 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6307 mov%?\\t%0, %1\\t%@ movhi
6308 mov%?\\t%0, %1\\t%@ movhi
6309 mvn%?\\t%0, #%B1\\t%@ movhi"
6310 [(set_attr "predicable" "yes")
6311 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6314 ;; We use a DImode scratch because we may occasionally need an additional
6315 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6316 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6317 (define_expand "reload_outhi"
6318 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6319 (match_operand:HI 1 "s_register_operand" "r")
6320 (match_operand:DI 2 "s_register_operand" "=&l")])]
6323 arm_reload_out_hi (operands);
6325 thumb_reload_out_hi (operands);
6330 (define_expand "reload_inhi"
6331 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6332 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6333 (match_operand:DI 2 "s_register_operand" "=&r")])]
6337 arm_reload_in_hi (operands);
6339 thumb_reload_out_hi (operands);
6343 (define_expand "movqi"
6344 [(set (match_operand:QI 0 "general_operand" "")
6345 (match_operand:QI 1 "general_operand" ""))]
6348 /* Everything except mem = const or mem = mem can be done easily */
6350 if (can_create_pseudo_p ())
6352 if (CONST_INT_P (operands[1]))
6354 rtx reg = gen_reg_rtx (SImode);
6356 /* For thumb we want an unsigned immediate, then we are more likely
6357 to be able to use a movs insn. */
6359 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6361 emit_insn (gen_movsi (reg, operands[1]));
6362 operands[1] = gen_lowpart (QImode, reg);
6367 /* ??? We shouldn't really get invalid addresses here, but this can
6368 happen if we are passed a SP (never OK for HImode/QImode) or
6369 virtual register (also rejected as illegitimate for HImode/QImode)
6370 relative address. */
6371 /* ??? This should perhaps be fixed elsewhere, for instance, in
6372 fixup_stack_1, by checking for other kinds of invalid addresses,
6373 e.g. a bare reference to a virtual register. This may confuse the
6374 alpha though, which must handle this case differently. */
6375 if (MEM_P (operands[0])
6376 && !memory_address_p (GET_MODE (operands[0]),
6377 XEXP (operands[0], 0)))
6379 = replace_equiv_address (operands[0],
6380 copy_to_reg (XEXP (operands[0], 0)));
6381 if (MEM_P (operands[1])
6382 && !memory_address_p (GET_MODE (operands[1]),
6383 XEXP (operands[1], 0)))
6385 = replace_equiv_address (operands[1],
6386 copy_to_reg (XEXP (operands[1], 0)));
6389 if (MEM_P (operands[1]) && optimize > 0)
6391 rtx reg = gen_reg_rtx (SImode);
6393 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6394 operands[1] = gen_lowpart (QImode, reg);
6397 if (MEM_P (operands[0]))
6398 operands[1] = force_reg (QImode, operands[1]);
6400 else if (TARGET_THUMB
6401 && CONST_INT_P (operands[1])
6402 && !satisfies_constraint_I (operands[1]))
6404 /* Handle loading a large integer during reload. */
6406 /* Writing a constant to memory needs a scratch, which should
6407 be handled with SECONDARY_RELOADs. */
6408 gcc_assert (REG_P (operands[0]));
6410 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6411 emit_insn (gen_movsi (operands[0], operands[1]));
6417 (define_insn "*arm_movqi_insn"
6418 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6419 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6421 && ( register_operand (operands[0], QImode)
6422 || register_operand (operands[1], QImode))"
6433 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6434 (set_attr "predicable" "yes")
6435 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6436 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6437 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6441 (define_expand "movhf"
6442 [(set (match_operand:HF 0 "general_operand" "")
6443 (match_operand:HF 1 "general_operand" ""))]
6448 if (MEM_P (operands[0]))
6449 operands[1] = force_reg (HFmode, operands[1]);
6451 else /* TARGET_THUMB1 */
6453 if (can_create_pseudo_p ())
6455 if (!REG_P (operands[0]))
6456 operands[1] = force_reg (HFmode, operands[1]);
6462 (define_insn "*arm32_movhf"
6463 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6464 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6465 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
6466 && ( s_register_operand (operands[0], HFmode)
6467 || s_register_operand (operands[1], HFmode))"
6469 switch (which_alternative)
6471 case 0: /* ARM register from memory */
6472 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6473 case 1: /* memory from ARM register */
6474 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6475 case 2: /* ARM register from ARM register */
6476 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6477 case 3: /* ARM register from constant */
6483 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6484 bits = real_to_target (NULL, &r, HFmode);
6485 ops[0] = operands[0];
6486 ops[1] = GEN_INT (bits);
6487 ops[2] = GEN_INT (bits & 0xff00);
6488 ops[3] = GEN_INT (bits & 0x00ff);
6490 if (arm_arch_thumb2)
6491 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6493 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6500 [(set_attr "conds" "unconditional")
6501 (set_attr "type" "load1,store1,mov_reg,multiple")
6502 (set_attr "length" "4,4,4,8")
6503 (set_attr "predicable" "yes")]
6506 (define_expand "movsf"
6507 [(set (match_operand:SF 0 "general_operand" "")
6508 (match_operand:SF 1 "general_operand" ""))]
6513 if (MEM_P (operands[0]))
6514 operands[1] = force_reg (SFmode, operands[1]);
6516 else /* TARGET_THUMB1 */
6518 if (can_create_pseudo_p ())
6520 if (!REG_P (operands[0]))
6521 operands[1] = force_reg (SFmode, operands[1]);
6527 ;; Transform a floating-point move of a constant into a core register into
6528 ;; an SImode operation.
6530 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6531 (match_operand:SF 1 "immediate_operand" ""))]
6534 && CONST_DOUBLE_P (operands[1])"
6535 [(set (match_dup 2) (match_dup 3))]
6537 operands[2] = gen_lowpart (SImode, operands[0]);
6538 operands[3] = gen_lowpart (SImode, operands[1]);
6539 if (operands[2] == 0 || operands[3] == 0)
6544 (define_insn "*arm_movsf_soft_insn"
6545 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6546 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6548 && TARGET_SOFT_FLOAT
6549 && (!MEM_P (operands[0])
6550 || register_operand (operands[1], SFmode))"
6553 ldr%?\\t%0, %1\\t%@ float
6554 str%?\\t%1, %0\\t%@ float"
6555 [(set_attr "predicable" "yes")
6556 (set_attr "predicable_short_it" "no")
6557 (set_attr "type" "mov_reg,load1,store1")
6558 (set_attr "arm_pool_range" "*,4096,*")
6559 (set_attr "thumb2_pool_range" "*,4094,*")
6560 (set_attr "arm_neg_pool_range" "*,4084,*")
6561 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6564 (define_expand "movdf"
6565 [(set (match_operand:DF 0 "general_operand" "")
6566 (match_operand:DF 1 "general_operand" ""))]
6571 if (MEM_P (operands[0]))
6572 operands[1] = force_reg (DFmode, operands[1]);
6574 else /* TARGET_THUMB */
6576 if (can_create_pseudo_p ())
6578 if (!REG_P (operands[0]))
6579 operands[1] = force_reg (DFmode, operands[1]);
6585 ;; Reloading a df mode value stored in integer regs to memory can require a
6587 (define_expand "reload_outdf"
6588 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6589 (match_operand:DF 1 "s_register_operand" "r")
6590 (match_operand:SI 2 "s_register_operand" "=&r")]
6594 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6597 operands[2] = XEXP (operands[0], 0);
6598 else if (code == POST_INC || code == PRE_DEC)
6600 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6601 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6602 emit_insn (gen_movdi (operands[0], operands[1]));
6605 else if (code == PRE_INC)
6607 rtx reg = XEXP (XEXP (operands[0], 0), 0);
6609 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6612 else if (code == POST_DEC)
6613 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6615 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6616 XEXP (XEXP (operands[0], 0), 1)));
6618 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
6621 if (code == POST_DEC)
6622 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6628 (define_insn "*movdf_soft_insn"
6629 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6630 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
6631 "TARGET_32BIT && TARGET_SOFT_FLOAT
6632 && ( register_operand (operands[0], DFmode)
6633 || register_operand (operands[1], DFmode))"
6635 switch (which_alternative)
6642 return output_move_double (operands, true, NULL);
6645 [(set_attr "length" "8,12,16,8,8")
6646 (set_attr "type" "multiple,multiple,multiple,load2,store2")
6647 (set_attr "arm_pool_range" "*,*,*,1020,*")
6648 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6649 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6650 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6654 ;; load- and store-multiple insns
6655 ;; The arm can load/store any set of registers, provided that they are in
6656 ;; ascending order, but these expanders assume a contiguous set.
6658 (define_expand "load_multiple"
6659 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6660 (match_operand:SI 1 "" ""))
6661 (use (match_operand:SI 2 "" ""))])]
6664 HOST_WIDE_INT offset = 0;
6666 /* Support only fixed point registers. */
6667 if (!CONST_INT_P (operands[2])
6668 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6669 || INTVAL (operands[2]) < 2
6670 || !MEM_P (operands[1])
6671 || !REG_P (operands[0])
6672 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6673 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6677 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6678 INTVAL (operands[2]),
6679 force_reg (SImode, XEXP (operands[1], 0)),
6680 FALSE, operands[1], &offset);
6683 (define_expand "store_multiple"
6684 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6685 (match_operand:SI 1 "" ""))
6686 (use (match_operand:SI 2 "" ""))])]
6689 HOST_WIDE_INT offset = 0;
6691 /* Support only fixed point registers. */
6692 if (!CONST_INT_P (operands[2])
6693 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6694 || INTVAL (operands[2]) < 2
6695 || !REG_P (operands[1])
6696 || !MEM_P (operands[0])
6697 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6698 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6702 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6703 INTVAL (operands[2]),
6704 force_reg (SImode, XEXP (operands[0], 0)),
6705 FALSE, operands[0], &offset);
6709 (define_expand "setmemsi"
6710 [(match_operand:BLK 0 "general_operand" "")
6711 (match_operand:SI 1 "const_int_operand" "")
6712 (match_operand:SI 2 "const_int_operand" "")
6713 (match_operand:SI 3 "const_int_operand" "")]
6716 if (arm_gen_setmem (operands))
6723 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6724 ;; We could let this apply for blocks of less than this, but it clobbers so
6725 ;; many registers that there is then probably a better way.
6727 (define_expand "movmemqi"
6728 [(match_operand:BLK 0 "general_operand" "")
6729 (match_operand:BLK 1 "general_operand" "")
6730 (match_operand:SI 2 "const_int_operand" "")
6731 (match_operand:SI 3 "const_int_operand" "")]
6736 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6737 && !optimize_function_for_size_p (cfun))
6739 if (gen_movmem_ldrd_strd (operands))
6744 if (arm_gen_movmemqi (operands))
6748 else /* TARGET_THUMB1 */
6750 if ( INTVAL (operands[3]) != 4
6751 || INTVAL (operands[2]) > 48)
6754 thumb_expand_movmemqi (operands);
6761 ;; Compare & branch insns
6762 ;; The range calculations are based as follows:
6763 ;; For forward branches, the address calculation returns the address of
6764 ;; the next instruction. This is 2 beyond the branch instruction.
6765 ;; For backward branches, the address calculation returns the address of
6766 ;; the first instruction in this pattern (cmp). This is 2 before the branch
6767 ;; instruction for the shortest sequence, and 4 before the branch instruction
6768 ;; if we have to jump around an unconditional branch.
6769 ;; To the basic branch range the PC offset must be added (this is +4).
6770 ;; So for forward branches we have
6771 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6772 ;; And for backward branches we have
6773 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6775 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6776 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
6778 (define_expand "cbranchsi4"
6779 [(set (pc) (if_then_else
6780 (match_operator 0 "expandable_comparison_operator"
6781 [(match_operand:SI 1 "s_register_operand" "")
6782 (match_operand:SI 2 "nonmemory_operand" "")])
6783 (label_ref (match_operand 3 "" ""))
6789 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6791 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6795 if (thumb1_cmpneg_operand (operands[2], SImode))
6797 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6798 operands[3], operands[0]));
6801 if (!thumb1_cmp_operand (operands[2], SImode))
6802 operands[2] = force_reg (SImode, operands[2]);
6805 (define_expand "cbranchsf4"
6806 [(set (pc) (if_then_else
6807 (match_operator 0 "expandable_comparison_operator"
6808 [(match_operand:SF 1 "s_register_operand" "")
6809 (match_operand:SF 2 "arm_float_compare_operand" "")])
6810 (label_ref (match_operand 3 "" ""))
6812 "TARGET_32BIT && TARGET_HARD_FLOAT"
6813 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6814 operands[3])); DONE;"
6817 (define_expand "cbranchdf4"
6818 [(set (pc) (if_then_else
6819 (match_operator 0 "expandable_comparison_operator"
6820 [(match_operand:DF 1 "s_register_operand" "")
6821 (match_operand:DF 2 "arm_float_compare_operand" "")])
6822 (label_ref (match_operand 3 "" ""))
6824 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6825 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6826 operands[3])); DONE;"
6829 (define_expand "cbranchdi4"
6830 [(set (pc) (if_then_else
6831 (match_operator 0 "expandable_comparison_operator"
6832 [(match_operand:DI 1 "s_register_operand" "")
6833 (match_operand:DI 2 "cmpdi_operand" "")])
6834 (label_ref (match_operand 3 "" ""))
6838 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6840 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6846 ;; Comparison and test insns
6848 (define_insn "*arm_cmpsi_insn"
6849 [(set (reg:CC CC_REGNUM)
6850 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6851 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
6859 [(set_attr "conds" "set")
6860 (set_attr "arch" "t2,t2,any,any,any")
6861 (set_attr "length" "2,2,4,4,4")
6862 (set_attr "predicable" "yes")
6863 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6864 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6867 (define_insn "*cmpsi_shiftsi"
6868 [(set (reg:CC CC_REGNUM)
6869 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
6870 (match_operator:SI 3 "shift_operator"
6871 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6872 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6875 [(set_attr "conds" "set")
6876 (set_attr "shift" "1")
6877 (set_attr "arch" "32,a,a")
6878 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6880 (define_insn "*cmpsi_shiftsi_swp"
6881 [(set (reg:CC_SWP CC_REGNUM)
6882 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6883 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6884 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6885 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6888 [(set_attr "conds" "set")
6889 (set_attr "shift" "1")
6890 (set_attr "arch" "32,a,a")
6891 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6893 (define_insn "*arm_cmpsi_negshiftsi_si"
6894 [(set (reg:CC_Z CC_REGNUM)
6896 (neg:SI (match_operator:SI 1 "shift_operator"
6897 [(match_operand:SI 2 "s_register_operand" "r")
6898 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6899 (match_operand:SI 0 "s_register_operand" "r")))]
6902 [(set_attr "conds" "set")
6903 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6904 (const_string "alus_shift_imm")
6905 (const_string "alus_shift_reg")))
6906 (set_attr "predicable" "yes")]
6909 ;; DImode comparisons. The generic code generates branches that
6910 ;; if-conversion can not reduce to a conditional compare, so we do
6913 (define_insn_and_split "*arm_cmpdi_insn"
6914 [(set (reg:CC_NCV CC_REGNUM)
6915 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6916 (match_operand:DI 1 "arm_di_operand" "rDi")))
6917 (clobber (match_scratch:SI 2 "=r"))]
6919 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6920 "&& reload_completed"
6921 [(set (reg:CC CC_REGNUM)
6922 (compare:CC (match_dup 0) (match_dup 1)))
6923 (parallel [(set (reg:CC CC_REGNUM)
6924 (compare:CC (match_dup 3) (match_dup 4)))
6926 (minus:SI (match_dup 5)
6927 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6929 operands[3] = gen_highpart (SImode, operands[0]);
6930 operands[0] = gen_lowpart (SImode, operands[0]);
6931 if (CONST_INT_P (operands[1]))
6933 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
6936 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
6940 operands[4] = gen_highpart (SImode, operands[1]);
6941 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6943 operands[1] = gen_lowpart (SImode, operands[1]);
6944 operands[2] = gen_lowpart (SImode, operands[2]);
6946 [(set_attr "conds" "set")
6947 (set_attr "length" "8")
6948 (set_attr "type" "multiple")]
6951 (define_insn_and_split "*arm_cmpdi_unsigned"
6952 [(set (reg:CC_CZ CC_REGNUM)
6953 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6954 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
6957 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6958 "&& reload_completed"
6959 [(set (reg:CC CC_REGNUM)
6960 (compare:CC (match_dup 2) (match_dup 3)))
6961 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6962 (set (reg:CC CC_REGNUM)
6963 (compare:CC (match_dup 0) (match_dup 1))))]
6965 operands[2] = gen_highpart (SImode, operands[0]);
6966 operands[0] = gen_lowpart (SImode, operands[0]);
6967 if (CONST_INT_P (operands[1]))
6968 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6970 operands[3] = gen_highpart (SImode, operands[1]);
6971 operands[1] = gen_lowpart (SImode, operands[1]);
6973 [(set_attr "conds" "set")
6974 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
6975 (set_attr "arch" "t2,t2,t2,a")
6976 (set_attr "length" "6,6,10,8")
6977 (set_attr "type" "multiple")]
6980 (define_insn "*arm_cmpdi_zero"
6981 [(set (reg:CC_Z CC_REGNUM)
6982 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6984 (clobber (match_scratch:SI 1 "=r"))]
6986 "orr%.\\t%1, %Q0, %R0"
6987 [(set_attr "conds" "set")
6988 (set_attr "type" "logics_reg")]
6991 ; This insn allows redundant compares to be removed by cse, nothing should
6992 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6993 ; is deleted later on. The match_dup will match the mode here, so that
6994 ; mode changes of the condition codes aren't lost by this even though we don't
6995 ; specify what they are.
6997 (define_insn "*deleted_compare"
6998 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7000 "\\t%@ deleted compare"
7001 [(set_attr "conds" "set")
7002 (set_attr "length" "0")
7003 (set_attr "type" "no_insn")]
7007 ;; Conditional branch insns
7009 (define_expand "cbranch_cc"
7011 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7012 (match_operand 2 "" "")])
7013 (label_ref (match_operand 3 "" ""))
7016 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7017 operands[1], operands[2], NULL_RTX);
7018 operands[2] = const0_rtx;"
7022 ;; Patterns to match conditional branch insns.
7025 (define_insn "arm_cond_branch"
7027 (if_then_else (match_operator 1 "arm_comparison_operator"
7028 [(match_operand 2 "cc_register" "") (const_int 0)])
7029 (label_ref (match_operand 0 "" ""))
7033 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7035 arm_ccfsm_state += 2;
7038 return \"b%d1\\t%l0\";
7040 [(set_attr "conds" "use")
7041 (set_attr "type" "branch")
7042 (set (attr "length")
7044 (and (match_test "TARGET_THUMB2")
7045 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7046 (le (minus (match_dup 0) (pc)) (const_int 256))))
7051 (define_insn "*arm_cond_branch_reversed"
7053 (if_then_else (match_operator 1 "arm_comparison_operator"
7054 [(match_operand 2 "cc_register" "") (const_int 0)])
7056 (label_ref (match_operand 0 "" ""))))]
7059 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7061 arm_ccfsm_state += 2;
7064 return \"b%D1\\t%l0\";
7066 [(set_attr "conds" "use")
7067 (set_attr "type" "branch")
7068 (set (attr "length")
7070 (and (match_test "TARGET_THUMB2")
7071 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7072 (le (minus (match_dup 0) (pc)) (const_int 256))))
7081 (define_expand "cstore_cc"
7082 [(set (match_operand:SI 0 "s_register_operand" "")
7083 (match_operator:SI 1 "" [(match_operand 2 "" "")
7084 (match_operand 3 "" "")]))]
7086 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7087 operands[2], operands[3], NULL_RTX);
7088 operands[3] = const0_rtx;"
7091 (define_insn_and_split "*mov_scc"
7092 [(set (match_operand:SI 0 "s_register_operand" "=r")
7093 (match_operator:SI 1 "arm_comparison_operator"
7094 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7096 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7099 (if_then_else:SI (match_dup 1)
7103 [(set_attr "conds" "use")
7104 (set_attr "length" "8")
7105 (set_attr "type" "multiple")]
7108 (define_insn_and_split "*mov_negscc"
7109 [(set (match_operand:SI 0 "s_register_operand" "=r")
7110 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7111 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7113 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7116 (if_then_else:SI (match_dup 1)
7120 operands[3] = GEN_INT (~0);
7122 [(set_attr "conds" "use")
7123 (set_attr "length" "8")
7124 (set_attr "type" "multiple")]
7127 (define_insn_and_split "*mov_notscc"
7128 [(set (match_operand:SI 0 "s_register_operand" "=r")
7129 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7130 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7132 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7135 (if_then_else:SI (match_dup 1)
7139 operands[3] = GEN_INT (~1);
7140 operands[4] = GEN_INT (~0);
7142 [(set_attr "conds" "use")
7143 (set_attr "length" "8")
7144 (set_attr "type" "multiple")]
7147 (define_expand "cstoresi4"
7148 [(set (match_operand:SI 0 "s_register_operand" "")
7149 (match_operator:SI 1 "expandable_comparison_operator"
7150 [(match_operand:SI 2 "s_register_operand" "")
7151 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7152 "TARGET_32BIT || TARGET_THUMB1"
7154 rtx op3, scratch, scratch2;
7158 if (!arm_add_operand (operands[3], SImode))
7159 operands[3] = force_reg (SImode, operands[3]);
7160 emit_insn (gen_cstore_cc (operands[0], operands[1],
7161 operands[2], operands[3]));
7165 if (operands[3] == const0_rtx)
7167 switch (GET_CODE (operands[1]))
7170 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7174 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7178 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7179 NULL_RTX, 0, OPTAB_WIDEN);
7180 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7181 NULL_RTX, 0, OPTAB_WIDEN);
7182 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7183 operands[0], 1, OPTAB_WIDEN);
7187 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7189 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7190 NULL_RTX, 1, OPTAB_WIDEN);
7194 scratch = expand_binop (SImode, ashr_optab, operands[2],
7195 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7196 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7197 NULL_RTX, 0, OPTAB_WIDEN);
7198 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7202 /* LT is handled by generic code. No need for unsigned with 0. */
7209 switch (GET_CODE (operands[1]))
7212 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7213 NULL_RTX, 0, OPTAB_WIDEN);
7214 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7218 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7219 NULL_RTX, 0, OPTAB_WIDEN);
7220 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7224 op3 = force_reg (SImode, operands[3]);
7226 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7227 NULL_RTX, 1, OPTAB_WIDEN);
7228 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7229 NULL_RTX, 0, OPTAB_WIDEN);
7230 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7236 if (!thumb1_cmp_operand (op3, SImode))
7237 op3 = force_reg (SImode, op3);
7238 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7239 NULL_RTX, 0, OPTAB_WIDEN);
7240 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7241 NULL_RTX, 1, OPTAB_WIDEN);
7242 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7247 op3 = force_reg (SImode, operands[3]);
7248 scratch = force_reg (SImode, const0_rtx);
7249 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7255 if (!thumb1_cmp_operand (op3, SImode))
7256 op3 = force_reg (SImode, op3);
7257 scratch = force_reg (SImode, const0_rtx);
7258 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7264 if (!thumb1_cmp_operand (op3, SImode))
7265 op3 = force_reg (SImode, op3);
7266 scratch = gen_reg_rtx (SImode);
7267 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7271 op3 = force_reg (SImode, operands[3]);
7272 scratch = gen_reg_rtx (SImode);
7273 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7276 /* No good sequences for GT, LT. */
7283 (define_expand "cstoresf4"
7284 [(set (match_operand:SI 0 "s_register_operand" "")
7285 (match_operator:SI 1 "expandable_comparison_operator"
7286 [(match_operand:SF 2 "s_register_operand" "")
7287 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7288 "TARGET_32BIT && TARGET_HARD_FLOAT"
7289 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7290 operands[2], operands[3])); DONE;"
7293 (define_expand "cstoredf4"
7294 [(set (match_operand:SI 0 "s_register_operand" "")
7295 (match_operator:SI 1 "expandable_comparison_operator"
7296 [(match_operand:DF 2 "s_register_operand" "")
7297 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7298 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7299 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7300 operands[2], operands[3])); DONE;"
7303 (define_expand "cstoredi4"
7304 [(set (match_operand:SI 0 "s_register_operand" "")
7305 (match_operator:SI 1 "expandable_comparison_operator"
7306 [(match_operand:DI 2 "s_register_operand" "")
7307 (match_operand:DI 3 "cmpdi_operand" "")]))]
7310 if (!arm_validize_comparison (&operands[1],
7314 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7321 ;; Conditional move insns
7323 (define_expand "movsicc"
7324 [(set (match_operand:SI 0 "s_register_operand" "")
7325 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7326 (match_operand:SI 2 "arm_not_operand" "")
7327 (match_operand:SI 3 "arm_not_operand" "")))]
7334 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7335 &XEXP (operands[1], 1)))
7338 code = GET_CODE (operands[1]);
7339 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7340 XEXP (operands[1], 1), NULL_RTX);
7341 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7345 (define_expand "movsfcc"
7346 [(set (match_operand:SF 0 "s_register_operand" "")
7347 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7348 (match_operand:SF 2 "s_register_operand" "")
7349 (match_operand:SF 3 "s_register_operand" "")))]
7350 "TARGET_32BIT && TARGET_HARD_FLOAT"
7353 enum rtx_code code = GET_CODE (operands[1]);
7356 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7357 &XEXP (operands[1], 1)))
7360 code = GET_CODE (operands[1]);
7361 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7362 XEXP (operands[1], 1), NULL_RTX);
7363 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7367 (define_expand "movdfcc"
7368 [(set (match_operand:DF 0 "s_register_operand" "")
7369 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7370 (match_operand:DF 2 "s_register_operand" "")
7371 (match_operand:DF 3 "s_register_operand" "")))]
7372 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7375 enum rtx_code code = GET_CODE (operands[1]);
7378 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7379 &XEXP (operands[1], 1)))
7381 code = GET_CODE (operands[1]);
7382 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7383 XEXP (operands[1], 1), NULL_RTX);
7384 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7388 (define_insn "*cmov<mode>"
7389 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7390 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7391 [(match_operand 2 "cc_register" "") (const_int 0)])
7392 (match_operand:SDF 3 "s_register_operand"
7394 (match_operand:SDF 4 "s_register_operand"
7395 "<F_constraint>")))]
7396 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7399 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7406 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7411 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7417 [(set_attr "conds" "use")
7418 (set_attr "type" "fcsel")]
7421 (define_insn_and_split "*movsicc_insn"
7422 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7424 (match_operator 3 "arm_comparison_operator"
7425 [(match_operand 4 "cc_register" "") (const_int 0)])
7426 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7427 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7438 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7439 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7440 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7441 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7442 "&& reload_completed"
7445 enum rtx_code rev_code;
7449 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7451 gen_rtx_SET (operands[0], operands[1])));
7453 rev_code = GET_CODE (operands[3]);
7454 mode = GET_MODE (operands[4]);
7455 if (mode == CCFPmode || mode == CCFPEmode)
7456 rev_code = reverse_condition_maybe_unordered (rev_code);
7458 rev_code = reverse_condition (rev_code);
7460 rev_cond = gen_rtx_fmt_ee (rev_code,
7464 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7466 gen_rtx_SET (operands[0], operands[2])));
7469 [(set_attr "length" "4,4,4,4,8,8,8,8")
7470 (set_attr "conds" "use")
7471 (set_attr_alternative "type"
7472 [(if_then_else (match_operand 2 "const_int_operand" "")
7473 (const_string "mov_imm")
7474 (const_string "mov_reg"))
7475 (const_string "mvn_imm")
7476 (if_then_else (match_operand 1 "const_int_operand" "")
7477 (const_string "mov_imm")
7478 (const_string "mov_reg"))
7479 (const_string "mvn_imm")
7480 (const_string "multiple")
7481 (const_string "multiple")
7482 (const_string "multiple")
7483 (const_string "multiple")])]
7486 (define_insn "*movsfcc_soft_insn"
7487 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7488 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7489 [(match_operand 4 "cc_register" "") (const_int 0)])
7490 (match_operand:SF 1 "s_register_operand" "0,r")
7491 (match_operand:SF 2 "s_register_operand" "r,0")))]
7492 "TARGET_ARM && TARGET_SOFT_FLOAT"
7496 [(set_attr "conds" "use")
7497 (set_attr "type" "mov_reg")]
7501 ;; Jump and linkage insns
7503 (define_expand "jump"
7505 (label_ref (match_operand 0 "" "")))]
7510 (define_insn "*arm_jump"
7512 (label_ref (match_operand 0 "" "")))]
7516 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7518 arm_ccfsm_state += 2;
7521 return \"b%?\\t%l0\";
7524 [(set_attr "predicable" "yes")
7525 (set (attr "length")
7527 (and (match_test "TARGET_THUMB2")
7528 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7529 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7532 (set_attr "type" "branch")]
7535 (define_expand "call"
7536 [(parallel [(call (match_operand 0 "memory_operand" "")
7537 (match_operand 1 "general_operand" ""))
7538 (use (match_operand 2 "" ""))
7539 (clobber (reg:SI LR_REGNUM))])]
7545 /* In an untyped call, we can get NULL for operand 2. */
7546 if (operands[2] == NULL_RTX)
7547 operands[2] = const0_rtx;
7549 /* Decide if we should generate indirect calls by loading the
7550 32-bit address of the callee into a register before performing the
7552 callee = XEXP (operands[0], 0);
7553 if (GET_CODE (callee) == SYMBOL_REF
7554 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7556 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7558 pat = gen_call_internal (operands[0], operands[1], operands[2]);
7559 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7564 (define_expand "call_internal"
7565 [(parallel [(call (match_operand 0 "memory_operand" "")
7566 (match_operand 1 "general_operand" ""))
7567 (use (match_operand 2 "" ""))
7568 (clobber (reg:SI LR_REGNUM))])])
7570 (define_insn "*call_reg_armv5"
7571 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7572 (match_operand 1 "" ""))
7573 (use (match_operand 2 "" ""))
7574 (clobber (reg:SI LR_REGNUM))]
7575 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7577 [(set_attr "type" "call")]
7580 (define_insn "*call_reg_arm"
7581 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7582 (match_operand 1 "" ""))
7583 (use (match_operand 2 "" ""))
7584 (clobber (reg:SI LR_REGNUM))]
7585 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7587 return output_call (operands);
7589 ;; length is worst case, normally it is only two
7590 [(set_attr "length" "12")
7591 (set_attr "type" "call")]
7595 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7596 ;; considered a function call by the branch predictor of some cores (PR40887).
7597 ;; Falls back to blx rN (*call_reg_armv5).
7599 (define_insn "*call_mem"
7600 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
7601 (match_operand 1 "" ""))
7602 (use (match_operand 2 "" ""))
7603 (clobber (reg:SI LR_REGNUM))]
7604 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7606 return output_call_mem (operands);
7608 [(set_attr "length" "12")
7609 (set_attr "type" "call")]
7612 (define_expand "call_value"
7613 [(parallel [(set (match_operand 0 "" "")
7614 (call (match_operand 1 "memory_operand" "")
7615 (match_operand 2 "general_operand" "")))
7616 (use (match_operand 3 "" ""))
7617 (clobber (reg:SI LR_REGNUM))])]
7623 /* In an untyped call, we can get NULL for operand 2. */
7624 if (operands[3] == 0)
7625 operands[3] = const0_rtx;
7627 /* Decide if we should generate indirect calls by loading the
7628 32-bit address of the callee into a register before performing the
7630 callee = XEXP (operands[1], 0);
7631 if (GET_CODE (callee) == SYMBOL_REF
7632 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7634 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7636 pat = gen_call_value_internal (operands[0], operands[1],
7637 operands[2], operands[3]);
7638 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7643 (define_expand "call_value_internal"
7644 [(parallel [(set (match_operand 0 "" "")
7645 (call (match_operand 1 "memory_operand" "")
7646 (match_operand 2 "general_operand" "")))
7647 (use (match_operand 3 "" ""))
7648 (clobber (reg:SI LR_REGNUM))])])
7650 (define_insn "*call_value_reg_armv5"
7651 [(set (match_operand 0 "" "")
7652 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7653 (match_operand 2 "" "")))
7654 (use (match_operand 3 "" ""))
7655 (clobber (reg:SI LR_REGNUM))]
7656 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7658 [(set_attr "type" "call")]
7661 (define_insn "*call_value_reg_arm"
7662 [(set (match_operand 0 "" "")
7663 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7664 (match_operand 2 "" "")))
7665 (use (match_operand 3 "" ""))
7666 (clobber (reg:SI LR_REGNUM))]
7667 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7669 return output_call (&operands[1]);
7671 [(set_attr "length" "12")
7672 (set_attr "type" "call")]
7675 ;; Note: see *call_mem
7677 (define_insn "*call_value_mem"
7678 [(set (match_operand 0 "" "")
7679 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
7680 (match_operand 2 "" "")))
7681 (use (match_operand 3 "" ""))
7682 (clobber (reg:SI LR_REGNUM))]
7683 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7684 && !SIBLING_CALL_P (insn)"
7686 return output_call_mem (&operands[1]);
7688 [(set_attr "length" "12")
7689 (set_attr "type" "call")]
7692 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7693 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7695 (define_insn "*call_symbol"
7696 [(call (mem:SI (match_operand:SI 0 "" ""))
7697 (match_operand 1 "" ""))
7698 (use (match_operand 2 "" ""))
7699 (clobber (reg:SI LR_REGNUM))]
7701 && !SIBLING_CALL_P (insn)
7702 && (GET_CODE (operands[0]) == SYMBOL_REF)
7703 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7706 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7708 [(set_attr "type" "call")]
7711 (define_insn "*call_value_symbol"
7712 [(set (match_operand 0 "" "")
7713 (call (mem:SI (match_operand:SI 1 "" ""))
7714 (match_operand:SI 2 "" "")))
7715 (use (match_operand 3 "" ""))
7716 (clobber (reg:SI LR_REGNUM))]
7718 && !SIBLING_CALL_P (insn)
7719 && (GET_CODE (operands[1]) == SYMBOL_REF)
7720 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7723 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7725 [(set_attr "type" "call")]
7728 (define_expand "sibcall_internal"
7729 [(parallel [(call (match_operand 0 "memory_operand" "")
7730 (match_operand 1 "general_operand" ""))
7732 (use (match_operand 2 "" ""))])])
7734 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7735 (define_expand "sibcall"
7736 [(parallel [(call (match_operand 0 "memory_operand" "")
7737 (match_operand 1 "general_operand" ""))
7739 (use (match_operand 2 "" ""))])]
7745 if ((!REG_P (XEXP (operands[0], 0))
7746 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7747 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7748 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7749 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7751 if (operands[2] == NULL_RTX)
7752 operands[2] = const0_rtx;
7754 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7755 arm_emit_call_insn (pat, operands[0], true);
7760 (define_expand "sibcall_value_internal"
7761 [(parallel [(set (match_operand 0 "" "")
7762 (call (match_operand 1 "memory_operand" "")
7763 (match_operand 2 "general_operand" "")))
7765 (use (match_operand 3 "" ""))])])
7767 (define_expand "sibcall_value"
7768 [(parallel [(set (match_operand 0 "" "")
7769 (call (match_operand 1 "memory_operand" "")
7770 (match_operand 2 "general_operand" "")))
7772 (use (match_operand 3 "" ""))])]
7778 if ((!REG_P (XEXP (operands[1], 0))
7779 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7780 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7781 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7782 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7784 if (operands[3] == NULL_RTX)
7785 operands[3] = const0_rtx;
7787 pat = gen_sibcall_value_internal (operands[0], operands[1],
7788 operands[2], operands[3]);
7789 arm_emit_call_insn (pat, operands[1], true);
7794 (define_insn "*sibcall_insn"
7795 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7796 (match_operand 1 "" ""))
7798 (use (match_operand 2 "" ""))]
7799 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7801 if (which_alternative == 1)
7802 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7805 if (arm_arch5 || arm_arch4t)
7806 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7808 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7811 [(set_attr "type" "call")]
7814 (define_insn "*sibcall_value_insn"
7815 [(set (match_operand 0 "" "")
7816 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7817 (match_operand 2 "" "")))
7819 (use (match_operand 3 "" ""))]
7820 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7822 if (which_alternative == 1)
7823 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7826 if (arm_arch5 || arm_arch4t)
7827 return \"bx%?\\t%1\";
7829 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7832 [(set_attr "type" "call")]
7835 (define_expand "<return_str>return"
7837 "(TARGET_ARM || (TARGET_THUMB2
7838 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7839 && !IS_STACKALIGN (arm_current_func_type ())))
7840 <return_cond_false>"
7845 thumb2_expand_return (<return_simple_p>);
7852 ;; Often the return insn will be the same as loading from memory, so set attr
7853 (define_insn "*arm_return"
7855 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7858 if (arm_ccfsm_state == 2)
7860 arm_ccfsm_state += 2;
7863 return output_return_instruction (const_true_rtx, true, false, false);
7865 [(set_attr "type" "load1")
7866 (set_attr "length" "12")
7867 (set_attr "predicable" "yes")]
7870 (define_insn "*cond_<return_str>return"
7872 (if_then_else (match_operator 0 "arm_comparison_operator"
7873 [(match_operand 1 "cc_register" "") (const_int 0)])
7876 "TARGET_ARM <return_cond_true>"
7879 if (arm_ccfsm_state == 2)
7881 arm_ccfsm_state += 2;
7884 return output_return_instruction (operands[0], true, false,
7887 [(set_attr "conds" "use")
7888 (set_attr "length" "12")
7889 (set_attr "type" "load1")]
7892 (define_insn "*cond_<return_str>return_inverted"
7894 (if_then_else (match_operator 0 "arm_comparison_operator"
7895 [(match_operand 1 "cc_register" "") (const_int 0)])
7898 "TARGET_ARM <return_cond_true>"
7901 if (arm_ccfsm_state == 2)
7903 arm_ccfsm_state += 2;
7906 return output_return_instruction (operands[0], true, true,
7909 [(set_attr "conds" "use")
7910 (set_attr "length" "12")
7911 (set_attr "type" "load1")]
7914 (define_insn "*arm_simple_return"
7919 if (arm_ccfsm_state == 2)
7921 arm_ccfsm_state += 2;
7924 return output_return_instruction (const_true_rtx, true, false, true);
7926 [(set_attr "type" "branch")
7927 (set_attr "length" "4")
7928 (set_attr "predicable" "yes")]
7931 ;; Generate a sequence of instructions to determine if the processor is
7932 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7935 (define_expand "return_addr_mask"
7937 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7939 (set (match_operand:SI 0 "s_register_operand" "")
7940 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7942 (const_int 67108860)))] ; 0x03fffffc
7945 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7948 (define_insn "*check_arch2"
7949 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7950 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7953 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7954 [(set_attr "length" "8")
7955 (set_attr "conds" "set")
7956 (set_attr "type" "multiple")]
7959 ;; Call subroutine returning any type.
7961 (define_expand "untyped_call"
7962 [(parallel [(call (match_operand 0 "" "")
7964 (match_operand 1 "" "")
7965 (match_operand 2 "" "")])]
7970 rtx par = gen_rtx_PARALLEL (VOIDmode,
7971 rtvec_alloc (XVECLEN (operands[2], 0)));
7972 rtx addr = gen_reg_rtx (Pmode);
7976 emit_move_insn (addr, XEXP (operands[1], 0));
7977 mem = change_address (operands[1], BLKmode, addr);
7979 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7981 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
7983 /* Default code only uses r0 as a return value, but we could
7984 be using anything up to 4 registers. */
7985 if (REGNO (src) == R0_REGNUM)
7986 src = gen_rtx_REG (TImode, R0_REGNUM);
7988 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
7990 size += GET_MODE_SIZE (GET_MODE (src));
7993 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
7998 for (i = 0; i < XVECLEN (par, 0); i++)
8000 HOST_WIDE_INT offset = 0;
8001 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8004 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8006 mem = change_address (mem, GET_MODE (reg), NULL);
8007 if (REGNO (reg) == R0_REGNUM)
8009 /* On thumb we have to use a write-back instruction. */
8010 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8011 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8012 size = TARGET_ARM ? 16 : 0;
8016 emit_move_insn (mem, reg);
8017 size = GET_MODE_SIZE (GET_MODE (reg));
8021 /* The optimizer does not know that the call sets the function value
8022 registers we stored in the result block. We avoid problems by
8023 claiming that all hard registers are used and clobbered at this
8025 emit_insn (gen_blockage ());
8031 (define_expand "untyped_return"
8032 [(match_operand:BLK 0 "memory_operand" "")
8033 (match_operand 1 "" "")]
8038 rtx addr = gen_reg_rtx (Pmode);
8042 emit_move_insn (addr, XEXP (operands[0], 0));
8043 mem = change_address (operands[0], BLKmode, addr);
8045 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8047 HOST_WIDE_INT offset = 0;
8048 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8051 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8053 mem = change_address (mem, GET_MODE (reg), NULL);
8054 if (REGNO (reg) == R0_REGNUM)
8056 /* On thumb we have to use a write-back instruction. */
8057 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8058 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8059 size = TARGET_ARM ? 16 : 0;
8063 emit_move_insn (reg, mem);
8064 size = GET_MODE_SIZE (GET_MODE (reg));
8068 /* Emit USE insns before the return. */
8069 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8070 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8072 /* Construct the return. */
8073 expand_naked_return ();
8079 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8080 ;; all of memory. This blocks insns from being moved across this point.
8082 (define_insn "blockage"
8083 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8086 [(set_attr "length" "0")
8087 (set_attr "type" "block")]
8090 (define_expand "casesi"
8091 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8092 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8093 (match_operand:SI 2 "const_int_operand" "") ; total range
8094 (match_operand:SI 3 "" "") ; table label
8095 (match_operand:SI 4 "" "")] ; Out of range label
8096 "TARGET_32BIT || optimize_size || flag_pic"
8099 enum insn_code code;
8100 if (operands[1] != const0_rtx)
8102 rtx reg = gen_reg_rtx (SImode);
8104 emit_insn (gen_addsi3 (reg, operands[0],
8105 gen_int_mode (-INTVAL (operands[1]),
8111 code = CODE_FOR_arm_casesi_internal;
8112 else if (TARGET_THUMB1)
8113 code = CODE_FOR_thumb1_casesi_internal_pic;
8115 code = CODE_FOR_thumb2_casesi_internal_pic;
8117 code = CODE_FOR_thumb2_casesi_internal;
8119 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8120 operands[2] = force_reg (SImode, operands[2]);
8122 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8123 operands[3], operands[4]));
8128 ;; The USE in this pattern is needed to tell flow analysis that this is
8129 ;; a CASESI insn. It has no other purpose.
8130 (define_insn "arm_casesi_internal"
8131 [(parallel [(set (pc)
8133 (leu (match_operand:SI 0 "s_register_operand" "r")
8134 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8135 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8136 (label_ref (match_operand 2 "" ""))))
8137 (label_ref (match_operand 3 "" ""))))
8138 (clobber (reg:CC CC_REGNUM))
8139 (use (label_ref (match_dup 2)))])]
8143 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8144 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8146 [(set_attr "conds" "clob")
8147 (set_attr "length" "12")
8148 (set_attr "type" "multiple")]
8151 (define_expand "indirect_jump"
8153 (match_operand:SI 0 "s_register_operand" ""))]
8156 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8157 address and use bx. */
8161 tmp = gen_reg_rtx (SImode);
8162 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8168 ;; NB Never uses BX.
8169 (define_insn "*arm_indirect_jump"
8171 (match_operand:SI 0 "s_register_operand" "r"))]
8173 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8174 [(set_attr "predicable" "yes")
8175 (set_attr "type" "branch")]
8178 (define_insn "*load_indirect_jump"
8180 (match_operand:SI 0 "memory_operand" "m"))]
8182 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8183 [(set_attr "type" "load1")
8184 (set_attr "pool_range" "4096")
8185 (set_attr "neg_pool_range" "4084")
8186 (set_attr "predicable" "yes")]
8196 if (TARGET_UNIFIED_ASM)
8199 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8200 return \"mov\\tr8, r8\";
8202 [(set (attr "length")
8203 (if_then_else (eq_attr "is_thumb" "yes")
8206 (set_attr "type" "mov_reg")]
8210 [(trap_if (const_int 1) (const_int 0))]
8214 return \".inst\\t0xe7f000f0\";
8216 return \".inst\\t0xdeff\";
8218 [(set (attr "length")
8219 (if_then_else (eq_attr "is_thumb" "yes")
8222 (set_attr "type" "trap")
8223 (set_attr "conds" "unconditional")]
8227 ;; Patterns to allow combination of arithmetic, cond code and shifts
8229 (define_insn "*<arith_shift_insn>_multsi"
8230 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8232 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8233 (match_operand:SI 3 "power_of_two_operand" ""))
8234 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8236 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8237 [(set_attr "predicable" "yes")
8238 (set_attr "predicable_short_it" "no")
8239 (set_attr "shift" "2")
8240 (set_attr "arch" "a,t2")
8241 (set_attr "type" "alu_shift_imm")])
8243 (define_insn "*<arith_shift_insn>_shiftsi"
8244 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8246 (match_operator:SI 2 "shift_nomul_operator"
8247 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8248 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8249 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8250 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8251 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8252 [(set_attr "predicable" "yes")
8253 (set_attr "predicable_short_it" "no")
8254 (set_attr "shift" "3")
8255 (set_attr "arch" "a,t2,a")
8256 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8259 [(set (match_operand:SI 0 "s_register_operand" "")
8260 (match_operator:SI 1 "shiftable_operator"
8261 [(match_operator:SI 2 "shiftable_operator"
8262 [(match_operator:SI 3 "shift_operator"
8263 [(match_operand:SI 4 "s_register_operand" "")
8264 (match_operand:SI 5 "reg_or_int_operand" "")])
8265 (match_operand:SI 6 "s_register_operand" "")])
8266 (match_operand:SI 7 "arm_rhs_operand" "")]))
8267 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8270 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8273 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8276 (define_insn "*arith_shiftsi_compare0"
8277 [(set (reg:CC_NOOV CC_REGNUM)
8279 (match_operator:SI 1 "shiftable_operator"
8280 [(match_operator:SI 3 "shift_operator"
8281 [(match_operand:SI 4 "s_register_operand" "r,r")
8282 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8283 (match_operand:SI 2 "s_register_operand" "r,r")])
8285 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8286 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8289 "%i1%.\\t%0, %2, %4%S3"
8290 [(set_attr "conds" "set")
8291 (set_attr "shift" "4")
8292 (set_attr "arch" "32,a")
8293 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8295 (define_insn "*arith_shiftsi_compare0_scratch"
8296 [(set (reg:CC_NOOV CC_REGNUM)
8298 (match_operator:SI 1 "shiftable_operator"
8299 [(match_operator:SI 3 "shift_operator"
8300 [(match_operand:SI 4 "s_register_operand" "r,r")
8301 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8302 (match_operand:SI 2 "s_register_operand" "r,r")])
8304 (clobber (match_scratch:SI 0 "=r,r"))]
8306 "%i1%.\\t%0, %2, %4%S3"
8307 [(set_attr "conds" "set")
8308 (set_attr "shift" "4")
8309 (set_attr "arch" "32,a")
8310 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8312 (define_insn "*sub_shiftsi"
8313 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8314 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8315 (match_operator:SI 2 "shift_operator"
8316 [(match_operand:SI 3 "s_register_operand" "r,r")
8317 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8319 "sub%?\\t%0, %1, %3%S2"
8320 [(set_attr "predicable" "yes")
8321 (set_attr "shift" "3")
8322 (set_attr "arch" "32,a")
8323 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8325 (define_insn "*sub_shiftsi_compare0"
8326 [(set (reg:CC_NOOV CC_REGNUM)
8328 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8329 (match_operator:SI 2 "shift_operator"
8330 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8331 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8333 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8334 (minus:SI (match_dup 1)
8335 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8337 "sub%.\\t%0, %1, %3%S2"
8338 [(set_attr "conds" "set")
8339 (set_attr "shift" "3")
8340 (set_attr "arch" "32,a,a")
8341 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8343 (define_insn "*sub_shiftsi_compare0_scratch"
8344 [(set (reg:CC_NOOV CC_REGNUM)
8346 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8347 (match_operator:SI 2 "shift_operator"
8348 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8349 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8351 (clobber (match_scratch:SI 0 "=r,r,r"))]
8353 "sub%.\\t%0, %1, %3%S2"
8354 [(set_attr "conds" "set")
8355 (set_attr "shift" "3")
8356 (set_attr "arch" "32,a,a")
8357 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8360 (define_insn_and_split "*and_scc"
8361 [(set (match_operand:SI 0 "s_register_operand" "=r")
8362 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8363 [(match_operand 2 "cc_register" "") (const_int 0)])
8364 (match_operand:SI 3 "s_register_operand" "r")))]
8366 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8367 "&& reload_completed"
8368 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8369 (cond_exec (match_dup 4) (set (match_dup 0)
8370 (and:SI (match_dup 3) (const_int 1))))]
8372 machine_mode mode = GET_MODE (operands[2]);
8373 enum rtx_code rc = GET_CODE (operands[1]);
8375 /* Note that operands[4] is the same as operands[1],
8376 but with VOIDmode as the result. */
8377 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8378 if (mode == CCFPmode || mode == CCFPEmode)
8379 rc = reverse_condition_maybe_unordered (rc);
8381 rc = reverse_condition (rc);
8382 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8384 [(set_attr "conds" "use")
8385 (set_attr "type" "multiple")
8386 (set_attr "length" "8")]
8389 (define_insn_and_split "*ior_scc"
8390 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8391 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8392 [(match_operand 2 "cc_register" "") (const_int 0)])
8393 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8398 "&& reload_completed
8399 && REGNO (operands [0]) != REGNO (operands[3])"
8400 ;; && which_alternative == 1
8401 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8402 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8403 (cond_exec (match_dup 4) (set (match_dup 0)
8404 (ior:SI (match_dup 3) (const_int 1))))]
8406 machine_mode mode = GET_MODE (operands[2]);
8407 enum rtx_code rc = GET_CODE (operands[1]);
8409 /* Note that operands[4] is the same as operands[1],
8410 but with VOIDmode as the result. */
8411 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8412 if (mode == CCFPmode || mode == CCFPEmode)
8413 rc = reverse_condition_maybe_unordered (rc);
8415 rc = reverse_condition (rc);
8416 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8418 [(set_attr "conds" "use")
8419 (set_attr "length" "4,8")
8420 (set_attr "type" "logic_imm,multiple")]
8423 ; A series of splitters for the compare_scc pattern below. Note that
8424 ; order is important.
8426 [(set (match_operand:SI 0 "s_register_operand" "")
8427 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8429 (clobber (reg:CC CC_REGNUM))]
8430 "TARGET_32BIT && reload_completed"
8431 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8434 [(set (match_operand:SI 0 "s_register_operand" "")
8435 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8437 (clobber (reg:CC CC_REGNUM))]
8438 "TARGET_32BIT && reload_completed"
8439 [(set (match_dup 0) (not:SI (match_dup 1)))
8440 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8443 [(set (match_operand:SI 0 "s_register_operand" "")
8444 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8446 (clobber (reg:CC CC_REGNUM))]
8447 "arm_arch5 && TARGET_32BIT"
8448 [(set (match_dup 0) (clz:SI (match_dup 1)))
8449 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8453 [(set (match_operand:SI 0 "s_register_operand" "")
8454 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8456 (clobber (reg:CC CC_REGNUM))]
8457 "TARGET_32BIT && reload_completed"
8459 [(set (reg:CC CC_REGNUM)
8460 (compare:CC (const_int 1) (match_dup 1)))
8462 (minus:SI (const_int 1) (match_dup 1)))])
8463 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8464 (set (match_dup 0) (const_int 0)))])
8467 [(set (match_operand:SI 0 "s_register_operand" "")
8468 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8469 (match_operand:SI 2 "const_int_operand" "")))
8470 (clobber (reg:CC CC_REGNUM))]
8471 "TARGET_32BIT && reload_completed"
8473 [(set (reg:CC CC_REGNUM)
8474 (compare:CC (match_dup 1) (match_dup 2)))
8475 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8476 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8477 (set (match_dup 0) (const_int 1)))]
8479 operands[3] = GEN_INT (-INTVAL (operands[2]));
8483 [(set (match_operand:SI 0 "s_register_operand" "")
8484 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8485 (match_operand:SI 2 "arm_add_operand" "")))
8486 (clobber (reg:CC CC_REGNUM))]
8487 "TARGET_32BIT && reload_completed"
8489 [(set (reg:CC_NOOV CC_REGNUM)
8490 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8492 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8493 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8494 (set (match_dup 0) (const_int 1)))])
8496 (define_insn_and_split "*compare_scc"
8497 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8498 (match_operator:SI 1 "arm_comparison_operator"
8499 [(match_operand:SI 2 "s_register_operand" "r,r")
8500 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8501 (clobber (reg:CC CC_REGNUM))]
8504 "&& reload_completed"
8505 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8506 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8507 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8510 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8511 operands[2], operands[3]);
8512 enum rtx_code rc = GET_CODE (operands[1]);
8514 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8516 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8517 if (mode == CCFPmode || mode == CCFPEmode)
8518 rc = reverse_condition_maybe_unordered (rc);
8520 rc = reverse_condition (rc);
8521 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8523 [(set_attr "type" "multiple")]
8526 ;; Attempt to improve the sequence generated by the compare_scc splitters
8527 ;; not to use conditional execution.
8529 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
8533 [(set (reg:CC CC_REGNUM)
8534 (compare:CC (match_operand:SI 1 "register_operand" "")
8536 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8537 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8538 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8539 (set (match_dup 0) (const_int 1)))]
8540 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8541 [(set (match_dup 0) (clz:SI (match_dup 1)))
8542 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8545 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8549 [(set (reg:CC CC_REGNUM)
8550 (compare:CC (match_operand:SI 1 "register_operand" "")
8552 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8553 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8554 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8555 (set (match_dup 0) (const_int 1)))
8556 (match_scratch:SI 2 "r")]
8557 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8559 [(set (reg:CC CC_REGNUM)
8560 (compare:CC (const_int 0) (match_dup 1)))
8561 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8563 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8564 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8567 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
8568 ;; sub Rd, Reg1, reg2
8572 [(set (reg:CC CC_REGNUM)
8573 (compare:CC (match_operand:SI 1 "register_operand" "")
8574 (match_operand:SI 2 "arm_rhs_operand" "")))
8575 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8576 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8577 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8578 (set (match_dup 0) (const_int 1)))]
8579 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8580 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8581 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8582 (set (match_dup 0) (clz:SI (match_dup 0)))
8583 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8587 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
8588 ;; sub T1, Reg1, reg2
8592 [(set (reg:CC CC_REGNUM)
8593 (compare:CC (match_operand:SI 1 "register_operand" "")
8594 (match_operand:SI 2 "arm_rhs_operand" "")))
8595 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8596 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8597 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8598 (set (match_dup 0) (const_int 1)))
8599 (match_scratch:SI 3 "r")]
8600 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8601 [(set (match_dup 3) (match_dup 4))
8603 [(set (reg:CC CC_REGNUM)
8604 (compare:CC (const_int 0) (match_dup 3)))
8605 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8607 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8608 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8610 if (CONST_INT_P (operands[2]))
8611 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8613 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8616 (define_insn "*cond_move"
8617 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8618 (if_then_else:SI (match_operator 3 "equality_operator"
8619 [(match_operator 4 "arm_comparison_operator"
8620 [(match_operand 5 "cc_register" "") (const_int 0)])
8622 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8623 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8626 if (GET_CODE (operands[3]) == NE)
8628 if (which_alternative != 1)
8629 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8630 if (which_alternative != 0)
8631 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8634 if (which_alternative != 0)
8635 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8636 if (which_alternative != 1)
8637 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8640 [(set_attr "conds" "use")
8641 (set_attr_alternative "type"
8642 [(if_then_else (match_operand 2 "const_int_operand" "")
8643 (const_string "mov_imm")
8644 (const_string "mov_reg"))
8645 (if_then_else (match_operand 1 "const_int_operand" "")
8646 (const_string "mov_imm")
8647 (const_string "mov_reg"))
8648 (const_string "multiple")])
8649 (set_attr "length" "4,4,8")]
8652 (define_insn "*cond_arith"
8653 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8654 (match_operator:SI 5 "shiftable_operator"
8655 [(match_operator:SI 4 "arm_comparison_operator"
8656 [(match_operand:SI 2 "s_register_operand" "r,r")
8657 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8658 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8659 (clobber (reg:CC CC_REGNUM))]
8662 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8663 return \"%i5\\t%0, %1, %2, lsr #31\";
8665 output_asm_insn (\"cmp\\t%2, %3\", operands);
8666 if (GET_CODE (operands[5]) == AND)
8667 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8668 else if (GET_CODE (operands[5]) == MINUS)
8669 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8670 else if (which_alternative != 0)
8671 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8672 return \"%i5%d4\\t%0, %1, #1\";
8674 [(set_attr "conds" "clob")
8675 (set_attr "length" "12")
8676 (set_attr "type" "multiple")]
8679 (define_insn "*cond_sub"
8680 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8681 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8682 (match_operator:SI 4 "arm_comparison_operator"
8683 [(match_operand:SI 2 "s_register_operand" "r,r")
8684 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8685 (clobber (reg:CC CC_REGNUM))]
8688 output_asm_insn (\"cmp\\t%2, %3\", operands);
8689 if (which_alternative != 0)
8690 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8691 return \"sub%d4\\t%0, %1, #1\";
8693 [(set_attr "conds" "clob")
8694 (set_attr "length" "8,12")
8695 (set_attr "type" "multiple")]
8698 (define_insn "*cmp_ite0"
8699 [(set (match_operand 6 "dominant_cc_register" "")
8702 (match_operator 4 "arm_comparison_operator"
8703 [(match_operand:SI 0 "s_register_operand"
8704 "l,l,l,r,r,r,r,r,r")
8705 (match_operand:SI 1 "arm_add_operand"
8706 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8707 (match_operator:SI 5 "arm_comparison_operator"
8708 [(match_operand:SI 2 "s_register_operand"
8709 "l,r,r,l,l,r,r,r,r")
8710 (match_operand:SI 3 "arm_add_operand"
8711 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8717 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8719 {\"cmp%d5\\t%0, %1\",
8720 \"cmp%d4\\t%2, %3\"},
8721 {\"cmn%d5\\t%0, #%n1\",
8722 \"cmp%d4\\t%2, %3\"},
8723 {\"cmp%d5\\t%0, %1\",
8724 \"cmn%d4\\t%2, #%n3\"},
8725 {\"cmn%d5\\t%0, #%n1\",
8726 \"cmn%d4\\t%2, #%n3\"}
8728 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8733 \"cmn\\t%0, #%n1\"},
8734 {\"cmn\\t%2, #%n3\",
8736 {\"cmn\\t%2, #%n3\",
8739 static const char * const ite[2] =
8744 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8745 CMP_CMP, CMN_CMP, CMP_CMP,
8746 CMN_CMP, CMP_CMN, CMN_CMN};
8748 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8750 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8751 if (TARGET_THUMB2) {
8752 output_asm_insn (ite[swap], operands);
8754 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8757 [(set_attr "conds" "set")
8758 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8759 (set_attr "type" "multiple")
8760 (set_attr_alternative "length"
8766 (if_then_else (eq_attr "is_thumb" "no")
8769 (if_then_else (eq_attr "is_thumb" "no")
8772 (if_then_else (eq_attr "is_thumb" "no")
8775 (if_then_else (eq_attr "is_thumb" "no")
8780 (define_insn "*cmp_ite1"
8781 [(set (match_operand 6 "dominant_cc_register" "")
8784 (match_operator 4 "arm_comparison_operator"
8785 [(match_operand:SI 0 "s_register_operand"
8786 "l,l,l,r,r,r,r,r,r")
8787 (match_operand:SI 1 "arm_add_operand"
8788 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8789 (match_operator:SI 5 "arm_comparison_operator"
8790 [(match_operand:SI 2 "s_register_operand"
8791 "l,r,r,l,l,r,r,r,r")
8792 (match_operand:SI 3 "arm_add_operand"
8793 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8799 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8803 {\"cmn\\t%0, #%n1\",
8806 \"cmn\\t%2, #%n3\"},
8807 {\"cmn\\t%0, #%n1\",
8810 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8812 {\"cmp%d4\\t%2, %3\",
8813 \"cmp%D5\\t%0, %1\"},
8814 {\"cmp%d4\\t%2, %3\",
8815 \"cmn%D5\\t%0, #%n1\"},
8816 {\"cmn%d4\\t%2, #%n3\",
8817 \"cmp%D5\\t%0, %1\"},
8818 {\"cmn%d4\\t%2, #%n3\",
8819 \"cmn%D5\\t%0, #%n1\"}
8821 static const char * const ite[2] =
8826 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8827 CMP_CMP, CMN_CMP, CMP_CMP,
8828 CMN_CMP, CMP_CMN, CMN_CMN};
8830 comparison_dominates_p (GET_CODE (operands[5]),
8831 reverse_condition (GET_CODE (operands[4])));
8833 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8834 if (TARGET_THUMB2) {
8835 output_asm_insn (ite[swap], operands);
8837 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8840 [(set_attr "conds" "set")
8841 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8842 (set_attr_alternative "length"
8848 (if_then_else (eq_attr "is_thumb" "no")
8851 (if_then_else (eq_attr "is_thumb" "no")
8854 (if_then_else (eq_attr "is_thumb" "no")
8857 (if_then_else (eq_attr "is_thumb" "no")
8860 (set_attr "type" "multiple")]
8863 (define_insn "*cmp_and"
8864 [(set (match_operand 6 "dominant_cc_register" "")
8867 (match_operator 4 "arm_comparison_operator"
8868 [(match_operand:SI 0 "s_register_operand"
8869 "l,l,l,r,r,r,r,r,r")
8870 (match_operand:SI 1 "arm_add_operand"
8871 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8872 (match_operator:SI 5 "arm_comparison_operator"
8873 [(match_operand:SI 2 "s_register_operand"
8874 "l,r,r,l,l,r,r,r,r")
8875 (match_operand:SI 3 "arm_add_operand"
8876 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8881 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8883 {\"cmp%d5\\t%0, %1\",
8884 \"cmp%d4\\t%2, %3\"},
8885 {\"cmn%d5\\t%0, #%n1\",
8886 \"cmp%d4\\t%2, %3\"},
8887 {\"cmp%d5\\t%0, %1\",
8888 \"cmn%d4\\t%2, #%n3\"},
8889 {\"cmn%d5\\t%0, #%n1\",
8890 \"cmn%d4\\t%2, #%n3\"}
8892 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8897 \"cmn\\t%0, #%n1\"},
8898 {\"cmn\\t%2, #%n3\",
8900 {\"cmn\\t%2, #%n3\",
8903 static const char *const ite[2] =
8908 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8909 CMP_CMP, CMN_CMP, CMP_CMP,
8910 CMN_CMP, CMP_CMN, CMN_CMN};
8912 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8914 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8915 if (TARGET_THUMB2) {
8916 output_asm_insn (ite[swap], operands);
8918 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8921 [(set_attr "conds" "set")
8922 (set_attr "predicable" "no")
8923 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8924 (set_attr_alternative "length"
8930 (if_then_else (eq_attr "is_thumb" "no")
8933 (if_then_else (eq_attr "is_thumb" "no")
8936 (if_then_else (eq_attr "is_thumb" "no")
8939 (if_then_else (eq_attr "is_thumb" "no")
8942 (set_attr "type" "multiple")]
8945 (define_insn "*cmp_ior"
8946 [(set (match_operand 6 "dominant_cc_register" "")
8949 (match_operator 4 "arm_comparison_operator"
8950 [(match_operand:SI 0 "s_register_operand"
8951 "l,l,l,r,r,r,r,r,r")
8952 (match_operand:SI 1 "arm_add_operand"
8953 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8954 (match_operator:SI 5 "arm_comparison_operator"
8955 [(match_operand:SI 2 "s_register_operand"
8956 "l,r,r,l,l,r,r,r,r")
8957 (match_operand:SI 3 "arm_add_operand"
8958 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8963 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8967 {\"cmn\\t%0, #%n1\",
8970 \"cmn\\t%2, #%n3\"},
8971 {\"cmn\\t%0, #%n1\",
8974 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8976 {\"cmp%D4\\t%2, %3\",
8977 \"cmp%D5\\t%0, %1\"},
8978 {\"cmp%D4\\t%2, %3\",
8979 \"cmn%D5\\t%0, #%n1\"},
8980 {\"cmn%D4\\t%2, #%n3\",
8981 \"cmp%D5\\t%0, %1\"},
8982 {\"cmn%D4\\t%2, #%n3\",
8983 \"cmn%D5\\t%0, #%n1\"}
8985 static const char *const ite[2] =
8990 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8991 CMP_CMP, CMN_CMP, CMP_CMP,
8992 CMN_CMP, CMP_CMN, CMN_CMN};
8994 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8996 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8997 if (TARGET_THUMB2) {
8998 output_asm_insn (ite[swap], operands);
9000 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9004 [(set_attr "conds" "set")
9005 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9006 (set_attr_alternative "length"
9012 (if_then_else (eq_attr "is_thumb" "no")
9015 (if_then_else (eq_attr "is_thumb" "no")
9018 (if_then_else (eq_attr "is_thumb" "no")
9021 (if_then_else (eq_attr "is_thumb" "no")
9024 (set_attr "type" "multiple")]
9027 (define_insn_and_split "*ior_scc_scc"
9028 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9029 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9030 [(match_operand:SI 1 "s_register_operand" "r")
9031 (match_operand:SI 2 "arm_add_operand" "rIL")])
9032 (match_operator:SI 6 "arm_comparison_operator"
9033 [(match_operand:SI 4 "s_register_operand" "r")
9034 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9035 (clobber (reg:CC CC_REGNUM))]
9037 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9040 "TARGET_32BIT && reload_completed"
9044 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9045 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9047 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9049 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9052 [(set_attr "conds" "clob")
9053 (set_attr "length" "16")
9054 (set_attr "type" "multiple")]
9057 ; If the above pattern is followed by a CMP insn, then the compare is
9058 ; redundant, since we can rework the conditional instruction that follows.
9059 (define_insn_and_split "*ior_scc_scc_cmp"
9060 [(set (match_operand 0 "dominant_cc_register" "")
9061 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9062 [(match_operand:SI 1 "s_register_operand" "r")
9063 (match_operand:SI 2 "arm_add_operand" "rIL")])
9064 (match_operator:SI 6 "arm_comparison_operator"
9065 [(match_operand:SI 4 "s_register_operand" "r")
9066 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9068 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9069 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9070 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9073 "TARGET_32BIT && reload_completed"
9077 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9078 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9080 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9082 [(set_attr "conds" "set")
9083 (set_attr "length" "16")
9084 (set_attr "type" "multiple")]
9087 (define_insn_and_split "*and_scc_scc"
9088 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9089 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9090 [(match_operand:SI 1 "s_register_operand" "r")
9091 (match_operand:SI 2 "arm_add_operand" "rIL")])
9092 (match_operator:SI 6 "arm_comparison_operator"
9093 [(match_operand:SI 4 "s_register_operand" "r")
9094 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9095 (clobber (reg:CC CC_REGNUM))]
9097 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9100 "TARGET_32BIT && reload_completed
9101 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9106 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9107 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9109 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9111 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9114 [(set_attr "conds" "clob")
9115 (set_attr "length" "16")
9116 (set_attr "type" "multiple")]
9119 ; If the above pattern is followed by a CMP insn, then the compare is
9120 ; redundant, since we can rework the conditional instruction that follows.
9121 (define_insn_and_split "*and_scc_scc_cmp"
9122 [(set (match_operand 0 "dominant_cc_register" "")
9123 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9124 [(match_operand:SI 1 "s_register_operand" "r")
9125 (match_operand:SI 2 "arm_add_operand" "rIL")])
9126 (match_operator:SI 6 "arm_comparison_operator"
9127 [(match_operand:SI 4 "s_register_operand" "r")
9128 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9130 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9131 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9132 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9135 "TARGET_32BIT && reload_completed"
9139 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9140 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9142 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9144 [(set_attr "conds" "set")
9145 (set_attr "length" "16")
9146 (set_attr "type" "multiple")]
9149 ;; If there is no dominance in the comparison, then we can still save an
9150 ;; instruction in the AND case, since we can know that the second compare
9151 ;; need only zero the value if false (if true, then the value is already
9153 (define_insn_and_split "*and_scc_scc_nodom"
9154 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9155 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9156 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9157 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9158 (match_operator:SI 6 "arm_comparison_operator"
9159 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9160 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9161 (clobber (reg:CC CC_REGNUM))]
9163 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9166 "TARGET_32BIT && reload_completed"
9167 [(parallel [(set (match_dup 0)
9168 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9169 (clobber (reg:CC CC_REGNUM))])
9170 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9172 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9175 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9176 operands[4], operands[5]),
9178 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9180 [(set_attr "conds" "clob")
9181 (set_attr "length" "20")
9182 (set_attr "type" "multiple")]
9186 [(set (reg:CC_NOOV CC_REGNUM)
9187 (compare:CC_NOOV (ior:SI
9188 (and:SI (match_operand:SI 0 "s_register_operand" "")
9190 (match_operator:SI 1 "arm_comparison_operator"
9191 [(match_operand:SI 2 "s_register_operand" "")
9192 (match_operand:SI 3 "arm_add_operand" "")]))
9194 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9197 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9199 (set (reg:CC_NOOV CC_REGNUM)
9200 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9205 [(set (reg:CC_NOOV CC_REGNUM)
9206 (compare:CC_NOOV (ior:SI
9207 (match_operator:SI 1 "arm_comparison_operator"
9208 [(match_operand:SI 2 "s_register_operand" "")
9209 (match_operand:SI 3 "arm_add_operand" "")])
9210 (and:SI (match_operand:SI 0 "s_register_operand" "")
9213 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9216 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9218 (set (reg:CC_NOOV CC_REGNUM)
9219 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9222 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9224 (define_insn_and_split "*negscc"
9225 [(set (match_operand:SI 0 "s_register_operand" "=r")
9226 (neg:SI (match_operator 3 "arm_comparison_operator"
9227 [(match_operand:SI 1 "s_register_operand" "r")
9228 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9229 (clobber (reg:CC CC_REGNUM))]
9232 "&& reload_completed"
9235 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9237 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9239 /* Emit mov\\t%0, %1, asr #31 */
9240 emit_insn (gen_rtx_SET (operands[0],
9241 gen_rtx_ASHIFTRT (SImode,
9246 else if (GET_CODE (operands[3]) == NE)
9248 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9249 if (CONST_INT_P (operands[2]))
9250 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9251 GEN_INT (- INTVAL (operands[2]))));
9253 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9255 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9259 gen_rtx_SET (operands[0],
9265 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9266 emit_insn (gen_rtx_SET (cc_reg,
9267 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9268 enum rtx_code rc = GET_CODE (operands[3]);
9270 rc = reverse_condition (rc);
9271 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9276 gen_rtx_SET (operands[0], const0_rtx)));
9277 rc = GET_CODE (operands[3]);
9278 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9283 gen_rtx_SET (operands[0],
9289 [(set_attr "conds" "clob")
9290 (set_attr "length" "12")
9291 (set_attr "type" "multiple")]
9294 (define_insn_and_split "movcond_addsi"
9295 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9297 (match_operator 5 "comparison_operator"
9298 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9299 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9301 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9302 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9303 (clobber (reg:CC CC_REGNUM))]
9306 "&& reload_completed"
9307 [(set (reg:CC_NOOV CC_REGNUM)
9309 (plus:SI (match_dup 3)
9312 (set (match_dup 0) (match_dup 1))
9313 (cond_exec (match_dup 6)
9314 (set (match_dup 0) (match_dup 2)))]
9317 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9318 operands[3], operands[4]);
9319 enum rtx_code rc = GET_CODE (operands[5]);
9320 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9321 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9322 if (REGNO (operands[2]) != REGNO (operands[0]))
9323 rc = reverse_condition (rc);
9325 std::swap (operands[1], operands[2]);
9327 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9330 [(set_attr "conds" "clob")
9331 (set_attr "enabled_for_depr_it" "no,yes,yes")
9332 (set_attr "type" "multiple")]
9335 (define_insn "movcond"
9336 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9338 (match_operator 5 "arm_comparison_operator"
9339 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9340 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9341 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9342 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9343 (clobber (reg:CC CC_REGNUM))]
9346 if (GET_CODE (operands[5]) == LT
9347 && (operands[4] == const0_rtx))
9349 if (which_alternative != 1 && REG_P (operands[1]))
9351 if (operands[2] == const0_rtx)
9352 return \"and\\t%0, %1, %3, asr #31\";
9353 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9355 else if (which_alternative != 0 && REG_P (operands[2]))
9357 if (operands[1] == const0_rtx)
9358 return \"bic\\t%0, %2, %3, asr #31\";
9359 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9361 /* The only case that falls through to here is when both ops 1 & 2
9365 if (GET_CODE (operands[5]) == GE
9366 && (operands[4] == const0_rtx))
9368 if (which_alternative != 1 && REG_P (operands[1]))
9370 if (operands[2] == const0_rtx)
9371 return \"bic\\t%0, %1, %3, asr #31\";
9372 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9374 else if (which_alternative != 0 && REG_P (operands[2]))
9376 if (operands[1] == const0_rtx)
9377 return \"and\\t%0, %2, %3, asr #31\";
9378 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9380 /* The only case that falls through to here is when both ops 1 & 2
9383 if (CONST_INT_P (operands[4])
9384 && !const_ok_for_arm (INTVAL (operands[4])))
9385 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9387 output_asm_insn (\"cmp\\t%3, %4\", operands);
9388 if (which_alternative != 0)
9389 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9390 if (which_alternative != 1)
9391 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9394 [(set_attr "conds" "clob")
9395 (set_attr "length" "8,8,12")
9396 (set_attr "type" "multiple")]
9399 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9401 (define_insn "*ifcompare_plus_move"
9402 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9403 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9404 [(match_operand:SI 4 "s_register_operand" "r,r")
9405 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9407 (match_operand:SI 2 "s_register_operand" "r,r")
9408 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9409 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9410 (clobber (reg:CC CC_REGNUM))]
9413 [(set_attr "conds" "clob")
9414 (set_attr "length" "8,12")
9415 (set_attr "type" "multiple")]
9418 (define_insn "*if_plus_move"
9419 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9421 (match_operator 4 "arm_comparison_operator"
9422 [(match_operand 5 "cc_register" "") (const_int 0)])
9424 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9425 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9426 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9430 sub%d4\\t%0, %2, #%n3
9431 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9432 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9433 [(set_attr "conds" "use")
9434 (set_attr "length" "4,4,8,8")
9435 (set_attr_alternative "type"
9436 [(if_then_else (match_operand 3 "const_int_operand" "")
9437 (const_string "alu_imm" )
9438 (const_string "alu_sreg"))
9439 (const_string "alu_imm")
9440 (const_string "multiple")
9441 (const_string "multiple")])]
9444 (define_insn "*ifcompare_move_plus"
9445 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9446 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9447 [(match_operand:SI 4 "s_register_operand" "r,r")
9448 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9449 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9451 (match_operand:SI 2 "s_register_operand" "r,r")
9452 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9453 (clobber (reg:CC CC_REGNUM))]
9456 [(set_attr "conds" "clob")
9457 (set_attr "length" "8,12")
9458 (set_attr "type" "multiple")]
9461 (define_insn "*if_move_plus"
9462 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9464 (match_operator 4 "arm_comparison_operator"
9465 [(match_operand 5 "cc_register" "") (const_int 0)])
9466 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9468 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9469 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9473 sub%D4\\t%0, %2, #%n3
9474 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9475 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9476 [(set_attr "conds" "use")
9477 (set_attr "length" "4,4,8,8")
9478 (set_attr_alternative "type"
9479 [(if_then_else (match_operand 3 "const_int_operand" "")
9480 (const_string "alu_imm" )
9481 (const_string "alu_sreg"))
9482 (const_string "alu_imm")
9483 (const_string "multiple")
9484 (const_string "multiple")])]
9487 (define_insn "*ifcompare_arith_arith"
9488 [(set (match_operand:SI 0 "s_register_operand" "=r")
9489 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9490 [(match_operand:SI 5 "s_register_operand" "r")
9491 (match_operand:SI 6 "arm_add_operand" "rIL")])
9492 (match_operator:SI 8 "shiftable_operator"
9493 [(match_operand:SI 1 "s_register_operand" "r")
9494 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9495 (match_operator:SI 7 "shiftable_operator"
9496 [(match_operand:SI 3 "s_register_operand" "r")
9497 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9498 (clobber (reg:CC CC_REGNUM))]
9501 [(set_attr "conds" "clob")
9502 (set_attr "length" "12")
9503 (set_attr "type" "multiple")]
9506 (define_insn "*if_arith_arith"
9507 [(set (match_operand:SI 0 "s_register_operand" "=r")
9508 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9509 [(match_operand 8 "cc_register" "") (const_int 0)])
9510 (match_operator:SI 6 "shiftable_operator"
9511 [(match_operand:SI 1 "s_register_operand" "r")
9512 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9513 (match_operator:SI 7 "shiftable_operator"
9514 [(match_operand:SI 3 "s_register_operand" "r")
9515 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9517 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9518 [(set_attr "conds" "use")
9519 (set_attr "length" "8")
9520 (set_attr "type" "multiple")]
9523 (define_insn "*ifcompare_arith_move"
9524 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9525 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9526 [(match_operand:SI 2 "s_register_operand" "r,r")
9527 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9528 (match_operator:SI 7 "shiftable_operator"
9529 [(match_operand:SI 4 "s_register_operand" "r,r")
9530 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9531 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9532 (clobber (reg:CC CC_REGNUM))]
9535 /* If we have an operation where (op x 0) is the identity operation and
9536 the conditional operator is LT or GE and we are comparing against zero and
9537 everything is in registers then we can do this in two instructions. */
9538 if (operands[3] == const0_rtx
9539 && GET_CODE (operands[7]) != AND
9540 && REG_P (operands[5])
9541 && REG_P (operands[1])
9542 && REGNO (operands[1]) == REGNO (operands[4])
9543 && REGNO (operands[4]) != REGNO (operands[0]))
9545 if (GET_CODE (operands[6]) == LT)
9546 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9547 else if (GET_CODE (operands[6]) == GE)
9548 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9550 if (CONST_INT_P (operands[3])
9551 && !const_ok_for_arm (INTVAL (operands[3])))
9552 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9554 output_asm_insn (\"cmp\\t%2, %3\", operands);
9555 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9556 if (which_alternative != 0)
9557 return \"mov%D6\\t%0, %1\";
9560 [(set_attr "conds" "clob")
9561 (set_attr "length" "8,12")
9562 (set_attr "type" "multiple")]
9565 (define_insn "*if_arith_move"
9566 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9567 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9568 [(match_operand 6 "cc_register" "") (const_int 0)])
9569 (match_operator:SI 5 "shiftable_operator"
9570 [(match_operand:SI 2 "s_register_operand" "r,r")
9571 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9572 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9576 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9577 [(set_attr "conds" "use")
9578 (set_attr "length" "4,8")
9579 (set_attr_alternative "type"
9580 [(if_then_else (match_operand 3 "const_int_operand" "")
9581 (const_string "alu_shift_imm" )
9582 (const_string "alu_shift_reg"))
9583 (const_string "multiple")])]
9586 (define_insn "*ifcompare_move_arith"
9587 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9588 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9589 [(match_operand:SI 4 "s_register_operand" "r,r")
9590 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9591 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9592 (match_operator:SI 7 "shiftable_operator"
9593 [(match_operand:SI 2 "s_register_operand" "r,r")
9594 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9595 (clobber (reg:CC CC_REGNUM))]
9598 /* If we have an operation where (op x 0) is the identity operation and
9599 the conditional operator is LT or GE and we are comparing against zero and
9600 everything is in registers then we can do this in two instructions */
9601 if (operands[5] == const0_rtx
9602 && GET_CODE (operands[7]) != AND
9603 && REG_P (operands[3])
9604 && REG_P (operands[1])
9605 && REGNO (operands[1]) == REGNO (operands[2])
9606 && REGNO (operands[2]) != REGNO (operands[0]))
9608 if (GET_CODE (operands[6]) == GE)
9609 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9610 else if (GET_CODE (operands[6]) == LT)
9611 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9614 if (CONST_INT_P (operands[5])
9615 && !const_ok_for_arm (INTVAL (operands[5])))
9616 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9618 output_asm_insn (\"cmp\\t%4, %5\", operands);
9620 if (which_alternative != 0)
9621 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9622 return \"%I7%D6\\t%0, %2, %3\";
9624 [(set_attr "conds" "clob")
9625 (set_attr "length" "8,12")
9626 (set_attr "type" "multiple")]
9629 (define_insn "*if_move_arith"
9630 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9632 (match_operator 4 "arm_comparison_operator"
9633 [(match_operand 6 "cc_register" "") (const_int 0)])
9634 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9635 (match_operator:SI 5 "shiftable_operator"
9636 [(match_operand:SI 2 "s_register_operand" "r,r")
9637 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9641 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9642 [(set_attr "conds" "use")
9643 (set_attr "length" "4,8")
9644 (set_attr_alternative "type"
9645 [(if_then_else (match_operand 3 "const_int_operand" "")
9646 (const_string "alu_shift_imm" )
9647 (const_string "alu_shift_reg"))
9648 (const_string "multiple")])]
9651 (define_insn "*ifcompare_move_not"
9652 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9654 (match_operator 5 "arm_comparison_operator"
9655 [(match_operand:SI 3 "s_register_operand" "r,r")
9656 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9657 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9659 (match_operand:SI 2 "s_register_operand" "r,r"))))
9660 (clobber (reg:CC CC_REGNUM))]
9663 [(set_attr "conds" "clob")
9664 (set_attr "length" "8,12")
9665 (set_attr "type" "multiple")]
9668 (define_insn "*if_move_not"
9669 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9671 (match_operator 4 "arm_comparison_operator"
9672 [(match_operand 3 "cc_register" "") (const_int 0)])
9673 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9674 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9678 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9679 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9680 [(set_attr "conds" "use")
9681 (set_attr "type" "mvn_reg")
9682 (set_attr "length" "4,8,8")
9683 (set_attr "type" "mvn_reg,multiple,multiple")]
9686 (define_insn "*ifcompare_not_move"
9687 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9689 (match_operator 5 "arm_comparison_operator"
9690 [(match_operand:SI 3 "s_register_operand" "r,r")
9691 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9693 (match_operand:SI 2 "s_register_operand" "r,r"))
9694 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9695 (clobber (reg:CC CC_REGNUM))]
9698 [(set_attr "conds" "clob")
9699 (set_attr "length" "8,12")
9700 (set_attr "type" "multiple")]
9703 (define_insn "*if_not_move"
9704 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9706 (match_operator 4 "arm_comparison_operator"
9707 [(match_operand 3 "cc_register" "") (const_int 0)])
9708 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9709 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9713 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9714 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9715 [(set_attr "conds" "use")
9716 (set_attr "type" "mvn_reg,multiple,multiple")
9717 (set_attr "length" "4,8,8")]
9720 (define_insn "*ifcompare_shift_move"
9721 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9723 (match_operator 6 "arm_comparison_operator"
9724 [(match_operand:SI 4 "s_register_operand" "r,r")
9725 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9726 (match_operator:SI 7 "shift_operator"
9727 [(match_operand:SI 2 "s_register_operand" "r,r")
9728 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9729 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9730 (clobber (reg:CC CC_REGNUM))]
9733 [(set_attr "conds" "clob")
9734 (set_attr "length" "8,12")
9735 (set_attr "type" "multiple")]
9738 (define_insn "*if_shift_move"
9739 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9741 (match_operator 5 "arm_comparison_operator"
9742 [(match_operand 6 "cc_register" "") (const_int 0)])
9743 (match_operator:SI 4 "shift_operator"
9744 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9745 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9746 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9750 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9751 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9752 [(set_attr "conds" "use")
9753 (set_attr "shift" "2")
9754 (set_attr "length" "4,8,8")
9755 (set_attr_alternative "type"
9756 [(if_then_else (match_operand 3 "const_int_operand" "")
9757 (const_string "mov_shift" )
9758 (const_string "mov_shift_reg"))
9759 (const_string "multiple")
9760 (const_string "multiple")])]
9763 (define_insn "*ifcompare_move_shift"
9764 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9766 (match_operator 6 "arm_comparison_operator"
9767 [(match_operand:SI 4 "s_register_operand" "r,r")
9768 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9769 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9770 (match_operator:SI 7 "shift_operator"
9771 [(match_operand:SI 2 "s_register_operand" "r,r")
9772 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9773 (clobber (reg:CC CC_REGNUM))]
9776 [(set_attr "conds" "clob")
9777 (set_attr "length" "8,12")
9778 (set_attr "type" "multiple")]
9781 (define_insn "*if_move_shift"
9782 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9784 (match_operator 5 "arm_comparison_operator"
9785 [(match_operand 6 "cc_register" "") (const_int 0)])
9786 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9787 (match_operator:SI 4 "shift_operator"
9788 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9789 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9793 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9794 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9795 [(set_attr "conds" "use")
9796 (set_attr "shift" "2")
9797 (set_attr "length" "4,8,8")
9798 (set_attr_alternative "type"
9799 [(if_then_else (match_operand 3 "const_int_operand" "")
9800 (const_string "mov_shift" )
9801 (const_string "mov_shift_reg"))
9802 (const_string "multiple")
9803 (const_string "multiple")])]
9806 (define_insn "*ifcompare_shift_shift"
9807 [(set (match_operand:SI 0 "s_register_operand" "=r")
9809 (match_operator 7 "arm_comparison_operator"
9810 [(match_operand:SI 5 "s_register_operand" "r")
9811 (match_operand:SI 6 "arm_add_operand" "rIL")])
9812 (match_operator:SI 8 "shift_operator"
9813 [(match_operand:SI 1 "s_register_operand" "r")
9814 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9815 (match_operator:SI 9 "shift_operator"
9816 [(match_operand:SI 3 "s_register_operand" "r")
9817 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9818 (clobber (reg:CC CC_REGNUM))]
9821 [(set_attr "conds" "clob")
9822 (set_attr "length" "12")
9823 (set_attr "type" "multiple")]
9826 (define_insn "*if_shift_shift"
9827 [(set (match_operand:SI 0 "s_register_operand" "=r")
9829 (match_operator 5 "arm_comparison_operator"
9830 [(match_operand 8 "cc_register" "") (const_int 0)])
9831 (match_operator:SI 6 "shift_operator"
9832 [(match_operand:SI 1 "s_register_operand" "r")
9833 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9834 (match_operator:SI 7 "shift_operator"
9835 [(match_operand:SI 3 "s_register_operand" "r")
9836 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9838 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9839 [(set_attr "conds" "use")
9840 (set_attr "shift" "1")
9841 (set_attr "length" "8")
9842 (set (attr "type") (if_then_else
9843 (and (match_operand 2 "const_int_operand" "")
9844 (match_operand 4 "const_int_operand" ""))
9845 (const_string "mov_shift")
9846 (const_string "mov_shift_reg")))]
9849 (define_insn "*ifcompare_not_arith"
9850 [(set (match_operand:SI 0 "s_register_operand" "=r")
9852 (match_operator 6 "arm_comparison_operator"
9853 [(match_operand:SI 4 "s_register_operand" "r")
9854 (match_operand:SI 5 "arm_add_operand" "rIL")])
9855 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9856 (match_operator:SI 7 "shiftable_operator"
9857 [(match_operand:SI 2 "s_register_operand" "r")
9858 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9859 (clobber (reg:CC CC_REGNUM))]
9862 [(set_attr "conds" "clob")
9863 (set_attr "length" "12")
9864 (set_attr "type" "multiple")]
9867 (define_insn "*if_not_arith"
9868 [(set (match_operand:SI 0 "s_register_operand" "=r")
9870 (match_operator 5 "arm_comparison_operator"
9871 [(match_operand 4 "cc_register" "") (const_int 0)])
9872 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9873 (match_operator:SI 6 "shiftable_operator"
9874 [(match_operand:SI 2 "s_register_operand" "r")
9875 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9877 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9878 [(set_attr "conds" "use")
9879 (set_attr "type" "mvn_reg")
9880 (set_attr "length" "8")]
9883 (define_insn "*ifcompare_arith_not"
9884 [(set (match_operand:SI 0 "s_register_operand" "=r")
9886 (match_operator 6 "arm_comparison_operator"
9887 [(match_operand:SI 4 "s_register_operand" "r")
9888 (match_operand:SI 5 "arm_add_operand" "rIL")])
9889 (match_operator:SI 7 "shiftable_operator"
9890 [(match_operand:SI 2 "s_register_operand" "r")
9891 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9892 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9893 (clobber (reg:CC CC_REGNUM))]
9896 [(set_attr "conds" "clob")
9897 (set_attr "length" "12")
9898 (set_attr "type" "multiple")]
9901 (define_insn "*if_arith_not"
9902 [(set (match_operand:SI 0 "s_register_operand" "=r")
9904 (match_operator 5 "arm_comparison_operator"
9905 [(match_operand 4 "cc_register" "") (const_int 0)])
9906 (match_operator:SI 6 "shiftable_operator"
9907 [(match_operand:SI 2 "s_register_operand" "r")
9908 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9909 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9911 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9912 [(set_attr "conds" "use")
9913 (set_attr "type" "multiple")
9914 (set_attr "length" "8")]
9917 (define_insn "*ifcompare_neg_move"
9918 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9920 (match_operator 5 "arm_comparison_operator"
9921 [(match_operand:SI 3 "s_register_operand" "r,r")
9922 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9923 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9924 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9925 (clobber (reg:CC CC_REGNUM))]
9928 [(set_attr "conds" "clob")
9929 (set_attr "length" "8,12")
9930 (set_attr "type" "multiple")]
9933 (define_insn "*if_neg_move"
9934 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9936 (match_operator 4 "arm_comparison_operator"
9937 [(match_operand 3 "cc_register" "") (const_int 0)])
9938 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9939 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9943 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9944 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9945 [(set_attr "conds" "use")
9946 (set_attr "length" "4,8,8")
9947 (set_attr "type" "logic_shift_imm,multiple,multiple")]
9950 (define_insn "*ifcompare_move_neg"
9951 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9953 (match_operator 5 "arm_comparison_operator"
9954 [(match_operand:SI 3 "s_register_operand" "r,r")
9955 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9956 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9957 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9958 (clobber (reg:CC CC_REGNUM))]
9961 [(set_attr "conds" "clob")
9962 (set_attr "length" "8,12")
9963 (set_attr "type" "multiple")]
9966 (define_insn "*if_move_neg"
9967 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9969 (match_operator 4 "arm_comparison_operator"
9970 [(match_operand 3 "cc_register" "") (const_int 0)])
9971 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9972 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9976 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9977 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9978 [(set_attr "conds" "use")
9979 (set_attr "length" "4,8,8")
9980 (set_attr "type" "logic_shift_imm,multiple,multiple")]
9983 (define_insn "*arith_adjacentmem"
9984 [(set (match_operand:SI 0 "s_register_operand" "=r")
9985 (match_operator:SI 1 "shiftable_operator"
9986 [(match_operand:SI 2 "memory_operand" "m")
9987 (match_operand:SI 3 "memory_operand" "m")]))
9988 (clobber (match_scratch:SI 4 "=r"))]
9989 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9995 HOST_WIDE_INT val1 = 0, val2 = 0;
9997 if (REGNO (operands[0]) > REGNO (operands[4]))
9999 ldm[1] = operands[4];
10000 ldm[2] = operands[0];
10004 ldm[1] = operands[0];
10005 ldm[2] = operands[4];
10008 base_reg = XEXP (operands[2], 0);
10010 if (!REG_P (base_reg))
10012 val1 = INTVAL (XEXP (base_reg, 1));
10013 base_reg = XEXP (base_reg, 0);
10016 if (!REG_P (XEXP (operands[3], 0)))
10017 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10019 arith[0] = operands[0];
10020 arith[3] = operands[1];
10034 if (val1 !=0 && val2 != 0)
10038 if (val1 == 4 || val2 == 4)
10039 /* Other val must be 8, since we know they are adjacent and neither
10041 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
10042 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10044 ldm[0] = ops[0] = operands[4];
10046 ops[2] = GEN_INT (val1);
10047 output_add_immediate (ops);
10049 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10051 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10055 /* Offset is out of range for a single add, so use two ldr. */
10058 ops[2] = GEN_INT (val1);
10059 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10061 ops[2] = GEN_INT (val2);
10062 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10065 else if (val1 != 0)
10068 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10070 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10075 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10077 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10079 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10082 [(set_attr "length" "12")
10083 (set_attr "predicable" "yes")
10084 (set_attr "type" "load1")]
10087 ; This pattern is never tried by combine, so do it as a peephole
10090 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10091 (match_operand:SI 1 "arm_general_register_operand" ""))
10092 (set (reg:CC CC_REGNUM)
10093 (compare:CC (match_dup 1) (const_int 0)))]
10095 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10096 (set (match_dup 0) (match_dup 1))])]
10101 [(set (match_operand:SI 0 "s_register_operand" "")
10102 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10104 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10105 [(match_operand:SI 3 "s_register_operand" "")
10106 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10107 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10109 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10110 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10115 ;; This split can be used because CC_Z mode implies that the following
10116 ;; branch will be an equality, or an unsigned inequality, so the sign
10117 ;; extension is not needed.
10120 [(set (reg:CC_Z CC_REGNUM)
10122 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10124 (match_operand 1 "const_int_operand" "")))
10125 (clobber (match_scratch:SI 2 ""))]
10127 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10128 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
10129 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10130 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10132 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10135 ;; ??? Check the patterns above for Thumb-2 usefulness
10137 (define_expand "prologue"
10138 [(clobber (const_int 0))]
10141 arm_expand_prologue ();
10143 thumb1_expand_prologue ();
10148 (define_expand "epilogue"
10149 [(clobber (const_int 0))]
10152 if (crtl->calls_eh_return)
10153 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10156 thumb1_expand_epilogue ();
10157 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10158 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10160 else if (HAVE_return)
10162 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10163 no need for explicit testing again. */
10164 emit_jump_insn (gen_return ());
10166 else if (TARGET_32BIT)
10168 arm_expand_epilogue (true);
10174 ;; Note - although unspec_volatile's USE all hard registers,
10175 ;; USEs are ignored after relaod has completed. Thus we need
10176 ;; to add an unspec of the link register to ensure that flow
10177 ;; does not think that it is unused by the sibcall branch that
10178 ;; will replace the standard function epilogue.
10179 (define_expand "sibcall_epilogue"
10180 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10181 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10184 arm_expand_epilogue (false);
10189 (define_expand "eh_epilogue"
10190 [(use (match_operand:SI 0 "register_operand" ""))
10191 (use (match_operand:SI 1 "register_operand" ""))
10192 (use (match_operand:SI 2 "register_operand" ""))]
10196 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10197 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10199 rtx ra = gen_rtx_REG (Pmode, 2);
10201 emit_move_insn (ra, operands[2]);
10204 /* This is a hack -- we may have crystalized the function type too
10206 cfun->machine->func_type = 0;
10210 ;; This split is only used during output to reduce the number of patterns
10211 ;; that need assembler instructions adding to them. We allowed the setting
10212 ;; of the conditions to be implicit during rtl generation so that
10213 ;; the conditional compare patterns would work. However this conflicts to
10214 ;; some extent with the conditional data operations, so we have to split them
10217 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10218 ;; conditional execution sufficient?
10221 [(set (match_operand:SI 0 "s_register_operand" "")
10222 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10223 [(match_operand 2 "" "") (match_operand 3 "" "")])
10225 (match_operand 4 "" "")))
10226 (clobber (reg:CC CC_REGNUM))]
10227 "TARGET_ARM && reload_completed"
10228 [(set (match_dup 5) (match_dup 6))
10229 (cond_exec (match_dup 7)
10230 (set (match_dup 0) (match_dup 4)))]
10233 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10234 operands[2], operands[3]);
10235 enum rtx_code rc = GET_CODE (operands[1]);
10237 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10238 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10239 if (mode == CCFPmode || mode == CCFPEmode)
10240 rc = reverse_condition_maybe_unordered (rc);
10242 rc = reverse_condition (rc);
10244 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10249 [(set (match_operand:SI 0 "s_register_operand" "")
10250 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10251 [(match_operand 2 "" "") (match_operand 3 "" "")])
10252 (match_operand 4 "" "")
10254 (clobber (reg:CC CC_REGNUM))]
10255 "TARGET_ARM && reload_completed"
10256 [(set (match_dup 5) (match_dup 6))
10257 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10258 (set (match_dup 0) (match_dup 4)))]
10261 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10262 operands[2], operands[3]);
10264 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10265 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10270 [(set (match_operand:SI 0 "s_register_operand" "")
10271 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10272 [(match_operand 2 "" "") (match_operand 3 "" "")])
10273 (match_operand 4 "" "")
10274 (match_operand 5 "" "")))
10275 (clobber (reg:CC CC_REGNUM))]
10276 "TARGET_ARM && reload_completed"
10277 [(set (match_dup 6) (match_dup 7))
10278 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10279 (set (match_dup 0) (match_dup 4)))
10280 (cond_exec (match_dup 8)
10281 (set (match_dup 0) (match_dup 5)))]
10284 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10285 operands[2], operands[3]);
10286 enum rtx_code rc = GET_CODE (operands[1]);
10288 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10289 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10290 if (mode == CCFPmode || mode == CCFPEmode)
10291 rc = reverse_condition_maybe_unordered (rc);
10293 rc = reverse_condition (rc);
10295 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10300 [(set (match_operand:SI 0 "s_register_operand" "")
10301 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10302 [(match_operand:SI 2 "s_register_operand" "")
10303 (match_operand:SI 3 "arm_add_operand" "")])
10304 (match_operand:SI 4 "arm_rhs_operand" "")
10306 (match_operand:SI 5 "s_register_operand" ""))))
10307 (clobber (reg:CC CC_REGNUM))]
10308 "TARGET_ARM && reload_completed"
10309 [(set (match_dup 6) (match_dup 7))
10310 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10311 (set (match_dup 0) (match_dup 4)))
10312 (cond_exec (match_dup 8)
10313 (set (match_dup 0) (not:SI (match_dup 5))))]
10316 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10317 operands[2], operands[3]);
10318 enum rtx_code rc = GET_CODE (operands[1]);
10320 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10321 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10322 if (mode == CCFPmode || mode == CCFPEmode)
10323 rc = reverse_condition_maybe_unordered (rc);
10325 rc = reverse_condition (rc);
10327 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10331 (define_insn "*cond_move_not"
10332 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10333 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10334 [(match_operand 3 "cc_register" "") (const_int 0)])
10335 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10337 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10341 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10342 [(set_attr "conds" "use")
10343 (set_attr "type" "mvn_reg,multiple")
10344 (set_attr "length" "4,8")]
10347 ;; The next two patterns occur when an AND operation is followed by a
10348 ;; scc insn sequence
10350 (define_insn "*sign_extract_onebit"
10351 [(set (match_operand:SI 0 "s_register_operand" "=r")
10352 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10354 (match_operand:SI 2 "const_int_operand" "n")))
10355 (clobber (reg:CC CC_REGNUM))]
10358 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10359 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10360 return \"mvnne\\t%0, #0\";
10362 [(set_attr "conds" "clob")
10363 (set_attr "length" "8")
10364 (set_attr "type" "multiple")]
10367 (define_insn "*not_signextract_onebit"
10368 [(set (match_operand:SI 0 "s_register_operand" "=r")
10370 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10372 (match_operand:SI 2 "const_int_operand" "n"))))
10373 (clobber (reg:CC CC_REGNUM))]
10376 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10377 output_asm_insn (\"tst\\t%1, %2\", operands);
10378 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10379 return \"movne\\t%0, #0\";
10381 [(set_attr "conds" "clob")
10382 (set_attr "length" "12")
10383 (set_attr "type" "multiple")]
10385 ;; ??? The above patterns need auditing for Thumb-2
10387 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10388 ;; expressions. For simplicity, the first register is also in the unspec
10390 ;; To avoid the usage of GNU extension, the length attribute is computed
10391 ;; in a C function arm_attr_length_push_multi.
10392 (define_insn "*push_multi"
10393 [(match_parallel 2 "multi_register_push"
10394 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10395 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10396 UNSPEC_PUSH_MULT))])]
10400 int num_saves = XVECLEN (operands[2], 0);
10402 /* For the StrongARM at least it is faster to
10403 use STR to store only a single register.
10404 In Thumb mode always use push, and the assembler will pick
10405 something appropriate. */
10406 if (num_saves == 1 && TARGET_ARM)
10407 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10414 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10415 else if (TARGET_THUMB2)
10416 strcpy (pattern, \"push%?\\t{%1\");
10418 strcpy (pattern, \"push\\t{%1\");
10420 for (i = 1; i < num_saves; i++)
10422 strcat (pattern, \", %|\");
10424 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10427 strcat (pattern, \"}\");
10428 output_asm_insn (pattern, operands);
10433 [(set_attr "type" "store4")
10434 (set (attr "length")
10435 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10438 (define_insn "stack_tie"
10439 [(set (mem:BLK (scratch))
10440 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10441 (match_operand:SI 1 "s_register_operand" "rk")]
10445 [(set_attr "length" "0")
10446 (set_attr "type" "block")]
10449 ;; Pop (as used in epilogue RTL)
10451 (define_insn "*load_multiple_with_writeback"
10452 [(match_parallel 0 "load_multiple_operation"
10453 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10454 (plus:SI (match_dup 1)
10455 (match_operand:SI 2 "const_int_I_operand" "I")))
10456 (set (match_operand:SI 3 "s_register_operand" "=rk")
10457 (mem:SI (match_dup 1)))
10459 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10462 arm_output_multireg_pop (operands, /*return_pc=*/false,
10463 /*cond=*/const_true_rtx,
10469 [(set_attr "type" "load4")
10470 (set_attr "predicable" "yes")]
10473 ;; Pop with return (as used in epilogue RTL)
10475 ;; This instruction is generated when the registers are popped at the end of
10476 ;; epilogue. Here, instead of popping the value into LR and then generating
10477 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10479 (define_insn "*pop_multiple_with_writeback_and_return"
10480 [(match_parallel 0 "pop_multiple_return"
10482 (set (match_operand:SI 1 "s_register_operand" "+rk")
10483 (plus:SI (match_dup 1)
10484 (match_operand:SI 2 "const_int_I_operand" "I")))
10485 (set (match_operand:SI 3 "s_register_operand" "=rk")
10486 (mem:SI (match_dup 1)))
10488 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10491 arm_output_multireg_pop (operands, /*return_pc=*/true,
10492 /*cond=*/const_true_rtx,
10498 [(set_attr "type" "load4")
10499 (set_attr "predicable" "yes")]
10502 (define_insn "*pop_multiple_with_return"
10503 [(match_parallel 0 "pop_multiple_return"
10505 (set (match_operand:SI 2 "s_register_operand" "=rk")
10506 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10508 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10511 arm_output_multireg_pop (operands, /*return_pc=*/true,
10512 /*cond=*/const_true_rtx,
10518 [(set_attr "type" "load4")
10519 (set_attr "predicable" "yes")]
10522 ;; Load into PC and return
10523 (define_insn "*ldr_with_return"
10525 (set (reg:SI PC_REGNUM)
10526 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10527 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10528 "ldr%?\t%|pc, [%0], #4"
10529 [(set_attr "type" "load1")
10530 (set_attr "predicable" "yes")]
10532 ;; Pop for floating point registers (as used in epilogue RTL)
10533 (define_insn "*vfp_pop_multiple_with_writeback"
10534 [(match_parallel 0 "pop_multiple_fp"
10535 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10536 (plus:SI (match_dup 1)
10537 (match_operand:SI 2 "const_int_I_operand" "I")))
10538 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10539 (mem:DF (match_dup 1)))])]
10540 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10543 int num_regs = XVECLEN (operands[0], 0);
10546 strcpy (pattern, \"vldm\\t\");
10547 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10548 strcat (pattern, \"!, {\");
10549 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10550 strcat (pattern, \"%P0\");
10551 if ((num_regs - 1) > 1)
10553 strcat (pattern, \"-%P1\");
10554 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10557 strcat (pattern, \"}\");
10558 output_asm_insn (pattern, op_list);
10562 [(set_attr "type" "load4")
10563 (set_attr "conds" "unconditional")
10564 (set_attr "predicable" "no")]
10567 ;; Special patterns for dealing with the constant pool
10569 (define_insn "align_4"
10570 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10573 assemble_align (32);
10576 [(set_attr "type" "no_insn")]
10579 (define_insn "align_8"
10580 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10583 assemble_align (64);
10586 [(set_attr "type" "no_insn")]
10589 (define_insn "consttable_end"
10590 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10593 making_const_table = FALSE;
10596 [(set_attr "type" "no_insn")]
10599 (define_insn "consttable_1"
10600 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10603 making_const_table = TRUE;
10604 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10605 assemble_zeros (3);
10608 [(set_attr "length" "4")
10609 (set_attr "type" "no_insn")]
10612 (define_insn "consttable_2"
10613 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10617 rtx x = operands[0];
10618 making_const_table = TRUE;
10619 switch (GET_MODE_CLASS (GET_MODE (x)))
10622 arm_emit_fp16_const (x);
10625 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10626 assemble_zeros (2);
10631 [(set_attr "length" "4")
10632 (set_attr "type" "no_insn")]
10635 (define_insn "consttable_4"
10636 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10640 rtx x = operands[0];
10641 making_const_table = TRUE;
10642 switch (GET_MODE_CLASS (GET_MODE (x)))
10647 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10648 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10652 /* XXX: Sometimes gcc does something really dumb and ends up with
10653 a HIGH in a constant pool entry, usually because it's trying to
10654 load into a VFP register. We know this will always be used in
10655 combination with a LO_SUM which ignores the high bits, so just
10656 strip off the HIGH. */
10657 if (GET_CODE (x) == HIGH)
10659 assemble_integer (x, 4, BITS_PER_WORD, 1);
10660 mark_symbol_refs_as_used (x);
10665 [(set_attr "length" "4")
10666 (set_attr "type" "no_insn")]
10669 (define_insn "consttable_8"
10670 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10674 making_const_table = TRUE;
10675 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10680 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10681 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10685 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10690 [(set_attr "length" "8")
10691 (set_attr "type" "no_insn")]
10694 (define_insn "consttable_16"
10695 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10699 making_const_table = TRUE;
10700 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10705 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10706 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10710 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10715 [(set_attr "length" "16")
10716 (set_attr "type" "no_insn")]
10719 ;; V5 Instructions,
10721 (define_insn "clzsi2"
10722 [(set (match_operand:SI 0 "s_register_operand" "=r")
10723 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10724 "TARGET_32BIT && arm_arch5"
10726 [(set_attr "predicable" "yes")
10727 (set_attr "predicable_short_it" "no")
10728 (set_attr "type" "clz")])
10730 (define_insn "rbitsi2"
10731 [(set (match_operand:SI 0 "s_register_operand" "=r")
10732 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10733 "TARGET_32BIT && arm_arch_thumb2"
10735 [(set_attr "predicable" "yes")
10736 (set_attr "predicable_short_it" "no")
10737 (set_attr "type" "clz")])
10739 (define_expand "ctzsi2"
10740 [(set (match_operand:SI 0 "s_register_operand" "")
10741 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10742 "TARGET_32BIT && arm_arch_thumb2"
10745 rtx tmp = gen_reg_rtx (SImode);
10746 emit_insn (gen_rbitsi2 (tmp, operands[1]));
10747 emit_insn (gen_clzsi2 (operands[0], tmp));
10753 ;; V5E instructions.
10755 (define_insn "prefetch"
10756 [(prefetch (match_operand:SI 0 "address_operand" "p")
10757 (match_operand:SI 1 "" "")
10758 (match_operand:SI 2 "" ""))]
10759 "TARGET_32BIT && arm_arch5e"
10761 [(set_attr "type" "load1")]
10764 ;; General predication pattern
10767 [(match_operator 0 "arm_comparison_operator"
10768 [(match_operand 1 "cc_register" "")
10771 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
10773 [(set_attr "predicated" "yes")]
10776 (define_insn "force_register_use"
10777 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10780 [(set_attr "length" "0")
10781 (set_attr "type" "no_insn")]
10785 ;; Patterns for exception handling
10787 (define_expand "eh_return"
10788 [(use (match_operand 0 "general_operand" ""))]
10793 emit_insn (gen_arm_eh_return (operands[0]));
10795 emit_insn (gen_thumb_eh_return (operands[0]));
10800 ;; We can't expand this before we know where the link register is stored.
10801 (define_insn_and_split "arm_eh_return"
10802 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10804 (clobber (match_scratch:SI 1 "=&r"))]
10807 "&& reload_completed"
10811 arm_set_return_address (operands[0], operands[1]);
10819 (define_insn "load_tp_hard"
10820 [(set (match_operand:SI 0 "register_operand" "=r")
10821 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10823 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
10824 [(set_attr "predicable" "yes")
10825 (set_attr "type" "mrs")]
10828 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
10829 (define_insn "load_tp_soft"
10830 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10831 (clobber (reg:SI LR_REGNUM))
10832 (clobber (reg:SI IP_REGNUM))
10833 (clobber (reg:CC CC_REGNUM))]
10835 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
10836 [(set_attr "conds" "clob")
10837 (set_attr "type" "branch")]
10840 ;; tls descriptor call
10841 (define_insn "tlscall"
10842 [(set (reg:SI R0_REGNUM)
10843 (unspec:SI [(reg:SI R0_REGNUM)
10844 (match_operand:SI 0 "" "X")
10845 (match_operand 1 "" "")] UNSPEC_TLS))
10846 (clobber (reg:SI R1_REGNUM))
10847 (clobber (reg:SI LR_REGNUM))
10848 (clobber (reg:SI CC_REGNUM))]
10851 targetm.asm_out.internal_label (asm_out_file, "LPIC",
10852 INTVAL (operands[1]));
10853 return "bl\\t%c0(tlscall)";
10855 [(set_attr "conds" "clob")
10856 (set_attr "length" "4")
10857 (set_attr "type" "branch")]
10860 ;; For thread pointer builtin
10861 (define_expand "get_thread_pointersi"
10862 [(match_operand:SI 0 "s_register_operand" "=r")]
10866 arm_load_tp (operands[0]);
10872 ;; We only care about the lower 16 bits of the constant
10873 ;; being inserted into the upper 16 bits of the register.
10874 (define_insn "*arm_movtas_ze"
10875 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10878 (match_operand:SI 1 "const_int_operand" ""))]
10881 [(set_attr "predicable" "yes")
10882 (set_attr "predicable_short_it" "no")
10883 (set_attr "length" "4")
10884 (set_attr "type" "alu_sreg")]
10887 (define_insn "*arm_rev"
10888 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10889 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10895 [(set_attr "arch" "t1,t2,32")
10896 (set_attr "length" "2,2,4")
10897 (set_attr "predicable" "no,yes,yes")
10898 (set_attr "predicable_short_it" "no")
10899 (set_attr "type" "rev")]
10902 (define_expand "arm_legacy_rev"
10903 [(set (match_operand:SI 2 "s_register_operand" "")
10904 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
10908 (lshiftrt:SI (match_dup 2)
10910 (set (match_operand:SI 3 "s_register_operand" "")
10911 (rotatert:SI (match_dup 1)
10914 (and:SI (match_dup 2)
10915 (const_int -65281)))
10916 (set (match_operand:SI 0 "s_register_operand" "")
10917 (xor:SI (match_dup 3)
10923 ;; Reuse temporaries to keep register pressure down.
10924 (define_expand "thumb_legacy_rev"
10925 [(set (match_operand:SI 2 "s_register_operand" "")
10926 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
10928 (set (match_operand:SI 3 "s_register_operand" "")
10929 (lshiftrt:SI (match_dup 1)
10932 (ior:SI (match_dup 3)
10934 (set (match_operand:SI 4 "s_register_operand" "")
10936 (set (match_operand:SI 5 "s_register_operand" "")
10937 (rotatert:SI (match_dup 1)
10940 (ashift:SI (match_dup 5)
10943 (lshiftrt:SI (match_dup 5)
10946 (ior:SI (match_dup 5)
10949 (rotatert:SI (match_dup 5)
10951 (set (match_operand:SI 0 "s_register_operand" "")
10952 (ior:SI (match_dup 5)
10958 (define_expand "bswapsi2"
10959 [(set (match_operand:SI 0 "s_register_operand" "=r")
10960 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
10961 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
10965 rtx op2 = gen_reg_rtx (SImode);
10966 rtx op3 = gen_reg_rtx (SImode);
10970 rtx op4 = gen_reg_rtx (SImode);
10971 rtx op5 = gen_reg_rtx (SImode);
10973 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
10974 op2, op3, op4, op5));
10978 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
10987 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
10988 ;; and unsigned variants, respectively. For rev16, expose
10989 ;; byte-swapping in the lower 16 bits only.
10990 (define_insn "*arm_revsh"
10991 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10992 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
10998 [(set_attr "arch" "t1,t2,32")
10999 (set_attr "length" "2,2,4")
11000 (set_attr "type" "rev")]
11003 (define_insn "*arm_rev16"
11004 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11005 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11011 [(set_attr "arch" "t1,t2,32")
11012 (set_attr "length" "2,2,4")
11013 (set_attr "type" "rev")]
11016 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11017 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11018 ;; each valid permutation.
11020 (define_insn "arm_rev16si2"
11021 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11022 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11024 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11025 (and:SI (lshiftrt:SI (match_dup 1)
11027 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11029 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11030 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11032 [(set_attr "arch" "t1,t2,32")
11033 (set_attr "length" "2,2,4")
11034 (set_attr "type" "rev")]
11037 (define_insn "arm_rev16si2_alt"
11038 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11039 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11041 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11042 (and:SI (ashift:SI (match_dup 1)
11044 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11046 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11047 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11049 [(set_attr "arch" "t1,t2,32")
11050 (set_attr "length" "2,2,4")
11051 (set_attr "type" "rev")]
11054 (define_expand "bswaphi2"
11055 [(set (match_operand:HI 0 "s_register_operand" "=r")
11056 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11061 ;; Patterns for LDRD/STRD in Thumb2 mode
11063 (define_insn "*thumb2_ldrd"
11064 [(set (match_operand:SI 0 "s_register_operand" "=r")
11065 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11066 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11067 (set (match_operand:SI 3 "s_register_operand" "=r")
11068 (mem:SI (plus:SI (match_dup 1)
11069 (match_operand:SI 4 "const_int_operand" ""))))]
11070 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11071 && current_tune->prefer_ldrd_strd
11072 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11073 && (operands_ok_ldrd_strd (operands[0], operands[3],
11074 operands[1], INTVAL (operands[2]),
11076 "ldrd%?\t%0, %3, [%1, %2]"
11077 [(set_attr "type" "load2")
11078 (set_attr "predicable" "yes")
11079 (set_attr "predicable_short_it" "no")])
11081 (define_insn "*thumb2_ldrd_base"
11082 [(set (match_operand:SI 0 "s_register_operand" "=r")
11083 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11084 (set (match_operand:SI 2 "s_register_operand" "=r")
11085 (mem:SI (plus:SI (match_dup 1)
11087 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11088 && current_tune->prefer_ldrd_strd
11089 && (operands_ok_ldrd_strd (operands[0], operands[2],
11090 operands[1], 0, false, true))"
11091 "ldrd%?\t%0, %2, [%1]"
11092 [(set_attr "type" "load2")
11093 (set_attr "predicable" "yes")
11094 (set_attr "predicable_short_it" "no")])
11096 (define_insn "*thumb2_ldrd_base_neg"
11097 [(set (match_operand:SI 0 "s_register_operand" "=r")
11098 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11100 (set (match_operand:SI 2 "s_register_operand" "=r")
11101 (mem:SI (match_dup 1)))]
11102 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11103 && current_tune->prefer_ldrd_strd
11104 && (operands_ok_ldrd_strd (operands[0], operands[2],
11105 operands[1], -4, false, true))"
11106 "ldrd%?\t%0, %2, [%1, #-4]"
11107 [(set_attr "type" "load2")
11108 (set_attr "predicable" "yes")
11109 (set_attr "predicable_short_it" "no")])
11111 (define_insn "*thumb2_strd"
11112 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11113 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11114 (match_operand:SI 2 "s_register_operand" "r"))
11115 (set (mem:SI (plus:SI (match_dup 0)
11116 (match_operand:SI 3 "const_int_operand" "")))
11117 (match_operand:SI 4 "s_register_operand" "r"))]
11118 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11119 && current_tune->prefer_ldrd_strd
11120 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11121 && (operands_ok_ldrd_strd (operands[2], operands[4],
11122 operands[0], INTVAL (operands[1]),
11124 "strd%?\t%2, %4, [%0, %1]"
11125 [(set_attr "type" "store2")
11126 (set_attr "predicable" "yes")
11127 (set_attr "predicable_short_it" "no")])
11129 (define_insn "*thumb2_strd_base"
11130 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11131 (match_operand:SI 1 "s_register_operand" "r"))
11132 (set (mem:SI (plus:SI (match_dup 0)
11134 (match_operand:SI 2 "s_register_operand" "r"))]
11135 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11136 && current_tune->prefer_ldrd_strd
11137 && (operands_ok_ldrd_strd (operands[1], operands[2],
11138 operands[0], 0, false, false))"
11139 "strd%?\t%1, %2, [%0]"
11140 [(set_attr "type" "store2")
11141 (set_attr "predicable" "yes")
11142 (set_attr "predicable_short_it" "no")])
11144 (define_insn "*thumb2_strd_base_neg"
11145 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11147 (match_operand:SI 1 "s_register_operand" "r"))
11148 (set (mem:SI (match_dup 0))
11149 (match_operand:SI 2 "s_register_operand" "r"))]
11150 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11151 && current_tune->prefer_ldrd_strd
11152 && (operands_ok_ldrd_strd (operands[1], operands[2],
11153 operands[0], -4, false, false))"
11154 "strd%?\t%1, %2, [%0, #-4]"
11155 [(set_attr "type" "store2")
11156 (set_attr "predicable" "yes")
11157 (set_attr "predicable_short_it" "no")])
11159 ;; ARMv8 CRC32 instructions.
11160 (define_insn "<crc_variant>"
11161 [(set (match_operand:SI 0 "s_register_operand" "=r")
11162 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11163 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11166 "<crc_variant>\\t%0, %1, %2"
11167 [(set_attr "type" "crc")
11168 (set_attr "conds" "unconditional")]
11171 ;; Load the load/store double peephole optimizations.
11172 (include "ldrdstrd.md")
11174 ;; Load the load/store multiple patterns
11175 (include "ldmstm.md")
11177 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11178 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11179 (define_insn "*load_multiple"
11180 [(match_parallel 0 "load_multiple_operation"
11181 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11182 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11187 arm_output_multireg_pop (operands, /*return_pc=*/false,
11188 /*cond=*/const_true_rtx,
11194 [(set_attr "predicable" "yes")]
11197 (define_expand "copysignsf3"
11198 [(match_operand:SF 0 "register_operand")
11199 (match_operand:SF 1 "register_operand")
11200 (match_operand:SF 2 "register_operand")]
11201 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11203 emit_move_insn (operands[0], operands[2]);
11204 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11205 GEN_INT (31), GEN_INT (0),
11206 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11211 (define_expand "copysigndf3"
11212 [(match_operand:DF 0 "register_operand")
11213 (match_operand:DF 1 "register_operand")
11214 (match_operand:DF 2 "register_operand")]
11215 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11217 rtx op0_low = gen_lowpart (SImode, operands[0]);
11218 rtx op0_high = gen_highpart (SImode, operands[0]);
11219 rtx op1_low = gen_lowpart (SImode, operands[1]);
11220 rtx op1_high = gen_highpart (SImode, operands[1]);
11221 rtx op2_high = gen_highpart (SImode, operands[2]);
11223 rtx scratch1 = gen_reg_rtx (SImode);
11224 rtx scratch2 = gen_reg_rtx (SImode);
11225 emit_move_insn (scratch1, op2_high);
11226 emit_move_insn (scratch2, op1_high);
11228 emit_insn(gen_rtx_SET(scratch1,
11229 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11230 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11231 emit_move_insn (op0_low, op1_low);
11232 emit_move_insn (op0_high, scratch2);
11238 ;; Vector bits common to IWMMXT and Neon
11239 (include "vec-common.md")
11240 ;; Load the Intel Wireless Multimedia Extension patterns
11241 (include "iwmmxt.md")
11242 ;; Load the VFP co-processor patterns
11244 ;; Thumb-1 patterns
11245 (include "thumb1.md")
11246 ;; Thumb-2 patterns
11247 (include "thumb2.md")
11249 (include "neon.md")
11251 (include "crypto.md")
11252 ;; Synchronization Primitives
11253 (include "sync.md")
11254 ;; Fixed-point patterns
11255 (include "arm-fixed.md")