1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2014 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25 ;; Beware of splitting Thumb1 patterns that output multiple
26 ;; assembly instructions, in particular instruction such as SBC and
27 ;; ADC which consume flags. For example, in the pattern thumb_subdi3
28 ;; below, the output SUB implicitly sets the flags (assembled to SUBS)
29 ;; and then the Carry flag is used by SBC to compute the correct
30 ;; result. If we split thumb_subdi3 pattern into two separate RTL
31 ;; insns (using define_insn_and_split), the scheduler might place
32 ;; other RTL insns between SUB and SBC, possibly modifying the Carry
33 ;; flag used by SBC. This might happen because most Thumb1 patterns
34 ;; for flag-setting instructions do not have explicit RTL for setting
35 ;; or clobbering the flags. Instead, they have the attribute "conds"
36 ;; with value "set" or "clob". However, this attribute is not used to
37 ;; identify dependencies and therefore the scheduler might reorder
38 ;; these instruction. Currenly, this problem cannot happen because
39 ;; there are no separate Thumb1 patterns for individual instruction
40 ;; that consume flags (except conditional execution, which is treated
41 ;; differently). In particular there is no Thumb1 armv6-m pattern for
45 ;;---------------------------------------------------------------------------
48 ;; Register numbers -- All machine registers should be defined here
50 [(R0_REGNUM 0) ; First CORE register
51 (R1_REGNUM 1) ; Second CORE register
52 (IP_REGNUM 12) ; Scratch register
53 (SP_REGNUM 13) ; Stack pointer
54 (LR_REGNUM 14) ; Return address register
55 (PC_REGNUM 15) ; Program counter
56 (LAST_ARM_REGNUM 15) ;
57 (CC_REGNUM 100) ; Condition code pseudo register
58 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
61 ;; 3rd operand to select_dominance_cc_mode
68 ;; conditional compare combination
79 ;;---------------------------------------------------------------------------
82 ;; Processor type. This is created automatically from arm-cores.def.
83 (include "arm-tune.md")
85 ;; Instruction classification types
88 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
89 ; generating ARM code. This is used to control the length of some insn
90 ; patterns that share the same RTL in both ARM and Thumb code.
91 (define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
93 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
94 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
96 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
97 (define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
99 ; We use this attribute to disable alternatives that can produce 32-bit
100 ; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
101 ; that contain 32-bit instructions.
102 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
104 ; This attribute is used to disable a predicated alternative when we have
106 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
108 ;; Operand number of an input operand that is shifted. Zero if the
109 ;; given instruction does not shift one of its input operands.
110 (define_attr "shift" "" (const_int 0))
112 ;; [For compatibility with AArch64 in pipeline models]
113 ;; Attribute that specifies whether or not the instruction touches fp
115 (define_attr "fp" "no,yes" (const_string "no"))
117 ; Floating Point Unit. If we only have floating point emulation, then there
118 ; is no point in scheduling the floating point insns. (Well, for best
119 ; performance we should try and group them together).
120 (define_attr "fpu" "none,vfp"
121 (const (symbol_ref "arm_fpu_attr")))
123 (define_attr "predicated" "yes,no" (const_string "no"))
125 ; LENGTH of an instruction (in bytes)
126 (define_attr "length" ""
129 ; The architecture which supports the instruction (or alternative).
130 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
131 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
132 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
133 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6. This attribute is
134 ; used to compute attribute "enabled", use type "any" to enable an
135 ; alternative in all cases.
136 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2"
137 (const_string "any"))
139 (define_attr "arch_enabled" "no,yes"
140 (cond [(eq_attr "arch" "any")
143 (and (eq_attr "arch" "a")
144 (match_test "TARGET_ARM"))
147 (and (eq_attr "arch" "t")
148 (match_test "TARGET_THUMB"))
151 (and (eq_attr "arch" "t1")
152 (match_test "TARGET_THUMB1"))
155 (and (eq_attr "arch" "t2")
156 (match_test "TARGET_THUMB2"))
159 (and (eq_attr "arch" "32")
160 (match_test "TARGET_32BIT"))
163 (and (eq_attr "arch" "v6")
164 (match_test "TARGET_32BIT && arm_arch6"))
167 (and (eq_attr "arch" "nov6")
168 (match_test "TARGET_32BIT && !arm_arch6"))
171 (and (eq_attr "arch" "v6t2")
172 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
175 (and (eq_attr "arch" "avoid_neon_for_64bits")
176 (match_test "TARGET_NEON")
177 (not (match_test "TARGET_PREFER_NEON_64BITS")))
180 (and (eq_attr "arch" "neon_for_64bits")
181 (match_test "TARGET_NEON")
182 (match_test "TARGET_PREFER_NEON_64BITS"))
185 (and (eq_attr "arch" "iwmmxt2")
186 (match_test "TARGET_REALLY_IWMMXT2"))
187 (const_string "yes")]
189 (const_string "no")))
191 (define_attr "opt" "any,speed,size"
192 (const_string "any"))
194 (define_attr "opt_enabled" "no,yes"
195 (cond [(eq_attr "opt" "any")
198 (and (eq_attr "opt" "speed")
199 (match_test "optimize_function_for_speed_p (cfun)"))
202 (and (eq_attr "opt" "size")
203 (match_test "optimize_function_for_size_p (cfun)"))
204 (const_string "yes")]
205 (const_string "no")))
207 (define_attr "use_literal_pool" "no,yes"
208 (cond [(and (eq_attr "type" "f_loads,f_loadd")
209 (match_test "CONSTANT_P (operands[1])"))
210 (const_string "yes")]
211 (const_string "no")))
213 ; Enable all alternatives that are both arch_enabled and insn_enabled.
214 (define_attr "enabled" "no,yes"
215 (cond [(and (eq_attr "predicable_short_it" "no")
216 (and (eq_attr "predicated" "yes")
217 (match_test "arm_restrict_it")))
220 (and (eq_attr "enabled_for_depr_it" "no")
221 (match_test "arm_restrict_it"))
224 (and (eq_attr "use_literal_pool" "yes")
225 (match_test "arm_disable_literal_pool"))
228 (eq_attr "arch_enabled" "no")
231 (eq_attr "opt_enabled" "no")
233 (const_string "yes")))
235 ; POOL_RANGE is how far away from a constant pool entry that this insn
236 ; can be placed. If the distance is zero, then this insn will never
237 ; reference the pool.
238 ; Note that for Thumb constant pools the PC value is rounded down to the
239 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
240 ; Thumb insns) should be set to <max_range> - 2.
241 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
242 ; before its address. It is set to <max_range> - (8 + <data_size>).
243 (define_attr "arm_pool_range" "" (const_int 0))
244 (define_attr "thumb2_pool_range" "" (const_int 0))
245 (define_attr "arm_neg_pool_range" "" (const_int 0))
246 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
248 (define_attr "pool_range" ""
249 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
250 (attr "arm_pool_range")))
251 (define_attr "neg_pool_range" ""
252 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
253 (attr "arm_neg_pool_range")))
255 ; An assembler sequence may clobber the condition codes without us knowing.
256 ; If such an insn references the pool, then we have no way of knowing how,
257 ; so use the most conservative value for pool_range.
258 (define_asm_attributes
259 [(set_attr "conds" "clob")
260 (set_attr "length" "4")
261 (set_attr "pool_range" "250")])
263 ; Load scheduling, set from the arm_ld_sched variable
264 ; initialized by arm_option_override()
265 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
267 ; condition codes: this one is used by final_prescan_insn to speed up
268 ; conditionalizing instructions. It saves having to scan the rtl to see if
269 ; it uses or alters the condition codes.
271 ; USE means that the condition codes are used by the insn in the process of
272 ; outputting code, this means (at present) that we can't use the insn in
275 ; SET means that the purpose of the insn is to set the condition codes in a
276 ; well defined manner.
278 ; CLOB means that the condition codes are altered in an undefined manner, if
279 ; they are altered at all
281 ; UNCONDITIONAL means the instruction can not be conditionally executed and
282 ; that the instruction does not use or alter the condition codes.
284 ; NOCOND means that the instruction does not use or alter the condition
285 ; codes but can be converted into a conditionally exectuted instruction.
287 (define_attr "conds" "use,set,clob,unconditional,nocond"
289 (ior (eq_attr "is_thumb1" "yes")
290 (eq_attr "type" "call"))
291 (const_string "clob")
292 (if_then_else (eq_attr "is_neon_type" "no")
293 (const_string "nocond")
294 (const_string "unconditional"))))
296 ; Predicable means that the insn can be conditionally executed based on
297 ; an automatically added predicate (additional patterns are generated by
298 ; gen...). We default to 'no' because no Thumb patterns match this rule
299 ; and not all ARM patterns do.
300 (define_attr "predicable" "no,yes" (const_string "no"))
302 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
303 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
304 ; suffer blockages enough to warrant modelling this (and it can adversely
305 ; affect the schedule).
306 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
308 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
309 ; to stall the processor. Used with model_wbuf above.
310 (define_attr "write_conflict" "no,yes"
311 (if_then_else (eq_attr "type"
314 (const_string "no")))
316 ; Classify the insns into those that take one cycle and those that take more
317 ; than one on the main cpu execution unit.
318 (define_attr "core_cycles" "single,multi"
319 (if_then_else (eq_attr "type"
320 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_reg,\
321 alu_shift_imm, alu_shift_reg, alus_ext, alus_imm, alus_reg,\
322 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
323 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
324 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
325 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
326 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
327 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
328 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
329 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
330 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
331 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
332 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
333 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
334 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
335 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
336 (const_string "single")
337 (const_string "multi")))
339 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
340 ;; distant label. Only applicable to Thumb code.
341 (define_attr "far_jump" "yes,no" (const_string "no"))
344 ;; The number of machine instructions this pattern expands to.
345 ;; Used for Thumb-2 conditional execution.
346 (define_attr "ce_count" "" (const_int 1))
348 ;;---------------------------------------------------------------------------
351 (include "unspecs.md")
353 ;;---------------------------------------------------------------------------
356 (include "iterators.md")
358 ;;---------------------------------------------------------------------------
361 (include "predicates.md")
362 (include "constraints.md")
364 ;;---------------------------------------------------------------------------
365 ;; Pipeline descriptions
367 (define_attr "tune_cortexr4" "yes,no"
369 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
371 (const_string "no"))))
373 ;; True if the generic scheduling description should be used.
375 (define_attr "generic_sched" "yes,no"
377 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
378 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
379 arm1136jfs,cortexa5,cortexa7,cortexa8,\
380 cortexa9,cortexa12,cortexa15,cortexa17,\
381 cortexa53,cortexa57,cortexm4,cortexm7,\
383 (eq_attr "tune_cortexr4" "yes"))
385 (const_string "yes"))))
387 (define_attr "generic_vfp" "yes,no"
389 (and (eq_attr "fpu" "vfp")
390 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
391 cortexa8,cortexa9,cortexa53,cortexm4,\
392 cortexm7,marvell_pj4,xgene1")
393 (eq_attr "tune_cortexr4" "no"))
395 (const_string "no"))))
397 (include "marvell-f-iwmmxt.md")
398 (include "arm-generic.md")
399 (include "arm926ejs.md")
400 (include "arm1020e.md")
401 (include "arm1026ejs.md")
402 (include "arm1136jfs.md")
404 (include "fa606te.md")
405 (include "fa626te.md")
406 (include "fmp626.md")
407 (include "fa726te.md")
408 (include "cortex-a5.md")
409 (include "cortex-a7.md")
410 (include "cortex-a8.md")
411 (include "cortex-a9.md")
412 (include "cortex-a15.md")
413 (include "cortex-a17.md")
414 (include "cortex-a53.md")
415 (include "cortex-a57.md")
416 (include "cortex-r4.md")
417 (include "cortex-r4f.md")
418 (include "cortex-m7.md")
419 (include "cortex-m4.md")
420 (include "cortex-m4-fpu.md")
422 (include "marvell-pj4.md")
423 (include "xgene1.md")
426 ;;---------------------------------------------------------------------------
431 ;; Note: For DImode insns, there is normally no reason why operands should
432 ;; not be in the same register, what we don't want is for something being
433 ;; written to partially overlap something that is an input.
435 (define_expand "adddi3"
437 [(set (match_operand:DI 0 "s_register_operand" "")
438 (plus:DI (match_operand:DI 1 "s_register_operand" "")
439 (match_operand:DI 2 "arm_adddi_operand" "")))
440 (clobber (reg:CC CC_REGNUM))])]
445 if (!REG_P (operands[1]))
446 operands[1] = force_reg (DImode, operands[1]);
447 if (!REG_P (operands[2]))
448 operands[2] = force_reg (DImode, operands[2]);
453 (define_insn "*thumb1_adddi3"
454 [(set (match_operand:DI 0 "register_operand" "=l")
455 (plus:DI (match_operand:DI 1 "register_operand" "%0")
456 (match_operand:DI 2 "register_operand" "l")))
457 (clobber (reg:CC CC_REGNUM))
460 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
461 [(set_attr "length" "4")
462 (set_attr "type" "multiple")]
465 (define_insn_and_split "*arm_adddi3"
466 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
467 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
468 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
469 (clobber (reg:CC CC_REGNUM))]
470 "TARGET_32BIT && !TARGET_NEON"
472 "TARGET_32BIT && reload_completed
473 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
474 [(parallel [(set (reg:CC_C CC_REGNUM)
475 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
477 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
478 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
479 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
482 operands[3] = gen_highpart (SImode, operands[0]);
483 operands[0] = gen_lowpart (SImode, operands[0]);
484 operands[4] = gen_highpart (SImode, operands[1]);
485 operands[1] = gen_lowpart (SImode, operands[1]);
486 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
487 operands[2] = gen_lowpart (SImode, operands[2]);
489 [(set_attr "conds" "clob")
490 (set_attr "length" "8")
491 (set_attr "type" "multiple")]
494 (define_insn_and_split "*adddi_sesidi_di"
495 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
496 (plus:DI (sign_extend:DI
497 (match_operand:SI 2 "s_register_operand" "r,r"))
498 (match_operand:DI 1 "s_register_operand" "0,r")))
499 (clobber (reg:CC CC_REGNUM))]
502 "TARGET_32BIT && reload_completed"
503 [(parallel [(set (reg:CC_C CC_REGNUM)
504 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
506 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
507 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
510 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
513 operands[3] = gen_highpart (SImode, operands[0]);
514 operands[0] = gen_lowpart (SImode, operands[0]);
515 operands[4] = gen_highpart (SImode, operands[1]);
516 operands[1] = gen_lowpart (SImode, operands[1]);
517 operands[2] = gen_lowpart (SImode, operands[2]);
519 [(set_attr "conds" "clob")
520 (set_attr "length" "8")
521 (set_attr "type" "multiple")]
524 (define_insn_and_split "*adddi_zesidi_di"
525 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
526 (plus:DI (zero_extend:DI
527 (match_operand:SI 2 "s_register_operand" "r,r"))
528 (match_operand:DI 1 "s_register_operand" "0,r")))
529 (clobber (reg:CC CC_REGNUM))]
532 "TARGET_32BIT && reload_completed"
533 [(parallel [(set (reg:CC_C CC_REGNUM)
534 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
536 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
537 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
538 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
541 operands[3] = gen_highpart (SImode, operands[0]);
542 operands[0] = gen_lowpart (SImode, operands[0]);
543 operands[4] = gen_highpart (SImode, operands[1]);
544 operands[1] = gen_lowpart (SImode, operands[1]);
545 operands[2] = gen_lowpart (SImode, operands[2]);
547 [(set_attr "conds" "clob")
548 (set_attr "length" "8")
549 (set_attr "type" "multiple")]
552 (define_expand "addsi3"
553 [(set (match_operand:SI 0 "s_register_operand" "")
554 (plus:SI (match_operand:SI 1 "s_register_operand" "")
555 (match_operand:SI 2 "reg_or_int_operand" "")))]
558 if (TARGET_32BIT && CONST_INT_P (operands[2]))
560 arm_split_constant (PLUS, SImode, NULL_RTX,
561 INTVAL (operands[2]), operands[0], operands[1],
562 optimize && can_create_pseudo_p ());
568 ; If there is a scratch available, this will be faster than synthesizing the
571 [(match_scratch:SI 3 "r")
572 (set (match_operand:SI 0 "arm_general_register_operand" "")
573 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
574 (match_operand:SI 2 "const_int_operand" "")))]
576 !(const_ok_for_arm (INTVAL (operands[2]))
577 || const_ok_for_arm (-INTVAL (operands[2])))
578 && const_ok_for_arm (~INTVAL (operands[2]))"
579 [(set (match_dup 3) (match_dup 2))
580 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
584 ;; The r/r/k alternative is required when reloading the address
585 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
586 ;; put the duplicated register first, and not try the commutative version.
587 (define_insn_and_split "*arm_addsi3"
588 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
589 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
590 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
605 subw%?\\t%0, %1, #%n2
606 subw%?\\t%0, %1, #%n2
609 && CONST_INT_P (operands[2])
610 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
611 && (reload_completed || !arm_eliminable_register (operands[1]))"
612 [(clobber (const_int 0))]
614 arm_split_constant (PLUS, SImode, curr_insn,
615 INTVAL (operands[2]), operands[0],
619 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
620 (set_attr "predicable" "yes")
621 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
622 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
623 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
624 (const_string "alu_imm")
625 (const_string "alu_reg")))
629 (define_insn_and_split "*thumb1_addsi3"
630 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,k,l,l,l")
631 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,k,k,0,l,k")
632 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,M,O,Pa,Pb,Pc")))]
635 static const char * const asms[] =
637 \"add\\t%0, %0, %2\",
638 \"sub\\t%0, %0, #%n2\",
639 \"add\\t%0, %1, %2\",
640 \"add\\t%0, %0, %2\",
641 \"add\\t%0, %0, %2\",
642 \"add\\t%0, %1, %2\",
643 \"add\\t%0, %1, %2\",
648 if ((which_alternative == 2 || which_alternative == 6)
649 && CONST_INT_P (operands[2])
650 && INTVAL (operands[2]) < 0)
651 return \"sub\\t%0, %1, #%n2\";
652 return asms[which_alternative];
654 "&& reload_completed && CONST_INT_P (operands[2])
655 && ((operands[1] != stack_pointer_rtx
656 && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255))
657 || (operands[1] == stack_pointer_rtx
658 && INTVAL (operands[2]) > 1020))"
659 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
660 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
662 HOST_WIDE_INT offset = INTVAL (operands[2]);
663 if (operands[1] == stack_pointer_rtx)
669 else if (offset < -255)
672 operands[3] = GEN_INT (offset);
673 operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
675 [(set_attr "length" "2,2,2,2,2,2,2,4,4,4")
676 (set_attr "type" "alus_imm,alus_imm,alus_reg,alus_reg,alus_reg,
677 alus_reg,alus_reg,multiple,multiple,multiple")]
680 ;; Reloading and elimination of the frame pointer can
681 ;; sometimes cause this optimization to be missed.
683 [(set (match_operand:SI 0 "arm_general_register_operand" "")
684 (match_operand:SI 1 "const_int_operand" ""))
686 (plus:SI (match_dup 0) (reg:SI SP_REGNUM)))]
688 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024
689 && (INTVAL (operands[1]) & 3) == 0"
690 [(set (match_dup 0) (plus:SI (reg:SI SP_REGNUM) (match_dup 1)))]
694 (define_insn "addsi3_compare0"
695 [(set (reg:CC_NOOV CC_REGNUM)
697 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
698 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
700 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
701 (plus:SI (match_dup 1) (match_dup 2)))]
707 [(set_attr "conds" "set")
708 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
711 (define_insn "*addsi3_compare0_scratch"
712 [(set (reg:CC_NOOV CC_REGNUM)
714 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
715 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
722 [(set_attr "conds" "set")
723 (set_attr "predicable" "yes")
724 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
727 (define_insn "*compare_negsi_si"
728 [(set (reg:CC_Z CC_REGNUM)
730 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
731 (match_operand:SI 1 "s_register_operand" "l,r")))]
734 [(set_attr "conds" "set")
735 (set_attr "predicable" "yes")
736 (set_attr "arch" "t2,*")
737 (set_attr "length" "2,4")
738 (set_attr "predicable_short_it" "yes,no")
739 (set_attr "type" "alus_reg")]
742 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
743 ;; addend is a constant.
744 (define_insn "cmpsi2_addneg"
745 [(set (reg:CC CC_REGNUM)
747 (match_operand:SI 1 "s_register_operand" "r,r")
748 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
749 (set (match_operand:SI 0 "s_register_operand" "=r,r")
750 (plus:SI (match_dup 1)
751 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
752 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
755 sub%.\\t%0, %1, #%n3"
756 [(set_attr "conds" "set")
757 (set_attr "type" "alus_reg")]
760 ;; Convert the sequence
762 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
766 ;; bcs dest ((unsigned)rn >= 1)
767 ;; similarly for the beq variant using bcc.
768 ;; This is a common looping idiom (while (n--))
770 [(set (match_operand:SI 0 "arm_general_register_operand" "")
771 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
773 (set (match_operand 2 "cc_register" "")
774 (compare (match_dup 0) (const_int -1)))
776 (if_then_else (match_operator 3 "equality_operator"
777 [(match_dup 2) (const_int 0)])
778 (match_operand 4 "" "")
779 (match_operand 5 "" "")))]
780 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
784 (match_dup 1) (const_int 1)))
785 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
787 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
790 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
791 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
794 operands[2], const0_rtx);"
797 ;; The next four insns work because they compare the result with one of
798 ;; the operands, and we know that the use of the condition code is
799 ;; either GEU or LTU, so we can use the carry flag from the addition
800 ;; instead of doing the compare a second time.
801 (define_insn "*addsi3_compare_op1"
802 [(set (reg:CC_C CC_REGNUM)
804 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
805 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
807 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
808 (plus:SI (match_dup 1) (match_dup 2)))]
814 [(set_attr "conds" "set")
815 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
818 (define_insn "*addsi3_compare_op2"
819 [(set (reg:CC_C CC_REGNUM)
821 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
822 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
824 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
825 (plus:SI (match_dup 1) (match_dup 2)))]
830 sub%.\\t%0, %1, #%n2"
831 [(set_attr "conds" "set")
832 (set_attr "type" "alus_imm,alus_imm,alus_reg")]
835 (define_insn "*compare_addsi2_op0"
836 [(set (reg:CC_C CC_REGNUM)
838 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
839 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
848 [(set_attr "conds" "set")
849 (set_attr "predicable" "yes")
850 (set_attr "arch" "t2,t2,*,*,*")
851 (set_attr "predicable_short_it" "yes,yes,no,no,no")
852 (set_attr "length" "2,2,4,4,4")
853 (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
856 (define_insn "*compare_addsi2_op1"
857 [(set (reg:CC_C CC_REGNUM)
859 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
860 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
869 [(set_attr "conds" "set")
870 (set_attr "predicable" "yes")
871 (set_attr "arch" "t2,t2,*,*,*")
872 (set_attr "predicable_short_it" "yes,yes,no,no,no")
873 (set_attr "length" "2,2,4,4,4")
874 (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
877 (define_insn "*addsi3_carryin_<optab>"
878 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
879 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
880 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
881 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
886 sbc%?\\t%0, %1, #%B2"
887 [(set_attr "conds" "use")
888 (set_attr "predicable" "yes")
889 (set_attr "arch" "t2,*,*")
890 (set_attr "length" "4")
891 (set_attr "predicable_short_it" "yes,no,no")
892 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
895 (define_insn "*addsi3_carryin_alt2_<optab>"
896 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
897 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
898 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
899 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
904 sbc%?\\t%0, %1, #%B2"
905 [(set_attr "conds" "use")
906 (set_attr "predicable" "yes")
907 (set_attr "arch" "t2,*,*")
908 (set_attr "length" "4")
909 (set_attr "predicable_short_it" "yes,no,no")
910 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
913 (define_insn "*addsi3_carryin_shift_<optab>"
914 [(set (match_operand:SI 0 "s_register_operand" "=r")
916 (match_operator:SI 2 "shift_operator"
917 [(match_operand:SI 3 "s_register_operand" "r")
918 (match_operand:SI 4 "reg_or_int_operand" "rM")])
919 (match_operand:SI 1 "s_register_operand" "r"))
920 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
922 "adc%?\\t%0, %1, %3%S2"
923 [(set_attr "conds" "use")
924 (set_attr "predicable" "yes")
925 (set_attr "predicable_short_it" "no")
926 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
927 (const_string "alu_shift_imm")
928 (const_string "alu_shift_reg")))]
931 (define_insn "*addsi3_carryin_clobercc_<optab>"
932 [(set (match_operand:SI 0 "s_register_operand" "=r")
933 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
934 (match_operand:SI 2 "arm_rhs_operand" "rI"))
935 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
936 (clobber (reg:CC CC_REGNUM))]
939 [(set_attr "conds" "set")
940 (set_attr "type" "adcs_reg")]
943 (define_insn "*subsi3_carryin"
944 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
945 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
946 (match_operand:SI 2 "s_register_operand" "r,r"))
947 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
952 [(set_attr "conds" "use")
953 (set_attr "arch" "*,a")
954 (set_attr "predicable" "yes")
955 (set_attr "predicable_short_it" "no")
956 (set_attr "type" "adc_reg,adc_imm")]
959 (define_insn "*subsi3_carryin_const"
960 [(set (match_operand:SI 0 "s_register_operand" "=r")
961 (minus:SI (plus:SI (match_operand:SI 1 "reg_or_int_operand" "r")
962 (match_operand:SI 2 "arm_not_operand" "K"))
963 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
966 [(set_attr "conds" "use")
967 (set_attr "type" "adc_imm")]
970 (define_insn "*subsi3_carryin_compare"
971 [(set (reg:CC CC_REGNUM)
972 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
973 (match_operand:SI 2 "s_register_operand" "r")))
974 (set (match_operand:SI 0 "s_register_operand" "=r")
975 (minus:SI (minus:SI (match_dup 1)
977 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
980 [(set_attr "conds" "set")
981 (set_attr "type" "adcs_reg")]
984 (define_insn "*subsi3_carryin_compare_const"
985 [(set (reg:CC CC_REGNUM)
986 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
987 (match_operand:SI 2 "arm_not_operand" "K")))
988 (set (match_operand:SI 0 "s_register_operand" "=r")
989 (minus:SI (plus:SI (match_dup 1)
991 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
993 "sbcs\\t%0, %1, #%B2"
994 [(set_attr "conds" "set")
995 (set_attr "type" "adcs_imm")]
998 (define_insn "*subsi3_carryin_shift"
999 [(set (match_operand:SI 0 "s_register_operand" "=r")
1001 (match_operand:SI 1 "s_register_operand" "r")
1002 (match_operator:SI 2 "shift_operator"
1003 [(match_operand:SI 3 "s_register_operand" "r")
1004 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1005 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1007 "sbc%?\\t%0, %1, %3%S2"
1008 [(set_attr "conds" "use")
1009 (set_attr "predicable" "yes")
1010 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1011 (const_string "alu_shift_imm")
1012 (const_string "alu_shift_reg")))]
1015 (define_insn "*rsbsi3_carryin_shift"
1016 [(set (match_operand:SI 0 "s_register_operand" "=r")
1018 (match_operator:SI 2 "shift_operator"
1019 [(match_operand:SI 3 "s_register_operand" "r")
1020 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1021 (match_operand:SI 1 "s_register_operand" "r"))
1022 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1024 "rsc%?\\t%0, %1, %3%S2"
1025 [(set_attr "conds" "use")
1026 (set_attr "predicable" "yes")
1027 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1028 (const_string "alu_shift_imm")
1029 (const_string "alu_shift_reg")))]
1032 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1034 [(set (match_operand:SI 0 "s_register_operand" "")
1035 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1036 (match_operand:SI 2 "s_register_operand" ""))
1038 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1040 [(set (match_dup 3) (match_dup 1))
1041 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1043 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1046 (define_expand "addsf3"
1047 [(set (match_operand:SF 0 "s_register_operand" "")
1048 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1049 (match_operand:SF 2 "s_register_operand" "")))]
1050 "TARGET_32BIT && TARGET_HARD_FLOAT"
1054 (define_expand "adddf3"
1055 [(set (match_operand:DF 0 "s_register_operand" "")
1056 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1057 (match_operand:DF 2 "s_register_operand" "")))]
1058 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1062 (define_expand "subdi3"
1064 [(set (match_operand:DI 0 "s_register_operand" "")
1065 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1066 (match_operand:DI 2 "s_register_operand" "")))
1067 (clobber (reg:CC CC_REGNUM))])]
1072 if (!REG_P (operands[1]))
1073 operands[1] = force_reg (DImode, operands[1]);
1074 if (!REG_P (operands[2]))
1075 operands[2] = force_reg (DImode, operands[2]);
1080 (define_insn_and_split "*arm_subdi3"
1081 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1082 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1083 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1084 (clobber (reg:CC CC_REGNUM))]
1085 "TARGET_32BIT && !TARGET_NEON"
1086 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1087 "&& reload_completed"
1088 [(parallel [(set (reg:CC CC_REGNUM)
1089 (compare:CC (match_dup 1) (match_dup 2)))
1090 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1091 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1092 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1094 operands[3] = gen_highpart (SImode, operands[0]);
1095 operands[0] = gen_lowpart (SImode, operands[0]);
1096 operands[4] = gen_highpart (SImode, operands[1]);
1097 operands[1] = gen_lowpart (SImode, operands[1]);
1098 operands[5] = gen_highpart (SImode, operands[2]);
1099 operands[2] = gen_lowpart (SImode, operands[2]);
1101 [(set_attr "conds" "clob")
1102 (set_attr "length" "8")
1103 (set_attr "type" "multiple")]
1106 (define_insn "*thumb_subdi3"
1107 [(set (match_operand:DI 0 "register_operand" "=l")
1108 (minus:DI (match_operand:DI 1 "register_operand" "0")
1109 (match_operand:DI 2 "register_operand" "l")))
1110 (clobber (reg:CC CC_REGNUM))]
1112 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
1113 [(set_attr "length" "4")
1114 (set_attr "type" "multiple")]
1117 (define_insn_and_split "*subdi_di_zesidi"
1118 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1119 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1121 (match_operand:SI 2 "s_register_operand" "r,r"))))
1122 (clobber (reg:CC CC_REGNUM))]
1124 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1125 "&& reload_completed"
1126 [(parallel [(set (reg:CC CC_REGNUM)
1127 (compare:CC (match_dup 1) (match_dup 2)))
1128 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1129 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1130 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1132 operands[3] = gen_highpart (SImode, operands[0]);
1133 operands[0] = gen_lowpart (SImode, operands[0]);
1134 operands[4] = gen_highpart (SImode, operands[1]);
1135 operands[1] = gen_lowpart (SImode, operands[1]);
1136 operands[5] = GEN_INT (~0);
1138 [(set_attr "conds" "clob")
1139 (set_attr "length" "8")
1140 (set_attr "type" "multiple")]
1143 (define_insn_and_split "*subdi_di_sesidi"
1144 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1145 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1147 (match_operand:SI 2 "s_register_operand" "r,r"))))
1148 (clobber (reg:CC CC_REGNUM))]
1150 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1151 "&& reload_completed"
1152 [(parallel [(set (reg:CC CC_REGNUM)
1153 (compare:CC (match_dup 1) (match_dup 2)))
1154 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1155 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1156 (ashiftrt:SI (match_dup 2)
1158 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1160 operands[3] = gen_highpart (SImode, operands[0]);
1161 operands[0] = gen_lowpart (SImode, operands[0]);
1162 operands[4] = gen_highpart (SImode, operands[1]);
1163 operands[1] = gen_lowpart (SImode, operands[1]);
1165 [(set_attr "conds" "clob")
1166 (set_attr "length" "8")
1167 (set_attr "type" "multiple")]
1170 (define_insn_and_split "*subdi_zesidi_di"
1171 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1172 (minus:DI (zero_extend:DI
1173 (match_operand:SI 2 "s_register_operand" "r,r"))
1174 (match_operand:DI 1 "s_register_operand" "0,r")))
1175 (clobber (reg:CC CC_REGNUM))]
1177 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1179 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1180 "&& reload_completed"
1181 [(parallel [(set (reg:CC CC_REGNUM)
1182 (compare:CC (match_dup 2) (match_dup 1)))
1183 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1184 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1185 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1187 operands[3] = gen_highpart (SImode, operands[0]);
1188 operands[0] = gen_lowpart (SImode, operands[0]);
1189 operands[4] = gen_highpart (SImode, operands[1]);
1190 operands[1] = gen_lowpart (SImode, operands[1]);
1192 [(set_attr "conds" "clob")
1193 (set_attr "length" "8")
1194 (set_attr "type" "multiple")]
1197 (define_insn_and_split "*subdi_sesidi_di"
1198 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1199 (minus:DI (sign_extend:DI
1200 (match_operand:SI 2 "s_register_operand" "r,r"))
1201 (match_operand:DI 1 "s_register_operand" "0,r")))
1202 (clobber (reg:CC CC_REGNUM))]
1204 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1206 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1207 "&& reload_completed"
1208 [(parallel [(set (reg:CC CC_REGNUM)
1209 (compare:CC (match_dup 2) (match_dup 1)))
1210 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1211 (set (match_dup 3) (minus:SI (minus:SI
1212 (ashiftrt:SI (match_dup 2)
1215 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1217 operands[3] = gen_highpart (SImode, operands[0]);
1218 operands[0] = gen_lowpart (SImode, operands[0]);
1219 operands[4] = gen_highpart (SImode, operands[1]);
1220 operands[1] = gen_lowpart (SImode, operands[1]);
1222 [(set_attr "conds" "clob")
1223 (set_attr "length" "8")
1224 (set_attr "type" "multiple")]
1227 (define_insn_and_split "*subdi_zesidi_zesidi"
1228 [(set (match_operand:DI 0 "s_register_operand" "=r")
1229 (minus:DI (zero_extend:DI
1230 (match_operand:SI 1 "s_register_operand" "r"))
1232 (match_operand:SI 2 "s_register_operand" "r"))))
1233 (clobber (reg:CC CC_REGNUM))]
1235 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1236 "&& reload_completed"
1237 [(parallel [(set (reg:CC CC_REGNUM)
1238 (compare:CC (match_dup 1) (match_dup 2)))
1239 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1240 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1241 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1243 operands[3] = gen_highpart (SImode, operands[0]);
1244 operands[0] = gen_lowpart (SImode, operands[0]);
1246 [(set_attr "conds" "clob")
1247 (set_attr "length" "8")
1248 (set_attr "type" "multiple")]
1251 (define_expand "subsi3"
1252 [(set (match_operand:SI 0 "s_register_operand" "")
1253 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1254 (match_operand:SI 2 "s_register_operand" "")))]
1257 if (CONST_INT_P (operands[1]))
1261 arm_split_constant (MINUS, SImode, NULL_RTX,
1262 INTVAL (operands[1]), operands[0],
1263 operands[2], optimize && can_create_pseudo_p ());
1266 else /* TARGET_THUMB1 */
1267 operands[1] = force_reg (SImode, operands[1]);
1272 (define_insn "thumb1_subsi3_insn"
1273 [(set (match_operand:SI 0 "register_operand" "=l")
1274 (minus:SI (match_operand:SI 1 "register_operand" "l")
1275 (match_operand:SI 2 "reg_or_int_operand" "lPd")))]
1278 [(set_attr "length" "2")
1279 (set_attr "conds" "set")
1280 (set_attr "type" "alus_reg")]
1283 ; ??? Check Thumb-2 split length
1284 (define_insn_and_split "*arm_subsi3_insn"
1285 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r ,r,r,rk,r")
1286 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,rI,r,r,k ,?n")
1287 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r ,I,r,r ,r")))]
1299 "&& (CONST_INT_P (operands[1])
1300 && !const_ok_for_arm (INTVAL (operands[1])))"
1301 [(clobber (const_int 0))]
1303 arm_split_constant (MINUS, SImode, curr_insn,
1304 INTVAL (operands[1]), operands[0], operands[2], 0);
1307 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1308 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1309 (set_attr "predicable" "yes")
1310 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1311 (set_attr "type" "alu_reg,alu_reg,alu_reg,alu_reg,alu_imm,alu_imm,alu_reg,alu_reg,multiple")]
1315 [(match_scratch:SI 3 "r")
1316 (set (match_operand:SI 0 "arm_general_register_operand" "")
1317 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1318 (match_operand:SI 2 "arm_general_register_operand" "")))]
1320 && !const_ok_for_arm (INTVAL (operands[1]))
1321 && const_ok_for_arm (~INTVAL (operands[1]))"
1322 [(set (match_dup 3) (match_dup 1))
1323 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1327 (define_insn "*subsi3_compare0"
1328 [(set (reg:CC_NOOV CC_REGNUM)
1330 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1331 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1333 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1334 (minus:SI (match_dup 1) (match_dup 2)))]
1340 [(set_attr "conds" "set")
1341 (set_attr "type" "alus_imm,alus_reg,alus_reg")]
1344 (define_insn "subsi3_compare"
1345 [(set (reg:CC CC_REGNUM)
1346 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1347 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1348 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1349 (minus:SI (match_dup 1) (match_dup 2)))]
1355 [(set_attr "conds" "set")
1356 (set_attr "type" "alus_imm,alus_reg,alus_reg")]
1359 (define_expand "subsf3"
1360 [(set (match_operand:SF 0 "s_register_operand" "")
1361 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1362 (match_operand:SF 2 "s_register_operand" "")))]
1363 "TARGET_32BIT && TARGET_HARD_FLOAT"
1367 (define_expand "subdf3"
1368 [(set (match_operand:DF 0 "s_register_operand" "")
1369 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1370 (match_operand:DF 2 "s_register_operand" "")))]
1371 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1376 ;; Multiplication insns
1378 (define_expand "mulhi3"
1379 [(set (match_operand:HI 0 "s_register_operand" "")
1380 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1381 (match_operand:HI 2 "s_register_operand" "")))]
1382 "TARGET_DSP_MULTIPLY"
1385 rtx result = gen_reg_rtx (SImode);
1386 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1387 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1392 (define_expand "mulsi3"
1393 [(set (match_operand:SI 0 "s_register_operand" "")
1394 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1395 (match_operand:SI 1 "s_register_operand" "")))]
1400 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1401 (define_insn "*arm_mulsi3"
1402 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1403 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1404 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1405 "TARGET_32BIT && !arm_arch6"
1406 "mul%?\\t%0, %2, %1"
1407 [(set_attr "type" "mul")
1408 (set_attr "predicable" "yes")]
1411 (define_insn "*arm_mulsi3_v6"
1412 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1413 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1414 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1415 "TARGET_32BIT && arm_arch6"
1416 "mul%?\\t%0, %1, %2"
1417 [(set_attr "type" "mul")
1418 (set_attr "predicable" "yes")
1419 (set_attr "arch" "t2,t2,*")
1420 (set_attr "length" "4")
1421 (set_attr "predicable_short_it" "yes,yes,no")]
1424 ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands
1425 ; 1 and 2; are the same, because reload will make operand 0 match
1426 ; operand 1 without realizing that this conflicts with operand 2. We fix
1427 ; this by adding another alternative to match this case, and then `reload'
1428 ; it ourselves. This alternative must come first.
1429 (define_insn "*thumb_mulsi3"
1430 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l")
1431 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0")
1432 (match_operand:SI 2 "register_operand" "l,l,l")))]
1433 "TARGET_THUMB1 && !arm_arch6"
1435 if (which_alternative < 2)
1436 return \"mov\\t%0, %1\;mul\\t%0, %2\";
1438 return \"mul\\t%0, %2\";
1440 [(set_attr "length" "4,4,2")
1441 (set_attr "type" "muls")]
1444 (define_insn "*thumb_mulsi3_v6"
1445 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
1446 (mult:SI (match_operand:SI 1 "register_operand" "0,l,0")
1447 (match_operand:SI 2 "register_operand" "l,0,0")))]
1448 "TARGET_THUMB1 && arm_arch6"
1453 [(set_attr "length" "2")
1454 (set_attr "type" "muls")]
1457 (define_insn "*mulsi3_compare0"
1458 [(set (reg:CC_NOOV CC_REGNUM)
1459 (compare:CC_NOOV (mult:SI
1460 (match_operand:SI 2 "s_register_operand" "r,r")
1461 (match_operand:SI 1 "s_register_operand" "%0,r"))
1463 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1464 (mult:SI (match_dup 2) (match_dup 1)))]
1465 "TARGET_ARM && !arm_arch6"
1466 "mul%.\\t%0, %2, %1"
1467 [(set_attr "conds" "set")
1468 (set_attr "type" "muls")]
1471 (define_insn "*mulsi3_compare0_v6"
1472 [(set (reg:CC_NOOV CC_REGNUM)
1473 (compare:CC_NOOV (mult:SI
1474 (match_operand:SI 2 "s_register_operand" "r")
1475 (match_operand:SI 1 "s_register_operand" "r"))
1477 (set (match_operand:SI 0 "s_register_operand" "=r")
1478 (mult:SI (match_dup 2) (match_dup 1)))]
1479 "TARGET_ARM && arm_arch6 && optimize_size"
1480 "mul%.\\t%0, %2, %1"
1481 [(set_attr "conds" "set")
1482 (set_attr "type" "muls")]
1485 (define_insn "*mulsi_compare0_scratch"
1486 [(set (reg:CC_NOOV CC_REGNUM)
1487 (compare:CC_NOOV (mult:SI
1488 (match_operand:SI 2 "s_register_operand" "r,r")
1489 (match_operand:SI 1 "s_register_operand" "%0,r"))
1491 (clobber (match_scratch:SI 0 "=&r,&r"))]
1492 "TARGET_ARM && !arm_arch6"
1493 "mul%.\\t%0, %2, %1"
1494 [(set_attr "conds" "set")
1495 (set_attr "type" "muls")]
1498 (define_insn "*mulsi_compare0_scratch_v6"
1499 [(set (reg:CC_NOOV CC_REGNUM)
1500 (compare:CC_NOOV (mult:SI
1501 (match_operand:SI 2 "s_register_operand" "r")
1502 (match_operand:SI 1 "s_register_operand" "r"))
1504 (clobber (match_scratch:SI 0 "=r"))]
1505 "TARGET_ARM && arm_arch6 && optimize_size"
1506 "mul%.\\t%0, %2, %1"
1507 [(set_attr "conds" "set")
1508 (set_attr "type" "muls")]
1511 ;; Unnamed templates to match MLA instruction.
1513 (define_insn "*mulsi3addsi"
1514 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1516 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1517 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1518 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1519 "TARGET_32BIT && !arm_arch6"
1520 "mla%?\\t%0, %2, %1, %3"
1521 [(set_attr "type" "mla")
1522 (set_attr "predicable" "yes")]
1525 (define_insn "*mulsi3addsi_v6"
1526 [(set (match_operand:SI 0 "s_register_operand" "=r")
1528 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1529 (match_operand:SI 1 "s_register_operand" "r"))
1530 (match_operand:SI 3 "s_register_operand" "r")))]
1531 "TARGET_32BIT && arm_arch6"
1532 "mla%?\\t%0, %2, %1, %3"
1533 [(set_attr "type" "mla")
1534 (set_attr "predicable" "yes")
1535 (set_attr "predicable_short_it" "no")]
1538 (define_insn "*mulsi3addsi_compare0"
1539 [(set (reg:CC_NOOV CC_REGNUM)
1542 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1543 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1544 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1546 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1547 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1549 "TARGET_ARM && arm_arch6"
1550 "mla%.\\t%0, %2, %1, %3"
1551 [(set_attr "conds" "set")
1552 (set_attr "type" "mlas")]
1555 (define_insn "*mulsi3addsi_compare0_v6"
1556 [(set (reg:CC_NOOV CC_REGNUM)
1559 (match_operand:SI 2 "s_register_operand" "r")
1560 (match_operand:SI 1 "s_register_operand" "r"))
1561 (match_operand:SI 3 "s_register_operand" "r"))
1563 (set (match_operand:SI 0 "s_register_operand" "=r")
1564 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1566 "TARGET_ARM && arm_arch6 && optimize_size"
1567 "mla%.\\t%0, %2, %1, %3"
1568 [(set_attr "conds" "set")
1569 (set_attr "type" "mlas")]
1572 (define_insn "*mulsi3addsi_compare0_scratch"
1573 [(set (reg:CC_NOOV CC_REGNUM)
1576 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1577 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1578 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1580 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1581 "TARGET_ARM && !arm_arch6"
1582 "mla%.\\t%0, %2, %1, %3"
1583 [(set_attr "conds" "set")
1584 (set_attr "type" "mlas")]
1587 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1588 [(set (reg:CC_NOOV CC_REGNUM)
1591 (match_operand:SI 2 "s_register_operand" "r")
1592 (match_operand:SI 1 "s_register_operand" "r"))
1593 (match_operand:SI 3 "s_register_operand" "r"))
1595 (clobber (match_scratch:SI 0 "=r"))]
1596 "TARGET_ARM && arm_arch6 && optimize_size"
1597 "mla%.\\t%0, %2, %1, %3"
1598 [(set_attr "conds" "set")
1599 (set_attr "type" "mlas")]
1602 (define_insn "*mulsi3subsi"
1603 [(set (match_operand:SI 0 "s_register_operand" "=r")
1605 (match_operand:SI 3 "s_register_operand" "r")
1606 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1607 (match_operand:SI 1 "s_register_operand" "r"))))]
1608 "TARGET_32BIT && arm_arch_thumb2"
1609 "mls%?\\t%0, %2, %1, %3"
1610 [(set_attr "type" "mla")
1611 (set_attr "predicable" "yes")
1612 (set_attr "predicable_short_it" "no")]
1615 (define_expand "maddsidi4"
1616 [(set (match_operand:DI 0 "s_register_operand" "")
1619 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1620 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1621 (match_operand:DI 3 "s_register_operand" "")))]
1622 "TARGET_32BIT && arm_arch3m"
1625 (define_insn "*mulsidi3adddi"
1626 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1629 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1630 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1631 (match_operand:DI 1 "s_register_operand" "0")))]
1632 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1633 "smlal%?\\t%Q0, %R0, %3, %2"
1634 [(set_attr "type" "smlal")
1635 (set_attr "predicable" "yes")]
1638 (define_insn "*mulsidi3adddi_v6"
1639 [(set (match_operand:DI 0 "s_register_operand" "=r")
1642 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1643 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1644 (match_operand:DI 1 "s_register_operand" "0")))]
1645 "TARGET_32BIT && arm_arch6"
1646 "smlal%?\\t%Q0, %R0, %3, %2"
1647 [(set_attr "type" "smlal")
1648 (set_attr "predicable" "yes")
1649 (set_attr "predicable_short_it" "no")]
1652 ;; 32x32->64 widening multiply.
1653 ;; As with mulsi3, the only difference between the v3-5 and v6+
1654 ;; versions of these patterns is the requirement that the output not
1655 ;; overlap the inputs, but that still means we have to have a named
1656 ;; expander and two different starred insns.
1658 (define_expand "mulsidi3"
1659 [(set (match_operand:DI 0 "s_register_operand" "")
1661 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1662 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1663 "TARGET_32BIT && arm_arch3m"
1667 (define_insn "*mulsidi3_nov6"
1668 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1670 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1671 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1672 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1673 "smull%?\\t%Q0, %R0, %1, %2"
1674 [(set_attr "type" "smull")
1675 (set_attr "predicable" "yes")]
1678 (define_insn "*mulsidi3_v6"
1679 [(set (match_operand:DI 0 "s_register_operand" "=r")
1681 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1682 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1683 "TARGET_32BIT && arm_arch6"
1684 "smull%?\\t%Q0, %R0, %1, %2"
1685 [(set_attr "type" "smull")
1686 (set_attr "predicable" "yes")
1687 (set_attr "predicable_short_it" "no")]
1690 (define_expand "umulsidi3"
1691 [(set (match_operand:DI 0 "s_register_operand" "")
1693 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1694 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1695 "TARGET_32BIT && arm_arch3m"
1699 (define_insn "*umulsidi3_nov6"
1700 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1702 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1703 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1704 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1705 "umull%?\\t%Q0, %R0, %1, %2"
1706 [(set_attr "type" "umull")
1707 (set_attr "predicable" "yes")]
1710 (define_insn "*umulsidi3_v6"
1711 [(set (match_operand:DI 0 "s_register_operand" "=r")
1713 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1714 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1715 "TARGET_32BIT && arm_arch6"
1716 "umull%?\\t%Q0, %R0, %1, %2"
1717 [(set_attr "type" "umull")
1718 (set_attr "predicable" "yes")
1719 (set_attr "predicable_short_it" "no")]
1722 (define_expand "umaddsidi4"
1723 [(set (match_operand:DI 0 "s_register_operand" "")
1726 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1727 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1728 (match_operand:DI 3 "s_register_operand" "")))]
1729 "TARGET_32BIT && arm_arch3m"
1732 (define_insn "*umulsidi3adddi"
1733 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1736 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1737 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1738 (match_operand:DI 1 "s_register_operand" "0")))]
1739 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1740 "umlal%?\\t%Q0, %R0, %3, %2"
1741 [(set_attr "type" "umlal")
1742 (set_attr "predicable" "yes")]
1745 (define_insn "*umulsidi3adddi_v6"
1746 [(set (match_operand:DI 0 "s_register_operand" "=r")
1749 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1750 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1751 (match_operand:DI 1 "s_register_operand" "0")))]
1752 "TARGET_32BIT && arm_arch6"
1753 "umlal%?\\t%Q0, %R0, %3, %2"
1754 [(set_attr "type" "umlal")
1755 (set_attr "predicable" "yes")
1756 (set_attr "predicable_short_it" "no")]
1759 (define_expand "smulsi3_highpart"
1761 [(set (match_operand:SI 0 "s_register_operand" "")
1765 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1766 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1768 (clobber (match_scratch:SI 3 ""))])]
1769 "TARGET_32BIT && arm_arch3m"
1773 (define_insn "*smulsi3_highpart_nov6"
1774 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1778 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1779 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1781 (clobber (match_scratch:SI 3 "=&r,&r"))]
1782 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1783 "smull%?\\t%3, %0, %2, %1"
1784 [(set_attr "type" "smull")
1785 (set_attr "predicable" "yes")]
1788 (define_insn "*smulsi3_highpart_v6"
1789 [(set (match_operand:SI 0 "s_register_operand" "=r")
1793 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1794 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1796 (clobber (match_scratch:SI 3 "=r"))]
1797 "TARGET_32BIT && arm_arch6"
1798 "smull%?\\t%3, %0, %2, %1"
1799 [(set_attr "type" "smull")
1800 (set_attr "predicable" "yes")
1801 (set_attr "predicable_short_it" "no")]
1804 (define_expand "umulsi3_highpart"
1806 [(set (match_operand:SI 0 "s_register_operand" "")
1810 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1811 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1813 (clobber (match_scratch:SI 3 ""))])]
1814 "TARGET_32BIT && arm_arch3m"
1818 (define_insn "*umulsi3_highpart_nov6"
1819 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1823 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1824 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1826 (clobber (match_scratch:SI 3 "=&r,&r"))]
1827 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1828 "umull%?\\t%3, %0, %2, %1"
1829 [(set_attr "type" "umull")
1830 (set_attr "predicable" "yes")]
1833 (define_insn "*umulsi3_highpart_v6"
1834 [(set (match_operand:SI 0 "s_register_operand" "=r")
1838 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1839 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1841 (clobber (match_scratch:SI 3 "=r"))]
1842 "TARGET_32BIT && arm_arch6"
1843 "umull%?\\t%3, %0, %2, %1"
1844 [(set_attr "type" "umull")
1845 (set_attr "predicable" "yes")
1846 (set_attr "predicable_short_it" "no")]
1849 (define_insn "mulhisi3"
1850 [(set (match_operand:SI 0 "s_register_operand" "=r")
1851 (mult:SI (sign_extend:SI
1852 (match_operand:HI 1 "s_register_operand" "%r"))
1854 (match_operand:HI 2 "s_register_operand" "r"))))]
1855 "TARGET_DSP_MULTIPLY"
1856 "smulbb%?\\t%0, %1, %2"
1857 [(set_attr "type" "smulxy")
1858 (set_attr "predicable" "yes")]
1861 (define_insn "*mulhisi3tb"
1862 [(set (match_operand:SI 0 "s_register_operand" "=r")
1863 (mult:SI (ashiftrt:SI
1864 (match_operand:SI 1 "s_register_operand" "r")
1867 (match_operand:HI 2 "s_register_operand" "r"))))]
1868 "TARGET_DSP_MULTIPLY"
1869 "smultb%?\\t%0, %1, %2"
1870 [(set_attr "type" "smulxy")
1871 (set_attr "predicable" "yes")
1872 (set_attr "predicable_short_it" "no")]
1875 (define_insn "*mulhisi3bt"
1876 [(set (match_operand:SI 0 "s_register_operand" "=r")
1877 (mult:SI (sign_extend:SI
1878 (match_operand:HI 1 "s_register_operand" "r"))
1880 (match_operand:SI 2 "s_register_operand" "r")
1882 "TARGET_DSP_MULTIPLY"
1883 "smulbt%?\\t%0, %1, %2"
1884 [(set_attr "type" "smulxy")
1885 (set_attr "predicable" "yes")
1886 (set_attr "predicable_short_it" "no")]
1889 (define_insn "*mulhisi3tt"
1890 [(set (match_operand:SI 0 "s_register_operand" "=r")
1891 (mult:SI (ashiftrt:SI
1892 (match_operand:SI 1 "s_register_operand" "r")
1895 (match_operand:SI 2 "s_register_operand" "r")
1897 "TARGET_DSP_MULTIPLY"
1898 "smultt%?\\t%0, %1, %2"
1899 [(set_attr "type" "smulxy")
1900 (set_attr "predicable" "yes")
1901 (set_attr "predicable_short_it" "no")]
1904 (define_insn "maddhisi4"
1905 [(set (match_operand:SI 0 "s_register_operand" "=r")
1906 (plus:SI (mult:SI (sign_extend:SI
1907 (match_operand:HI 1 "s_register_operand" "r"))
1909 (match_operand:HI 2 "s_register_operand" "r")))
1910 (match_operand:SI 3 "s_register_operand" "r")))]
1911 "TARGET_DSP_MULTIPLY"
1912 "smlabb%?\\t%0, %1, %2, %3"
1913 [(set_attr "type" "smlaxy")
1914 (set_attr "predicable" "yes")
1915 (set_attr "predicable_short_it" "no")]
1918 ;; Note: there is no maddhisi4ibt because this one is canonical form
1919 (define_insn "*maddhisi4tb"
1920 [(set (match_operand:SI 0 "s_register_operand" "=r")
1921 (plus:SI (mult:SI (ashiftrt:SI
1922 (match_operand:SI 1 "s_register_operand" "r")
1925 (match_operand:HI 2 "s_register_operand" "r")))
1926 (match_operand:SI 3 "s_register_operand" "r")))]
1927 "TARGET_DSP_MULTIPLY"
1928 "smlatb%?\\t%0, %1, %2, %3"
1929 [(set_attr "type" "smlaxy")
1930 (set_attr "predicable" "yes")
1931 (set_attr "predicable_short_it" "no")]
1934 (define_insn "*maddhisi4tt"
1935 [(set (match_operand:SI 0 "s_register_operand" "=r")
1936 (plus:SI (mult:SI (ashiftrt:SI
1937 (match_operand:SI 1 "s_register_operand" "r")
1940 (match_operand:SI 2 "s_register_operand" "r")
1942 (match_operand:SI 3 "s_register_operand" "r")))]
1943 "TARGET_DSP_MULTIPLY"
1944 "smlatt%?\\t%0, %1, %2, %3"
1945 [(set_attr "type" "smlaxy")
1946 (set_attr "predicable" "yes")
1947 (set_attr "predicable_short_it" "no")]
1950 (define_insn "maddhidi4"
1951 [(set (match_operand:DI 0 "s_register_operand" "=r")
1953 (mult:DI (sign_extend:DI
1954 (match_operand:HI 1 "s_register_operand" "r"))
1956 (match_operand:HI 2 "s_register_operand" "r")))
1957 (match_operand:DI 3 "s_register_operand" "0")))]
1958 "TARGET_DSP_MULTIPLY"
1959 "smlalbb%?\\t%Q0, %R0, %1, %2"
1960 [(set_attr "type" "smlalxy")
1961 (set_attr "predicable" "yes")
1962 (set_attr "predicable_short_it" "no")])
1964 ;; Note: there is no maddhidi4ibt because this one is canonical form
1965 (define_insn "*maddhidi4tb"
1966 [(set (match_operand:DI 0 "s_register_operand" "=r")
1968 (mult:DI (sign_extend:DI
1970 (match_operand:SI 1 "s_register_operand" "r")
1973 (match_operand:HI 2 "s_register_operand" "r")))
1974 (match_operand:DI 3 "s_register_operand" "0")))]
1975 "TARGET_DSP_MULTIPLY"
1976 "smlaltb%?\\t%Q0, %R0, %1, %2"
1977 [(set_attr "type" "smlalxy")
1978 (set_attr "predicable" "yes")
1979 (set_attr "predicable_short_it" "no")])
1981 (define_insn "*maddhidi4tt"
1982 [(set (match_operand:DI 0 "s_register_operand" "=r")
1984 (mult:DI (sign_extend:DI
1986 (match_operand:SI 1 "s_register_operand" "r")
1990 (match_operand:SI 2 "s_register_operand" "r")
1992 (match_operand:DI 3 "s_register_operand" "0")))]
1993 "TARGET_DSP_MULTIPLY"
1994 "smlaltt%?\\t%Q0, %R0, %1, %2"
1995 [(set_attr "type" "smlalxy")
1996 (set_attr "predicable" "yes")
1997 (set_attr "predicable_short_it" "no")])
1999 (define_expand "mulsf3"
2000 [(set (match_operand:SF 0 "s_register_operand" "")
2001 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2002 (match_operand:SF 2 "s_register_operand" "")))]
2003 "TARGET_32BIT && TARGET_HARD_FLOAT"
2007 (define_expand "muldf3"
2008 [(set (match_operand:DF 0 "s_register_operand" "")
2009 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2010 (match_operand:DF 2 "s_register_operand" "")))]
2011 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2017 (define_expand "divsf3"
2018 [(set (match_operand:SF 0 "s_register_operand" "")
2019 (div:SF (match_operand:SF 1 "s_register_operand" "")
2020 (match_operand:SF 2 "s_register_operand" "")))]
2021 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
2024 (define_expand "divdf3"
2025 [(set (match_operand:DF 0 "s_register_operand" "")
2026 (div:DF (match_operand:DF 1 "s_register_operand" "")
2027 (match_operand:DF 2 "s_register_operand" "")))]
2028 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2031 ;; Boolean and,ior,xor insns
2033 ;; Split up double word logical operations
2035 ;; Split up simple DImode logical operations. Simply perform the logical
2036 ;; operation on the upper and lower halves of the registers.
2038 [(set (match_operand:DI 0 "s_register_operand" "")
2039 (match_operator:DI 6 "logical_binary_operator"
2040 [(match_operand:DI 1 "s_register_operand" "")
2041 (match_operand:DI 2 "s_register_operand" "")]))]
2042 "TARGET_32BIT && reload_completed
2043 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2044 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2045 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2046 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2049 operands[3] = gen_highpart (SImode, operands[0]);
2050 operands[0] = gen_lowpart (SImode, operands[0]);
2051 operands[4] = gen_highpart (SImode, operands[1]);
2052 operands[1] = gen_lowpart (SImode, operands[1]);
2053 operands[5] = gen_highpart (SImode, operands[2]);
2054 operands[2] = gen_lowpart (SImode, operands[2]);
2059 [(set (match_operand:DI 0 "s_register_operand" "")
2060 (match_operator:DI 6 "logical_binary_operator"
2061 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2062 (match_operand:DI 1 "s_register_operand" "")]))]
2063 "TARGET_32BIT && reload_completed"
2064 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2065 (set (match_dup 3) (match_op_dup:SI 6
2066 [(ashiftrt:SI (match_dup 2) (const_int 31))
2070 operands[3] = gen_highpart (SImode, operands[0]);
2071 operands[0] = gen_lowpart (SImode, operands[0]);
2072 operands[4] = gen_highpart (SImode, operands[1]);
2073 operands[1] = gen_lowpart (SImode, operands[1]);
2074 operands[5] = gen_highpart (SImode, operands[2]);
2075 operands[2] = gen_lowpart (SImode, operands[2]);
2079 ;; The zero extend of operand 2 means we can just copy the high part of
2080 ;; operand1 into operand0.
2082 [(set (match_operand:DI 0 "s_register_operand" "")
2084 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2085 (match_operand:DI 1 "s_register_operand" "")))]
2086 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2087 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2088 (set (match_dup 3) (match_dup 4))]
2091 operands[4] = gen_highpart (SImode, operands[1]);
2092 operands[3] = gen_highpart (SImode, operands[0]);
2093 operands[0] = gen_lowpart (SImode, operands[0]);
2094 operands[1] = gen_lowpart (SImode, operands[1]);
2098 ;; The zero extend of operand 2 means we can just copy the high part of
2099 ;; operand1 into operand0.
2101 [(set (match_operand:DI 0 "s_register_operand" "")
2103 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2104 (match_operand:DI 1 "s_register_operand" "")))]
2105 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2106 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2107 (set (match_dup 3) (match_dup 4))]
2110 operands[4] = gen_highpart (SImode, operands[1]);
2111 operands[3] = gen_highpart (SImode, operands[0]);
2112 operands[0] = gen_lowpart (SImode, operands[0]);
2113 operands[1] = gen_lowpart (SImode, operands[1]);
2117 (define_expand "anddi3"
2118 [(set (match_operand:DI 0 "s_register_operand" "")
2119 (and:DI (match_operand:DI 1 "s_register_operand" "")
2120 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2125 (define_insn_and_split "*anddi3_insn"
2126 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2127 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2128 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2129 "TARGET_32BIT && !TARGET_IWMMXT"
2131 switch (which_alternative)
2133 case 0: /* fall through */
2134 case 6: return "vand\t%P0, %P1, %P2";
2135 case 1: /* fall through */
2136 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2137 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2141 case 5: /* fall through */
2143 default: gcc_unreachable ();
2146 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2147 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2148 [(set (match_dup 3) (match_dup 4))
2149 (set (match_dup 5) (match_dup 6))]
2152 operands[3] = gen_lowpart (SImode, operands[0]);
2153 operands[5] = gen_highpart (SImode, operands[0]);
2155 operands[4] = simplify_gen_binary (AND, SImode,
2156 gen_lowpart (SImode, operands[1]),
2157 gen_lowpart (SImode, operands[2]));
2158 operands[6] = simplify_gen_binary (AND, SImode,
2159 gen_highpart (SImode, operands[1]),
2160 gen_highpart_mode (SImode, DImode, operands[2]));
2163 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2164 multiple,multiple,neon_logic,neon_logic")
2165 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2166 avoid_neon_for_64bits,avoid_neon_for_64bits")
2167 (set_attr "length" "*,*,8,8,8,8,*,*")
2171 (define_insn_and_split "*anddi_zesidi_di"
2172 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2173 (and:DI (zero_extend:DI
2174 (match_operand:SI 2 "s_register_operand" "r,r"))
2175 (match_operand:DI 1 "s_register_operand" "0,r")))]
2178 "TARGET_32BIT && reload_completed"
2179 ; The zero extend of operand 2 clears the high word of the output
2181 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2182 (set (match_dup 3) (const_int 0))]
2185 operands[3] = gen_highpart (SImode, operands[0]);
2186 operands[0] = gen_lowpart (SImode, operands[0]);
2187 operands[1] = gen_lowpart (SImode, operands[1]);
2189 [(set_attr "length" "8")
2190 (set_attr "type" "multiple")]
2193 (define_insn "*anddi_sesdi_di"
2194 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2195 (and:DI (sign_extend:DI
2196 (match_operand:SI 2 "s_register_operand" "r,r"))
2197 (match_operand:DI 1 "s_register_operand" "0,r")))]
2200 [(set_attr "length" "8")
2201 (set_attr "type" "multiple")]
2204 (define_expand "andsi3"
2205 [(set (match_operand:SI 0 "s_register_operand" "")
2206 (and:SI (match_operand:SI 1 "s_register_operand" "")
2207 (match_operand:SI 2 "reg_or_int_operand" "")))]
2212 if (CONST_INT_P (operands[2]))
2214 if (INTVAL (operands[2]) == 255 && arm_arch6)
2216 operands[1] = convert_to_mode (QImode, operands[1], 1);
2217 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2221 arm_split_constant (AND, SImode, NULL_RTX,
2222 INTVAL (operands[2]), operands[0],
2224 optimize && can_create_pseudo_p ());
2229 else /* TARGET_THUMB1 */
2231 if (!CONST_INT_P (operands[2]))
2233 rtx tmp = force_reg (SImode, operands[2]);
2234 if (rtx_equal_p (operands[0], operands[1]))
2238 operands[2] = operands[1];
2246 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2248 operands[2] = force_reg (SImode,
2249 GEN_INT (~INTVAL (operands[2])));
2251 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2256 for (i = 9; i <= 31; i++)
2258 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2]))
2260 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2264 else if ((((HOST_WIDE_INT) 1) << i) - 1
2265 == ~INTVAL (operands[2]))
2267 rtx shift = GEN_INT (i);
2268 rtx reg = gen_reg_rtx (SImode);
2270 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2271 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2277 operands[2] = force_reg (SImode, operands[2]);
2283 ; ??? Check split length for Thumb-2
2284 (define_insn_and_split "*arm_andsi3_insn"
2285 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2286 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2287 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2292 bic%?\\t%0, %1, #%B2
2296 && CONST_INT_P (operands[2])
2297 && !(const_ok_for_arm (INTVAL (operands[2]))
2298 || const_ok_for_arm (~INTVAL (operands[2])))"
2299 [(clobber (const_int 0))]
2301 arm_split_constant (AND, SImode, curr_insn,
2302 INTVAL (operands[2]), operands[0], operands[1], 0);
2305 [(set_attr "length" "4,4,4,4,16")
2306 (set_attr "predicable" "yes")
2307 (set_attr "predicable_short_it" "no,yes,no,no,no")
2308 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2311 (define_insn "*thumb1_andsi3_insn"
2312 [(set (match_operand:SI 0 "register_operand" "=l")
2313 (and:SI (match_operand:SI 1 "register_operand" "%0")
2314 (match_operand:SI 2 "register_operand" "l")))]
2317 [(set_attr "length" "2")
2318 (set_attr "type" "logic_imm")
2319 (set_attr "conds" "set")])
2321 (define_insn "*andsi3_compare0"
2322 [(set (reg:CC_NOOV CC_REGNUM)
2324 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2325 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2327 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2328 (and:SI (match_dup 1) (match_dup 2)))]
2332 bic%.\\t%0, %1, #%B2
2334 [(set_attr "conds" "set")
2335 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2338 (define_insn "*andsi3_compare0_scratch"
2339 [(set (reg:CC_NOOV CC_REGNUM)
2341 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2342 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2344 (clobber (match_scratch:SI 2 "=X,r,X"))]
2348 bic%.\\t%2, %0, #%B1
2350 [(set_attr "conds" "set")
2351 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2354 (define_insn "*zeroextractsi_compare0_scratch"
2355 [(set (reg:CC_NOOV CC_REGNUM)
2356 (compare:CC_NOOV (zero_extract:SI
2357 (match_operand:SI 0 "s_register_operand" "r")
2358 (match_operand 1 "const_int_operand" "n")
2359 (match_operand 2 "const_int_operand" "n"))
2362 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2363 && INTVAL (operands[1]) > 0
2364 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2365 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2367 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2368 << INTVAL (operands[2]));
2369 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2372 [(set_attr "conds" "set")
2373 (set_attr "predicable" "yes")
2374 (set_attr "predicable_short_it" "no")
2375 (set_attr "type" "logics_imm")]
2378 (define_insn_and_split "*ne_zeroextractsi"
2379 [(set (match_operand:SI 0 "s_register_operand" "=r")
2380 (ne:SI (zero_extract:SI
2381 (match_operand:SI 1 "s_register_operand" "r")
2382 (match_operand:SI 2 "const_int_operand" "n")
2383 (match_operand:SI 3 "const_int_operand" "n"))
2385 (clobber (reg:CC CC_REGNUM))]
2387 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2388 && INTVAL (operands[2]) > 0
2389 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2390 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2393 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2394 && INTVAL (operands[2]) > 0
2395 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2396 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2397 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2398 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2400 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2402 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2403 (match_dup 0) (const_int 1)))]
2405 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2406 << INTVAL (operands[3]));
2408 [(set_attr "conds" "clob")
2409 (set (attr "length")
2410 (if_then_else (eq_attr "is_thumb" "yes")
2413 (set_attr "type" "multiple")]
2416 (define_insn_and_split "*ne_zeroextractsi_shifted"
2417 [(set (match_operand:SI 0 "s_register_operand" "=r")
2418 (ne:SI (zero_extract:SI
2419 (match_operand:SI 1 "s_register_operand" "r")
2420 (match_operand:SI 2 "const_int_operand" "n")
2423 (clobber (reg:CC CC_REGNUM))]
2427 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2428 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2430 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2432 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2433 (match_dup 0) (const_int 1)))]
2435 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2437 [(set_attr "conds" "clob")
2438 (set_attr "length" "8")
2439 (set_attr "type" "multiple")]
2442 (define_insn_and_split "*ite_ne_zeroextractsi"
2443 [(set (match_operand:SI 0 "s_register_operand" "=r")
2444 (if_then_else:SI (ne (zero_extract:SI
2445 (match_operand:SI 1 "s_register_operand" "r")
2446 (match_operand:SI 2 "const_int_operand" "n")
2447 (match_operand:SI 3 "const_int_operand" "n"))
2449 (match_operand:SI 4 "arm_not_operand" "rIK")
2451 (clobber (reg:CC CC_REGNUM))]
2453 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2454 && INTVAL (operands[2]) > 0
2455 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2456 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2457 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2460 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2461 && INTVAL (operands[2]) > 0
2462 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2463 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2464 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2465 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2466 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2468 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2470 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2471 (match_dup 0) (match_dup 4)))]
2473 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2474 << INTVAL (operands[3]));
2476 [(set_attr "conds" "clob")
2477 (set_attr "length" "8")
2478 (set_attr "type" "multiple")]
2481 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2482 [(set (match_operand:SI 0 "s_register_operand" "=r")
2483 (if_then_else:SI (ne (zero_extract:SI
2484 (match_operand:SI 1 "s_register_operand" "r")
2485 (match_operand:SI 2 "const_int_operand" "n")
2488 (match_operand:SI 3 "arm_not_operand" "rIK")
2490 (clobber (reg:CC CC_REGNUM))]
2491 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2493 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2494 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2495 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2497 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2499 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2500 (match_dup 0) (match_dup 3)))]
2502 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2504 [(set_attr "conds" "clob")
2505 (set_attr "length" "8")
2506 (set_attr "type" "multiple")]
2510 [(set (match_operand:SI 0 "s_register_operand" "")
2511 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
2512 (match_operand:SI 2 "const_int_operand" "")
2513 (match_operand:SI 3 "const_int_operand" "")))
2514 (clobber (match_operand:SI 4 "s_register_operand" ""))]
2516 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
2517 (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
2519 HOST_WIDE_INT temp = INTVAL (operands[2]);
2521 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2522 operands[3] = GEN_INT (32 - temp);
2526 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2528 [(set (match_operand:SI 0 "s_register_operand" "")
2529 (match_operator:SI 1 "shiftable_operator"
2530 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2531 (match_operand:SI 3 "const_int_operand" "")
2532 (match_operand:SI 4 "const_int_operand" ""))
2533 (match_operand:SI 5 "s_register_operand" "")]))
2534 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2536 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2539 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2542 HOST_WIDE_INT temp = INTVAL (operands[3]);
2544 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2545 operands[4] = GEN_INT (32 - temp);
2550 [(set (match_operand:SI 0 "s_register_operand" "")
2551 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
2552 (match_operand:SI 2 "const_int_operand" "")
2553 (match_operand:SI 3 "const_int_operand" "")))]
2555 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2556 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
2558 HOST_WIDE_INT temp = INTVAL (operands[2]);
2560 operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
2561 operands[3] = GEN_INT (32 - temp);
2566 [(set (match_operand:SI 0 "s_register_operand" "")
2567 (match_operator:SI 1 "shiftable_operator"
2568 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2569 (match_operand:SI 3 "const_int_operand" "")
2570 (match_operand:SI 4 "const_int_operand" ""))
2571 (match_operand:SI 5 "s_register_operand" "")]))
2572 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2574 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2577 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2580 HOST_WIDE_INT temp = INTVAL (operands[3]);
2582 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2583 operands[4] = GEN_INT (32 - temp);
2587 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2588 ;;; represented by the bitfield, then this will produce incorrect results.
2589 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2590 ;;; which have a real bit-field insert instruction, the truncation happens
2591 ;;; in the bit-field insert instruction itself. Since arm does not have a
2592 ;;; bit-field insert instruction, we would have to emit code here to truncate
2593 ;;; the value before we insert. This loses some of the advantage of having
2594 ;;; this insv pattern, so this pattern needs to be reevalutated.
2596 (define_expand "insv"
2597 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2598 (match_operand 1 "general_operand" "")
2599 (match_operand 2 "general_operand" ""))
2600 (match_operand 3 "reg_or_int_operand" ""))]
2601 "TARGET_ARM || arm_arch_thumb2"
2604 int start_bit = INTVAL (operands[2]);
2605 int width = INTVAL (operands[1]);
2606 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1;
2607 rtx target, subtarget;
2609 if (arm_arch_thumb2)
2611 if (unaligned_access && MEM_P (operands[0])
2612 && s_register_operand (operands[3], GET_MODE (operands[3]))
2613 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2617 if (BYTES_BIG_ENDIAN)
2618 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2623 base_addr = adjust_address (operands[0], SImode,
2624 start_bit / BITS_PER_UNIT);
2625 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2629 rtx tmp = gen_reg_rtx (HImode);
2631 base_addr = adjust_address (operands[0], HImode,
2632 start_bit / BITS_PER_UNIT);
2633 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2634 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2638 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2640 bool use_bfi = TRUE;
2642 if (CONST_INT_P (operands[3]))
2644 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2648 emit_insn (gen_insv_zero (operands[0], operands[1],
2653 /* See if the set can be done with a single orr instruction. */
2654 if (val == mask && const_ok_for_arm (val << start_bit))
2660 if (!REG_P (operands[3]))
2661 operands[3] = force_reg (SImode, operands[3]);
2663 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2672 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2675 target = copy_rtx (operands[0]);
2676 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2677 subreg as the final target. */
2678 if (GET_CODE (target) == SUBREG)
2680 subtarget = gen_reg_rtx (SImode);
2681 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2682 < GET_MODE_SIZE (SImode))
2683 target = SUBREG_REG (target);
2688 if (CONST_INT_P (operands[3]))
2690 /* Since we are inserting a known constant, we may be able to
2691 reduce the number of bits that we have to clear so that
2692 the mask becomes simple. */
2693 /* ??? This code does not check to see if the new mask is actually
2694 simpler. It may not be. */
2695 rtx op1 = gen_reg_rtx (SImode);
2696 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2697 start of this pattern. */
2698 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2699 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2701 emit_insn (gen_andsi3 (op1, operands[0],
2702 gen_int_mode (~mask2, SImode)));
2703 emit_insn (gen_iorsi3 (subtarget, op1,
2704 gen_int_mode (op3_value << start_bit, SImode)));
2706 else if (start_bit == 0
2707 && !(const_ok_for_arm (mask)
2708 || const_ok_for_arm (~mask)))
2710 /* A Trick, since we are setting the bottom bits in the word,
2711 we can shift operand[3] up, operand[0] down, OR them together
2712 and rotate the result back again. This takes 3 insns, and
2713 the third might be mergeable into another op. */
2714 /* The shift up copes with the possibility that operand[3] is
2715 wider than the bitfield. */
2716 rtx op0 = gen_reg_rtx (SImode);
2717 rtx op1 = gen_reg_rtx (SImode);
2719 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2720 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2721 emit_insn (gen_iorsi3 (op1, op1, op0));
2722 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2724 else if ((width + start_bit == 32)
2725 && !(const_ok_for_arm (mask)
2726 || const_ok_for_arm (~mask)))
2728 /* Similar trick, but slightly less efficient. */
2730 rtx op0 = gen_reg_rtx (SImode);
2731 rtx op1 = gen_reg_rtx (SImode);
2733 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2734 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2735 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2736 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2740 rtx op0 = gen_int_mode (mask, SImode);
2741 rtx op1 = gen_reg_rtx (SImode);
2742 rtx op2 = gen_reg_rtx (SImode);
2744 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2746 rtx tmp = gen_reg_rtx (SImode);
2748 emit_insn (gen_movsi (tmp, op0));
2752 /* Mask out any bits in operand[3] that are not needed. */
2753 emit_insn (gen_andsi3 (op1, operands[3], op0));
2755 if (CONST_INT_P (op0)
2756 && (const_ok_for_arm (mask << start_bit)
2757 || const_ok_for_arm (~(mask << start_bit))))
2759 op0 = gen_int_mode (~(mask << start_bit), SImode);
2760 emit_insn (gen_andsi3 (op2, operands[0], op0));
2764 if (CONST_INT_P (op0))
2766 rtx tmp = gen_reg_rtx (SImode);
2768 emit_insn (gen_movsi (tmp, op0));
2773 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2775 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2779 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2781 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2784 if (subtarget != target)
2786 /* If TARGET is still a SUBREG, then it must be wider than a word,
2787 so we must be careful only to set the subword we were asked to. */
2788 if (GET_CODE (target) == SUBREG)
2789 emit_move_insn (target, subtarget);
2791 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2798 (define_insn "insv_zero"
2799 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2800 (match_operand:SI 1 "const_int_M_operand" "M")
2801 (match_operand:SI 2 "const_int_M_operand" "M"))
2805 [(set_attr "length" "4")
2806 (set_attr "predicable" "yes")
2807 (set_attr "predicable_short_it" "no")
2808 (set_attr "type" "bfm")]
2811 (define_insn "insv_t2"
2812 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2813 (match_operand:SI 1 "const_int_M_operand" "M")
2814 (match_operand:SI 2 "const_int_M_operand" "M"))
2815 (match_operand:SI 3 "s_register_operand" "r"))]
2817 "bfi%?\t%0, %3, %2, %1"
2818 [(set_attr "length" "4")
2819 (set_attr "predicable" "yes")
2820 (set_attr "predicable_short_it" "no")
2821 (set_attr "type" "bfm")]
2824 ; constants for op 2 will never be given to these patterns.
2825 (define_insn_and_split "*anddi_notdi_di"
2826 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2827 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2828 (match_operand:DI 2 "s_register_operand" "r,0")))]
2831 "TARGET_32BIT && reload_completed
2832 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2833 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2834 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2835 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2838 operands[3] = gen_highpart (SImode, operands[0]);
2839 operands[0] = gen_lowpart (SImode, operands[0]);
2840 operands[4] = gen_highpart (SImode, operands[1]);
2841 operands[1] = gen_lowpart (SImode, operands[1]);
2842 operands[5] = gen_highpart (SImode, operands[2]);
2843 operands[2] = gen_lowpart (SImode, operands[2]);
2845 [(set_attr "length" "8")
2846 (set_attr "predicable" "yes")
2847 (set_attr "type" "multiple")]
2850 (define_insn_and_split "*anddi_notzesidi_di"
2851 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2852 (and:DI (not: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 bic%?\\t%Q0, %Q1, %2
2859 ; (not (zero_extend ...)) allows us to just copy the high word from
2860 ; operand1 to operand0.
2863 && operands[0] != operands[1]"
2864 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2865 (set (match_dup 3) (match_dup 4))]
2868 operands[3] = gen_highpart (SImode, operands[0]);
2869 operands[0] = gen_lowpart (SImode, operands[0]);
2870 operands[4] = gen_highpart (SImode, operands[1]);
2871 operands[1] = gen_lowpart (SImode, operands[1]);
2873 [(set_attr "length" "4,8")
2874 (set_attr "predicable" "yes")
2875 (set_attr "predicable_short_it" "no")
2876 (set_attr "type" "multiple")]
2879 (define_insn_and_split "*anddi_notdi_zesidi"
2880 [(set (match_operand:DI 0 "s_register_operand" "=r")
2881 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2883 (match_operand:SI 1 "s_register_operand" "r"))))]
2886 "TARGET_32BIT && reload_completed"
2887 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2888 (set (match_dup 3) (const_int 0))]
2891 operands[3] = gen_highpart (SImode, operands[0]);
2892 operands[0] = gen_lowpart (SImode, operands[0]);
2893 operands[2] = gen_lowpart (SImode, operands[2]);
2895 [(set_attr "length" "8")
2896 (set_attr "predicable" "yes")
2897 (set_attr "predicable_short_it" "no")
2898 (set_attr "type" "multiple")]
2901 (define_insn_and_split "*anddi_notsesidi_di"
2902 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2903 (and:DI (not:DI (sign_extend:DI
2904 (match_operand:SI 2 "s_register_operand" "r,r")))
2905 (match_operand:DI 1 "s_register_operand" "0,r")))]
2908 "TARGET_32BIT && reload_completed"
2909 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2910 (set (match_dup 3) (and:SI (not:SI
2911 (ashiftrt:SI (match_dup 2) (const_int 31)))
2915 operands[3] = gen_highpart (SImode, operands[0]);
2916 operands[0] = gen_lowpart (SImode, operands[0]);
2917 operands[4] = gen_highpart (SImode, operands[1]);
2918 operands[1] = gen_lowpart (SImode, operands[1]);
2920 [(set_attr "length" "8")
2921 (set_attr "predicable" "yes")
2922 (set_attr "predicable_short_it" "no")
2923 (set_attr "type" "multiple")]
2926 (define_insn "andsi_notsi_si"
2927 [(set (match_operand:SI 0 "s_register_operand" "=r")
2928 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2929 (match_operand:SI 1 "s_register_operand" "r")))]
2931 "bic%?\\t%0, %1, %2"
2932 [(set_attr "predicable" "yes")
2933 (set_attr "predicable_short_it" "no")
2934 (set_attr "type" "logic_reg")]
2937 (define_insn "thumb1_bicsi3"
2938 [(set (match_operand:SI 0 "register_operand" "=l")
2939 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
2940 (match_operand:SI 2 "register_operand" "0")))]
2943 [(set_attr "length" "2")
2944 (set_attr "conds" "set")
2945 (set_attr "type" "logics_reg")]
2948 (define_insn "andsi_not_shiftsi_si"
2949 [(set (match_operand:SI 0 "s_register_operand" "=r")
2950 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2951 [(match_operand:SI 2 "s_register_operand" "r")
2952 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2953 (match_operand:SI 1 "s_register_operand" "r")))]
2955 "bic%?\\t%0, %1, %2%S4"
2956 [(set_attr "predicable" "yes")
2957 (set_attr "shift" "2")
2958 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2959 (const_string "logic_shift_imm")
2960 (const_string "logic_shift_reg")))]
2963 (define_insn "*andsi_notsi_si_compare0"
2964 [(set (reg:CC_NOOV CC_REGNUM)
2966 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2967 (match_operand:SI 1 "s_register_operand" "r"))
2969 (set (match_operand:SI 0 "s_register_operand" "=r")
2970 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2972 "bic%.\\t%0, %1, %2"
2973 [(set_attr "conds" "set")
2974 (set_attr "type" "logics_shift_reg")]
2977 (define_insn "*andsi_notsi_si_compare0_scratch"
2978 [(set (reg:CC_NOOV CC_REGNUM)
2980 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2981 (match_operand:SI 1 "s_register_operand" "r"))
2983 (clobber (match_scratch:SI 0 "=r"))]
2985 "bic%.\\t%0, %1, %2"
2986 [(set_attr "conds" "set")
2987 (set_attr "type" "logics_shift_reg")]
2990 (define_expand "iordi3"
2991 [(set (match_operand:DI 0 "s_register_operand" "")
2992 (ior:DI (match_operand:DI 1 "s_register_operand" "")
2993 (match_operand:DI 2 "neon_logic_op2" "")))]
2998 (define_insn_and_split "*iordi3_insn"
2999 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3000 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3001 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3002 "TARGET_32BIT && !TARGET_IWMMXT"
3004 switch (which_alternative)
3006 case 0: /* fall through */
3007 case 6: return "vorr\t%P0, %P1, %P2";
3008 case 1: /* fall through */
3009 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3010 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3016 default: gcc_unreachable ();
3019 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3020 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3021 [(set (match_dup 3) (match_dup 4))
3022 (set (match_dup 5) (match_dup 6))]
3025 operands[3] = gen_lowpart (SImode, operands[0]);
3026 operands[5] = gen_highpart (SImode, operands[0]);
3028 operands[4] = simplify_gen_binary (IOR, SImode,
3029 gen_lowpart (SImode, operands[1]),
3030 gen_lowpart (SImode, operands[2]));
3031 operands[6] = simplify_gen_binary (IOR, SImode,
3032 gen_highpart (SImode, operands[1]),
3033 gen_highpart_mode (SImode, DImode, operands[2]));
3036 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3037 multiple,neon_logic,neon_logic")
3038 (set_attr "length" "*,*,8,8,8,8,*,*")
3039 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3042 (define_insn "*iordi_zesidi_di"
3043 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3044 (ior:DI (zero_extend:DI
3045 (match_operand:SI 2 "s_register_operand" "r,r"))
3046 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3049 orr%?\\t%Q0, %Q1, %2
3051 [(set_attr "length" "4,8")
3052 (set_attr "predicable" "yes")
3053 (set_attr "predicable_short_it" "no")
3054 (set_attr "type" "logic_reg,multiple")]
3057 (define_insn "*iordi_sesidi_di"
3058 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3059 (ior:DI (sign_extend:DI
3060 (match_operand:SI 2 "s_register_operand" "r,r"))
3061 (match_operand:DI 1 "s_register_operand" "0,r")))]
3064 [(set_attr "length" "8")
3065 (set_attr "predicable" "yes")
3066 (set_attr "type" "multiple")]
3069 (define_expand "iorsi3"
3070 [(set (match_operand:SI 0 "s_register_operand" "")
3071 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3072 (match_operand:SI 2 "reg_or_int_operand" "")))]
3075 if (CONST_INT_P (operands[2]))
3079 arm_split_constant (IOR, SImode, NULL_RTX,
3080 INTVAL (operands[2]), operands[0], operands[1],
3081 optimize && can_create_pseudo_p ());
3084 else /* TARGET_THUMB1 */
3086 rtx tmp = force_reg (SImode, operands[2]);
3087 if (rtx_equal_p (operands[0], operands[1]))
3091 operands[2] = operands[1];
3099 (define_insn_and_split "*iorsi3_insn"
3100 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3101 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3102 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3107 orn%?\\t%0, %1, #%B2
3111 && CONST_INT_P (operands[2])
3112 && !(const_ok_for_arm (INTVAL (operands[2]))
3113 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3114 [(clobber (const_int 0))]
3116 arm_split_constant (IOR, SImode, curr_insn,
3117 INTVAL (operands[2]), operands[0], operands[1], 0);
3120 [(set_attr "length" "4,4,4,4,16")
3121 (set_attr "arch" "32,t2,t2,32,32")
3122 (set_attr "predicable" "yes")
3123 (set_attr "predicable_short_it" "no,yes,no,no,no")
3124 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3127 (define_insn "*thumb1_iorsi3_insn"
3128 [(set (match_operand:SI 0 "register_operand" "=l")
3129 (ior:SI (match_operand:SI 1 "register_operand" "%0")
3130 (match_operand:SI 2 "register_operand" "l")))]
3133 [(set_attr "length" "2")
3134 (set_attr "conds" "set")
3135 (set_attr "type" "logics_reg")])
3138 [(match_scratch:SI 3 "r")
3139 (set (match_operand:SI 0 "arm_general_register_operand" "")
3140 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3141 (match_operand:SI 2 "const_int_operand" "")))]
3143 && !const_ok_for_arm (INTVAL (operands[2]))
3144 && const_ok_for_arm (~INTVAL (operands[2]))"
3145 [(set (match_dup 3) (match_dup 2))
3146 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3150 (define_insn "*iorsi3_compare0"
3151 [(set (reg:CC_NOOV CC_REGNUM)
3152 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3153 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3155 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3156 (ior:SI (match_dup 1) (match_dup 2)))]
3158 "orr%.\\t%0, %1, %2"
3159 [(set_attr "conds" "set")
3160 (set_attr "type" "logics_imm,logics_reg")]
3163 (define_insn "*iorsi3_compare0_scratch"
3164 [(set (reg:CC_NOOV CC_REGNUM)
3165 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3166 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3168 (clobber (match_scratch:SI 0 "=r,r"))]
3170 "orr%.\\t%0, %1, %2"
3171 [(set_attr "conds" "set")
3172 (set_attr "type" "logics_imm,logics_reg")]
3175 (define_expand "xordi3"
3176 [(set (match_operand:DI 0 "s_register_operand" "")
3177 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3178 (match_operand:DI 2 "arm_xordi_operand" "")))]
3183 (define_insn_and_split "*xordi3_insn"
3184 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3185 (xor:DI (match_operand:DI 1 "s_register_operand" "w ,%0,r ,0 ,r ,w")
3186 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3187 "TARGET_32BIT && !TARGET_IWMMXT"
3189 switch (which_alternative)
3194 case 4: /* fall through */
3196 case 0: /* fall through */
3197 case 5: return "veor\t%P0, %P1, %P2";
3198 default: gcc_unreachable ();
3201 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3202 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3203 [(set (match_dup 3) (match_dup 4))
3204 (set (match_dup 5) (match_dup 6))]
3207 operands[3] = gen_lowpart (SImode, operands[0]);
3208 operands[5] = gen_highpart (SImode, operands[0]);
3210 operands[4] = simplify_gen_binary (XOR, SImode,
3211 gen_lowpart (SImode, operands[1]),
3212 gen_lowpart (SImode, operands[2]));
3213 operands[6] = simplify_gen_binary (XOR, SImode,
3214 gen_highpart (SImode, operands[1]),
3215 gen_highpart_mode (SImode, DImode, operands[2]));
3218 [(set_attr "length" "*,8,8,8,8,*")
3219 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3220 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3223 (define_insn "*xordi_zesidi_di"
3224 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3225 (xor:DI (zero_extend:DI
3226 (match_operand:SI 2 "s_register_operand" "r,r"))
3227 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3230 eor%?\\t%Q0, %Q1, %2
3232 [(set_attr "length" "4,8")
3233 (set_attr "predicable" "yes")
3234 (set_attr "predicable_short_it" "no")
3235 (set_attr "type" "logic_reg")]
3238 (define_insn "*xordi_sesidi_di"
3239 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3240 (xor:DI (sign_extend:DI
3241 (match_operand:SI 2 "s_register_operand" "r,r"))
3242 (match_operand:DI 1 "s_register_operand" "0,r")))]
3245 [(set_attr "length" "8")
3246 (set_attr "predicable" "yes")
3247 (set_attr "type" "multiple")]
3250 (define_expand "xorsi3"
3251 [(set (match_operand:SI 0 "s_register_operand" "")
3252 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3253 (match_operand:SI 2 "reg_or_int_operand" "")))]
3255 "if (CONST_INT_P (operands[2]))
3259 arm_split_constant (XOR, SImode, NULL_RTX,
3260 INTVAL (operands[2]), operands[0], operands[1],
3261 optimize && can_create_pseudo_p ());
3264 else /* TARGET_THUMB1 */
3266 rtx tmp = force_reg (SImode, operands[2]);
3267 if (rtx_equal_p (operands[0], operands[1]))
3271 operands[2] = operands[1];
3278 (define_insn_and_split "*arm_xorsi3"
3279 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3280 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3281 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3289 && CONST_INT_P (operands[2])
3290 && !const_ok_for_arm (INTVAL (operands[2]))"
3291 [(clobber (const_int 0))]
3293 arm_split_constant (XOR, SImode, curr_insn,
3294 INTVAL (operands[2]), operands[0], operands[1], 0);
3297 [(set_attr "length" "4,4,4,16")
3298 (set_attr "predicable" "yes")
3299 (set_attr "predicable_short_it" "no,yes,no,no")
3300 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3303 (define_insn "*thumb1_xorsi3_insn"
3304 [(set (match_operand:SI 0 "register_operand" "=l")
3305 (xor:SI (match_operand:SI 1 "register_operand" "%0")
3306 (match_operand:SI 2 "register_operand" "l")))]
3309 [(set_attr "length" "2")
3310 (set_attr "conds" "set")
3311 (set_attr "type" "logics_reg")]
3314 (define_insn "*xorsi3_compare0"
3315 [(set (reg:CC_NOOV CC_REGNUM)
3316 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3317 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3319 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3320 (xor:SI (match_dup 1) (match_dup 2)))]
3322 "eor%.\\t%0, %1, %2"
3323 [(set_attr "conds" "set")
3324 (set_attr "type" "logics_imm,logics_reg")]
3327 (define_insn "*xorsi3_compare0_scratch"
3328 [(set (reg:CC_NOOV CC_REGNUM)
3329 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3330 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3334 [(set_attr "conds" "set")
3335 (set_attr "type" "logics_imm,logics_reg")]
3338 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3339 ; (NOT D) we can sometimes merge the final NOT into one of the following
3343 [(set (match_operand:SI 0 "s_register_operand" "")
3344 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3345 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3346 (match_operand:SI 3 "arm_rhs_operand" "")))
3347 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3349 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3350 (not:SI (match_dup 3))))
3351 (set (match_dup 0) (not:SI (match_dup 4)))]
3355 (define_insn_and_split "*andsi_iorsi3_notsi"
3356 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3357 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3358 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3359 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3361 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3362 "&& reload_completed"
3363 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3364 (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 0)))]
3366 [(set_attr "length" "8")
3367 (set_attr "ce_count" "2")
3368 (set_attr "predicable" "yes")
3369 (set_attr "predicable_short_it" "no")
3370 (set_attr "type" "multiple")]
3373 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3374 ; insns are available?
3376 [(set (match_operand:SI 0 "s_register_operand" "")
3377 (match_operator:SI 1 "logical_binary_operator"
3378 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3379 (match_operand:SI 3 "const_int_operand" "")
3380 (match_operand:SI 4 "const_int_operand" ""))
3381 (match_operator:SI 9 "logical_binary_operator"
3382 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3383 (match_operand:SI 6 "const_int_operand" ""))
3384 (match_operand:SI 7 "s_register_operand" "")])]))
3385 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3387 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3388 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3391 [(ashift:SI (match_dup 2) (match_dup 4))
3395 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3398 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3402 [(set (match_operand:SI 0 "s_register_operand" "")
3403 (match_operator:SI 1 "logical_binary_operator"
3404 [(match_operator:SI 9 "logical_binary_operator"
3405 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3406 (match_operand:SI 6 "const_int_operand" ""))
3407 (match_operand:SI 7 "s_register_operand" "")])
3408 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3409 (match_operand:SI 3 "const_int_operand" "")
3410 (match_operand:SI 4 "const_int_operand" ""))]))
3411 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3413 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3414 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3417 [(ashift:SI (match_dup 2) (match_dup 4))
3421 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3424 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3428 [(set (match_operand:SI 0 "s_register_operand" "")
3429 (match_operator:SI 1 "logical_binary_operator"
3430 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3431 (match_operand:SI 3 "const_int_operand" "")
3432 (match_operand:SI 4 "const_int_operand" ""))
3433 (match_operator:SI 9 "logical_binary_operator"
3434 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3435 (match_operand:SI 6 "const_int_operand" ""))
3436 (match_operand:SI 7 "s_register_operand" "")])]))
3437 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3439 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3440 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3443 [(ashift:SI (match_dup 2) (match_dup 4))
3447 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3450 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3454 [(set (match_operand:SI 0 "s_register_operand" "")
3455 (match_operator:SI 1 "logical_binary_operator"
3456 [(match_operator:SI 9 "logical_binary_operator"
3457 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3458 (match_operand:SI 6 "const_int_operand" ""))
3459 (match_operand:SI 7 "s_register_operand" "")])
3460 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3461 (match_operand:SI 3 "const_int_operand" "")
3462 (match_operand:SI 4 "const_int_operand" ""))]))
3463 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3465 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3466 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3469 [(ashift:SI (match_dup 2) (match_dup 4))
3473 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3476 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3480 ;; Minimum and maximum insns
3482 (define_expand "smaxsi3"
3484 (set (match_operand:SI 0 "s_register_operand" "")
3485 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3486 (match_operand:SI 2 "arm_rhs_operand" "")))
3487 (clobber (reg:CC CC_REGNUM))])]
3490 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3492 /* No need for a clobber of the condition code register here. */
3493 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3494 gen_rtx_SMAX (SImode, operands[1],
3500 (define_insn "*smax_0"
3501 [(set (match_operand:SI 0 "s_register_operand" "=r")
3502 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3505 "bic%?\\t%0, %1, %1, asr #31"
3506 [(set_attr "predicable" "yes")
3507 (set_attr "predicable_short_it" "no")
3508 (set_attr "type" "logic_shift_reg")]
3511 (define_insn "*smax_m1"
3512 [(set (match_operand:SI 0 "s_register_operand" "=r")
3513 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3516 "orr%?\\t%0, %1, %1, asr #31"
3517 [(set_attr "predicable" "yes")
3518 (set_attr "predicable_short_it" "no")
3519 (set_attr "type" "logic_shift_reg")]
3522 (define_insn_and_split "*arm_smax_insn"
3523 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3524 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3525 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3526 (clobber (reg:CC CC_REGNUM))]
3529 ; cmp\\t%1, %2\;movlt\\t%0, %2
3530 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3532 [(set (reg:CC CC_REGNUM)
3533 (compare:CC (match_dup 1) (match_dup 2)))
3535 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3539 [(set_attr "conds" "clob")
3540 (set_attr "length" "8,12")
3541 (set_attr "type" "multiple")]
3544 (define_expand "sminsi3"
3546 (set (match_operand:SI 0 "s_register_operand" "")
3547 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3548 (match_operand:SI 2 "arm_rhs_operand" "")))
3549 (clobber (reg:CC CC_REGNUM))])]
3552 if (operands[2] == const0_rtx)
3554 /* No need for a clobber of the condition code register here. */
3555 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3556 gen_rtx_SMIN (SImode, operands[1],
3562 (define_insn "*smin_0"
3563 [(set (match_operand:SI 0 "s_register_operand" "=r")
3564 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3567 "and%?\\t%0, %1, %1, asr #31"
3568 [(set_attr "predicable" "yes")
3569 (set_attr "predicable_short_it" "no")
3570 (set_attr "type" "logic_shift_reg")]
3573 (define_insn_and_split "*arm_smin_insn"
3574 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3575 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3576 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3577 (clobber (reg:CC CC_REGNUM))]
3580 ; cmp\\t%1, %2\;movge\\t%0, %2
3581 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3583 [(set (reg:CC CC_REGNUM)
3584 (compare:CC (match_dup 1) (match_dup 2)))
3586 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3590 [(set_attr "conds" "clob")
3591 (set_attr "length" "8,12")
3592 (set_attr "type" "multiple,multiple")]
3595 (define_expand "umaxsi3"
3597 (set (match_operand:SI 0 "s_register_operand" "")
3598 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3599 (match_operand:SI 2 "arm_rhs_operand" "")))
3600 (clobber (reg:CC CC_REGNUM))])]
3605 (define_insn_and_split "*arm_umaxsi3"
3606 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3607 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3608 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3609 (clobber (reg:CC CC_REGNUM))]
3612 ; cmp\\t%1, %2\;movcc\\t%0, %2
3613 ; cmp\\t%1, %2\;movcs\\t%0, %1
3614 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3616 [(set (reg:CC CC_REGNUM)
3617 (compare:CC (match_dup 1) (match_dup 2)))
3619 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3623 [(set_attr "conds" "clob")
3624 (set_attr "length" "8,8,12")
3625 (set_attr "type" "store1")]
3628 (define_expand "uminsi3"
3630 (set (match_operand:SI 0 "s_register_operand" "")
3631 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3632 (match_operand:SI 2 "arm_rhs_operand" "")))
3633 (clobber (reg:CC CC_REGNUM))])]
3638 (define_insn_and_split "*arm_uminsi3"
3639 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3640 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3641 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3642 (clobber (reg:CC CC_REGNUM))]
3645 ; cmp\\t%1, %2\;movcs\\t%0, %2
3646 ; cmp\\t%1, %2\;movcc\\t%0, %1
3647 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3649 [(set (reg:CC CC_REGNUM)
3650 (compare:CC (match_dup 1) (match_dup 2)))
3652 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3656 [(set_attr "conds" "clob")
3657 (set_attr "length" "8,8,12")
3658 (set_attr "type" "store1")]
3661 (define_insn "*store_minmaxsi"
3662 [(set (match_operand:SI 0 "memory_operand" "=m")
3663 (match_operator:SI 3 "minmax_operator"
3664 [(match_operand:SI 1 "s_register_operand" "r")
3665 (match_operand:SI 2 "s_register_operand" "r")]))
3666 (clobber (reg:CC CC_REGNUM))]
3667 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3669 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3670 operands[1], operands[2]);
3671 output_asm_insn (\"cmp\\t%1, %2\", operands);
3673 output_asm_insn (\"ite\t%d3\", operands);
3674 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3675 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3678 [(set_attr "conds" "clob")
3679 (set (attr "length")
3680 (if_then_else (eq_attr "is_thumb" "yes")
3683 (set_attr "type" "store1")]
3686 ; Reject the frame pointer in operand[1], since reloading this after
3687 ; it has been eliminated can cause carnage.
3688 (define_insn "*minmax_arithsi"
3689 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3690 (match_operator:SI 4 "shiftable_operator"
3691 [(match_operator:SI 5 "minmax_operator"
3692 [(match_operand:SI 2 "s_register_operand" "r,r")
3693 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3694 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3695 (clobber (reg:CC CC_REGNUM))]
3696 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3699 enum rtx_code code = GET_CODE (operands[4]);
3702 if (which_alternative != 0 || operands[3] != const0_rtx
3703 || (code != PLUS && code != IOR && code != XOR))
3708 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3709 operands[2], operands[3]);
3710 output_asm_insn (\"cmp\\t%2, %3\", operands);
3714 output_asm_insn (\"ite\\t%d5\", operands);
3716 output_asm_insn (\"it\\t%d5\", operands);
3718 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3720 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3723 [(set_attr "conds" "clob")
3724 (set (attr "length")
3725 (if_then_else (eq_attr "is_thumb" "yes")
3728 (set_attr "type" "multiple")]
3731 ; Reject the frame pointer in operand[1], since reloading this after
3732 ; it has been eliminated can cause carnage.
3733 (define_insn_and_split "*minmax_arithsi_non_canon"
3734 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3736 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3737 (match_operator:SI 4 "minmax_operator"
3738 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3739 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3740 (clobber (reg:CC CC_REGNUM))]
3741 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3742 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3744 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3745 [(set (reg:CC CC_REGNUM)
3746 (compare:CC (match_dup 2) (match_dup 3)))
3748 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3750 (minus:SI (match_dup 1)
3752 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3756 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3757 operands[2], operands[3]);
3758 enum rtx_code rc = minmax_code (operands[4]);
3759 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3760 operands[2], operands[3]);
3762 if (mode == CCFPmode || mode == CCFPEmode)
3763 rc = reverse_condition_maybe_unordered (rc);
3765 rc = reverse_condition (rc);
3766 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3767 if (CONST_INT_P (operands[3]))
3768 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3770 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3772 [(set_attr "conds" "clob")
3773 (set (attr "length")
3774 (if_then_else (eq_attr "is_thumb" "yes")
3777 (set_attr "type" "multiple")]
3780 (define_code_iterator SAT [smin smax])
3781 (define_code_iterator SATrev [smin smax])
3782 (define_code_attr SATlo [(smin "1") (smax "2")])
3783 (define_code_attr SAThi [(smin "2") (smax "1")])
3785 (define_insn "*satsi_<SAT:code>"
3786 [(set (match_operand:SI 0 "s_register_operand" "=r")
3787 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3788 (match_operand:SI 1 "const_int_operand" "i"))
3789 (match_operand:SI 2 "const_int_operand" "i")))]
3790 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3791 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3795 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3796 &mask, &signed_sat))
3799 operands[1] = GEN_INT (mask);
3801 return "ssat%?\t%0, %1, %3";
3803 return "usat%?\t%0, %1, %3";
3805 [(set_attr "predicable" "yes")
3806 (set_attr "predicable_short_it" "no")
3807 (set_attr "type" "alus_imm")]
3810 (define_insn "*satsi_<SAT:code>_shift"
3811 [(set (match_operand:SI 0 "s_register_operand" "=r")
3812 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3813 [(match_operand:SI 4 "s_register_operand" "r")
3814 (match_operand:SI 5 "const_int_operand" "i")])
3815 (match_operand:SI 1 "const_int_operand" "i"))
3816 (match_operand:SI 2 "const_int_operand" "i")))]
3817 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3818 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3822 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3823 &mask, &signed_sat))
3826 operands[1] = GEN_INT (mask);
3828 return "ssat%?\t%0, %1, %4%S3";
3830 return "usat%?\t%0, %1, %4%S3";
3832 [(set_attr "predicable" "yes")
3833 (set_attr "predicable_short_it" "no")
3834 (set_attr "shift" "3")
3835 (set_attr "type" "logic_shift_reg")])
3837 ;; Shift and rotation insns
3839 (define_expand "ashldi3"
3840 [(set (match_operand:DI 0 "s_register_operand" "")
3841 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3842 (match_operand:SI 2 "general_operand" "")))]
3847 /* Delay the decision whether to use NEON or core-regs until
3848 register allocation. */
3849 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3854 /* Only the NEON case can handle in-memory shift counts. */
3855 if (!reg_or_int_operand (operands[2], SImode))
3856 operands[2] = force_reg (SImode, operands[2]);
3859 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3860 ; /* No special preparation statements; expand pattern as above. */
3863 rtx scratch1, scratch2;
3865 if (CONST_INT_P (operands[2])
3866 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3868 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
3872 /* Ideally we should use iwmmxt here if we could know that operands[1]
3873 ends up already living in an iwmmxt register. Otherwise it's
3874 cheaper to have the alternate code being generated than moving
3875 values to iwmmxt regs and back. */
3877 /* If we're optimizing for size, we prefer the libgcc calls. */
3878 if (optimize_function_for_size_p (cfun))
3881 /* Expand operation using core-registers.
3882 'FAIL' would achieve the same thing, but this is a bit smarter. */
3883 scratch1 = gen_reg_rtx (SImode);
3884 scratch2 = gen_reg_rtx (SImode);
3885 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3886 operands[2], scratch1, scratch2);
3892 (define_insn "arm_ashldi3_1bit"
3893 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3894 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
3896 (clobber (reg:CC CC_REGNUM))]
3898 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
3899 [(set_attr "conds" "clob")
3900 (set_attr "length" "8")
3901 (set_attr "type" "multiple")]
3904 (define_expand "ashlsi3"
3905 [(set (match_operand:SI 0 "s_register_operand" "")
3906 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
3907 (match_operand:SI 2 "arm_rhs_operand" "")))]
3910 if (CONST_INT_P (operands[2])
3911 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3913 emit_insn (gen_movsi (operands[0], const0_rtx));
3919 (define_insn "*thumb1_ashlsi3"
3920 [(set (match_operand:SI 0 "register_operand" "=l,l")
3921 (ashift:SI (match_operand:SI 1 "register_operand" "l,0")
3922 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
3925 [(set_attr "length" "2")
3926 (set_attr "type" "shift_imm,shift_reg")
3927 (set_attr "conds" "set")])
3929 (define_expand "ashrdi3"
3930 [(set (match_operand:DI 0 "s_register_operand" "")
3931 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
3932 (match_operand:SI 2 "reg_or_int_operand" "")))]
3937 /* Delay the decision whether to use NEON or core-regs until
3938 register allocation. */
3939 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
3943 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
3944 ; /* No special preparation statements; expand pattern as above. */
3947 rtx scratch1, scratch2;
3949 if (CONST_INT_P (operands[2])
3950 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
3952 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
3956 /* Ideally we should use iwmmxt here if we could know that operands[1]
3957 ends up already living in an iwmmxt register. Otherwise it's
3958 cheaper to have the alternate code being generated than moving
3959 values to iwmmxt regs and back. */
3961 /* If we're optimizing for size, we prefer the libgcc calls. */
3962 if (optimize_function_for_size_p (cfun))
3965 /* Expand operation using core-registers.
3966 'FAIL' would achieve the same thing, but this is a bit smarter. */
3967 scratch1 = gen_reg_rtx (SImode);
3968 scratch2 = gen_reg_rtx (SImode);
3969 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3970 operands[2], scratch1, scratch2);
3976 (define_insn "arm_ashrdi3_1bit"
3977 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
3978 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
3980 (clobber (reg:CC CC_REGNUM))]
3982 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
3983 [(set_attr "conds" "clob")
3984 (set_attr "length" "8")
3985 (set_attr "type" "multiple")]
3988 (define_expand "ashrsi3"
3989 [(set (match_operand:SI 0 "s_register_operand" "")
3990 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
3991 (match_operand:SI 2 "arm_rhs_operand" "")))]
3994 if (CONST_INT_P (operands[2])
3995 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
3996 operands[2] = GEN_INT (31);
4000 (define_insn "*thumb1_ashrsi3"
4001 [(set (match_operand:SI 0 "register_operand" "=l,l")
4002 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
4003 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
4006 [(set_attr "length" "2")
4007 (set_attr "type" "shift_imm,shift_reg")
4008 (set_attr "conds" "set")])
4010 (define_expand "lshrdi3"
4011 [(set (match_operand:DI 0 "s_register_operand" "")
4012 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4013 (match_operand:SI 2 "reg_or_int_operand" "")))]
4018 /* Delay the decision whether to use NEON or core-regs until
4019 register allocation. */
4020 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4024 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4025 ; /* No special preparation statements; expand pattern as above. */
4028 rtx scratch1, scratch2;
4030 if (CONST_INT_P (operands[2])
4031 && (HOST_WIDE_INT) INTVAL (operands[2]) == 1)
4033 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4037 /* Ideally we should use iwmmxt here if we could know that operands[1]
4038 ends up already living in an iwmmxt register. Otherwise it's
4039 cheaper to have the alternate code being generated than moving
4040 values to iwmmxt regs and back. */
4042 /* If we're optimizing for size, we prefer the libgcc calls. */
4043 if (optimize_function_for_size_p (cfun))
4046 /* Expand operation using core-registers.
4047 'FAIL' would achieve the same thing, but this is a bit smarter. */
4048 scratch1 = gen_reg_rtx (SImode);
4049 scratch2 = gen_reg_rtx (SImode);
4050 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4051 operands[2], scratch1, scratch2);
4057 (define_insn "arm_lshrdi3_1bit"
4058 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4059 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4061 (clobber (reg:CC CC_REGNUM))]
4063 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4064 [(set_attr "conds" "clob")
4065 (set_attr "length" "8")
4066 (set_attr "type" "multiple")]
4069 (define_expand "lshrsi3"
4070 [(set (match_operand:SI 0 "s_register_operand" "")
4071 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4072 (match_operand:SI 2 "arm_rhs_operand" "")))]
4075 if (CONST_INT_P (operands[2])
4076 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4078 emit_insn (gen_movsi (operands[0], const0_rtx));
4084 (define_insn "*thumb1_lshrsi3"
4085 [(set (match_operand:SI 0 "register_operand" "=l,l")
4086 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0")
4087 (match_operand:SI 2 "nonmemory_operand" "N,l")))]
4090 [(set_attr "length" "2")
4091 (set_attr "type" "shift_imm,shift_reg")
4092 (set_attr "conds" "set")])
4094 (define_expand "rotlsi3"
4095 [(set (match_operand:SI 0 "s_register_operand" "")
4096 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4097 (match_operand:SI 2 "reg_or_int_operand" "")))]
4100 if (CONST_INT_P (operands[2]))
4101 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4104 rtx reg = gen_reg_rtx (SImode);
4105 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4111 (define_expand "rotrsi3"
4112 [(set (match_operand:SI 0 "s_register_operand" "")
4113 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4114 (match_operand:SI 2 "arm_rhs_operand" "")))]
4119 if (CONST_INT_P (operands[2])
4120 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31)
4121 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4123 else /* TARGET_THUMB1 */
4125 if (CONST_INT_P (operands [2]))
4126 operands [2] = force_reg (SImode, operands[2]);
4131 (define_insn "*thumb1_rotrsi3"
4132 [(set (match_operand:SI 0 "register_operand" "=l")
4133 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
4134 (match_operand:SI 2 "register_operand" "l")))]
4137 [(set_attr "type" "shift_reg")
4138 (set_attr "length" "2")]
4141 (define_insn "*arm_shiftsi3"
4142 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4143 (match_operator:SI 3 "shift_operator"
4144 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4145 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4147 "* return arm_output_shift(operands, 0);"
4148 [(set_attr "predicable" "yes")
4149 (set_attr "arch" "t2,t2,*,*")
4150 (set_attr "predicable_short_it" "yes,yes,no,no")
4151 (set_attr "length" "4")
4152 (set_attr "shift" "1")
4153 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4156 (define_insn "*shiftsi3_compare0"
4157 [(set (reg:CC_NOOV CC_REGNUM)
4158 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4159 [(match_operand:SI 1 "s_register_operand" "r,r")
4160 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4162 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4163 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4165 "* return arm_output_shift(operands, 1);"
4166 [(set_attr "conds" "set")
4167 (set_attr "shift" "1")
4168 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4171 (define_insn "*shiftsi3_compare0_scratch"
4172 [(set (reg:CC_NOOV CC_REGNUM)
4173 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4174 [(match_operand:SI 1 "s_register_operand" "r,r")
4175 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4177 (clobber (match_scratch:SI 0 "=r,r"))]
4179 "* return arm_output_shift(operands, 1);"
4180 [(set_attr "conds" "set")
4181 (set_attr "shift" "1")
4182 (set_attr "type" "shift_imm,shift_reg")]
4185 (define_insn "*not_shiftsi"
4186 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4187 (not:SI (match_operator:SI 3 "shift_operator"
4188 [(match_operand:SI 1 "s_register_operand" "r,r")
4189 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4192 [(set_attr "predicable" "yes")
4193 (set_attr "predicable_short_it" "no")
4194 (set_attr "shift" "1")
4195 (set_attr "arch" "32,a")
4196 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4198 (define_insn "*not_shiftsi_compare0"
4199 [(set (reg:CC_NOOV CC_REGNUM)
4201 (not:SI (match_operator:SI 3 "shift_operator"
4202 [(match_operand:SI 1 "s_register_operand" "r,r")
4203 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4205 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4206 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4209 [(set_attr "conds" "set")
4210 (set_attr "shift" "1")
4211 (set_attr "arch" "32,a")
4212 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4214 (define_insn "*not_shiftsi_compare0_scratch"
4215 [(set (reg:CC_NOOV CC_REGNUM)
4217 (not:SI (match_operator:SI 3 "shift_operator"
4218 [(match_operand:SI 1 "s_register_operand" "r,r")
4219 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4221 (clobber (match_scratch:SI 0 "=r,r"))]
4224 [(set_attr "conds" "set")
4225 (set_attr "shift" "1")
4226 (set_attr "arch" "32,a")
4227 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4229 ;; We don't really have extzv, but defining this using shifts helps
4230 ;; to reduce register pressure later on.
4232 (define_expand "extzv"
4233 [(set (match_operand 0 "s_register_operand" "")
4234 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4235 (match_operand 2 "const_int_operand" "")
4236 (match_operand 3 "const_int_operand" "")))]
4237 "TARGET_THUMB1 || arm_arch_thumb2"
4240 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4241 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4243 if (arm_arch_thumb2)
4245 HOST_WIDE_INT width = INTVAL (operands[2]);
4246 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4248 if (unaligned_access && MEM_P (operands[1])
4249 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4253 if (BYTES_BIG_ENDIAN)
4254 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4259 base_addr = adjust_address (operands[1], SImode,
4260 bitpos / BITS_PER_UNIT);
4261 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4265 rtx dest = operands[0];
4266 rtx tmp = gen_reg_rtx (SImode);
4268 /* We may get a paradoxical subreg here. Strip it off. */
4269 if (GET_CODE (dest) == SUBREG
4270 && GET_MODE (dest) == SImode
4271 && GET_MODE (SUBREG_REG (dest)) == HImode)
4272 dest = SUBREG_REG (dest);
4274 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4277 base_addr = adjust_address (operands[1], HImode,
4278 bitpos / BITS_PER_UNIT);
4279 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4280 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4284 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4286 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4294 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4297 operands[3] = GEN_INT (rshift);
4301 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4305 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4306 operands[3], gen_reg_rtx (SImode)));
4311 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4313 (define_expand "extzv_t1"
4314 [(set (match_operand:SI 4 "s_register_operand" "")
4315 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4316 (match_operand:SI 2 "const_int_operand" "")))
4317 (set (match_operand:SI 0 "s_register_operand" "")
4318 (lshiftrt:SI (match_dup 4)
4319 (match_operand:SI 3 "const_int_operand" "")))]
4323 (define_expand "extv"
4324 [(set (match_operand 0 "s_register_operand" "")
4325 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4326 (match_operand 2 "const_int_operand" "")
4327 (match_operand 3 "const_int_operand" "")))]
4330 HOST_WIDE_INT width = INTVAL (operands[2]);
4331 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4333 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4334 && (bitpos % BITS_PER_UNIT) == 0)
4338 if (BYTES_BIG_ENDIAN)
4339 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4343 base_addr = adjust_address (operands[1], SImode,
4344 bitpos / BITS_PER_UNIT);
4345 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4349 rtx dest = operands[0];
4350 rtx tmp = gen_reg_rtx (SImode);
4352 /* We may get a paradoxical subreg here. Strip it off. */
4353 if (GET_CODE (dest) == SUBREG
4354 && GET_MODE (dest) == SImode
4355 && GET_MODE (SUBREG_REG (dest)) == HImode)
4356 dest = SUBREG_REG (dest);
4358 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4361 base_addr = adjust_address (operands[1], HImode,
4362 bitpos / BITS_PER_UNIT);
4363 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4364 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4369 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4371 else if (GET_MODE (operands[0]) == SImode
4372 && GET_MODE (operands[1]) == SImode)
4374 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4382 ; Helper to expand register forms of extv with the proper modes.
4384 (define_expand "extv_regsi"
4385 [(set (match_operand:SI 0 "s_register_operand" "")
4386 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4387 (match_operand 2 "const_int_operand" "")
4388 (match_operand 3 "const_int_operand" "")))]
4393 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4395 (define_insn "unaligned_loadsi"
4396 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4397 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4398 UNSPEC_UNALIGNED_LOAD))]
4399 "unaligned_access && TARGET_32BIT"
4400 "ldr%?\t%0, %1\t@ unaligned"
4401 [(set_attr "arch" "t2,any")
4402 (set_attr "length" "2,4")
4403 (set_attr "predicable" "yes")
4404 (set_attr "predicable_short_it" "yes,no")
4405 (set_attr "type" "load1")])
4407 (define_insn "unaligned_loadhis"
4408 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4410 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4411 UNSPEC_UNALIGNED_LOAD)))]
4412 "unaligned_access && TARGET_32BIT"
4413 "ldr%(sh%)\t%0, %1\t@ unaligned"
4414 [(set_attr "arch" "t2,any")
4415 (set_attr "length" "2,4")
4416 (set_attr "predicable" "yes")
4417 (set_attr "predicable_short_it" "yes,no")
4418 (set_attr "type" "load_byte")])
4420 (define_insn "unaligned_loadhiu"
4421 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4423 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4424 UNSPEC_UNALIGNED_LOAD)))]
4425 "unaligned_access && TARGET_32BIT"
4426 "ldr%(h%)\t%0, %1\t@ unaligned"
4427 [(set_attr "arch" "t2,any")
4428 (set_attr "length" "2,4")
4429 (set_attr "predicable" "yes")
4430 (set_attr "predicable_short_it" "yes,no")
4431 (set_attr "type" "load_byte")])
4433 (define_insn "unaligned_storesi"
4434 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4435 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4436 UNSPEC_UNALIGNED_STORE))]
4437 "unaligned_access && TARGET_32BIT"
4438 "str%?\t%1, %0\t@ unaligned"
4439 [(set_attr "arch" "t2,any")
4440 (set_attr "length" "2,4")
4441 (set_attr "predicable" "yes")
4442 (set_attr "predicable_short_it" "yes,no")
4443 (set_attr "type" "store1")])
4445 (define_insn "unaligned_storehi"
4446 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4447 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4448 UNSPEC_UNALIGNED_STORE))]
4449 "unaligned_access && TARGET_32BIT"
4450 "str%(h%)\t%1, %0\t@ unaligned"
4451 [(set_attr "arch" "t2,any")
4452 (set_attr "length" "2,4")
4453 (set_attr "predicable" "yes")
4454 (set_attr "predicable_short_it" "yes,no")
4455 (set_attr "type" "store1")])
4457 ;; Unaligned double-word load and store.
4458 ;; Split after reload into two unaligned single-word accesses.
4459 ;; It prevents lower_subreg from splitting some other aligned
4460 ;; double-word accesses too early. Used for internal memcpy.
4462 (define_insn_and_split "unaligned_loaddi"
4463 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4464 (unspec:DI [(match_operand:DI 1 "memory_operand" "o,o")]
4465 UNSPEC_UNALIGNED_LOAD))]
4466 "unaligned_access && TARGET_32BIT"
4468 "&& reload_completed"
4469 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_LOAD))
4470 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_LOAD))]
4472 operands[2] = gen_highpart (SImode, operands[0]);
4473 operands[0] = gen_lowpart (SImode, operands[0]);
4474 operands[3] = gen_highpart (SImode, operands[1]);
4475 operands[1] = gen_lowpart (SImode, operands[1]);
4477 /* If the first destination register overlaps with the base address,
4478 swap the order in which the loads are emitted. */
4479 if (reg_overlap_mentioned_p (operands[0], operands[1]))
4481 rtx tmp = operands[1];
4482 operands[1] = operands[3];
4485 operands[0] = operands[2];
4489 [(set_attr "arch" "t2,any")
4490 (set_attr "length" "4,8")
4491 (set_attr "predicable" "yes")
4492 (set_attr "type" "load2")])
4494 (define_insn_and_split "unaligned_storedi"
4495 [(set (match_operand:DI 0 "memory_operand" "=o,o")
4496 (unspec:DI [(match_operand:DI 1 "s_register_operand" "l,r")]
4497 UNSPEC_UNALIGNED_STORE))]
4498 "unaligned_access && TARGET_32BIT"
4500 "&& reload_completed"
4501 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_UNALIGNED_STORE))
4502 (set (match_dup 2) (unspec:SI [(match_dup 3)] UNSPEC_UNALIGNED_STORE))]
4504 operands[2] = gen_highpart (SImode, operands[0]);
4505 operands[0] = gen_lowpart (SImode, operands[0]);
4506 operands[3] = gen_highpart (SImode, operands[1]);
4507 operands[1] = gen_lowpart (SImode, operands[1]);
4509 [(set_attr "arch" "t2,any")
4510 (set_attr "length" "4,8")
4511 (set_attr "predicable" "yes")
4512 (set_attr "type" "store2")])
4515 (define_insn "*extv_reg"
4516 [(set (match_operand:SI 0 "s_register_operand" "=r")
4517 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4518 (match_operand:SI 2 "const_int_M_operand" "M")
4519 (match_operand:SI 3 "const_int_M_operand" "M")))]
4521 "sbfx%?\t%0, %1, %3, %2"
4522 [(set_attr "length" "4")
4523 (set_attr "predicable" "yes")
4524 (set_attr "predicable_short_it" "no")
4525 (set_attr "type" "bfm")]
4528 (define_insn "extzv_t2"
4529 [(set (match_operand:SI 0 "s_register_operand" "=r")
4530 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4531 (match_operand:SI 2 "const_int_M_operand" "M")
4532 (match_operand:SI 3 "const_int_M_operand" "M")))]
4534 "ubfx%?\t%0, %1, %3, %2"
4535 [(set_attr "length" "4")
4536 (set_attr "predicable" "yes")
4537 (set_attr "predicable_short_it" "no")
4538 (set_attr "type" "bfm")]
4542 ;; Division instructions
4543 (define_insn "divsi3"
4544 [(set (match_operand:SI 0 "s_register_operand" "=r")
4545 (div:SI (match_operand:SI 1 "s_register_operand" "r")
4546 (match_operand:SI 2 "s_register_operand" "r")))]
4548 "sdiv%?\t%0, %1, %2"
4549 [(set_attr "predicable" "yes")
4550 (set_attr "predicable_short_it" "no")
4551 (set_attr "type" "sdiv")]
4554 (define_insn "udivsi3"
4555 [(set (match_operand:SI 0 "s_register_operand" "=r")
4556 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
4557 (match_operand:SI 2 "s_register_operand" "r")))]
4559 "udiv%?\t%0, %1, %2"
4560 [(set_attr "predicable" "yes")
4561 (set_attr "predicable_short_it" "no")
4562 (set_attr "type" "udiv")]
4566 ;; Unary arithmetic insns
4568 (define_expand "negdi2"
4570 [(set (match_operand:DI 0 "s_register_operand" "")
4571 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4572 (clobber (reg:CC CC_REGNUM))])]
4577 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4583 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4584 ;; The first alternative allows the common case of a *full* overlap.
4585 (define_insn_and_split "*arm_negdi2"
4586 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4587 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4588 (clobber (reg:CC CC_REGNUM))]
4590 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4591 "&& reload_completed"
4592 [(parallel [(set (reg:CC CC_REGNUM)
4593 (compare:CC (const_int 0) (match_dup 1)))
4594 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4595 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4596 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4598 operands[2] = gen_highpart (SImode, operands[0]);
4599 operands[0] = gen_lowpart (SImode, operands[0]);
4600 operands[3] = gen_highpart (SImode, operands[1]);
4601 operands[1] = gen_lowpart (SImode, operands[1]);
4603 [(set_attr "conds" "clob")
4604 (set_attr "length" "8")
4605 (set_attr "type" "multiple")]
4608 (define_insn "*thumb1_negdi2"
4609 [(set (match_operand:DI 0 "register_operand" "=&l")
4610 (neg:DI (match_operand:DI 1 "register_operand" "l")))
4611 (clobber (reg:CC CC_REGNUM))]
4613 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
4614 [(set_attr "length" "6")
4615 (set_attr "type" "multiple")]
4618 (define_expand "negsi2"
4619 [(set (match_operand:SI 0 "s_register_operand" "")
4620 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4625 (define_insn "*arm_negsi2"
4626 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4627 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4629 "rsb%?\\t%0, %1, #0"
4630 [(set_attr "predicable" "yes")
4631 (set_attr "predicable_short_it" "yes,no")
4632 (set_attr "arch" "t2,*")
4633 (set_attr "length" "4")
4634 (set_attr "type" "alu_reg")]
4637 (define_insn "*thumb1_negsi2"
4638 [(set (match_operand:SI 0 "register_operand" "=l")
4639 (neg:SI (match_operand:SI 1 "register_operand" "l")))]
4642 [(set_attr "length" "2")
4643 (set_attr "type" "alu_imm")]
4646 (define_expand "negsf2"
4647 [(set (match_operand:SF 0 "s_register_operand" "")
4648 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4649 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4653 (define_expand "negdf2"
4654 [(set (match_operand:DF 0 "s_register_operand" "")
4655 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4656 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4659 (define_insn_and_split "*zextendsidi_negsi"
4660 [(set (match_operand:DI 0 "s_register_operand" "=r")
4661 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4666 (neg:SI (match_dup 1)))
4670 operands[2] = gen_lowpart (SImode, operands[0]);
4671 operands[3] = gen_highpart (SImode, operands[0]);
4673 [(set_attr "length" "8")
4674 (set_attr "type" "multiple")]
4677 ;; Negate an extended 32-bit value.
4678 (define_insn_and_split "*negdi_extendsidi"
4679 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4680 (neg:DI (sign_extend:DI
4681 (match_operand:SI 1 "s_register_operand" "l,r"))))
4682 (clobber (reg:CC CC_REGNUM))]
4685 "&& reload_completed"
4688 rtx low = gen_lowpart (SImode, operands[0]);
4689 rtx high = gen_highpart (SImode, operands[0]);
4691 if (reg_overlap_mentioned_p (low, operands[1]))
4693 /* Input overlaps the low word of the output. Use:
4696 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4697 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4699 emit_insn (gen_rtx_SET (VOIDmode, high,
4700 gen_rtx_ASHIFTRT (SImode, operands[1],
4703 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4705 emit_insn (gen_rtx_SET (VOIDmode, high,
4706 gen_rtx_MINUS (SImode,
4707 gen_rtx_MINUS (SImode,
4710 gen_rtx_LTU (SImode,
4715 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4716 emit_insn (gen_rtx_SET (VOIDmode, high,
4717 gen_rtx_MINUS (SImode,
4718 gen_rtx_MINUS (SImode,
4721 gen_rtx_LTU (SImode,
4728 /* No overlap, or overlap on high word. Use:
4732 Flags not needed for this sequence. */
4733 emit_insn (gen_rtx_SET (VOIDmode, low,
4734 gen_rtx_NEG (SImode, operands[1])));
4735 emit_insn (gen_rtx_SET (VOIDmode, high,
4736 gen_rtx_AND (SImode,
4737 gen_rtx_NOT (SImode, operands[1]),
4739 emit_insn (gen_rtx_SET (VOIDmode, high,
4740 gen_rtx_ASHIFTRT (SImode, high,
4745 [(set_attr "length" "12")
4746 (set_attr "arch" "t2,*")
4747 (set_attr "type" "multiple")]
4750 (define_insn_and_split "*negdi_zero_extendsidi"
4751 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4752 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4753 (clobber (reg:CC CC_REGNUM))]
4755 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4756 ;; Don't care what register is input to sbc,
4757 ;; since we just just need to propagate the carry.
4758 "&& reload_completed"
4759 [(parallel [(set (reg:CC CC_REGNUM)
4760 (compare:CC (const_int 0) (match_dup 1)))
4761 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4762 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4763 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4765 operands[2] = gen_highpart (SImode, operands[0]);
4766 operands[0] = gen_lowpart (SImode, operands[0]);
4768 [(set_attr "conds" "clob")
4769 (set_attr "length" "8")
4770 (set_attr "type" "multiple")] ;; length in thumb is 4
4773 ;; abssi2 doesn't really clobber the condition codes if a different register
4774 ;; is being set. To keep things simple, assume during rtl manipulations that
4775 ;; it does, but tell the final scan operator the truth. Similarly for
4778 (define_expand "abssi2"
4780 [(set (match_operand:SI 0 "s_register_operand" "")
4781 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4782 (clobber (match_dup 2))])]
4786 operands[2] = gen_rtx_SCRATCH (SImode);
4788 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4791 (define_insn_and_split "*arm_abssi2"
4792 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4793 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4794 (clobber (reg:CC CC_REGNUM))]
4797 "&& reload_completed"
4800 /* if (which_alternative == 0) */
4801 if (REGNO(operands[0]) == REGNO(operands[1]))
4803 /* Emit the pattern:
4804 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4805 [(set (reg:CC CC_REGNUM)
4806 (compare:CC (match_dup 0) (const_int 0)))
4807 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4808 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4810 emit_insn (gen_rtx_SET (VOIDmode,
4811 gen_rtx_REG (CCmode, CC_REGNUM),
4812 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4813 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4814 (gen_rtx_LT (SImode,
4815 gen_rtx_REG (CCmode, CC_REGNUM),
4817 (gen_rtx_SET (VOIDmode,
4819 (gen_rtx_MINUS (SImode,
4826 /* Emit the pattern:
4827 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4829 (xor:SI (match_dup 1)
4830 (ashiftrt:SI (match_dup 1) (const_int 31))))
4832 (minus:SI (match_dup 0)
4833 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4835 emit_insn (gen_rtx_SET (VOIDmode,
4837 gen_rtx_XOR (SImode,
4838 gen_rtx_ASHIFTRT (SImode,
4842 emit_insn (gen_rtx_SET (VOIDmode,
4844 gen_rtx_MINUS (SImode,
4846 gen_rtx_ASHIFTRT (SImode,
4852 [(set_attr "conds" "clob,*")
4853 (set_attr "shift" "1")
4854 (set_attr "predicable" "no, yes")
4855 (set_attr "length" "8")
4856 (set_attr "type" "multiple")]
4859 (define_insn_and_split "*thumb1_abssi2"
4860 [(set (match_operand:SI 0 "s_register_operand" "=l")
4861 (abs:SI (match_operand:SI 1 "s_register_operand" "l")))
4862 (clobber (match_scratch:SI 2 "=&l"))]
4865 "TARGET_THUMB1 && reload_completed"
4866 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
4867 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
4868 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
4870 [(set_attr "length" "6")
4871 (set_attr "type" "multiple")]
4874 (define_insn_and_split "*arm_neg_abssi2"
4875 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4876 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4877 (clobber (reg:CC CC_REGNUM))]
4880 "&& reload_completed"
4883 /* if (which_alternative == 0) */
4884 if (REGNO (operands[0]) == REGNO (operands[1]))
4886 /* Emit the pattern:
4887 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4889 emit_insn (gen_rtx_SET (VOIDmode,
4890 gen_rtx_REG (CCmode, CC_REGNUM),
4891 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4892 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4894 gen_rtx_REG (CCmode, CC_REGNUM),
4896 gen_rtx_SET (VOIDmode,
4898 (gen_rtx_MINUS (SImode,
4904 /* Emit the pattern:
4905 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4907 emit_insn (gen_rtx_SET (VOIDmode,
4909 gen_rtx_XOR (SImode,
4910 gen_rtx_ASHIFTRT (SImode,
4914 emit_insn (gen_rtx_SET (VOIDmode,
4916 gen_rtx_MINUS (SImode,
4917 gen_rtx_ASHIFTRT (SImode,
4924 [(set_attr "conds" "clob,*")
4925 (set_attr "shift" "1")
4926 (set_attr "predicable" "no, yes")
4927 (set_attr "length" "8")
4928 (set_attr "type" "multiple")]
4931 (define_insn_and_split "*thumb1_neg_abssi2"
4932 [(set (match_operand:SI 0 "s_register_operand" "=l")
4933 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "l"))))
4934 (clobber (match_scratch:SI 2 "=&l"))]
4937 "TARGET_THUMB1 && reload_completed"
4938 [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
4939 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))
4940 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
4942 [(set_attr "length" "6")
4943 (set_attr "type" "multiple")]
4946 (define_expand "abssf2"
4947 [(set (match_operand:SF 0 "s_register_operand" "")
4948 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4949 "TARGET_32BIT && TARGET_HARD_FLOAT"
4952 (define_expand "absdf2"
4953 [(set (match_operand:DF 0 "s_register_operand" "")
4954 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4955 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4958 (define_expand "sqrtsf2"
4959 [(set (match_operand:SF 0 "s_register_operand" "")
4960 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4961 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4964 (define_expand "sqrtdf2"
4965 [(set (match_operand:DF 0 "s_register_operand" "")
4966 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4967 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4970 (define_insn_and_split "one_cmpldi2"
4971 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
4972 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
4979 "TARGET_32BIT && reload_completed
4980 && arm_general_register_operand (operands[0], DImode)"
4981 [(set (match_dup 0) (not:SI (match_dup 1)))
4982 (set (match_dup 2) (not:SI (match_dup 3)))]
4985 operands[2] = gen_highpart (SImode, operands[0]);
4986 operands[0] = gen_lowpart (SImode, operands[0]);
4987 operands[3] = gen_highpart (SImode, operands[1]);
4988 operands[1] = gen_lowpart (SImode, operands[1]);
4990 [(set_attr "length" "*,8,8,*")
4991 (set_attr "predicable" "no,yes,yes,no")
4992 (set_attr "type" "neon_move,multiple,multiple,neon_move")
4993 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
4996 (define_expand "one_cmplsi2"
4997 [(set (match_operand:SI 0 "s_register_operand" "")
4998 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5003 (define_insn "*arm_one_cmplsi2"
5004 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5005 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5008 [(set_attr "predicable" "yes")
5009 (set_attr "predicable_short_it" "yes,no")
5010 (set_attr "arch" "t2,*")
5011 (set_attr "length" "4")
5012 (set_attr "type" "mvn_reg")]
5015 (define_insn "*thumb1_one_cmplsi2"
5016 [(set (match_operand:SI 0 "register_operand" "=l")
5017 (not:SI (match_operand:SI 1 "register_operand" "l")))]
5020 [(set_attr "length" "2")
5021 (set_attr "type" "mvn_reg")]
5024 (define_insn "*notsi_compare0"
5025 [(set (reg:CC_NOOV CC_REGNUM)
5026 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5028 (set (match_operand:SI 0 "s_register_operand" "=r")
5029 (not:SI (match_dup 1)))]
5032 [(set_attr "conds" "set")
5033 (set_attr "type" "mvn_reg")]
5036 (define_insn "*notsi_compare0_scratch"
5037 [(set (reg:CC_NOOV CC_REGNUM)
5038 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5040 (clobber (match_scratch:SI 0 "=r"))]
5043 [(set_attr "conds" "set")
5044 (set_attr "type" "mvn_reg")]
5047 ;; Fixed <--> Floating conversion insns
5049 (define_expand "floatsihf2"
5050 [(set (match_operand:HF 0 "general_operand" "")
5051 (float:HF (match_operand:SI 1 "general_operand" "")))]
5055 rtx op1 = gen_reg_rtx (SFmode);
5056 expand_float (op1, operands[1], 0);
5057 op1 = convert_to_mode (HFmode, op1, 0);
5058 emit_move_insn (operands[0], op1);
5063 (define_expand "floatdihf2"
5064 [(set (match_operand:HF 0 "general_operand" "")
5065 (float:HF (match_operand:DI 1 "general_operand" "")))]
5069 rtx op1 = gen_reg_rtx (SFmode);
5070 expand_float (op1, operands[1], 0);
5071 op1 = convert_to_mode (HFmode, op1, 0);
5072 emit_move_insn (operands[0], op1);
5077 (define_expand "floatsisf2"
5078 [(set (match_operand:SF 0 "s_register_operand" "")
5079 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5080 "TARGET_32BIT && TARGET_HARD_FLOAT"
5084 (define_expand "floatsidf2"
5085 [(set (match_operand:DF 0 "s_register_operand" "")
5086 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5087 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5091 (define_expand "fix_trunchfsi2"
5092 [(set (match_operand:SI 0 "general_operand" "")
5093 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5097 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5098 expand_fix (operands[0], op1, 0);
5103 (define_expand "fix_trunchfdi2"
5104 [(set (match_operand:DI 0 "general_operand" "")
5105 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5109 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5110 expand_fix (operands[0], op1, 0);
5115 (define_expand "fix_truncsfsi2"
5116 [(set (match_operand:SI 0 "s_register_operand" "")
5117 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5118 "TARGET_32BIT && TARGET_HARD_FLOAT"
5122 (define_expand "fix_truncdfsi2"
5123 [(set (match_operand:SI 0 "s_register_operand" "")
5124 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5125 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5131 (define_expand "truncdfsf2"
5132 [(set (match_operand:SF 0 "s_register_operand" "")
5134 (match_operand:DF 1 "s_register_operand" "")))]
5135 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5139 /* DFmode -> HFmode conversions have to go through SFmode. */
5140 (define_expand "truncdfhf2"
5141 [(set (match_operand:HF 0 "general_operand" "")
5143 (match_operand:DF 1 "general_operand" "")))]
5148 op1 = convert_to_mode (SFmode, operands[1], 0);
5149 op1 = convert_to_mode (HFmode, op1, 0);
5150 emit_move_insn (operands[0], op1);
5155 ;; Zero and sign extension instructions.
5157 (define_insn "zero_extend<mode>di2"
5158 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5159 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5160 "<qhs_zextenddi_cstr>")))]
5161 "TARGET_32BIT <qhs_zextenddi_cond>"
5163 [(set_attr "length" "8,4,8,8")
5164 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5165 (set_attr "ce_count" "2")
5166 (set_attr "predicable" "yes")
5167 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5170 (define_insn "extend<mode>di2"
5171 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5172 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5173 "<qhs_extenddi_cstr>")))]
5174 "TARGET_32BIT <qhs_sextenddi_cond>"
5176 [(set_attr "length" "8,4,8,8,8")
5177 (set_attr "ce_count" "2")
5178 (set_attr "shift" "1")
5179 (set_attr "predicable" "yes")
5180 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5181 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5184 ;; Splits for all extensions to DImode
5186 [(set (match_operand:DI 0 "s_register_operand" "")
5187 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5188 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5189 [(set (match_dup 0) (match_dup 1))]
5191 rtx lo_part = gen_lowpart (SImode, operands[0]);
5192 enum machine_mode src_mode = GET_MODE (operands[1]);
5194 if (REG_P (operands[0])
5195 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5196 emit_clobber (operands[0]);
5197 if (!REG_P (lo_part) || src_mode != SImode
5198 || !rtx_equal_p (lo_part, operands[1]))
5200 if (src_mode == SImode)
5201 emit_move_insn (lo_part, operands[1]);
5203 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5204 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5205 operands[1] = lo_part;
5207 operands[0] = gen_highpart (SImode, operands[0]);
5208 operands[1] = const0_rtx;
5212 [(set (match_operand:DI 0 "s_register_operand" "")
5213 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5214 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5215 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5217 rtx lo_part = gen_lowpart (SImode, operands[0]);
5218 enum machine_mode src_mode = GET_MODE (operands[1]);
5220 if (REG_P (operands[0])
5221 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5222 emit_clobber (operands[0]);
5224 if (!REG_P (lo_part) || src_mode != SImode
5225 || !rtx_equal_p (lo_part, operands[1]))
5227 if (src_mode == SImode)
5228 emit_move_insn (lo_part, operands[1]);
5230 emit_insn (gen_rtx_SET (VOIDmode, lo_part,
5231 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5232 operands[1] = lo_part;
5234 operands[0] = gen_highpart (SImode, operands[0]);
5237 (define_expand "zero_extendhisi2"
5238 [(set (match_operand:SI 0 "s_register_operand" "")
5239 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5242 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5244 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5247 if (!arm_arch6 && !MEM_P (operands[1]))
5249 rtx t = gen_lowpart (SImode, operands[1]);
5250 rtx tmp = gen_reg_rtx (SImode);
5251 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5252 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5258 [(set (match_operand:SI 0 "s_register_operand" "")
5259 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5260 "!TARGET_THUMB2 && !arm_arch6"
5261 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5262 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5264 operands[2] = gen_lowpart (SImode, operands[1]);
5267 (define_insn "*thumb1_zero_extendhisi2"
5268 [(set (match_operand:SI 0 "register_operand" "=l,l")
5269 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))]
5274 if (which_alternative == 0 && arm_arch6)
5275 return "uxth\t%0, %1";
5276 if (which_alternative == 0)
5279 mem = XEXP (operands[1], 0);
5281 if (GET_CODE (mem) == CONST)
5282 mem = XEXP (mem, 0);
5284 if (GET_CODE (mem) == PLUS)
5286 rtx a = XEXP (mem, 0);
5288 /* This can happen due to bugs in reload. */
5289 if (REG_P (a) && REGNO (a) == SP_REGNUM)
5292 ops[0] = operands[0];
5295 output_asm_insn ("mov\t%0, %1", ops);
5297 XEXP (mem, 0) = operands[0];
5301 return "ldrh\t%0, %1";
5303 [(set_attr_alternative "length"
5304 [(if_then_else (eq_attr "is_arch6" "yes")
5305 (const_int 2) (const_int 4))
5307 (set_attr "type" "extend,load_byte")]
5310 (define_insn "*arm_zero_extendhisi2"
5311 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5312 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5313 "TARGET_ARM && arm_arch4 && !arm_arch6"
5317 [(set_attr "type" "alu_shift_reg,load_byte")
5318 (set_attr "predicable" "yes")]
5321 (define_insn "*arm_zero_extendhisi2_v6"
5322 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5323 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5324 "TARGET_ARM && arm_arch6"
5328 [(set_attr "predicable" "yes")
5329 (set_attr "type" "extend,load_byte")]
5332 (define_insn "*arm_zero_extendhisi2addsi"
5333 [(set (match_operand:SI 0 "s_register_operand" "=r")
5334 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5335 (match_operand:SI 2 "s_register_operand" "r")))]
5337 "uxtah%?\\t%0, %2, %1"
5338 [(set_attr "type" "alu_shift_reg")
5339 (set_attr "predicable" "yes")
5340 (set_attr "predicable_short_it" "no")]
5343 (define_expand "zero_extendqisi2"
5344 [(set (match_operand:SI 0 "s_register_operand" "")
5345 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5348 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5350 emit_insn (gen_andsi3 (operands[0],
5351 gen_lowpart (SImode, operands[1]),
5355 if (!arm_arch6 && !MEM_P (operands[1]))
5357 rtx t = gen_lowpart (SImode, operands[1]);
5358 rtx tmp = gen_reg_rtx (SImode);
5359 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5360 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5366 [(set (match_operand:SI 0 "s_register_operand" "")
5367 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5369 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5370 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5372 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5375 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5380 (define_insn "*thumb1_zero_extendqisi2"
5381 [(set (match_operand:SI 0 "register_operand" "=l,l")
5382 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
5383 "TARGET_THUMB1 && !arm_arch6"
5387 [(set_attr "length" "4,2")
5388 (set_attr "type" "alu_shift_reg,load_byte")
5389 (set_attr "pool_range" "*,32")]
5392 (define_insn "*thumb1_zero_extendqisi2_v6"
5393 [(set (match_operand:SI 0 "register_operand" "=l,l")
5394 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,m")))]
5395 "TARGET_THUMB1 && arm_arch6"
5399 [(set_attr "length" "2")
5400 (set_attr "type" "extend,load_byte")]
5403 (define_insn "*arm_zero_extendqisi2"
5404 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5405 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5406 "TARGET_ARM && !arm_arch6"
5409 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5410 [(set_attr "length" "8,4")
5411 (set_attr "type" "alu_shift_reg,load_byte")
5412 (set_attr "predicable" "yes")]
5415 (define_insn "*arm_zero_extendqisi2_v6"
5416 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5417 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5418 "TARGET_ARM && arm_arch6"
5421 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
5422 [(set_attr "type" "extend,load_byte")
5423 (set_attr "predicable" "yes")]
5426 (define_insn "*arm_zero_extendqisi2addsi"
5427 [(set (match_operand:SI 0 "s_register_operand" "=r")
5428 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5429 (match_operand:SI 2 "s_register_operand" "r")))]
5431 "uxtab%?\\t%0, %2, %1"
5432 [(set_attr "predicable" "yes")
5433 (set_attr "predicable_short_it" "no")
5434 (set_attr "type" "alu_shift_reg")]
5438 [(set (match_operand:SI 0 "s_register_operand" "")
5439 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5440 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5441 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5442 [(set (match_dup 2) (match_dup 1))
5443 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5448 [(set (match_operand:SI 0 "s_register_operand" "")
5449 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5450 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5451 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5452 [(set (match_dup 2) (match_dup 1))
5453 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5459 [(set (match_operand:SI 0 "s_register_operand" "")
5460 (ior_xor:SI (and:SI (ashift:SI
5461 (match_operand:SI 1 "s_register_operand" "")
5462 (match_operand:SI 2 "const_int_operand" ""))
5463 (match_operand:SI 3 "const_int_operand" ""))
5465 (match_operator 5 "subreg_lowpart_operator"
5466 [(match_operand:SI 4 "s_register_operand" "")]))))]
5468 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5469 == (GET_MODE_MASK (GET_MODE (operands[5]))
5470 & (GET_MODE_MASK (GET_MODE (operands[5]))
5471 << (INTVAL (operands[2])))))"
5472 [(set (match_dup 0) (ior_xor:SI (ashift:SI (match_dup 1) (match_dup 2))
5474 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5475 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5478 (define_insn "*compareqi_eq0"
5479 [(set (reg:CC_Z CC_REGNUM)
5480 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5484 [(set_attr "conds" "set")
5485 (set_attr "predicable" "yes")
5486 (set_attr "predicable_short_it" "no")
5487 (set_attr "type" "logic_imm")]
5490 (define_expand "extendhisi2"
5491 [(set (match_operand:SI 0 "s_register_operand" "")
5492 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5497 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5500 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5502 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5506 if (!arm_arch6 && !MEM_P (operands[1]))
5508 rtx t = gen_lowpart (SImode, operands[1]);
5509 rtx tmp = gen_reg_rtx (SImode);
5510 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5511 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5518 [(set (match_operand:SI 0 "register_operand" "")
5519 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5520 (clobber (match_scratch:SI 2 ""))])]
5522 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5523 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5525 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5528 ;; We used to have an early-clobber on the scratch register here.
5529 ;; However, there's a bug somewhere in reload which means that this
5530 ;; can be partially ignored during spill allocation if the memory
5531 ;; address also needs reloading; this causes us to die later on when
5532 ;; we try to verify the operands. Fortunately, we don't really need
5533 ;; the early-clobber: we can always use operand 0 if operand 2
5534 ;; overlaps the address.
5535 (define_insn "thumb1_extendhisi2"
5536 [(set (match_operand:SI 0 "register_operand" "=l,l")
5537 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "l,m")))
5538 (clobber (match_scratch:SI 2 "=X,l"))]
5545 if (which_alternative == 0 && !arm_arch6)
5547 if (which_alternative == 0)
5548 return \"sxth\\t%0, %1\";
5550 mem = XEXP (operands[1], 0);
5552 /* This code used to try to use 'V', and fix the address only if it was
5553 offsettable, but this fails for e.g. REG+48 because 48 is outside the
5554 range of QImode offsets, and offsettable_address_p does a QImode
5557 if (GET_CODE (mem) == CONST)
5558 mem = XEXP (mem, 0);
5560 if (GET_CODE (mem) == LABEL_REF)
5561 return \"ldr\\t%0, %1\";
5563 if (GET_CODE (mem) == PLUS)
5565 rtx a = XEXP (mem, 0);
5566 rtx b = XEXP (mem, 1);
5568 if (GET_CODE (a) == LABEL_REF
5570 return \"ldr\\t%0, %1\";
5573 return \"ldrsh\\t%0, %1\";
5581 ops[2] = const0_rtx;
5584 gcc_assert (REG_P (ops[1]));
5586 ops[0] = operands[0];
5587 if (reg_mentioned_p (operands[2], ops[1]))
5590 ops[3] = operands[2];
5591 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops);
5594 [(set_attr_alternative "length"
5595 [(if_then_else (eq_attr "is_arch6" "yes")
5596 (const_int 2) (const_int 4))
5598 (set_attr "type" "extend,load_byte")
5599 (set_attr "pool_range" "*,1018")]
5602 ;; This pattern will only be used when ldsh is not available
5603 (define_expand "extendhisi2_mem"
5604 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5606 (zero_extend:SI (match_dup 7)))
5607 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5608 (set (match_operand:SI 0 "" "")
5609 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5614 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5616 mem1 = change_address (operands[1], QImode, addr);
5617 mem2 = change_address (operands[1], QImode,
5618 plus_constant (Pmode, addr, 1));
5619 operands[0] = gen_lowpart (SImode, operands[0]);
5621 operands[2] = gen_reg_rtx (SImode);
5622 operands[3] = gen_reg_rtx (SImode);
5623 operands[6] = gen_reg_rtx (SImode);
5626 if (BYTES_BIG_ENDIAN)
5628 operands[4] = operands[2];
5629 operands[5] = operands[3];
5633 operands[4] = operands[3];
5634 operands[5] = operands[2];
5640 [(set (match_operand:SI 0 "register_operand" "")
5641 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5643 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5644 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5646 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5649 (define_insn "*arm_extendhisi2"
5650 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5651 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5652 "TARGET_ARM && arm_arch4 && !arm_arch6"
5656 [(set_attr "length" "8,4")
5657 (set_attr "type" "alu_shift_reg,load_byte")
5658 (set_attr "predicable" "yes")]
5661 ;; ??? Check Thumb-2 pool range
5662 (define_insn "*arm_extendhisi2_v6"
5663 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5664 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5665 "TARGET_32BIT && arm_arch6"
5669 [(set_attr "type" "extend,load_byte")
5670 (set_attr "predicable" "yes")
5671 (set_attr "predicable_short_it" "no")]
5674 (define_insn "*arm_extendhisi2addsi"
5675 [(set (match_operand:SI 0 "s_register_operand" "=r")
5676 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5677 (match_operand:SI 2 "s_register_operand" "r")))]
5679 "sxtah%?\\t%0, %2, %1"
5680 [(set_attr "type" "alu_shift_reg")]
5683 (define_expand "extendqihi2"
5685 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5687 (set (match_operand:HI 0 "s_register_operand" "")
5688 (ashiftrt:SI (match_dup 2)
5693 if (arm_arch4 && MEM_P (operands[1]))
5695 emit_insn (gen_rtx_SET (VOIDmode,
5697 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5700 if (!s_register_operand (operands[1], QImode))
5701 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5702 operands[0] = gen_lowpart (SImode, operands[0]);
5703 operands[1] = gen_lowpart (SImode, operands[1]);
5704 operands[2] = gen_reg_rtx (SImode);
5708 (define_insn "*arm_extendqihi_insn"
5709 [(set (match_operand:HI 0 "s_register_operand" "=r")
5710 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5711 "TARGET_ARM && arm_arch4"
5712 "ldr%(sb%)\\t%0, %1"
5713 [(set_attr "type" "load_byte")
5714 (set_attr "predicable" "yes")]
5717 (define_expand "extendqisi2"
5718 [(set (match_operand:SI 0 "s_register_operand" "")
5719 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5722 if (!arm_arch4 && MEM_P (operands[1]))
5723 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5725 if (!arm_arch6 && !MEM_P (operands[1]))
5727 rtx t = gen_lowpart (SImode, operands[1]);
5728 rtx tmp = gen_reg_rtx (SImode);
5729 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5730 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5736 [(set (match_operand:SI 0 "register_operand" "")
5737 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5739 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5740 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5742 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5745 (define_insn "*arm_extendqisi"
5746 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5747 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5748 "TARGET_ARM && arm_arch4 && !arm_arch6"
5752 [(set_attr "length" "8,4")
5753 (set_attr "type" "alu_shift_reg,load_byte")
5754 (set_attr "predicable" "yes")]
5757 (define_insn "*arm_extendqisi_v6"
5758 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5760 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5761 "TARGET_ARM && arm_arch6"
5765 [(set_attr "type" "extend,load_byte")
5766 (set_attr "predicable" "yes")]
5769 (define_insn "*arm_extendqisi2addsi"
5770 [(set (match_operand:SI 0 "s_register_operand" "=r")
5771 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5772 (match_operand:SI 2 "s_register_operand" "r")))]
5774 "sxtab%?\\t%0, %2, %1"
5775 [(set_attr "type" "alu_shift_reg")
5776 (set_attr "predicable" "yes")
5777 (set_attr "predicable_short_it" "no")]
5781 [(set (match_operand:SI 0 "register_operand" "")
5782 (sign_extend:SI (match_operand:QI 1 "memory_operand" "")))]
5783 "TARGET_THUMB1 && reload_completed"
5784 [(set (match_dup 0) (match_dup 2))
5785 (set (match_dup 0) (sign_extend:SI (match_dup 3)))]
5787 rtx addr = XEXP (operands[1], 0);
5789 if (GET_CODE (addr) == CONST)
5790 addr = XEXP (addr, 0);
5792 if (GET_CODE (addr) == PLUS
5793 && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5794 /* No split necessary. */
5797 if (GET_CODE (addr) == PLUS
5798 && !REG_P (XEXP (addr, 0)) && !REG_P (XEXP (addr, 1)))
5801 if (reg_overlap_mentioned_p (operands[0], addr))
5803 rtx t = gen_lowpart (QImode, operands[0]);
5804 emit_move_insn (t, operands[1]);
5805 emit_insn (gen_thumb1_extendqisi2 (operands[0], t));
5811 addr = gen_rtx_PLUS (Pmode, addr, operands[0]);
5812 operands[2] = const0_rtx;
5814 else if (GET_CODE (addr) != PLUS)
5816 else if (REG_P (XEXP (addr, 0)))
5818 operands[2] = XEXP (addr, 1);
5819 addr = gen_rtx_PLUS (Pmode, XEXP (addr, 0), operands[0]);
5823 operands[2] = XEXP (addr, 0);
5824 addr = gen_rtx_PLUS (Pmode, XEXP (addr, 1), operands[0]);
5827 operands[3] = change_address (operands[1], QImode, addr);
5831 [(set (match_operand:SI 0 "register_operand" "")
5832 (plus:SI (match_dup 0) (match_operand 1 "const_int_operand")))
5833 (set (match_operand:SI 2 "register_operand" "") (const_int 0))
5834 (set (match_operand:SI 3 "register_operand" "")
5835 (sign_extend:SI (match_operand:QI 4 "memory_operand" "")))]
5837 && GET_CODE (XEXP (operands[4], 0)) == PLUS
5838 && rtx_equal_p (operands[0], XEXP (XEXP (operands[4], 0), 0))
5839 && rtx_equal_p (operands[2], XEXP (XEXP (operands[4], 0), 1))
5840 && (peep2_reg_dead_p (3, operands[0])
5841 || rtx_equal_p (operands[0], operands[3]))
5842 && (peep2_reg_dead_p (3, operands[2])
5843 || rtx_equal_p (operands[2], operands[3]))"
5844 [(set (match_dup 2) (match_dup 1))
5845 (set (match_dup 3) (sign_extend:SI (match_dup 4)))]
5847 rtx addr = gen_rtx_PLUS (Pmode, operands[0], operands[2]);
5848 operands[4] = change_address (operands[4], QImode, addr);
5851 (define_insn "thumb1_extendqisi2"
5852 [(set (match_operand:SI 0 "register_operand" "=l,l,l")
5853 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "l,V,m")))]
5858 if (which_alternative == 0 && arm_arch6)
5859 return "sxtb\\t%0, %1";
5860 if (which_alternative == 0)
5863 addr = XEXP (operands[1], 0);
5864 if (GET_CODE (addr) == PLUS
5865 && REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))
5866 return "ldrsb\\t%0, %1";
5870 [(set_attr_alternative "length"
5871 [(if_then_else (eq_attr "is_arch6" "yes")
5872 (const_int 2) (const_int 4))
5874 (if_then_else (eq_attr "is_arch6" "yes")
5875 (const_int 4) (const_int 6))])
5876 (set_attr "type" "extend,load_byte,load_byte")]
5879 (define_expand "extendsfdf2"
5880 [(set (match_operand:DF 0 "s_register_operand" "")
5881 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5882 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5886 /* HFmode -> DFmode conversions have to go through SFmode. */
5887 (define_expand "extendhfdf2"
5888 [(set (match_operand:DF 0 "general_operand" "")
5889 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5894 op1 = convert_to_mode (SFmode, operands[1], 0);
5895 op1 = convert_to_mode (DFmode, op1, 0);
5896 emit_insn (gen_movdf (operands[0], op1));
5901 ;; Move insns (including loads and stores)
5903 ;; XXX Just some ideas about movti.
5904 ;; I don't think these are a good idea on the arm, there just aren't enough
5906 ;;(define_expand "loadti"
5907 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5908 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5911 ;;(define_expand "storeti"
5912 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5913 ;; (match_operand:TI 1 "s_register_operand" ""))]
5916 ;;(define_expand "movti"
5917 ;; [(set (match_operand:TI 0 "general_operand" "")
5918 ;; (match_operand:TI 1 "general_operand" ""))]
5924 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5925 ;; operands[1] = copy_to_reg (operands[1]);
5926 ;; if (MEM_P (operands[0]))
5927 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5928 ;; else if (MEM_P (operands[1]))
5929 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5933 ;; emit_insn (insn);
5937 ;; Recognize garbage generated above.
5940 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5941 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5945 ;; register mem = (which_alternative < 3);
5946 ;; register const char *template;
5948 ;; operands[mem] = XEXP (operands[mem], 0);
5949 ;; switch (which_alternative)
5951 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5952 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5953 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5954 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5955 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5956 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5958 ;; output_asm_insn (template, operands);
5962 (define_expand "movdi"
5963 [(set (match_operand:DI 0 "general_operand" "")
5964 (match_operand:DI 1 "general_operand" ""))]
5967 if (can_create_pseudo_p ())
5969 if (!REG_P (operands[0]))
5970 operands[1] = force_reg (DImode, operands[1]);
5975 (define_insn "*arm_movdi"
5976 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5977 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5979 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5981 && ( register_operand (operands[0], DImode)
5982 || register_operand (operands[1], DImode))"
5984 switch (which_alternative)
5991 return output_move_double (operands, true, NULL);
5994 [(set_attr "length" "8,12,16,8,8")
5995 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5996 (set_attr "arm_pool_range" "*,*,*,1020,*")
5997 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5998 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5999 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6003 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6004 (match_operand:ANY64 1 "const_double_operand" ""))]
6007 && (arm_const_double_inline_cost (operands[1])
6008 <= arm_max_const_double_inline_cost ())"
6011 arm_split_constant (SET, SImode, curr_insn,
6012 INTVAL (gen_lowpart (SImode, operands[1])),
6013 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
6014 arm_split_constant (SET, SImode, curr_insn,
6015 INTVAL (gen_highpart_mode (SImode,
6016 GET_MODE (operands[0]),
6018 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
6023 ; If optimizing for size, or if we have load delay slots, then
6024 ; we want to split the constant into two separate operations.
6025 ; In both cases this may split a trivial part into a single data op
6026 ; leaving a single complex constant to load. We can also get longer
6027 ; offsets in a LDR which means we get better chances of sharing the pool
6028 ; entries. Finally, we can normally do a better job of scheduling
6029 ; LDR instructions than we can with LDM.
6030 ; This pattern will only match if the one above did not.
6032 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6033 (match_operand:ANY64 1 "const_double_operand" ""))]
6034 "TARGET_ARM && reload_completed
6035 && arm_const_double_by_parts (operands[1])"
6036 [(set (match_dup 0) (match_dup 1))
6037 (set (match_dup 2) (match_dup 3))]
6039 operands[2] = gen_highpart (SImode, operands[0]);
6040 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
6042 operands[0] = gen_lowpart (SImode, operands[0]);
6043 operands[1] = gen_lowpart (SImode, operands[1]);
6048 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
6049 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
6050 "TARGET_EITHER && reload_completed"
6051 [(set (match_dup 0) (match_dup 1))
6052 (set (match_dup 2) (match_dup 3))]
6054 operands[2] = gen_highpart (SImode, operands[0]);
6055 operands[3] = gen_highpart (SImode, operands[1]);
6056 operands[0] = gen_lowpart (SImode, operands[0]);
6057 operands[1] = gen_lowpart (SImode, operands[1]);
6059 /* Handle a partial overlap. */
6060 if (rtx_equal_p (operands[0], operands[3]))
6062 rtx tmp0 = operands[0];
6063 rtx tmp1 = operands[1];
6065 operands[0] = operands[2];
6066 operands[1] = operands[3];
6073 ;; We can't actually do base+index doubleword loads if the index and
6074 ;; destination overlap. Split here so that we at least have chance to
6077 [(set (match_operand:DI 0 "s_register_operand" "")
6078 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
6079 (match_operand:SI 2 "s_register_operand" ""))))]
6081 && reg_overlap_mentioned_p (operands[0], operands[1])
6082 && reg_overlap_mentioned_p (operands[0], operands[2])"
6084 (plus:SI (match_dup 1)
6087 (mem:DI (match_dup 4)))]
6089 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
6093 ;;; ??? This should have alternatives for constants.
6094 ;;; ??? This was originally identical to the movdf_insn pattern.
6095 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
6096 ;;; thumb_reorg with a memory reference.
6097 (define_insn "*thumb1_movdi_insn"
6098 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
6099 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
6101 && ( register_operand (operands[0], DImode)
6102 || register_operand (operands[1], DImode))"
6105 switch (which_alternative)
6109 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6110 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
6111 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
6113 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\";
6115 operands[1] = GEN_INT (- INTVAL (operands[1]));
6116 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\";
6118 return \"ldmia\\t%1, {%0, %H0}\";
6120 return \"stmia\\t%0, {%1, %H1}\";
6122 return thumb_load_double_from_address (operands);
6124 operands[2] = gen_rtx_MEM (SImode,
6125 plus_constant (Pmode, XEXP (operands[0], 0), 4));
6126 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
6129 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
6130 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
6131 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
6134 [(set_attr "length" "4,4,6,2,2,6,4,4")
6135 (set_attr "type" "multiple,multiple,multiple,load2,store2,load2,store2,multiple")
6136 (set_attr "pool_range" "*,*,*,*,*,1018,*,*")]
6139 (define_expand "movsi"
6140 [(set (match_operand:SI 0 "general_operand" "")
6141 (match_operand:SI 1 "general_operand" ""))]
6145 rtx base, offset, tmp;
6149 /* Everything except mem = const or mem = mem can be done easily. */
6150 if (MEM_P (operands[0]))
6151 operands[1] = force_reg (SImode, operands[1]);
6152 if (arm_general_register_operand (operands[0], SImode)
6153 && CONST_INT_P (operands[1])
6154 && !(const_ok_for_arm (INTVAL (operands[1]))
6155 || const_ok_for_arm (~INTVAL (operands[1]))))
6157 arm_split_constant (SET, SImode, NULL_RTX,
6158 INTVAL (operands[1]), operands[0], NULL_RTX,
6159 optimize && can_create_pseudo_p ());
6163 else /* TARGET_THUMB1... */
6165 if (can_create_pseudo_p ())
6167 if (!REG_P (operands[0]))
6168 operands[1] = force_reg (SImode, operands[1]);
6172 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6174 split_const (operands[1], &base, &offset);
6175 if (GET_CODE (base) == SYMBOL_REF
6176 && !offset_within_block_p (base, INTVAL (offset)))
6178 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6179 emit_move_insn (tmp, base);
6180 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6185 /* Recognize the case where operand[1] is a reference to thread-local
6186 data and load its address to a register. */
6187 if (arm_tls_referenced_p (operands[1]))
6189 rtx tmp = operands[1];
6192 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6194 addend = XEXP (XEXP (tmp, 0), 1);
6195 tmp = XEXP (XEXP (tmp, 0), 0);
6198 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6199 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6201 tmp = legitimize_tls_address (tmp,
6202 !can_create_pseudo_p () ? operands[0] : 0);
6205 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6206 tmp = force_operand (tmp, operands[0]);
6211 && (CONSTANT_P (operands[1])
6212 || symbol_mentioned_p (operands[1])
6213 || label_mentioned_p (operands[1])))
6214 operands[1] = legitimize_pic_address (operands[1], SImode,
6215 (!can_create_pseudo_p ()
6222 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6223 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6224 ;; so this does not matter.
6225 (define_insn "*arm_movt"
6226 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
6227 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
6228 (match_operand:SI 2 "general_operand" "i")))]
6230 "movt%?\t%0, #:upper16:%c2"
6231 [(set_attr "predicable" "yes")
6232 (set_attr "predicable_short_it" "no")
6233 (set_attr "length" "4")
6234 (set_attr "type" "mov_imm")]
6237 (define_insn "*arm_movsi_insn"
6238 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6239 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6240 "TARGET_ARM && ! TARGET_IWMMXT
6241 && !(TARGET_HARD_FLOAT && TARGET_VFP)
6242 && ( register_operand (operands[0], SImode)
6243 || register_operand (operands[1], SImode))"
6251 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6252 (set_attr "predicable" "yes")
6253 (set_attr "pool_range" "*,*,*,*,4096,*")
6254 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6258 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6259 (match_operand:SI 1 "const_int_operand" ""))]
6261 && (!(const_ok_for_arm (INTVAL (operands[1]))
6262 || const_ok_for_arm (~INTVAL (operands[1]))))"
6263 [(clobber (const_int 0))]
6265 arm_split_constant (SET, SImode, NULL_RTX,
6266 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6271 ;; A normal way to do (symbol + offset) requires three instructions at least
6272 ;; (depends on how big the offset is) as below:
6273 ;; movw r0, #:lower16:g
6274 ;; movw r0, #:upper16:g
6277 ;; A better way would be:
6278 ;; movw r0, #:lower16:g+4
6279 ;; movw r0, #:upper16:g+4
6281 ;; The limitation of this way is that the length of offset should be a 16-bit
6282 ;; signed value, because current assembler only supports REL type relocation for
6283 ;; such case. If the more powerful RELA type is supported in future, we should
6284 ;; update this pattern to go with better way.
6286 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6287 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6288 (match_operand:SI 2 "const_int_operand" ""))))]
6290 && arm_disable_literal_pool
6292 && GET_CODE (operands[1]) == SYMBOL_REF"
6293 [(clobber (const_int 0))]
6295 int offset = INTVAL (operands[2]);
6297 if (offset < -0x8000 || offset > 0x7fff)
6299 arm_emit_movpair (operands[0], operands[1]);
6300 emit_insn (gen_rtx_SET (SImode, operands[0],
6301 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6305 rtx op = gen_rtx_CONST (SImode,
6306 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6307 arm_emit_movpair (operands[0], op);
6312 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6313 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6314 ;; and lo_sum would be merged back into memory load at cprop. However,
6315 ;; if the default is to prefer movt/movw rather than a load from the constant
6316 ;; pool, the performance is better.
6318 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6319 (match_operand:SI 1 "general_operand" ""))]
6321 && TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6322 && !flag_pic && !target_word_relocations
6323 && !arm_tls_referenced_p (operands[1])"
6324 [(clobber (const_int 0))]
6326 arm_emit_movpair (operands[0], operands[1]);
6330 (define_insn "*thumb1_movsi_insn"
6331 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*l*h*k")
6332 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*l*h*k"))]
6334 && ( register_operand (operands[0], SImode)
6335 || register_operand (operands[1], SImode))"
6346 [(set_attr "length" "2,2,4,4,2,2,2,2,2")
6347 (set_attr "type" "mov_reg,mov_imm,multiple,multiple,load1,store1,load1,store1,mov_reg")
6348 (set_attr "pool_range" "*,*,*,*,*,*,1018,*,*")
6349 (set_attr "conds" "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")])
6352 [(set (match_operand:SI 0 "register_operand" "")
6353 (match_operand:SI 1 "const_int_operand" ""))]
6354 "TARGET_THUMB1 && satisfies_constraint_J (operands[1])"
6355 [(set (match_dup 2) (match_dup 1))
6356 (set (match_dup 0) (neg:SI (match_dup 2)))]
6359 operands[1] = GEN_INT (- INTVAL (operands[1]));
6360 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6365 [(set (match_operand:SI 0 "register_operand" "")
6366 (match_operand:SI 1 "const_int_operand" ""))]
6367 "TARGET_THUMB1 && satisfies_constraint_K (operands[1])"
6368 [(set (match_dup 2) (match_dup 1))
6369 (set (match_dup 0) (ashift:SI (match_dup 2) (match_dup 3)))]
6372 unsigned HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffffffffu;
6373 unsigned HOST_WIDE_INT mask = 0xff;
6376 for (i = 0; i < 25; i++)
6377 if ((val & (mask << i)) == val)
6380 /* Don't split if the shift is zero. */
6384 operands[1] = GEN_INT (val >> i);
6385 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6386 operands[3] = GEN_INT (i);
6390 ;; For thumb1 split imm move [256-510] into mov [1-255] and add #255
6392 [(set (match_operand:SI 0 "register_operand" "")
6393 (match_operand:SI 1 "const_int_operand" ""))]
6394 "TARGET_THUMB1 && satisfies_constraint_Pe (operands[1])"
6395 [(set (match_dup 2) (match_dup 1))
6396 (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 3)))]
6399 operands[1] = GEN_INT (INTVAL (operands[1]) - 255);
6400 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6401 operands[3] = GEN_INT (255);
6405 ;; When generating pic, we need to load the symbol offset into a register.
6406 ;; So that the optimizer does not confuse this with a normal symbol load
6407 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6408 ;; since that is the only type of relocation we can use.
6410 ;; Wrap calculation of the whole PIC address in a single pattern for the
6411 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6412 ;; a PIC address involves two loads from memory, so we want to CSE it
6413 ;; as often as possible.
6414 ;; This pattern will be split into one of the pic_load_addr_* patterns
6415 ;; and a move after GCSE optimizations.
6417 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6418 (define_expand "calculate_pic_address"
6419 [(set (match_operand:SI 0 "register_operand" "")
6420 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6421 (unspec:SI [(match_operand:SI 2 "" "")]
6426 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6428 [(set (match_operand:SI 0 "register_operand" "")
6429 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6430 (unspec:SI [(match_operand:SI 2 "" "")]
6433 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6434 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6435 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6438 ;; operand1 is the memory address to go into
6439 ;; pic_load_addr_32bit.
6440 ;; operand2 is the PIC label to be emitted
6441 ;; from pic_add_dot_plus_eight.
6442 ;; We do this to allow hoisting of the entire insn.
6443 (define_insn_and_split "pic_load_addr_unified"
6444 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6445 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6446 (match_operand:SI 2 "" "")]
6447 UNSPEC_PIC_UNIFIED))]
6450 "&& reload_completed"
6451 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6452 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6453 (match_dup 2)] UNSPEC_PIC_BASE))]
6454 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6455 [(set_attr "type" "load1,load1,load1")
6456 (set_attr "pool_range" "4096,4094,1022")
6457 (set_attr "neg_pool_range" "4084,0,0")
6458 (set_attr "arch" "a,t2,t1")
6459 (set_attr "length" "8,6,4")]
6462 ;; The rather odd constraints on the following are to force reload to leave
6463 ;; the insn alone, and to force the minipool generation pass to then move
6464 ;; the GOT symbol to memory.
6466 (define_insn "pic_load_addr_32bit"
6467 [(set (match_operand:SI 0 "s_register_operand" "=r")
6468 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6469 "TARGET_32BIT && flag_pic"
6471 [(set_attr "type" "load1")
6472 (set (attr "pool_range")
6473 (if_then_else (eq_attr "is_thumb" "no")
6476 (set (attr "neg_pool_range")
6477 (if_then_else (eq_attr "is_thumb" "no")
6482 (define_insn "pic_load_addr_thumb1"
6483 [(set (match_operand:SI 0 "s_register_operand" "=l")
6484 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6485 "TARGET_THUMB1 && flag_pic"
6487 [(set_attr "type" "load1")
6488 (set (attr "pool_range") (const_int 1018))]
6491 (define_insn "pic_add_dot_plus_four"
6492 [(set (match_operand:SI 0 "register_operand" "=r")
6493 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6495 (match_operand 2 "" "")]
6499 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6500 INTVAL (operands[2]));
6501 return \"add\\t%0, %|pc\";
6503 [(set_attr "length" "2")
6504 (set_attr "type" "alu_reg")]
6507 (define_insn "pic_add_dot_plus_eight"
6508 [(set (match_operand:SI 0 "register_operand" "=r")
6509 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6511 (match_operand 2 "" "")]
6515 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6516 INTVAL (operands[2]));
6517 return \"add%?\\t%0, %|pc, %1\";
6519 [(set_attr "predicable" "yes")
6520 (set_attr "type" "alu_reg")]
6523 (define_insn "tls_load_dot_plus_eight"
6524 [(set (match_operand:SI 0 "register_operand" "=r")
6525 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6527 (match_operand 2 "" "")]
6531 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6532 INTVAL (operands[2]));
6533 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6535 [(set_attr "predicable" "yes")
6536 (set_attr "type" "load1")]
6539 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6540 ;; followed by a load. These sequences can be crunched down to
6541 ;; tls_load_dot_plus_eight by a peephole.
6544 [(set (match_operand:SI 0 "register_operand" "")
6545 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6547 (match_operand 1 "" "")]
6549 (set (match_operand:SI 2 "arm_general_register_operand" "")
6550 (mem:SI (match_dup 0)))]
6551 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6553 (mem:SI (unspec:SI [(match_dup 3)
6560 (define_insn "pic_offset_arm"
6561 [(set (match_operand:SI 0 "register_operand" "=r")
6562 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6563 (unspec:SI [(match_operand:SI 2 "" "X")]
6564 UNSPEC_PIC_OFFSET))))]
6565 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6566 "ldr%?\\t%0, [%1,%2]"
6567 [(set_attr "type" "load1")]
6570 (define_expand "builtin_setjmp_receiver"
6571 [(label_ref (match_operand 0 "" ""))]
6575 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6577 if (arm_pic_register != INVALID_REGNUM)
6578 arm_load_pic_register (1UL << 3);
6582 ;; If copying one reg to another we can set the condition codes according to
6583 ;; its value. Such a move is common after a return from subroutine and the
6584 ;; result is being tested against zero.
6586 (define_insn "*movsi_compare0"
6587 [(set (reg:CC CC_REGNUM)
6588 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6590 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6596 [(set_attr "conds" "set")
6597 (set_attr "type" "alus_imm,alus_imm")]
6600 ;; Subroutine to store a half word from a register into memory.
6601 ;; Operand 0 is the source register (HImode)
6602 ;; Operand 1 is the destination address in a register (SImode)
6604 ;; In both this routine and the next, we must be careful not to spill
6605 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6606 ;; can generate unrecognizable rtl.
6608 (define_expand "storehi"
6609 [;; store the low byte
6610 (set (match_operand 1 "" "") (match_dup 3))
6611 ;; extract the high byte
6613 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6614 ;; store the high byte
6615 (set (match_dup 4) (match_dup 5))]
6619 rtx op1 = operands[1];
6620 rtx addr = XEXP (op1, 0);
6621 enum rtx_code code = GET_CODE (addr);
6623 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6625 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6627 operands[4] = adjust_address (op1, QImode, 1);
6628 operands[1] = adjust_address (operands[1], QImode, 0);
6629 operands[3] = gen_lowpart (QImode, operands[0]);
6630 operands[0] = gen_lowpart (SImode, operands[0]);
6631 operands[2] = gen_reg_rtx (SImode);
6632 operands[5] = gen_lowpart (QImode, operands[2]);
6636 (define_expand "storehi_bigend"
6637 [(set (match_dup 4) (match_dup 3))
6639 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6640 (set (match_operand 1 "" "") (match_dup 5))]
6644 rtx op1 = operands[1];
6645 rtx addr = XEXP (op1, 0);
6646 enum rtx_code code = GET_CODE (addr);
6648 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6650 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6652 operands[4] = adjust_address (op1, QImode, 1);
6653 operands[1] = adjust_address (operands[1], QImode, 0);
6654 operands[3] = gen_lowpart (QImode, operands[0]);
6655 operands[0] = gen_lowpart (SImode, operands[0]);
6656 operands[2] = gen_reg_rtx (SImode);
6657 operands[5] = gen_lowpart (QImode, operands[2]);
6661 ;; Subroutine to store a half word integer constant into memory.
6662 (define_expand "storeinthi"
6663 [(set (match_operand 0 "" "")
6664 (match_operand 1 "" ""))
6665 (set (match_dup 3) (match_dup 2))]
6669 HOST_WIDE_INT value = INTVAL (operands[1]);
6670 rtx addr = XEXP (operands[0], 0);
6671 rtx op0 = operands[0];
6672 enum rtx_code code = GET_CODE (addr);
6674 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6676 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6678 operands[1] = gen_reg_rtx (SImode);
6679 if (BYTES_BIG_ENDIAN)
6681 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6682 if ((value & 255) == ((value >> 8) & 255))
6683 operands[2] = operands[1];
6686 operands[2] = gen_reg_rtx (SImode);
6687 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6692 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6693 if ((value & 255) == ((value >> 8) & 255))
6694 operands[2] = operands[1];
6697 operands[2] = gen_reg_rtx (SImode);
6698 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6702 operands[3] = adjust_address (op0, QImode, 1);
6703 operands[0] = adjust_address (operands[0], QImode, 0);
6704 operands[2] = gen_lowpart (QImode, operands[2]);
6705 operands[1] = gen_lowpart (QImode, operands[1]);
6709 (define_expand "storehi_single_op"
6710 [(set (match_operand:HI 0 "memory_operand" "")
6711 (match_operand:HI 1 "general_operand" ""))]
6712 "TARGET_32BIT && arm_arch4"
6714 if (!s_register_operand (operands[1], HImode))
6715 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6719 (define_expand "movhi"
6720 [(set (match_operand:HI 0 "general_operand" "")
6721 (match_operand:HI 1 "general_operand" ""))]
6726 if (can_create_pseudo_p ())
6728 if (MEM_P (operands[0]))
6732 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6735 if (CONST_INT_P (operands[1]))
6736 emit_insn (gen_storeinthi (operands[0], operands[1]));
6739 if (MEM_P (operands[1]))
6740 operands[1] = force_reg (HImode, operands[1]);
6741 if (BYTES_BIG_ENDIAN)
6742 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6744 emit_insn (gen_storehi (operands[1], operands[0]));
6748 /* Sign extend a constant, and keep it in an SImode reg. */
6749 else if (CONST_INT_P (operands[1]))
6751 rtx reg = gen_reg_rtx (SImode);
6752 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6754 /* If the constant is already valid, leave it alone. */
6755 if (!const_ok_for_arm (val))
6757 /* If setting all the top bits will make the constant
6758 loadable in a single instruction, then set them.
6759 Otherwise, sign extend the number. */
6761 if (const_ok_for_arm (~(val | ~0xffff)))
6763 else if (val & 0x8000)
6767 emit_insn (gen_movsi (reg, GEN_INT (val)));
6768 operands[1] = gen_lowpart (HImode, reg);
6770 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6771 && MEM_P (operands[1]))
6773 rtx reg = gen_reg_rtx (SImode);
6775 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6776 operands[1] = gen_lowpart (HImode, reg);
6778 else if (!arm_arch4)
6780 if (MEM_P (operands[1]))
6783 rtx offset = const0_rtx;
6784 rtx reg = gen_reg_rtx (SImode);
6786 if ((REG_P (base = XEXP (operands[1], 0))
6787 || (GET_CODE (base) == PLUS
6788 && (CONST_INT_P (offset = XEXP (base, 1)))
6789 && ((INTVAL(offset) & 1) != 1)
6790 && REG_P (base = XEXP (base, 0))))
6791 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6795 new_rtx = widen_memory_access (operands[1], SImode,
6796 ((INTVAL (offset) & ~3)
6797 - INTVAL (offset)));
6798 emit_insn (gen_movsi (reg, new_rtx));
6799 if (((INTVAL (offset) & 2) != 0)
6800 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6802 rtx reg2 = gen_reg_rtx (SImode);
6804 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6809 emit_insn (gen_movhi_bytes (reg, operands[1]));
6811 operands[1] = gen_lowpart (HImode, reg);
6815 /* Handle loading a large integer during reload. */
6816 else if (CONST_INT_P (operands[1])
6817 && !const_ok_for_arm (INTVAL (operands[1]))
6818 && !const_ok_for_arm (~INTVAL (operands[1])))
6820 /* Writing a constant to memory needs a scratch, which should
6821 be handled with SECONDARY_RELOADs. */
6822 gcc_assert (REG_P (operands[0]));
6824 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6825 emit_insn (gen_movsi (operands[0], operands[1]));
6829 else if (TARGET_THUMB2)
6831 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6832 if (can_create_pseudo_p ())
6834 if (!REG_P (operands[0]))
6835 operands[1] = force_reg (HImode, operands[1]);
6836 /* Zero extend a constant, and keep it in an SImode reg. */
6837 else if (CONST_INT_P (operands[1]))
6839 rtx reg = gen_reg_rtx (SImode);
6840 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6842 emit_insn (gen_movsi (reg, GEN_INT (val)));
6843 operands[1] = gen_lowpart (HImode, reg);
6847 else /* TARGET_THUMB1 */
6849 if (can_create_pseudo_p ())
6851 if (CONST_INT_P (operands[1]))
6853 rtx reg = gen_reg_rtx (SImode);
6855 emit_insn (gen_movsi (reg, operands[1]));
6856 operands[1] = gen_lowpart (HImode, reg);
6859 /* ??? We shouldn't really get invalid addresses here, but this can
6860 happen if we are passed a SP (never OK for HImode/QImode) or
6861 virtual register (also rejected as illegitimate for HImode/QImode)
6862 relative address. */
6863 /* ??? This should perhaps be fixed elsewhere, for instance, in
6864 fixup_stack_1, by checking for other kinds of invalid addresses,
6865 e.g. a bare reference to a virtual register. This may confuse the
6866 alpha though, which must handle this case differently. */
6867 if (MEM_P (operands[0])
6868 && !memory_address_p (GET_MODE (operands[0]),
6869 XEXP (operands[0], 0)))
6871 = replace_equiv_address (operands[0],
6872 copy_to_reg (XEXP (operands[0], 0)));
6874 if (MEM_P (operands[1])
6875 && !memory_address_p (GET_MODE (operands[1]),
6876 XEXP (operands[1], 0)))
6878 = replace_equiv_address (operands[1],
6879 copy_to_reg (XEXP (operands[1], 0)));
6881 if (MEM_P (operands[1]) && optimize > 0)
6883 rtx reg = gen_reg_rtx (SImode);
6885 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6886 operands[1] = gen_lowpart (HImode, reg);
6889 if (MEM_P (operands[0]))
6890 operands[1] = force_reg (HImode, operands[1]);
6892 else if (CONST_INT_P (operands[1])
6893 && !satisfies_constraint_I (operands[1]))
6895 /* Handle loading a large integer during reload. */
6897 /* Writing a constant to memory needs a scratch, which should
6898 be handled with SECONDARY_RELOADs. */
6899 gcc_assert (REG_P (operands[0]));
6901 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6902 emit_insn (gen_movsi (operands[0], operands[1]));
6909 (define_insn "*thumb1_movhi_insn"
6910 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
6911 (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
6913 && ( register_operand (operands[0], HImode)
6914 || register_operand (operands[1], HImode))"
6916 switch (which_alternative)
6918 case 0: return \"add %0, %1, #0\";
6919 case 2: return \"strh %1, %0\";
6920 case 3: return \"mov %0, %1\";
6921 case 4: return \"mov %0, %1\";
6922 case 5: return \"mov %0, %1\";
6923 default: gcc_unreachable ();
6925 /* The stack pointer can end up being taken as an index register.
6926 Catch this case here and deal with it. */
6927 if (GET_CODE (XEXP (operands[1], 0)) == PLUS
6928 && REG_P (XEXP (XEXP (operands[1], 0), 0))
6929 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM)
6932 ops[0] = operands[0];
6933 ops[1] = XEXP (XEXP (operands[1], 0), 0);
6935 output_asm_insn (\"mov %0, %1\", ops);
6937 XEXP (XEXP (operands[1], 0), 0) = operands[0];
6940 return \"ldrh %0, %1\";
6942 [(set_attr "length" "2,4,2,2,2,2")
6943 (set_attr "type" "alus_imm,load1,store1,mov_reg,mov_reg,mov_imm")
6944 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
6947 (define_expand "movhi_bytes"
6948 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6950 (zero_extend:SI (match_dup 6)))
6951 (set (match_operand:SI 0 "" "")
6952 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6957 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6959 mem1 = change_address (operands[1], QImode, addr);
6960 mem2 = change_address (operands[1], QImode,
6961 plus_constant (Pmode, addr, 1));
6962 operands[0] = gen_lowpart (SImode, operands[0]);
6964 operands[2] = gen_reg_rtx (SImode);
6965 operands[3] = gen_reg_rtx (SImode);
6968 if (BYTES_BIG_ENDIAN)
6970 operands[4] = operands[2];
6971 operands[5] = operands[3];
6975 operands[4] = operands[3];
6976 operands[5] = operands[2];
6981 (define_expand "movhi_bigend"
6983 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6986 (ashiftrt:SI (match_dup 2) (const_int 16)))
6987 (set (match_operand:HI 0 "s_register_operand" "")
6991 operands[2] = gen_reg_rtx (SImode);
6992 operands[3] = gen_reg_rtx (SImode);
6993 operands[4] = gen_lowpart (HImode, operands[3]);
6997 ;; Pattern to recognize insn generated default case above
6998 (define_insn "*movhi_insn_arch4"
6999 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
7000 (match_operand:HI 1 "general_operand" "rI,K,n,r,mi"))]
7003 && (register_operand (operands[0], HImode)
7004 || register_operand (operands[1], HImode))"
7006 mov%?\\t%0, %1\\t%@ movhi
7007 mvn%?\\t%0, #%B1\\t%@ movhi
7008 movw%?\\t%0, %L1\\t%@ movhi
7009 str%(h%)\\t%1, %0\\t%@ movhi
7010 ldr%(h%)\\t%0, %1\\t%@ movhi"
7011 [(set_attr "predicable" "yes")
7012 (set_attr "pool_range" "*,*,*,*,256")
7013 (set_attr "neg_pool_range" "*,*,*,*,244")
7014 (set_attr "arch" "*,*,v6t2,*,*")
7015 (set_attr_alternative "type"
7016 [(if_then_else (match_operand 1 "const_int_operand" "")
7017 (const_string "mov_imm" )
7018 (const_string "mov_reg"))
7019 (const_string "mvn_imm")
7020 (const_string "mov_imm")
7021 (const_string "store1")
7022 (const_string "load1")])]
7025 (define_insn "*movhi_bytes"
7026 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
7027 (match_operand:HI 1 "arm_rhs_operand" "I,r,K"))]
7030 mov%?\\t%0, %1\\t%@ movhi
7031 mov%?\\t%0, %1\\t%@ movhi
7032 mvn%?\\t%0, #%B1\\t%@ movhi"
7033 [(set_attr "predicable" "yes")
7034 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
7037 (define_expand "thumb_movhi_clobber"
7038 [(set (match_operand:HI 0 "memory_operand" "")
7039 (match_operand:HI 1 "register_operand" ""))
7040 (clobber (match_operand:DI 2 "register_operand" ""))]
7043 if (strict_memory_address_p (HImode, XEXP (operands[0], 0))
7044 && REGNO (operands[1]) <= LAST_LO_REGNUM)
7046 emit_insn (gen_movhi (operands[0], operands[1]));
7049 /* XXX Fixme, need to handle other cases here as well. */
7054 ;; We use a DImode scratch because we may occasionally need an additional
7055 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
7056 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
7057 (define_expand "reload_outhi"
7058 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
7059 (match_operand:HI 1 "s_register_operand" "r")
7060 (match_operand:DI 2 "s_register_operand" "=&l")])]
7063 arm_reload_out_hi (operands);
7065 thumb_reload_out_hi (operands);
7070 (define_expand "reload_inhi"
7071 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
7072 (match_operand:HI 1 "arm_reload_memory_operand" "o")
7073 (match_operand:DI 2 "s_register_operand" "=&r")])]
7077 arm_reload_in_hi (operands);
7079 thumb_reload_out_hi (operands);
7083 (define_expand "movqi"
7084 [(set (match_operand:QI 0 "general_operand" "")
7085 (match_operand:QI 1 "general_operand" ""))]
7088 /* Everything except mem = const or mem = mem can be done easily */
7090 if (can_create_pseudo_p ())
7092 if (CONST_INT_P (operands[1]))
7094 rtx reg = gen_reg_rtx (SImode);
7096 /* For thumb we want an unsigned immediate, then we are more likely
7097 to be able to use a movs insn. */
7099 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
7101 emit_insn (gen_movsi (reg, operands[1]));
7102 operands[1] = gen_lowpart (QImode, reg);
7107 /* ??? We shouldn't really get invalid addresses here, but this can
7108 happen if we are passed a SP (never OK for HImode/QImode) or
7109 virtual register (also rejected as illegitimate for HImode/QImode)
7110 relative address. */
7111 /* ??? This should perhaps be fixed elsewhere, for instance, in
7112 fixup_stack_1, by checking for other kinds of invalid addresses,
7113 e.g. a bare reference to a virtual register. This may confuse the
7114 alpha though, which must handle this case differently. */
7115 if (MEM_P (operands[0])
7116 && !memory_address_p (GET_MODE (operands[0]),
7117 XEXP (operands[0], 0)))
7119 = replace_equiv_address (operands[0],
7120 copy_to_reg (XEXP (operands[0], 0)));
7121 if (MEM_P (operands[1])
7122 && !memory_address_p (GET_MODE (operands[1]),
7123 XEXP (operands[1], 0)))
7125 = replace_equiv_address (operands[1],
7126 copy_to_reg (XEXP (operands[1], 0)));
7129 if (MEM_P (operands[1]) && optimize > 0)
7131 rtx reg = gen_reg_rtx (SImode);
7133 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
7134 operands[1] = gen_lowpart (QImode, reg);
7137 if (MEM_P (operands[0]))
7138 operands[1] = force_reg (QImode, operands[1]);
7140 else if (TARGET_THUMB
7141 && CONST_INT_P (operands[1])
7142 && !satisfies_constraint_I (operands[1]))
7144 /* Handle loading a large integer during reload. */
7146 /* Writing a constant to memory needs a scratch, which should
7147 be handled with SECONDARY_RELOADs. */
7148 gcc_assert (REG_P (operands[0]));
7150 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
7151 emit_insn (gen_movsi (operands[0], operands[1]));
7157 (define_insn "*arm_movqi_insn"
7158 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
7159 (match_operand:QI 1 "general_operand" "r,r,I,Py,K,Uu,l,m,r"))]
7161 && ( register_operand (operands[0], QImode)
7162 || register_operand (operands[1], QImode))"
7173 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
7174 (set_attr "predicable" "yes")
7175 (set_attr "predicable_short_it" "yes,yes,yes,no,no,no,no,no,no")
7176 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
7177 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
7180 (define_insn "*thumb1_movqi_insn"
7181 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
7182 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))]
7184 && ( register_operand (operands[0], QImode)
7185 || register_operand (operands[1], QImode))"
7193 [(set_attr "length" "2")
7194 (set_attr "type" "alu_imm,load1,store1,mov_reg,mov_imm,mov_imm")
7195 (set_attr "pool_range" "*,32,*,*,*,*")
7196 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
7199 (define_expand "movhf"
7200 [(set (match_operand:HF 0 "general_operand" "")
7201 (match_operand:HF 1 "general_operand" ""))]
7206 if (MEM_P (operands[0]))
7207 operands[1] = force_reg (HFmode, operands[1]);
7209 else /* TARGET_THUMB1 */
7211 if (can_create_pseudo_p ())
7213 if (!REG_P (operands[0]))
7214 operands[1] = force_reg (HFmode, operands[1]);
7220 (define_insn "*arm32_movhf"
7221 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
7222 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
7223 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16) && !arm_restrict_it
7224 && ( s_register_operand (operands[0], HFmode)
7225 || s_register_operand (operands[1], HFmode))"
7227 switch (which_alternative)
7229 case 0: /* ARM register from memory */
7230 return \"ldr%(h%)\\t%0, %1\\t%@ __fp16\";
7231 case 1: /* memory from ARM register */
7232 return \"str%(h%)\\t%1, %0\\t%@ __fp16\";
7233 case 2: /* ARM register from ARM register */
7234 return \"mov%?\\t%0, %1\\t%@ __fp16\";
7235 case 3: /* ARM register from constant */
7241 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
7242 bits = real_to_target (NULL, &r, HFmode);
7243 ops[0] = operands[0];
7244 ops[1] = GEN_INT (bits);
7245 ops[2] = GEN_INT (bits & 0xff00);
7246 ops[3] = GEN_INT (bits & 0x00ff);
7248 if (arm_arch_thumb2)
7249 output_asm_insn (\"movw%?\\t%0, %1\", ops);
7251 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
7258 [(set_attr "conds" "unconditional")
7259 (set_attr "type" "load1,store1,mov_reg,multiple")
7260 (set_attr "length" "4,4,4,8")
7261 (set_attr "predicable" "yes")]
7264 (define_insn "*thumb1_movhf"
7265 [(set (match_operand:HF 0 "nonimmediate_operand" "=l,l,m,*r,*h")
7266 (match_operand:HF 1 "general_operand" "l,mF,l,*h,*r"))]
7268 && ( s_register_operand (operands[0], HFmode)
7269 || s_register_operand (operands[1], HFmode))"
7271 switch (which_alternative)
7276 gcc_assert (MEM_P (operands[1]));
7277 addr = XEXP (operands[1], 0);
7278 if (GET_CODE (addr) == LABEL_REF
7279 || (GET_CODE (addr) == CONST
7280 && GET_CODE (XEXP (addr, 0)) == PLUS
7281 && GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF
7282 && CONST_INT_P (XEXP (XEXP (addr, 0), 1))))
7284 /* Constant pool entry. */
7285 return \"ldr\\t%0, %1\";
7287 return \"ldrh\\t%0, %1\";
7289 case 2: return \"strh\\t%1, %0\";
7290 default: return \"mov\\t%0, %1\";
7293 [(set_attr "length" "2")
7294 (set_attr "type" "mov_reg,load1,store1,mov_reg,mov_reg")
7295 (set_attr "pool_range" "*,1018,*,*,*")
7296 (set_attr "conds" "clob,nocond,nocond,nocond,nocond")])
7298 (define_expand "movsf"
7299 [(set (match_operand:SF 0 "general_operand" "")
7300 (match_operand:SF 1 "general_operand" ""))]
7305 if (MEM_P (operands[0]))
7306 operands[1] = force_reg (SFmode, operands[1]);
7308 else /* TARGET_THUMB1 */
7310 if (can_create_pseudo_p ())
7312 if (!REG_P (operands[0]))
7313 operands[1] = force_reg (SFmode, operands[1]);
7319 ;; Transform a floating-point move of a constant into a core register into
7320 ;; an SImode operation.
7322 [(set (match_operand:SF 0 "arm_general_register_operand" "")
7323 (match_operand:SF 1 "immediate_operand" ""))]
7326 && CONST_DOUBLE_P (operands[1])"
7327 [(set (match_dup 2) (match_dup 3))]
7329 operands[2] = gen_lowpart (SImode, operands[0]);
7330 operands[3] = gen_lowpart (SImode, operands[1]);
7331 if (operands[2] == 0 || operands[3] == 0)
7336 (define_insn "*arm_movsf_soft_insn"
7337 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7338 (match_operand:SF 1 "general_operand" "r,mE,r"))]
7340 && TARGET_SOFT_FLOAT
7341 && (!MEM_P (operands[0])
7342 || register_operand (operands[1], SFmode))"
7345 ldr%?\\t%0, %1\\t%@ float
7346 str%?\\t%1, %0\\t%@ float"
7347 [(set_attr "predicable" "yes")
7348 (set_attr "predicable_short_it" "no")
7349 (set_attr "type" "mov_reg,load1,store1")
7350 (set_attr "arm_pool_range" "*,4096,*")
7351 (set_attr "thumb2_pool_range" "*,4094,*")
7352 (set_attr "arm_neg_pool_range" "*,4084,*")
7353 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7356 ;;; ??? This should have alternatives for constants.
7357 (define_insn "*thumb1_movsf_insn"
7358 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h")
7359 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))]
7361 && ( register_operand (operands[0], SFmode)
7362 || register_operand (operands[1], SFmode))"
7371 [(set_attr "length" "2")
7372 (set_attr "type" "alus_imm,load1,store1,load1,store1,mov_reg,mov_reg")
7373 (set_attr "pool_range" "*,*,*,1018,*,*,*")
7374 (set_attr "conds" "clob,nocond,nocond,nocond,nocond,nocond,nocond")]
7377 (define_expand "movdf"
7378 [(set (match_operand:DF 0 "general_operand" "")
7379 (match_operand:DF 1 "general_operand" ""))]
7384 if (MEM_P (operands[0]))
7385 operands[1] = force_reg (DFmode, operands[1]);
7387 else /* TARGET_THUMB */
7389 if (can_create_pseudo_p ())
7391 if (!REG_P (operands[0]))
7392 operands[1] = force_reg (DFmode, operands[1]);
7398 ;; Reloading a df mode value stored in integer regs to memory can require a
7400 (define_expand "reload_outdf"
7401 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7402 (match_operand:DF 1 "s_register_operand" "r")
7403 (match_operand:SI 2 "s_register_operand" "=&r")]
7407 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7410 operands[2] = XEXP (operands[0], 0);
7411 else if (code == POST_INC || code == PRE_DEC)
7413 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7414 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7415 emit_insn (gen_movdi (operands[0], operands[1]));
7418 else if (code == PRE_INC)
7420 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7422 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7425 else if (code == POST_DEC)
7426 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7428 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7429 XEXP (XEXP (operands[0], 0), 1)));
7431 emit_insn (gen_rtx_SET (VOIDmode,
7432 replace_equiv_address (operands[0], operands[2]),
7435 if (code == POST_DEC)
7436 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7442 (define_insn "*movdf_soft_insn"
7443 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7444 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7445 "TARGET_32BIT && TARGET_SOFT_FLOAT
7446 && ( register_operand (operands[0], DFmode)
7447 || register_operand (operands[1], DFmode))"
7449 switch (which_alternative)
7456 return output_move_double (operands, true, NULL);
7459 [(set_attr "length" "8,12,16,8,8")
7460 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7461 (set_attr "arm_pool_range" "*,*,*,1020,*")
7462 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7463 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7464 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7467 ;;; ??? This should have alternatives for constants.
7468 ;;; ??? This was originally identical to the movdi_insn pattern.
7469 ;;; ??? The 'F' constraint looks funny, but it should always be replaced by
7470 ;;; thumb_reorg with a memory reference.
7471 (define_insn "*thumb_movdf_insn"
7472 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r")
7473 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))]
7475 && ( register_operand (operands[0], DFmode)
7476 || register_operand (operands[1], DFmode))"
7478 switch (which_alternative)
7482 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
7483 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\";
7484 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\";
7486 return \"ldmia\\t%1, {%0, %H0}\";
7488 return \"stmia\\t%0, {%1, %H1}\";
7490 return thumb_load_double_from_address (operands);
7492 operands[2] = gen_rtx_MEM (SImode,
7493 plus_constant (Pmode,
7494 XEXP (operands[0], 0), 4));
7495 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands);
7498 if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
7499 return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
7500 return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
7503 [(set_attr "length" "4,2,2,6,4,4")
7504 (set_attr "type" "multiple,load2,store2,load2,store2,multiple")
7505 (set_attr "pool_range" "*,*,*,1018,*,*")]
7509 ;; load- and store-multiple insns
7510 ;; The arm can load/store any set of registers, provided that they are in
7511 ;; ascending order, but these expanders assume a contiguous set.
7513 (define_expand "load_multiple"
7514 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7515 (match_operand:SI 1 "" ""))
7516 (use (match_operand:SI 2 "" ""))])]
7519 HOST_WIDE_INT offset = 0;
7521 /* Support only fixed point registers. */
7522 if (!CONST_INT_P (operands[2])
7523 || INTVAL (operands[2]) > 14
7524 || INTVAL (operands[2]) < 2
7525 || !MEM_P (operands[1])
7526 || !REG_P (operands[0])
7527 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7528 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7532 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7533 INTVAL (operands[2]),
7534 force_reg (SImode, XEXP (operands[1], 0)),
7535 FALSE, operands[1], &offset);
7538 (define_expand "store_multiple"
7539 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7540 (match_operand:SI 1 "" ""))
7541 (use (match_operand:SI 2 "" ""))])]
7544 HOST_WIDE_INT offset = 0;
7546 /* Support only fixed point registers. */
7547 if (!CONST_INT_P (operands[2])
7548 || INTVAL (operands[2]) > 14
7549 || INTVAL (operands[2]) < 2
7550 || !REG_P (operands[1])
7551 || !MEM_P (operands[0])
7552 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7553 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7557 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7558 INTVAL (operands[2]),
7559 force_reg (SImode, XEXP (operands[0], 0)),
7560 FALSE, operands[0], &offset);
7564 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7565 ;; We could let this apply for blocks of less than this, but it clobbers so
7566 ;; many registers that there is then probably a better way.
7568 (define_expand "movmemqi"
7569 [(match_operand:BLK 0 "general_operand" "")
7570 (match_operand:BLK 1 "general_operand" "")
7571 (match_operand:SI 2 "const_int_operand" "")
7572 (match_operand:SI 3 "const_int_operand" "")]
7577 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7578 && !optimize_function_for_size_p (cfun))
7580 if (gen_movmem_ldrd_strd (operands))
7585 if (arm_gen_movmemqi (operands))
7589 else /* TARGET_THUMB1 */
7591 if ( INTVAL (operands[3]) != 4
7592 || INTVAL (operands[2]) > 48)
7595 thumb_expand_movmemqi (operands);
7601 ;; Thumb block-move insns
7603 (define_insn "movmem12b"
7604 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
7605 (mem:SI (match_operand:SI 3 "register_operand" "1")))
7606 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
7607 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
7608 (set (mem:SI (plus:SI (match_dup 2) (const_int 8)))
7609 (mem:SI (plus:SI (match_dup 3) (const_int 8))))
7610 (set (match_operand:SI 0 "register_operand" "=l")
7611 (plus:SI (match_dup 2) (const_int 12)))
7612 (set (match_operand:SI 1 "register_operand" "=l")
7613 (plus:SI (match_dup 3) (const_int 12)))
7614 (clobber (match_scratch:SI 4 "=&l"))
7615 (clobber (match_scratch:SI 5 "=&l"))
7616 (clobber (match_scratch:SI 6 "=&l"))]
7618 "* return thumb_output_move_mem_multiple (3, operands);"
7619 [(set_attr "length" "4")
7620 ; This isn't entirely accurate... It loads as well, but in terms of
7621 ; scheduling the following insn it is better to consider it as a store
7622 (set_attr "type" "store3")]
7625 (define_insn "movmem8b"
7626 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
7627 (mem:SI (match_operand:SI 3 "register_operand" "1")))
7628 (set (mem:SI (plus:SI (match_dup 2) (const_int 4)))
7629 (mem:SI (plus:SI (match_dup 3) (const_int 4))))
7630 (set (match_operand:SI 0 "register_operand" "=l")
7631 (plus:SI (match_dup 2) (const_int 8)))
7632 (set (match_operand:SI 1 "register_operand" "=l")
7633 (plus:SI (match_dup 3) (const_int 8)))
7634 (clobber (match_scratch:SI 4 "=&l"))
7635 (clobber (match_scratch:SI 5 "=&l"))]
7637 "* return thumb_output_move_mem_multiple (2, operands);"
7638 [(set_attr "length" "4")
7639 ; This isn't entirely accurate... It loads as well, but in terms of
7640 ; scheduling the following insn it is better to consider it as a store
7641 (set_attr "type" "store2")]
7646 ;; Compare & branch insns
7647 ;; The range calculations are based as follows:
7648 ;; For forward branches, the address calculation returns the address of
7649 ;; the next instruction. This is 2 beyond the branch instruction.
7650 ;; For backward branches, the address calculation returns the address of
7651 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7652 ;; instruction for the shortest sequence, and 4 before the branch instruction
7653 ;; if we have to jump around an unconditional branch.
7654 ;; To the basic branch range the PC offset must be added (this is +4).
7655 ;; So for forward branches we have
7656 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7657 ;; And for backward branches we have
7658 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7660 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7661 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7663 (define_expand "cbranchsi4"
7664 [(set (pc) (if_then_else
7665 (match_operator 0 "expandable_comparison_operator"
7666 [(match_operand:SI 1 "s_register_operand" "")
7667 (match_operand:SI 2 "nonmemory_operand" "")])
7668 (label_ref (match_operand 3 "" ""))
7674 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7676 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7680 if (thumb1_cmpneg_operand (operands[2], SImode))
7682 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7683 operands[3], operands[0]));
7686 if (!thumb1_cmp_operand (operands[2], SImode))
7687 operands[2] = force_reg (SImode, operands[2]);
7690 ;; A pattern to recognize a special situation and optimize for it.
7691 ;; On the thumb, zero-extension from memory is preferrable to sign-extension
7692 ;; due to the available addressing modes. Hence, convert a signed comparison
7693 ;; with zero into an unsigned comparison with 127 if possible.
7694 (define_expand "cbranchqi4"
7695 [(set (pc) (if_then_else
7696 (match_operator 0 "lt_ge_comparison_operator"
7697 [(match_operand:QI 1 "memory_operand" "")
7698 (match_operand:QI 2 "const0_operand" "")])
7699 (label_ref (match_operand 3 "" ""))
7704 xops[1] = gen_reg_rtx (SImode);
7705 emit_insn (gen_zero_extendqisi2 (xops[1], operands[1]));
7706 xops[2] = GEN_INT (127);
7707 xops[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]) == GE ? LEU : GTU,
7708 VOIDmode, xops[1], xops[2]);
7709 xops[3] = operands[3];
7710 emit_insn (gen_cbranchsi4 (xops[0], xops[1], xops[2], xops[3]));
7714 (define_expand "cbranchsf4"
7715 [(set (pc) (if_then_else
7716 (match_operator 0 "expandable_comparison_operator"
7717 [(match_operand:SF 1 "s_register_operand" "")
7718 (match_operand:SF 2 "arm_float_compare_operand" "")])
7719 (label_ref (match_operand 3 "" ""))
7721 "TARGET_32BIT && TARGET_HARD_FLOAT"
7722 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7723 operands[3])); DONE;"
7726 (define_expand "cbranchdf4"
7727 [(set (pc) (if_then_else
7728 (match_operator 0 "expandable_comparison_operator"
7729 [(match_operand:DF 1 "s_register_operand" "")
7730 (match_operand:DF 2 "arm_float_compare_operand" "")])
7731 (label_ref (match_operand 3 "" ""))
7733 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7734 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7735 operands[3])); DONE;"
7738 (define_expand "cbranchdi4"
7739 [(set (pc) (if_then_else
7740 (match_operator 0 "expandable_comparison_operator"
7741 [(match_operand:DI 1 "s_register_operand" "")
7742 (match_operand:DI 2 "cmpdi_operand" "")])
7743 (label_ref (match_operand 3 "" ""))
7747 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7749 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7755 (define_insn "cbranchsi4_insn"
7756 [(set (pc) (if_then_else
7757 (match_operator 0 "arm_comparison_operator"
7758 [(match_operand:SI 1 "s_register_operand" "l,l*h")
7759 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")])
7760 (label_ref (match_operand 3 "" ""))
7764 rtx t = cfun->machine->thumb1_cc_insn;
7767 if (!rtx_equal_p (cfun->machine->thumb1_cc_op0, operands[1])
7768 || !rtx_equal_p (cfun->machine->thumb1_cc_op1, operands[2]))
7770 if (cfun->machine->thumb1_cc_mode == CC_NOOVmode)
7772 if (!noov_comparison_operator (operands[0], VOIDmode))
7775 else if (cfun->machine->thumb1_cc_mode != CCmode)
7780 output_asm_insn ("cmp\t%1, %2", operands);
7781 cfun->machine->thumb1_cc_insn = insn;
7782 cfun->machine->thumb1_cc_op0 = operands[1];
7783 cfun->machine->thumb1_cc_op1 = operands[2];
7784 cfun->machine->thumb1_cc_mode = CCmode;
7787 /* Ensure we emit the right type of condition code on the jump. */
7788 XEXP (operands[0], 0) = gen_rtx_REG (cfun->machine->thumb1_cc_mode,
7791 switch (get_attr_length (insn))
7793 case 4: return \"b%d0\\t%l3\";
7794 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7795 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7798 [(set (attr "far_jump")
7800 (eq_attr "length" "8")
7801 (const_string "yes")
7802 (const_string "no")))
7803 (set (attr "length")
7805 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7806 (le (minus (match_dup 3) (pc)) (const_int 256)))
7809 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7810 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7813 (set_attr "type" "multiple")]
7816 (define_insn "cbranchsi4_scratch"
7817 [(set (pc) (if_then_else
7818 (match_operator 4 "arm_comparison_operator"
7819 [(match_operand:SI 1 "s_register_operand" "l,0")
7820 (match_operand:SI 2 "thumb1_cmpneg_operand" "L,J")])
7821 (label_ref (match_operand 3 "" ""))
7823 (clobber (match_scratch:SI 0 "=l,l"))]
7826 output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
7828 switch (get_attr_length (insn))
7830 case 4: return \"b%d4\\t%l3\";
7831 case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7832 default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7835 [(set (attr "far_jump")
7837 (eq_attr "length" "8")
7838 (const_string "yes")
7839 (const_string "no")))
7840 (set (attr "length")
7842 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7843 (le (minus (match_dup 3) (pc)) (const_int 256)))
7846 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7847 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7850 (set_attr "type" "multiple")]
7853 (define_insn "*negated_cbranchsi4"
7856 (match_operator 0 "equality_operator"
7857 [(match_operand:SI 1 "s_register_operand" "l")
7858 (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
7859 (label_ref (match_operand 3 "" ""))
7863 output_asm_insn (\"cmn\\t%1, %2\", operands);
7864 switch (get_attr_length (insn))
7866 case 4: return \"b%d0\\t%l3\";
7867 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7868 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7871 [(set (attr "far_jump")
7873 (eq_attr "length" "8")
7874 (const_string "yes")
7875 (const_string "no")))
7876 (set (attr "length")
7878 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7879 (le (minus (match_dup 3) (pc)) (const_int 256)))
7882 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7883 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7886 (set_attr "type" "multiple")]
7889 (define_insn "*tbit_cbranch"
7892 (match_operator 0 "equality_operator"
7893 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
7895 (match_operand:SI 2 "const_int_operand" "i"))
7897 (label_ref (match_operand 3 "" ""))
7899 (clobber (match_scratch:SI 4 "=l"))]
7904 op[0] = operands[4];
7905 op[1] = operands[1];
7906 op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
7908 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
7909 switch (get_attr_length (insn))
7911 case 4: return \"b%d0\\t%l3\";
7912 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7913 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7916 [(set (attr "far_jump")
7918 (eq_attr "length" "8")
7919 (const_string "yes")
7920 (const_string "no")))
7921 (set (attr "length")
7923 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7924 (le (minus (match_dup 3) (pc)) (const_int 256)))
7927 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7928 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7931 (set_attr "type" "multiple")]
7934 (define_insn "*tlobits_cbranch"
7937 (match_operator 0 "equality_operator"
7938 [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
7939 (match_operand:SI 2 "const_int_operand" "i")
7942 (label_ref (match_operand 3 "" ""))
7944 (clobber (match_scratch:SI 4 "=l"))]
7949 op[0] = operands[4];
7950 op[1] = operands[1];
7951 op[2] = GEN_INT (32 - INTVAL (operands[2]));
7953 output_asm_insn (\"lsl\\t%0, %1, %2\", op);
7954 switch (get_attr_length (insn))
7956 case 4: return \"b%d0\\t%l3\";
7957 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
7958 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
7961 [(set (attr "far_jump")
7963 (eq_attr "length" "8")
7964 (const_string "yes")
7965 (const_string "no")))
7966 (set (attr "length")
7968 (and (ge (minus (match_dup 3) (pc)) (const_int -250))
7969 (le (minus (match_dup 3) (pc)) (const_int 256)))
7972 (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
7973 (le (minus (match_dup 3) (pc)) (const_int 2048)))
7976 (set_attr "type" "multiple")]
7979 (define_insn "*tstsi3_cbranch"
7982 (match_operator 3 "equality_operator"
7983 [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
7984 (match_operand:SI 1 "s_register_operand" "l"))
7986 (label_ref (match_operand 2 "" ""))
7991 output_asm_insn (\"tst\\t%0, %1\", operands);
7992 switch (get_attr_length (insn))
7994 case 4: return \"b%d3\\t%l2\";
7995 case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
7996 default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
7999 [(set (attr "far_jump")
8001 (eq_attr "length" "8")
8002 (const_string "yes")
8003 (const_string "no")))
8004 (set (attr "length")
8006 (and (ge (minus (match_dup 2) (pc)) (const_int -250))
8007 (le (minus (match_dup 2) (pc)) (const_int 256)))
8010 (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
8011 (le (minus (match_dup 2) (pc)) (const_int 2048)))
8014 (set_attr "type" "multiple")]
8017 (define_insn "*cbranchne_decr1"
8019 (if_then_else (match_operator 3 "equality_operator"
8020 [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
8022 (label_ref (match_operand 4 "" ""))
8024 (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
8025 (plus:SI (match_dup 2) (const_int -1)))
8026 (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
8031 cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
8033 VOIDmode, operands[2], const1_rtx);
8034 cond[1] = operands[4];
8036 if (which_alternative == 0)
8037 output_asm_insn (\"sub\\t%0, %2, #1\", operands);
8038 else if (which_alternative == 1)
8040 /* We must provide an alternative for a hi reg because reload
8041 cannot handle output reloads on a jump instruction, but we
8042 can't subtract into that. Fortunately a mov from lo to hi
8043 does not clobber the condition codes. */
8044 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
8045 output_asm_insn (\"mov\\t%0, %1\", operands);
8049 /* Similarly, but the target is memory. */
8050 output_asm_insn (\"sub\\t%1, %2, #1\", operands);
8051 output_asm_insn (\"str\\t%1, %0\", operands);
8054 switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
8057 output_asm_insn (\"b%d0\\t%l1\", cond);
8060 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
8061 return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
8063 output_asm_insn (\"b%D0\\t.LCB%=\", cond);
8064 return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
8068 [(set (attr "far_jump")
8070 (ior (and (eq (symbol_ref ("which_alternative"))
8072 (eq_attr "length" "8"))
8073 (eq_attr "length" "10"))
8074 (const_string "yes")
8075 (const_string "no")))
8076 (set_attr_alternative "length"
8080 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8081 (le (minus (match_dup 4) (pc)) (const_int 256)))
8084 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8085 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8090 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8091 (le (minus (match_dup 4) (pc)) (const_int 256)))
8094 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8095 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8100 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8101 (le (minus (match_dup 4) (pc)) (const_int 256)))
8104 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8105 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8110 (and (ge (minus (match_dup 4) (pc)) (const_int -248))
8111 (le (minus (match_dup 4) (pc)) (const_int 256)))
8114 (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
8115 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8118 (set_attr "type" "multiple")]
8121 (define_insn "*addsi3_cbranch"
8124 (match_operator 4 "arm_comparison_operator"
8126 (match_operand:SI 2 "s_register_operand" "%0,l,*l,1,1,1")
8127 (match_operand:SI 3 "reg_or_int_operand" "IJ,lL,*l,lIJ,lIJ,lIJ"))
8129 (label_ref (match_operand 5 "" ""))
8132 (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
8133 (plus:SI (match_dup 2) (match_dup 3)))
8134 (clobber (match_scratch:SI 1 "=X,X,l,l,&l,&l"))]
8136 && (GET_CODE (operands[4]) == EQ
8137 || GET_CODE (operands[4]) == NE
8138 || GET_CODE (operands[4]) == GE
8139 || GET_CODE (operands[4]) == LT)"
8144 cond[0] = (which_alternative < 2) ? operands[0] : operands[1];
8145 cond[1] = operands[2];
8146 cond[2] = operands[3];
8148 if (CONST_INT_P (cond[2]) && INTVAL (cond[2]) < 0)
8149 output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
8151 output_asm_insn (\"add\\t%0, %1, %2\", cond);
8153 if (which_alternative >= 2
8154 && which_alternative < 4)
8155 output_asm_insn (\"mov\\t%0, %1\", operands);
8156 else if (which_alternative >= 4)
8157 output_asm_insn (\"str\\t%1, %0\", operands);
8159 switch (get_attr_length (insn) - ((which_alternative >= 2) ? 2 : 0))
8162 return \"b%d4\\t%l5\";
8164 return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
8166 return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
8170 [(set (attr "far_jump")
8172 (ior (and (lt (symbol_ref ("which_alternative"))
8174 (eq_attr "length" "8"))
8175 (eq_attr "length" "10"))
8176 (const_string "yes")
8177 (const_string "no")))
8178 (set (attr "length")
8180 (lt (symbol_ref ("which_alternative"))
8183 (and (ge (minus (match_dup 5) (pc)) (const_int -250))
8184 (le (minus (match_dup 5) (pc)) (const_int 256)))
8187 (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
8188 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8192 (and (ge (minus (match_dup 5) (pc)) (const_int -248))
8193 (le (minus (match_dup 5) (pc)) (const_int 256)))
8196 (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
8197 (le (minus (match_dup 5) (pc)) (const_int 2048)))
8200 (set_attr "type" "multiple")]
8203 (define_insn "*addsi3_cbranch_scratch"
8206 (match_operator 3 "arm_comparison_operator"
8208 (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
8209 (match_operand:SI 2 "reg_or_int_operand" "J,l,L,IJ"))
8211 (label_ref (match_operand 4 "" ""))
8213 (clobber (match_scratch:SI 0 "=X,X,l,l"))]
8215 && (GET_CODE (operands[3]) == EQ
8216 || GET_CODE (operands[3]) == NE
8217 || GET_CODE (operands[3]) == GE
8218 || GET_CODE (operands[3]) == LT)"
8221 switch (which_alternative)
8224 output_asm_insn (\"cmp\t%1, #%n2\", operands);
8227 output_asm_insn (\"cmn\t%1, %2\", operands);
8230 if (INTVAL (operands[2]) < 0)
8231 output_asm_insn (\"sub\t%0, %1, %2\", operands);
8233 output_asm_insn (\"add\t%0, %1, %2\", operands);
8236 if (INTVAL (operands[2]) < 0)
8237 output_asm_insn (\"sub\t%0, %0, %2\", operands);
8239 output_asm_insn (\"add\t%0, %0, %2\", operands);
8243 switch (get_attr_length (insn))
8246 return \"b%d3\\t%l4\";
8248 return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
8250 return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
8254 [(set (attr "far_jump")
8256 (eq_attr "length" "8")
8257 (const_string "yes")
8258 (const_string "no")))
8259 (set (attr "length")
8261 (and (ge (minus (match_dup 4) (pc)) (const_int -250))
8262 (le (minus (match_dup 4) (pc)) (const_int 256)))
8265 (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
8266 (le (minus (match_dup 4) (pc)) (const_int 2048)))
8269 (set_attr "type" "multiple")]
8273 ;; Comparison and test insns
8275 (define_insn "*arm_cmpsi_insn"
8276 [(set (reg:CC CC_REGNUM)
8277 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
8278 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
8286 [(set_attr "conds" "set")
8287 (set_attr "arch" "t2,t2,any,any,any")
8288 (set_attr "length" "2,2,4,4,4")
8289 (set_attr "predicable" "yes")
8290 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
8291 (set_attr "type" "alus_imm,alus_reg,alus_reg,alus_imm,alus_imm")]
8294 (define_insn "*cmpsi_shiftsi"
8295 [(set (reg:CC CC_REGNUM)
8296 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
8297 (match_operator:SI 3 "shift_operator"
8298 [(match_operand:SI 1 "s_register_operand" "r,r,r")
8299 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
8302 [(set_attr "conds" "set")
8303 (set_attr "shift" "1")
8304 (set_attr "arch" "32,a,a")
8305 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
8307 (define_insn "*cmpsi_shiftsi_swp"
8308 [(set (reg:CC_SWP CC_REGNUM)
8309 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
8310 [(match_operand:SI 1 "s_register_operand" "r,r,r")
8311 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
8312 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
8315 [(set_attr "conds" "set")
8316 (set_attr "shift" "1")
8317 (set_attr "arch" "32,a,a")
8318 (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
8320 (define_insn "*arm_cmpsi_negshiftsi_si"
8321 [(set (reg:CC_Z CC_REGNUM)
8323 (neg:SI (match_operator:SI 1 "shift_operator"
8324 [(match_operand:SI 2 "s_register_operand" "r")
8325 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
8326 (match_operand:SI 0 "s_register_operand" "r")))]
8329 [(set_attr "conds" "set")
8330 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
8331 (const_string "alus_shift_imm")
8332 (const_string "alus_shift_reg")))
8333 (set_attr "predicable" "yes")]
8336 ;; DImode comparisons. The generic code generates branches that
8337 ;; if-conversion can not reduce to a conditional compare, so we do
8340 (define_insn_and_split "*arm_cmpdi_insn"
8341 [(set (reg:CC_NCV CC_REGNUM)
8342 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
8343 (match_operand:DI 1 "arm_di_operand" "rDi")))
8344 (clobber (match_scratch:SI 2 "=r"))]
8346 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
8347 "&& reload_completed"
8348 [(set (reg:CC CC_REGNUM)
8349 (compare:CC (match_dup 0) (match_dup 1)))
8350 (parallel [(set (reg:CC CC_REGNUM)
8351 (compare:CC (match_dup 3) (match_dup 4)))
8353 (minus:SI (match_dup 5)
8354 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
8356 operands[3] = gen_highpart (SImode, operands[0]);
8357 operands[0] = gen_lowpart (SImode, operands[0]);
8358 if (CONST_INT_P (operands[1]))
8360 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
8363 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
8367 operands[4] = gen_highpart (SImode, operands[1]);
8368 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
8370 operands[1] = gen_lowpart (SImode, operands[1]);
8371 operands[2] = gen_lowpart (SImode, operands[2]);
8373 [(set_attr "conds" "set")
8374 (set_attr "length" "8")
8375 (set_attr "type" "multiple")]
8378 (define_insn_and_split "*arm_cmpdi_unsigned"
8379 [(set (reg:CC_CZ CC_REGNUM)
8380 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
8381 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
8384 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
8385 "&& reload_completed"
8386 [(set (reg:CC CC_REGNUM)
8387 (compare:CC (match_dup 2) (match_dup 3)))
8388 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
8389 (set (reg:CC CC_REGNUM)
8390 (compare:CC (match_dup 0) (match_dup 1))))]
8392 operands[2] = gen_highpart (SImode, operands[0]);
8393 operands[0] = gen_lowpart (SImode, operands[0]);
8394 if (CONST_INT_P (operands[1]))
8395 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
8397 operands[3] = gen_highpart (SImode, operands[1]);
8398 operands[1] = gen_lowpart (SImode, operands[1]);
8400 [(set_attr "conds" "set")
8401 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
8402 (set_attr "arch" "t2,t2,t2,a")
8403 (set_attr "length" "6,6,10,8")
8404 (set_attr "type" "multiple")]
8407 (define_insn "*arm_cmpdi_zero"
8408 [(set (reg:CC_Z CC_REGNUM)
8409 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
8411 (clobber (match_scratch:SI 1 "=r"))]
8413 "orr%.\\t%1, %Q0, %R0"
8414 [(set_attr "conds" "set")
8415 (set_attr "type" "logics_reg")]
8418 (define_insn "*thumb_cmpdi_zero"
8419 [(set (reg:CC_Z CC_REGNUM)
8420 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "l")
8422 (clobber (match_scratch:SI 1 "=l"))]
8424 "orr\\t%1, %Q0, %R0"
8425 [(set_attr "conds" "set")
8426 (set_attr "length" "2")
8427 (set_attr "type" "logics_reg")]
8430 ; This insn allows redundant compares to be removed by cse, nothing should
8431 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
8432 ; is deleted later on. The match_dup will match the mode here, so that
8433 ; mode changes of the condition codes aren't lost by this even though we don't
8434 ; specify what they are.
8436 (define_insn "*deleted_compare"
8437 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
8439 "\\t%@ deleted compare"
8440 [(set_attr "conds" "set")
8441 (set_attr "length" "0")
8442 (set_attr "type" "no_insn")]
8446 ;; Conditional branch insns
8448 (define_expand "cbranch_cc"
8450 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
8451 (match_operand 2 "" "")])
8452 (label_ref (match_operand 3 "" ""))
8455 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
8456 operands[1], operands[2], NULL_RTX);
8457 operands[2] = const0_rtx;"
8461 ;; Patterns to match conditional branch insns.
8464 (define_insn "arm_cond_branch"
8466 (if_then_else (match_operator 1 "arm_comparison_operator"
8467 [(match_operand 2 "cc_register" "") (const_int 0)])
8468 (label_ref (match_operand 0 "" ""))
8472 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8474 arm_ccfsm_state += 2;
8477 return \"b%d1\\t%l0\";
8479 [(set_attr "conds" "use")
8480 (set_attr "type" "branch")
8481 (set (attr "length")
8483 (and (match_test "TARGET_THUMB2")
8484 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
8485 (le (minus (match_dup 0) (pc)) (const_int 256))))
8490 (define_insn "*arm_cond_branch_reversed"
8492 (if_then_else (match_operator 1 "arm_comparison_operator"
8493 [(match_operand 2 "cc_register" "") (const_int 0)])
8495 (label_ref (match_operand 0 "" ""))))]
8498 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8500 arm_ccfsm_state += 2;
8503 return \"b%D1\\t%l0\";
8505 [(set_attr "conds" "use")
8506 (set_attr "type" "branch")
8507 (set (attr "length")
8509 (and (match_test "TARGET_THUMB2")
8510 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
8511 (le (minus (match_dup 0) (pc)) (const_int 256))))
8520 (define_expand "cstore_cc"
8521 [(set (match_operand:SI 0 "s_register_operand" "")
8522 (match_operator:SI 1 "" [(match_operand 2 "" "")
8523 (match_operand 3 "" "")]))]
8525 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
8526 operands[2], operands[3], NULL_RTX);
8527 operands[3] = const0_rtx;"
8530 (define_insn_and_split "*mov_scc"
8531 [(set (match_operand:SI 0 "s_register_operand" "=r")
8532 (match_operator:SI 1 "arm_comparison_operator"
8533 [(match_operand 2 "cc_register" "") (const_int 0)]))]
8535 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
8538 (if_then_else:SI (match_dup 1)
8542 [(set_attr "conds" "use")
8543 (set_attr "length" "8")
8544 (set_attr "type" "multiple")]
8547 (define_insn_and_split "*mov_negscc"
8548 [(set (match_operand:SI 0 "s_register_operand" "=r")
8549 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
8550 [(match_operand 2 "cc_register" "") (const_int 0)])))]
8552 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
8555 (if_then_else:SI (match_dup 1)
8559 operands[3] = GEN_INT (~0);
8561 [(set_attr "conds" "use")
8562 (set_attr "length" "8")
8563 (set_attr "type" "multiple")]
8566 (define_insn_and_split "*mov_notscc"
8567 [(set (match_operand:SI 0 "s_register_operand" "=r")
8568 (not:SI (match_operator:SI 1 "arm_comparison_operator"
8569 [(match_operand 2 "cc_register" "") (const_int 0)])))]
8571 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
8574 (if_then_else:SI (match_dup 1)
8578 operands[3] = GEN_INT (~1);
8579 operands[4] = GEN_INT (~0);
8581 [(set_attr "conds" "use")
8582 (set_attr "length" "8")
8583 (set_attr "type" "multiple")]
8586 (define_expand "cstoresi4"
8587 [(set (match_operand:SI 0 "s_register_operand" "")
8588 (match_operator:SI 1 "expandable_comparison_operator"
8589 [(match_operand:SI 2 "s_register_operand" "")
8590 (match_operand:SI 3 "reg_or_int_operand" "")]))]
8591 "TARGET_32BIT || TARGET_THUMB1"
8593 rtx op3, scratch, scratch2;
8597 if (!arm_add_operand (operands[3], SImode))
8598 operands[3] = force_reg (SImode, operands[3]);
8599 emit_insn (gen_cstore_cc (operands[0], operands[1],
8600 operands[2], operands[3]));
8604 if (operands[3] == const0_rtx)
8606 switch (GET_CODE (operands[1]))
8609 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
8613 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
8617 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
8618 NULL_RTX, 0, OPTAB_WIDEN);
8619 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
8620 NULL_RTX, 0, OPTAB_WIDEN);
8621 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
8622 operands[0], 1, OPTAB_WIDEN);
8626 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
8628 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
8629 NULL_RTX, 1, OPTAB_WIDEN);
8633 scratch = expand_binop (SImode, ashr_optab, operands[2],
8634 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
8635 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
8636 NULL_RTX, 0, OPTAB_WIDEN);
8637 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
8641 /* LT is handled by generic code. No need for unsigned with 0. */
8648 switch (GET_CODE (operands[1]))
8651 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
8652 NULL_RTX, 0, OPTAB_WIDEN);
8653 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
8657 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
8658 NULL_RTX, 0, OPTAB_WIDEN);
8659 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
8663 op3 = force_reg (SImode, operands[3]);
8665 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
8666 NULL_RTX, 1, OPTAB_WIDEN);
8667 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
8668 NULL_RTX, 0, OPTAB_WIDEN);
8669 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
8675 if (!thumb1_cmp_operand (op3, SImode))
8676 op3 = force_reg (SImode, op3);
8677 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
8678 NULL_RTX, 0, OPTAB_WIDEN);
8679 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
8680 NULL_RTX, 1, OPTAB_WIDEN);
8681 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
8686 op3 = force_reg (SImode, operands[3]);
8687 scratch = force_reg (SImode, const0_rtx);
8688 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
8694 if (!thumb1_cmp_operand (op3, SImode))
8695 op3 = force_reg (SImode, op3);
8696 scratch = force_reg (SImode, const0_rtx);
8697 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
8703 if (!thumb1_cmp_operand (op3, SImode))
8704 op3 = force_reg (SImode, op3);
8705 scratch = gen_reg_rtx (SImode);
8706 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
8710 op3 = force_reg (SImode, operands[3]);
8711 scratch = gen_reg_rtx (SImode);
8712 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
8715 /* No good sequences for GT, LT. */
8722 (define_expand "cstoresf4"
8723 [(set (match_operand:SI 0 "s_register_operand" "")
8724 (match_operator:SI 1 "expandable_comparison_operator"
8725 [(match_operand:SF 2 "s_register_operand" "")
8726 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
8727 "TARGET_32BIT && TARGET_HARD_FLOAT"
8728 "emit_insn (gen_cstore_cc (operands[0], operands[1],
8729 operands[2], operands[3])); DONE;"
8732 (define_expand "cstoredf4"
8733 [(set (match_operand:SI 0 "s_register_operand" "")
8734 (match_operator:SI 1 "expandable_comparison_operator"
8735 [(match_operand:DF 2 "s_register_operand" "")
8736 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
8737 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
8738 "emit_insn (gen_cstore_cc (operands[0], operands[1],
8739 operands[2], operands[3])); DONE;"
8742 (define_expand "cstoredi4"
8743 [(set (match_operand:SI 0 "s_register_operand" "")
8744 (match_operator:SI 1 "expandable_comparison_operator"
8745 [(match_operand:DI 2 "s_register_operand" "")
8746 (match_operand:DI 3 "cmpdi_operand" "")]))]
8749 if (!arm_validize_comparison (&operands[1],
8753 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
8759 (define_expand "cstoresi_eq0_thumb1"
8761 [(set (match_operand:SI 0 "s_register_operand" "")
8762 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8764 (clobber (match_dup:SI 2))])]
8766 "operands[2] = gen_reg_rtx (SImode);"
8769 (define_expand "cstoresi_ne0_thumb1"
8771 [(set (match_operand:SI 0 "s_register_operand" "")
8772 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8774 (clobber (match_dup:SI 2))])]
8776 "operands[2] = gen_reg_rtx (SImode);"
8779 (define_insn "*cstoresi_eq0_thumb1_insn"
8780 [(set (match_operand:SI 0 "s_register_operand" "=&l,l")
8781 (eq:SI (match_operand:SI 1 "s_register_operand" "l,0")
8783 (clobber (match_operand:SI 2 "s_register_operand" "=X,l"))]
8786 neg\\t%0, %1\;adc\\t%0, %0, %1
8787 neg\\t%2, %1\;adc\\t%0, %1, %2"
8788 [(set_attr "length" "4")
8789 (set_attr "type" "multiple")]
8792 (define_insn "*cstoresi_ne0_thumb1_insn"
8793 [(set (match_operand:SI 0 "s_register_operand" "=l")
8794 (ne:SI (match_operand:SI 1 "s_register_operand" "0")
8796 (clobber (match_operand:SI 2 "s_register_operand" "=l"))]
8798 "sub\\t%2, %1, #1\;sbc\\t%0, %1, %2"
8799 [(set_attr "length" "4")]
8802 ;; Used as part of the expansion of thumb ltu and gtu sequences
8803 (define_insn "cstoresi_nltu_thumb1"
8804 [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8805 (neg:SI (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8806 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r"))))]
8808 "cmp\\t%1, %2\;sbc\\t%0, %0, %0"
8809 [(set_attr "length" "4")
8810 (set_attr "type" "multiple")]
8813 (define_insn_and_split "cstoresi_ltu_thumb1"
8814 [(set (match_operand:SI 0 "s_register_operand" "=l,l")
8815 (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
8816 (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")))]
8821 (neg:SI (ltu:SI (match_dup 1) (match_dup 2))))
8822 (set (match_dup 0) (neg:SI (match_dup 3)))]
8823 "operands[3] = gen_reg_rtx (SImode);"
8824 [(set_attr "length" "4")
8825 (set_attr "type" "multiple")]
8828 ;; Used as part of the expansion of thumb les sequence.
8829 (define_insn "thumb1_addsi3_addgeu"
8830 [(set (match_operand:SI 0 "s_register_operand" "=l")
8831 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0")
8832 (match_operand:SI 2 "s_register_operand" "l"))
8833 (geu:SI (match_operand:SI 3 "s_register_operand" "l")
8834 (match_operand:SI 4 "thumb1_cmp_operand" "lI"))))]
8836 "cmp\\t%3, %4\;adc\\t%0, %1, %2"
8837 [(set_attr "length" "4")
8838 (set_attr "type" "multiple")]
8842 ;; Conditional move insns
8844 (define_expand "movsicc"
8845 [(set (match_operand:SI 0 "s_register_operand" "")
8846 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
8847 (match_operand:SI 2 "arm_not_operand" "")
8848 (match_operand:SI 3 "arm_not_operand" "")))]
8855 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8856 &XEXP (operands[1], 1)))
8859 code = GET_CODE (operands[1]);
8860 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8861 XEXP (operands[1], 1), NULL_RTX);
8862 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8866 (define_expand "movsfcc"
8867 [(set (match_operand:SF 0 "s_register_operand" "")
8868 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
8869 (match_operand:SF 2 "s_register_operand" "")
8870 (match_operand:SF 3 "s_register_operand" "")))]
8871 "TARGET_32BIT && TARGET_HARD_FLOAT"
8874 enum rtx_code code = GET_CODE (operands[1]);
8877 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8878 &XEXP (operands[1], 1)))
8881 code = GET_CODE (operands[1]);
8882 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8883 XEXP (operands[1], 1), NULL_RTX);
8884 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8888 (define_expand "movdfcc"
8889 [(set (match_operand:DF 0 "s_register_operand" "")
8890 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
8891 (match_operand:DF 2 "s_register_operand" "")
8892 (match_operand:DF 3 "s_register_operand" "")))]
8893 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
8896 enum rtx_code code = GET_CODE (operands[1]);
8899 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
8900 &XEXP (operands[1], 1)))
8902 code = GET_CODE (operands[1]);
8903 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
8904 XEXP (operands[1], 1), NULL_RTX);
8905 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
8909 (define_insn "*cmov<mode>"
8910 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
8911 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
8912 [(match_operand 2 "cc_register" "") (const_int 0)])
8913 (match_operand:SDF 3 "s_register_operand"
8915 (match_operand:SDF 4 "s_register_operand"
8916 "<F_constraint>")))]
8917 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
8920 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
8927 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
8932 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
8938 [(set_attr "conds" "use")
8939 (set_attr "type" "fcsel")]
8942 (define_insn_and_split "*movsicc_insn"
8943 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8945 (match_operator 3 "arm_comparison_operator"
8946 [(match_operand 4 "cc_register" "") (const_int 0)])
8947 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8948 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8959 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8960 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8961 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8962 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8963 "&& reload_completed"
8966 enum rtx_code rev_code;
8967 enum machine_mode mode;
8970 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8972 gen_rtx_SET (VOIDmode,
8976 rev_code = GET_CODE (operands[3]);
8977 mode = GET_MODE (operands[4]);
8978 if (mode == CCFPmode || mode == CCFPEmode)
8979 rev_code = reverse_condition_maybe_unordered (rev_code);
8981 rev_code = reverse_condition (rev_code);
8983 rev_cond = gen_rtx_fmt_ee (rev_code,
8987 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8989 gen_rtx_SET (VOIDmode,
8994 [(set_attr "length" "4,4,4,4,8,8,8,8")
8995 (set_attr "conds" "use")
8996 (set_attr_alternative "type"
8997 [(if_then_else (match_operand 2 "const_int_operand" "")
8998 (const_string "mov_imm")
8999 (const_string "mov_reg"))
9000 (const_string "mvn_imm")
9001 (if_then_else (match_operand 1 "const_int_operand" "")
9002 (const_string "mov_imm")
9003 (const_string "mov_reg"))
9004 (const_string "mvn_imm")
9005 (const_string "mov_reg")
9006 (const_string "mov_reg")
9007 (const_string "mov_reg")
9008 (const_string "mov_reg")])]
9011 (define_insn "*movsfcc_soft_insn"
9012 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
9013 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
9014 [(match_operand 4 "cc_register" "") (const_int 0)])
9015 (match_operand:SF 1 "s_register_operand" "0,r")
9016 (match_operand:SF 2 "s_register_operand" "r,0")))]
9017 "TARGET_ARM && TARGET_SOFT_FLOAT"
9021 [(set_attr "conds" "use")
9022 (set_attr "type" "mov_reg")]
9026 ;; Jump and linkage insns
9028 (define_expand "jump"
9030 (label_ref (match_operand 0 "" "")))]
9035 (define_insn "*arm_jump"
9037 (label_ref (match_operand 0 "" "")))]
9041 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
9043 arm_ccfsm_state += 2;
9046 return \"b%?\\t%l0\";
9049 [(set_attr "predicable" "yes")
9050 (set (attr "length")
9052 (and (match_test "TARGET_THUMB2")
9053 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
9054 (le (minus (match_dup 0) (pc)) (const_int 2048))))
9057 (set_attr "type" "branch")]
9060 (define_insn "*thumb_jump"
9062 (label_ref (match_operand 0 "" "")))]
9065 if (get_attr_length (insn) == 2)
9067 return \"bl\\t%l0\\t%@ far jump\";
9069 [(set (attr "far_jump")
9071 (eq_attr "length" "4")
9072 (const_string "yes")
9073 (const_string "no")))
9074 (set (attr "length")
9076 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
9077 (le (minus (match_dup 0) (pc)) (const_int 2048)))
9080 (set_attr "type" "branch")]
9083 (define_expand "call"
9084 [(parallel [(call (match_operand 0 "memory_operand" "")
9085 (match_operand 1 "general_operand" ""))
9086 (use (match_operand 2 "" ""))
9087 (clobber (reg:SI LR_REGNUM))])]
9093 /* In an untyped call, we can get NULL for operand 2. */
9094 if (operands[2] == NULL_RTX)
9095 operands[2] = const0_rtx;
9097 /* Decide if we should generate indirect calls by loading the
9098 32-bit address of the callee into a register before performing the
9100 callee = XEXP (operands[0], 0);
9101 if (GET_CODE (callee) == SYMBOL_REF
9102 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9104 XEXP (operands[0], 0) = force_reg (Pmode, callee);
9106 pat = gen_call_internal (operands[0], operands[1], operands[2]);
9107 arm_emit_call_insn (pat, XEXP (operands[0], 0));
9112 (define_expand "call_internal"
9113 [(parallel [(call (match_operand 0 "memory_operand" "")
9114 (match_operand 1 "general_operand" ""))
9115 (use (match_operand 2 "" ""))
9116 (clobber (reg:SI LR_REGNUM))])])
9118 (define_insn "*call_reg_armv5"
9119 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
9120 (match_operand 1 "" ""))
9121 (use (match_operand 2 "" ""))
9122 (clobber (reg:SI LR_REGNUM))]
9123 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
9125 [(set_attr "type" "call")]
9128 (define_insn "*call_reg_arm"
9129 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
9130 (match_operand 1 "" ""))
9131 (use (match_operand 2 "" ""))
9132 (clobber (reg:SI LR_REGNUM))]
9133 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9135 return output_call (operands);
9137 ;; length is worst case, normally it is only two
9138 [(set_attr "length" "12")
9139 (set_attr "type" "call")]
9143 ;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not
9144 ;; considered a function call by the branch predictor of some cores (PR40887).
9145 ;; Falls back to blx rN (*call_reg_armv5).
9147 (define_insn "*call_mem"
9148 [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
9149 (match_operand 1 "" ""))
9150 (use (match_operand 2 "" ""))
9151 (clobber (reg:SI LR_REGNUM))]
9152 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9154 return output_call_mem (operands);
9156 [(set_attr "length" "12")
9157 (set_attr "type" "call")]
9160 (define_insn "*call_reg_thumb1_v5"
9161 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
9162 (match_operand 1 "" ""))
9163 (use (match_operand 2 "" ""))
9164 (clobber (reg:SI LR_REGNUM))]
9165 "TARGET_THUMB1 && arm_arch5 && !SIBLING_CALL_P (insn)"
9167 [(set_attr "length" "2")
9168 (set_attr "type" "call")]
9171 (define_insn "*call_reg_thumb1"
9172 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r"))
9173 (match_operand 1 "" ""))
9174 (use (match_operand 2 "" ""))
9175 (clobber (reg:SI LR_REGNUM))]
9176 "TARGET_THUMB1 && !arm_arch5 && !SIBLING_CALL_P (insn)"
9179 if (!TARGET_CALLER_INTERWORKING)
9180 return thumb_call_via_reg (operands[0]);
9181 else if (operands[1] == const0_rtx)
9182 return \"bl\\t%__interwork_call_via_%0\";
9183 else if (frame_pointer_needed)
9184 return \"bl\\t%__interwork_r7_call_via_%0\";
9186 return \"bl\\t%__interwork_r11_call_via_%0\";
9188 [(set_attr "type" "call")]
9191 (define_expand "call_value"
9192 [(parallel [(set (match_operand 0 "" "")
9193 (call (match_operand 1 "memory_operand" "")
9194 (match_operand 2 "general_operand" "")))
9195 (use (match_operand 3 "" ""))
9196 (clobber (reg:SI LR_REGNUM))])]
9202 /* In an untyped call, we can get NULL for operand 2. */
9203 if (operands[3] == 0)
9204 operands[3] = const0_rtx;
9206 /* Decide if we should generate indirect calls by loading the
9207 32-bit address of the callee into a register before performing the
9209 callee = XEXP (operands[1], 0);
9210 if (GET_CODE (callee) == SYMBOL_REF
9211 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
9213 XEXP (operands[1], 0) = force_reg (Pmode, callee);
9215 pat = gen_call_value_internal (operands[0], operands[1],
9216 operands[2], operands[3]);
9217 arm_emit_call_insn (pat, XEXP (operands[1], 0));
9222 (define_expand "call_value_internal"
9223 [(parallel [(set (match_operand 0 "" "")
9224 (call (match_operand 1 "memory_operand" "")
9225 (match_operand 2 "general_operand" "")))
9226 (use (match_operand 3 "" ""))
9227 (clobber (reg:SI LR_REGNUM))])])
9229 (define_insn "*call_value_reg_armv5"
9230 [(set (match_operand 0 "" "")
9231 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
9232 (match_operand 2 "" "")))
9233 (use (match_operand 3 "" ""))
9234 (clobber (reg:SI LR_REGNUM))]
9235 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
9237 [(set_attr "type" "call")]
9240 (define_insn "*call_value_reg_arm"
9241 [(set (match_operand 0 "" "")
9242 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
9243 (match_operand 2 "" "")))
9244 (use (match_operand 3 "" ""))
9245 (clobber (reg:SI LR_REGNUM))]
9246 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
9248 return output_call (&operands[1]);
9250 [(set_attr "length" "12")
9251 (set_attr "type" "call")]
9254 ;; Note: see *call_mem
9256 (define_insn "*call_value_mem"
9257 [(set (match_operand 0 "" "")
9258 (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
9259 (match_operand 2 "" "")))
9260 (use (match_operand 3 "" ""))
9261 (clobber (reg:SI LR_REGNUM))]
9262 "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
9263 && !SIBLING_CALL_P (insn)"
9265 return output_call_mem (&operands[1]);
9267 [(set_attr "length" "12")
9268 (set_attr "type" "call")]
9271 (define_insn "*call_value_reg_thumb1_v5"
9272 [(set (match_operand 0 "" "")
9273 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
9274 (match_operand 2 "" "")))
9275 (use (match_operand 3 "" ""))
9276 (clobber (reg:SI LR_REGNUM))]
9277 "TARGET_THUMB1 && arm_arch5"
9279 [(set_attr "length" "2")
9280 (set_attr "type" "call")]
9283 (define_insn "*call_value_reg_thumb1"
9284 [(set (match_operand 0 "" "")
9285 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
9286 (match_operand 2 "" "")))
9287 (use (match_operand 3 "" ""))
9288 (clobber (reg:SI LR_REGNUM))]
9289 "TARGET_THUMB1 && !arm_arch5"
9292 if (!TARGET_CALLER_INTERWORKING)
9293 return thumb_call_via_reg (operands[1]);
9294 else if (operands[2] == const0_rtx)
9295 return \"bl\\t%__interwork_call_via_%1\";
9296 else if (frame_pointer_needed)
9297 return \"bl\\t%__interwork_r7_call_via_%1\";
9299 return \"bl\\t%__interwork_r11_call_via_%1\";
9301 [(set_attr "type" "call")]
9304 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
9305 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
9307 (define_insn "*call_symbol"
9308 [(call (mem:SI (match_operand:SI 0 "" ""))
9309 (match_operand 1 "" ""))
9310 (use (match_operand 2 "" ""))
9311 (clobber (reg:SI LR_REGNUM))]
9313 && !SIBLING_CALL_P (insn)
9314 && (GET_CODE (operands[0]) == SYMBOL_REF)
9315 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
9318 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
9320 [(set_attr "type" "call")]
9323 (define_insn "*call_value_symbol"
9324 [(set (match_operand 0 "" "")
9325 (call (mem:SI (match_operand:SI 1 "" ""))
9326 (match_operand:SI 2 "" "")))
9327 (use (match_operand 3 "" ""))
9328 (clobber (reg:SI LR_REGNUM))]
9330 && !SIBLING_CALL_P (insn)
9331 && (GET_CODE (operands[1]) == SYMBOL_REF)
9332 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
9335 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
9337 [(set_attr "type" "call")]
9340 (define_insn "*call_insn"
9341 [(call (mem:SI (match_operand:SI 0 "" ""))
9342 (match_operand:SI 1 "" ""))
9343 (use (match_operand 2 "" ""))
9344 (clobber (reg:SI LR_REGNUM))]
9346 && GET_CODE (operands[0]) == SYMBOL_REF
9347 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
9349 [(set_attr "length" "4")
9350 (set_attr "type" "call")]
9353 (define_insn "*call_value_insn"
9354 [(set (match_operand 0 "" "")
9355 (call (mem:SI (match_operand 1 "" ""))
9356 (match_operand 2 "" "")))
9357 (use (match_operand 3 "" ""))
9358 (clobber (reg:SI LR_REGNUM))]
9360 && GET_CODE (operands[1]) == SYMBOL_REF
9361 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
9363 [(set_attr "length" "4")
9364 (set_attr "type" "call")]
9367 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
9368 (define_expand "sibcall"
9369 [(parallel [(call (match_operand 0 "memory_operand" "")
9370 (match_operand 1 "general_operand" ""))
9372 (use (match_operand 2 "" ""))])]
9376 if ((!REG_P (XEXP (operands[0], 0))
9377 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
9378 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
9379 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
9380 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
9382 if (operands[2] == NULL_RTX)
9383 operands[2] = const0_rtx;
9387 (define_expand "sibcall_value"
9388 [(parallel [(set (match_operand 0 "" "")
9389 (call (match_operand 1 "memory_operand" "")
9390 (match_operand 2 "general_operand" "")))
9392 (use (match_operand 3 "" ""))])]
9396 if ((!REG_P (XEXP (operands[1], 0))
9397 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
9398 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
9399 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
9400 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
9402 if (operands[3] == NULL_RTX)
9403 operands[3] = const0_rtx;
9407 (define_insn "*sibcall_insn"
9408 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
9409 (match_operand 1 "" ""))
9411 (use (match_operand 2 "" ""))]
9412 "TARGET_32BIT && SIBLING_CALL_P (insn)"
9414 if (which_alternative == 1)
9415 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
9418 if (arm_arch5 || arm_arch4t)
9419 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
9421 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
9424 [(set_attr "type" "call")]
9427 (define_insn "*sibcall_value_insn"
9428 [(set (match_operand 0 "" "")
9429 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
9430 (match_operand 2 "" "")))
9432 (use (match_operand 3 "" ""))]
9433 "TARGET_32BIT && SIBLING_CALL_P (insn)"
9435 if (which_alternative == 1)
9436 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
9439 if (arm_arch5 || arm_arch4t)
9440 return \"bx%?\\t%1\";
9442 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
9445 [(set_attr "type" "call")]
9448 (define_expand "<return_str>return"
9450 "(TARGET_ARM || (TARGET_THUMB2
9451 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
9452 && !IS_STACKALIGN (arm_current_func_type ())))
9453 <return_cond_false>"
9458 thumb2_expand_return (<return_simple_p>);
9465 ;; Often the return insn will be the same as loading from memory, so set attr
9466 (define_insn "*arm_return"
9468 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
9471 if (arm_ccfsm_state == 2)
9473 arm_ccfsm_state += 2;
9476 return output_return_instruction (const_true_rtx, true, false, false);
9478 [(set_attr "type" "load1")
9479 (set_attr "length" "12")
9480 (set_attr "predicable" "yes")]
9483 (define_insn "*cond_<return_str>return"
9485 (if_then_else (match_operator 0 "arm_comparison_operator"
9486 [(match_operand 1 "cc_register" "") (const_int 0)])
9489 "TARGET_ARM <return_cond_true>"
9492 if (arm_ccfsm_state == 2)
9494 arm_ccfsm_state += 2;
9497 return output_return_instruction (operands[0], true, false,
9500 [(set_attr "conds" "use")
9501 (set_attr "length" "12")
9502 (set_attr "type" "load1")]
9505 (define_insn "*cond_<return_str>return_inverted"
9507 (if_then_else (match_operator 0 "arm_comparison_operator"
9508 [(match_operand 1 "cc_register" "") (const_int 0)])
9511 "TARGET_ARM <return_cond_true>"
9514 if (arm_ccfsm_state == 2)
9516 arm_ccfsm_state += 2;
9519 return output_return_instruction (operands[0], true, true,
9522 [(set_attr "conds" "use")
9523 (set_attr "length" "12")
9524 (set_attr "type" "load1")]
9527 (define_insn "*arm_simple_return"
9532 if (arm_ccfsm_state == 2)
9534 arm_ccfsm_state += 2;
9537 return output_return_instruction (const_true_rtx, true, false, true);
9539 [(set_attr "type" "branch")
9540 (set_attr "length" "4")
9541 (set_attr "predicable" "yes")]
9544 ;; Generate a sequence of instructions to determine if the processor is
9545 ;; in 26-bit or 32-bit mode, and return the appropriate return address
9548 (define_expand "return_addr_mask"
9550 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
9552 (set (match_operand:SI 0 "s_register_operand" "")
9553 (if_then_else:SI (eq (match_dup 1) (const_int 0))
9555 (const_int 67108860)))] ; 0x03fffffc
9558 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
9561 (define_insn "*check_arch2"
9562 [(set (match_operand:CC_NOOV 0 "cc_register" "")
9563 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
9566 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
9567 [(set_attr "length" "8")
9568 (set_attr "conds" "set")
9569 (set_attr "type" "multiple")]
9572 ;; Call subroutine returning any type.
9574 (define_expand "untyped_call"
9575 [(parallel [(call (match_operand 0 "" "")
9577 (match_operand 1 "" "")
9578 (match_operand 2 "" "")])]
9583 rtx par = gen_rtx_PARALLEL (VOIDmode,
9584 rtvec_alloc (XVECLEN (operands[2], 0)));
9585 rtx addr = gen_reg_rtx (Pmode);
9589 emit_move_insn (addr, XEXP (operands[1], 0));
9590 mem = change_address (operands[1], BLKmode, addr);
9592 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9594 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
9596 /* Default code only uses r0 as a return value, but we could
9597 be using anything up to 4 registers. */
9598 if (REGNO (src) == R0_REGNUM)
9599 src = gen_rtx_REG (TImode, R0_REGNUM);
9601 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
9603 size += GET_MODE_SIZE (GET_MODE (src));
9606 emit_call_insn (GEN_CALL_VALUE (par, operands[0], const0_rtx, NULL,
9611 for (i = 0; i < XVECLEN (par, 0); i++)
9613 HOST_WIDE_INT offset = 0;
9614 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
9617 emit_move_insn (addr, plus_constant (Pmode, addr, size));
9619 mem = change_address (mem, GET_MODE (reg), NULL);
9620 if (REGNO (reg) == R0_REGNUM)
9622 /* On thumb we have to use a write-back instruction. */
9623 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
9624 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
9625 size = TARGET_ARM ? 16 : 0;
9629 emit_move_insn (mem, reg);
9630 size = GET_MODE_SIZE (GET_MODE (reg));
9634 /* The optimizer does not know that the call sets the function value
9635 registers we stored in the result block. We avoid problems by
9636 claiming that all hard registers are used and clobbered at this
9638 emit_insn (gen_blockage ());
9644 (define_expand "untyped_return"
9645 [(match_operand:BLK 0 "memory_operand" "")
9646 (match_operand 1 "" "")]
9651 rtx addr = gen_reg_rtx (Pmode);
9655 emit_move_insn (addr, XEXP (operands[0], 0));
9656 mem = change_address (operands[0], BLKmode, addr);
9658 for (i = 0; i < XVECLEN (operands[1], 0); i++)
9660 HOST_WIDE_INT offset = 0;
9661 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
9664 emit_move_insn (addr, plus_constant (Pmode, addr, size));
9666 mem = change_address (mem, GET_MODE (reg), NULL);
9667 if (REGNO (reg) == R0_REGNUM)
9669 /* On thumb we have to use a write-back instruction. */
9670 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
9671 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
9672 size = TARGET_ARM ? 16 : 0;
9676 emit_move_insn (reg, mem);
9677 size = GET_MODE_SIZE (GET_MODE (reg));
9681 /* Emit USE insns before the return. */
9682 for (i = 0; i < XVECLEN (operands[1], 0); i++)
9683 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
9685 /* Construct the return. */
9686 expand_naked_return ();
9692 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9693 ;; all of memory. This blocks insns from being moved across this point.
9695 (define_insn "blockage"
9696 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
9699 [(set_attr "length" "0")
9700 (set_attr "type" "block")]
9703 (define_expand "casesi"
9704 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
9705 (match_operand:SI 1 "const_int_operand" "") ; lower bound
9706 (match_operand:SI 2 "const_int_operand" "") ; total range
9707 (match_operand:SI 3 "" "") ; table label
9708 (match_operand:SI 4 "" "")] ; Out of range label
9709 "TARGET_32BIT || optimize_size || flag_pic"
9712 enum insn_code code;
9713 if (operands[1] != const0_rtx)
9715 rtx reg = gen_reg_rtx (SImode);
9717 emit_insn (gen_addsi3 (reg, operands[0],
9718 gen_int_mode (-INTVAL (operands[1]),
9724 code = CODE_FOR_arm_casesi_internal;
9725 else if (TARGET_THUMB1)
9726 code = CODE_FOR_thumb1_casesi_internal_pic;
9728 code = CODE_FOR_thumb2_casesi_internal_pic;
9730 code = CODE_FOR_thumb2_casesi_internal;
9732 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
9733 operands[2] = force_reg (SImode, operands[2]);
9735 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
9736 operands[3], operands[4]));
9741 ;; The USE in this pattern is needed to tell flow analysis that this is
9742 ;; a CASESI insn. It has no other purpose.
9743 (define_insn "arm_casesi_internal"
9744 [(parallel [(set (pc)
9746 (leu (match_operand:SI 0 "s_register_operand" "r")
9747 (match_operand:SI 1 "arm_rhs_operand" "rI"))
9748 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
9749 (label_ref (match_operand 2 "" ""))))
9750 (label_ref (match_operand 3 "" ""))))
9751 (clobber (reg:CC CC_REGNUM))
9752 (use (label_ref (match_dup 2)))])]
9756 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
9757 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
9759 [(set_attr "conds" "clob")
9760 (set_attr "length" "12")
9761 (set_attr "type" "multiple")]
9764 (define_expand "thumb1_casesi_internal_pic"
9765 [(match_operand:SI 0 "s_register_operand" "")
9766 (match_operand:SI 1 "thumb1_cmp_operand" "")
9767 (match_operand 2 "" "")
9768 (match_operand 3 "" "")]
9772 rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[1]);
9773 emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[1],
9775 reg0 = gen_rtx_REG (SImode, 0);
9776 emit_move_insn (reg0, operands[0]);
9777 emit_jump_insn (gen_thumb1_casesi_dispatch (operands[2]/*, operands[3]*/));
9782 (define_insn "thumb1_casesi_dispatch"
9783 [(parallel [(set (pc) (unspec [(reg:SI 0)
9784 (label_ref (match_operand 0 "" ""))
9785 ;; (label_ref (match_operand 1 "" ""))
9787 UNSPEC_THUMB1_CASESI))
9788 (clobber (reg:SI IP_REGNUM))
9789 (clobber (reg:SI LR_REGNUM))])]
9791 "* return thumb1_output_casesi(operands);"
9792 [(set_attr "length" "4")
9793 (set_attr "type" "multiple")]
9796 (define_expand "indirect_jump"
9798 (match_operand:SI 0 "s_register_operand" ""))]
9801 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
9802 address and use bx. */
9806 tmp = gen_reg_rtx (SImode);
9807 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
9813 ;; NB Never uses BX.
9814 (define_insn "*arm_indirect_jump"
9816 (match_operand:SI 0 "s_register_operand" "r"))]
9818 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
9819 [(set_attr "predicable" "yes")
9820 (set_attr "type" "branch")]
9823 (define_insn "*load_indirect_jump"
9825 (match_operand:SI 0 "memory_operand" "m"))]
9827 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
9828 [(set_attr "type" "load1")
9829 (set_attr "pool_range" "4096")
9830 (set_attr "neg_pool_range" "4084")
9831 (set_attr "predicable" "yes")]
9834 ;; NB Never uses BX.
9835 (define_insn "*thumb1_indirect_jump"
9837 (match_operand:SI 0 "register_operand" "l*r"))]
9840 [(set_attr "conds" "clob")
9841 (set_attr "length" "2")
9842 (set_attr "type" "branch")]
9852 if (TARGET_UNIFIED_ASM)
9855 return \"mov%?\\t%|r0, %|r0\\t%@ nop\";
9856 return \"mov\\tr8, r8\";
9858 [(set (attr "length")
9859 (if_then_else (eq_attr "is_thumb" "yes")
9862 (set_attr "type" "mov_reg")]
9866 [(trap_if (const_int 1) (const_int 0))]
9870 return \".inst\\t0xe7f000f0\";
9872 return \".inst\\t0xdeff\";
9874 [(set (attr "length")
9875 (if_then_else (eq_attr "is_thumb" "yes")
9878 (set_attr "type" "trap")
9879 (set_attr "conds" "unconditional")]
9883 ;; Patterns to allow combination of arithmetic, cond code and shifts
9885 (define_insn "*<arith_shift_insn>_multsi"
9886 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9888 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
9889 (match_operand:SI 3 "power_of_two_operand" ""))
9890 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
9892 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
9893 [(set_attr "predicable" "yes")
9894 (set_attr "predicable_short_it" "no")
9895 (set_attr "shift" "2")
9896 (set_attr "arch" "a,t2")
9897 (set_attr "type" "alu_shift_imm")])
9899 (define_insn "*<arith_shift_insn>_shiftsi"
9900 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9902 (match_operator:SI 2 "shift_nomul_operator"
9903 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9904 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
9905 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
9906 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
9907 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
9908 [(set_attr "predicable" "yes")
9909 (set_attr "predicable_short_it" "no")
9910 (set_attr "shift" "3")
9911 (set_attr "arch" "a,t2,a")
9912 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9915 [(set (match_operand:SI 0 "s_register_operand" "")
9916 (match_operator:SI 1 "shiftable_operator"
9917 [(match_operator:SI 2 "shiftable_operator"
9918 [(match_operator:SI 3 "shift_operator"
9919 [(match_operand:SI 4 "s_register_operand" "")
9920 (match_operand:SI 5 "reg_or_int_operand" "")])
9921 (match_operand:SI 6 "s_register_operand" "")])
9922 (match_operand:SI 7 "arm_rhs_operand" "")]))
9923 (clobber (match_operand:SI 8 "s_register_operand" ""))]
9926 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9929 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
9932 (define_insn "*arith_shiftsi_compare0"
9933 [(set (reg:CC_NOOV CC_REGNUM)
9935 (match_operator:SI 1 "shiftable_operator"
9936 [(match_operator:SI 3 "shift_operator"
9937 [(match_operand:SI 4 "s_register_operand" "r,r")
9938 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9939 (match_operand:SI 2 "s_register_operand" "r,r")])
9941 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9942 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9945 "%i1%.\\t%0, %2, %4%S3"
9946 [(set_attr "conds" "set")
9947 (set_attr "shift" "4")
9948 (set_attr "arch" "32,a")
9949 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9951 (define_insn "*arith_shiftsi_compare0_scratch"
9952 [(set (reg:CC_NOOV CC_REGNUM)
9954 (match_operator:SI 1 "shiftable_operator"
9955 [(match_operator:SI 3 "shift_operator"
9956 [(match_operand:SI 4 "s_register_operand" "r,r")
9957 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9958 (match_operand:SI 2 "s_register_operand" "r,r")])
9960 (clobber (match_scratch:SI 0 "=r,r"))]
9962 "%i1%.\\t%0, %2, %4%S3"
9963 [(set_attr "conds" "set")
9964 (set_attr "shift" "4")
9965 (set_attr "arch" "32,a")
9966 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9968 (define_insn "*sub_shiftsi"
9969 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9970 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9971 (match_operator:SI 2 "shift_operator"
9972 [(match_operand:SI 3 "s_register_operand" "r,r")
9973 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
9975 "sub%?\\t%0, %1, %3%S2"
9976 [(set_attr "predicable" "yes")
9977 (set_attr "shift" "3")
9978 (set_attr "arch" "32,a")
9979 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9981 (define_insn "*sub_shiftsi_compare0"
9982 [(set (reg:CC_NOOV CC_REGNUM)
9984 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9985 (match_operator:SI 2 "shift_operator"
9986 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9987 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9989 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9990 (minus:SI (match_dup 1)
9991 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
9993 "sub%.\\t%0, %1, %3%S2"
9994 [(set_attr "conds" "set")
9995 (set_attr "shift" "3")
9996 (set_attr "arch" "32,a,a")
9997 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9999 (define_insn "*sub_shiftsi_compare0_scratch"
10000 [(set (reg:CC_NOOV CC_REGNUM)
10002 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
10003 (match_operator:SI 2 "shift_operator"
10004 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10005 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
10007 (clobber (match_scratch:SI 0 "=r,r,r"))]
10009 "sub%.\\t%0, %1, %3%S2"
10010 [(set_attr "conds" "set")
10011 (set_attr "shift" "3")
10012 (set_attr "arch" "32,a,a")
10013 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
10016 (define_insn_and_split "*and_scc"
10017 [(set (match_operand:SI 0 "s_register_operand" "=r")
10018 (and:SI (match_operator:SI 1 "arm_comparison_operator"
10019 [(match_operand 2 "cc_register" "") (const_int 0)])
10020 (match_operand:SI 3 "s_register_operand" "r")))]
10022 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
10023 "&& reload_completed"
10024 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
10025 (cond_exec (match_dup 4) (set (match_dup 0)
10026 (and:SI (match_dup 3) (const_int 1))))]
10028 enum machine_mode mode = GET_MODE (operands[2]);
10029 enum rtx_code rc = GET_CODE (operands[1]);
10031 /* Note that operands[4] is the same as operands[1],
10032 but with VOIDmode as the result. */
10033 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10034 if (mode == CCFPmode || mode == CCFPEmode)
10035 rc = reverse_condition_maybe_unordered (rc);
10037 rc = reverse_condition (rc);
10038 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10040 [(set_attr "conds" "use")
10041 (set_attr "type" "multiple")
10042 (set_attr "length" "8")]
10045 (define_insn_and_split "*ior_scc"
10046 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10047 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
10048 [(match_operand 2 "cc_register" "") (const_int 0)])
10049 (match_operand:SI 3 "s_register_operand" "0,?r")))]
10052 orr%d1\\t%0, %3, #1
10054 "&& reload_completed
10055 && REGNO (operands [0]) != REGNO (operands[3])"
10056 ;; && which_alternative == 1
10057 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
10058 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
10059 (cond_exec (match_dup 4) (set (match_dup 0)
10060 (ior:SI (match_dup 3) (const_int 1))))]
10062 enum machine_mode mode = GET_MODE (operands[2]);
10063 enum rtx_code rc = GET_CODE (operands[1]);
10065 /* Note that operands[4] is the same as operands[1],
10066 but with VOIDmode as the result. */
10067 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10068 if (mode == CCFPmode || mode == CCFPEmode)
10069 rc = reverse_condition_maybe_unordered (rc);
10071 rc = reverse_condition (rc);
10072 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
10074 [(set_attr "conds" "use")
10075 (set_attr "length" "4,8")
10076 (set_attr "type" "logic_imm,multiple")]
10079 ; A series of splitters for the compare_scc pattern below. Note that
10080 ; order is important.
10082 [(set (match_operand:SI 0 "s_register_operand" "")
10083 (lt:SI (match_operand:SI 1 "s_register_operand" "")
10085 (clobber (reg:CC CC_REGNUM))]
10086 "TARGET_32BIT && reload_completed"
10087 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
10090 [(set (match_operand:SI 0 "s_register_operand" "")
10091 (ge:SI (match_operand:SI 1 "s_register_operand" "")
10093 (clobber (reg:CC CC_REGNUM))]
10094 "TARGET_32BIT && reload_completed"
10095 [(set (match_dup 0) (not:SI (match_dup 1)))
10096 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
10099 [(set (match_operand:SI 0 "s_register_operand" "")
10100 (eq:SI (match_operand:SI 1 "s_register_operand" "")
10102 (clobber (reg:CC CC_REGNUM))]
10103 "arm_arch5 && TARGET_32BIT"
10104 [(set (match_dup 0) (clz:SI (match_dup 1)))
10105 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10109 [(set (match_operand:SI 0 "s_register_operand" "")
10110 (eq:SI (match_operand:SI 1 "s_register_operand" "")
10112 (clobber (reg:CC CC_REGNUM))]
10113 "TARGET_32BIT && reload_completed"
10115 [(set (reg:CC CC_REGNUM)
10116 (compare:CC (const_int 1) (match_dup 1)))
10118 (minus:SI (const_int 1) (match_dup 1)))])
10119 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
10120 (set (match_dup 0) (const_int 0)))])
10123 [(set (match_operand:SI 0 "s_register_operand" "")
10124 (ne:SI (match_operand:SI 1 "s_register_operand" "")
10125 (match_operand:SI 2 "const_int_operand" "")))
10126 (clobber (reg:CC CC_REGNUM))]
10127 "TARGET_32BIT && reload_completed"
10129 [(set (reg:CC CC_REGNUM)
10130 (compare:CC (match_dup 1) (match_dup 2)))
10131 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
10132 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
10133 (set (match_dup 0) (const_int 1)))]
10135 operands[3] = GEN_INT (-INTVAL (operands[2]));
10139 [(set (match_operand:SI 0 "s_register_operand" "")
10140 (ne:SI (match_operand:SI 1 "s_register_operand" "")
10141 (match_operand:SI 2 "arm_add_operand" "")))
10142 (clobber (reg:CC CC_REGNUM))]
10143 "TARGET_32BIT && reload_completed"
10145 [(set (reg:CC_NOOV CC_REGNUM)
10146 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
10148 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
10149 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
10150 (set (match_dup 0) (const_int 1)))])
10152 (define_insn_and_split "*compare_scc"
10153 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
10154 (match_operator:SI 1 "arm_comparison_operator"
10155 [(match_operand:SI 2 "s_register_operand" "r,r")
10156 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
10157 (clobber (reg:CC CC_REGNUM))]
10160 "&& reload_completed"
10161 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
10162 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
10163 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
10166 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10167 operands[2], operands[3]);
10168 enum rtx_code rc = GET_CODE (operands[1]);
10170 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
10172 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
10173 if (mode == CCFPmode || mode == CCFPEmode)
10174 rc = reverse_condition_maybe_unordered (rc);
10176 rc = reverse_condition (rc);
10177 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
10179 [(set_attr "type" "multiple")]
10182 ;; Attempt to improve the sequence generated by the compare_scc splitters
10183 ;; not to use conditional execution.
10185 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
10189 [(set (reg:CC CC_REGNUM)
10190 (compare:CC (match_operand:SI 1 "register_operand" "")
10192 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10193 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10194 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10195 (set (match_dup 0) (const_int 1)))]
10196 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10197 [(set (match_dup 0) (clz:SI (match_dup 1)))
10198 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10201 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
10203 ;; adc Rd, Rd, reg1
10205 [(set (reg:CC CC_REGNUM)
10206 (compare:CC (match_operand:SI 1 "register_operand" "")
10208 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10209 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10210 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10211 (set (match_dup 0) (const_int 1)))
10212 (match_scratch:SI 2 "r")]
10213 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10215 [(set (reg:CC CC_REGNUM)
10216 (compare:CC (const_int 0) (match_dup 1)))
10217 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
10219 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
10220 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
10223 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
10224 ;; sub Rd, Reg1, reg2
10228 [(set (reg:CC CC_REGNUM)
10229 (compare:CC (match_operand:SI 1 "register_operand" "")
10230 (match_operand:SI 2 "arm_rhs_operand" "")))
10231 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10232 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10233 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10234 (set (match_dup 0) (const_int 1)))]
10235 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
10236 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
10237 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
10238 (set (match_dup 0) (clz:SI (match_dup 0)))
10239 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
10243 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
10244 ;; sub T1, Reg1, reg2
10248 [(set (reg:CC CC_REGNUM)
10249 (compare:CC (match_operand:SI 1 "register_operand" "")
10250 (match_operand:SI 2 "arm_rhs_operand" "")))
10251 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
10252 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
10253 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
10254 (set (match_dup 0) (const_int 1)))
10255 (match_scratch:SI 3 "r")]
10256 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
10257 [(set (match_dup 3) (match_dup 4))
10259 [(set (reg:CC CC_REGNUM)
10260 (compare:CC (const_int 0) (match_dup 3)))
10261 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
10263 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
10264 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
10266 if (CONST_INT_P (operands[2]))
10267 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
10269 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
10272 (define_insn "*cond_move"
10273 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10274 (if_then_else:SI (match_operator 3 "equality_operator"
10275 [(match_operator 4 "arm_comparison_operator"
10276 [(match_operand 5 "cc_register" "") (const_int 0)])
10278 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10279 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
10282 if (GET_CODE (operands[3]) == NE)
10284 if (which_alternative != 1)
10285 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
10286 if (which_alternative != 0)
10287 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
10290 if (which_alternative != 0)
10291 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10292 if (which_alternative != 1)
10293 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
10296 [(set_attr "conds" "use")
10297 (set_attr "type" "mov_reg,mov_reg,multiple")
10298 (set_attr "length" "4,4,8")]
10301 (define_insn "*cond_arith"
10302 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10303 (match_operator:SI 5 "shiftable_operator"
10304 [(match_operator:SI 4 "arm_comparison_operator"
10305 [(match_operand:SI 2 "s_register_operand" "r,r")
10306 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10307 (match_operand:SI 1 "s_register_operand" "0,?r")]))
10308 (clobber (reg:CC CC_REGNUM))]
10311 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
10312 return \"%i5\\t%0, %1, %2, lsr #31\";
10314 output_asm_insn (\"cmp\\t%2, %3\", operands);
10315 if (GET_CODE (operands[5]) == AND)
10316 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
10317 else if (GET_CODE (operands[5]) == MINUS)
10318 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
10319 else if (which_alternative != 0)
10320 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10321 return \"%i5%d4\\t%0, %1, #1\";
10323 [(set_attr "conds" "clob")
10324 (set_attr "length" "12")
10325 (set_attr "type" "multiple")]
10328 (define_insn "*cond_sub"
10329 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10330 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
10331 (match_operator:SI 4 "arm_comparison_operator"
10332 [(match_operand:SI 2 "s_register_operand" "r,r")
10333 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10334 (clobber (reg:CC CC_REGNUM))]
10337 output_asm_insn (\"cmp\\t%2, %3\", operands);
10338 if (which_alternative != 0)
10339 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
10340 return \"sub%d4\\t%0, %1, #1\";
10342 [(set_attr "conds" "clob")
10343 (set_attr "length" "8,12")
10344 (set_attr "type" "multiple")]
10347 (define_insn "*cmp_ite0"
10348 [(set (match_operand 6 "dominant_cc_register" "")
10351 (match_operator 4 "arm_comparison_operator"
10352 [(match_operand:SI 0 "s_register_operand"
10353 "l,l,l,r,r,r,r,r,r")
10354 (match_operand:SI 1 "arm_add_operand"
10355 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10356 (match_operator:SI 5 "arm_comparison_operator"
10357 [(match_operand:SI 2 "s_register_operand"
10358 "l,r,r,l,l,r,r,r,r")
10359 (match_operand:SI 3 "arm_add_operand"
10360 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
10366 static const char * const cmp1[NUM_OF_COND_CMP][2] =
10368 {\"cmp%d5\\t%0, %1\",
10369 \"cmp%d4\\t%2, %3\"},
10370 {\"cmn%d5\\t%0, #%n1\",
10371 \"cmp%d4\\t%2, %3\"},
10372 {\"cmp%d5\\t%0, %1\",
10373 \"cmn%d4\\t%2, #%n3\"},
10374 {\"cmn%d5\\t%0, #%n1\",
10375 \"cmn%d4\\t%2, #%n3\"}
10377 static const char * const cmp2[NUM_OF_COND_CMP][2] =
10382 \"cmn\\t%0, #%n1\"},
10383 {\"cmn\\t%2, #%n3\",
10385 {\"cmn\\t%2, #%n3\",
10386 \"cmn\\t%0, #%n1\"}
10388 static const char * const ite[2] =
10393 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10394 CMP_CMP, CMN_CMP, CMP_CMP,
10395 CMN_CMP, CMP_CMN, CMN_CMN};
10397 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10399 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10400 if (TARGET_THUMB2) {
10401 output_asm_insn (ite[swap], operands);
10403 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10406 [(set_attr "conds" "set")
10407 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10408 (set_attr "type" "multiple")
10409 (set_attr_alternative "length"
10415 (if_then_else (eq_attr "is_thumb" "no")
10418 (if_then_else (eq_attr "is_thumb" "no")
10421 (if_then_else (eq_attr "is_thumb" "no")
10424 (if_then_else (eq_attr "is_thumb" "no")
10429 (define_insn "*cmp_ite1"
10430 [(set (match_operand 6 "dominant_cc_register" "")
10433 (match_operator 4 "arm_comparison_operator"
10434 [(match_operand:SI 0 "s_register_operand"
10435 "l,l,l,r,r,r,r,r,r")
10436 (match_operand:SI 1 "arm_add_operand"
10437 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10438 (match_operator:SI 5 "arm_comparison_operator"
10439 [(match_operand:SI 2 "s_register_operand"
10440 "l,r,r,l,l,r,r,r,r")
10441 (match_operand:SI 3 "arm_add_operand"
10442 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
10448 static const char * const cmp1[NUM_OF_COND_CMP][2] =
10452 {\"cmn\\t%0, #%n1\",
10455 \"cmn\\t%2, #%n3\"},
10456 {\"cmn\\t%0, #%n1\",
10457 \"cmn\\t%2, #%n3\"}
10459 static const char * const cmp2[NUM_OF_COND_CMP][2] =
10461 {\"cmp%d4\\t%2, %3\",
10462 \"cmp%D5\\t%0, %1\"},
10463 {\"cmp%d4\\t%2, %3\",
10464 \"cmn%D5\\t%0, #%n1\"},
10465 {\"cmn%d4\\t%2, #%n3\",
10466 \"cmp%D5\\t%0, %1\"},
10467 {\"cmn%d4\\t%2, #%n3\",
10468 \"cmn%D5\\t%0, #%n1\"}
10470 static const char * const ite[2] =
10475 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10476 CMP_CMP, CMN_CMP, CMP_CMP,
10477 CMN_CMP, CMP_CMN, CMN_CMN};
10479 comparison_dominates_p (GET_CODE (operands[5]),
10480 reverse_condition (GET_CODE (operands[4])));
10482 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10483 if (TARGET_THUMB2) {
10484 output_asm_insn (ite[swap], operands);
10486 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10489 [(set_attr "conds" "set")
10490 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10491 (set_attr_alternative "length"
10497 (if_then_else (eq_attr "is_thumb" "no")
10500 (if_then_else (eq_attr "is_thumb" "no")
10503 (if_then_else (eq_attr "is_thumb" "no")
10506 (if_then_else (eq_attr "is_thumb" "no")
10509 (set_attr "type" "multiple")]
10512 (define_insn "*cmp_and"
10513 [(set (match_operand 6 "dominant_cc_register" "")
10516 (match_operator 4 "arm_comparison_operator"
10517 [(match_operand:SI 0 "s_register_operand"
10518 "l,l,l,r,r,r,r,r,r")
10519 (match_operand:SI 1 "arm_add_operand"
10520 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10521 (match_operator:SI 5 "arm_comparison_operator"
10522 [(match_operand:SI 2 "s_register_operand"
10523 "l,r,r,l,l,r,r,r,r")
10524 (match_operand:SI 3 "arm_add_operand"
10525 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
10530 static const char *const cmp1[NUM_OF_COND_CMP][2] =
10532 {\"cmp%d5\\t%0, %1\",
10533 \"cmp%d4\\t%2, %3\"},
10534 {\"cmn%d5\\t%0, #%n1\",
10535 \"cmp%d4\\t%2, %3\"},
10536 {\"cmp%d5\\t%0, %1\",
10537 \"cmn%d4\\t%2, #%n3\"},
10538 {\"cmn%d5\\t%0, #%n1\",
10539 \"cmn%d4\\t%2, #%n3\"}
10541 static const char *const cmp2[NUM_OF_COND_CMP][2] =
10546 \"cmn\\t%0, #%n1\"},
10547 {\"cmn\\t%2, #%n3\",
10549 {\"cmn\\t%2, #%n3\",
10550 \"cmn\\t%0, #%n1\"}
10552 static const char *const ite[2] =
10557 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10558 CMP_CMP, CMN_CMP, CMP_CMP,
10559 CMN_CMP, CMP_CMN, CMN_CMN};
10561 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10563 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10564 if (TARGET_THUMB2) {
10565 output_asm_insn (ite[swap], operands);
10567 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10570 [(set_attr "conds" "set")
10571 (set_attr "predicable" "no")
10572 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10573 (set_attr_alternative "length"
10579 (if_then_else (eq_attr "is_thumb" "no")
10582 (if_then_else (eq_attr "is_thumb" "no")
10585 (if_then_else (eq_attr "is_thumb" "no")
10588 (if_then_else (eq_attr "is_thumb" "no")
10591 (set_attr "type" "multiple")]
10594 (define_insn "*cmp_ior"
10595 [(set (match_operand 6 "dominant_cc_register" "")
10598 (match_operator 4 "arm_comparison_operator"
10599 [(match_operand:SI 0 "s_register_operand"
10600 "l,l,l,r,r,r,r,r,r")
10601 (match_operand:SI 1 "arm_add_operand"
10602 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
10603 (match_operator:SI 5 "arm_comparison_operator"
10604 [(match_operand:SI 2 "s_register_operand"
10605 "l,r,r,l,l,r,r,r,r")
10606 (match_operand:SI 3 "arm_add_operand"
10607 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
10612 static const char *const cmp1[NUM_OF_COND_CMP][2] =
10616 {\"cmn\\t%0, #%n1\",
10619 \"cmn\\t%2, #%n3\"},
10620 {\"cmn\\t%0, #%n1\",
10621 \"cmn\\t%2, #%n3\"}
10623 static const char *const cmp2[NUM_OF_COND_CMP][2] =
10625 {\"cmp%D4\\t%2, %3\",
10626 \"cmp%D5\\t%0, %1\"},
10627 {\"cmp%D4\\t%2, %3\",
10628 \"cmn%D5\\t%0, #%n1\"},
10629 {\"cmn%D4\\t%2, #%n3\",
10630 \"cmp%D5\\t%0, %1\"},
10631 {\"cmn%D4\\t%2, #%n3\",
10632 \"cmn%D5\\t%0, #%n1\"}
10634 static const char *const ite[2] =
10639 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
10640 CMP_CMP, CMN_CMP, CMP_CMP,
10641 CMN_CMP, CMP_CMN, CMN_CMN};
10643 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
10645 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
10646 if (TARGET_THUMB2) {
10647 output_asm_insn (ite[swap], operands);
10649 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
10653 [(set_attr "conds" "set")
10654 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
10655 (set_attr_alternative "length"
10661 (if_then_else (eq_attr "is_thumb" "no")
10664 (if_then_else (eq_attr "is_thumb" "no")
10667 (if_then_else (eq_attr "is_thumb" "no")
10670 (if_then_else (eq_attr "is_thumb" "no")
10673 (set_attr "type" "multiple")]
10676 (define_insn_and_split "*ior_scc_scc"
10677 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
10678 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
10679 [(match_operand:SI 1 "s_register_operand" "r")
10680 (match_operand:SI 2 "arm_add_operand" "rIL")])
10681 (match_operator:SI 6 "arm_comparison_operator"
10682 [(match_operand:SI 4 "s_register_operand" "r")
10683 (match_operand:SI 5 "arm_add_operand" "rIL")])))
10684 (clobber (reg:CC CC_REGNUM))]
10686 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
10689 "TARGET_32BIT && reload_completed"
10690 [(set (match_dup 7)
10693 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10694 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10696 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10698 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10701 [(set_attr "conds" "clob")
10702 (set_attr "length" "16")
10703 (set_attr "type" "multiple")]
10706 ; If the above pattern is followed by a CMP insn, then the compare is
10707 ; redundant, since we can rework the conditional instruction that follows.
10708 (define_insn_and_split "*ior_scc_scc_cmp"
10709 [(set (match_operand 0 "dominant_cc_register" "")
10710 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
10711 [(match_operand:SI 1 "s_register_operand" "r")
10712 (match_operand:SI 2 "arm_add_operand" "rIL")])
10713 (match_operator:SI 6 "arm_comparison_operator"
10714 [(match_operand:SI 4 "s_register_operand" "r")
10715 (match_operand:SI 5 "arm_add_operand" "rIL")]))
10717 (set (match_operand:SI 7 "s_register_operand" "=Ts")
10718 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10719 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
10722 "TARGET_32BIT && reload_completed"
10723 [(set (match_dup 0)
10726 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10727 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10729 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10731 [(set_attr "conds" "set")
10732 (set_attr "length" "16")
10733 (set_attr "type" "multiple")]
10736 (define_insn_and_split "*and_scc_scc"
10737 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
10738 (and:SI (match_operator:SI 3 "arm_comparison_operator"
10739 [(match_operand:SI 1 "s_register_operand" "r")
10740 (match_operand:SI 2 "arm_add_operand" "rIL")])
10741 (match_operator:SI 6 "arm_comparison_operator"
10742 [(match_operand:SI 4 "s_register_operand" "r")
10743 (match_operand:SI 5 "arm_add_operand" "rIL")])))
10744 (clobber (reg:CC CC_REGNUM))]
10746 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10749 "TARGET_32BIT && reload_completed
10750 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10752 [(set (match_dup 7)
10755 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10756 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10758 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
10760 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
10763 [(set_attr "conds" "clob")
10764 (set_attr "length" "16")
10765 (set_attr "type" "multiple")]
10768 ; If the above pattern is followed by a CMP insn, then the compare is
10769 ; redundant, since we can rework the conditional instruction that follows.
10770 (define_insn_and_split "*and_scc_scc_cmp"
10771 [(set (match_operand 0 "dominant_cc_register" "")
10772 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
10773 [(match_operand:SI 1 "s_register_operand" "r")
10774 (match_operand:SI 2 "arm_add_operand" "rIL")])
10775 (match_operator:SI 6 "arm_comparison_operator"
10776 [(match_operand:SI 4 "s_register_operand" "r")
10777 (match_operand:SI 5 "arm_add_operand" "rIL")]))
10779 (set (match_operand:SI 7 "s_register_operand" "=Ts")
10780 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10781 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
10784 "TARGET_32BIT && reload_completed"
10785 [(set (match_dup 0)
10788 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
10789 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
10791 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
10793 [(set_attr "conds" "set")
10794 (set_attr "length" "16")
10795 (set_attr "type" "multiple")]
10798 ;; If there is no dominance in the comparison, then we can still save an
10799 ;; instruction in the AND case, since we can know that the second compare
10800 ;; need only zero the value if false (if true, then the value is already
10802 (define_insn_and_split "*and_scc_scc_nodom"
10803 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
10804 (and:SI (match_operator:SI 3 "arm_comparison_operator"
10805 [(match_operand:SI 1 "s_register_operand" "r,r,0")
10806 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
10807 (match_operator:SI 6 "arm_comparison_operator"
10808 [(match_operand:SI 4 "s_register_operand" "r,r,r")
10809 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
10810 (clobber (reg:CC CC_REGNUM))]
10812 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10815 "TARGET_32BIT && reload_completed"
10816 [(parallel [(set (match_dup 0)
10817 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
10818 (clobber (reg:CC CC_REGNUM))])
10819 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
10821 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
10824 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
10825 operands[4], operands[5]),
10827 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
10829 [(set_attr "conds" "clob")
10830 (set_attr "length" "20")
10831 (set_attr "type" "multiple")]
10835 [(set (reg:CC_NOOV CC_REGNUM)
10836 (compare:CC_NOOV (ior:SI
10837 (and:SI (match_operand:SI 0 "s_register_operand" "")
10839 (match_operator:SI 1 "arm_comparison_operator"
10840 [(match_operand:SI 2 "s_register_operand" "")
10841 (match_operand:SI 3 "arm_add_operand" "")]))
10843 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10845 [(set (match_dup 4)
10846 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10848 (set (reg:CC_NOOV CC_REGNUM)
10849 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10854 [(set (reg:CC_NOOV CC_REGNUM)
10855 (compare:CC_NOOV (ior:SI
10856 (match_operator:SI 1 "arm_comparison_operator"
10857 [(match_operand:SI 2 "s_register_operand" "")
10858 (match_operand:SI 3 "arm_add_operand" "")])
10859 (and:SI (match_operand:SI 0 "s_register_operand" "")
10862 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10864 [(set (match_dup 4)
10865 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10867 (set (reg:CC_NOOV CC_REGNUM)
10868 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10871 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10873 (define_insn_and_split "*negscc"
10874 [(set (match_operand:SI 0 "s_register_operand" "=r")
10875 (neg:SI (match_operator 3 "arm_comparison_operator"
10876 [(match_operand:SI 1 "s_register_operand" "r")
10877 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10878 (clobber (reg:CC CC_REGNUM))]
10881 "&& reload_completed"
10884 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10886 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10888 /* Emit mov\\t%0, %1, asr #31 */
10889 emit_insn (gen_rtx_SET (VOIDmode,
10891 gen_rtx_ASHIFTRT (SImode,
10896 else if (GET_CODE (operands[3]) == NE)
10898 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10899 if (CONST_INT_P (operands[2]))
10900 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10901 GEN_INT (- INTVAL (operands[2]))));
10903 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10905 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10906 gen_rtx_NE (SImode,
10909 gen_rtx_SET (SImode,
10916 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10917 emit_insn (gen_rtx_SET (VOIDmode,
10919 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10920 enum rtx_code rc = GET_CODE (operands[3]);
10922 rc = reverse_condition (rc);
10923 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10924 gen_rtx_fmt_ee (rc,
10928 gen_rtx_SET (VOIDmode, operands[0], const0_rtx)));
10929 rc = GET_CODE (operands[3]);
10930 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10931 gen_rtx_fmt_ee (rc,
10935 gen_rtx_SET (VOIDmode,
10942 [(set_attr "conds" "clob")
10943 (set_attr "length" "12")
10944 (set_attr "type" "multiple")]
10947 (define_insn_and_split "movcond_addsi"
10948 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
10950 (match_operator 5 "comparison_operator"
10951 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
10952 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
10954 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
10955 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
10956 (clobber (reg:CC CC_REGNUM))]
10959 "&& reload_completed"
10960 [(set (reg:CC_NOOV CC_REGNUM)
10962 (plus:SI (match_dup 3)
10965 (set (match_dup 0) (match_dup 1))
10966 (cond_exec (match_dup 6)
10967 (set (match_dup 0) (match_dup 2)))]
10970 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
10971 operands[3], operands[4]);
10972 enum rtx_code rc = GET_CODE (operands[5]);
10973 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10974 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
10975 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
10976 rc = reverse_condition (rc);
10979 rtx tmp = operands[1];
10980 operands[1] = operands[2];
10984 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10987 [(set_attr "conds" "clob")
10988 (set_attr "enabled_for_depr_it" "no,yes,yes")
10989 (set_attr "type" "multiple")]
10992 (define_insn "movcond"
10993 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10995 (match_operator 5 "arm_comparison_operator"
10996 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10997 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
10998 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10999 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
11000 (clobber (reg:CC CC_REGNUM))]
11003 if (GET_CODE (operands[5]) == LT
11004 && (operands[4] == const0_rtx))
11006 if (which_alternative != 1 && REG_P (operands[1]))
11008 if (operands[2] == const0_rtx)
11009 return \"and\\t%0, %1, %3, asr #31\";
11010 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
11012 else if (which_alternative != 0 && REG_P (operands[2]))
11014 if (operands[1] == const0_rtx)
11015 return \"bic\\t%0, %2, %3, asr #31\";
11016 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
11018 /* The only case that falls through to here is when both ops 1 & 2
11022 if (GET_CODE (operands[5]) == GE
11023 && (operands[4] == const0_rtx))
11025 if (which_alternative != 1 && REG_P (operands[1]))
11027 if (operands[2] == const0_rtx)
11028 return \"bic\\t%0, %1, %3, asr #31\";
11029 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
11031 else if (which_alternative != 0 && REG_P (operands[2]))
11033 if (operands[1] == const0_rtx)
11034 return \"and\\t%0, %2, %3, asr #31\";
11035 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
11037 /* The only case that falls through to here is when both ops 1 & 2
11040 if (CONST_INT_P (operands[4])
11041 && !const_ok_for_arm (INTVAL (operands[4])))
11042 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
11044 output_asm_insn (\"cmp\\t%3, %4\", operands);
11045 if (which_alternative != 0)
11046 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
11047 if (which_alternative != 1)
11048 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
11051 [(set_attr "conds" "clob")
11052 (set_attr "length" "8,8,12")
11053 (set_attr "type" "multiple")]
11056 ;; ??? The patterns below need checking for Thumb-2 usefulness.
11058 (define_insn "*ifcompare_plus_move"
11059 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11060 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11061 [(match_operand:SI 4 "s_register_operand" "r,r")
11062 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11064 (match_operand:SI 2 "s_register_operand" "r,r")
11065 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
11066 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
11067 (clobber (reg:CC CC_REGNUM))]
11070 [(set_attr "conds" "clob")
11071 (set_attr "length" "8,12")
11072 (set_attr "type" "multiple")]
11075 (define_insn "*if_plus_move"
11076 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
11078 (match_operator 4 "arm_comparison_operator"
11079 [(match_operand 5 "cc_register" "") (const_int 0)])
11081 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
11082 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
11083 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
11086 add%d4\\t%0, %2, %3
11087 sub%d4\\t%0, %2, #%n3
11088 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
11089 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
11090 [(set_attr "conds" "use")
11091 (set_attr "length" "4,4,8,8")
11092 (set_attr_alternative "type"
11093 [(if_then_else (match_operand 3 "const_int_operand" "")
11094 (const_string "alu_imm" )
11095 (const_string "alu_reg"))
11096 (const_string "alu_imm")
11097 (const_string "alu_reg")
11098 (const_string "alu_reg")])]
11101 (define_insn "*ifcompare_move_plus"
11102 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11103 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11104 [(match_operand:SI 4 "s_register_operand" "r,r")
11105 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11106 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11108 (match_operand:SI 2 "s_register_operand" "r,r")
11109 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
11110 (clobber (reg:CC CC_REGNUM))]
11113 [(set_attr "conds" "clob")
11114 (set_attr "length" "8,12")
11115 (set_attr "type" "multiple")]
11118 (define_insn "*if_move_plus"
11119 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
11121 (match_operator 4 "arm_comparison_operator"
11122 [(match_operand 5 "cc_register" "") (const_int 0)])
11123 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
11125 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
11126 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
11129 add%D4\\t%0, %2, %3
11130 sub%D4\\t%0, %2, #%n3
11131 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
11132 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
11133 [(set_attr "conds" "use")
11134 (set_attr "length" "4,4,8,8")
11135 (set_attr "type" "alu_reg,alu_imm,multiple,multiple")]
11138 (define_insn "*ifcompare_arith_arith"
11139 [(set (match_operand:SI 0 "s_register_operand" "=r")
11140 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
11141 [(match_operand:SI 5 "s_register_operand" "r")
11142 (match_operand:SI 6 "arm_add_operand" "rIL")])
11143 (match_operator:SI 8 "shiftable_operator"
11144 [(match_operand:SI 1 "s_register_operand" "r")
11145 (match_operand:SI 2 "arm_rhs_operand" "rI")])
11146 (match_operator:SI 7 "shiftable_operator"
11147 [(match_operand:SI 3 "s_register_operand" "r")
11148 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
11149 (clobber (reg:CC CC_REGNUM))]
11152 [(set_attr "conds" "clob")
11153 (set_attr "length" "12")
11154 (set_attr "type" "multiple")]
11157 (define_insn "*if_arith_arith"
11158 [(set (match_operand:SI 0 "s_register_operand" "=r")
11159 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
11160 [(match_operand 8 "cc_register" "") (const_int 0)])
11161 (match_operator:SI 6 "shiftable_operator"
11162 [(match_operand:SI 1 "s_register_operand" "r")
11163 (match_operand:SI 2 "arm_rhs_operand" "rI")])
11164 (match_operator:SI 7 "shiftable_operator"
11165 [(match_operand:SI 3 "s_register_operand" "r")
11166 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
11168 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
11169 [(set_attr "conds" "use")
11170 (set_attr "length" "8")
11171 (set_attr "type" "multiple")]
11174 (define_insn "*ifcompare_arith_move"
11175 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11176 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11177 [(match_operand:SI 2 "s_register_operand" "r,r")
11178 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
11179 (match_operator:SI 7 "shiftable_operator"
11180 [(match_operand:SI 4 "s_register_operand" "r,r")
11181 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
11182 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
11183 (clobber (reg:CC CC_REGNUM))]
11186 /* If we have an operation where (op x 0) is the identity operation and
11187 the conditional operator is LT or GE and we are comparing against zero and
11188 everything is in registers then we can do this in two instructions. */
11189 if (operands[3] == const0_rtx
11190 && GET_CODE (operands[7]) != AND
11191 && REG_P (operands[5])
11192 && REG_P (operands[1])
11193 && REGNO (operands[1]) == REGNO (operands[4])
11194 && REGNO (operands[4]) != REGNO (operands[0]))
11196 if (GET_CODE (operands[6]) == LT)
11197 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
11198 else if (GET_CODE (operands[6]) == GE)
11199 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
11201 if (CONST_INT_P (operands[3])
11202 && !const_ok_for_arm (INTVAL (operands[3])))
11203 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
11205 output_asm_insn (\"cmp\\t%2, %3\", operands);
11206 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
11207 if (which_alternative != 0)
11208 return \"mov%D6\\t%0, %1\";
11211 [(set_attr "conds" "clob")
11212 (set_attr "length" "8,12")
11213 (set_attr "type" "multiple")]
11216 (define_insn "*if_arith_move"
11217 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11218 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11219 [(match_operand 6 "cc_register" "") (const_int 0)])
11220 (match_operator:SI 5 "shiftable_operator"
11221 [(match_operand:SI 2 "s_register_operand" "r,r")
11222 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
11223 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
11226 %I5%d4\\t%0, %2, %3
11227 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
11228 [(set_attr "conds" "use")
11229 (set_attr "length" "4,8")
11230 (set_attr "type" "alu_shift_reg,multiple")]
11233 (define_insn "*ifcompare_move_arith"
11234 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11235 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
11236 [(match_operand:SI 4 "s_register_operand" "r,r")
11237 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11238 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11239 (match_operator:SI 7 "shiftable_operator"
11240 [(match_operand:SI 2 "s_register_operand" "r,r")
11241 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
11242 (clobber (reg:CC CC_REGNUM))]
11245 /* If we have an operation where (op x 0) is the identity operation and
11246 the conditional operator is LT or GE and we are comparing against zero and
11247 everything is in registers then we can do this in two instructions */
11248 if (operands[5] == const0_rtx
11249 && GET_CODE (operands[7]) != AND
11250 && REG_P (operands[3])
11251 && REG_P (operands[1])
11252 && REGNO (operands[1]) == REGNO (operands[2])
11253 && REGNO (operands[2]) != REGNO (operands[0]))
11255 if (GET_CODE (operands[6]) == GE)
11256 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
11257 else if (GET_CODE (operands[6]) == LT)
11258 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
11261 if (CONST_INT_P (operands[5])
11262 && !const_ok_for_arm (INTVAL (operands[5])))
11263 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
11265 output_asm_insn (\"cmp\\t%4, %5\", operands);
11267 if (which_alternative != 0)
11268 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
11269 return \"%I7%D6\\t%0, %2, %3\";
11271 [(set_attr "conds" "clob")
11272 (set_attr "length" "8,12")
11273 (set_attr "type" "multiple")]
11276 (define_insn "*if_move_arith"
11277 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11279 (match_operator 4 "arm_comparison_operator"
11280 [(match_operand 6 "cc_register" "") (const_int 0)])
11281 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11282 (match_operator:SI 5 "shiftable_operator"
11283 [(match_operand:SI 2 "s_register_operand" "r,r")
11284 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
11287 %I5%D4\\t%0, %2, %3
11288 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
11289 [(set_attr "conds" "use")
11290 (set_attr "length" "4,8")
11291 (set_attr "type" "alu_shift_reg,multiple")]
11294 (define_insn "*ifcompare_move_not"
11295 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11297 (match_operator 5 "arm_comparison_operator"
11298 [(match_operand:SI 3 "s_register_operand" "r,r")
11299 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11300 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11302 (match_operand:SI 2 "s_register_operand" "r,r"))))
11303 (clobber (reg:CC CC_REGNUM))]
11306 [(set_attr "conds" "clob")
11307 (set_attr "length" "8,12")
11308 (set_attr "type" "multiple")]
11311 (define_insn "*if_move_not"
11312 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11314 (match_operator 4 "arm_comparison_operator"
11315 [(match_operand 3 "cc_register" "") (const_int 0)])
11316 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11317 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
11321 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
11322 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
11323 [(set_attr "conds" "use")
11324 (set_attr "type" "mvn_reg")
11325 (set_attr "length" "4,8,8")
11326 (set_attr "type" "mvn_reg,multiple,multiple")]
11329 (define_insn "*ifcompare_not_move"
11330 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11332 (match_operator 5 "arm_comparison_operator"
11333 [(match_operand:SI 3 "s_register_operand" "r,r")
11334 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11336 (match_operand:SI 2 "s_register_operand" "r,r"))
11337 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11338 (clobber (reg:CC CC_REGNUM))]
11341 [(set_attr "conds" "clob")
11342 (set_attr "length" "8,12")
11343 (set_attr "type" "multiple")]
11346 (define_insn "*if_not_move"
11347 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11349 (match_operator 4 "arm_comparison_operator"
11350 [(match_operand 3 "cc_register" "") (const_int 0)])
11351 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
11352 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11356 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
11357 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
11358 [(set_attr "conds" "use")
11359 (set_attr "type" "mvn_reg,multiple,multiple")
11360 (set_attr "length" "4,8,8")]
11363 (define_insn "*ifcompare_shift_move"
11364 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11366 (match_operator 6 "arm_comparison_operator"
11367 [(match_operand:SI 4 "s_register_operand" "r,r")
11368 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11369 (match_operator:SI 7 "shift_operator"
11370 [(match_operand:SI 2 "s_register_operand" "r,r")
11371 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
11372 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11373 (clobber (reg:CC CC_REGNUM))]
11376 [(set_attr "conds" "clob")
11377 (set_attr "length" "8,12")
11378 (set_attr "type" "multiple")]
11381 (define_insn "*if_shift_move"
11382 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11384 (match_operator 5 "arm_comparison_operator"
11385 [(match_operand 6 "cc_register" "") (const_int 0)])
11386 (match_operator:SI 4 "shift_operator"
11387 [(match_operand:SI 2 "s_register_operand" "r,r,r")
11388 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
11389 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11393 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
11394 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
11395 [(set_attr "conds" "use")
11396 (set_attr "shift" "2")
11397 (set_attr "length" "4,8,8")
11398 (set_attr "type" "mov_shift_reg,multiple,multiple")]
11401 (define_insn "*ifcompare_move_shift"
11402 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11404 (match_operator 6 "arm_comparison_operator"
11405 [(match_operand:SI 4 "s_register_operand" "r,r")
11406 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
11407 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11408 (match_operator:SI 7 "shift_operator"
11409 [(match_operand:SI 2 "s_register_operand" "r,r")
11410 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
11411 (clobber (reg:CC CC_REGNUM))]
11414 [(set_attr "conds" "clob")
11415 (set_attr "length" "8,12")
11416 (set_attr "type" "multiple")]
11419 (define_insn "*if_move_shift"
11420 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11422 (match_operator 5 "arm_comparison_operator"
11423 [(match_operand 6 "cc_register" "") (const_int 0)])
11424 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11425 (match_operator:SI 4 "shift_operator"
11426 [(match_operand:SI 2 "s_register_operand" "r,r,r")
11427 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
11431 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
11432 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
11433 [(set_attr "conds" "use")
11434 (set_attr "shift" "2")
11435 (set_attr "length" "4,8,8")
11436 (set_attr "type" "mov_shift_reg,multiple,multiple")]
11439 (define_insn "*ifcompare_shift_shift"
11440 [(set (match_operand:SI 0 "s_register_operand" "=r")
11442 (match_operator 7 "arm_comparison_operator"
11443 [(match_operand:SI 5 "s_register_operand" "r")
11444 (match_operand:SI 6 "arm_add_operand" "rIL")])
11445 (match_operator:SI 8 "shift_operator"
11446 [(match_operand:SI 1 "s_register_operand" "r")
11447 (match_operand:SI 2 "arm_rhs_operand" "rM")])
11448 (match_operator:SI 9 "shift_operator"
11449 [(match_operand:SI 3 "s_register_operand" "r")
11450 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
11451 (clobber (reg:CC CC_REGNUM))]
11454 [(set_attr "conds" "clob")
11455 (set_attr "length" "12")
11456 (set_attr "type" "multiple")]
11459 (define_insn "*if_shift_shift"
11460 [(set (match_operand:SI 0 "s_register_operand" "=r")
11462 (match_operator 5 "arm_comparison_operator"
11463 [(match_operand 8 "cc_register" "") (const_int 0)])
11464 (match_operator:SI 6 "shift_operator"
11465 [(match_operand:SI 1 "s_register_operand" "r")
11466 (match_operand:SI 2 "arm_rhs_operand" "rM")])
11467 (match_operator:SI 7 "shift_operator"
11468 [(match_operand:SI 3 "s_register_operand" "r")
11469 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
11471 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
11472 [(set_attr "conds" "use")
11473 (set_attr "shift" "1")
11474 (set_attr "length" "8")
11475 (set (attr "type") (if_then_else
11476 (and (match_operand 2 "const_int_operand" "")
11477 (match_operand 4 "const_int_operand" ""))
11478 (const_string "mov_shift")
11479 (const_string "mov_shift_reg")))]
11482 (define_insn "*ifcompare_not_arith"
11483 [(set (match_operand:SI 0 "s_register_operand" "=r")
11485 (match_operator 6 "arm_comparison_operator"
11486 [(match_operand:SI 4 "s_register_operand" "r")
11487 (match_operand:SI 5 "arm_add_operand" "rIL")])
11488 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
11489 (match_operator:SI 7 "shiftable_operator"
11490 [(match_operand:SI 2 "s_register_operand" "r")
11491 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
11492 (clobber (reg:CC CC_REGNUM))]
11495 [(set_attr "conds" "clob")
11496 (set_attr "length" "12")
11497 (set_attr "type" "multiple")]
11500 (define_insn "*if_not_arith"
11501 [(set (match_operand:SI 0 "s_register_operand" "=r")
11503 (match_operator 5 "arm_comparison_operator"
11504 [(match_operand 4 "cc_register" "") (const_int 0)])
11505 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
11506 (match_operator:SI 6 "shiftable_operator"
11507 [(match_operand:SI 2 "s_register_operand" "r")
11508 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
11510 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
11511 [(set_attr "conds" "use")
11512 (set_attr "type" "mvn_reg")
11513 (set_attr "length" "8")]
11516 (define_insn "*ifcompare_arith_not"
11517 [(set (match_operand:SI 0 "s_register_operand" "=r")
11519 (match_operator 6 "arm_comparison_operator"
11520 [(match_operand:SI 4 "s_register_operand" "r")
11521 (match_operand:SI 5 "arm_add_operand" "rIL")])
11522 (match_operator:SI 7 "shiftable_operator"
11523 [(match_operand:SI 2 "s_register_operand" "r")
11524 (match_operand:SI 3 "arm_rhs_operand" "rI")])
11525 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
11526 (clobber (reg:CC CC_REGNUM))]
11529 [(set_attr "conds" "clob")
11530 (set_attr "length" "12")
11531 (set_attr "type" "multiple")]
11534 (define_insn "*if_arith_not"
11535 [(set (match_operand:SI 0 "s_register_operand" "=r")
11537 (match_operator 5 "arm_comparison_operator"
11538 [(match_operand 4 "cc_register" "") (const_int 0)])
11539 (match_operator:SI 6 "shiftable_operator"
11540 [(match_operand:SI 2 "s_register_operand" "r")
11541 (match_operand:SI 3 "arm_rhs_operand" "rI")])
11542 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
11544 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
11545 [(set_attr "conds" "use")
11546 (set_attr "type" "multiple")
11547 (set_attr "length" "8")]
11550 (define_insn "*ifcompare_neg_move"
11551 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11553 (match_operator 5 "arm_comparison_operator"
11554 [(match_operand:SI 3 "s_register_operand" "r,r")
11555 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11556 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
11557 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
11558 (clobber (reg:CC CC_REGNUM))]
11561 [(set_attr "conds" "clob")
11562 (set_attr "length" "8,12")
11563 (set_attr "type" "multiple")]
11566 (define_insn "*if_neg_move"
11567 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11569 (match_operator 4 "arm_comparison_operator"
11570 [(match_operand 3 "cc_register" "") (const_int 0)])
11571 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
11572 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
11575 rsb%d4\\t%0, %2, #0
11576 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
11577 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
11578 [(set_attr "conds" "use")
11579 (set_attr "length" "4,8,8")
11580 (set_attr "type" "logic_shift_imm,multiple,multiple")]
11583 (define_insn "*ifcompare_move_neg"
11584 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11586 (match_operator 5 "arm_comparison_operator"
11587 [(match_operand:SI 3 "s_register_operand" "r,r")
11588 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
11589 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
11590 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
11591 (clobber (reg:CC CC_REGNUM))]
11594 [(set_attr "conds" "clob")
11595 (set_attr "length" "8,12")
11596 (set_attr "type" "multiple")]
11599 (define_insn "*if_move_neg"
11600 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
11602 (match_operator 4 "arm_comparison_operator"
11603 [(match_operand 3 "cc_register" "") (const_int 0)])
11604 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
11605 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
11608 rsb%D4\\t%0, %2, #0
11609 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
11610 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
11611 [(set_attr "conds" "use")
11612 (set_attr "length" "4,8,8")
11613 (set_attr "type" "logic_shift_imm,multiple,multiple")]
11616 (define_insn "*arith_adjacentmem"
11617 [(set (match_operand:SI 0 "s_register_operand" "=r")
11618 (match_operator:SI 1 "shiftable_operator"
11619 [(match_operand:SI 2 "memory_operand" "m")
11620 (match_operand:SI 3 "memory_operand" "m")]))
11621 (clobber (match_scratch:SI 4 "=r"))]
11622 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
11628 HOST_WIDE_INT val1 = 0, val2 = 0;
11630 if (REGNO (operands[0]) > REGNO (operands[4]))
11632 ldm[1] = operands[4];
11633 ldm[2] = operands[0];
11637 ldm[1] = operands[0];
11638 ldm[2] = operands[4];
11641 base_reg = XEXP (operands[2], 0);
11643 if (!REG_P (base_reg))
11645 val1 = INTVAL (XEXP (base_reg, 1));
11646 base_reg = XEXP (base_reg, 0);
11649 if (!REG_P (XEXP (operands[3], 0)))
11650 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
11652 arith[0] = operands[0];
11653 arith[3] = operands[1];
11667 if (val1 !=0 && val2 != 0)
11671 if (val1 == 4 || val2 == 4)
11672 /* Other val must be 8, since we know they are adjacent and neither
11674 output_asm_insn (\"ldm%(ib%)\\t%0, {%1, %2}\", ldm);
11675 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
11677 ldm[0] = ops[0] = operands[4];
11679 ops[2] = GEN_INT (val1);
11680 output_add_immediate (ops);
11682 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11684 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11688 /* Offset is out of range for a single add, so use two ldr. */
11691 ops[2] = GEN_INT (val1);
11692 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11694 ops[2] = GEN_INT (val2);
11695 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
11698 else if (val1 != 0)
11701 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11703 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11708 output_asm_insn (\"ldm%(ia%)\\t%0, {%1, %2}\", ldm);
11710 output_asm_insn (\"ldm%(da%)\\t%0, {%1, %2}\", ldm);
11712 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
11715 [(set_attr "length" "12")
11716 (set_attr "predicable" "yes")
11717 (set_attr "type" "load1")]
11720 ; This pattern is never tried by combine, so do it as a peephole
11723 [(set (match_operand:SI 0 "arm_general_register_operand" "")
11724 (match_operand:SI 1 "arm_general_register_operand" ""))
11725 (set (reg:CC CC_REGNUM)
11726 (compare:CC (match_dup 1) (const_int 0)))]
11728 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
11729 (set (match_dup 0) (match_dup 1))])]
11734 [(set (match_operand:SI 0 "s_register_operand" "")
11735 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
11737 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
11738 [(match_operand:SI 3 "s_register_operand" "")
11739 (match_operand:SI 4 "arm_rhs_operand" "")]))))
11740 (clobber (match_operand:SI 5 "s_register_operand" ""))]
11742 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
11743 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
11748 ;; This split can be used because CC_Z mode implies that the following
11749 ;; branch will be an equality, or an unsigned inequality, so the sign
11750 ;; extension is not needed.
11753 [(set (reg:CC_Z CC_REGNUM)
11755 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
11757 (match_operand 1 "const_int_operand" "")))
11758 (clobber (match_scratch:SI 2 ""))]
11760 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1]))
11761 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)"
11762 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
11763 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
11765 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
11768 ;; ??? Check the patterns above for Thumb-2 usefulness
11770 (define_expand "prologue"
11771 [(clobber (const_int 0))]
11774 arm_expand_prologue ();
11776 thumb1_expand_prologue ();
11781 (define_expand "epilogue"
11782 [(clobber (const_int 0))]
11785 if (crtl->calls_eh_return)
11786 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
11789 thumb1_expand_epilogue ();
11790 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
11791 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
11793 else if (HAVE_return)
11795 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
11796 no need for explicit testing again. */
11797 emit_jump_insn (gen_return ());
11799 else if (TARGET_32BIT)
11801 arm_expand_epilogue (true);
11807 (define_insn "prologue_thumb1_interwork"
11808 [(unspec_volatile [(const_int 0)] VUNSPEC_THUMB1_INTERWORK)]
11810 "* return thumb1_output_interwork ();"
11811 [(set_attr "length" "8")
11812 (set_attr "type" "multiple")]
11815 ;; Note - although unspec_volatile's USE all hard registers,
11816 ;; USEs are ignored after relaod has completed. Thus we need
11817 ;; to add an unspec of the link register to ensure that flow
11818 ;; does not think that it is unused by the sibcall branch that
11819 ;; will replace the standard function epilogue.
11820 (define_expand "sibcall_epilogue"
11821 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
11822 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
11825 arm_expand_epilogue (false);
11830 (define_insn "*epilogue_insns"
11831 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
11834 return thumb1_unexpanded_epilogue ();
11836 ; Length is absolute worst case
11837 [(set_attr "length" "44")
11838 (set_attr "type" "block")
11839 ;; We don't clobber the conditions, but the potential length of this
11840 ;; operation is sufficient to make conditionalizing the sequence
11841 ;; unlikely to be profitable.
11842 (set_attr "conds" "clob")]
11845 (define_expand "eh_epilogue"
11846 [(use (match_operand:SI 0 "register_operand" ""))
11847 (use (match_operand:SI 1 "register_operand" ""))
11848 (use (match_operand:SI 2 "register_operand" ""))]
11852 cfun->machine->eh_epilogue_sp_ofs = operands[1];
11853 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11855 rtx ra = gen_rtx_REG (Pmode, 2);
11857 emit_move_insn (ra, operands[2]);
11860 /* This is a hack -- we may have crystalized the function type too
11862 cfun->machine->func_type = 0;
11866 ;; This split is only used during output to reduce the number of patterns
11867 ;; that need assembler instructions adding to them. We allowed the setting
11868 ;; of the conditions to be implicit during rtl generation so that
11869 ;; the conditional compare patterns would work. However this conflicts to
11870 ;; some extent with the conditional data operations, so we have to split them
11873 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
11874 ;; conditional execution sufficient?
11877 [(set (match_operand:SI 0 "s_register_operand" "")
11878 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11879 [(match_operand 2 "" "") (match_operand 3 "" "")])
11881 (match_operand 4 "" "")))
11882 (clobber (reg:CC CC_REGNUM))]
11883 "TARGET_ARM && reload_completed"
11884 [(set (match_dup 5) (match_dup 6))
11885 (cond_exec (match_dup 7)
11886 (set (match_dup 0) (match_dup 4)))]
11889 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11890 operands[2], operands[3]);
11891 enum rtx_code rc = GET_CODE (operands[1]);
11893 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11894 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11895 if (mode == CCFPmode || mode == CCFPEmode)
11896 rc = reverse_condition_maybe_unordered (rc);
11898 rc = reverse_condition (rc);
11900 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11905 [(set (match_operand:SI 0 "s_register_operand" "")
11906 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11907 [(match_operand 2 "" "") (match_operand 3 "" "")])
11908 (match_operand 4 "" "")
11910 (clobber (reg:CC CC_REGNUM))]
11911 "TARGET_ARM && reload_completed"
11912 [(set (match_dup 5) (match_dup 6))
11913 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11914 (set (match_dup 0) (match_dup 4)))]
11917 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11918 operands[2], operands[3]);
11920 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11921 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11926 [(set (match_operand:SI 0 "s_register_operand" "")
11927 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11928 [(match_operand 2 "" "") (match_operand 3 "" "")])
11929 (match_operand 4 "" "")
11930 (match_operand 5 "" "")))
11931 (clobber (reg:CC CC_REGNUM))]
11932 "TARGET_ARM && reload_completed"
11933 [(set (match_dup 6) (match_dup 7))
11934 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11935 (set (match_dup 0) (match_dup 4)))
11936 (cond_exec (match_dup 8)
11937 (set (match_dup 0) (match_dup 5)))]
11940 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11941 operands[2], operands[3]);
11942 enum rtx_code rc = GET_CODE (operands[1]);
11944 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11945 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11946 if (mode == CCFPmode || mode == CCFPEmode)
11947 rc = reverse_condition_maybe_unordered (rc);
11949 rc = reverse_condition (rc);
11951 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11956 [(set (match_operand:SI 0 "s_register_operand" "")
11957 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11958 [(match_operand:SI 2 "s_register_operand" "")
11959 (match_operand:SI 3 "arm_add_operand" "")])
11960 (match_operand:SI 4 "arm_rhs_operand" "")
11962 (match_operand:SI 5 "s_register_operand" ""))))
11963 (clobber (reg:CC CC_REGNUM))]
11964 "TARGET_ARM && reload_completed"
11965 [(set (match_dup 6) (match_dup 7))
11966 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11967 (set (match_dup 0) (match_dup 4)))
11968 (cond_exec (match_dup 8)
11969 (set (match_dup 0) (not:SI (match_dup 5))))]
11972 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11973 operands[2], operands[3]);
11974 enum rtx_code rc = GET_CODE (operands[1]);
11976 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11977 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11978 if (mode == CCFPmode || mode == CCFPEmode)
11979 rc = reverse_condition_maybe_unordered (rc);
11981 rc = reverse_condition (rc);
11983 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11987 (define_insn "*cond_move_not"
11988 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11989 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11990 [(match_operand 3 "cc_register" "") (const_int 0)])
11991 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11993 (match_operand:SI 2 "s_register_operand" "r,r"))))]
11997 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11998 [(set_attr "conds" "use")
11999 (set_attr "type" "mvn_reg,multiple")
12000 (set_attr "length" "4,8")]
12003 ;; The next two patterns occur when an AND operation is followed by a
12004 ;; scc insn sequence
12006 (define_insn "*sign_extract_onebit"
12007 [(set (match_operand:SI 0 "s_register_operand" "=r")
12008 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
12010 (match_operand:SI 2 "const_int_operand" "n")))
12011 (clobber (reg:CC CC_REGNUM))]
12014 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
12015 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
12016 return \"mvnne\\t%0, #0\";
12018 [(set_attr "conds" "clob")
12019 (set_attr "length" "8")
12020 (set_attr "type" "multiple")]
12023 (define_insn "*not_signextract_onebit"
12024 [(set (match_operand:SI 0 "s_register_operand" "=r")
12026 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
12028 (match_operand:SI 2 "const_int_operand" "n"))))
12029 (clobber (reg:CC CC_REGNUM))]
12032 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
12033 output_asm_insn (\"tst\\t%1, %2\", operands);
12034 output_asm_insn (\"mvneq\\t%0, #0\", operands);
12035 return \"movne\\t%0, #0\";
12037 [(set_attr "conds" "clob")
12038 (set_attr "length" "12")
12039 (set_attr "type" "multiple")]
12041 ;; ??? The above patterns need auditing for Thumb-2
12043 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
12044 ;; expressions. For simplicity, the first register is also in the unspec
12046 ;; To avoid the usage of GNU extension, the length attribute is computed
12047 ;; in a C function arm_attr_length_push_multi.
12048 (define_insn "*push_multi"
12049 [(match_parallel 2 "multi_register_push"
12050 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
12051 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
12052 UNSPEC_PUSH_MULT))])]
12056 int num_saves = XVECLEN (operands[2], 0);
12058 /* For the StrongARM at least it is faster to
12059 use STR to store only a single register.
12060 In Thumb mode always use push, and the assembler will pick
12061 something appropriate. */
12062 if (num_saves == 1 && TARGET_ARM)
12063 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
12070 strcpy (pattern, \"stm%(fd%)\\t%m0!, {%1\");
12071 else if (TARGET_THUMB2)
12072 strcpy (pattern, \"push%?\\t{%1\");
12074 strcpy (pattern, \"push\\t{%1\");
12076 for (i = 1; i < num_saves; i++)
12078 strcat (pattern, \", %|\");
12080 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
12083 strcat (pattern, \"}\");
12084 output_asm_insn (pattern, operands);
12089 [(set_attr "type" "store4")
12090 (set (attr "length")
12091 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
12094 (define_insn "stack_tie"
12095 [(set (mem:BLK (scratch))
12096 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
12097 (match_operand:SI 1 "s_register_operand" "rk")]
12101 [(set_attr "length" "0")
12102 (set_attr "type" "block")]
12105 ;; Pop (as used in epilogue RTL)
12107 (define_insn "*load_multiple_with_writeback"
12108 [(match_parallel 0 "load_multiple_operation"
12109 [(set (match_operand:SI 1 "s_register_operand" "+rk")
12110 (plus:SI (match_dup 1)
12111 (match_operand:SI 2 "const_int_I_operand" "I")))
12112 (set (match_operand:SI 3 "s_register_operand" "=rk")
12113 (mem:SI (match_dup 1)))
12115 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12118 arm_output_multireg_pop (operands, /*return_pc=*/false,
12119 /*cond=*/const_true_rtx,
12125 [(set_attr "type" "load4")
12126 (set_attr "predicable" "yes")]
12129 ;; Pop with return (as used in epilogue RTL)
12131 ;; This instruction is generated when the registers are popped at the end of
12132 ;; epilogue. Here, instead of popping the value into LR and then generating
12133 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
12135 (define_insn "*pop_multiple_with_writeback_and_return"
12136 [(match_parallel 0 "pop_multiple_return"
12138 (set (match_operand:SI 1 "s_register_operand" "+rk")
12139 (plus:SI (match_dup 1)
12140 (match_operand:SI 2 "const_int_I_operand" "I")))
12141 (set (match_operand:SI 3 "s_register_operand" "=rk")
12142 (mem:SI (match_dup 1)))
12144 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12147 arm_output_multireg_pop (operands, /*return_pc=*/true,
12148 /*cond=*/const_true_rtx,
12154 [(set_attr "type" "load4")
12155 (set_attr "predicable" "yes")]
12158 (define_insn "*pop_multiple_with_return"
12159 [(match_parallel 0 "pop_multiple_return"
12161 (set (match_operand:SI 2 "s_register_operand" "=rk")
12162 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12164 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12167 arm_output_multireg_pop (operands, /*return_pc=*/true,
12168 /*cond=*/const_true_rtx,
12174 [(set_attr "type" "load4")
12175 (set_attr "predicable" "yes")]
12178 ;; Load into PC and return
12179 (define_insn "*ldr_with_return"
12181 (set (reg:SI PC_REGNUM)
12182 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
12183 "TARGET_32BIT && (reload_in_progress || reload_completed)"
12184 "ldr%?\t%|pc, [%0], #4"
12185 [(set_attr "type" "load1")
12186 (set_attr "predicable" "yes")]
12188 ;; Pop for floating point registers (as used in epilogue RTL)
12189 (define_insn "*vfp_pop_multiple_with_writeback"
12190 [(match_parallel 0 "pop_multiple_fp"
12191 [(set (match_operand:SI 1 "s_register_operand" "+rk")
12192 (plus:SI (match_dup 1)
12193 (match_operand:SI 2 "const_int_I_operand" "I")))
12194 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
12195 (mem:DF (match_dup 1)))])]
12196 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
12199 int num_regs = XVECLEN (operands[0], 0);
12202 strcpy (pattern, \"vldm\\t\");
12203 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
12204 strcat (pattern, \"!, {\");
12205 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
12206 strcat (pattern, \"%P0\");
12207 if ((num_regs - 1) > 1)
12209 strcat (pattern, \"-%P1\");
12210 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
12213 strcat (pattern, \"}\");
12214 output_asm_insn (pattern, op_list);
12218 [(set_attr "type" "load4")
12219 (set_attr "conds" "unconditional")
12220 (set_attr "predicable" "no")]
12223 ;; Special patterns for dealing with the constant pool
12225 (define_insn "align_4"
12226 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
12229 assemble_align (32);
12232 [(set_attr "type" "no_insn")]
12235 (define_insn "align_8"
12236 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
12239 assemble_align (64);
12242 [(set_attr "type" "no_insn")]
12245 (define_insn "consttable_end"
12246 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
12249 making_const_table = FALSE;
12252 [(set_attr "type" "no_insn")]
12255 (define_insn "consttable_1"
12256 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
12259 making_const_table = TRUE;
12260 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
12261 assemble_zeros (3);
12264 [(set_attr "length" "4")
12265 (set_attr "type" "no_insn")]
12268 (define_insn "consttable_2"
12269 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
12273 rtx x = operands[0];
12274 making_const_table = TRUE;
12275 switch (GET_MODE_CLASS (GET_MODE (x)))
12278 arm_emit_fp16_const (x);
12281 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
12282 assemble_zeros (2);
12287 [(set_attr "length" "4")
12288 (set_attr "type" "no_insn")]
12291 (define_insn "consttable_4"
12292 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
12296 rtx x = operands[0];
12297 making_const_table = TRUE;
12298 switch (GET_MODE_CLASS (GET_MODE (x)))
12303 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
12304 assemble_real (r, GET_MODE (x), BITS_PER_WORD);
12308 /* XXX: Sometimes gcc does something really dumb and ends up with
12309 a HIGH in a constant pool entry, usually because it's trying to
12310 load into a VFP register. We know this will always be used in
12311 combination with a LO_SUM which ignores the high bits, so just
12312 strip off the HIGH. */
12313 if (GET_CODE (x) == HIGH)
12315 assemble_integer (x, 4, BITS_PER_WORD, 1);
12316 mark_symbol_refs_as_used (x);
12321 [(set_attr "length" "4")
12322 (set_attr "type" "no_insn")]
12325 (define_insn "consttable_8"
12326 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
12330 making_const_table = TRUE;
12331 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12336 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12337 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
12341 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
12346 [(set_attr "length" "8")
12347 (set_attr "type" "no_insn")]
12350 (define_insn "consttable_16"
12351 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
12355 making_const_table = TRUE;
12356 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
12361 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
12362 assemble_real (r, GET_MODE (operands[0]), BITS_PER_WORD);
12366 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
12371 [(set_attr "length" "16")
12372 (set_attr "type" "no_insn")]
12375 ;; Miscellaneous Thumb patterns
12377 (define_expand "tablejump"
12378 [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
12379 (use (label_ref (match_operand 1 "" "")))])]
12384 /* Hopefully, CSE will eliminate this copy. */
12385 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
12386 rtx reg2 = gen_reg_rtx (SImode);
12388 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
12389 operands[0] = reg2;
12394 ;; NB never uses BX.
12395 (define_insn "*thumb1_tablejump"
12396 [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
12397 (use (label_ref (match_operand 1 "" "")))]
12400 [(set_attr "length" "2")
12401 (set_attr "type" "no_insn")]
12404 ;; V5 Instructions,
12406 (define_insn "clzsi2"
12407 [(set (match_operand:SI 0 "s_register_operand" "=r")
12408 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
12409 "TARGET_32BIT && arm_arch5"
12411 [(set_attr "predicable" "yes")
12412 (set_attr "predicable_short_it" "no")
12413 (set_attr "type" "clz")])
12415 (define_insn "rbitsi2"
12416 [(set (match_operand:SI 0 "s_register_operand" "=r")
12417 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
12418 "TARGET_32BIT && arm_arch_thumb2"
12420 [(set_attr "predicable" "yes")
12421 (set_attr "predicable_short_it" "no")
12422 (set_attr "type" "clz")])
12424 (define_expand "ctzsi2"
12425 [(set (match_operand:SI 0 "s_register_operand" "")
12426 (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
12427 "TARGET_32BIT && arm_arch_thumb2"
12430 rtx tmp = gen_reg_rtx (SImode);
12431 emit_insn (gen_rbitsi2 (tmp, operands[1]));
12432 emit_insn (gen_clzsi2 (operands[0], tmp));
12438 ;; V5E instructions.
12440 (define_insn "prefetch"
12441 [(prefetch (match_operand:SI 0 "address_operand" "p")
12442 (match_operand:SI 1 "" "")
12443 (match_operand:SI 2 "" ""))]
12444 "TARGET_32BIT && arm_arch5e"
12446 [(set_attr "type" "load1")]
12449 ;; General predication pattern
12452 [(match_operator 0 "arm_comparison_operator"
12453 [(match_operand 1 "cc_register" "")
12457 [(set_attr "predicated" "yes")]
12460 (define_insn "force_register_use"
12461 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
12464 [(set_attr "length" "0")
12465 (set_attr "type" "no_insn")]
12469 ;; Patterns for exception handling
12471 (define_expand "eh_return"
12472 [(use (match_operand 0 "general_operand" ""))]
12477 emit_insn (gen_arm_eh_return (operands[0]));
12479 emit_insn (gen_thumb_eh_return (operands[0]));
12484 ;; We can't expand this before we know where the link register is stored.
12485 (define_insn_and_split "arm_eh_return"
12486 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
12488 (clobber (match_scratch:SI 1 "=&r"))]
12491 "&& reload_completed"
12495 arm_set_return_address (operands[0], operands[1]);
12500 (define_insn_and_split "thumb_eh_return"
12501 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "l")]
12503 (clobber (match_scratch:SI 1 "=&l"))]
12506 "&& reload_completed"
12510 thumb_set_return_address (operands[0], operands[1]);
12513 [(set_attr "type" "mov_reg")]
12519 (define_insn "load_tp_hard"
12520 [(set (match_operand:SI 0 "register_operand" "=r")
12521 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
12523 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
12524 [(set_attr "predicable" "yes")
12525 (set_attr "type" "mrs")]
12528 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
12529 (define_insn "load_tp_soft"
12530 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
12531 (clobber (reg:SI LR_REGNUM))
12532 (clobber (reg:SI IP_REGNUM))
12533 (clobber (reg:CC CC_REGNUM))]
12535 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
12536 [(set_attr "conds" "clob")
12537 (set_attr "type" "branch")]
12540 ;; tls descriptor call
12541 (define_insn "tlscall"
12542 [(set (reg:SI R0_REGNUM)
12543 (unspec:SI [(reg:SI R0_REGNUM)
12544 (match_operand:SI 0 "" "X")
12545 (match_operand 1 "" "")] UNSPEC_TLS))
12546 (clobber (reg:SI R1_REGNUM))
12547 (clobber (reg:SI LR_REGNUM))
12548 (clobber (reg:SI CC_REGNUM))]
12551 targetm.asm_out.internal_label (asm_out_file, "LPIC",
12552 INTVAL (operands[1]));
12553 return "bl\\t%c0(tlscall)";
12555 [(set_attr "conds" "clob")
12556 (set_attr "length" "4")
12557 (set_attr "type" "branch")]
12560 ;; For thread pointer builtin
12561 (define_expand "get_thread_pointersi"
12562 [(match_operand:SI 0 "s_register_operand" "=r")]
12566 arm_load_tp (operands[0]);
12572 ;; We only care about the lower 16 bits of the constant
12573 ;; being inserted into the upper 16 bits of the register.
12574 (define_insn "*arm_movtas_ze"
12575 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
12578 (match_operand:SI 1 "const_int_operand" ""))]
12581 [(set_attr "predicable" "yes")
12582 (set_attr "predicable_short_it" "no")
12583 (set_attr "length" "4")
12584 (set_attr "type" "mov_imm")]
12587 (define_insn "*arm_rev"
12588 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
12589 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
12595 [(set_attr "arch" "t1,t2,32")
12596 (set_attr "length" "2,2,4")
12597 (set_attr "predicable" "no,yes,yes")
12598 (set_attr "predicable_short_it" "no")
12599 (set_attr "type" "rev")]
12602 (define_expand "arm_legacy_rev"
12603 [(set (match_operand:SI 2 "s_register_operand" "")
12604 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
12608 (lshiftrt:SI (match_dup 2)
12610 (set (match_operand:SI 3 "s_register_operand" "")
12611 (rotatert:SI (match_dup 1)
12614 (and:SI (match_dup 2)
12615 (const_int -65281)))
12616 (set (match_operand:SI 0 "s_register_operand" "")
12617 (xor:SI (match_dup 3)
12623 ;; Reuse temporaries to keep register pressure down.
12624 (define_expand "thumb_legacy_rev"
12625 [(set (match_operand:SI 2 "s_register_operand" "")
12626 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
12628 (set (match_operand:SI 3 "s_register_operand" "")
12629 (lshiftrt:SI (match_dup 1)
12632 (ior:SI (match_dup 3)
12634 (set (match_operand:SI 4 "s_register_operand" "")
12636 (set (match_operand:SI 5 "s_register_operand" "")
12637 (rotatert:SI (match_dup 1)
12640 (ashift:SI (match_dup 5)
12643 (lshiftrt:SI (match_dup 5)
12646 (ior:SI (match_dup 5)
12649 (rotatert:SI (match_dup 5)
12651 (set (match_operand:SI 0 "s_register_operand" "")
12652 (ior:SI (match_dup 5)
12658 (define_expand "bswapsi2"
12659 [(set (match_operand:SI 0 "s_register_operand" "=r")
12660 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
12661 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
12665 rtx op2 = gen_reg_rtx (SImode);
12666 rtx op3 = gen_reg_rtx (SImode);
12670 rtx op4 = gen_reg_rtx (SImode);
12671 rtx op5 = gen_reg_rtx (SImode);
12673 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
12674 op2, op3, op4, op5));
12678 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
12687 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
12688 ;; and unsigned variants, respectively. For rev16, expose
12689 ;; byte-swapping in the lower 16 bits only.
12690 (define_insn "*arm_revsh"
12691 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
12692 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
12698 [(set_attr "arch" "t1,t2,32")
12699 (set_attr "length" "2,2,4")
12700 (set_attr "type" "rev")]
12703 (define_insn "*arm_rev16"
12704 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
12705 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
12711 [(set_attr "arch" "t1,t2,32")
12712 (set_attr "length" "2,2,4")
12713 (set_attr "type" "rev")]
12716 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
12717 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
12718 ;; each valid permutation.
12720 (define_insn "arm_rev16si2"
12721 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
12722 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
12724 (match_operand:SI 3 "const_int_operand" "n,n,n"))
12725 (and:SI (lshiftrt:SI (match_dup 1)
12727 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
12729 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
12730 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
12732 [(set_attr "arch" "t1,t2,32")
12733 (set_attr "length" "2,2,4")
12734 (set_attr "type" "rev")]
12737 (define_insn "arm_rev16si2_alt"
12738 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
12739 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
12741 (match_operand:SI 2 "const_int_operand" "n,n,n"))
12742 (and:SI (ashift:SI (match_dup 1)
12744 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
12746 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
12747 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
12749 [(set_attr "arch" "t1,t2,32")
12750 (set_attr "length" "2,2,4")
12751 (set_attr "type" "rev")]
12754 (define_expand "bswaphi2"
12755 [(set (match_operand:HI 0 "s_register_operand" "=r")
12756 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
12761 ;; Patterns for LDRD/STRD in Thumb2 mode
12763 (define_insn "*thumb2_ldrd"
12764 [(set (match_operand:SI 0 "s_register_operand" "=r")
12765 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12766 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
12767 (set (match_operand:SI 3 "s_register_operand" "=r")
12768 (mem:SI (plus:SI (match_dup 1)
12769 (match_operand:SI 4 "const_int_operand" ""))))]
12770 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12771 && current_tune->prefer_ldrd_strd
12772 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
12773 && (operands_ok_ldrd_strd (operands[0], operands[3],
12774 operands[1], INTVAL (operands[2]),
12776 "ldrd%?\t%0, %3, [%1, %2]"
12777 [(set_attr "type" "load2")
12778 (set_attr "predicable" "yes")
12779 (set_attr "predicable_short_it" "no")])
12781 (define_insn "*thumb2_ldrd_base"
12782 [(set (match_operand:SI 0 "s_register_operand" "=r")
12783 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12784 (set (match_operand:SI 2 "s_register_operand" "=r")
12785 (mem:SI (plus:SI (match_dup 1)
12787 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12788 && current_tune->prefer_ldrd_strd
12789 && (operands_ok_ldrd_strd (operands[0], operands[2],
12790 operands[1], 0, false, true))"
12791 "ldrd%?\t%0, %2, [%1]"
12792 [(set_attr "type" "load2")
12793 (set_attr "predicable" "yes")
12794 (set_attr "predicable_short_it" "no")])
12796 (define_insn "*thumb2_ldrd_base_neg"
12797 [(set (match_operand:SI 0 "s_register_operand" "=r")
12798 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12800 (set (match_operand:SI 2 "s_register_operand" "=r")
12801 (mem:SI (match_dup 1)))]
12802 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12803 && current_tune->prefer_ldrd_strd
12804 && (operands_ok_ldrd_strd (operands[0], operands[2],
12805 operands[1], -4, false, true))"
12806 "ldrd%?\t%0, %2, [%1, #-4]"
12807 [(set_attr "type" "load2")
12808 (set_attr "predicable" "yes")
12809 (set_attr "predicable_short_it" "no")])
12811 (define_insn "*thumb2_strd"
12812 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12813 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
12814 (match_operand:SI 2 "s_register_operand" "r"))
12815 (set (mem:SI (plus:SI (match_dup 0)
12816 (match_operand:SI 3 "const_int_operand" "")))
12817 (match_operand:SI 4 "s_register_operand" "r"))]
12818 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12819 && current_tune->prefer_ldrd_strd
12820 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
12821 && (operands_ok_ldrd_strd (operands[2], operands[4],
12822 operands[0], INTVAL (operands[1]),
12824 "strd%?\t%2, %4, [%0, %1]"
12825 [(set_attr "type" "store2")
12826 (set_attr "predicable" "yes")
12827 (set_attr "predicable_short_it" "no")])
12829 (define_insn "*thumb2_strd_base"
12830 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
12831 (match_operand:SI 1 "s_register_operand" "r"))
12832 (set (mem:SI (plus:SI (match_dup 0)
12834 (match_operand:SI 2 "s_register_operand" "r"))]
12835 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12836 && current_tune->prefer_ldrd_strd
12837 && (operands_ok_ldrd_strd (operands[1], operands[2],
12838 operands[0], 0, false, false))"
12839 "strd%?\t%1, %2, [%0]"
12840 [(set_attr "type" "store2")
12841 (set_attr "predicable" "yes")
12842 (set_attr "predicable_short_it" "no")])
12844 (define_insn "*thumb2_strd_base_neg"
12845 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12847 (match_operand:SI 1 "s_register_operand" "r"))
12848 (set (mem:SI (match_dup 0))
12849 (match_operand:SI 2 "s_register_operand" "r"))]
12850 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12851 && current_tune->prefer_ldrd_strd
12852 && (operands_ok_ldrd_strd (operands[1], operands[2],
12853 operands[0], -4, false, false))"
12854 "strd%?\t%1, %2, [%0, #-4]"
12855 [(set_attr "type" "store2")
12856 (set_attr "predicable" "yes")
12857 (set_attr "predicable_short_it" "no")])
12859 ;; ARMv8 CRC32 instructions.
12860 (define_insn "<crc_variant>"
12861 [(set (match_operand:SI 0 "s_register_operand" "=r")
12862 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
12863 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
12866 "<crc_variant>\\t%0, %1, %2"
12867 [(set_attr "type" "crc")
12868 (set_attr "conds" "unconditional")]
12871 ;; Load the load/store double peephole optimizations.
12872 (include "ldrdstrd.md")
12874 ;; Load the load/store multiple patterns
12875 (include "ldmstm.md")
12877 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12878 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12879 (define_insn "*load_multiple"
12880 [(match_parallel 0 "load_multiple_operation"
12881 [(set (match_operand:SI 2 "s_register_operand" "=rk")
12882 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12887 arm_output_multireg_pop (operands, /*return_pc=*/false,
12888 /*cond=*/const_true_rtx,
12894 [(set_attr "predicable" "yes")]
12897 ;; Vector bits common to IWMMXT and Neon
12898 (include "vec-common.md")
12899 ;; Load the Intel Wireless Multimedia Extension patterns
12900 (include "iwmmxt.md")
12901 ;; Load the VFP co-processor patterns
12903 ;; Thumb-2 patterns
12904 (include "thumb2.md")
12906 (include "neon.md")
12908 (include "crypto.md")
12909 ;; Synchronization Primitives
12910 (include "sync.md")
12911 ;; Fixed-point patterns
12912 (include "arm-fixed.md")