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,rI,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 (VOIDmode, 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 (VOIDmode, 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 (VOIDmode, 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 (VOIDmode, 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 (VOIDmode, 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 (VOIDmode, low,
4458 gen_rtx_NEG (SImode, operands[1])));
4459 emit_insn (gen_rtx_SET (VOIDmode, high,
4460 gen_rtx_AND (SImode,
4461 gen_rtx_NOT (SImode, operands[1]),
4463 emit_insn (gen_rtx_SET (VOIDmode, high,
4464 gen_rtx_ASHIFTRT (SImode, high,
4469 [(set_attr "length" "12")
4470 (set_attr "arch" "t2,*")
4471 (set_attr "type" "multiple")]
4474 (define_insn_and_split "*negdi_zero_extendsidi"
4475 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4476 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4477 (clobber (reg:CC CC_REGNUM))]
4479 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4480 ;; Don't care what register is input to sbc,
4481 ;; since we just just need to propagate the carry.
4482 "&& reload_completed"
4483 [(parallel [(set (reg:CC CC_REGNUM)
4484 (compare:CC (const_int 0) (match_dup 1)))
4485 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4486 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4487 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4489 operands[2] = gen_highpart (SImode, operands[0]);
4490 operands[0] = gen_lowpart (SImode, operands[0]);
4492 [(set_attr "conds" "clob")
4493 (set_attr "length" "8")
4494 (set_attr "type" "multiple")] ;; length in thumb is 4
4497 ;; abssi2 doesn't really clobber the condition codes if a different register
4498 ;; is being set. To keep things simple, assume during rtl manipulations that
4499 ;; it does, but tell the final scan operator the truth. Similarly for
4502 (define_expand "abssi2"
4504 [(set (match_operand:SI 0 "s_register_operand" "")
4505 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4506 (clobber (match_dup 2))])]
4510 operands[2] = gen_rtx_SCRATCH (SImode);
4512 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4515 (define_insn_and_split "*arm_abssi2"
4516 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4517 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4518 (clobber (reg:CC CC_REGNUM))]
4521 "&& reload_completed"
4524 /* if (which_alternative == 0) */
4525 if (REGNO(operands[0]) == REGNO(operands[1]))
4527 /* Emit the pattern:
4528 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4529 [(set (reg:CC CC_REGNUM)
4530 (compare:CC (match_dup 0) (const_int 0)))
4531 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4532 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4534 emit_insn (gen_rtx_SET (VOIDmode,
4535 gen_rtx_REG (CCmode, CC_REGNUM),
4536 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4537 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4538 (gen_rtx_LT (SImode,
4539 gen_rtx_REG (CCmode, CC_REGNUM),
4541 (gen_rtx_SET (VOIDmode,
4543 (gen_rtx_MINUS (SImode,
4550 /* Emit the pattern:
4551 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4553 (xor:SI (match_dup 1)
4554 (ashiftrt:SI (match_dup 1) (const_int 31))))
4556 (minus:SI (match_dup 0)
4557 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4559 emit_insn (gen_rtx_SET (VOIDmode,
4561 gen_rtx_XOR (SImode,
4562 gen_rtx_ASHIFTRT (SImode,
4566 emit_insn (gen_rtx_SET (VOIDmode,
4568 gen_rtx_MINUS (SImode,
4570 gen_rtx_ASHIFTRT (SImode,
4576 [(set_attr "conds" "clob,*")
4577 (set_attr "shift" "1")
4578 (set_attr "predicable" "no, yes")
4579 (set_attr "length" "8")
4580 (set_attr "type" "multiple")]
4583 (define_insn_and_split "*arm_neg_abssi2"
4584 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4585 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4586 (clobber (reg:CC CC_REGNUM))]
4589 "&& reload_completed"
4592 /* if (which_alternative == 0) */
4593 if (REGNO (operands[0]) == REGNO (operands[1]))
4595 /* Emit the pattern:
4596 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4598 emit_insn (gen_rtx_SET (VOIDmode,
4599 gen_rtx_REG (CCmode, CC_REGNUM),
4600 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4601 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4603 gen_rtx_REG (CCmode, CC_REGNUM),
4605 gen_rtx_SET (VOIDmode,
4607 (gen_rtx_MINUS (SImode,
4613 /* Emit the pattern:
4614 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4616 emit_insn (gen_rtx_SET (VOIDmode,
4618 gen_rtx_XOR (SImode,
4619 gen_rtx_ASHIFTRT (SImode,
4623 emit_insn (gen_rtx_SET (VOIDmode,
4625 gen_rtx_MINUS (SImode,
4626 gen_rtx_ASHIFTRT (SImode,
4633 [(set_attr "conds" "clob,*")
4634 (set_attr "shift" "1")
4635 (set_attr "predicable" "no, yes")
4636 (set_attr "length" "8")
4637 (set_attr "type" "multiple")]
4640 (define_expand "abssf2"
4641 [(set (match_operand:SF 0 "s_register_operand" "")
4642 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4643 "TARGET_32BIT && TARGET_HARD_FLOAT"
4646 (define_expand "absdf2"
4647 [(set (match_operand:DF 0 "s_register_operand" "")
4648 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4649 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4652 (define_expand "sqrtsf2"
4653 [(set (match_operand:SF 0 "s_register_operand" "")
4654 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4655 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4658 (define_expand "sqrtdf2"
4659 [(set (match_operand:DF 0 "s_register_operand" "")
4660 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4661 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4664 (define_insn_and_split "one_cmpldi2"
4665 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4666 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4673 "TARGET_32BIT && reload_completed
4674 && arm_general_register_operand (operands[0], DImode)"
4675 [(set (match_dup 0) (not:SI (match_dup 1)))
4676 (set (match_dup 2) (not:SI (match_dup 3)))]
4679 operands[2] = gen_highpart (SImode, operands[0]);
4680 operands[0] = gen_lowpart (SImode, operands[0]);
4681 operands[3] = gen_highpart (SImode, operands[1]);
4682 operands[1] = gen_lowpart (SImode, operands[1]);
4684 [(set_attr "length" "*,8,8,*")
4685 (set_attr "predicable" "no,yes,yes,no")
4686 (set_attr "type" "neon_move,multiple,multiple,neon_move")
4687 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4690 (define_expand "one_cmplsi2"
4691 [(set (match_operand:SI 0 "s_register_operand" "")
4692 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
4697 (define_insn "*arm_one_cmplsi2"
4698 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4699 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4702 [(set_attr "predicable" "yes")
4703 (set_attr "predicable_short_it" "yes,no")
4704 (set_attr "arch" "t2,*")
4705 (set_attr "length" "4")
4706 (set_attr "type" "mvn_reg")]
4709 (define_insn "*notsi_compare0"
4710 [(set (reg:CC_NOOV CC_REGNUM)
4711 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4713 (set (match_operand:SI 0 "s_register_operand" "=r")
4714 (not:SI (match_dup 1)))]
4717 [(set_attr "conds" "set")
4718 (set_attr "type" "mvn_reg")]
4721 (define_insn "*notsi_compare0_scratch"
4722 [(set (reg:CC_NOOV CC_REGNUM)
4723 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4725 (clobber (match_scratch:SI 0 "=r"))]
4728 [(set_attr "conds" "set")
4729 (set_attr "type" "mvn_reg")]
4732 ;; Fixed <--> Floating conversion insns
4734 (define_expand "floatsihf2"
4735 [(set (match_operand:HF 0 "general_operand" "")
4736 (float:HF (match_operand:SI 1 "general_operand" "")))]
4740 rtx op1 = gen_reg_rtx (SFmode);
4741 expand_float (op1, operands[1], 0);
4742 op1 = convert_to_mode (HFmode, op1, 0);
4743 emit_move_insn (operands[0], op1);
4748 (define_expand "floatdihf2"
4749 [(set (match_operand:HF 0 "general_operand" "")
4750 (float:HF (match_operand:DI 1 "general_operand" "")))]
4754 rtx op1 = gen_reg_rtx (SFmode);
4755 expand_float (op1, operands[1], 0);
4756 op1 = convert_to_mode (HFmode, op1, 0);
4757 emit_move_insn (operands[0], op1);
4762 (define_expand "floatsisf2"
4763 [(set (match_operand:SF 0 "s_register_operand" "")
4764 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
4765 "TARGET_32BIT && TARGET_HARD_FLOAT"
4769 (define_expand "floatsidf2"
4770 [(set (match_operand:DF 0 "s_register_operand" "")
4771 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
4772 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4776 (define_expand "fix_trunchfsi2"
4777 [(set (match_operand:SI 0 "general_operand" "")
4778 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4782 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4783 expand_fix (operands[0], op1, 0);
4788 (define_expand "fix_trunchfdi2"
4789 [(set (match_operand:DI 0 "general_operand" "")
4790 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
4794 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4795 expand_fix (operands[0], op1, 0);
4800 (define_expand "fix_truncsfsi2"
4801 [(set (match_operand:SI 0 "s_register_operand" "")
4802 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
4803 "TARGET_32BIT && TARGET_HARD_FLOAT"
4807 (define_expand "fix_truncdfsi2"
4808 [(set (match_operand:SI 0 "s_register_operand" "")
4809 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
4810 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4816 (define_expand "truncdfsf2"
4817 [(set (match_operand:SF 0 "s_register_operand" "")
4819 (match_operand:DF 1 "s_register_operand" "")))]
4820 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4824 /* DFmode -> HFmode conversions have to go through SFmode. */
4825 (define_expand "truncdfhf2"
4826 [(set (match_operand:HF 0 "general_operand" "")
4828 (match_operand:DF 1 "general_operand" "")))]
4833 op1 = convert_to_mode (SFmode, operands[1], 0);
4834 op1 = convert_to_mode (HFmode, op1, 0);
4835 emit_move_insn (operands[0], op1);
4840 ;; Zero and sign extension instructions.
4842 (define_insn "zero_extend<mode>di2"
4843 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
4844 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4845 "<qhs_zextenddi_cstr>")))]
4846 "TARGET_32BIT <qhs_zextenddi_cond>"
4848 [(set_attr "length" "8,4,8,8")
4849 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
4850 (set_attr "ce_count" "2")
4851 (set_attr "predicable" "yes")
4852 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
4855 (define_insn "extend<mode>di2"
4856 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
4857 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4858 "<qhs_extenddi_cstr>")))]
4859 "TARGET_32BIT <qhs_sextenddi_cond>"
4861 [(set_attr "length" "8,4,8,8,8")
4862 (set_attr "ce_count" "2")
4863 (set_attr "shift" "1")
4864 (set_attr "predicable" "yes")
4865 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
4866 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
4869 ;; Splits for all extensions to DImode
4871 [(set (match_operand:DI 0 "s_register_operand" "")
4872 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4873 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4874 [(set (match_dup 0) (match_dup 1))]
4876 rtx lo_part = gen_lowpart (SImode, operands[0]);
4877 machine_mode src_mode = GET_MODE (operands[1]);
4879 if (REG_P (operands[0])
4880 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4881 emit_clobber (operands[0]);
4882 if (!REG_P (lo_part) || src_mode != SImode
4883 || !rtx_equal_p (lo_part, operands[1]))
4885 if (src_mode == SImode)
4886 emit_move_insn (lo_part, operands[1]);
4888 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4889 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4890 operands[1] = lo_part;
4892 operands[0] = gen_highpart (SImode, operands[0]);
4893 operands[1] = const0_rtx;
4897 [(set (match_operand:DI 0 "s_register_operand" "")
4898 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4899 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
4900 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4902 rtx lo_part = gen_lowpart (SImode, operands[0]);
4903 machine_mode src_mode = GET_MODE (operands[1]);
4905 if (REG_P (operands[0])
4906 && !reg_overlap_mentioned_p (operands[0], operands[1]))
4907 emit_clobber (operands[0]);
4909 if (!REG_P (lo_part) || src_mode != SImode
4910 || !rtx_equal_p (lo_part, operands[1]))
4912 if (src_mode == SImode)
4913 emit_move_insn (lo_part, operands[1]);
4915 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
4916 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4917 operands[1] = lo_part;
4919 operands[0] = gen_highpart (SImode, operands[0]);
4922 (define_expand "zero_extendhisi2"
4923 [(set (match_operand:SI 0 "s_register_operand" "")
4924 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
4927 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4929 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4932 if (!arm_arch6 && !MEM_P (operands[1]))
4934 rtx t = gen_lowpart (SImode, operands[1]);
4935 rtx tmp = gen_reg_rtx (SImode);
4936 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4937 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4943 [(set (match_operand:SI 0 "s_register_operand" "")
4944 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4945 "!TARGET_THUMB2 && !arm_arch6"
4946 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4947 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4949 operands[2] = gen_lowpart (SImode, operands[1]);
4952 (define_insn "*arm_zero_extendhisi2"
4953 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4954 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4955 "TARGET_ARM && arm_arch4 && !arm_arch6"
4959 [(set_attr "type" "alu_shift_reg,load_byte")
4960 (set_attr "predicable" "yes")]
4963 (define_insn "*arm_zero_extendhisi2_v6"
4964 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4965 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4966 "TARGET_ARM && arm_arch6"
4970 [(set_attr "predicable" "yes")
4971 (set_attr "type" "extend,load_byte")]
4974 (define_insn "*arm_zero_extendhisi2addsi"
4975 [(set (match_operand:SI 0 "s_register_operand" "=r")
4976 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4977 (match_operand:SI 2 "s_register_operand" "r")))]
4979 "uxtah%?\\t%0, %2, %1"
4980 [(set_attr "type" "alu_shift_reg")
4981 (set_attr "predicable" "yes")
4982 (set_attr "predicable_short_it" "no")]
4985 (define_expand "zero_extendqisi2"
4986 [(set (match_operand:SI 0 "s_register_operand" "")
4987 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
4990 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
4992 emit_insn (gen_andsi3 (operands[0],
4993 gen_lowpart (SImode, operands[1]),
4997 if (!arm_arch6 && !MEM_P (operands[1]))
4999 rtx t = gen_lowpart (SImode, operands[1]);
5000 rtx tmp = gen_reg_rtx (SImode);
5001 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5002 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5008 [(set (match_operand:SI 0 "s_register_operand" "")
5009 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5011 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5012 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5014 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5017 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5022 (define_insn "*arm_zero_extendqisi2"
5023 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5024 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5025 "TARGET_ARM && !arm_arch6"
5028 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5029 [(set_attr "length" "8,4")
5030 (set_attr "type" "alu_shift_reg,load_byte")
5031 (set_attr "predicable" "yes")]
5034 (define_insn "*arm_zero_extendqisi2_v6"
5035 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5036 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5037 "TARGET_ARM && arm_arch6"
5040 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5041 [(set_attr "type" "extend,load_byte")
5042 (set_attr "predicable" "yes")]
5045 (define_insn "*arm_zero_extendqisi2addsi"
5046 [(set (match_operand:SI 0 "s_register_operand" "=r")
5047 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5048 (match_operand:SI 2 "s_register_operand" "r")))]
5050 "uxtab%?\\t%0, %2, %1"
5051 [(set_attr "predicable" "yes")
5052 (set_attr "predicable_short_it" "no")
5053 (set_attr "type" "alu_shift_reg")]
5057 [(set (match_operand:SI 0 "s_register_operand" "")
5058 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5059 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5060 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5061 [(set (match_dup 2) (match_dup 1))
5062 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5067 [(set (match_operand:SI 0 "s_register_operand" "")
5068 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5069 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5070 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5071 [(set (match_dup 2) (match_dup 1))
5072 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5078 [(set (match_operand:SI 0 "s_register_operand" "")
5079 (IOR_XOR:SI (and:SI (ashift:SI
5080 (match_operand:SI 1 "s_register_operand" "")
5081 (match_operand:SI 2 "const_int_operand" ""))
5082 (match_operand:SI 3 "const_int_operand" ""))
5084 (match_operator 5 "subreg_lowpart_operator"
5085 [(match_operand:SI 4 "s_register_operand" "")]))))]
5087 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5088 == (GET_MODE_MASK (GET_MODE (operands[5]))
5089 & (GET_MODE_MASK (GET_MODE (operands[5]))
5090 << (INTVAL (operands[2])))))"
5091 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5093 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5094 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5097 (define_insn "*compareqi_eq0"
5098 [(set (reg:CC_Z CC_REGNUM)
5099 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5103 [(set_attr "conds" "set")
5104 (set_attr "predicable" "yes")
5105 (set_attr "predicable_short_it" "no")
5106 (set_attr "type" "logic_imm")]
5109 (define_expand "extendhisi2"
5110 [(set (match_operand:SI 0 "s_register_operand" "")
5111 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5116 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5119 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5121 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5125 if (!arm_arch6 && !MEM_P (operands[1]))
5127 rtx t = gen_lowpart (SImode, operands[1]);
5128 rtx tmp = gen_reg_rtx (SImode);
5129 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5130 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5137 [(set (match_operand:SI 0 "register_operand" "")
5138 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5139 (clobber (match_scratch:SI 2 ""))])]
5141 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5142 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5144 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5147 ;; This pattern will only be used when ldsh is not available
5148 (define_expand "extendhisi2_mem"
5149 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5151 (zero_extend:SI (match_dup 7)))
5152 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5153 (set (match_operand:SI 0 "" "")
5154 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5159 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5161 mem1 = change_address (operands[1], QImode, addr);
5162 mem2 = change_address (operands[1], QImode,
5163 plus_constant (Pmode, addr, 1));
5164 operands[0] = gen_lowpart (SImode, operands[0]);
5166 operands[2] = gen_reg_rtx (SImode);
5167 operands[3] = gen_reg_rtx (SImode);
5168 operands[6] = gen_reg_rtx (SImode);
5171 if (BYTES_BIG_ENDIAN)
5173 operands[4] = operands[2];
5174 operands[5] = operands[3];
5178 operands[4] = operands[3];
5179 operands[5] = operands[2];
5185 [(set (match_operand:SI 0 "register_operand" "")
5186 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5188 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5189 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5191 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5194 (define_insn "*arm_extendhisi2"
5195 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5196 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5197 "TARGET_ARM && arm_arch4 && !arm_arch6"
5201 [(set_attr "length" "8,4")
5202 (set_attr "type" "alu_shift_reg,load_byte")
5203 (set_attr "predicable" "yes")]
5206 ;; ??? Check Thumb-2 pool range
5207 (define_insn "*arm_extendhisi2_v6"
5208 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5209 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5210 "TARGET_32BIT && arm_arch6"
5214 [(set_attr "type" "extend,load_byte")
5215 (set_attr "predicable" "yes")
5216 (set_attr "predicable_short_it" "no")]
5219 (define_insn "*arm_extendhisi2addsi"
5220 [(set (match_operand:SI 0 "s_register_operand" "=r")
5221 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5222 (match_operand:SI 2 "s_register_operand" "r")))]
5224 "sxtah%?\\t%0, %2, %1"
5225 [(set_attr "type" "alu_shift_reg")]
5228 (define_expand "extendqihi2"
5230 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5232 (set (match_operand:HI 0 "s_register_operand" "")
5233 (ashiftrt:SI (match_dup 2)
5238 if (arm_arch4 && MEM_P (operands[1]))
5240 emit_insn (gen_rtx_SET (VOIDmode,
5242 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5245 if (!s_register_operand (operands[1], QImode))
5246 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5247 operands[0] = gen_lowpart (SImode, operands[0]);
5248 operands[1] = gen_lowpart (SImode, operands[1]);
5249 operands[2] = gen_reg_rtx (SImode);
5253 (define_insn "*arm_extendqihi_insn"
5254 [(set (match_operand:HI 0 "s_register_operand" "=r")
5255 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5256 "TARGET_ARM && arm_arch4"
5257 "ldr%(sb%)\\t%0, %1"
5258 [(set_attr "type" "load_byte")
5259 (set_attr "predicable" "yes")]
5262 (define_expand "extendqisi2"
5263 [(set (match_operand:SI 0 "s_register_operand" "")
5264 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5267 if (!arm_arch4 && MEM_P (operands[1]))
5268 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5270 if (!arm_arch6 && !MEM_P (operands[1]))
5272 rtx t = gen_lowpart (SImode, operands[1]);
5273 rtx tmp = gen_reg_rtx (SImode);
5274 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5275 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5281 [(set (match_operand:SI 0 "register_operand" "")
5282 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5284 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5285 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5287 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5290 (define_insn "*arm_extendqisi"
5291 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5292 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5293 "TARGET_ARM && arm_arch4 && !arm_arch6"
5297 [(set_attr "length" "8,4")
5298 (set_attr "type" "alu_shift_reg,load_byte")
5299 (set_attr "predicable" "yes")]
5302 (define_insn "*arm_extendqisi_v6"
5303 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5305 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5306 "TARGET_ARM && arm_arch6"
5310 [(set_attr "type" "extend,load_byte")
5311 (set_attr "predicable" "yes")]
5314 (define_insn "*arm_extendqisi2addsi"
5315 [(set (match_operand:SI 0 "s_register_operand" "=r")
5316 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5317 (match_operand:SI 2 "s_register_operand" "r")))]
5319 "sxtab%?\\t%0, %2, %1"
5320 [(set_attr "type" "alu_shift_reg")
5321 (set_attr "predicable" "yes")
5322 (set_attr "predicable_short_it" "no")]
5325 (define_expand "extendsfdf2"
5326 [(set (match_operand:DF 0 "s_register_operand" "")
5327 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5328 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5332 /* HFmode -> DFmode conversions have to go through SFmode. */
5333 (define_expand "extendhfdf2"
5334 [(set (match_operand:DF 0 "general_operand" "")
5335 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5340 op1 = convert_to_mode (SFmode, operands[1], 0);
5341 op1 = convert_to_mode (DFmode, op1, 0);
5342 emit_insn (gen_movdf (operands[0], op1));
5347 ;; Move insns (including loads and stores)
5349 ;; XXX Just some ideas about movti.
5350 ;; I don't think these are a good idea on the arm, there just aren't enough
5352 ;;(define_expand "loadti"
5353 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5354 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5357 ;;(define_expand "storeti"
5358 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5359 ;; (match_operand:TI 1 "s_register_operand" ""))]
5362 ;;(define_expand "movti"
5363 ;; [(set (match_operand:TI 0 "general_operand" "")
5364 ;; (match_operand:TI 1 "general_operand" ""))]
5370 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5371 ;; operands[1] = copy_to_reg (operands[1]);
5372 ;; if (MEM_P (operands[0]))
5373 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5374 ;; else if (MEM_P (operands[1]))
5375 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5379 ;; emit_insn (insn);
5383 ;; Recognize garbage generated above.
5386 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5387 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5391 ;; register mem = (which_alternative < 3);
5392 ;; register const char *template;
5394 ;; operands[mem] = XEXP (operands[mem], 0);
5395 ;; switch (which_alternative)
5397 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5398 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5399 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5400 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5401 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5402 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5404 ;; output_asm_insn (template, operands);
5408 (define_expand "movdi"
5409 [(set (match_operand:DI 0 "general_operand" "")
5410 (match_operand:DI 1 "general_operand" ""))]
5413 if (can_create_pseudo_p ())
5415 if (!REG_P (operands[0]))
5416 operands[1] = force_reg (DImode, operands[1]);
5421 (define_insn "*arm_movdi"
5422 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5423 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5425 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5427 && ( register_operand (operands[0], DImode)
5428 || register_operand (operands[1], DImode))"
5430 switch (which_alternative)
5437 return output_move_double (operands, true, NULL);
5440 [(set_attr "length" "8,12,16,8,8")
5441 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5442 (set_attr "arm_pool_range" "*,*,*,1020,*")
5443 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5444 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5445 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5449 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5450 (match_operand:ANY64 1 "immediate_operand" ""))]
5453 && (arm_const_double_inline_cost (operands[1])
5454 <= arm_max_const_double_inline_cost ())"
5457 arm_split_constant (SET, SImode, curr_insn,
5458 INTVAL (gen_lowpart (SImode, operands[1])),
5459 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5460 arm_split_constant (SET, SImode, curr_insn,
5461 INTVAL (gen_highpart_mode (SImode,
5462 GET_MODE (operands[0]),
5464 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5469 ; If optimizing for size, or if we have load delay slots, then
5470 ; we want to split the constant into two separate operations.
5471 ; In both cases this may split a trivial part into a single data op
5472 ; leaving a single complex constant to load. We can also get longer
5473 ; offsets in a LDR which means we get better chances of sharing the pool
5474 ; entries. Finally, we can normally do a better job of scheduling
5475 ; LDR instructions than we can with LDM.
5476 ; This pattern will only match if the one above did not.
5478 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5479 (match_operand:ANY64 1 "const_double_operand" ""))]
5480 "TARGET_ARM && reload_completed
5481 && arm_const_double_by_parts (operands[1])"
5482 [(set (match_dup 0) (match_dup 1))
5483 (set (match_dup 2) (match_dup 3))]
5485 operands[2] = gen_highpart (SImode, operands[0]);
5486 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5488 operands[0] = gen_lowpart (SImode, operands[0]);
5489 operands[1] = gen_lowpart (SImode, operands[1]);
5494 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5495 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5496 "TARGET_EITHER && reload_completed"
5497 [(set (match_dup 0) (match_dup 1))
5498 (set (match_dup 2) (match_dup 3))]
5500 operands[2] = gen_highpart (SImode, operands[0]);
5501 operands[3] = gen_highpart (SImode, operands[1]);
5502 operands[0] = gen_lowpart (SImode, operands[0]);
5503 operands[1] = gen_lowpart (SImode, operands[1]);
5505 /* Handle a partial overlap. */
5506 if (rtx_equal_p (operands[0], operands[3]))
5508 rtx tmp0 = operands[0];
5509 rtx tmp1 = operands[1];
5511 operands[0] = operands[2];
5512 operands[1] = operands[3];
5519 ;; We can't actually do base+index doubleword loads if the index and
5520 ;; destination overlap. Split here so that we at least have chance to
5523 [(set (match_operand:DI 0 "s_register_operand" "")
5524 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5525 (match_operand:SI 2 "s_register_operand" ""))))]
5527 && reg_overlap_mentioned_p (operands[0], operands[1])
5528 && reg_overlap_mentioned_p (operands[0], operands[2])"
5530 (plus:SI (match_dup 1)
5533 (mem:DI (match_dup 4)))]
5535 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5539 (define_expand "movsi"
5540 [(set (match_operand:SI 0 "general_operand" "")
5541 (match_operand:SI 1 "general_operand" ""))]
5545 rtx base, offset, tmp;
5549 /* Everything except mem = const or mem = mem can be done easily. */
5550 if (MEM_P (operands[0]))
5551 operands[1] = force_reg (SImode, operands[1]);
5552 if (arm_general_register_operand (operands[0], SImode)
5553 && CONST_INT_P (operands[1])
5554 && !(const_ok_for_arm (INTVAL (operands[1]))
5555 || const_ok_for_arm (~INTVAL (operands[1]))))
5557 arm_split_constant (SET, SImode, NULL_RTX,
5558 INTVAL (operands[1]), operands[0], NULL_RTX,
5559 optimize && can_create_pseudo_p ());
5563 else /* TARGET_THUMB1... */
5565 if (can_create_pseudo_p ())
5567 if (!REG_P (operands[0]))
5568 operands[1] = force_reg (SImode, operands[1]);
5572 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5574 split_const (operands[1], &base, &offset);
5575 if (GET_CODE (base) == SYMBOL_REF
5576 && !offset_within_block_p (base, INTVAL (offset)))
5578 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5579 emit_move_insn (tmp, base);
5580 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5585 /* Recognize the case where operand[1] is a reference to thread-local
5586 data and load its address to a register. */
5587 if (arm_tls_referenced_p (operands[1]))
5589 rtx tmp = operands[1];
5592 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5594 addend = XEXP (XEXP (tmp, 0), 1);
5595 tmp = XEXP (XEXP (tmp, 0), 0);
5598 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
5599 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
5601 tmp = legitimize_tls_address (tmp,
5602 !can_create_pseudo_p () ? operands[0] : 0);
5605 tmp = gen_rtx_PLUS (SImode, tmp, addend);
5606 tmp = force_operand (tmp, operands[0]);
5611 && (CONSTANT_P (operands[1])
5612 || symbol_mentioned_p (operands[1])
5613 || label_mentioned_p (operands[1])))
5614 operands[1] = legitimize_pic_address (operands[1], SImode,
5615 (!can_create_pseudo_p ()
5622 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5623 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5624 ;; so this does not matter.
5625 (define_insn "*arm_movt"
5626 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
5627 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
5628 (match_operand:SI 2 "general_operand" "i")))]
5630 "movt%?\t%0, #:upper16:%c2"
5631 [(set_attr "predicable" "yes")
5632 (set_attr "predicable_short_it" "no")
5633 (set_attr "length" "4")
5634 (set_attr "type" "mov_imm")]
5637 (define_insn "*arm_movsi_insn"
5638 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5639 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
5640 "TARGET_ARM && ! TARGET_IWMMXT
5641 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5642 && ( register_operand (operands[0], SImode)
5643 || register_operand (operands[1], SImode))"
5651 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
5652 (set_attr "predicable" "yes")
5653 (set_attr "pool_range" "*,*,*,*,4096,*")
5654 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5658 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5659 (match_operand:SI 1 "const_int_operand" ""))]
5661 && (!(const_ok_for_arm (INTVAL (operands[1]))
5662 || const_ok_for_arm (~INTVAL (operands[1]))))"
5663 [(clobber (const_int 0))]
5665 arm_split_constant (SET, SImode, NULL_RTX,
5666 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5671 ;; A normal way to do (symbol + offset) requires three instructions at least
5672 ;; (depends on how big the offset is) as below:
5673 ;; movw r0, #:lower16:g
5674 ;; movw r0, #:upper16:g
5677 ;; A better way would be:
5678 ;; movw r0, #:lower16:g+4
5679 ;; movw r0, #:upper16:g+4
5681 ;; The limitation of this way is that the length of offset should be a 16-bit
5682 ;; signed value, because current assembler only supports REL type relocation for
5683 ;; such case. If the more powerful RELA type is supported in future, we should
5684 ;; update this pattern to go with better way.
5686 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5687 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5688 (match_operand:SI 2 "const_int_operand" ""))))]
5690 && arm_disable_literal_pool
5692 && GET_CODE (operands[1]) == SYMBOL_REF"
5693 [(clobber (const_int 0))]
5695 int offset = INTVAL (operands[2]);
5697 if (offset < -0x8000 || offset > 0x7fff)
5699 arm_emit_movpair (operands[0], operands[1]);
5700 emit_insn (gen_rtx_SET (SImode, operands[0],
5701 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5705 rtx op = gen_rtx_CONST (SImode,
5706 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5707 arm_emit_movpair (operands[0], op);
5712 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5713 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5714 ;; and lo_sum would be merged back into memory load at cprop. However,
5715 ;; if the default is to prefer movt/movw rather than a load from the constant
5716 ;; pool, the performance is better.
5718 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5719 (match_operand:SI 1 "general_operand" ""))]
5721 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5722 && !flag_pic && !target_word_relocations
5723 && !arm_tls_referenced_p (operands[1])"
5724 [(clobber (const_int 0))]
5726 arm_emit_movpair (operands[0], operands[1]);
5730 ;; When generating pic, we need to load the symbol offset into a register.
5731 ;; So that the optimizer does not confuse this with a normal symbol load
5732 ;; we use an unspec. The offset will be loaded from a constant pool entry,
5733 ;; since that is the only type of relocation we can use.
5735 ;; Wrap calculation of the whole PIC address in a single pattern for the
5736 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5737 ;; a PIC address involves two loads from memory, so we want to CSE it
5738 ;; as often as possible.
5739 ;; This pattern will be split into one of the pic_load_addr_* patterns
5740 ;; and a move after GCSE optimizations.
5742 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5743 (define_expand "calculate_pic_address"
5744 [(set (match_operand:SI 0 "register_operand" "")
5745 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5746 (unspec:SI [(match_operand:SI 2 "" "")]
5751 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5753 [(set (match_operand:SI 0 "register_operand" "")
5754 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5755 (unspec:SI [(match_operand:SI 2 "" "")]
5758 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5759 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5760 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5763 ;; operand1 is the memory address to go into
5764 ;; pic_load_addr_32bit.
5765 ;; operand2 is the PIC label to be emitted
5766 ;; from pic_add_dot_plus_eight.
5767 ;; We do this to allow hoisting of the entire insn.
5768 (define_insn_and_split "pic_load_addr_unified"
5769 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5770 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5771 (match_operand:SI 2 "" "")]
5772 UNSPEC_PIC_UNIFIED))]
5775 "&& reload_completed"
5776 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5777 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5778 (match_dup 2)] UNSPEC_PIC_BASE))]
5779 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5780 [(set_attr "type" "load1,load1,load1")
5781 (set_attr "pool_range" "4096,4094,1022")
5782 (set_attr "neg_pool_range" "4084,0,0")
5783 (set_attr "arch" "a,t2,t1")
5784 (set_attr "length" "8,6,4")]
5787 ;; The rather odd constraints on the following are to force reload to leave
5788 ;; the insn alone, and to force the minipool generation pass to then move
5789 ;; the GOT symbol to memory.
5791 (define_insn "pic_load_addr_32bit"
5792 [(set (match_operand:SI 0 "s_register_operand" "=r")
5793 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5794 "TARGET_32BIT && flag_pic"
5796 [(set_attr "type" "load1")
5797 (set (attr "pool_range")
5798 (if_then_else (eq_attr "is_thumb" "no")
5801 (set (attr "neg_pool_range")
5802 (if_then_else (eq_attr "is_thumb" "no")
5807 (define_insn "pic_load_addr_thumb1"
5808 [(set (match_operand:SI 0 "s_register_operand" "=l")
5809 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5810 "TARGET_THUMB1 && flag_pic"
5812 [(set_attr "type" "load1")
5813 (set (attr "pool_range") (const_int 1018))]
5816 (define_insn "pic_add_dot_plus_four"
5817 [(set (match_operand:SI 0 "register_operand" "=r")
5818 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5820 (match_operand 2 "" "")]
5824 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5825 INTVAL (operands[2]));
5826 return \"add\\t%0, %|pc\";
5828 [(set_attr "length" "2")
5829 (set_attr "type" "alu_sreg")]
5832 (define_insn "pic_add_dot_plus_eight"
5833 [(set (match_operand:SI 0 "register_operand" "=r")
5834 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5836 (match_operand 2 "" "")]
5840 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5841 INTVAL (operands[2]));
5842 return \"add%?\\t%0, %|pc, %1\";
5844 [(set_attr "predicable" "yes")
5845 (set_attr "type" "alu_sreg")]
5848 (define_insn "tls_load_dot_plus_eight"
5849 [(set (match_operand:SI 0 "register_operand" "=r")
5850 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5852 (match_operand 2 "" "")]
5856 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5857 INTVAL (operands[2]));
5858 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5860 [(set_attr "predicable" "yes")
5861 (set_attr "type" "load1")]
5864 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5865 ;; followed by a load. These sequences can be crunched down to
5866 ;; tls_load_dot_plus_eight by a peephole.
5869 [(set (match_operand:SI 0 "register_operand" "")
5870 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5872 (match_operand 1 "" "")]
5874 (set (match_operand:SI 2 "arm_general_register_operand" "")
5875 (mem:SI (match_dup 0)))]
5876 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5878 (mem:SI (unspec:SI [(match_dup 3)
5885 (define_insn "pic_offset_arm"
5886 [(set (match_operand:SI 0 "register_operand" "=r")
5887 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5888 (unspec:SI [(match_operand:SI 2 "" "X")]
5889 UNSPEC_PIC_OFFSET))))]
5890 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5891 "ldr%?\\t%0, [%1,%2]"
5892 [(set_attr "type" "load1")]
5895 (define_expand "builtin_setjmp_receiver"
5896 [(label_ref (match_operand 0 "" ""))]
5900 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5902 if (arm_pic_register != INVALID_REGNUM)
5903 arm_load_pic_register (1UL << 3);
5907 ;; If copying one reg to another we can set the condition codes according to
5908 ;; its value. Such a move is common after a return from subroutine and the
5909 ;; result is being tested against zero.
5911 (define_insn "*movsi_compare0"
5912 [(set (reg:CC CC_REGNUM)
5913 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5915 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5921 [(set_attr "conds" "set")
5922 (set_attr "type" "alus_imm,alus_imm")]
5925 ;; Subroutine to store a half word from a register into memory.
5926 ;; Operand 0 is the source register (HImode)
5927 ;; Operand 1 is the destination address in a register (SImode)
5929 ;; In both this routine and the next, we must be careful not to spill
5930 ;; a memory address of reg+large_const into a separate PLUS insn, since this
5931 ;; can generate unrecognizable rtl.
5933 (define_expand "storehi"
5934 [;; store the low byte
5935 (set (match_operand 1 "" "") (match_dup 3))
5936 ;; extract the high byte
5938 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5939 ;; store the high byte
5940 (set (match_dup 4) (match_dup 5))]
5944 rtx op1 = operands[1];
5945 rtx addr = XEXP (op1, 0);
5946 enum rtx_code code = GET_CODE (addr);
5948 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5950 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
5952 operands[4] = adjust_address (op1, QImode, 1);
5953 operands[1] = adjust_address (operands[1], QImode, 0);
5954 operands[3] = gen_lowpart (QImode, operands[0]);
5955 operands[0] = gen_lowpart (SImode, operands[0]);
5956 operands[2] = gen_reg_rtx (SImode);
5957 operands[5] = gen_lowpart (QImode, operands[2]);
5961 (define_expand "storehi_bigend"
5962 [(set (match_dup 4) (match_dup 3))
5964 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5965 (set (match_operand 1 "" "") (match_dup 5))]
5969 rtx op1 = operands[1];
5970 rtx addr = XEXP (op1, 0);
5971 enum rtx_code code = GET_CODE (addr);
5973 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5975 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
5977 operands[4] = adjust_address (op1, QImode, 1);
5978 operands[1] = adjust_address (operands[1], QImode, 0);
5979 operands[3] = gen_lowpart (QImode, operands[0]);
5980 operands[0] = gen_lowpart (SImode, operands[0]);
5981 operands[2] = gen_reg_rtx (SImode);
5982 operands[5] = gen_lowpart (QImode, operands[2]);
5986 ;; Subroutine to store a half word integer constant into memory.
5987 (define_expand "storeinthi"
5988 [(set (match_operand 0 "" "")
5989 (match_operand 1 "" ""))
5990 (set (match_dup 3) (match_dup 2))]
5994 HOST_WIDE_INT value = INTVAL (operands[1]);
5995 rtx addr = XEXP (operands[0], 0);
5996 rtx op0 = operands[0];
5997 enum rtx_code code = GET_CODE (addr);
5999 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6001 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6003 operands[1] = gen_reg_rtx (SImode);
6004 if (BYTES_BIG_ENDIAN)
6006 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6007 if ((value & 255) == ((value >> 8) & 255))
6008 operands[2] = operands[1];
6011 operands[2] = gen_reg_rtx (SImode);
6012 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6017 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6018 if ((value & 255) == ((value >> 8) & 255))
6019 operands[2] = operands[1];
6022 operands[2] = gen_reg_rtx (SImode);
6023 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6027 operands[3] = adjust_address (op0, QImode, 1);
6028 operands[0] = adjust_address (operands[0], QImode, 0);
6029 operands[2] = gen_lowpart (QImode, operands[2]);
6030 operands[1] = gen_lowpart (QImode, operands[1]);
6034 (define_expand "storehi_single_op"
6035 [(set (match_operand:HI 0 "memory_operand" "")
6036 (match_operand:HI 1 "general_operand" ""))]
6037 "TARGET_32BIT && arm_arch4"
6039 if (!s_register_operand (operands[1], HImode))
6040 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6044 (define_expand "movhi"
6045 [(set (match_operand:HI 0 "general_operand" "")
6046 (match_operand:HI 1 "general_operand" ""))]
6051 if (can_create_pseudo_p ())
6053 if (MEM_P (operands[0]))
6057 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6060 if (CONST_INT_P (operands[1]))
6061 emit_insn (gen_storeinthi (operands[0], operands[1]));
6064 if (MEM_P (operands[1]))
6065 operands[1] = force_reg (HImode, operands[1]);
6066 if (BYTES_BIG_ENDIAN)
6067 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6069 emit_insn (gen_storehi (operands[1], operands[0]));
6073 /* Sign extend a constant, and keep it in an SImode reg. */
6074 else if (CONST_INT_P (operands[1]))
6076 rtx reg = gen_reg_rtx (SImode);
6077 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6079 /* If the constant is already valid, leave it alone. */
6080 if (!const_ok_for_arm (val))
6082 /* If setting all the top bits will make the constant
6083 loadable in a single instruction, then set them.
6084 Otherwise, sign extend the number. */
6086 if (const_ok_for_arm (~(val | ~0xffff)))
6088 else if (val & 0x8000)
6092 emit_insn (gen_movsi (reg, GEN_INT (val)));
6093 operands[1] = gen_lowpart (HImode, reg);
6095 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6096 && MEM_P (operands[1]))
6098 rtx reg = gen_reg_rtx (SImode);
6100 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6101 operands[1] = gen_lowpart (HImode, reg);
6103 else if (!arm_arch4)
6105 if (MEM_P (operands[1]))
6108 rtx offset = const0_rtx;
6109 rtx reg = gen_reg_rtx (SImode);
6111 if ((REG_P (base = XEXP (operands[1], 0))
6112 || (GET_CODE (base) == PLUS
6113 && (CONST_INT_P (offset = XEXP (base, 1)))
6114 && ((INTVAL(offset) & 1) != 1)
6115 && REG_P (base = XEXP (base, 0))))
6116 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6120 new_rtx = widen_memory_access (operands[1], SImode,
6121 ((INTVAL (offset) & ~3)
6122 - INTVAL (offset)));
6123 emit_insn (gen_movsi (reg, new_rtx));
6124 if (((INTVAL (offset) & 2) != 0)
6125 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6127 rtx reg2 = gen_reg_rtx (SImode);
6129 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6134 emit_insn (gen_movhi_bytes (reg, operands[1]));
6136 operands[1] = gen_lowpart (HImode, reg);
6140 /* Handle loading a large integer during reload. */
6141 else if (CONST_INT_P (operands[1])
6142 && !const_ok_for_arm (INTVAL (operands[1]))
6143 && !const_ok_for_arm (~INTVAL (operands[1])))
6145 /* Writing a constant to memory needs a scratch, which should
6146 be handled with SECONDARY_RELOADs. */
6147 gcc_assert (REG_P (operands[0]));
6149 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6150 emit_insn (gen_movsi (operands[0], operands[1]));
6154 else if (TARGET_THUMB2)
6156 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6157 if (can_create_pseudo_p ())
6159 if (!REG_P (operands[0]))
6160 operands[1] = force_reg (HImode, operands[1]);
6161 /* Zero extend a constant, and keep it in an SImode reg. */
6162 else if (CONST_INT_P (operands[1]))
6164 rtx reg = gen_reg_rtx (SImode);
6165 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6167 emit_insn (gen_movsi (reg, GEN_INT (val)));
6168 operands[1] = gen_lowpart (HImode, reg);
6172 else /* TARGET_THUMB1 */
6174 if (can_create_pseudo_p ())
6176 if (CONST_INT_P (operands[1]))
6178 rtx reg = gen_reg_rtx (SImode);
6180 emit_insn (gen_movsi (reg, operands[1]));
6181 operands[1] = gen_lowpart (HImode, reg);
6184 /* ??? We shouldn't really get invalid addresses here, but this can
6185 happen if we are passed a SP (never OK for HImode/QImode) or
6186 virtual register (also rejected as illegitimate for HImode/QImode)
6187 relative address. */
6188 /* ??? This should perhaps be fixed elsewhere, for instance, in
6189 fixup_stack_1, by checking for other kinds of invalid addresses,
6190 e.g. a bare reference to a virtual register. This may confuse the
6191 alpha though, which must handle this case differently. */
6192 if (MEM_P (operands[0])
6193 && !memory_address_p (GET_MODE (operands[0]),
6194 XEXP (operands[0], 0)))
6196 = replace_equiv_address (operands[0],
6197 copy_to_reg (XEXP (operands[0], 0)));
6199 if (MEM_P (operands[1])
6200 && !memory_address_p (GET_MODE (operands[1]),
6201 XEXP (operands[1], 0)))
6203 = replace_equiv_address (operands[1],
6204 copy_to_reg (XEXP (operands[1], 0)));
6206 if (MEM_P (operands[1]) && optimize > 0)
6208 rtx reg = gen_reg_rtx (SImode);
6210 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6211 operands[1] = gen_lowpart (HImode, reg);
6214 if (MEM_P (operands[0]))
6215 operands[1] = force_reg (HImode, operands[1]);
6217 else if (CONST_INT_P (operands[1])
6218 && !satisfies_constraint_I (operands[1]))
6220 /* Handle loading a large integer during reload. */
6222 /* Writing a constant to memory needs a scratch, which should
6223 be handled with SECONDARY_RELOADs. */
6224 gcc_assert (REG_P (operands[0]));
6226 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6227 emit_insn (gen_movsi (operands[0], operands[1]));
6234 (define_expand "movhi_bytes"
6235 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6237 (zero_extend:SI (match_dup 6)))
6238 (set (match_operand:SI 0 "" "")
6239 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6244 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6246 mem1 = change_address (operands[1], QImode, addr);
6247 mem2 = change_address (operands[1], QImode,
6248 plus_constant (Pmode, addr, 1));
6249 operands[0] = gen_lowpart (SImode, operands[0]);
6251 operands[2] = gen_reg_rtx (SImode);
6252 operands[3] = gen_reg_rtx (SImode);
6255 if (BYTES_BIG_ENDIAN)
6257 operands[4] = operands[2];
6258 operands[5] = operands[3];
6262 operands[4] = operands[3];
6263 operands[5] = operands[2];
6268 (define_expand "movhi_bigend"
6270 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6273 (ashiftrt:SI (match_dup 2) (const_int 16)))
6274 (set (match_operand:HI 0 "s_register_operand" "")
6278 operands[2] = gen_reg_rtx (SImode);
6279 operands[3] = gen_reg_rtx (SImode);
6280 operands[4] = gen_lowpart (HImode, operands[3]);
6284 ;; Pattern to recognize insn generated default case above
6285 (define_insn "*movhi_insn_arch4"
6286 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6287 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6290 && (register_operand (operands[0], HImode)
6291 || register_operand (operands[1], HImode))"
6293 mov%?\\t%0, %1\\t%@ movhi
6294 mvn%?\\t%0, #%B1\\t%@ movhi
6295 movw%?\\t%0, %L1\\t%@ movhi
6296 str%(h%)\\t%1, %0\\t%@ movhi
6297 ldr%(h%)\\t%0, %1\\t%@ movhi"
6298 [(set_attr "predicable" "yes")
6299 (set_attr "pool_range" "*,*,*,*,256")
6300 (set_attr "neg_pool_range" "*,*,*,*,244")
6301 (set_attr "arch" "*,*,v6t2,*,*")
6302 (set_attr_alternative "type"
6303 [(if_then_else (match_operand 1 "const_int_operand" "")
6304 (const_string "mov_imm" )
6305 (const_string "mov_reg"))
6306 (const_string "mvn_imm")
6307 (const_string "mov_imm")
6308 (const_string "store1")
6309 (const_string "load1")])]
6312 (define_insn "*movhi_bytes"
6313 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6314 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6317 mov%?\\t%0, %1\\t%@ movhi
6318 mov%?\\t%0, %1\\t%@ movhi
6319 mvn%?\\t%0, #%B1\\t%@ movhi"
6320 [(set_attr "predicable" "yes")
6321 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6324 ;; We use a DImode scratch because we may occasionally need an additional
6325 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6326 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6327 (define_expand "reload_outhi"
6328 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6329 (match_operand:HI 1 "s_register_operand" "r")
6330 (match_operand:DI 2 "s_register_operand" "=&l")])]
6333 arm_reload_out_hi (operands);
6335 thumb_reload_out_hi (operands);
6340 (define_expand "reload_inhi"
6341 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6342 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6343 (match_operand:DI 2 "s_register_operand" "=&r")])]
6347 arm_reload_in_hi (operands);
6349 thumb_reload_out_hi (operands);
6353 (define_expand "movqi"
6354 [(set (match_operand:QI 0 "general_operand" "")
6355 (match_operand:QI 1 "general_operand" ""))]
6358 /* Everything except mem = const or mem = mem can be done easily */
6360 if (can_create_pseudo_p ())
6362 if (CONST_INT_P (operands[1]))
6364 rtx reg = gen_reg_rtx (SImode);
6366 /* For thumb we want an unsigned immediate, then we are more likely
6367 to be able to use a movs insn. */
6369 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6371 emit_insn (gen_movsi (reg, operands[1]));
6372 operands[1] = gen_lowpart (QImode, reg);
6377 /* ??? We shouldn't really get invalid addresses here, but this can
6378 happen if we are passed a SP (never OK for HImode/QImode) or
6379 virtual register (also rejected as illegitimate for HImode/QImode)
6380 relative address. */
6381 /* ??? This should perhaps be fixed elsewhere, for instance, in
6382 fixup_stack_1, by checking for other kinds of invalid addresses,
6383 e.g. a bare reference to a virtual register. This may confuse the
6384 alpha though, which must handle this case differently. */
6385 if (MEM_P (operands[0])
6386 && !memory_address_p (GET_MODE (operands[0]),
6387 XEXP (operands[0], 0)))
6389 = replace_equiv_address (operands[0],
6390 copy_to_reg (XEXP (operands[0], 0)));
6391 if (MEM_P (operands[1])
6392 && !memory_address_p (GET_MODE (operands[1]),
6393 XEXP (operands[1], 0)))
6395 = replace_equiv_address (operands[1],
6396 copy_to_reg (XEXP (operands[1], 0)));
6399 if (MEM_P (operands[1]) && optimize > 0)
6401 rtx reg = gen_reg_rtx (SImode);
6403 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6404 operands[1] = gen_lowpart (QImode, reg);
6407 if (MEM_P (operands[0]))
6408 operands[1] = force_reg (QImode, operands[1]);
6410 else if (TARGET_THUMB
6411 && CONST_INT_P (operands[1])
6412 && !satisfies_constraint_I (operands[1]))
6414 /* Handle loading a large integer during reload. */
6416 /* Writing a constant to memory needs a scratch, which should
6417 be handled with SECONDARY_RELOADs. */
6418 gcc_assert (REG_P (operands[0]));
6420 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6421 emit_insn (gen_movsi (operands[0], operands[1]));
6427 (define_insn "*arm_movqi_insn"
6428 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6429 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6431 && ( register_operand (operands[0], QImode)
6432 || register_operand (operands[1], QImode))"
6443 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6444 (set_attr "predicable" "yes")
6445 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
6446 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6447 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6451 (define_expand "movhf"
6452 [(set (match_operand:HF 0 "general_operand" "")
6453 (match_operand:HF 1 "general_operand" ""))]
6458 if (MEM_P (operands[0]))
6459 operands[1] = force_reg (HFmode, operands[1]);
6461 else /* TARGET_THUMB1 */
6463 if (can_create_pseudo_p ())
6465 if (!REG_P (operands[0]))
6466 operands[1] = force_reg (HFmode, operands[1]);
6472 (define_insn "*arm32_movhf"
6473 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6474 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6475 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
6476 && ( s_register_operand (operands[0], HFmode)
6477 || s_register_operand (operands[1], HFmode))"
6479 switch (which_alternative)
6481 case 0: /* ARM register from memory */
6482 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
6483 case 1: /* memory from ARM register */
6484 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
6485 case 2: /* ARM register from ARM register */
6486 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6487 case 3: /* ARM register from constant */
6493 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
6494 bits = real_to_target (NULL, &r, HFmode);
6495 ops[0] = operands[0];
6496 ops[1] = GEN_INT (bits);
6497 ops[2] = GEN_INT (bits & 0xff00);
6498 ops[3] = GEN_INT (bits & 0x00ff);
6500 if (arm_arch_thumb2)
6501 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6503 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6510 [(set_attr "conds" "unconditional")
6511 (set_attr "type" "load1,store1,mov_reg,multiple")
6512 (set_attr "length" "4,4,4,8")
6513 (set_attr "predicable" "yes")]
6516 (define_expand "movsf"
6517 [(set (match_operand:SF 0 "general_operand" "")
6518 (match_operand:SF 1 "general_operand" ""))]
6523 if (MEM_P (operands[0]))
6524 operands[1] = force_reg (SFmode, operands[1]);
6526 else /* TARGET_THUMB1 */
6528 if (can_create_pseudo_p ())
6530 if (!REG_P (operands[0]))
6531 operands[1] = force_reg (SFmode, operands[1]);
6537 ;; Transform a floating-point move of a constant into a core register into
6538 ;; an SImode operation.
6540 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6541 (match_operand:SF 1 "immediate_operand" ""))]
6544 && CONST_DOUBLE_P (operands[1])"
6545 [(set (match_dup 2) (match_dup 3))]
6547 operands[2] = gen_lowpart (SImode, operands[0]);
6548 operands[3] = gen_lowpart (SImode, operands[1]);
6549 if (operands[2] == 0 || operands[3] == 0)
6554 (define_insn "*arm_movsf_soft_insn"
6555 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6556 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6558 && TARGET_SOFT_FLOAT
6559 && (!MEM_P (operands[0])
6560 || register_operand (operands[1], SFmode))"
6563 ldr%?\\t%0, %1\\t%@ float
6564 str%?\\t%1, %0\\t%@ float"
6565 [(set_attr "predicable" "yes")
6566 (set_attr "predicable_short_it" "no")
6567 (set_attr "type" "mov_reg,load1,store1")
6568 (set_attr "arm_pool_range" "*,4096,*")
6569 (set_attr "thumb2_pool_range" "*,4094,*")
6570 (set_attr "arm_neg_pool_range" "*,4084,*")
6571 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6574 (define_expand "movdf"
6575 [(set (match_operand:DF 0 "general_operand" "")
6576 (match_operand:DF 1 "general_operand" ""))]
6581 if (MEM_P (operands[0]))
6582 operands[1] = force_reg (DFmode, operands[1]);
6584 else /* TARGET_THUMB */
6586 if (can_create_pseudo_p ())
6588 if (!REG_P (operands[0]))
6589 operands[1] = force_reg (DFmode, operands[1]);
6595 ;; Reloading a df mode value stored in integer regs to memory can require a
6597 (define_expand "reload_outdf"
6598 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6599 (match_operand:DF 1 "s_register_operand" "r")
6600 (match_operand:SI 2 "s_register_operand" "=&r")]
6604 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6607 operands[2] = XEXP (operands[0], 0);
6608 else if (code == POST_INC || code == PRE_DEC)
6610 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6611 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6612 emit_insn (gen_movdi (operands[0], operands[1]));
6615 else if (code == PRE_INC)
6617 rtx reg = XEXP (XEXP (operands[0], 0), 0);
6619 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6622 else if (code == POST_DEC)
6623 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6625 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6626 XEXP (XEXP (operands[0], 0), 1)));
6628 emit_insn (gen_rtx_SET (VOIDmode,
6629 replace_equiv_address (operands[0], operands[2]),
6632 if (code == POST_DEC)
6633 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6639 (define_insn "*movdf_soft_insn"
6640 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
6641 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
6642 "TARGET_32BIT && TARGET_SOFT_FLOAT
6643 && ( register_operand (operands[0], DFmode)
6644 || register_operand (operands[1], DFmode))"
6646 switch (which_alternative)
6653 return output_move_double (operands, true, NULL);
6656 [(set_attr "length" "8,12,16,8,8")
6657 (set_attr "type" "multiple,multiple,multiple,load2,store2")
6658 (set_attr "arm_pool_range" "*,*,*,1020,*")
6659 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6660 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6661 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6665 ;; load- and store-multiple insns
6666 ;; The arm can load/store any set of registers, provided that they are in
6667 ;; ascending order, but these expanders assume a contiguous set.
6669 (define_expand "load_multiple"
6670 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6671 (match_operand:SI 1 "" ""))
6672 (use (match_operand:SI 2 "" ""))])]
6675 HOST_WIDE_INT offset = 0;
6677 /* Support only fixed point registers. */
6678 if (!CONST_INT_P (operands[2])
6679 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6680 || INTVAL (operands[2]) < 2
6681 || !MEM_P (operands[1])
6682 || !REG_P (operands[0])
6683 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6684 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6688 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6689 INTVAL (operands[2]),
6690 force_reg (SImode, XEXP (operands[1], 0)),
6691 FALSE, operands[1], &offset);
6694 (define_expand "store_multiple"
6695 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6696 (match_operand:SI 1 "" ""))
6697 (use (match_operand:SI 2 "" ""))])]
6700 HOST_WIDE_INT offset = 0;
6702 /* Support only fixed point registers. */
6703 if (!CONST_INT_P (operands[2])
6704 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6705 || INTVAL (operands[2]) < 2
6706 || !REG_P (operands[1])
6707 || !MEM_P (operands[0])
6708 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6709 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6713 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6714 INTVAL (operands[2]),
6715 force_reg (SImode, XEXP (operands[0], 0)),
6716 FALSE, operands[0], &offset);
6720 (define_expand "setmemsi"
6721 [(match_operand:BLK 0 "general_operand" "")
6722 (match_operand:SI 1 "const_int_operand" "")
6723 (match_operand:SI 2 "const_int_operand" "")
6724 (match_operand:SI 3 "const_int_operand" "")]
6727 if (arm_gen_setmem (operands))
6734 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6735 ;; We could let this apply for blocks of less than this, but it clobbers so
6736 ;; many registers that there is then probably a better way.
6738 (define_expand "movmemqi"
6739 [(match_operand:BLK 0 "general_operand" "")
6740 (match_operand:BLK 1 "general_operand" "")
6741 (match_operand:SI 2 "const_int_operand" "")
6742 (match_operand:SI 3 "const_int_operand" "")]
6747 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6748 && !optimize_function_for_size_p (cfun))
6750 if (gen_movmem_ldrd_strd (operands))
6755 if (arm_gen_movmemqi (operands))
6759 else /* TARGET_THUMB1 */
6761 if ( INTVAL (operands[3]) != 4
6762 || INTVAL (operands[2]) > 48)
6765 thumb_expand_movmemqi (operands);
6772 ;; Compare & branch insns
6773 ;; The range calculations are based as follows:
6774 ;; For forward branches, the address calculation returns the address of
6775 ;; the next instruction. This is 2 beyond the branch instruction.
6776 ;; For backward branches, the address calculation returns the address of
6777 ;; the first instruction in this pattern (cmp). This is 2 before the branch
6778 ;; instruction for the shortest sequence, and 4 before the branch instruction
6779 ;; if we have to jump around an unconditional branch.
6780 ;; To the basic branch range the PC offset must be added (this is +4).
6781 ;; So for forward branches we have
6782 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6783 ;; And for backward branches we have
6784 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6786 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6787 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
6789 (define_expand "cbranchsi4"
6790 [(set (pc) (if_then_else
6791 (match_operator 0 "expandable_comparison_operator"
6792 [(match_operand:SI 1 "s_register_operand" "")
6793 (match_operand:SI 2 "nonmemory_operand" "")])
6794 (label_ref (match_operand 3 "" ""))
6800 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6802 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6806 if (thumb1_cmpneg_operand (operands[2], SImode))
6808 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6809 operands[3], operands[0]));
6812 if (!thumb1_cmp_operand (operands[2], SImode))
6813 operands[2] = force_reg (SImode, operands[2]);
6816 (define_expand "cbranchsf4"
6817 [(set (pc) (if_then_else
6818 (match_operator 0 "expandable_comparison_operator"
6819 [(match_operand:SF 1 "s_register_operand" "")
6820 (match_operand:SF 2 "arm_float_compare_operand" "")])
6821 (label_ref (match_operand 3 "" ""))
6823 "TARGET_32BIT && TARGET_HARD_FLOAT"
6824 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6825 operands[3])); DONE;"
6828 (define_expand "cbranchdf4"
6829 [(set (pc) (if_then_else
6830 (match_operator 0 "expandable_comparison_operator"
6831 [(match_operand:DF 1 "s_register_operand" "")
6832 (match_operand:DF 2 "arm_float_compare_operand" "")])
6833 (label_ref (match_operand 3 "" ""))
6835 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6836 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6837 operands[3])); DONE;"
6840 (define_expand "cbranchdi4"
6841 [(set (pc) (if_then_else
6842 (match_operator 0 "expandable_comparison_operator"
6843 [(match_operand:DI 1 "s_register_operand" "")
6844 (match_operand:DI 2 "cmpdi_operand" "")])
6845 (label_ref (match_operand 3 "" ""))
6849 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6851 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6857 ;; Comparison and test insns
6859 (define_insn "*arm_cmpsi_insn"
6860 [(set (reg:CC CC_REGNUM)
6861 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6862 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
6870 [(set_attr "conds" "set")
6871 (set_attr "arch" "t2,t2,any,any,any")
6872 (set_attr "length" "2,2,4,4,4")
6873 (set_attr "predicable" "yes")
6874 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6875 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6878 (define_insn "*cmpsi_shiftsi"
6879 [(set (reg:CC CC_REGNUM)
6880 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
6881 (match_operator:SI 3 "shift_operator"
6882 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6883 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6886 [(set_attr "conds" "set")
6887 (set_attr "shift" "1")
6888 (set_attr "arch" "32,a,a")
6889 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
6891 (define_insn "*cmpsi_shiftsi_swp"
6892 [(set (reg:CC_SWP CC_REGNUM)
6893 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6894 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6895 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6896 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6899 [(set_attr "conds" "set")
6900 (set_attr "shift" "1")
6901 (set_attr "arch" "32,a,a")
6902 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
6904 (define_insn "*arm_cmpsi_negshiftsi_si"
6905 [(set (reg:CC_Z CC_REGNUM)
6907 (neg:SI (match_operator:SI 1 "shift_operator"
6908 [(match_operand:SI 2 "s_register_operand" "r")
6909 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6910 (match_operand:SI 0 "s_register_operand" "r")))]
6913 [(set_attr "conds" "set")
6914 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6915 (const_string "alus_shift_imm")
6916 (const_string "alus_shift_reg")))
6917 (set_attr "predicable" "yes")]
6920 ;; DImode comparisons. The generic code generates branches that
6921 ;; if-conversion can not reduce to a conditional compare, so we do
6924 (define_insn_and_split "*arm_cmpdi_insn"
6925 [(set (reg:CC_NCV CC_REGNUM)
6926 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6927 (match_operand:DI 1 "arm_di_operand" "rDi")))
6928 (clobber (match_scratch:SI 2 "=r"))]
6930 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6931 "&& reload_completed"
6932 [(set (reg:CC CC_REGNUM)
6933 (compare:CC (match_dup 0) (match_dup 1)))
6934 (parallel [(set (reg:CC CC_REGNUM)
6935 (compare:CC (match_dup 3) (match_dup 4)))
6937 (minus:SI (match_dup 5)
6938 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
6940 operands[3] = gen_highpart (SImode, operands[0]);
6941 operands[0] = gen_lowpart (SImode, operands[0]);
6942 if (CONST_INT_P (operands[1]))
6944 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
6947 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
6951 operands[4] = gen_highpart (SImode, operands[1]);
6952 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6954 operands[1] = gen_lowpart (SImode, operands[1]);
6955 operands[2] = gen_lowpart (SImode, operands[2]);
6957 [(set_attr "conds" "set")
6958 (set_attr "length" "8")
6959 (set_attr "type" "multiple")]
6962 (define_insn_and_split "*arm_cmpdi_unsigned"
6963 [(set (reg:CC_CZ CC_REGNUM)
6964 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6965 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
6968 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6969 "&& reload_completed"
6970 [(set (reg:CC CC_REGNUM)
6971 (compare:CC (match_dup 2) (match_dup 3)))
6972 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6973 (set (reg:CC CC_REGNUM)
6974 (compare:CC (match_dup 0) (match_dup 1))))]
6976 operands[2] = gen_highpart (SImode, operands[0]);
6977 operands[0] = gen_lowpart (SImode, operands[0]);
6978 if (CONST_INT_P (operands[1]))
6979 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6981 operands[3] = gen_highpart (SImode, operands[1]);
6982 operands[1] = gen_lowpart (SImode, operands[1]);
6984 [(set_attr "conds" "set")
6985 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
6986 (set_attr "arch" "t2,t2,t2,a")
6987 (set_attr "length" "6,6,10,8")
6988 (set_attr "type" "multiple")]
6991 (define_insn "*arm_cmpdi_zero"
6992 [(set (reg:CC_Z CC_REGNUM)
6993 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6995 (clobber (match_scratch:SI 1 "=r"))]
6997 "orr%.\\t%1, %Q0, %R0"
6998 [(set_attr "conds" "set")
6999 (set_attr "type" "logics_reg")]
7002 ; This insn allows redundant compares to be removed by cse, nothing should
7003 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7004 ; is deleted later on. The match_dup will match the mode here, so that
7005 ; mode changes of the condition codes aren't lost by this even though we don't
7006 ; specify what they are.
7008 (define_insn "*deleted_compare"
7009 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7011 "\\t%@ deleted compare"
7012 [(set_attr "conds" "set")
7013 (set_attr "length" "0")
7014 (set_attr "type" "no_insn")]
7018 ;; Conditional branch insns
7020 (define_expand "cbranch_cc"
7022 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7023 (match_operand 2 "" "")])
7024 (label_ref (match_operand 3 "" ""))
7027 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7028 operands[1], operands[2], NULL_RTX);
7029 operands[2] = const0_rtx;"
7033 ;; Patterns to match conditional branch insns.
7036 (define_insn "arm_cond_branch"
7038 (if_then_else (match_operator 1 "arm_comparison_operator"
7039 [(match_operand 2 "cc_register" "") (const_int 0)])
7040 (label_ref (match_operand 0 "" ""))
7044 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7046 arm_ccfsm_state += 2;
7049 return \"b%d1\\t%l0\";
7051 [(set_attr "conds" "use")
7052 (set_attr "type" "branch")
7053 (set (attr "length")
7055 (and (match_test "TARGET_THUMB2")
7056 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7057 (le (minus (match_dup 0) (pc)) (const_int 256))))
7062 (define_insn "*arm_cond_branch_reversed"
7064 (if_then_else (match_operator 1 "arm_comparison_operator"
7065 [(match_operand 2 "cc_register" "") (const_int 0)])
7067 (label_ref (match_operand 0 "" ""))))]
7070 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7072 arm_ccfsm_state += 2;
7075 return \"b%D1\\t%l0\";
7077 [(set_attr "conds" "use")
7078 (set_attr "type" "branch")
7079 (set (attr "length")
7081 (and (match_test "TARGET_THUMB2")
7082 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7083 (le (minus (match_dup 0) (pc)) (const_int 256))))
7092 (define_expand "cstore_cc"
7093 [(set (match_operand:SI 0 "s_register_operand" "")
7094 (match_operator:SI 1 "" [(match_operand 2 "" "")
7095 (match_operand 3 "" "")]))]
7097 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7098 operands[2], operands[3], NULL_RTX);
7099 operands[3] = const0_rtx;"
7102 (define_insn_and_split "*mov_scc"
7103 [(set (match_operand:SI 0 "s_register_operand" "=r")
7104 (match_operator:SI 1 "arm_comparison_operator"
7105 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7107 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7110 (if_then_else:SI (match_dup 1)
7114 [(set_attr "conds" "use")
7115 (set_attr "length" "8")
7116 (set_attr "type" "multiple")]
7119 (define_insn_and_split "*mov_negscc"
7120 [(set (match_operand:SI 0 "s_register_operand" "=r")
7121 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
7122 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7124 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7127 (if_then_else:SI (match_dup 1)
7131 operands[3] = GEN_INT (~0);
7133 [(set_attr "conds" "use")
7134 (set_attr "length" "8")
7135 (set_attr "type" "multiple")]
7138 (define_insn_and_split "*mov_notscc"
7139 [(set (match_operand:SI 0 "s_register_operand" "=r")
7140 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7141 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7143 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7146 (if_then_else:SI (match_dup 1)
7150 operands[3] = GEN_INT (~1);
7151 operands[4] = GEN_INT (~0);
7153 [(set_attr "conds" "use")
7154 (set_attr "length" "8")
7155 (set_attr "type" "multiple")]
7158 (define_expand "cstoresi4"
7159 [(set (match_operand:SI 0 "s_register_operand" "")
7160 (match_operator:SI 1 "expandable_comparison_operator"
7161 [(match_operand:SI 2 "s_register_operand" "")
7162 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7163 "TARGET_32BIT || TARGET_THUMB1"
7165 rtx op3, scratch, scratch2;
7169 if (!arm_add_operand (operands[3], SImode))
7170 operands[3] = force_reg (SImode, operands[3]);
7171 emit_insn (gen_cstore_cc (operands[0], operands[1],
7172 operands[2], operands[3]));
7176 if (operands[3] == const0_rtx)
7178 switch (GET_CODE (operands[1]))
7181 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7185 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7189 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7190 NULL_RTX, 0, OPTAB_WIDEN);
7191 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7192 NULL_RTX, 0, OPTAB_WIDEN);
7193 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7194 operands[0], 1, OPTAB_WIDEN);
7198 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7200 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7201 NULL_RTX, 1, OPTAB_WIDEN);
7205 scratch = expand_binop (SImode, ashr_optab, operands[2],
7206 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7207 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7208 NULL_RTX, 0, OPTAB_WIDEN);
7209 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7213 /* LT is handled by generic code. No need for unsigned with 0. */
7220 switch (GET_CODE (operands[1]))
7223 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7224 NULL_RTX, 0, OPTAB_WIDEN);
7225 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7229 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7230 NULL_RTX, 0, OPTAB_WIDEN);
7231 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7235 op3 = force_reg (SImode, operands[3]);
7237 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7238 NULL_RTX, 1, OPTAB_WIDEN);
7239 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7240 NULL_RTX, 0, OPTAB_WIDEN);
7241 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7247 if (!thumb1_cmp_operand (op3, SImode))
7248 op3 = force_reg (SImode, op3);
7249 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7250 NULL_RTX, 0, OPTAB_WIDEN);
7251 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7252 NULL_RTX, 1, OPTAB_WIDEN);
7253 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7258 op3 = force_reg (SImode, operands[3]);
7259 scratch = force_reg (SImode, const0_rtx);
7260 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7266 if (!thumb1_cmp_operand (op3, SImode))
7267 op3 = force_reg (SImode, op3);
7268 scratch = force_reg (SImode, const0_rtx);
7269 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7275 if (!thumb1_cmp_operand (op3, SImode))
7276 op3 = force_reg (SImode, op3);
7277 scratch = gen_reg_rtx (SImode);
7278 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7282 op3 = force_reg (SImode, operands[3]);
7283 scratch = gen_reg_rtx (SImode);
7284 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7287 /* No good sequences for GT, LT. */
7294 (define_expand "cstoresf4"
7295 [(set (match_operand:SI 0 "s_register_operand" "")
7296 (match_operator:SI 1 "expandable_comparison_operator"
7297 [(match_operand:SF 2 "s_register_operand" "")
7298 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7299 "TARGET_32BIT && TARGET_HARD_FLOAT"
7300 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7301 operands[2], operands[3])); DONE;"
7304 (define_expand "cstoredf4"
7305 [(set (match_operand:SI 0 "s_register_operand" "")
7306 (match_operator:SI 1 "expandable_comparison_operator"
7307 [(match_operand:DF 2 "s_register_operand" "")
7308 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7309 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7310 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7311 operands[2], operands[3])); DONE;"
7314 (define_expand "cstoredi4"
7315 [(set (match_operand:SI 0 "s_register_operand" "")
7316 (match_operator:SI 1 "expandable_comparison_operator"
7317 [(match_operand:DI 2 "s_register_operand" "")
7318 (match_operand:DI 3 "cmpdi_operand" "")]))]
7321 if (!arm_validize_comparison (&operands[1],
7325 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7332 ;; Conditional move insns
7334 (define_expand "movsicc"
7335 [(set (match_operand:SI 0 "s_register_operand" "")
7336 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7337 (match_operand:SI 2 "arm_not_operand" "")
7338 (match_operand:SI 3 "arm_not_operand" "")))]
7345 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7346 &XEXP (operands[1], 1)))
7349 code = GET_CODE (operands[1]);
7350 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7351 XEXP (operands[1], 1), NULL_RTX);
7352 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7356 (define_expand "movsfcc"
7357 [(set (match_operand:SF 0 "s_register_operand" "")
7358 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7359 (match_operand:SF 2 "s_register_operand" "")
7360 (match_operand:SF 3 "s_register_operand" "")))]
7361 "TARGET_32BIT && TARGET_HARD_FLOAT"
7364 enum rtx_code code = GET_CODE (operands[1]);
7367 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7368 &XEXP (operands[1], 1)))
7371 code = GET_CODE (operands[1]);
7372 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7373 XEXP (operands[1], 1), NULL_RTX);
7374 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7378 (define_expand "movdfcc"
7379 [(set (match_operand:DF 0 "s_register_operand" "")
7380 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7381 (match_operand:DF 2 "s_register_operand" "")
7382 (match_operand:DF 3 "s_register_operand" "")))]
7383 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7386 enum rtx_code code = GET_CODE (operands[1]);
7389 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7390 &XEXP (operands[1], 1)))
7392 code = GET_CODE (operands[1]);
7393 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7394 XEXP (operands[1], 1), NULL_RTX);
7395 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7399 (define_insn "*cmov<mode>"
7400 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7401 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7402 [(match_operand 2 "cc_register" "") (const_int 0)])
7403 (match_operand:SDF 3 "s_register_operand"
7405 (match_operand:SDF 4 "s_register_operand"
7406 "<F_constraint>")))]
7407 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7410 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7417 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7422 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7428 [(set_attr "conds" "use")
7429 (set_attr "type" "fcsel")]
7432 (define_insn_and_split "*movsicc_insn"
7433 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7435 (match_operator 3 "arm_comparison_operator"
7436 [(match_operand 4 "cc_register" "") (const_int 0)])
7437 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7438 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7449 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7450 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7451 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7452 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7453 "&& reload_completed"
7456 enum rtx_code rev_code;
7460 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7462 gen_rtx_SET (VOIDmode,
7466 rev_code = GET_CODE (operands[3]);
7467 mode = GET_MODE (operands[4]);
7468 if (mode == CCFPmode || mode == CCFPEmode)
7469 rev_code = reverse_condition_maybe_unordered (rev_code);
7471 rev_code = reverse_condition (rev_code);
7473 rev_cond = gen_rtx_fmt_ee (rev_code,
7477 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7479 gen_rtx_SET (VOIDmode,
7484 [(set_attr "length" "4,4,4,4,8,8,8,8")
7485 (set_attr "conds" "use")
7486 (set_attr_alternative "type"
7487 [(if_then_else (match_operand 2 "const_int_operand" "")
7488 (const_string "mov_imm")
7489 (const_string "mov_reg"))
7490 (const_string "mvn_imm")
7491 (if_then_else (match_operand 1 "const_int_operand" "")
7492 (const_string "mov_imm")
7493 (const_string "mov_reg"))
7494 (const_string "mvn_imm")
7495 (const_string "mov_reg")
7496 (const_string "mov_reg")
7497 (const_string "mov_reg")
7498 (const_string "mov_reg")])]
7501 (define_insn "*movsfcc_soft_insn"
7502 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7503 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7504 [(match_operand 4 "cc_register" "") (const_int 0)])
7505 (match_operand:SF 1 "s_register_operand" "0,r")
7506 (match_operand:SF 2 "s_register_operand" "r,0")))]
7507 "TARGET_ARM && TARGET_SOFT_FLOAT"
7511 [(set_attr "conds" "use")
7512 (set_attr "type" "mov_reg")]
7516 ;; Jump and linkage insns
7518 (define_expand "jump"
7520 (label_ref (match_operand 0 "" "")))]
7525 (define_insn "*arm_jump"
7527 (label_ref (match_operand 0 "" "")))]
7531 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7533 arm_ccfsm_state += 2;
7536 return \"b%?\\t%l0\";
7539 [(set_attr "predicable" "yes")
7540 (set (attr "length")
7542 (and (match_test "TARGET_THUMB2")
7543 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7544 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7547 (set_attr "type" "branch")]
7550 (define_expand "call"
7551 [(parallel [(call (match_operand 0 "memory_operand" "")
7552 (match_operand 1 "general_operand" ""))
7553 (use (match_operand 2 "" ""))
7554 (clobber (reg:SI LR_REGNUM))])]
7560 /* In an untyped call, we can get NULL for operand 2. */
7561 if (operands[2] == NULL_RTX)
7562 operands[2] = const0_rtx;
7564 /* Decide if we should generate indirect calls by loading the
7565 32-bit address of the callee into a register before performing the
7567 callee = XEXP (operands[0], 0);
7568 if (GET_CODE (callee) == SYMBOL_REF
7569 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7571 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7573 pat = gen_call_internal (operands[0], operands[1], operands[2]);
7574 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7579 (define_expand "call_internal"
7580 [(parallel [(call (match_operand 0 "memory_operand" "")
7581 (match_operand 1 "general_operand" ""))
7582 (use (match_operand 2 "" ""))
7583 (clobber (reg:SI LR_REGNUM))])])
7585 (define_insn "*call_reg_armv5"
7586 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7587 (match_operand 1 "" ""))
7588 (use (match_operand 2 "" ""))
7589 (clobber (reg:SI LR_REGNUM))]
7590 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7592 [(set_attr "type" "call")]
7595 (define_insn "*call_reg_arm"
7596 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7597 (match_operand 1 "" ""))
7598 (use (match_operand 2 "" ""))
7599 (clobber (reg:SI LR_REGNUM))]
7600 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7602 return output_call (operands);
7604 ;; length is worst case, normally it is only two
7605 [(set_attr "length" "12")
7606 (set_attr "type" "call")]
7610 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
7611 ;; considered a function call by the branch predictor of some cores (PR40887).
7612 ;; Falls back to blx rN (*call_reg_armv5).
7614 (define_insn "*call_mem"
7615 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
7616 (match_operand 1 "" ""))
7617 (use (match_operand 2 "" ""))
7618 (clobber (reg:SI LR_REGNUM))]
7619 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7621 return output_call_mem (operands);
7623 [(set_attr "length" "12")
7624 (set_attr "type" "call")]
7627 (define_expand "call_value"
7628 [(parallel [(set (match_operand 0 "" "")
7629 (call (match_operand 1 "memory_operand" "")
7630 (match_operand 2 "general_operand" "")))
7631 (use (match_operand 3 "" ""))
7632 (clobber (reg:SI LR_REGNUM))])]
7638 /* In an untyped call, we can get NULL for operand 2. */
7639 if (operands[3] == 0)
7640 operands[3] = const0_rtx;
7642 /* Decide if we should generate indirect calls by loading the
7643 32-bit address of the callee into a register before performing the
7645 callee = XEXP (operands[1], 0);
7646 if (GET_CODE (callee) == SYMBOL_REF
7647 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7649 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7651 pat = gen_call_value_internal (operands[0], operands[1],
7652 operands[2], operands[3]);
7653 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7658 (define_expand "call_value_internal"
7659 [(parallel [(set (match_operand 0 "" "")
7660 (call (match_operand 1 "memory_operand" "")
7661 (match_operand 2 "general_operand" "")))
7662 (use (match_operand 3 "" ""))
7663 (clobber (reg:SI LR_REGNUM))])])
7665 (define_insn "*call_value_reg_armv5"
7666 [(set (match_operand 0 "" "")
7667 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7668 (match_operand 2 "" "")))
7669 (use (match_operand 3 "" ""))
7670 (clobber (reg:SI LR_REGNUM))]
7671 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
7673 [(set_attr "type" "call")]
7676 (define_insn "*call_value_reg_arm"
7677 [(set (match_operand 0 "" "")
7678 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7679 (match_operand 2 "" "")))
7680 (use (match_operand 3 "" ""))
7681 (clobber (reg:SI LR_REGNUM))]
7682 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
7684 return output_call (&operands[1]);
7686 [(set_attr "length" "12")
7687 (set_attr "type" "call")]
7690 ;; Note: see *call_mem
7692 (define_insn "*call_value_mem"
7693 [(set (match_operand 0 "" "")
7694 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
7695 (match_operand 2 "" "")))
7696 (use (match_operand 3 "" ""))
7697 (clobber (reg:SI LR_REGNUM))]
7698 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
7699 && !SIBLING_CALL_P (insn)"
7701 return output_call_mem (&operands[1]);
7703 [(set_attr "length" "12")
7704 (set_attr "type" "call")]
7707 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7708 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7710 (define_insn "*call_symbol"
7711 [(call (mem:SI (match_operand:SI 0 "" ""))
7712 (match_operand 1 "" ""))
7713 (use (match_operand 2 "" ""))
7714 (clobber (reg:SI LR_REGNUM))]
7716 && !SIBLING_CALL_P (insn)
7717 && (GET_CODE (operands[0]) == SYMBOL_REF)
7718 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7721 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7723 [(set_attr "type" "call")]
7726 (define_insn "*call_value_symbol"
7727 [(set (match_operand 0 "" "")
7728 (call (mem:SI (match_operand:SI 1 "" ""))
7729 (match_operand:SI 2 "" "")))
7730 (use (match_operand 3 "" ""))
7731 (clobber (reg:SI LR_REGNUM))]
7733 && !SIBLING_CALL_P (insn)
7734 && (GET_CODE (operands[1]) == SYMBOL_REF)
7735 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7738 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7740 [(set_attr "type" "call")]
7743 (define_expand "sibcall_internal"
7744 [(parallel [(call (match_operand 0 "memory_operand" "")
7745 (match_operand 1 "general_operand" ""))
7747 (use (match_operand 2 "" ""))])])
7749 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7750 (define_expand "sibcall"
7751 [(parallel [(call (match_operand 0 "memory_operand" "")
7752 (match_operand 1 "general_operand" ""))
7754 (use (match_operand 2 "" ""))])]
7760 if ((!REG_P (XEXP (operands[0], 0))
7761 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7762 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7763 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7764 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7766 if (operands[2] == NULL_RTX)
7767 operands[2] = const0_rtx;
7769 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7770 arm_emit_call_insn (pat, operands[0], true);
7775 (define_expand "sibcall_value_internal"
7776 [(parallel [(set (match_operand 0 "" "")
7777 (call (match_operand 1 "memory_operand" "")
7778 (match_operand 2 "general_operand" "")))
7780 (use (match_operand 3 "" ""))])])
7782 (define_expand "sibcall_value"
7783 [(parallel [(set (match_operand 0 "" "")
7784 (call (match_operand 1 "memory_operand" "")
7785 (match_operand 2 "general_operand" "")))
7787 (use (match_operand 3 "" ""))])]
7793 if ((!REG_P (XEXP (operands[1], 0))
7794 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7795 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7796 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7797 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7799 if (operands[3] == NULL_RTX)
7800 operands[3] = const0_rtx;
7802 pat = gen_sibcall_value_internal (operands[0], operands[1],
7803 operands[2], operands[3]);
7804 arm_emit_call_insn (pat, operands[1], true);
7809 (define_insn "*sibcall_insn"
7810 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7811 (match_operand 1 "" ""))
7813 (use (match_operand 2 "" ""))]
7814 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7816 if (which_alternative == 1)
7817 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7820 if (arm_arch5 || arm_arch4t)
7821 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7823 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7826 [(set_attr "type" "call")]
7829 (define_insn "*sibcall_value_insn"
7830 [(set (match_operand 0 "" "")
7831 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7832 (match_operand 2 "" "")))
7834 (use (match_operand 3 "" ""))]
7835 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7837 if (which_alternative == 1)
7838 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7841 if (arm_arch5 || arm_arch4t)
7842 return \"bx%?\\t%1\";
7844 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7847 [(set_attr "type" "call")]
7850 (define_expand "<return_str>return"
7852 "(TARGET_ARM || (TARGET_THUMB2
7853 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7854 && !IS_STACKALIGN (arm_current_func_type ())))
7855 <return_cond_false>"
7860 thumb2_expand_return (<return_simple_p>);
7867 ;; Often the return insn will be the same as loading from memory, so set attr
7868 (define_insn "*arm_return"
7870 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7873 if (arm_ccfsm_state == 2)
7875 arm_ccfsm_state += 2;
7878 return output_return_instruction (const_true_rtx, true, false, false);
7880 [(set_attr "type" "load1")
7881 (set_attr "length" "12")
7882 (set_attr "predicable" "yes")]
7885 (define_insn "*cond_<return_str>return"
7887 (if_then_else (match_operator 0 "arm_comparison_operator"
7888 [(match_operand 1 "cc_register" "") (const_int 0)])
7891 "TARGET_ARM <return_cond_true>"
7894 if (arm_ccfsm_state == 2)
7896 arm_ccfsm_state += 2;
7899 return output_return_instruction (operands[0], true, false,
7902 [(set_attr "conds" "use")
7903 (set_attr "length" "12")
7904 (set_attr "type" "load1")]
7907 (define_insn "*cond_<return_str>return_inverted"
7909 (if_then_else (match_operator 0 "arm_comparison_operator"
7910 [(match_operand 1 "cc_register" "") (const_int 0)])
7913 "TARGET_ARM <return_cond_true>"
7916 if (arm_ccfsm_state == 2)
7918 arm_ccfsm_state += 2;
7921 return output_return_instruction (operands[0], true, true,
7924 [(set_attr "conds" "use")
7925 (set_attr "length" "12")
7926 (set_attr "type" "load1")]
7929 (define_insn "*arm_simple_return"
7934 if (arm_ccfsm_state == 2)
7936 arm_ccfsm_state += 2;
7939 return output_return_instruction (const_true_rtx, true, false, true);
7941 [(set_attr "type" "branch")
7942 (set_attr "length" "4")
7943 (set_attr "predicable" "yes")]
7946 ;; Generate a sequence of instructions to determine if the processor is
7947 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7950 (define_expand "return_addr_mask"
7952 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7954 (set (match_operand:SI 0 "s_register_operand" "")
7955 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7957 (const_int 67108860)))] ; 0x03fffffc
7960 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7963 (define_insn "*check_arch2"
7964 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7965 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7968 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7969 [(set_attr "length" "8")
7970 (set_attr "conds" "set")
7971 (set_attr "type" "multiple")]
7974 ;; Call subroutine returning any type.
7976 (define_expand "untyped_call"
7977 [(parallel [(call (match_operand 0 "" "")
7979 (match_operand 1 "" "")
7980 (match_operand 2 "" "")])]
7985 rtx par = gen_rtx_PARALLEL (VOIDmode,
7986 rtvec_alloc (XVECLEN (operands[2], 0)));
7987 rtx addr = gen_reg_rtx (Pmode);
7991 emit_move_insn (addr, XEXP (operands[1], 0));
7992 mem = change_address (operands[1], BLKmode, addr);
7994 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7996 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
7998 /* Default code only uses r0 as a return value, but we could
7999 be using anything up to 4 registers. */
8000 if (REGNO (src) == R0_REGNUM)
8001 src = gen_rtx_REG (TImode, R0_REGNUM);
8003 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8005 size += GET_MODE_SIZE (GET_MODE (src));
8008 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
8013 for (i = 0; i < XVECLEN (par, 0); i++)
8015 HOST_WIDE_INT offset = 0;
8016 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8019 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8021 mem = change_address (mem, GET_MODE (reg), NULL);
8022 if (REGNO (reg) == R0_REGNUM)
8024 /* On thumb we have to use a write-back instruction. */
8025 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8026 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8027 size = TARGET_ARM ? 16 : 0;
8031 emit_move_insn (mem, reg);
8032 size = GET_MODE_SIZE (GET_MODE (reg));
8036 /* The optimizer does not know that the call sets the function value
8037 registers we stored in the result block. We avoid problems by
8038 claiming that all hard registers are used and clobbered at this
8040 emit_insn (gen_blockage ());
8046 (define_expand "untyped_return"
8047 [(match_operand:BLK 0 "memory_operand" "")
8048 (match_operand 1 "" "")]
8053 rtx addr = gen_reg_rtx (Pmode);
8057 emit_move_insn (addr, XEXP (operands[0], 0));
8058 mem = change_address (operands[0], BLKmode, addr);
8060 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8062 HOST_WIDE_INT offset = 0;
8063 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8066 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8068 mem = change_address (mem, GET_MODE (reg), NULL);
8069 if (REGNO (reg) == R0_REGNUM)
8071 /* On thumb we have to use a write-back instruction. */
8072 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8073 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8074 size = TARGET_ARM ? 16 : 0;
8078 emit_move_insn (reg, mem);
8079 size = GET_MODE_SIZE (GET_MODE (reg));
8083 /* Emit USE insns before the return. */
8084 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8085 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8087 /* Construct the return. */
8088 expand_naked_return ();
8094 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8095 ;; all of memory. This blocks insns from being moved across this point.
8097 (define_insn "blockage"
8098 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8101 [(set_attr "length" "0")
8102 (set_attr "type" "block")]
8105 (define_expand "casesi"
8106 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8107 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8108 (match_operand:SI 2 "const_int_operand" "") ; total range
8109 (match_operand:SI 3 "" "") ; table label
8110 (match_operand:SI 4 "" "")] ; Out of range label
8111 "TARGET_32BIT || optimize_size || flag_pic"
8114 enum insn_code code;
8115 if (operands[1] != const0_rtx)
8117 rtx reg = gen_reg_rtx (SImode);
8119 emit_insn (gen_addsi3 (reg, operands[0],
8120 gen_int_mode (-INTVAL (operands[1]),
8126 code = CODE_FOR_arm_casesi_internal;
8127 else if (TARGET_THUMB1)
8128 code = CODE_FOR_thumb1_casesi_internal_pic;
8130 code = CODE_FOR_thumb2_casesi_internal_pic;
8132 code = CODE_FOR_thumb2_casesi_internal;
8134 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8135 operands[2] = force_reg (SImode, operands[2]);
8137 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8138 operands[3], operands[4]));
8143 ;; The USE in this pattern is needed to tell flow analysis that this is
8144 ;; a CASESI insn. It has no other purpose.
8145 (define_insn "arm_casesi_internal"
8146 [(parallel [(set (pc)
8148 (leu (match_operand:SI 0 "s_register_operand" "r")
8149 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8150 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8151 (label_ref (match_operand 2 "" ""))))
8152 (label_ref (match_operand 3 "" ""))))
8153 (clobber (reg:CC CC_REGNUM))
8154 (use (label_ref (match_dup 2)))])]
8158 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8159 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8161 [(set_attr "conds" "clob")
8162 (set_attr "length" "12")
8163 (set_attr "type" "multiple")]
8166 (define_expand "indirect_jump"
8168 (match_operand:SI 0 "s_register_operand" ""))]
8171 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8172 address and use bx. */
8176 tmp = gen_reg_rtx (SImode);
8177 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8183 ;; NB Never uses BX.
8184 (define_insn "*arm_indirect_jump"
8186 (match_operand:SI 0 "s_register_operand" "r"))]
8188 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8189 [(set_attr "predicable" "yes")
8190 (set_attr "type" "branch")]
8193 (define_insn "*load_indirect_jump"
8195 (match_operand:SI 0 "memory_operand" "m"))]
8197 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8198 [(set_attr "type" "load1")
8199 (set_attr "pool_range" "4096")
8200 (set_attr "neg_pool_range" "4084")
8201 (set_attr "predicable" "yes")]
8211 if (TARGET_UNIFIED_ASM)
8214 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
8215 return \"mov\\tr8, r8\";
8217 [(set (attr "length")
8218 (if_then_else (eq_attr "is_thumb" "yes")
8221 (set_attr "type" "mov_reg")]
8225 [(trap_if (const_int 1) (const_int 0))]
8229 return \".inst\\t0xe7f000f0\";
8231 return \".inst\\t0xdeff\";
8233 [(set (attr "length")
8234 (if_then_else (eq_attr "is_thumb" "yes")
8237 (set_attr "type" "trap")
8238 (set_attr "conds" "unconditional")]
8242 ;; Patterns to allow combination of arithmetic, cond code and shifts
8244 (define_insn "*<arith_shift_insn>_multsi"
8245 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8247 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8248 (match_operand:SI 3 "power_of_two_operand" ""))
8249 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8251 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8252 [(set_attr "predicable" "yes")
8253 (set_attr "predicable_short_it" "no")
8254 (set_attr "shift" "2")
8255 (set_attr "arch" "a,t2")
8256 (set_attr "type" "alu_shift_imm")])
8258 (define_insn "*<arith_shift_insn>_shiftsi"
8259 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8261 (match_operator:SI 2 "shift_nomul_operator"
8262 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8263 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8264 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8265 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8266 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8267 [(set_attr "predicable" "yes")
8268 (set_attr "predicable_short_it" "no")
8269 (set_attr "shift" "3")
8270 (set_attr "arch" "a,t2,a")
8271 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8274 [(set (match_operand:SI 0 "s_register_operand" "")
8275 (match_operator:SI 1 "shiftable_operator"
8276 [(match_operator:SI 2 "shiftable_operator"
8277 [(match_operator:SI 3 "shift_operator"
8278 [(match_operand:SI 4 "s_register_operand" "")
8279 (match_operand:SI 5 "reg_or_int_operand" "")])
8280 (match_operand:SI 6 "s_register_operand" "")])
8281 (match_operand:SI 7 "arm_rhs_operand" "")]))
8282 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8285 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8288 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8291 (define_insn "*arith_shiftsi_compare0"
8292 [(set (reg:CC_NOOV CC_REGNUM)
8294 (match_operator:SI 1 "shiftable_operator"
8295 [(match_operator:SI 3 "shift_operator"
8296 [(match_operand:SI 4 "s_register_operand" "r,r")
8297 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8298 (match_operand:SI 2 "s_register_operand" "r,r")])
8300 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8301 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8304 "%i1%.\\t%0, %2, %4%S3"
8305 [(set_attr "conds" "set")
8306 (set_attr "shift" "4")
8307 (set_attr "arch" "32,a")
8308 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8310 (define_insn "*arith_shiftsi_compare0_scratch"
8311 [(set (reg:CC_NOOV CC_REGNUM)
8313 (match_operator:SI 1 "shiftable_operator"
8314 [(match_operator:SI 3 "shift_operator"
8315 [(match_operand:SI 4 "s_register_operand" "r,r")
8316 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8317 (match_operand:SI 2 "s_register_operand" "r,r")])
8319 (clobber (match_scratch:SI 0 "=r,r"))]
8321 "%i1%.\\t%0, %2, %4%S3"
8322 [(set_attr "conds" "set")
8323 (set_attr "shift" "4")
8324 (set_attr "arch" "32,a")
8325 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8327 (define_insn "*sub_shiftsi"
8328 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8329 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8330 (match_operator:SI 2 "shift_operator"
8331 [(match_operand:SI 3 "s_register_operand" "r,r")
8332 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8334 "sub%?\\t%0, %1, %3%S2"
8335 [(set_attr "predicable" "yes")
8336 (set_attr "shift" "3")
8337 (set_attr "arch" "32,a")
8338 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8340 (define_insn "*sub_shiftsi_compare0"
8341 [(set (reg:CC_NOOV CC_REGNUM)
8343 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8344 (match_operator:SI 2 "shift_operator"
8345 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8346 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8348 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8349 (minus:SI (match_dup 1)
8350 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8352 "sub%.\\t%0, %1, %3%S2"
8353 [(set_attr "conds" "set")
8354 (set_attr "shift" "3")
8355 (set_attr "arch" "32,a,a")
8356 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8358 (define_insn "*sub_shiftsi_compare0_scratch"
8359 [(set (reg:CC_NOOV CC_REGNUM)
8361 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8362 (match_operator:SI 2 "shift_operator"
8363 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8364 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8366 (clobber (match_scratch:SI 0 "=r,r,r"))]
8368 "sub%.\\t%0, %1, %3%S2"
8369 [(set_attr "conds" "set")
8370 (set_attr "shift" "3")
8371 (set_attr "arch" "32,a,a")
8372 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8375 (define_insn_and_split "*and_scc"
8376 [(set (match_operand:SI 0 "s_register_operand" "=r")
8377 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8378 [(match_operand 2 "cc_register" "") (const_int 0)])
8379 (match_operand:SI 3 "s_register_operand" "r")))]
8381 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8382 "&& reload_completed"
8383 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8384 (cond_exec (match_dup 4) (set (match_dup 0)
8385 (and:SI (match_dup 3) (const_int 1))))]
8387 machine_mode mode = GET_MODE (operands[2]);
8388 enum rtx_code rc = GET_CODE (operands[1]);
8390 /* Note that operands[4] is the same as operands[1],
8391 but with VOIDmode as the result. */
8392 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8393 if (mode == CCFPmode || mode == CCFPEmode)
8394 rc = reverse_condition_maybe_unordered (rc);
8396 rc = reverse_condition (rc);
8397 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8399 [(set_attr "conds" "use")
8400 (set_attr "type" "multiple")
8401 (set_attr "length" "8")]
8404 (define_insn_and_split "*ior_scc"
8405 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8406 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8407 [(match_operand 2 "cc_register" "") (const_int 0)])
8408 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8413 "&& reload_completed
8414 && REGNO (operands [0]) != REGNO (operands[3])"
8415 ;; && which_alternative == 1
8416 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8417 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8418 (cond_exec (match_dup 4) (set (match_dup 0)
8419 (ior:SI (match_dup 3) (const_int 1))))]
8421 machine_mode mode = GET_MODE (operands[2]);
8422 enum rtx_code rc = GET_CODE (operands[1]);
8424 /* Note that operands[4] is the same as operands[1],
8425 but with VOIDmode as the result. */
8426 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8427 if (mode == CCFPmode || mode == CCFPEmode)
8428 rc = reverse_condition_maybe_unordered (rc);
8430 rc = reverse_condition (rc);
8431 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8433 [(set_attr "conds" "use")
8434 (set_attr "length" "4,8")
8435 (set_attr "type" "logic_imm,multiple")]
8438 ; A series of splitters for the compare_scc pattern below. Note that
8439 ; order is important.
8441 [(set (match_operand:SI 0 "s_register_operand" "")
8442 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8444 (clobber (reg:CC CC_REGNUM))]
8445 "TARGET_32BIT && reload_completed"
8446 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8449 [(set (match_operand:SI 0 "s_register_operand" "")
8450 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8452 (clobber (reg:CC CC_REGNUM))]
8453 "TARGET_32BIT && reload_completed"
8454 [(set (match_dup 0) (not:SI (match_dup 1)))
8455 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8458 [(set (match_operand:SI 0 "s_register_operand" "")
8459 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8461 (clobber (reg:CC CC_REGNUM))]
8462 "arm_arch5 && TARGET_32BIT"
8463 [(set (match_dup 0) (clz:SI (match_dup 1)))
8464 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8468 [(set (match_operand:SI 0 "s_register_operand" "")
8469 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8471 (clobber (reg:CC CC_REGNUM))]
8472 "TARGET_32BIT && reload_completed"
8474 [(set (reg:CC CC_REGNUM)
8475 (compare:CC (const_int 1) (match_dup 1)))
8477 (minus:SI (const_int 1) (match_dup 1)))])
8478 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8479 (set (match_dup 0) (const_int 0)))])
8482 [(set (match_operand:SI 0 "s_register_operand" "")
8483 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8484 (match_operand:SI 2 "const_int_operand" "")))
8485 (clobber (reg:CC CC_REGNUM))]
8486 "TARGET_32BIT && reload_completed"
8488 [(set (reg:CC CC_REGNUM)
8489 (compare:CC (match_dup 1) (match_dup 2)))
8490 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8491 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8492 (set (match_dup 0) (const_int 1)))]
8494 operands[3] = GEN_INT (-INTVAL (operands[2]));
8498 [(set (match_operand:SI 0 "s_register_operand" "")
8499 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8500 (match_operand:SI 2 "arm_add_operand" "")))
8501 (clobber (reg:CC CC_REGNUM))]
8502 "TARGET_32BIT && reload_completed"
8504 [(set (reg:CC_NOOV CC_REGNUM)
8505 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8507 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8508 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8509 (set (match_dup 0) (const_int 1)))])
8511 (define_insn_and_split "*compare_scc"
8512 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8513 (match_operator:SI 1 "arm_comparison_operator"
8514 [(match_operand:SI 2 "s_register_operand" "r,r")
8515 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8516 (clobber (reg:CC CC_REGNUM))]
8519 "&& reload_completed"
8520 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8521 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8522 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8525 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8526 operands[2], operands[3]);
8527 enum rtx_code rc = GET_CODE (operands[1]);
8529 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8531 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8532 if (mode == CCFPmode || mode == CCFPEmode)
8533 rc = reverse_condition_maybe_unordered (rc);
8535 rc = reverse_condition (rc);
8536 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8538 [(set_attr "type" "multiple")]
8541 ;; Attempt to improve the sequence generated by the compare_scc splitters
8542 ;; not to use conditional execution.
8544 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
8548 [(set (reg:CC CC_REGNUM)
8549 (compare:CC (match_operand:SI 1 "register_operand" "")
8551 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8552 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8553 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8554 (set (match_dup 0) (const_int 1)))]
8555 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8556 [(set (match_dup 0) (clz:SI (match_dup 1)))
8557 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8560 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8564 [(set (reg:CC CC_REGNUM)
8565 (compare:CC (match_operand:SI 1 "register_operand" "")
8567 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8568 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8569 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8570 (set (match_dup 0) (const_int 1)))
8571 (match_scratch:SI 2 "r")]
8572 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8574 [(set (reg:CC CC_REGNUM)
8575 (compare:CC (const_int 0) (match_dup 1)))
8576 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8578 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8579 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8582 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
8583 ;; sub Rd, Reg1, reg2
8587 [(set (reg:CC CC_REGNUM)
8588 (compare:CC (match_operand:SI 1 "register_operand" "")
8589 (match_operand:SI 2 "arm_rhs_operand" "")))
8590 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8591 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8592 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8593 (set (match_dup 0) (const_int 1)))]
8594 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8595 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8596 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8597 (set (match_dup 0) (clz:SI (match_dup 0)))
8598 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8602 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
8603 ;; sub T1, Reg1, reg2
8607 [(set (reg:CC CC_REGNUM)
8608 (compare:CC (match_operand:SI 1 "register_operand" "")
8609 (match_operand:SI 2 "arm_rhs_operand" "")))
8610 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8611 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8612 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8613 (set (match_dup 0) (const_int 1)))
8614 (match_scratch:SI 3 "r")]
8615 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8616 [(set (match_dup 3) (match_dup 4))
8618 [(set (reg:CC CC_REGNUM)
8619 (compare:CC (const_int 0) (match_dup 3)))
8620 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8622 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8623 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8625 if (CONST_INT_P (operands[2]))
8626 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8628 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8631 (define_insn "*cond_move"
8632 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8633 (if_then_else:SI (match_operator 3 "equality_operator"
8634 [(match_operator 4 "arm_comparison_operator"
8635 [(match_operand 5 "cc_register" "") (const_int 0)])
8637 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8638 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8641 if (GET_CODE (operands[3]) == NE)
8643 if (which_alternative != 1)
8644 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8645 if (which_alternative != 0)
8646 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8649 if (which_alternative != 0)
8650 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8651 if (which_alternative != 1)
8652 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8655 [(set_attr "conds" "use")
8656 (set_attr "type" "mov_reg,mov_reg,multiple")
8657 (set_attr "length" "4,4,8")]
8660 (define_insn "*cond_arith"
8661 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8662 (match_operator:SI 5 "shiftable_operator"
8663 [(match_operator:SI 4 "arm_comparison_operator"
8664 [(match_operand:SI 2 "s_register_operand" "r,r")
8665 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8666 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8667 (clobber (reg:CC CC_REGNUM))]
8670 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8671 return \"%i5\\t%0, %1, %2, lsr #31\";
8673 output_asm_insn (\"cmp\\t%2, %3\", operands);
8674 if (GET_CODE (operands[5]) == AND)
8675 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8676 else if (GET_CODE (operands[5]) == MINUS)
8677 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8678 else if (which_alternative != 0)
8679 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8680 return \"%i5%d4\\t%0, %1, #1\";
8682 [(set_attr "conds" "clob")
8683 (set_attr "length" "12")
8684 (set_attr "type" "multiple")]
8687 (define_insn "*cond_sub"
8688 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8689 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8690 (match_operator:SI 4 "arm_comparison_operator"
8691 [(match_operand:SI 2 "s_register_operand" "r,r")
8692 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8693 (clobber (reg:CC CC_REGNUM))]
8696 output_asm_insn (\"cmp\\t%2, %3\", operands);
8697 if (which_alternative != 0)
8698 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8699 return \"sub%d4\\t%0, %1, #1\";
8701 [(set_attr "conds" "clob")
8702 (set_attr "length" "8,12")
8703 (set_attr "type" "multiple")]
8706 (define_insn "*cmp_ite0"
8707 [(set (match_operand 6 "dominant_cc_register" "")
8710 (match_operator 4 "arm_comparison_operator"
8711 [(match_operand:SI 0 "s_register_operand"
8712 "l,l,l,r,r,r,r,r,r")
8713 (match_operand:SI 1 "arm_add_operand"
8714 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8715 (match_operator:SI 5 "arm_comparison_operator"
8716 [(match_operand:SI 2 "s_register_operand"
8717 "l,r,r,l,l,r,r,r,r")
8718 (match_operand:SI 3 "arm_add_operand"
8719 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8725 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8727 {\"cmp%d5\\t%0, %1\",
8728 \"cmp%d4\\t%2, %3\"},
8729 {\"cmn%d5\\t%0, #%n1\",
8730 \"cmp%d4\\t%2, %3\"},
8731 {\"cmp%d5\\t%0, %1\",
8732 \"cmn%d4\\t%2, #%n3\"},
8733 {\"cmn%d5\\t%0, #%n1\",
8734 \"cmn%d4\\t%2, #%n3\"}
8736 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8741 \"cmn\\t%0, #%n1\"},
8742 {\"cmn\\t%2, #%n3\",
8744 {\"cmn\\t%2, #%n3\",
8747 static const char * const ite[2] =
8752 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8753 CMP_CMP, CMN_CMP, CMP_CMP,
8754 CMN_CMP, CMP_CMN, CMN_CMN};
8756 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8758 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8759 if (TARGET_THUMB2) {
8760 output_asm_insn (ite[swap], operands);
8762 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8765 [(set_attr "conds" "set")
8766 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8767 (set_attr "type" "multiple")
8768 (set_attr_alternative "length"
8774 (if_then_else (eq_attr "is_thumb" "no")
8777 (if_then_else (eq_attr "is_thumb" "no")
8780 (if_then_else (eq_attr "is_thumb" "no")
8783 (if_then_else (eq_attr "is_thumb" "no")
8788 (define_insn "*cmp_ite1"
8789 [(set (match_operand 6 "dominant_cc_register" "")
8792 (match_operator 4 "arm_comparison_operator"
8793 [(match_operand:SI 0 "s_register_operand"
8794 "l,l,l,r,r,r,r,r,r")
8795 (match_operand:SI 1 "arm_add_operand"
8796 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8797 (match_operator:SI 5 "arm_comparison_operator"
8798 [(match_operand:SI 2 "s_register_operand"
8799 "l,r,r,l,l,r,r,r,r")
8800 (match_operand:SI 3 "arm_add_operand"
8801 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8807 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8811 {\"cmn\\t%0, #%n1\",
8814 \"cmn\\t%2, #%n3\"},
8815 {\"cmn\\t%0, #%n1\",
8818 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8820 {\"cmp%d4\\t%2, %3\",
8821 \"cmp%D5\\t%0, %1\"},
8822 {\"cmp%d4\\t%2, %3\",
8823 \"cmn%D5\\t%0, #%n1\"},
8824 {\"cmn%d4\\t%2, #%n3\",
8825 \"cmp%D5\\t%0, %1\"},
8826 {\"cmn%d4\\t%2, #%n3\",
8827 \"cmn%D5\\t%0, #%n1\"}
8829 static const char * const ite[2] =
8834 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8835 CMP_CMP, CMN_CMP, CMP_CMP,
8836 CMN_CMP, CMP_CMN, CMN_CMN};
8838 comparison_dominates_p (GET_CODE (operands[5]),
8839 reverse_condition (GET_CODE (operands[4])));
8841 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8842 if (TARGET_THUMB2) {
8843 output_asm_insn (ite[swap], operands);
8845 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8848 [(set_attr "conds" "set")
8849 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8850 (set_attr_alternative "length"
8856 (if_then_else (eq_attr "is_thumb" "no")
8859 (if_then_else (eq_attr "is_thumb" "no")
8862 (if_then_else (eq_attr "is_thumb" "no")
8865 (if_then_else (eq_attr "is_thumb" "no")
8868 (set_attr "type" "multiple")]
8871 (define_insn "*cmp_and"
8872 [(set (match_operand 6 "dominant_cc_register" "")
8875 (match_operator 4 "arm_comparison_operator"
8876 [(match_operand:SI 0 "s_register_operand"
8877 "l,l,l,r,r,r,r,r,r")
8878 (match_operand:SI 1 "arm_add_operand"
8879 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8880 (match_operator:SI 5 "arm_comparison_operator"
8881 [(match_operand:SI 2 "s_register_operand"
8882 "l,r,r,l,l,r,r,r,r")
8883 (match_operand:SI 3 "arm_add_operand"
8884 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8889 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8891 {\"cmp%d5\\t%0, %1\",
8892 \"cmp%d4\\t%2, %3\"},
8893 {\"cmn%d5\\t%0, #%n1\",
8894 \"cmp%d4\\t%2, %3\"},
8895 {\"cmp%d5\\t%0, %1\",
8896 \"cmn%d4\\t%2, #%n3\"},
8897 {\"cmn%d5\\t%0, #%n1\",
8898 \"cmn%d4\\t%2, #%n3\"}
8900 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8905 \"cmn\\t%0, #%n1\"},
8906 {\"cmn\\t%2, #%n3\",
8908 {\"cmn\\t%2, #%n3\",
8911 static const char *const ite[2] =
8916 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8917 CMP_CMP, CMN_CMP, CMP_CMP,
8918 CMN_CMP, CMP_CMN, CMN_CMN};
8920 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8922 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8923 if (TARGET_THUMB2) {
8924 output_asm_insn (ite[swap], operands);
8926 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8929 [(set_attr "conds" "set")
8930 (set_attr "predicable" "no")
8931 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8932 (set_attr_alternative "length"
8938 (if_then_else (eq_attr "is_thumb" "no")
8941 (if_then_else (eq_attr "is_thumb" "no")
8944 (if_then_else (eq_attr "is_thumb" "no")
8947 (if_then_else (eq_attr "is_thumb" "no")
8950 (set_attr "type" "multiple")]
8953 (define_insn "*cmp_ior"
8954 [(set (match_operand 6 "dominant_cc_register" "")
8957 (match_operator 4 "arm_comparison_operator"
8958 [(match_operand:SI 0 "s_register_operand"
8959 "l,l,l,r,r,r,r,r,r")
8960 (match_operand:SI 1 "arm_add_operand"
8961 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8962 (match_operator:SI 5 "arm_comparison_operator"
8963 [(match_operand:SI 2 "s_register_operand"
8964 "l,r,r,l,l,r,r,r,r")
8965 (match_operand:SI 3 "arm_add_operand"
8966 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
8971 static const char *const cmp1[NUM_OF_COND_CMP][2] =
8975 {\"cmn\\t%0, #%n1\",
8978 \"cmn\\t%2, #%n3\"},
8979 {\"cmn\\t%0, #%n1\",
8982 static const char *const cmp2[NUM_OF_COND_CMP][2] =
8984 {\"cmp%D4\\t%2, %3\",
8985 \"cmp%D5\\t%0, %1\"},
8986 {\"cmp%D4\\t%2, %3\",
8987 \"cmn%D5\\t%0, #%n1\"},
8988 {\"cmn%D4\\t%2, #%n3\",
8989 \"cmp%D5\\t%0, %1\"},
8990 {\"cmn%D4\\t%2, #%n3\",
8991 \"cmn%D5\\t%0, #%n1\"}
8993 static const char *const ite[2] =
8998 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8999 CMP_CMP, CMN_CMP, CMP_CMP,
9000 CMN_CMP, CMP_CMN, CMN_CMN};
9002 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9004 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9005 if (TARGET_THUMB2) {
9006 output_asm_insn (ite[swap], operands);
9008 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9012 [(set_attr "conds" "set")
9013 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9014 (set_attr_alternative "length"
9020 (if_then_else (eq_attr "is_thumb" "no")
9023 (if_then_else (eq_attr "is_thumb" "no")
9026 (if_then_else (eq_attr "is_thumb" "no")
9029 (if_then_else (eq_attr "is_thumb" "no")
9032 (set_attr "type" "multiple")]
9035 (define_insn_and_split "*ior_scc_scc"
9036 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9037 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9038 [(match_operand:SI 1 "s_register_operand" "r")
9039 (match_operand:SI 2 "arm_add_operand" "rIL")])
9040 (match_operator:SI 6 "arm_comparison_operator"
9041 [(match_operand:SI 4 "s_register_operand" "r")
9042 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9043 (clobber (reg:CC CC_REGNUM))]
9045 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9048 "TARGET_32BIT && reload_completed"
9052 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9053 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9055 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9057 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9060 [(set_attr "conds" "clob")
9061 (set_attr "length" "16")
9062 (set_attr "type" "multiple")]
9065 ; If the above pattern is followed by a CMP insn, then the compare is
9066 ; redundant, since we can rework the conditional instruction that follows.
9067 (define_insn_and_split "*ior_scc_scc_cmp"
9068 [(set (match_operand 0 "dominant_cc_register" "")
9069 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9070 [(match_operand:SI 1 "s_register_operand" "r")
9071 (match_operand:SI 2 "arm_add_operand" "rIL")])
9072 (match_operator:SI 6 "arm_comparison_operator"
9073 [(match_operand:SI 4 "s_register_operand" "r")
9074 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9076 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9077 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9078 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9081 "TARGET_32BIT && reload_completed"
9085 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9086 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9088 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9090 [(set_attr "conds" "set")
9091 (set_attr "length" "16")
9092 (set_attr "type" "multiple")]
9095 (define_insn_and_split "*and_scc_scc"
9096 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9097 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9098 [(match_operand:SI 1 "s_register_operand" "r")
9099 (match_operand:SI 2 "arm_add_operand" "rIL")])
9100 (match_operator:SI 6 "arm_comparison_operator"
9101 [(match_operand:SI 4 "s_register_operand" "r")
9102 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9103 (clobber (reg:CC CC_REGNUM))]
9105 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9108 "TARGET_32BIT && reload_completed
9109 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9114 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9115 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9117 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9119 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9122 [(set_attr "conds" "clob")
9123 (set_attr "length" "16")
9124 (set_attr "type" "multiple")]
9127 ; If the above pattern is followed by a CMP insn, then the compare is
9128 ; redundant, since we can rework the conditional instruction that follows.
9129 (define_insn_and_split "*and_scc_scc_cmp"
9130 [(set (match_operand 0 "dominant_cc_register" "")
9131 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9132 [(match_operand:SI 1 "s_register_operand" "r")
9133 (match_operand:SI 2 "arm_add_operand" "rIL")])
9134 (match_operator:SI 6 "arm_comparison_operator"
9135 [(match_operand:SI 4 "s_register_operand" "r")
9136 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9138 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9139 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9140 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9143 "TARGET_32BIT && reload_completed"
9147 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9148 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9150 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9152 [(set_attr "conds" "set")
9153 (set_attr "length" "16")
9154 (set_attr "type" "multiple")]
9157 ;; If there is no dominance in the comparison, then we can still save an
9158 ;; instruction in the AND case, since we can know that the second compare
9159 ;; need only zero the value if false (if true, then the value is already
9161 (define_insn_and_split "*and_scc_scc_nodom"
9162 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9163 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9164 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9165 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9166 (match_operator:SI 6 "arm_comparison_operator"
9167 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9168 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9169 (clobber (reg:CC CC_REGNUM))]
9171 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9174 "TARGET_32BIT && reload_completed"
9175 [(parallel [(set (match_dup 0)
9176 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9177 (clobber (reg:CC CC_REGNUM))])
9178 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9180 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9183 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9184 operands[4], operands[5]),
9186 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9188 [(set_attr "conds" "clob")
9189 (set_attr "length" "20")
9190 (set_attr "type" "multiple")]
9194 [(set (reg:CC_NOOV CC_REGNUM)
9195 (compare:CC_NOOV (ior:SI
9196 (and:SI (match_operand:SI 0 "s_register_operand" "")
9198 (match_operator:SI 1 "arm_comparison_operator"
9199 [(match_operand:SI 2 "s_register_operand" "")
9200 (match_operand:SI 3 "arm_add_operand" "")]))
9202 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9205 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9207 (set (reg:CC_NOOV CC_REGNUM)
9208 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9213 [(set (reg:CC_NOOV CC_REGNUM)
9214 (compare:CC_NOOV (ior:SI
9215 (match_operator:SI 1 "arm_comparison_operator"
9216 [(match_operand:SI 2 "s_register_operand" "")
9217 (match_operand:SI 3 "arm_add_operand" "")])
9218 (and:SI (match_operand:SI 0 "s_register_operand" "")
9221 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9224 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9226 (set (reg:CC_NOOV CC_REGNUM)
9227 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9230 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9232 (define_insn_and_split "*negscc"
9233 [(set (match_operand:SI 0 "s_register_operand" "=r")
9234 (neg:SI (match_operator 3 "arm_comparison_operator"
9235 [(match_operand:SI 1 "s_register_operand" "r")
9236 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9237 (clobber (reg:CC CC_REGNUM))]
9240 "&& reload_completed"
9243 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9245 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9247 /* Emit mov\\t%0, %1, asr #31 */
9248 emit_insn (gen_rtx_SET (VOIDmode,
9250 gen_rtx_ASHIFTRT (SImode,
9255 else if (GET_CODE (operands[3]) == NE)
9257 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9258 if (CONST_INT_P (operands[2]))
9259 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9260 GEN_INT (- INTVAL (operands[2]))));
9262 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9264 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9268 gen_rtx_SET (SImode,
9275 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9276 emit_insn (gen_rtx_SET (VOIDmode,
9278 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9279 enum rtx_code rc = GET_CODE (operands[3]);
9281 rc = reverse_condition (rc);
9282 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9287 gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
9288 rc = GET_CODE (operands[3]);
9289 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9294 gen_rtx_SET (VOIDmode,
9301 [(set_attr "conds" "clob")
9302 (set_attr "length" "12")
9303 (set_attr "type" "multiple")]
9306 (define_insn_and_split "movcond_addsi"
9307 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9309 (match_operator 5 "comparison_operator"
9310 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9311 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9313 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9314 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9315 (clobber (reg:CC CC_REGNUM))]
9318 "&& reload_completed"
9319 [(set (reg:CC_NOOV CC_REGNUM)
9321 (plus:SI (match_dup 3)
9324 (set (match_dup 0) (match_dup 1))
9325 (cond_exec (match_dup 6)
9326 (set (match_dup 0) (match_dup 2)))]
9329 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9330 operands[3], operands[4]);
9331 enum rtx_code rc = GET_CODE (operands[5]);
9332 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9333 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9334 if (REGNO (operands[2]) != REGNO (operands[0]))
9335 rc = reverse_condition (rc);
9337 std::swap (operands[1], operands[2]);
9339 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9342 [(set_attr "conds" "clob")
9343 (set_attr "enabled_for_depr_it" "no,yes,yes")
9344 (set_attr "type" "multiple")]
9347 (define_insn "movcond"
9348 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9350 (match_operator 5 "arm_comparison_operator"
9351 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9352 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9353 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9354 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9355 (clobber (reg:CC CC_REGNUM))]
9358 if (GET_CODE (operands[5]) == LT
9359 && (operands[4] == const0_rtx))
9361 if (which_alternative != 1 && REG_P (operands[1]))
9363 if (operands[2] == const0_rtx)
9364 return \"and\\t%0, %1, %3, asr #31\";
9365 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9367 else if (which_alternative != 0 && REG_P (operands[2]))
9369 if (operands[1] == const0_rtx)
9370 return \"bic\\t%0, %2, %3, asr #31\";
9371 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9373 /* The only case that falls through to here is when both ops 1 & 2
9377 if (GET_CODE (operands[5]) == GE
9378 && (operands[4] == const0_rtx))
9380 if (which_alternative != 1 && REG_P (operands[1]))
9382 if (operands[2] == const0_rtx)
9383 return \"bic\\t%0, %1, %3, asr #31\";
9384 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9386 else if (which_alternative != 0 && REG_P (operands[2]))
9388 if (operands[1] == const0_rtx)
9389 return \"and\\t%0, %2, %3, asr #31\";
9390 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9392 /* The only case that falls through to here is when both ops 1 & 2
9395 if (CONST_INT_P (operands[4])
9396 && !const_ok_for_arm (INTVAL (operands[4])))
9397 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9399 output_asm_insn (\"cmp\\t%3, %4\", operands);
9400 if (which_alternative != 0)
9401 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9402 if (which_alternative != 1)
9403 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9406 [(set_attr "conds" "clob")
9407 (set_attr "length" "8,8,12")
9408 (set_attr "type" "multiple")]
9411 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9413 (define_insn "*ifcompare_plus_move"
9414 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9415 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9416 [(match_operand:SI 4 "s_register_operand" "r,r")
9417 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9419 (match_operand:SI 2 "s_register_operand" "r,r")
9420 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9421 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9422 (clobber (reg:CC CC_REGNUM))]
9425 [(set_attr "conds" "clob")
9426 (set_attr "length" "8,12")
9427 (set_attr "type" "multiple")]
9430 (define_insn "*if_plus_move"
9431 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9433 (match_operator 4 "arm_comparison_operator"
9434 [(match_operand 5 "cc_register" "") (const_int 0)])
9436 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9437 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9438 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9442 sub%d4\\t%0, %2, #%n3
9443 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9444 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9445 [(set_attr "conds" "use")
9446 (set_attr "length" "4,4,8,8")
9447 (set_attr_alternative "type"
9448 [(if_then_else (match_operand 3 "const_int_operand" "")
9449 (const_string "alu_imm" )
9450 (const_string "alu_sreg"))
9451 (const_string "alu_imm")
9452 (const_string "alu_sreg")
9453 (const_string "alu_sreg")])]
9456 (define_insn "*ifcompare_move_plus"
9457 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9458 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9459 [(match_operand:SI 4 "s_register_operand" "r,r")
9460 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9461 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9463 (match_operand:SI 2 "s_register_operand" "r,r")
9464 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9465 (clobber (reg:CC CC_REGNUM))]
9468 [(set_attr "conds" "clob")
9469 (set_attr "length" "8,12")
9470 (set_attr "type" "multiple")]
9473 (define_insn "*if_move_plus"
9474 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9476 (match_operator 4 "arm_comparison_operator"
9477 [(match_operand 5 "cc_register" "") (const_int 0)])
9478 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9480 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9481 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9485 sub%D4\\t%0, %2, #%n3
9486 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9487 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9488 [(set_attr "conds" "use")
9489 (set_attr "length" "4,4,8,8")
9490 (set_attr "type" "alu_sreg,alu_imm,multiple,multiple")]
9493 (define_insn "*ifcompare_arith_arith"
9494 [(set (match_operand:SI 0 "s_register_operand" "=r")
9495 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9496 [(match_operand:SI 5 "s_register_operand" "r")
9497 (match_operand:SI 6 "arm_add_operand" "rIL")])
9498 (match_operator:SI 8 "shiftable_operator"
9499 [(match_operand:SI 1 "s_register_operand" "r")
9500 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9501 (match_operator:SI 7 "shiftable_operator"
9502 [(match_operand:SI 3 "s_register_operand" "r")
9503 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9504 (clobber (reg:CC CC_REGNUM))]
9507 [(set_attr "conds" "clob")
9508 (set_attr "length" "12")
9509 (set_attr "type" "multiple")]
9512 (define_insn "*if_arith_arith"
9513 [(set (match_operand:SI 0 "s_register_operand" "=r")
9514 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9515 [(match_operand 8 "cc_register" "") (const_int 0)])
9516 (match_operator:SI 6 "shiftable_operator"
9517 [(match_operand:SI 1 "s_register_operand" "r")
9518 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9519 (match_operator:SI 7 "shiftable_operator"
9520 [(match_operand:SI 3 "s_register_operand" "r")
9521 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9523 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9524 [(set_attr "conds" "use")
9525 (set_attr "length" "8")
9526 (set_attr "type" "multiple")]
9529 (define_insn "*ifcompare_arith_move"
9530 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9531 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9532 [(match_operand:SI 2 "s_register_operand" "r,r")
9533 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9534 (match_operator:SI 7 "shiftable_operator"
9535 [(match_operand:SI 4 "s_register_operand" "r,r")
9536 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9537 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9538 (clobber (reg:CC CC_REGNUM))]
9541 /* If we have an operation where (op x 0) is the identity operation and
9542 the conditional operator is LT or GE and we are comparing against zero and
9543 everything is in registers then we can do this in two instructions. */
9544 if (operands[3] == const0_rtx
9545 && GET_CODE (operands[7]) != AND
9546 && REG_P (operands[5])
9547 && REG_P (operands[1])
9548 && REGNO (operands[1]) == REGNO (operands[4])
9549 && REGNO (operands[4]) != REGNO (operands[0]))
9551 if (GET_CODE (operands[6]) == LT)
9552 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9553 else if (GET_CODE (operands[6]) == GE)
9554 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9556 if (CONST_INT_P (operands[3])
9557 && !const_ok_for_arm (INTVAL (operands[3])))
9558 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9560 output_asm_insn (\"cmp\\t%2, %3\", operands);
9561 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9562 if (which_alternative != 0)
9563 return \"mov%D6\\t%0, %1\";
9566 [(set_attr "conds" "clob")
9567 (set_attr "length" "8,12")
9568 (set_attr "type" "multiple")]
9571 (define_insn "*if_arith_move"
9572 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9573 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9574 [(match_operand 6 "cc_register" "") (const_int 0)])
9575 (match_operator:SI 5 "shiftable_operator"
9576 [(match_operand:SI 2 "s_register_operand" "r,r")
9577 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9578 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9582 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9583 [(set_attr "conds" "use")
9584 (set_attr "length" "4,8")
9585 (set_attr "type" "alu_shift_reg,multiple")]
9588 (define_insn "*ifcompare_move_arith"
9589 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9590 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9591 [(match_operand:SI 4 "s_register_operand" "r,r")
9592 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9593 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9594 (match_operator:SI 7 "shiftable_operator"
9595 [(match_operand:SI 2 "s_register_operand" "r,r")
9596 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9597 (clobber (reg:CC CC_REGNUM))]
9600 /* If we have an operation where (op x 0) is the identity operation and
9601 the conditional operator is LT or GE and we are comparing against zero and
9602 everything is in registers then we can do this in two instructions */
9603 if (operands[5] == const0_rtx
9604 && GET_CODE (operands[7]) != AND
9605 && REG_P (operands[3])
9606 && REG_P (operands[1])
9607 && REGNO (operands[1]) == REGNO (operands[2])
9608 && REGNO (operands[2]) != REGNO (operands[0]))
9610 if (GET_CODE (operands[6]) == GE)
9611 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9612 else if (GET_CODE (operands[6]) == LT)
9613 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9616 if (CONST_INT_P (operands[5])
9617 && !const_ok_for_arm (INTVAL (operands[5])))
9618 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9620 output_asm_insn (\"cmp\\t%4, %5\", operands);
9622 if (which_alternative != 0)
9623 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9624 return \"%I7%D6\\t%0, %2, %3\";
9626 [(set_attr "conds" "clob")
9627 (set_attr "length" "8,12")
9628 (set_attr "type" "multiple")]
9631 (define_insn "*if_move_arith"
9632 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9634 (match_operator 4 "arm_comparison_operator"
9635 [(match_operand 6 "cc_register" "") (const_int 0)])
9636 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9637 (match_operator:SI 5 "shiftable_operator"
9638 [(match_operand:SI 2 "s_register_operand" "r,r")
9639 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9643 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9644 [(set_attr "conds" "use")
9645 (set_attr "length" "4,8")
9646 (set_attr "type" "alu_shift_reg,multiple")]
9649 (define_insn "*ifcompare_move_not"
9650 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9652 (match_operator 5 "arm_comparison_operator"
9653 [(match_operand:SI 3 "s_register_operand" "r,r")
9654 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9655 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9657 (match_operand:SI 2 "s_register_operand" "r,r"))))
9658 (clobber (reg:CC CC_REGNUM))]
9661 [(set_attr "conds" "clob")
9662 (set_attr "length" "8,12")
9663 (set_attr "type" "multiple")]
9666 (define_insn "*if_move_not"
9667 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9669 (match_operator 4 "arm_comparison_operator"
9670 [(match_operand 3 "cc_register" "") (const_int 0)])
9671 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9672 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9676 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9677 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9678 [(set_attr "conds" "use")
9679 (set_attr "type" "mvn_reg")
9680 (set_attr "length" "4,8,8")
9681 (set_attr "type" "mvn_reg,multiple,multiple")]
9684 (define_insn "*ifcompare_not_move"
9685 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9687 (match_operator 5 "arm_comparison_operator"
9688 [(match_operand:SI 3 "s_register_operand" "r,r")
9689 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9691 (match_operand:SI 2 "s_register_operand" "r,r"))
9692 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9693 (clobber (reg:CC CC_REGNUM))]
9696 [(set_attr "conds" "clob")
9697 (set_attr "length" "8,12")
9698 (set_attr "type" "multiple")]
9701 (define_insn "*if_not_move"
9702 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9704 (match_operator 4 "arm_comparison_operator"
9705 [(match_operand 3 "cc_register" "") (const_int 0)])
9706 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9707 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9711 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9712 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9713 [(set_attr "conds" "use")
9714 (set_attr "type" "mvn_reg,multiple,multiple")
9715 (set_attr "length" "4,8,8")]
9718 (define_insn "*ifcompare_shift_move"
9719 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9721 (match_operator 6 "arm_comparison_operator"
9722 [(match_operand:SI 4 "s_register_operand" "r,r")
9723 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9724 (match_operator:SI 7 "shift_operator"
9725 [(match_operand:SI 2 "s_register_operand" "r,r")
9726 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9727 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9728 (clobber (reg:CC CC_REGNUM))]
9731 [(set_attr "conds" "clob")
9732 (set_attr "length" "8,12")
9733 (set_attr "type" "multiple")]
9736 (define_insn "*if_shift_move"
9737 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9739 (match_operator 5 "arm_comparison_operator"
9740 [(match_operand 6 "cc_register" "") (const_int 0)])
9741 (match_operator:SI 4 "shift_operator"
9742 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9743 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9744 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9748 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
9749 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
9750 [(set_attr "conds" "use")
9751 (set_attr "shift" "2")
9752 (set_attr "length" "4,8,8")
9753 (set_attr "type" "mov_shift_reg,multiple,multiple")]
9756 (define_insn "*ifcompare_move_shift"
9757 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9759 (match_operator 6 "arm_comparison_operator"
9760 [(match_operand:SI 4 "s_register_operand" "r,r")
9761 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9762 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9763 (match_operator:SI 7 "shift_operator"
9764 [(match_operand:SI 2 "s_register_operand" "r,r")
9765 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
9766 (clobber (reg:CC CC_REGNUM))]
9769 [(set_attr "conds" "clob")
9770 (set_attr "length" "8,12")
9771 (set_attr "type" "multiple")]
9774 (define_insn "*if_move_shift"
9775 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9777 (match_operator 5 "arm_comparison_operator"
9778 [(match_operand 6 "cc_register" "") (const_int 0)])
9779 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9780 (match_operator:SI 4 "shift_operator"
9781 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9782 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
9786 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
9787 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
9788 [(set_attr "conds" "use")
9789 (set_attr "shift" "2")
9790 (set_attr "length" "4,8,8")
9791 (set_attr "type" "mov_shift_reg,multiple,multiple")]
9794 (define_insn "*ifcompare_shift_shift"
9795 [(set (match_operand:SI 0 "s_register_operand" "=r")
9797 (match_operator 7 "arm_comparison_operator"
9798 [(match_operand:SI 5 "s_register_operand" "r")
9799 (match_operand:SI 6 "arm_add_operand" "rIL")])
9800 (match_operator:SI 8 "shift_operator"
9801 [(match_operand:SI 1 "s_register_operand" "r")
9802 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9803 (match_operator:SI 9 "shift_operator"
9804 [(match_operand:SI 3 "s_register_operand" "r")
9805 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
9806 (clobber (reg:CC CC_REGNUM))]
9809 [(set_attr "conds" "clob")
9810 (set_attr "length" "12")
9811 (set_attr "type" "multiple")]
9814 (define_insn "*if_shift_shift"
9815 [(set (match_operand:SI 0 "s_register_operand" "=r")
9817 (match_operator 5 "arm_comparison_operator"
9818 [(match_operand 8 "cc_register" "") (const_int 0)])
9819 (match_operator:SI 6 "shift_operator"
9820 [(match_operand:SI 1 "s_register_operand" "r")
9821 (match_operand:SI 2 "arm_rhs_operand" "rM")])
9822 (match_operator:SI 7 "shift_operator"
9823 [(match_operand:SI 3 "s_register_operand" "r")
9824 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
9826 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
9827 [(set_attr "conds" "use")
9828 (set_attr "shift" "1")
9829 (set_attr "length" "8")
9830 (set (attr "type") (if_then_else
9831 (and (match_operand 2 "const_int_operand" "")
9832 (match_operand 4 "const_int_operand" ""))
9833 (const_string "mov_shift")
9834 (const_string "mov_shift_reg")))]
9837 (define_insn "*ifcompare_not_arith"
9838 [(set (match_operand:SI 0 "s_register_operand" "=r")
9840 (match_operator 6 "arm_comparison_operator"
9841 [(match_operand:SI 4 "s_register_operand" "r")
9842 (match_operand:SI 5 "arm_add_operand" "rIL")])
9843 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9844 (match_operator:SI 7 "shiftable_operator"
9845 [(match_operand:SI 2 "s_register_operand" "r")
9846 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
9847 (clobber (reg:CC CC_REGNUM))]
9850 [(set_attr "conds" "clob")
9851 (set_attr "length" "12")
9852 (set_attr "type" "multiple")]
9855 (define_insn "*if_not_arith"
9856 [(set (match_operand:SI 0 "s_register_operand" "=r")
9858 (match_operator 5 "arm_comparison_operator"
9859 [(match_operand 4 "cc_register" "") (const_int 0)])
9860 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
9861 (match_operator:SI 6 "shiftable_operator"
9862 [(match_operand:SI 2 "s_register_operand" "r")
9863 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
9865 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
9866 [(set_attr "conds" "use")
9867 (set_attr "type" "mvn_reg")
9868 (set_attr "length" "8")]
9871 (define_insn "*ifcompare_arith_not"
9872 [(set (match_operand:SI 0 "s_register_operand" "=r")
9874 (match_operator 6 "arm_comparison_operator"
9875 [(match_operand:SI 4 "s_register_operand" "r")
9876 (match_operand:SI 5 "arm_add_operand" "rIL")])
9877 (match_operator:SI 7 "shiftable_operator"
9878 [(match_operand:SI 2 "s_register_operand" "r")
9879 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9880 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
9881 (clobber (reg:CC CC_REGNUM))]
9884 [(set_attr "conds" "clob")
9885 (set_attr "length" "12")
9886 (set_attr "type" "multiple")]
9889 (define_insn "*if_arith_not"
9890 [(set (match_operand:SI 0 "s_register_operand" "=r")
9892 (match_operator 5 "arm_comparison_operator"
9893 [(match_operand 4 "cc_register" "") (const_int 0)])
9894 (match_operator:SI 6 "shiftable_operator"
9895 [(match_operand:SI 2 "s_register_operand" "r")
9896 (match_operand:SI 3 "arm_rhs_operand" "rI")])
9897 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
9899 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
9900 [(set_attr "conds" "use")
9901 (set_attr "type" "multiple")
9902 (set_attr "length" "8")]
9905 (define_insn "*ifcompare_neg_move"
9906 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9908 (match_operator 5 "arm_comparison_operator"
9909 [(match_operand:SI 3 "s_register_operand" "r,r")
9910 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9911 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
9912 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9913 (clobber (reg:CC CC_REGNUM))]
9916 [(set_attr "conds" "clob")
9917 (set_attr "length" "8,12")
9918 (set_attr "type" "multiple")]
9921 (define_insn "*if_neg_move"
9922 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9924 (match_operator 4 "arm_comparison_operator"
9925 [(match_operand 3 "cc_register" "") (const_int 0)])
9926 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9927 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9931 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
9932 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
9933 [(set_attr "conds" "use")
9934 (set_attr "length" "4,8,8")
9935 (set_attr "type" "logic_shift_imm,multiple,multiple")]
9938 (define_insn "*ifcompare_move_neg"
9939 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9941 (match_operator 5 "arm_comparison_operator"
9942 [(match_operand:SI 3 "s_register_operand" "r,r")
9943 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9944 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9945 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
9946 (clobber (reg:CC CC_REGNUM))]
9949 [(set_attr "conds" "clob")
9950 (set_attr "length" "8,12")
9951 (set_attr "type" "multiple")]
9954 (define_insn "*if_move_neg"
9955 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9957 (match_operator 4 "arm_comparison_operator"
9958 [(match_operand 3 "cc_register" "") (const_int 0)])
9959 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9960 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9964 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
9965 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
9966 [(set_attr "conds" "use")
9967 (set_attr "length" "4,8,8")
9968 (set_attr "type" "logic_shift_imm,multiple,multiple")]
9971 (define_insn "*arith_adjacentmem"
9972 [(set (match_operand:SI 0 "s_register_operand" "=r")
9973 (match_operator:SI 1 "shiftable_operator"
9974 [(match_operand:SI 2 "memory_operand" "m")
9975 (match_operand:SI 3 "memory_operand" "m")]))
9976 (clobber (match_scratch:SI 4 "=r"))]
9977 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
9983 HOST_WIDE_INT val1 = 0, val2 = 0;
9985 if (REGNO (operands[0]) > REGNO (operands[4]))
9987 ldm[1] = operands[4];
9988 ldm[2] = operands[0];
9992 ldm[1] = operands[0];
9993 ldm[2] = operands[4];
9996 base_reg = XEXP (operands[2], 0);
9998 if (!REG_P (base_reg))
10000 val1 = INTVAL (XEXP (base_reg, 1));
10001 base_reg = XEXP (base_reg, 0);
10004 if (!REG_P (XEXP (operands[3], 0)))
10005 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10007 arith[0] = operands[0];
10008 arith[3] = operands[1];
10022 if (val1 !=0 && val2 != 0)
10026 if (val1 == 4 || val2 == 4)
10027 /* Other val must be 8, since we know they are adjacent and neither
10029 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
10030 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10032 ldm[0] = ops[0] = operands[4];
10034 ops[2] = GEN_INT (val1);
10035 output_add_immediate (ops);
10037 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10039 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10043 /* Offset is out of range for a single add, so use two ldr. */
10046 ops[2] = GEN_INT (val1);
10047 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10049 ops[2] = GEN_INT (val2);
10050 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10053 else if (val1 != 0)
10056 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10058 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10063 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
10065 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
10067 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10070 [(set_attr "length" "12")
10071 (set_attr "predicable" "yes")
10072 (set_attr "type" "load1")]
10075 ; This pattern is never tried by combine, so do it as a peephole
10078 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10079 (match_operand:SI 1 "arm_general_register_operand" ""))
10080 (set (reg:CC CC_REGNUM)
10081 (compare:CC (match_dup 1) (const_int 0)))]
10083 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10084 (set (match_dup 0) (match_dup 1))])]
10089 [(set (match_operand:SI 0 "s_register_operand" "")
10090 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10092 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10093 [(match_operand:SI 3 "s_register_operand" "")
10094 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10095 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10097 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10098 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10103 ;; This split can be used because CC_Z mode implies that the following
10104 ;; branch will be an equality, or an unsigned inequality, so the sign
10105 ;; extension is not needed.
10108 [(set (reg:CC_Z CC_REGNUM)
10110 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10112 (match_operand 1 "const_int_operand" "")))
10113 (clobber (match_scratch:SI 2 ""))]
10115 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
10116 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
10117 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10118 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10120 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10123 ;; ??? Check the patterns above for Thumb-2 usefulness
10125 (define_expand "prologue"
10126 [(clobber (const_int 0))]
10129 arm_expand_prologue ();
10131 thumb1_expand_prologue ();
10136 (define_expand "epilogue"
10137 [(clobber (const_int 0))]
10140 if (crtl->calls_eh_return)
10141 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10144 thumb1_expand_epilogue ();
10145 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10146 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10148 else if (HAVE_return)
10150 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10151 no need for explicit testing again. */
10152 emit_jump_insn (gen_return ());
10154 else if (TARGET_32BIT)
10156 arm_expand_epilogue (true);
10162 ;; Note - although unspec_volatile's USE all hard registers,
10163 ;; USEs are ignored after relaod has completed. Thus we need
10164 ;; to add an unspec of the link register to ensure that flow
10165 ;; does not think that it is unused by the sibcall branch that
10166 ;; will replace the standard function epilogue.
10167 (define_expand "sibcall_epilogue"
10168 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10169 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10172 arm_expand_epilogue (false);
10177 (define_expand "eh_epilogue"
10178 [(use (match_operand:SI 0 "register_operand" ""))
10179 (use (match_operand:SI 1 "register_operand" ""))
10180 (use (match_operand:SI 2 "register_operand" ""))]
10184 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10185 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10187 rtx ra = gen_rtx_REG (Pmode, 2);
10189 emit_move_insn (ra, operands[2]);
10192 /* This is a hack -- we may have crystalized the function type too
10194 cfun->machine->func_type = 0;
10198 ;; This split is only used during output to reduce the number of patterns
10199 ;; that need assembler instructions adding to them. We allowed the setting
10200 ;; of the conditions to be implicit during rtl generation so that
10201 ;; the conditional compare patterns would work. However this conflicts to
10202 ;; some extent with the conditional data operations, so we have to split them
10205 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10206 ;; conditional execution sufficient?
10209 [(set (match_operand:SI 0 "s_register_operand" "")
10210 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10211 [(match_operand 2 "" "") (match_operand 3 "" "")])
10213 (match_operand 4 "" "")))
10214 (clobber (reg:CC CC_REGNUM))]
10215 "TARGET_ARM && reload_completed"
10216 [(set (match_dup 5) (match_dup 6))
10217 (cond_exec (match_dup 7)
10218 (set (match_dup 0) (match_dup 4)))]
10221 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10222 operands[2], operands[3]);
10223 enum rtx_code rc = GET_CODE (operands[1]);
10225 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10226 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10227 if (mode == CCFPmode || mode == CCFPEmode)
10228 rc = reverse_condition_maybe_unordered (rc);
10230 rc = reverse_condition (rc);
10232 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10237 [(set (match_operand:SI 0 "s_register_operand" "")
10238 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10239 [(match_operand 2 "" "") (match_operand 3 "" "")])
10240 (match_operand 4 "" "")
10242 (clobber (reg:CC CC_REGNUM))]
10243 "TARGET_ARM && reload_completed"
10244 [(set (match_dup 5) (match_dup 6))
10245 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10246 (set (match_dup 0) (match_dup 4)))]
10249 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10250 operands[2], operands[3]);
10252 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10253 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10258 [(set (match_operand:SI 0 "s_register_operand" "")
10259 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10260 [(match_operand 2 "" "") (match_operand 3 "" "")])
10261 (match_operand 4 "" "")
10262 (match_operand 5 "" "")))
10263 (clobber (reg:CC CC_REGNUM))]
10264 "TARGET_ARM && reload_completed"
10265 [(set (match_dup 6) (match_dup 7))
10266 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10267 (set (match_dup 0) (match_dup 4)))
10268 (cond_exec (match_dup 8)
10269 (set (match_dup 0) (match_dup 5)))]
10272 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10273 operands[2], operands[3]);
10274 enum rtx_code rc = GET_CODE (operands[1]);
10276 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10277 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10278 if (mode == CCFPmode || mode == CCFPEmode)
10279 rc = reverse_condition_maybe_unordered (rc);
10281 rc = reverse_condition (rc);
10283 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10288 [(set (match_operand:SI 0 "s_register_operand" "")
10289 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10290 [(match_operand:SI 2 "s_register_operand" "")
10291 (match_operand:SI 3 "arm_add_operand" "")])
10292 (match_operand:SI 4 "arm_rhs_operand" "")
10294 (match_operand:SI 5 "s_register_operand" ""))))
10295 (clobber (reg:CC CC_REGNUM))]
10296 "TARGET_ARM && reload_completed"
10297 [(set (match_dup 6) (match_dup 7))
10298 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10299 (set (match_dup 0) (match_dup 4)))
10300 (cond_exec (match_dup 8)
10301 (set (match_dup 0) (not:SI (match_dup 5))))]
10304 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10305 operands[2], operands[3]);
10306 enum rtx_code rc = GET_CODE (operands[1]);
10308 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10309 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10310 if (mode == CCFPmode || mode == CCFPEmode)
10311 rc = reverse_condition_maybe_unordered (rc);
10313 rc = reverse_condition (rc);
10315 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10319 (define_insn "*cond_move_not"
10320 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10321 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10322 [(match_operand 3 "cc_register" "") (const_int 0)])
10323 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10325 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10329 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10330 [(set_attr "conds" "use")
10331 (set_attr "type" "mvn_reg,multiple")
10332 (set_attr "length" "4,8")]
10335 ;; The next two patterns occur when an AND operation is followed by a
10336 ;; scc insn sequence
10338 (define_insn "*sign_extract_onebit"
10339 [(set (match_operand:SI 0 "s_register_operand" "=r")
10340 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10342 (match_operand:SI 2 "const_int_operand" "n")))
10343 (clobber (reg:CC CC_REGNUM))]
10346 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10347 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10348 return \"mvnne\\t%0, #0\";
10350 [(set_attr "conds" "clob")
10351 (set_attr "length" "8")
10352 (set_attr "type" "multiple")]
10355 (define_insn "*not_signextract_onebit"
10356 [(set (match_operand:SI 0 "s_register_operand" "=r")
10358 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10360 (match_operand:SI 2 "const_int_operand" "n"))))
10361 (clobber (reg:CC CC_REGNUM))]
10364 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10365 output_asm_insn (\"tst\\t%1, %2\", operands);
10366 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10367 return \"movne\\t%0, #0\";
10369 [(set_attr "conds" "clob")
10370 (set_attr "length" "12")
10371 (set_attr "type" "multiple")]
10373 ;; ??? The above patterns need auditing for Thumb-2
10375 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10376 ;; expressions. For simplicity, the first register is also in the unspec
10378 ;; To avoid the usage of GNU extension, the length attribute is computed
10379 ;; in a C function arm_attr_length_push_multi.
10380 (define_insn "*push_multi"
10381 [(match_parallel 2 "multi_register_push"
10382 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10383 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10384 UNSPEC_PUSH_MULT))])]
10388 int num_saves = XVECLEN (operands[2], 0);
10390 /* For the StrongARM at least it is faster to
10391 use STR to store only a single register.
10392 In Thumb mode always use push, and the assembler will pick
10393 something appropriate. */
10394 if (num_saves == 1 && TARGET_ARM)
10395 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10402 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
10403 else if (TARGET_THUMB2)
10404 strcpy (pattern, \"push%?\\t{%1\");
10406 strcpy (pattern, \"push\\t{%1\");
10408 for (i = 1; i < num_saves; i++)
10410 strcat (pattern, \", %|\");
10412 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10415 strcat (pattern, \"}\");
10416 output_asm_insn (pattern, operands);
10421 [(set_attr "type" "store4")
10422 (set (attr "length")
10423 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10426 (define_insn "stack_tie"
10427 [(set (mem:BLK (scratch))
10428 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10429 (match_operand:SI 1 "s_register_operand" "rk")]
10433 [(set_attr "length" "0")
10434 (set_attr "type" "block")]
10437 ;; Pop (as used in epilogue RTL)
10439 (define_insn "*load_multiple_with_writeback"
10440 [(match_parallel 0 "load_multiple_operation"
10441 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10442 (plus:SI (match_dup 1)
10443 (match_operand:SI 2 "const_int_I_operand" "I")))
10444 (set (match_operand:SI 3 "s_register_operand" "=rk")
10445 (mem:SI (match_dup 1)))
10447 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10450 arm_output_multireg_pop (operands, /*return_pc=*/false,
10451 /*cond=*/const_true_rtx,
10457 [(set_attr "type" "load4")
10458 (set_attr "predicable" "yes")]
10461 ;; Pop with return (as used in epilogue RTL)
10463 ;; This instruction is generated when the registers are popped at the end of
10464 ;; epilogue. Here, instead of popping the value into LR and then generating
10465 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10467 (define_insn "*pop_multiple_with_writeback_and_return"
10468 [(match_parallel 0 "pop_multiple_return"
10470 (set (match_operand:SI 1 "s_register_operand" "+rk")
10471 (plus:SI (match_dup 1)
10472 (match_operand:SI 2 "const_int_I_operand" "I")))
10473 (set (match_operand:SI 3 "s_register_operand" "=rk")
10474 (mem:SI (match_dup 1)))
10476 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10479 arm_output_multireg_pop (operands, /*return_pc=*/true,
10480 /*cond=*/const_true_rtx,
10486 [(set_attr "type" "load4")
10487 (set_attr "predicable" "yes")]
10490 (define_insn "*pop_multiple_with_return"
10491 [(match_parallel 0 "pop_multiple_return"
10493 (set (match_operand:SI 2 "s_register_operand" "=rk")
10494 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10496 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10499 arm_output_multireg_pop (operands, /*return_pc=*/true,
10500 /*cond=*/const_true_rtx,
10506 [(set_attr "type" "load4")
10507 (set_attr "predicable" "yes")]
10510 ;; Load into PC and return
10511 (define_insn "*ldr_with_return"
10513 (set (reg:SI PC_REGNUM)
10514 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10515 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10516 "ldr%?\t%|pc, [%0], #4"
10517 [(set_attr "type" "load1")
10518 (set_attr "predicable" "yes")]
10520 ;; Pop for floating point registers (as used in epilogue RTL)
10521 (define_insn "*vfp_pop_multiple_with_writeback"
10522 [(match_parallel 0 "pop_multiple_fp"
10523 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10524 (plus:SI (match_dup 1)
10525 (match_operand:SI 2 "const_int_I_operand" "I")))
10526 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10527 (mem:DF (match_dup 1)))])]
10528 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10531 int num_regs = XVECLEN (operands[0], 0);
10534 strcpy (pattern, \"vldm\\t\");
10535 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10536 strcat (pattern, \"!, {\");
10537 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10538 strcat (pattern, \"%P0\");
10539 if ((num_regs - 1) > 1)
10541 strcat (pattern, \"-%P1\");
10542 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10545 strcat (pattern, \"}\");
10546 output_asm_insn (pattern, op_list);
10550 [(set_attr "type" "load4")
10551 (set_attr "conds" "unconditional")
10552 (set_attr "predicable" "no")]
10555 ;; Special patterns for dealing with the constant pool
10557 (define_insn "align_4"
10558 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10561 assemble_align (32);
10564 [(set_attr "type" "no_insn")]
10567 (define_insn "align_8"
10568 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10571 assemble_align (64);
10574 [(set_attr "type" "no_insn")]
10577 (define_insn "consttable_end"
10578 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10581 making_const_table = FALSE;
10584 [(set_attr "type" "no_insn")]
10587 (define_insn "consttable_1"
10588 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10591 making_const_table = TRUE;
10592 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10593 assemble_zeros (3);
10596 [(set_attr "length" "4")
10597 (set_attr "type" "no_insn")]
10600 (define_insn "consttable_2"
10601 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10605 rtx x = operands[0];
10606 making_const_table = TRUE;
10607 switch (GET_MODE_CLASS (GET_MODE (x)))
10610 arm_emit_fp16_const (x);
10613 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10614 assemble_zeros (2);
10619 [(set_attr "length" "4")
10620 (set_attr "type" "no_insn")]
10623 (define_insn "consttable_4"
10624 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10628 rtx x = operands[0];
10629 making_const_table = TRUE;
10630 switch (GET_MODE_CLASS (GET_MODE (x)))
10635 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
10636 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
10640 /* XXX: Sometimes gcc does something really dumb and ends up with
10641 a HIGH in a constant pool entry, usually because it's trying to
10642 load into a VFP register. We know this will always be used in
10643 combination with a LO_SUM which ignores the high bits, so just
10644 strip off the HIGH. */
10645 if (GET_CODE (x) == HIGH)
10647 assemble_integer (x, 4, BITS_PER_WORD, 1);
10648 mark_symbol_refs_as_used (x);
10653 [(set_attr "length" "4")
10654 (set_attr "type" "no_insn")]
10657 (define_insn "consttable_8"
10658 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10662 making_const_table = TRUE;
10663 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10668 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10669 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10673 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10678 [(set_attr "length" "8")
10679 (set_attr "type" "no_insn")]
10682 (define_insn "consttable_16"
10683 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10687 making_const_table = TRUE;
10688 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
10693 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
10694 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
10698 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10703 [(set_attr "length" "16")
10704 (set_attr "type" "no_insn")]
10707 ;; V5 Instructions,
10709 (define_insn "clzsi2"
10710 [(set (match_operand:SI 0 "s_register_operand" "=r")
10711 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10712 "TARGET_32BIT && arm_arch5"
10714 [(set_attr "predicable" "yes")
10715 (set_attr "predicable_short_it" "no")
10716 (set_attr "type" "clz")])
10718 (define_insn "rbitsi2"
10719 [(set (match_operand:SI 0 "s_register_operand" "=r")
10720 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10721 "TARGET_32BIT && arm_arch_thumb2"
10723 [(set_attr "predicable" "yes")
10724 (set_attr "predicable_short_it" "no")
10725 (set_attr "type" "clz")])
10727 (define_expand "ctzsi2"
10728 [(set (match_operand:SI 0 "s_register_operand" "")
10729 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
10730 "TARGET_32BIT && arm_arch_thumb2"
10733 rtx tmp = gen_reg_rtx (SImode);
10734 emit_insn (gen_rbitsi2 (tmp, operands[1]));
10735 emit_insn (gen_clzsi2 (operands[0], tmp));
10741 ;; V5E instructions.
10743 (define_insn "prefetch"
10744 [(prefetch (match_operand:SI 0 "address_operand" "p")
10745 (match_operand:SI 1 "" "")
10746 (match_operand:SI 2 "" ""))]
10747 "TARGET_32BIT && arm_arch5e"
10749 [(set_attr "type" "load1")]
10752 ;; General predication pattern
10755 [(match_operator 0 "arm_comparison_operator"
10756 [(match_operand 1 "cc_register" "")
10759 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
10761 [(set_attr "predicated" "yes")]
10764 (define_insn "force_register_use"
10765 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
10768 [(set_attr "length" "0")
10769 (set_attr "type" "no_insn")]
10773 ;; Patterns for exception handling
10775 (define_expand "eh_return"
10776 [(use (match_operand 0 "general_operand" ""))]
10781 emit_insn (gen_arm_eh_return (operands[0]));
10783 emit_insn (gen_thumb_eh_return (operands[0]));
10788 ;; We can't expand this before we know where the link register is stored.
10789 (define_insn_and_split "arm_eh_return"
10790 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
10792 (clobber (match_scratch:SI 1 "=&r"))]
10795 "&& reload_completed"
10799 arm_set_return_address (operands[0], operands[1]);
10807 (define_insn "load_tp_hard"
10808 [(set (match_operand:SI 0 "register_operand" "=r")
10809 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
10811 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
10812 [(set_attr "predicable" "yes")
10813 (set_attr "type" "mrs")]
10816 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
10817 (define_insn "load_tp_soft"
10818 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
10819 (clobber (reg:SI LR_REGNUM))
10820 (clobber (reg:SI IP_REGNUM))
10821 (clobber (reg:CC CC_REGNUM))]
10823 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
10824 [(set_attr "conds" "clob")
10825 (set_attr "type" "branch")]
10828 ;; tls descriptor call
10829 (define_insn "tlscall"
10830 [(set (reg:SI R0_REGNUM)
10831 (unspec:SI [(reg:SI R0_REGNUM)
10832 (match_operand:SI 0 "" "X")
10833 (match_operand 1 "" "")] UNSPEC_TLS))
10834 (clobber (reg:SI R1_REGNUM))
10835 (clobber (reg:SI LR_REGNUM))
10836 (clobber (reg:SI CC_REGNUM))]
10839 targetm.asm_out.internal_label (asm_out_file, "LPIC",
10840 INTVAL (operands[1]));
10841 return "bl\\t%c0(tlscall)";
10843 [(set_attr "conds" "clob")
10844 (set_attr "length" "4")
10845 (set_attr "type" "branch")]
10848 ;; For thread pointer builtin
10849 (define_expand "get_thread_pointersi"
10850 [(match_operand:SI 0 "s_register_operand" "=r")]
10854 arm_load_tp (operands[0]);
10860 ;; We only care about the lower 16 bits of the constant
10861 ;; being inserted into the upper 16 bits of the register.
10862 (define_insn "*arm_movtas_ze"
10863 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
10866 (match_operand:SI 1 "const_int_operand" ""))]
10869 [(set_attr "predicable" "yes")
10870 (set_attr "predicable_short_it" "no")
10871 (set_attr "length" "4")
10872 (set_attr "type" "mov_imm")]
10875 (define_insn "*arm_rev"
10876 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10877 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
10883 [(set_attr "arch" "t1,t2,32")
10884 (set_attr "length" "2,2,4")
10885 (set_attr "predicable" "no,yes,yes")
10886 (set_attr "predicable_short_it" "no")
10887 (set_attr "type" "rev")]
10890 (define_expand "arm_legacy_rev"
10891 [(set (match_operand:SI 2 "s_register_operand" "")
10892 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
10896 (lshiftrt:SI (match_dup 2)
10898 (set (match_operand:SI 3 "s_register_operand" "")
10899 (rotatert:SI (match_dup 1)
10902 (and:SI (match_dup 2)
10903 (const_int -65281)))
10904 (set (match_operand:SI 0 "s_register_operand" "")
10905 (xor:SI (match_dup 3)
10911 ;; Reuse temporaries to keep register pressure down.
10912 (define_expand "thumb_legacy_rev"
10913 [(set (match_operand:SI 2 "s_register_operand" "")
10914 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
10916 (set (match_operand:SI 3 "s_register_operand" "")
10917 (lshiftrt:SI (match_dup 1)
10920 (ior:SI (match_dup 3)
10922 (set (match_operand:SI 4 "s_register_operand" "")
10924 (set (match_operand:SI 5 "s_register_operand" "")
10925 (rotatert:SI (match_dup 1)
10928 (ashift:SI (match_dup 5)
10931 (lshiftrt:SI (match_dup 5)
10934 (ior:SI (match_dup 5)
10937 (rotatert:SI (match_dup 5)
10939 (set (match_operand:SI 0 "s_register_operand" "")
10940 (ior:SI (match_dup 5)
10946 (define_expand "bswapsi2"
10947 [(set (match_operand:SI 0 "s_register_operand" "=r")
10948 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
10949 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
10953 rtx op2 = gen_reg_rtx (SImode);
10954 rtx op3 = gen_reg_rtx (SImode);
10958 rtx op4 = gen_reg_rtx (SImode);
10959 rtx op5 = gen_reg_rtx (SImode);
10961 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
10962 op2, op3, op4, op5));
10966 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
10975 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
10976 ;; and unsigned variants, respectively. For rev16, expose
10977 ;; byte-swapping in the lower 16 bits only.
10978 (define_insn "*arm_revsh"
10979 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
10980 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
10986 [(set_attr "arch" "t1,t2,32")
10987 (set_attr "length" "2,2,4")
10988 (set_attr "type" "rev")]
10991 (define_insn "*arm_rev16"
10992 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
10993 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
10999 [(set_attr "arch" "t1,t2,32")
11000 (set_attr "length" "2,2,4")
11001 (set_attr "type" "rev")]
11004 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11005 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11006 ;; each valid permutation.
11008 (define_insn "arm_rev16si2"
11009 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11010 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11012 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11013 (and:SI (lshiftrt:SI (match_dup 1)
11015 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11017 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11018 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11020 [(set_attr "arch" "t1,t2,32")
11021 (set_attr "length" "2,2,4")
11022 (set_attr "type" "rev")]
11025 (define_insn "arm_rev16si2_alt"
11026 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11027 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11029 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11030 (and:SI (ashift:SI (match_dup 1)
11032 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11034 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11035 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11037 [(set_attr "arch" "t1,t2,32")
11038 (set_attr "length" "2,2,4")
11039 (set_attr "type" "rev")]
11042 (define_expand "bswaphi2"
11043 [(set (match_operand:HI 0 "s_register_operand" "=r")
11044 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11049 ;; Patterns for LDRD/STRD in Thumb2 mode
11051 (define_insn "*thumb2_ldrd"
11052 [(set (match_operand:SI 0 "s_register_operand" "=r")
11053 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11054 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11055 (set (match_operand:SI 3 "s_register_operand" "=r")
11056 (mem:SI (plus:SI (match_dup 1)
11057 (match_operand:SI 4 "const_int_operand" ""))))]
11058 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11059 && current_tune->prefer_ldrd_strd
11060 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11061 && (operands_ok_ldrd_strd (operands[0], operands[3],
11062 operands[1], INTVAL (operands[2]),
11064 "ldrd%?\t%0, %3, [%1, %2]"
11065 [(set_attr "type" "load2")
11066 (set_attr "predicable" "yes")
11067 (set_attr "predicable_short_it" "no")])
11069 (define_insn "*thumb2_ldrd_base"
11070 [(set (match_operand:SI 0 "s_register_operand" "=r")
11071 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11072 (set (match_operand:SI 2 "s_register_operand" "=r")
11073 (mem:SI (plus:SI (match_dup 1)
11075 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11076 && current_tune->prefer_ldrd_strd
11077 && (operands_ok_ldrd_strd (operands[0], operands[2],
11078 operands[1], 0, false, true))"
11079 "ldrd%?\t%0, %2, [%1]"
11080 [(set_attr "type" "load2")
11081 (set_attr "predicable" "yes")
11082 (set_attr "predicable_short_it" "no")])
11084 (define_insn "*thumb2_ldrd_base_neg"
11085 [(set (match_operand:SI 0 "s_register_operand" "=r")
11086 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11088 (set (match_operand:SI 2 "s_register_operand" "=r")
11089 (mem:SI (match_dup 1)))]
11090 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11091 && current_tune->prefer_ldrd_strd
11092 && (operands_ok_ldrd_strd (operands[0], operands[2],
11093 operands[1], -4, false, true))"
11094 "ldrd%?\t%0, %2, [%1, #-4]"
11095 [(set_attr "type" "load2")
11096 (set_attr "predicable" "yes")
11097 (set_attr "predicable_short_it" "no")])
11099 (define_insn "*thumb2_strd"
11100 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11101 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11102 (match_operand:SI 2 "s_register_operand" "r"))
11103 (set (mem:SI (plus:SI (match_dup 0)
11104 (match_operand:SI 3 "const_int_operand" "")))
11105 (match_operand:SI 4 "s_register_operand" "r"))]
11106 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11107 && current_tune->prefer_ldrd_strd
11108 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11109 && (operands_ok_ldrd_strd (operands[2], operands[4],
11110 operands[0], INTVAL (operands[1]),
11112 "strd%?\t%2, %4, [%0, %1]"
11113 [(set_attr "type" "store2")
11114 (set_attr "predicable" "yes")
11115 (set_attr "predicable_short_it" "no")])
11117 (define_insn "*thumb2_strd_base"
11118 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11119 (match_operand:SI 1 "s_register_operand" "r"))
11120 (set (mem:SI (plus:SI (match_dup 0)
11122 (match_operand:SI 2 "s_register_operand" "r"))]
11123 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11124 && current_tune->prefer_ldrd_strd
11125 && (operands_ok_ldrd_strd (operands[1], operands[2],
11126 operands[0], 0, false, false))"
11127 "strd%?\t%1, %2, [%0]"
11128 [(set_attr "type" "store2")
11129 (set_attr "predicable" "yes")
11130 (set_attr "predicable_short_it" "no")])
11132 (define_insn "*thumb2_strd_base_neg"
11133 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11135 (match_operand:SI 1 "s_register_operand" "r"))
11136 (set (mem:SI (match_dup 0))
11137 (match_operand:SI 2 "s_register_operand" "r"))]
11138 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11139 && current_tune->prefer_ldrd_strd
11140 && (operands_ok_ldrd_strd (operands[1], operands[2],
11141 operands[0], -4, false, false))"
11142 "strd%?\t%1, %2, [%0, #-4]"
11143 [(set_attr "type" "store2")
11144 (set_attr "predicable" "yes")
11145 (set_attr "predicable_short_it" "no")])
11147 ;; ARMv8 CRC32 instructions.
11148 (define_insn "<crc_variant>"
11149 [(set (match_operand:SI 0 "s_register_operand" "=r")
11150 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11151 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11154 "<crc_variant>\\t%0, %1, %2"
11155 [(set_attr "type" "crc")
11156 (set_attr "conds" "unconditional")]
11159 ;; Load the load/store double peephole optimizations.
11160 (include "ldrdstrd.md")
11162 ;; Load the load/store multiple patterns
11163 (include "ldmstm.md")
11165 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11166 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11167 (define_insn "*load_multiple"
11168 [(match_parallel 0 "load_multiple_operation"
11169 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11170 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11175 arm_output_multireg_pop (operands, /*return_pc=*/false,
11176 /*cond=*/const_true_rtx,
11182 [(set_attr "predicable" "yes")]
11185 (define_expand "copysignsf3"
11186 [(match_operand:SF 0 "register_operand")
11187 (match_operand:SF 1 "register_operand")
11188 (match_operand:SF 2 "register_operand")]
11189 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11191 emit_move_insn (operands[0], operands[2]);
11192 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11193 GEN_INT (31), GEN_INT (0),
11194 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11199 (define_expand "copysigndf3"
11200 [(match_operand:DF 0 "register_operand")
11201 (match_operand:DF 1 "register_operand")
11202 (match_operand:DF 2 "register_operand")]
11203 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11205 rtx op0_low = gen_lowpart (SImode, operands[0]);
11206 rtx op0_high = gen_highpart (SImode, operands[0]);
11207 rtx op1_low = gen_lowpart (SImode, operands[1]);
11208 rtx op1_high = gen_highpart (SImode, operands[1]);
11209 rtx op2_high = gen_highpart (SImode, operands[2]);
11211 rtx scratch1 = gen_reg_rtx (SImode);
11212 rtx scratch2 = gen_reg_rtx (SImode);
11213 emit_move_insn (scratch1, op2_high);
11214 emit_move_insn (scratch2, op1_high);
11216 emit_insn(gen_rtx_SET(SImode, scratch1,
11217 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11218 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11219 emit_move_insn (op0_low, op1_low);
11220 emit_move_insn (op0_high, scratch2);
11226 ;; Vector bits common to IWMMXT and Neon
11227 (include "vec-common.md")
11228 ;; Load the Intel Wireless Multimedia Extension patterns
11229 (include "iwmmxt.md")
11230 ;; Load the VFP co-processor patterns
11232 ;; Thumb-1 patterns
11233 (include "thumb1.md")
11234 ;; Thumb-2 patterns
11235 (include "thumb2.md")
11237 (include "neon.md")
11239 (include "crypto.md")
11240 ;; Synchronization Primitives
11241 (include "sync.md")
11242 ;; Fixed-point patterns
11243 (include "arm-fixed.md")