1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2019 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;---------------------------------------------------------------------------
29 ;; Register numbers -- All machine registers should be defined here
31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (R4_REGNUM 4) ; Fifth CORE register
34 (FDPIC_REGNUM 9) ; FDPIC register
35 (IP_REGNUM 12) ; Scratch register
36 (SP_REGNUM 13) ; Stack pointer
37 (LR_REGNUM 14) ; Return address register
38 (PC_REGNUM 15) ; Program counter
39 (LAST_ARM_REGNUM 15) ;
40 (CC_REGNUM 100) ; Condition code pseudo register
41 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
44 ;; 3rd operand to select_dominance_cc_mode
51 ;; conditional compare combination
62 ;;---------------------------------------------------------------------------
65 ;; Processor type. This is created automatically from arm-cores.def.
66 (include "arm-tune.md")
68 ;; Instruction classification types
71 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
72 ; generating ARM code. This is used to control the length of some insn
73 ; patterns that share the same RTL in both ARM and Thumb code.
74 (define_attr "is_thumb" "yes,no"
75 (const (if_then_else (symbol_ref "TARGET_THUMB")
76 (const_string "yes") (const_string "no"))))
78 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
79 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
81 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
82 (define_attr "is_thumb1" "yes,no"
83 (const (if_then_else (symbol_ref "TARGET_THUMB1")
84 (const_string "yes") (const_string "no"))))
86 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
87 ; The arm_restrict_it flag enables the "short IT" feature which
88 ; restricts IT blocks to a single 16-bit instruction.
89 ; This attribute should only be used on 16-bit Thumb-2 instructions
90 ; which may be predicated (the "predicable" attribute must be set).
91 (define_attr "predicable_short_it" "no,yes" (const_string "no"))
93 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
94 ; This attribute should only be used on instructions which may emit
95 ; an IT block in their expansion which is not a short IT.
96 (define_attr "enabled_for_short_it" "no,yes" (const_string "yes"))
98 ;; Operand number of an input operand that is shifted. Zero if the
99 ;; given instruction does not shift one of its input operands.
100 (define_attr "shift" "" (const_int 0))
102 ;; [For compatibility with AArch64 in pipeline models]
103 ;; Attribute that specifies whether or not the instruction touches fp
105 (define_attr "fp" "no,yes" (const_string "no"))
107 ; Floating Point Unit. If we only have floating point emulation, then there
108 ; is no point in scheduling the floating point insns. (Well, for best
109 ; performance we should try and group them together).
110 (define_attr "fpu" "none,vfp"
111 (const (symbol_ref "arm_fpu_attr")))
113 ; Predicated means that the insn form is conditionally executed based on a
114 ; predicate. We default to 'no' because no Thumb patterns match this rule
115 ; and not all ARM insns do.
116 (define_attr "predicated" "yes,no" (const_string "no"))
118 ; LENGTH of an instruction (in bytes)
119 (define_attr "length" ""
122 ; The architecture which supports the instruction (or alternative).
123 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
124 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
125 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
126 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
127 ; Baseline. This attribute is used to compute attribute "enabled",
128 ; use type "any" to enable an alternative in all cases.
129 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
130 (const_string "any"))
132 (define_attr "arch_enabled" "no,yes"
133 (cond [(eq_attr "arch" "any")
136 (and (eq_attr "arch" "a")
137 (match_test "TARGET_ARM"))
140 (and (eq_attr "arch" "t")
141 (match_test "TARGET_THUMB"))
144 (and (eq_attr "arch" "t1")
145 (match_test "TARGET_THUMB1"))
148 (and (eq_attr "arch" "t2")
149 (match_test "TARGET_THUMB2"))
152 (and (eq_attr "arch" "32")
153 (match_test "TARGET_32BIT"))
156 (and (eq_attr "arch" "v6")
157 (match_test "TARGET_32BIT && arm_arch6"))
160 (and (eq_attr "arch" "nov6")
161 (match_test "TARGET_32BIT && !arm_arch6"))
164 (and (eq_attr "arch" "v6t2")
165 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
168 (and (eq_attr "arch" "v8mb")
169 (match_test "TARGET_THUMB1 && arm_arch8"))
172 (and (eq_attr "arch" "iwmmxt2")
173 (match_test "TARGET_REALLY_IWMMXT2"))
176 (and (eq_attr "arch" "armv6_or_vfpv3")
177 (match_test "arm_arch6 || TARGET_VFP3"))
180 (and (eq_attr "arch" "neon")
181 (match_test "TARGET_NEON"))
185 (const_string "no")))
187 (define_attr "opt" "any,speed,size"
188 (const_string "any"))
190 (define_attr "opt_enabled" "no,yes"
191 (cond [(eq_attr "opt" "any")
194 (and (eq_attr "opt" "speed")
195 (match_test "optimize_function_for_speed_p (cfun)"))
198 (and (eq_attr "opt" "size")
199 (match_test "optimize_function_for_size_p (cfun)"))
200 (const_string "yes")]
201 (const_string "no")))
203 (define_attr "use_literal_pool" "no,yes"
204 (cond [(and (eq_attr "type" "f_loads,f_loadd")
205 (match_test "CONSTANT_P (operands[1])"))
206 (const_string "yes")]
207 (const_string "no")))
209 ; Enable all alternatives that are both arch_enabled and insn_enabled.
210 ; FIXME:: opt_enabled has been temporarily removed till the time we have
211 ; an attribute that allows the use of such alternatives.
212 ; This depends on caching of speed_p, size_p on a per
213 ; alternative basis. The problem is that the enabled attribute
214 ; cannot depend on any state that is not cached or is not constant
215 ; for a compilation unit. We probably need a generic "hot/cold"
216 ; alternative which if implemented can help with this. We disable this
217 ; until such a time as this is implemented and / or the improvements or
218 ; regressions with removing this attribute are double checked.
219 ; See ashldi3_neon and <shift>di3_neon in neon.md.
221 (define_attr "enabled" "no,yes"
222 (cond [(and (eq_attr "predicable_short_it" "no")
223 (and (eq_attr "predicated" "yes")
224 (match_test "arm_restrict_it")))
227 (and (eq_attr "enabled_for_short_it" "no")
228 (match_test "arm_restrict_it"))
231 (eq_attr "arch_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 cannot 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_sreg,\
321 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
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,arm10e,arm1026ejs,arm1136js,\
379 arm1136jfs,cortexa5,cortexa7,cortexa8,\
380 cortexa9,cortexa12,cortexa15,cortexa17,\
381 cortexa53,cortexa57,cortexm4,cortexm7,\
382 exynosm1,marvell_pj4,xgene1")
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" "!arm10e,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")
421 (include "exynos-m1.md")
423 (include "marvell-pj4.md")
424 (include "xgene1.md")
427 ;;---------------------------------------------------------------------------
432 ;; Note: For DImode insns, there is normally no reason why operands should
433 ;; not be in the same register, what we don't want is for something being
434 ;; written to partially overlap something that is an input.
436 (define_expand "adddi3"
438 [(set (match_operand:DI 0 "s_register_operand")
439 (plus:DI (match_operand:DI 1 "s_register_operand")
440 (match_operand:DI 2 "arm_adddi_operand")))
441 (clobber (reg:CC CC_REGNUM))])]
444 if (TARGET_THUMB1 && !REG_P (operands[2]))
445 operands[2] = force_reg (DImode, operands[2]);
449 (define_insn_and_split "*arm_adddi3"
450 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r,&r,&r")
451 (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r")
452 (match_operand:DI 2 "arm_general_adddi_operand" "r, 0, r, Dd, Dd")))
453 (clobber (reg:CC CC_REGNUM))]
457 [(parallel [(set (reg:CC_C CC_REGNUM)
458 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
460 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
461 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
462 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
465 operands[3] = gen_highpart (SImode, operands[0]);
466 operands[0] = gen_lowpart (SImode, operands[0]);
467 operands[4] = gen_highpart (SImode, operands[1]);
468 operands[1] = gen_lowpart (SImode, operands[1]);
469 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
470 operands[2] = gen_lowpart (SImode, operands[2]);
472 [(set_attr "conds" "clob")
473 (set_attr "length" "8")
474 (set_attr "type" "multiple")]
477 (define_insn_and_split "*adddi_sesidi_di"
478 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
479 (plus:DI (sign_extend:DI
480 (match_operand:SI 2 "s_register_operand" "r,r"))
481 (match_operand:DI 1 "s_register_operand" "0,r")))
482 (clobber (reg:CC CC_REGNUM))]
485 "TARGET_32BIT && reload_completed"
486 [(parallel [(set (reg:CC_C CC_REGNUM)
487 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
489 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
490 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
493 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
496 operands[3] = gen_highpart (SImode, operands[0]);
497 operands[0] = gen_lowpart (SImode, operands[0]);
498 operands[4] = gen_highpart (SImode, operands[1]);
499 operands[1] = gen_lowpart (SImode, operands[1]);
500 operands[2] = gen_lowpart (SImode, operands[2]);
502 [(set_attr "conds" "clob")
503 (set_attr "length" "8")
504 (set_attr "type" "multiple")]
507 (define_insn_and_split "*adddi_zesidi_di"
508 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
509 (plus:DI (zero_extend:DI
510 (match_operand:SI 2 "s_register_operand" "r,r"))
511 (match_operand:DI 1 "s_register_operand" "0,r")))
512 (clobber (reg:CC CC_REGNUM))]
515 "TARGET_32BIT && reload_completed"
516 [(parallel [(set (reg:CC_C CC_REGNUM)
517 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
519 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
520 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
521 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
524 operands[3] = gen_highpart (SImode, operands[0]);
525 operands[0] = gen_lowpart (SImode, operands[0]);
526 operands[4] = gen_highpart (SImode, operands[1]);
527 operands[1] = gen_lowpart (SImode, operands[1]);
528 operands[2] = gen_lowpart (SImode, operands[2]);
530 [(set_attr "conds" "clob")
531 (set_attr "length" "8")
532 (set_attr "type" "multiple")]
535 (define_expand "addv<mode>4"
536 [(match_operand:SIDI 0 "register_operand")
537 (match_operand:SIDI 1 "register_operand")
538 (match_operand:SIDI 2 "register_operand")
539 (match_operand 3 "")]
542 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
543 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
548 (define_expand "uaddv<mode>4"
549 [(match_operand:SIDI 0 "register_operand")
550 (match_operand:SIDI 1 "register_operand")
551 (match_operand:SIDI 2 "register_operand")
552 (match_operand 3 "")]
555 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
556 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
561 (define_expand "addsi3"
562 [(set (match_operand:SI 0 "s_register_operand")
563 (plus:SI (match_operand:SI 1 "s_register_operand")
564 (match_operand:SI 2 "reg_or_int_operand")))]
567 if (TARGET_32BIT && CONST_INT_P (operands[2]))
569 arm_split_constant (PLUS, SImode, NULL_RTX,
570 INTVAL (operands[2]), operands[0], operands[1],
571 optimize && can_create_pseudo_p ());
577 ; If there is a scratch available, this will be faster than synthesizing the
580 [(match_scratch:SI 3 "r")
581 (set (match_operand:SI 0 "arm_general_register_operand" "")
582 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
583 (match_operand:SI 2 "const_int_operand" "")))]
585 !(const_ok_for_arm (INTVAL (operands[2]))
586 || const_ok_for_arm (-INTVAL (operands[2])))
587 && const_ok_for_arm (~INTVAL (operands[2]))"
588 [(set (match_dup 3) (match_dup 2))
589 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
593 ;; The r/r/k alternative is required when reloading the address
594 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
595 ;; put the duplicated register first, and not try the commutative version.
596 (define_insn_and_split "*arm_addsi3"
597 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
598 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,r ,rk,k ,rk,k,r,rk,k ,rk")
599 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
615 subw%?\\t%0, %1, #%n2
616 subw%?\\t%0, %1, #%n2
619 && CONST_INT_P (operands[2])
620 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
621 && (reload_completed || !arm_eliminable_register (operands[1]))"
622 [(clobber (const_int 0))]
624 arm_split_constant (PLUS, SImode, curr_insn,
625 INTVAL (operands[2]), operands[0],
629 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
630 (set_attr "predicable" "yes")
631 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
632 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
633 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
634 (const_string "alu_imm")
635 (const_string "alu_sreg")))
639 (define_insn_and_split "adddi3_compareV"
640 [(set (reg:CC_V CC_REGNUM)
643 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
644 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
645 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
646 (set (match_operand:DI 0 "register_operand" "=&r")
647 (plus:DI (match_dup 1) (match_dup 2)))]
650 "&& reload_completed"
651 [(parallel [(set (reg:CC_C CC_REGNUM)
652 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
654 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
655 (parallel [(set (reg:CC_V CC_REGNUM)
658 (sign_extend:DI (match_dup 4))
659 (sign_extend:DI (match_dup 5)))
660 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
661 (plus:DI (sign_extend:DI
662 (plus:SI (match_dup 4) (match_dup 5)))
663 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
664 (set (match_dup 3) (plus:SI (plus:SI
665 (match_dup 4) (match_dup 5))
666 (ltu:SI (reg:CC_C CC_REGNUM)
670 operands[3] = gen_highpart (SImode, operands[0]);
671 operands[0] = gen_lowpart (SImode, operands[0]);
672 operands[4] = gen_highpart (SImode, operands[1]);
673 operands[1] = gen_lowpart (SImode, operands[1]);
674 operands[5] = gen_highpart (SImode, operands[2]);
675 operands[2] = gen_lowpart (SImode, operands[2]);
677 [(set_attr "conds" "set")
678 (set_attr "length" "8")
679 (set_attr "type" "multiple")]
682 (define_insn "addsi3_compareV"
683 [(set (reg:CC_V CC_REGNUM)
686 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
687 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
688 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
689 (set (match_operand:SI 0 "register_operand" "=r")
690 (plus:SI (match_dup 1) (match_dup 2)))]
692 "adds%?\\t%0, %1, %2"
693 [(set_attr "conds" "set")
694 (set_attr "type" "alus_sreg")]
697 (define_insn "*addsi3_compareV_upper"
698 [(set (reg:CC_V CC_REGNUM)
702 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
703 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
704 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
705 (plus:DI (sign_extend:DI
706 (plus:SI (match_dup 1) (match_dup 2)))
707 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
708 (set (match_operand:SI 0 "register_operand" "=r")
710 (plus:SI (match_dup 1) (match_dup 2))
711 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
713 "adcs%?\\t%0, %1, %2"
714 [(set_attr "conds" "set")
715 (set_attr "type" "adcs_reg")]
718 (define_insn_and_split "adddi3_compareC"
719 [(set (reg:CC_C CC_REGNUM)
722 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
723 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
724 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
725 (set (match_operand:DI 0 "register_operand" "=&r")
726 (plus:DI (match_dup 1) (match_dup 2)))]
729 "&& reload_completed"
730 [(parallel [(set (reg:CC_C CC_REGNUM)
731 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
733 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
734 (parallel [(set (reg:CC_C CC_REGNUM)
737 (zero_extend:DI (match_dup 4))
738 (zero_extend:DI (match_dup 5)))
739 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
740 (plus:DI (zero_extend:DI
741 (plus:SI (match_dup 4) (match_dup 5)))
742 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
743 (set (match_dup 3) (plus:SI
744 (plus:SI (match_dup 4) (match_dup 5))
745 (ltu:SI (reg:CC_C CC_REGNUM)
749 operands[3] = gen_highpart (SImode, operands[0]);
750 operands[0] = gen_lowpart (SImode, operands[0]);
751 operands[4] = gen_highpart (SImode, operands[1]);
752 operands[5] = gen_highpart (SImode, operands[2]);
753 operands[1] = gen_lowpart (SImode, operands[1]);
754 operands[2] = gen_lowpart (SImode, operands[2]);
756 [(set_attr "conds" "set")
757 (set_attr "length" "8")
758 (set_attr "type" "multiple")]
761 (define_insn "*addsi3_compareC_upper"
762 [(set (reg:CC_C CC_REGNUM)
766 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
767 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
768 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
769 (plus:DI (zero_extend:DI
770 (plus:SI (match_dup 1) (match_dup 2)))
771 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
772 (set (match_operand:SI 0 "register_operand" "=r")
774 (plus:SI (match_dup 1) (match_dup 2))
775 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
777 "adcs%?\\t%0, %1, %2"
778 [(set_attr "conds" "set")
779 (set_attr "type" "adcs_reg")]
782 (define_insn "addsi3_compareC"
783 [(set (reg:CC_C CC_REGNUM)
786 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
787 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
789 (plus:SI (match_dup 1) (match_dup 2)))))
790 (set (match_operand:SI 0 "register_operand" "=r")
791 (plus:SI (match_dup 1) (match_dup 2)))]
793 "adds%?\\t%0, %1, %2"
794 [(set_attr "conds" "set")
795 (set_attr "type" "alus_sreg")]
798 (define_insn "addsi3_compare0"
799 [(set (reg:CC_NOOV CC_REGNUM)
801 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
802 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
804 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
805 (plus:SI (match_dup 1) (match_dup 2)))]
809 subs%?\\t%0, %1, #%n2
811 [(set_attr "conds" "set")
812 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
815 (define_insn "*addsi3_compare0_scratch"
816 [(set (reg:CC_NOOV CC_REGNUM)
818 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
819 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
826 [(set_attr "conds" "set")
827 (set_attr "predicable" "yes")
828 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
831 (define_insn "*compare_negsi_si"
832 [(set (reg:CC_Z CC_REGNUM)
834 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
835 (match_operand:SI 1 "s_register_operand" "l,r")))]
838 [(set_attr "conds" "set")
839 (set_attr "predicable" "yes")
840 (set_attr "arch" "t2,*")
841 (set_attr "length" "2,4")
842 (set_attr "predicable_short_it" "yes,no")
843 (set_attr "type" "alus_sreg")]
846 ;; This is the canonicalization of subsi3_compare when the
847 ;; addend is a constant.
848 (define_insn "cmpsi2_addneg"
849 [(set (reg:CC CC_REGNUM)
851 (match_operand:SI 1 "s_register_operand" "r,r")
852 (match_operand:SI 2 "arm_addimm_operand" "I,L")))
853 (set (match_operand:SI 0 "s_register_operand" "=r,r")
854 (plus:SI (match_dup 1)
855 (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
857 && (INTVAL (operands[2])
858 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
860 /* For 0 and INT_MIN it is essential that we use subs, as adds will result
861 in different condition codes (like cmn rather than like cmp), so that
862 alternative comes first. Both alternatives can match for any 0x??000000
863 where except for 0 and INT_MIN it doesn't matter what we choose, and also
864 for -1 and 1 with TARGET_THUMB2, in that case prefer instruction with #1
866 if (which_alternative == 0 && operands[3] != const1_rtx)
867 return "subs%?\\t%0, %1, #%n3";
869 return "adds%?\\t%0, %1, %3";
871 [(set_attr "conds" "set")
872 (set_attr "type" "alus_sreg")]
875 ;; Convert the sequence
877 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
881 ;; bcs dest ((unsigned)rn >= 1)
882 ;; similarly for the beq variant using bcc.
883 ;; This is a common looping idiom (while (n--))
885 [(set (match_operand:SI 0 "arm_general_register_operand" "")
886 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
888 (set (match_operand 2 "cc_register" "")
889 (compare (match_dup 0) (const_int -1)))
891 (if_then_else (match_operator 3 "equality_operator"
892 [(match_dup 2) (const_int 0)])
893 (match_operand 4 "" "")
894 (match_operand 5 "" "")))]
895 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
899 (match_dup 1) (const_int 1)))
900 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
902 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
905 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
906 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
909 operands[2], const0_rtx);"
912 ;; The next four insns work because they compare the result with one of
913 ;; the operands, and we know that the use of the condition code is
914 ;; either GEU or LTU, so we can use the carry flag from the addition
915 ;; instead of doing the compare a second time.
916 (define_insn "*addsi3_compare_op1"
917 [(set (reg:CC_C CC_REGNUM)
919 (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r,r")
920 (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,I,L,r"))
922 (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r,r")
923 (plus:SI (match_dup 1) (match_dup 2)))]
928 subs%?\\t%0, %1, #%n2
929 subs%?\\t%0, %0, #%n2
931 subs%?\\t%0, %1, #%n2
933 [(set_attr "conds" "set")
934 (set_attr "arch" "t2,t2,t2,t2,*,*,*")
935 (set_attr "length" "2,2,2,2,4,4,4")
937 "alus_sreg,alus_imm,alus_sreg,alus_imm,alus_imm,alus_imm,alus_sreg")]
940 (define_insn "*addsi3_compare_op2"
941 [(set (reg:CC_C CC_REGNUM)
943 (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r,r")
944 (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,I,L,r"))
946 (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r,r")
947 (plus:SI (match_dup 1) (match_dup 2)))]
952 subs%?\\t%0, %1, #%n2
953 subs%?\\t%0, %0, #%n2
955 subs%?\\t%0, %1, #%n2
957 [(set_attr "conds" "set")
958 (set_attr "arch" "t2,t2,t2,t2,*,*,*")
959 (set_attr "length" "2,2,2,2,4,4,4")
961 "alus_sreg,alus_imm,alus_sreg,alus_imm,alus_imm,alus_imm,alus_sreg")]
964 (define_insn "*compare_addsi2_op0"
965 [(set (reg:CC_C CC_REGNUM)
967 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
968 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
977 [(set_attr "conds" "set")
978 (set_attr "predicable" "yes")
979 (set_attr "arch" "t2,t2,*,*,*")
980 (set_attr "predicable_short_it" "yes,yes,no,no,no")
981 (set_attr "length" "2,2,4,4,4")
982 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
985 (define_insn "*compare_addsi2_op1"
986 [(set (reg:CC_C CC_REGNUM)
988 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
989 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
998 [(set_attr "conds" "set")
999 (set_attr "predicable" "yes")
1000 (set_attr "arch" "t2,t2,*,*,*")
1001 (set_attr "predicable_short_it" "yes,yes,no,no,no")
1002 (set_attr "length" "2,2,4,4,4")
1003 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
1006 (define_insn "*addsi3_carryin_<optab>"
1007 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1008 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
1009 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
1010 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1015 sbc%?\\t%0, %1, #%B2"
1016 [(set_attr "conds" "use")
1017 (set_attr "predicable" "yes")
1018 (set_attr "arch" "t2,*,*")
1019 (set_attr "length" "4")
1020 (set_attr "predicable_short_it" "yes,no,no")
1021 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1024 (define_insn "*addsi3_carryin_alt2_<optab>"
1025 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1026 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1027 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1028 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1033 sbc%?\\t%0, %1, #%B2"
1034 [(set_attr "conds" "use")
1035 (set_attr "predicable" "yes")
1036 (set_attr "arch" "t2,*,*")
1037 (set_attr "length" "4")
1038 (set_attr "predicable_short_it" "yes,no,no")
1039 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1042 (define_insn "*addsi3_carryin_shift_<optab>"
1043 [(set (match_operand:SI 0 "s_register_operand" "=r")
1045 (match_operator:SI 2 "shift_operator"
1046 [(match_operand:SI 3 "s_register_operand" "r")
1047 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1048 (match_operand:SI 1 "s_register_operand" "r"))
1049 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1051 "adc%?\\t%0, %1, %3%S2"
1052 [(set_attr "conds" "use")
1053 (set_attr "predicable" "yes")
1054 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1055 (const_string "alu_shift_imm")
1056 (const_string "alu_shift_reg")))]
1059 (define_insn "*addsi3_carryin_clobercc_<optab>"
1060 [(set (match_operand:SI 0 "s_register_operand" "=r")
1061 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1062 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1063 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1064 (clobber (reg:CC CC_REGNUM))]
1066 "adcs%?\\t%0, %1, %2"
1067 [(set_attr "conds" "set")
1068 (set_attr "type" "adcs_reg")]
1071 (define_expand "subv<mode>4"
1072 [(match_operand:SIDI 0 "register_operand")
1073 (match_operand:SIDI 1 "register_operand")
1074 (match_operand:SIDI 2 "register_operand")
1075 (match_operand 3 "")]
1078 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1079 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1084 (define_expand "usubv<mode>4"
1085 [(match_operand:SIDI 0 "register_operand")
1086 (match_operand:SIDI 1 "register_operand")
1087 (match_operand:SIDI 2 "register_operand")
1088 (match_operand 3 "")]
1091 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1092 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1097 (define_insn_and_split "subdi3_compare1"
1098 [(set (reg:CC CC_REGNUM)
1100 (match_operand:DI 1 "register_operand" "r")
1101 (match_operand:DI 2 "register_operand" "r")))
1102 (set (match_operand:DI 0 "register_operand" "=&r")
1103 (minus:DI (match_dup 1) (match_dup 2)))]
1106 "&& reload_completed"
1107 [(parallel [(set (reg:CC CC_REGNUM)
1108 (compare:CC (match_dup 1) (match_dup 2)))
1109 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1110 (parallel [(set (reg:CC CC_REGNUM)
1111 (compare:CC (match_dup 4) (match_dup 5)))
1112 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1113 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))])]
1115 operands[3] = gen_highpart (SImode, operands[0]);
1116 operands[0] = gen_lowpart (SImode, operands[0]);
1117 operands[4] = gen_highpart (SImode, operands[1]);
1118 operands[1] = gen_lowpart (SImode, operands[1]);
1119 operands[5] = gen_highpart (SImode, operands[2]);
1120 operands[2] = gen_lowpart (SImode, operands[2]);
1122 [(set_attr "conds" "set")
1123 (set_attr "length" "8")
1124 (set_attr "type" "multiple")]
1127 (define_insn "subsi3_compare1"
1128 [(set (reg:CC CC_REGNUM)
1130 (match_operand:SI 1 "register_operand" "r")
1131 (match_operand:SI 2 "register_operand" "r")))
1132 (set (match_operand:SI 0 "register_operand" "=r")
1133 (minus:SI (match_dup 1) (match_dup 2)))]
1135 "subs%?\\t%0, %1, %2"
1136 [(set_attr "conds" "set")
1137 (set_attr "type" "alus_sreg")]
1140 (define_insn "*subsi3_carryin"
1141 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1142 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1143 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1144 (match_operand:SI 3 "arm_borrow_operation" "")))]
1149 sbc%?\\t%0, %2, %2, lsl #1"
1150 [(set_attr "conds" "use")
1151 (set_attr "arch" "*,a,t2")
1152 (set_attr "predicable" "yes")
1153 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1156 (define_insn "*subsi3_carryin_const"
1157 [(set (match_operand:SI 0 "s_register_operand" "=r")
1159 (match_operand:SI 1 "s_register_operand" "r")
1160 (match_operand:SI 2 "arm_neg_immediate_operand" "L"))
1161 (match_operand:SI 3 "arm_borrow_operation" "")))]
1163 "sbc\\t%0, %1, #%n2"
1164 [(set_attr "conds" "use")
1165 (set_attr "type" "adc_imm")]
1168 (define_insn "*subsi3_carryin_const0"
1169 [(set (match_operand:SI 0 "s_register_operand" "=r")
1170 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
1171 (match_operand:SI 2 "arm_borrow_operation" "")))]
1174 [(set_attr "conds" "use")
1175 (set_attr "type" "adc_imm")]
1178 (define_insn "*subsi3_carryin_compare"
1179 [(set (reg:CC CC_REGNUM)
1180 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1181 (match_operand:SI 2 "s_register_operand" "r")))
1182 (set (match_operand:SI 0 "s_register_operand" "=r")
1183 (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1184 (match_operand:SI 3 "arm_borrow_operation" "")))]
1187 [(set_attr "conds" "set")
1188 (set_attr "type" "adcs_reg")]
1191 (define_insn "*subsi3_carryin_compare_const"
1192 [(set (reg:CC CC_REGNUM)
1193 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1194 (match_operand:SI 2 "const_int_I_operand" "I")))
1195 (set (match_operand:SI 0 "s_register_operand" "=r")
1198 (match_operand:SI 3 "arm_neg_immediate_operand" "L"))
1199 (match_operand:SI 4 "arm_borrow_operation" "")))]
1201 && (INTVAL (operands[2])
1202 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
1203 "sbcs\\t%0, %1, #%n3"
1204 [(set_attr "conds" "set")
1205 (set_attr "type" "adcs_imm")]
1208 (define_insn "*subsi3_carryin_compare_const0"
1209 [(set (reg:CC CC_REGNUM)
1210 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1212 (set (match_operand:SI 0 "s_register_operand" "=r")
1213 (minus:SI (match_dup 1)
1214 (match_operand:SI 2 "arm_borrow_operation" "")))]
1217 [(set_attr "conds" "set")
1218 (set_attr "type" "adcs_imm")]
1221 (define_insn "*subsi3_carryin_shift"
1222 [(set (match_operand:SI 0 "s_register_operand" "=r")
1224 (match_operand:SI 1 "s_register_operand" "r")
1225 (match_operator:SI 2 "shift_operator"
1226 [(match_operand:SI 3 "s_register_operand" "r")
1227 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1228 (match_operand:SI 5 "arm_borrow_operation" "")))]
1230 "sbc%?\\t%0, %1, %3%S2"
1231 [(set_attr "conds" "use")
1232 (set_attr "predicable" "yes")
1233 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1234 (const_string "alu_shift_imm")
1235 (const_string "alu_shift_reg")))]
1238 (define_insn "*rsbsi3_carryin_shift"
1239 [(set (match_operand:SI 0 "s_register_operand" "=r")
1241 (match_operator:SI 2 "shift_operator"
1242 [(match_operand:SI 3 "s_register_operand" "r")
1243 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1244 (match_operand:SI 1 "s_register_operand" "r"))
1245 (match_operand:SI 5 "arm_borrow_operation" "")))]
1247 "rsc%?\\t%0, %1, %3%S2"
1248 [(set_attr "conds" "use")
1249 (set_attr "predicable" "yes")
1250 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1251 (const_string "alu_shift_imm")
1252 (const_string "alu_shift_reg")))]
1255 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1257 [(set (match_operand:SI 0 "s_register_operand" "")
1258 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1259 (match_operand:SI 2 "s_register_operand" ""))
1261 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1263 [(set (match_dup 3) (match_dup 1))
1264 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1266 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1269 (define_expand "addsf3"
1270 [(set (match_operand:SF 0 "s_register_operand")
1271 (plus:SF (match_operand:SF 1 "s_register_operand")
1272 (match_operand:SF 2 "s_register_operand")))]
1273 "TARGET_32BIT && TARGET_HARD_FLOAT"
1277 (define_expand "adddf3"
1278 [(set (match_operand:DF 0 "s_register_operand")
1279 (plus:DF (match_operand:DF 1 "s_register_operand")
1280 (match_operand:DF 2 "s_register_operand")))]
1281 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1285 (define_expand "subdi3"
1287 [(set (match_operand:DI 0 "s_register_operand")
1288 (minus:DI (match_operand:DI 1 "s_register_operand")
1289 (match_operand:DI 2 "s_register_operand")))
1290 (clobber (reg:CC CC_REGNUM))])]
1295 (define_insn_and_split "*arm_subdi3"
1296 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
1297 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1298 (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1299 (clobber (reg:CC CC_REGNUM))]
1301 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1303 [(parallel [(set (reg:CC CC_REGNUM)
1304 (compare:CC (match_dup 1) (match_dup 2)))
1305 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1306 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1307 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1309 operands[3] = gen_highpart (SImode, operands[0]);
1310 operands[0] = gen_lowpart (SImode, operands[0]);
1311 operands[4] = gen_highpart (SImode, operands[1]);
1312 operands[1] = gen_lowpart (SImode, operands[1]);
1313 operands[5] = gen_highpart (SImode, operands[2]);
1314 operands[2] = gen_lowpart (SImode, operands[2]);
1316 [(set_attr "conds" "clob")
1317 (set_attr "length" "8")
1318 (set_attr "type" "multiple")]
1321 (define_insn_and_split "*subdi_di_zesidi"
1322 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1323 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1325 (match_operand:SI 2 "s_register_operand" "r,r"))))
1326 (clobber (reg:CC CC_REGNUM))]
1328 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1329 "&& reload_completed"
1330 [(parallel [(set (reg:CC CC_REGNUM)
1331 (compare:CC (match_dup 1) (match_dup 2)))
1332 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1333 (set (match_dup 3) (minus:SI (match_dup 4)
1334 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1336 operands[3] = gen_highpart (SImode, operands[0]);
1337 operands[0] = gen_lowpart (SImode, operands[0]);
1338 operands[4] = gen_highpart (SImode, operands[1]);
1339 operands[1] = gen_lowpart (SImode, operands[1]);
1341 [(set_attr "conds" "clob")
1342 (set_attr "length" "8")
1343 (set_attr "type" "multiple")]
1346 (define_insn_and_split "*subdi_di_sesidi"
1347 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1348 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1350 (match_operand:SI 2 "s_register_operand" "r,r"))))
1351 (clobber (reg:CC CC_REGNUM))]
1353 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1354 "&& reload_completed"
1355 [(parallel [(set (reg:CC CC_REGNUM)
1356 (compare:CC (match_dup 1) (match_dup 2)))
1357 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1358 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1359 (ashiftrt:SI (match_dup 2)
1361 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1363 operands[3] = gen_highpart (SImode, operands[0]);
1364 operands[0] = gen_lowpart (SImode, operands[0]);
1365 operands[4] = gen_highpart (SImode, operands[1]);
1366 operands[1] = gen_lowpart (SImode, operands[1]);
1368 [(set_attr "conds" "clob")
1369 (set_attr "length" "8")
1370 (set_attr "type" "multiple")]
1373 (define_insn_and_split "*subdi_zesidi_di"
1374 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1375 (minus:DI (zero_extend:DI
1376 (match_operand:SI 2 "s_register_operand" "r,r"))
1377 (match_operand:DI 1 "s_register_operand" "0,r")))
1378 (clobber (reg:CC CC_REGNUM))]
1380 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1382 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1383 "&& reload_completed"
1384 [(parallel [(set (reg:CC CC_REGNUM)
1385 (compare:CC (match_dup 2) (match_dup 1)))
1386 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1387 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1388 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1390 operands[3] = gen_highpart (SImode, operands[0]);
1391 operands[0] = gen_lowpart (SImode, operands[0]);
1392 operands[4] = gen_highpart (SImode, operands[1]);
1393 operands[1] = gen_lowpart (SImode, operands[1]);
1395 [(set_attr "conds" "clob")
1396 (set_attr "length" "8")
1397 (set_attr "type" "multiple")]
1400 (define_insn_and_split "*subdi_sesidi_di"
1401 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1402 (minus:DI (sign_extend:DI
1403 (match_operand:SI 2 "s_register_operand" "r,r"))
1404 (match_operand:DI 1 "s_register_operand" "0,r")))
1405 (clobber (reg:CC CC_REGNUM))]
1407 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1409 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1410 "&& reload_completed"
1411 [(parallel [(set (reg:CC CC_REGNUM)
1412 (compare:CC (match_dup 2) (match_dup 1)))
1413 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1414 (set (match_dup 3) (minus:SI (minus:SI
1415 (ashiftrt:SI (match_dup 2)
1418 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1420 operands[3] = gen_highpart (SImode, operands[0]);
1421 operands[0] = gen_lowpart (SImode, operands[0]);
1422 operands[4] = gen_highpart (SImode, operands[1]);
1423 operands[1] = gen_lowpart (SImode, operands[1]);
1425 [(set_attr "conds" "clob")
1426 (set_attr "length" "8")
1427 (set_attr "type" "multiple")]
1430 (define_insn_and_split "*subdi_zesidi_zesidi"
1431 [(set (match_operand:DI 0 "s_register_operand" "=r")
1432 (minus:DI (zero_extend:DI
1433 (match_operand:SI 1 "s_register_operand" "r"))
1435 (match_operand:SI 2 "s_register_operand" "r"))))
1436 (clobber (reg:CC CC_REGNUM))]
1438 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1439 "&& reload_completed"
1440 [(parallel [(set (reg:CC CC_REGNUM)
1441 (compare:CC (match_dup 1) (match_dup 2)))
1442 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1443 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1444 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1446 operands[3] = gen_highpart (SImode, operands[0]);
1447 operands[0] = gen_lowpart (SImode, operands[0]);
1449 [(set_attr "conds" "clob")
1450 (set_attr "length" "8")
1451 (set_attr "type" "multiple")]
1454 (define_expand "subsi3"
1455 [(set (match_operand:SI 0 "s_register_operand")
1456 (minus:SI (match_operand:SI 1 "reg_or_int_operand")
1457 (match_operand:SI 2 "s_register_operand")))]
1460 if (CONST_INT_P (operands[1]))
1464 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1465 operands[1] = force_reg (SImode, operands[1]);
1468 arm_split_constant (MINUS, SImode, NULL_RTX,
1469 INTVAL (operands[1]), operands[0],
1471 optimize && can_create_pseudo_p ());
1475 else /* TARGET_THUMB1 */
1476 operands[1] = force_reg (SImode, operands[1]);
1481 ; ??? Check Thumb-2 split length
1482 (define_insn_and_split "*arm_subsi3_insn"
1483 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1484 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1485 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1497 "&& (CONST_INT_P (operands[1])
1498 && !const_ok_for_arm (INTVAL (operands[1])))"
1499 [(clobber (const_int 0))]
1501 arm_split_constant (MINUS, SImode, curr_insn,
1502 INTVAL (operands[1]), operands[0], operands[2], 0);
1505 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1506 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1507 (set_attr "predicable" "yes")
1508 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1509 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1513 [(match_scratch:SI 3 "r")
1514 (set (match_operand:SI 0 "arm_general_register_operand" "")
1515 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1516 (match_operand:SI 2 "arm_general_register_operand" "")))]
1518 && !const_ok_for_arm (INTVAL (operands[1]))
1519 && const_ok_for_arm (~INTVAL (operands[1]))"
1520 [(set (match_dup 3) (match_dup 1))
1521 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1525 (define_insn "subsi3_compare0"
1526 [(set (reg:CC_NOOV CC_REGNUM)
1528 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1529 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1531 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1532 (minus:SI (match_dup 1) (match_dup 2)))]
1537 rsbs%?\\t%0, %2, %1"
1538 [(set_attr "conds" "set")
1539 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1542 (define_insn "subsi3_compare"
1543 [(set (reg:CC CC_REGNUM)
1544 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1545 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1546 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1547 (minus:SI (match_dup 1) (match_dup 2)))]
1552 rsbs%?\\t%0, %2, %1"
1553 [(set_attr "conds" "set")
1554 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1557 (define_expand "subsf3"
1558 [(set (match_operand:SF 0 "s_register_operand")
1559 (minus:SF (match_operand:SF 1 "s_register_operand")
1560 (match_operand:SF 2 "s_register_operand")))]
1561 "TARGET_32BIT && TARGET_HARD_FLOAT"
1565 (define_expand "subdf3"
1566 [(set (match_operand:DF 0 "s_register_operand")
1567 (minus:DF (match_operand:DF 1 "s_register_operand")
1568 (match_operand:DF 2 "s_register_operand")))]
1569 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1574 ;; Multiplication insns
1576 (define_expand "mulhi3"
1577 [(set (match_operand:HI 0 "s_register_operand")
1578 (mult:HI (match_operand:HI 1 "s_register_operand")
1579 (match_operand:HI 2 "s_register_operand")))]
1580 "TARGET_DSP_MULTIPLY"
1583 rtx result = gen_reg_rtx (SImode);
1584 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1585 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1590 (define_expand "mulsi3"
1591 [(set (match_operand:SI 0 "s_register_operand")
1592 (mult:SI (match_operand:SI 2 "s_register_operand")
1593 (match_operand:SI 1 "s_register_operand")))]
1598 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1599 (define_insn "*arm_mulsi3"
1600 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1601 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1602 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1603 "TARGET_32BIT && !arm_arch6"
1604 "mul%?\\t%0, %2, %1"
1605 [(set_attr "type" "mul")
1606 (set_attr "predicable" "yes")]
1609 (define_insn "*arm_mulsi3_v6"
1610 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1611 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1612 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1613 "TARGET_32BIT && arm_arch6"
1614 "mul%?\\t%0, %1, %2"
1615 [(set_attr "type" "mul")
1616 (set_attr "predicable" "yes")
1617 (set_attr "arch" "t2,t2,*")
1618 (set_attr "length" "4")
1619 (set_attr "predicable_short_it" "yes,yes,no")]
1622 (define_insn "*mulsi3_compare0"
1623 [(set (reg:CC_NOOV CC_REGNUM)
1624 (compare:CC_NOOV (mult:SI
1625 (match_operand:SI 2 "s_register_operand" "r,r")
1626 (match_operand:SI 1 "s_register_operand" "%0,r"))
1628 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1629 (mult:SI (match_dup 2) (match_dup 1)))]
1630 "TARGET_ARM && !arm_arch6"
1631 "muls%?\\t%0, %2, %1"
1632 [(set_attr "conds" "set")
1633 (set_attr "type" "muls")]
1636 (define_insn "*mulsi3_compare0_v6"
1637 [(set (reg:CC_NOOV CC_REGNUM)
1638 (compare:CC_NOOV (mult:SI
1639 (match_operand:SI 2 "s_register_operand" "r")
1640 (match_operand:SI 1 "s_register_operand" "r"))
1642 (set (match_operand:SI 0 "s_register_operand" "=r")
1643 (mult:SI (match_dup 2) (match_dup 1)))]
1644 "TARGET_ARM && arm_arch6 && optimize_size"
1645 "muls%?\\t%0, %2, %1"
1646 [(set_attr "conds" "set")
1647 (set_attr "type" "muls")]
1650 (define_insn "*mulsi_compare0_scratch"
1651 [(set (reg:CC_NOOV CC_REGNUM)
1652 (compare:CC_NOOV (mult:SI
1653 (match_operand:SI 2 "s_register_operand" "r,r")
1654 (match_operand:SI 1 "s_register_operand" "%0,r"))
1656 (clobber (match_scratch:SI 0 "=&r,&r"))]
1657 "TARGET_ARM && !arm_arch6"
1658 "muls%?\\t%0, %2, %1"
1659 [(set_attr "conds" "set")
1660 (set_attr "type" "muls")]
1663 (define_insn "*mulsi_compare0_scratch_v6"
1664 [(set (reg:CC_NOOV CC_REGNUM)
1665 (compare:CC_NOOV (mult:SI
1666 (match_operand:SI 2 "s_register_operand" "r")
1667 (match_operand:SI 1 "s_register_operand" "r"))
1669 (clobber (match_scratch:SI 0 "=r"))]
1670 "TARGET_ARM && arm_arch6 && optimize_size"
1671 "muls%?\\t%0, %2, %1"
1672 [(set_attr "conds" "set")
1673 (set_attr "type" "muls")]
1676 ;; Unnamed templates to match MLA instruction.
1678 (define_insn "*mulsi3addsi"
1679 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1681 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1682 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1683 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1684 "TARGET_32BIT && !arm_arch6"
1685 "mla%?\\t%0, %2, %1, %3"
1686 [(set_attr "type" "mla")
1687 (set_attr "predicable" "yes")]
1690 (define_insn "*mulsi3addsi_v6"
1691 [(set (match_operand:SI 0 "s_register_operand" "=r")
1693 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1694 (match_operand:SI 1 "s_register_operand" "r"))
1695 (match_operand:SI 3 "s_register_operand" "r")))]
1696 "TARGET_32BIT && arm_arch6"
1697 "mla%?\\t%0, %2, %1, %3"
1698 [(set_attr "type" "mla")
1699 (set_attr "predicable" "yes")]
1702 (define_insn "*mulsi3addsi_compare0"
1703 [(set (reg:CC_NOOV CC_REGNUM)
1706 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1707 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1708 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1710 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1711 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1713 "TARGET_ARM && arm_arch6"
1714 "mlas%?\\t%0, %2, %1, %3"
1715 [(set_attr "conds" "set")
1716 (set_attr "type" "mlas")]
1719 (define_insn "*mulsi3addsi_compare0_v6"
1720 [(set (reg:CC_NOOV CC_REGNUM)
1723 (match_operand:SI 2 "s_register_operand" "r")
1724 (match_operand:SI 1 "s_register_operand" "r"))
1725 (match_operand:SI 3 "s_register_operand" "r"))
1727 (set (match_operand:SI 0 "s_register_operand" "=r")
1728 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1730 "TARGET_ARM && arm_arch6 && optimize_size"
1731 "mlas%?\\t%0, %2, %1, %3"
1732 [(set_attr "conds" "set")
1733 (set_attr "type" "mlas")]
1736 (define_insn "*mulsi3addsi_compare0_scratch"
1737 [(set (reg:CC_NOOV CC_REGNUM)
1740 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1741 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1742 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1744 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1745 "TARGET_ARM && !arm_arch6"
1746 "mlas%?\\t%0, %2, %1, %3"
1747 [(set_attr "conds" "set")
1748 (set_attr "type" "mlas")]
1751 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1752 [(set (reg:CC_NOOV CC_REGNUM)
1755 (match_operand:SI 2 "s_register_operand" "r")
1756 (match_operand:SI 1 "s_register_operand" "r"))
1757 (match_operand:SI 3 "s_register_operand" "r"))
1759 (clobber (match_scratch:SI 0 "=r"))]
1760 "TARGET_ARM && arm_arch6 && optimize_size"
1761 "mlas%?\\t%0, %2, %1, %3"
1762 [(set_attr "conds" "set")
1763 (set_attr "type" "mlas")]
1766 (define_insn "*mulsi3subsi"
1767 [(set (match_operand:SI 0 "s_register_operand" "=r")
1769 (match_operand:SI 3 "s_register_operand" "r")
1770 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1771 (match_operand:SI 1 "s_register_operand" "r"))))]
1772 "TARGET_32BIT && arm_arch_thumb2"
1773 "mls%?\\t%0, %2, %1, %3"
1774 [(set_attr "type" "mla")
1775 (set_attr "predicable" "yes")]
1778 (define_expand "maddsidi4"
1779 [(set (match_operand:DI 0 "s_register_operand")
1782 (sign_extend:DI (match_operand:SI 1 "s_register_operand"))
1783 (sign_extend:DI (match_operand:SI 2 "s_register_operand")))
1784 (match_operand:DI 3 "s_register_operand")))]
1788 (define_insn "*mulsidi3adddi"
1789 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1792 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1793 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1794 (match_operand:DI 1 "s_register_operand" "0")))]
1795 "TARGET_32BIT && !arm_arch6"
1796 "smlal%?\\t%Q0, %R0, %3, %2"
1797 [(set_attr "type" "smlal")
1798 (set_attr "predicable" "yes")]
1801 (define_insn "*mulsidi3adddi_v6"
1802 [(set (match_operand:DI 0 "s_register_operand" "=r")
1805 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1806 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1807 (match_operand:DI 1 "s_register_operand" "0")))]
1808 "TARGET_32BIT && arm_arch6"
1809 "smlal%?\\t%Q0, %R0, %3, %2"
1810 [(set_attr "type" "smlal")
1811 (set_attr "predicable" "yes")]
1814 ;; 32x32->64 widening multiply.
1815 ;; As with mulsi3, the only difference between the v3-5 and v6+
1816 ;; versions of these patterns is the requirement that the output not
1817 ;; overlap the inputs, but that still means we have to have a named
1818 ;; expander and two different starred insns.
1820 (define_expand "mulsidi3"
1821 [(set (match_operand:DI 0 "s_register_operand")
1823 (sign_extend:DI (match_operand:SI 1 "s_register_operand"))
1824 (sign_extend:DI (match_operand:SI 2 "s_register_operand"))))]
1829 (define_insn "*mulsidi3_nov6"
1830 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1832 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1833 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1834 "TARGET_32BIT && !arm_arch6"
1835 "smull%?\\t%Q0, %R0, %1, %2"
1836 [(set_attr "type" "smull")
1837 (set_attr "predicable" "yes")]
1840 (define_insn "*mulsidi3_v6"
1841 [(set (match_operand:DI 0 "s_register_operand" "=r")
1843 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1844 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1845 "TARGET_32BIT && arm_arch6"
1846 "smull%?\\t%Q0, %R0, %1, %2"
1847 [(set_attr "type" "smull")
1848 (set_attr "predicable" "yes")]
1851 (define_expand "umulsidi3"
1852 [(set (match_operand:DI 0 "s_register_operand")
1854 (zero_extend:DI (match_operand:SI 1 "s_register_operand"))
1855 (zero_extend:DI (match_operand:SI 2 "s_register_operand"))))]
1860 (define_insn "*umulsidi3_nov6"
1861 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1863 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1864 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1865 "TARGET_32BIT && !arm_arch6"
1866 "umull%?\\t%Q0, %R0, %1, %2"
1867 [(set_attr "type" "umull")
1868 (set_attr "predicable" "yes")]
1871 (define_insn "*umulsidi3_v6"
1872 [(set (match_operand:DI 0 "s_register_operand" "=r")
1874 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1875 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1876 "TARGET_32BIT && arm_arch6"
1877 "umull%?\\t%Q0, %R0, %1, %2"
1878 [(set_attr "type" "umull")
1879 (set_attr "predicable" "yes")]
1882 (define_expand "umaddsidi4"
1883 [(set (match_operand:DI 0 "s_register_operand")
1886 (zero_extend:DI (match_operand:SI 1 "s_register_operand"))
1887 (zero_extend:DI (match_operand:SI 2 "s_register_operand")))
1888 (match_operand:DI 3 "s_register_operand")))]
1892 (define_insn "*umulsidi3adddi"
1893 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1896 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1897 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1898 (match_operand:DI 1 "s_register_operand" "0")))]
1899 "TARGET_32BIT && !arm_arch6"
1900 "umlal%?\\t%Q0, %R0, %3, %2"
1901 [(set_attr "type" "umlal")
1902 (set_attr "predicable" "yes")]
1905 (define_insn "*umulsidi3adddi_v6"
1906 [(set (match_operand:DI 0 "s_register_operand" "=r")
1909 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1910 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1911 (match_operand:DI 1 "s_register_operand" "0")))]
1912 "TARGET_32BIT && arm_arch6"
1913 "umlal%?\\t%Q0, %R0, %3, %2"
1914 [(set_attr "type" "umlal")
1915 (set_attr "predicable" "yes")]
1918 (define_expand "smulsi3_highpart"
1920 [(set (match_operand:SI 0 "s_register_operand")
1924 (sign_extend:DI (match_operand:SI 1 "s_register_operand"))
1925 (sign_extend:DI (match_operand:SI 2 "s_register_operand")))
1927 (clobber (match_scratch:SI 3 ""))])]
1932 (define_insn "*smulsi3_highpart_nov6"
1933 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1937 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1938 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1940 (clobber (match_scratch:SI 3 "=&r,&r"))]
1941 "TARGET_32BIT && !arm_arch6"
1942 "smull%?\\t%3, %0, %2, %1"
1943 [(set_attr "type" "smull")
1944 (set_attr "predicable" "yes")]
1947 (define_insn "*smulsi3_highpart_v6"
1948 [(set (match_operand:SI 0 "s_register_operand" "=r")
1952 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1953 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1955 (clobber (match_scratch:SI 3 "=r"))]
1956 "TARGET_32BIT && arm_arch6"
1957 "smull%?\\t%3, %0, %2, %1"
1958 [(set_attr "type" "smull")
1959 (set_attr "predicable" "yes")]
1962 (define_expand "umulsi3_highpart"
1964 [(set (match_operand:SI 0 "s_register_operand")
1968 (zero_extend:DI (match_operand:SI 1 "s_register_operand"))
1969 (zero_extend:DI (match_operand:SI 2 "s_register_operand")))
1971 (clobber (match_scratch:SI 3 ""))])]
1976 (define_insn "*umulsi3_highpart_nov6"
1977 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1981 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1982 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1984 (clobber (match_scratch:SI 3 "=&r,&r"))]
1985 "TARGET_32BIT && !arm_arch6"
1986 "umull%?\\t%3, %0, %2, %1"
1987 [(set_attr "type" "umull")
1988 (set_attr "predicable" "yes")]
1991 (define_insn "*umulsi3_highpart_v6"
1992 [(set (match_operand:SI 0 "s_register_operand" "=r")
1996 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1997 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1999 (clobber (match_scratch:SI 3 "=r"))]
2000 "TARGET_32BIT && arm_arch6"
2001 "umull%?\\t%3, %0, %2, %1"
2002 [(set_attr "type" "umull")
2003 (set_attr "predicable" "yes")]
2006 (define_insn "mulhisi3"
2007 [(set (match_operand:SI 0 "s_register_operand" "=r")
2008 (mult:SI (sign_extend:SI
2009 (match_operand:HI 1 "s_register_operand" "%r"))
2011 (match_operand:HI 2 "s_register_operand" "r"))))]
2012 "TARGET_DSP_MULTIPLY"
2013 "smulbb%?\\t%0, %1, %2"
2014 [(set_attr "type" "smulxy")
2015 (set_attr "predicable" "yes")]
2018 (define_insn "*mulhisi3tb"
2019 [(set (match_operand:SI 0 "s_register_operand" "=r")
2020 (mult:SI (ashiftrt:SI
2021 (match_operand:SI 1 "s_register_operand" "r")
2024 (match_operand:HI 2 "s_register_operand" "r"))))]
2025 "TARGET_DSP_MULTIPLY"
2026 "smultb%?\\t%0, %1, %2"
2027 [(set_attr "type" "smulxy")
2028 (set_attr "predicable" "yes")]
2031 (define_insn "*mulhisi3bt"
2032 [(set (match_operand:SI 0 "s_register_operand" "=r")
2033 (mult:SI (sign_extend:SI
2034 (match_operand:HI 1 "s_register_operand" "r"))
2036 (match_operand:SI 2 "s_register_operand" "r")
2038 "TARGET_DSP_MULTIPLY"
2039 "smulbt%?\\t%0, %1, %2"
2040 [(set_attr "type" "smulxy")
2041 (set_attr "predicable" "yes")]
2044 (define_insn "*mulhisi3tt"
2045 [(set (match_operand:SI 0 "s_register_operand" "=r")
2046 (mult:SI (ashiftrt:SI
2047 (match_operand:SI 1 "s_register_operand" "r")
2050 (match_operand:SI 2 "s_register_operand" "r")
2052 "TARGET_DSP_MULTIPLY"
2053 "smultt%?\\t%0, %1, %2"
2054 [(set_attr "type" "smulxy")
2055 (set_attr "predicable" "yes")]
2058 (define_insn "maddhisi4"
2059 [(set (match_operand:SI 0 "s_register_operand" "=r")
2060 (plus:SI (mult:SI (sign_extend:SI
2061 (match_operand:HI 1 "s_register_operand" "r"))
2063 (match_operand:HI 2 "s_register_operand" "r")))
2064 (match_operand:SI 3 "s_register_operand" "r")))]
2065 "TARGET_DSP_MULTIPLY"
2066 "smlabb%?\\t%0, %1, %2, %3"
2067 [(set_attr "type" "smlaxy")
2068 (set_attr "predicable" "yes")]
2071 ;; Note: there is no maddhisi4ibt because this one is canonical form
2072 (define_insn "*maddhisi4tb"
2073 [(set (match_operand:SI 0 "s_register_operand" "=r")
2074 (plus:SI (mult:SI (ashiftrt:SI
2075 (match_operand:SI 1 "s_register_operand" "r")
2078 (match_operand:HI 2 "s_register_operand" "r")))
2079 (match_operand:SI 3 "s_register_operand" "r")))]
2080 "TARGET_DSP_MULTIPLY"
2081 "smlatb%?\\t%0, %1, %2, %3"
2082 [(set_attr "type" "smlaxy")
2083 (set_attr "predicable" "yes")]
2086 (define_insn "*maddhisi4tt"
2087 [(set (match_operand:SI 0 "s_register_operand" "=r")
2088 (plus:SI (mult:SI (ashiftrt:SI
2089 (match_operand:SI 1 "s_register_operand" "r")
2092 (match_operand:SI 2 "s_register_operand" "r")
2094 (match_operand:SI 3 "s_register_operand" "r")))]
2095 "TARGET_DSP_MULTIPLY"
2096 "smlatt%?\\t%0, %1, %2, %3"
2097 [(set_attr "type" "smlaxy")
2098 (set_attr "predicable" "yes")]
2101 (define_insn "maddhidi4"
2102 [(set (match_operand:DI 0 "s_register_operand" "=r")
2104 (mult:DI (sign_extend:DI
2105 (match_operand:HI 1 "s_register_operand" "r"))
2107 (match_operand:HI 2 "s_register_operand" "r")))
2108 (match_operand:DI 3 "s_register_operand" "0")))]
2109 "TARGET_DSP_MULTIPLY"
2110 "smlalbb%?\\t%Q0, %R0, %1, %2"
2111 [(set_attr "type" "smlalxy")
2112 (set_attr "predicable" "yes")])
2114 ;; Note: there is no maddhidi4ibt because this one is canonical form
2115 (define_insn "*maddhidi4tb"
2116 [(set (match_operand:DI 0 "s_register_operand" "=r")
2118 (mult:DI (sign_extend:DI
2120 (match_operand:SI 1 "s_register_operand" "r")
2123 (match_operand:HI 2 "s_register_operand" "r")))
2124 (match_operand:DI 3 "s_register_operand" "0")))]
2125 "TARGET_DSP_MULTIPLY"
2126 "smlaltb%?\\t%Q0, %R0, %1, %2"
2127 [(set_attr "type" "smlalxy")
2128 (set_attr "predicable" "yes")])
2130 (define_insn "*maddhidi4tt"
2131 [(set (match_operand:DI 0 "s_register_operand" "=r")
2133 (mult:DI (sign_extend:DI
2135 (match_operand:SI 1 "s_register_operand" "r")
2139 (match_operand:SI 2 "s_register_operand" "r")
2141 (match_operand:DI 3 "s_register_operand" "0")))]
2142 "TARGET_DSP_MULTIPLY"
2143 "smlaltt%?\\t%Q0, %R0, %1, %2"
2144 [(set_attr "type" "smlalxy")
2145 (set_attr "predicable" "yes")])
2147 (define_expand "mulsf3"
2148 [(set (match_operand:SF 0 "s_register_operand")
2149 (mult:SF (match_operand:SF 1 "s_register_operand")
2150 (match_operand:SF 2 "s_register_operand")))]
2151 "TARGET_32BIT && TARGET_HARD_FLOAT"
2155 (define_expand "muldf3"
2156 [(set (match_operand:DF 0 "s_register_operand")
2157 (mult:DF (match_operand:DF 1 "s_register_operand")
2158 (match_operand:DF 2 "s_register_operand")))]
2159 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2165 (define_expand "divsf3"
2166 [(set (match_operand:SF 0 "s_register_operand")
2167 (div:SF (match_operand:SF 1 "s_register_operand")
2168 (match_operand:SF 2 "s_register_operand")))]
2169 "TARGET_32BIT && TARGET_HARD_FLOAT"
2172 (define_expand "divdf3"
2173 [(set (match_operand:DF 0 "s_register_operand")
2174 (div:DF (match_operand:DF 1 "s_register_operand")
2175 (match_operand:DF 2 "s_register_operand")))]
2176 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2180 ;; Split DImode and, ior, xor operations. Simply perform the logical
2181 ;; operation on the upper and lower halves of the registers.
2182 ;; This is needed for atomic operations in arm_split_atomic_op.
2183 ;; Avoid splitting IWMMXT instructions.
2185 [(set (match_operand:DI 0 "s_register_operand" "")
2186 (match_operator:DI 6 "logical_binary_operator"
2187 [(match_operand:DI 1 "s_register_operand" "")
2188 (match_operand:DI 2 "s_register_operand" "")]))]
2189 "TARGET_32BIT && reload_completed
2190 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2191 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2192 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2195 operands[3] = gen_highpart (SImode, operands[0]);
2196 operands[0] = gen_lowpart (SImode, operands[0]);
2197 operands[4] = gen_highpart (SImode, operands[1]);
2198 operands[1] = gen_lowpart (SImode, operands[1]);
2199 operands[5] = gen_highpart (SImode, operands[2]);
2200 operands[2] = gen_lowpart (SImode, operands[2]);
2204 ;; Split DImode not (needed for atomic operations in arm_split_atomic_op).
2205 ;; Unconditionally split since there is no SIMD DImode NOT pattern.
2207 [(set (match_operand:DI 0 "s_register_operand")
2208 (not:DI (match_operand:DI 1 "s_register_operand")))]
2210 [(set (match_dup 0) (not:SI (match_dup 1)))
2211 (set (match_dup 2) (not:SI (match_dup 3)))]
2214 operands[2] = gen_highpart (SImode, operands[0]);
2215 operands[0] = gen_lowpart (SImode, operands[0]);
2216 operands[3] = gen_highpart (SImode, operands[1]);
2217 operands[1] = gen_lowpart (SImode, operands[1]);
2221 (define_expand "andsi3"
2222 [(set (match_operand:SI 0 "s_register_operand")
2223 (and:SI (match_operand:SI 1 "s_register_operand")
2224 (match_operand:SI 2 "reg_or_int_operand")))]
2229 if (CONST_INT_P (operands[2]))
2231 if (INTVAL (operands[2]) == 255 && arm_arch6)
2233 operands[1] = convert_to_mode (QImode, operands[1], 1);
2234 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2238 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2239 operands[2] = force_reg (SImode, operands[2]);
2242 arm_split_constant (AND, SImode, NULL_RTX,
2243 INTVAL (operands[2]), operands[0],
2245 optimize && can_create_pseudo_p ());
2251 else /* TARGET_THUMB1 */
2253 if (!CONST_INT_P (operands[2]))
2255 rtx tmp = force_reg (SImode, operands[2]);
2256 if (rtx_equal_p (operands[0], operands[1]))
2260 operands[2] = operands[1];
2268 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2270 operands[2] = force_reg (SImode,
2271 GEN_INT (~INTVAL (operands[2])));
2273 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2278 for (i = 9; i <= 31; i++)
2280 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2282 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2286 else if ((HOST_WIDE_INT_1 << i) - 1
2287 == ~INTVAL (operands[2]))
2289 rtx shift = GEN_INT (i);
2290 rtx reg = gen_reg_rtx (SImode);
2292 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2293 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2299 operands[2] = force_reg (SImode, operands[2]);
2305 ; ??? Check split length for Thumb-2
2306 (define_insn_and_split "*arm_andsi3_insn"
2307 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2308 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2309 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2314 bic%?\\t%0, %1, #%B2
2318 && CONST_INT_P (operands[2])
2319 && !(const_ok_for_arm (INTVAL (operands[2]))
2320 || const_ok_for_arm (~INTVAL (operands[2])))"
2321 [(clobber (const_int 0))]
2323 arm_split_constant (AND, SImode, curr_insn,
2324 INTVAL (operands[2]), operands[0], operands[1], 0);
2327 [(set_attr "length" "4,4,4,4,16")
2328 (set_attr "predicable" "yes")
2329 (set_attr "predicable_short_it" "no,yes,no,no,no")
2330 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2333 (define_insn "*andsi3_compare0"
2334 [(set (reg:CC_NOOV CC_REGNUM)
2336 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2337 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2339 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2340 (and:SI (match_dup 1) (match_dup 2)))]
2344 bics%?\\t%0, %1, #%B2
2345 ands%?\\t%0, %1, %2"
2346 [(set_attr "conds" "set")
2347 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2350 (define_insn "*andsi3_compare0_scratch"
2351 [(set (reg:CC_NOOV CC_REGNUM)
2353 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2354 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2356 (clobber (match_scratch:SI 2 "=X,r,X"))]
2360 bics%?\\t%2, %0, #%B1
2362 [(set_attr "conds" "set")
2363 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2366 (define_insn "*zeroextractsi_compare0_scratch"
2367 [(set (reg:CC_NOOV CC_REGNUM)
2368 (compare:CC_NOOV (zero_extract:SI
2369 (match_operand:SI 0 "s_register_operand" "r")
2370 (match_operand 1 "const_int_operand" "n")
2371 (match_operand 2 "const_int_operand" "n"))
2374 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2375 && INTVAL (operands[1]) > 0
2376 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2377 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2379 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2380 << INTVAL (operands[2]));
2381 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2384 [(set_attr "conds" "set")
2385 (set_attr "predicable" "yes")
2386 (set_attr "type" "logics_imm")]
2389 (define_insn_and_split "*ne_zeroextractsi"
2390 [(set (match_operand:SI 0 "s_register_operand" "=r")
2391 (ne:SI (zero_extract:SI
2392 (match_operand:SI 1 "s_register_operand" "r")
2393 (match_operand:SI 2 "const_int_operand" "n")
2394 (match_operand:SI 3 "const_int_operand" "n"))
2396 (clobber (reg:CC CC_REGNUM))]
2398 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2399 && INTVAL (operands[2]) > 0
2400 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2401 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2404 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2405 && INTVAL (operands[2]) > 0
2406 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2407 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2408 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2409 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2411 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2413 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2414 (match_dup 0) (const_int 1)))]
2416 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2417 << INTVAL (operands[3]));
2419 [(set_attr "conds" "clob")
2420 (set (attr "length")
2421 (if_then_else (eq_attr "is_thumb" "yes")
2424 (set_attr "type" "multiple")]
2427 (define_insn_and_split "*ne_zeroextractsi_shifted"
2428 [(set (match_operand:SI 0 "s_register_operand" "=r")
2429 (ne:SI (zero_extract:SI
2430 (match_operand:SI 1 "s_register_operand" "r")
2431 (match_operand:SI 2 "const_int_operand" "n")
2434 (clobber (reg:CC CC_REGNUM))]
2438 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2439 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2441 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2443 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2444 (match_dup 0) (const_int 1)))]
2446 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2448 [(set_attr "conds" "clob")
2449 (set_attr "length" "8")
2450 (set_attr "type" "multiple")]
2453 (define_insn_and_split "*ite_ne_zeroextractsi"
2454 [(set (match_operand:SI 0 "s_register_operand" "=r")
2455 (if_then_else:SI (ne (zero_extract:SI
2456 (match_operand:SI 1 "s_register_operand" "r")
2457 (match_operand:SI 2 "const_int_operand" "n")
2458 (match_operand:SI 3 "const_int_operand" "n"))
2460 (match_operand:SI 4 "arm_not_operand" "rIK")
2462 (clobber (reg:CC CC_REGNUM))]
2464 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2465 && INTVAL (operands[2]) > 0
2466 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2467 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2468 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2471 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2472 && INTVAL (operands[2]) > 0
2473 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2474 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2475 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2476 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2477 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2479 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2481 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2482 (match_dup 0) (match_dup 4)))]
2484 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2485 << INTVAL (operands[3]));
2487 [(set_attr "conds" "clob")
2488 (set_attr "length" "8")
2489 (set_attr "type" "multiple")]
2492 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2493 [(set (match_operand:SI 0 "s_register_operand" "=r")
2494 (if_then_else:SI (ne (zero_extract:SI
2495 (match_operand:SI 1 "s_register_operand" "r")
2496 (match_operand:SI 2 "const_int_operand" "n")
2499 (match_operand:SI 3 "arm_not_operand" "rIK")
2501 (clobber (reg:CC CC_REGNUM))]
2502 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2504 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2505 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2506 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2508 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2510 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2511 (match_dup 0) (match_dup 3)))]
2513 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2515 [(set_attr "conds" "clob")
2516 (set_attr "length" "8")
2517 (set_attr "type" "multiple")]
2520 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2522 [(set (match_operand:SI 0 "s_register_operand" "")
2523 (match_operator:SI 1 "shiftable_operator"
2524 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2525 (match_operand:SI 3 "const_int_operand" "")
2526 (match_operand:SI 4 "const_int_operand" ""))
2527 (match_operand:SI 5 "s_register_operand" "")]))
2528 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2530 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2533 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2536 HOST_WIDE_INT temp = INTVAL (operands[3]);
2538 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2539 operands[4] = GEN_INT (32 - temp);
2544 [(set (match_operand:SI 0 "s_register_operand" "")
2545 (match_operator:SI 1 "shiftable_operator"
2546 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2547 (match_operand:SI 3 "const_int_operand" "")
2548 (match_operand:SI 4 "const_int_operand" ""))
2549 (match_operand:SI 5 "s_register_operand" "")]))
2550 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2552 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2555 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2558 HOST_WIDE_INT temp = INTVAL (operands[3]);
2560 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2561 operands[4] = GEN_INT (32 - temp);
2565 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2566 ;;; represented by the bitfield, then this will produce incorrect results.
2567 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2568 ;;; which have a real bit-field insert instruction, the truncation happens
2569 ;;; in the bit-field insert instruction itself. Since arm does not have a
2570 ;;; bit-field insert instruction, we would have to emit code here to truncate
2571 ;;; the value before we insert. This loses some of the advantage of having
2572 ;;; this insv pattern, so this pattern needs to be reevalutated.
2574 (define_expand "insv"
2575 [(set (zero_extract (match_operand 0 "nonimmediate_operand")
2576 (match_operand 1 "general_operand")
2577 (match_operand 2 "general_operand"))
2578 (match_operand 3 "reg_or_int_operand"))]
2579 "TARGET_ARM || arm_arch_thumb2"
2582 int start_bit = INTVAL (operands[2]);
2583 int width = INTVAL (operands[1]);
2584 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2585 rtx target, subtarget;
2587 if (arm_arch_thumb2)
2589 if (unaligned_access && MEM_P (operands[0])
2590 && s_register_operand (operands[3], GET_MODE (operands[3]))
2591 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2595 if (BYTES_BIG_ENDIAN)
2596 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2601 base_addr = adjust_address (operands[0], SImode,
2602 start_bit / BITS_PER_UNIT);
2603 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2607 rtx tmp = gen_reg_rtx (HImode);
2609 base_addr = adjust_address (operands[0], HImode,
2610 start_bit / BITS_PER_UNIT);
2611 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2612 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2616 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2618 bool use_bfi = TRUE;
2620 if (CONST_INT_P (operands[3]))
2622 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2626 emit_insn (gen_insv_zero (operands[0], operands[1],
2631 /* See if the set can be done with a single orr instruction. */
2632 if (val == mask && const_ok_for_arm (val << start_bit))
2638 if (!REG_P (operands[3]))
2639 operands[3] = force_reg (SImode, operands[3]);
2641 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2650 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2653 target = copy_rtx (operands[0]);
2654 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2655 subreg as the final target. */
2656 if (GET_CODE (target) == SUBREG)
2658 subtarget = gen_reg_rtx (SImode);
2659 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2660 < GET_MODE_SIZE (SImode))
2661 target = SUBREG_REG (target);
2666 if (CONST_INT_P (operands[3]))
2668 /* Since we are inserting a known constant, we may be able to
2669 reduce the number of bits that we have to clear so that
2670 the mask becomes simple. */
2671 /* ??? This code does not check to see if the new mask is actually
2672 simpler. It may not be. */
2673 rtx op1 = gen_reg_rtx (SImode);
2674 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2675 start of this pattern. */
2676 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2677 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2679 emit_insn (gen_andsi3 (op1, operands[0],
2680 gen_int_mode (~mask2, SImode)));
2681 emit_insn (gen_iorsi3 (subtarget, op1,
2682 gen_int_mode (op3_value << start_bit, SImode)));
2684 else if (start_bit == 0
2685 && !(const_ok_for_arm (mask)
2686 || const_ok_for_arm (~mask)))
2688 /* A Trick, since we are setting the bottom bits in the word,
2689 we can shift operand[3] up, operand[0] down, OR them together
2690 and rotate the result back again. This takes 3 insns, and
2691 the third might be mergeable into another op. */
2692 /* The shift up copes with the possibility that operand[3] is
2693 wider than the bitfield. */
2694 rtx op0 = gen_reg_rtx (SImode);
2695 rtx op1 = gen_reg_rtx (SImode);
2697 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2698 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2699 emit_insn (gen_iorsi3 (op1, op1, op0));
2700 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2702 else if ((width + start_bit == 32)
2703 && !(const_ok_for_arm (mask)
2704 || const_ok_for_arm (~mask)))
2706 /* Similar trick, but slightly less efficient. */
2708 rtx op0 = gen_reg_rtx (SImode);
2709 rtx op1 = gen_reg_rtx (SImode);
2711 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2712 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2713 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2714 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2718 rtx op0 = gen_int_mode (mask, SImode);
2719 rtx op1 = gen_reg_rtx (SImode);
2720 rtx op2 = gen_reg_rtx (SImode);
2722 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2724 rtx tmp = gen_reg_rtx (SImode);
2726 emit_insn (gen_movsi (tmp, op0));
2730 /* Mask out any bits in operand[3] that are not needed. */
2731 emit_insn (gen_andsi3 (op1, operands[3], op0));
2733 if (CONST_INT_P (op0)
2734 && (const_ok_for_arm (mask << start_bit)
2735 || const_ok_for_arm (~(mask << start_bit))))
2737 op0 = gen_int_mode (~(mask << start_bit), SImode);
2738 emit_insn (gen_andsi3 (op2, operands[0], op0));
2742 if (CONST_INT_P (op0))
2744 rtx tmp = gen_reg_rtx (SImode);
2746 emit_insn (gen_movsi (tmp, op0));
2751 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2753 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2757 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2759 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2762 if (subtarget != target)
2764 /* If TARGET is still a SUBREG, then it must be wider than a word,
2765 so we must be careful only to set the subword we were asked to. */
2766 if (GET_CODE (target) == SUBREG)
2767 emit_move_insn (target, subtarget);
2769 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2776 (define_insn "insv_zero"
2777 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2778 (match_operand:SI 1 "const_int_M_operand" "M")
2779 (match_operand:SI 2 "const_int_M_operand" "M"))
2783 [(set_attr "length" "4")
2784 (set_attr "predicable" "yes")
2785 (set_attr "type" "bfm")]
2788 (define_insn "insv_t2"
2789 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2790 (match_operand:SI 1 "const_int_M_operand" "M")
2791 (match_operand:SI 2 "const_int_M_operand" "M"))
2792 (match_operand:SI 3 "s_register_operand" "r"))]
2794 "bfi%?\t%0, %3, %2, %1"
2795 [(set_attr "length" "4")
2796 (set_attr "predicable" "yes")
2797 (set_attr "type" "bfm")]
2800 (define_insn "andsi_notsi_si"
2801 [(set (match_operand:SI 0 "s_register_operand" "=r")
2802 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2803 (match_operand:SI 1 "s_register_operand" "r")))]
2805 "bic%?\\t%0, %1, %2"
2806 [(set_attr "predicable" "yes")
2807 (set_attr "type" "logic_reg")]
2810 (define_insn "andsi_not_shiftsi_si"
2811 [(set (match_operand:SI 0 "s_register_operand" "=r")
2812 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2813 [(match_operand:SI 2 "s_register_operand" "r")
2814 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2815 (match_operand:SI 1 "s_register_operand" "r")))]
2817 "bic%?\\t%0, %1, %2%S4"
2818 [(set_attr "predicable" "yes")
2819 (set_attr "shift" "2")
2820 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2821 (const_string "logic_shift_imm")
2822 (const_string "logic_shift_reg")))]
2825 ;; Shifted bics pattern used to set up CC status register and not reusing
2826 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
2827 ;; does not support shift by register.
2828 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
2829 [(set (reg:CC_NOOV CC_REGNUM)
2831 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2832 [(match_operand:SI 1 "s_register_operand" "r")
2833 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2834 (match_operand:SI 3 "s_register_operand" "r"))
2836 (clobber (match_scratch:SI 4 "=r"))]
2837 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2838 "bics%?\\t%4, %3, %1%S0"
2839 [(set_attr "predicable" "yes")
2840 (set_attr "conds" "set")
2841 (set_attr "shift" "1")
2842 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2843 (const_string "logic_shift_imm")
2844 (const_string "logic_shift_reg")))]
2847 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
2848 ;; getting reused later.
2849 (define_insn "andsi_not_shiftsi_si_scc"
2850 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2852 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2853 [(match_operand:SI 1 "s_register_operand" "r")
2854 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2855 (match_operand:SI 3 "s_register_operand" "r"))
2857 (set (match_operand:SI 4 "s_register_operand" "=r")
2858 (and:SI (not:SI (match_op_dup 0
2862 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2863 "bics%?\\t%4, %3, %1%S0"
2864 [(set_attr "predicable" "yes")
2865 (set_attr "conds" "set")
2866 (set_attr "shift" "1")
2867 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2868 (const_string "logic_shift_imm")
2869 (const_string "logic_shift_reg")))]
2872 (define_insn "*andsi_notsi_si_compare0"
2873 [(set (reg:CC_NOOV CC_REGNUM)
2875 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2876 (match_operand:SI 1 "s_register_operand" "r"))
2878 (set (match_operand:SI 0 "s_register_operand" "=r")
2879 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2882 [(set_attr "conds" "set")
2883 (set_attr "type" "logics_shift_reg")]
2886 (define_insn "*andsi_notsi_si_compare0_scratch"
2887 [(set (reg:CC_NOOV CC_REGNUM)
2889 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2890 (match_operand:SI 1 "s_register_operand" "r"))
2892 (clobber (match_scratch:SI 0 "=r"))]
2895 [(set_attr "conds" "set")
2896 (set_attr "type" "logics_shift_reg")]
2899 (define_expand "iorsi3"
2900 [(set (match_operand:SI 0 "s_register_operand")
2901 (ior:SI (match_operand:SI 1 "s_register_operand")
2902 (match_operand:SI 2 "reg_or_int_operand")))]
2905 if (CONST_INT_P (operands[2]))
2909 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
2910 operands[2] = force_reg (SImode, operands[2]);
2913 arm_split_constant (IOR, SImode, NULL_RTX,
2914 INTVAL (operands[2]), operands[0],
2916 optimize && can_create_pseudo_p ());
2920 else /* TARGET_THUMB1 */
2922 rtx tmp = force_reg (SImode, operands[2]);
2923 if (rtx_equal_p (operands[0], operands[1]))
2927 operands[2] = operands[1];
2935 (define_insn_and_split "*iorsi3_insn"
2936 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2937 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2938 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2943 orn%?\\t%0, %1, #%B2
2947 && CONST_INT_P (operands[2])
2948 && !(const_ok_for_arm (INTVAL (operands[2]))
2949 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
2950 [(clobber (const_int 0))]
2952 arm_split_constant (IOR, SImode, curr_insn,
2953 INTVAL (operands[2]), operands[0], operands[1], 0);
2956 [(set_attr "length" "4,4,4,4,16")
2957 (set_attr "arch" "32,t2,t2,32,32")
2958 (set_attr "predicable" "yes")
2959 (set_attr "predicable_short_it" "no,yes,no,no,no")
2960 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
2964 [(match_scratch:SI 3 "r")
2965 (set (match_operand:SI 0 "arm_general_register_operand" "")
2966 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2967 (match_operand:SI 2 "const_int_operand" "")))]
2969 && !const_ok_for_arm (INTVAL (operands[2]))
2970 && const_ok_for_arm (~INTVAL (operands[2]))"
2971 [(set (match_dup 3) (match_dup 2))
2972 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2976 (define_insn "*iorsi3_compare0"
2977 [(set (reg:CC_NOOV CC_REGNUM)
2979 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r")
2980 (match_operand:SI 2 "arm_rhs_operand" "I,l,r"))
2982 (set (match_operand:SI 0 "s_register_operand" "=r,l,r")
2983 (ior:SI (match_dup 1) (match_dup 2)))]
2985 "orrs%?\\t%0, %1, %2"
2986 [(set_attr "conds" "set")
2987 (set_attr "arch" "*,t2,*")
2988 (set_attr "length" "4,2,4")
2989 (set_attr "type" "logics_imm,logics_reg,logics_reg")]
2992 (define_insn "*iorsi3_compare0_scratch"
2993 [(set (reg:CC_NOOV CC_REGNUM)
2995 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r")
2996 (match_operand:SI 2 "arm_rhs_operand" "I,l,r"))
2998 (clobber (match_scratch:SI 0 "=r,l,r"))]
3000 "orrs%?\\t%0, %1, %2"
3001 [(set_attr "conds" "set")
3002 (set_attr "arch" "*,t2,*")
3003 (set_attr "length" "4,2,4")
3004 (set_attr "type" "logics_imm,logics_reg,logics_reg")]
3007 (define_expand "xorsi3"
3008 [(set (match_operand:SI 0 "s_register_operand")
3009 (xor:SI (match_operand:SI 1 "s_register_operand")
3010 (match_operand:SI 2 "reg_or_int_operand")))]
3012 "if (CONST_INT_P (operands[2]))
3016 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3017 operands[2] = force_reg (SImode, operands[2]);
3020 arm_split_constant (XOR, SImode, NULL_RTX,
3021 INTVAL (operands[2]), operands[0],
3023 optimize && can_create_pseudo_p ());
3027 else /* TARGET_THUMB1 */
3029 rtx tmp = force_reg (SImode, operands[2]);
3030 if (rtx_equal_p (operands[0], operands[1]))
3034 operands[2] = operands[1];
3041 (define_insn_and_split "*arm_xorsi3"
3042 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3043 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3044 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3052 && CONST_INT_P (operands[2])
3053 && !const_ok_for_arm (INTVAL (operands[2]))"
3054 [(clobber (const_int 0))]
3056 arm_split_constant (XOR, SImode, curr_insn,
3057 INTVAL (operands[2]), operands[0], operands[1], 0);
3060 [(set_attr "length" "4,4,4,16")
3061 (set_attr "predicable" "yes")
3062 (set_attr "predicable_short_it" "no,yes,no,no")
3063 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3066 (define_insn "*xorsi3_compare0"
3067 [(set (reg:CC_NOOV CC_REGNUM)
3068 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3069 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3071 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3072 (xor:SI (match_dup 1) (match_dup 2)))]
3074 "eors%?\\t%0, %1, %2"
3075 [(set_attr "conds" "set")
3076 (set_attr "type" "logics_imm,logics_reg")]
3079 (define_insn "*xorsi3_compare0_scratch"
3080 [(set (reg:CC_NOOV CC_REGNUM)
3081 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3082 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3086 [(set_attr "conds" "set")
3087 (set_attr "type" "logics_imm,logics_reg")]
3090 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3091 ; (NOT D) we can sometimes merge the final NOT into one of the following
3095 [(set (match_operand:SI 0 "s_register_operand" "")
3096 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3097 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3098 (match_operand:SI 3 "arm_rhs_operand" "")))
3099 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3101 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3102 (not:SI (match_dup 3))))
3103 (set (match_dup 0) (not:SI (match_dup 4)))]
3107 (define_insn_and_split "*andsi_iorsi3_notsi"
3108 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3109 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3110 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3111 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3113 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3114 "&& reload_completed"
3115 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3116 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3118 /* If operands[3] is a constant make sure to fold the NOT into it
3119 to avoid creating a NOT of a CONST_INT. */
3120 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3121 if (CONST_INT_P (not_rtx))
3123 operands[4] = operands[0];
3124 operands[5] = not_rtx;
3128 operands[5] = operands[0];
3129 operands[4] = not_rtx;
3132 [(set_attr "length" "8")
3133 (set_attr "ce_count" "2")
3134 (set_attr "predicable" "yes")
3135 (set_attr "type" "multiple")]
3138 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3139 ; insns are available?
3141 [(set (match_operand:SI 0 "s_register_operand" "")
3142 (match_operator:SI 1 "logical_binary_operator"
3143 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3144 (match_operand:SI 3 "const_int_operand" "")
3145 (match_operand:SI 4 "const_int_operand" ""))
3146 (match_operator:SI 9 "logical_binary_operator"
3147 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3148 (match_operand:SI 6 "const_int_operand" ""))
3149 (match_operand:SI 7 "s_register_operand" "")])]))
3150 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3152 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3153 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3156 [(ashift:SI (match_dup 2) (match_dup 4))
3160 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3163 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3167 [(set (match_operand:SI 0 "s_register_operand" "")
3168 (match_operator:SI 1 "logical_binary_operator"
3169 [(match_operator:SI 9 "logical_binary_operator"
3170 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3171 (match_operand:SI 6 "const_int_operand" ""))
3172 (match_operand:SI 7 "s_register_operand" "")])
3173 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3174 (match_operand:SI 3 "const_int_operand" "")
3175 (match_operand:SI 4 "const_int_operand" ""))]))
3176 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3178 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3179 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3182 [(ashift:SI (match_dup 2) (match_dup 4))
3186 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3189 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3193 [(set (match_operand:SI 0 "s_register_operand" "")
3194 (match_operator:SI 1 "logical_binary_operator"
3195 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3196 (match_operand:SI 3 "const_int_operand" "")
3197 (match_operand:SI 4 "const_int_operand" ""))
3198 (match_operator:SI 9 "logical_binary_operator"
3199 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3200 (match_operand:SI 6 "const_int_operand" ""))
3201 (match_operand:SI 7 "s_register_operand" "")])]))
3202 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3204 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3205 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3208 [(ashift:SI (match_dup 2) (match_dup 4))
3212 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3215 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3219 [(set (match_operand:SI 0 "s_register_operand" "")
3220 (match_operator:SI 1 "logical_binary_operator"
3221 [(match_operator:SI 9 "logical_binary_operator"
3222 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3223 (match_operand:SI 6 "const_int_operand" ""))
3224 (match_operand:SI 7 "s_register_operand" "")])
3225 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3226 (match_operand:SI 3 "const_int_operand" "")
3227 (match_operand:SI 4 "const_int_operand" ""))]))
3228 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3230 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3231 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3234 [(ashift:SI (match_dup 2) (match_dup 4))
3238 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3241 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3245 ;; Minimum and maximum insns
3247 (define_expand "smaxsi3"
3249 (set (match_operand:SI 0 "s_register_operand")
3250 (smax:SI (match_operand:SI 1 "s_register_operand")
3251 (match_operand:SI 2 "arm_rhs_operand")))
3252 (clobber (reg:CC CC_REGNUM))])]
3255 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3257 /* No need for a clobber of the condition code register here. */
3258 emit_insn (gen_rtx_SET (operands[0],
3259 gen_rtx_SMAX (SImode, operands[1],
3265 (define_insn "*smax_0"
3266 [(set (match_operand:SI 0 "s_register_operand" "=r")
3267 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3270 "bic%?\\t%0, %1, %1, asr #31"
3271 [(set_attr "predicable" "yes")
3272 (set_attr "type" "logic_shift_reg")]
3275 (define_insn "*smax_m1"
3276 [(set (match_operand:SI 0 "s_register_operand" "=r")
3277 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3280 "orr%?\\t%0, %1, %1, asr #31"
3281 [(set_attr "predicable" "yes")
3282 (set_attr "type" "logic_shift_reg")]
3285 (define_insn_and_split "*arm_smax_insn"
3286 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3287 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3288 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3289 (clobber (reg:CC CC_REGNUM))]
3292 ; cmp\\t%1, %2\;movlt\\t%0, %2
3293 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3295 [(set (reg:CC CC_REGNUM)
3296 (compare:CC (match_dup 1) (match_dup 2)))
3298 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3302 [(set_attr "conds" "clob")
3303 (set_attr "length" "8,12")
3304 (set_attr "type" "multiple")]
3307 (define_expand "sminsi3"
3309 (set (match_operand:SI 0 "s_register_operand")
3310 (smin:SI (match_operand:SI 1 "s_register_operand")
3311 (match_operand:SI 2 "arm_rhs_operand")))
3312 (clobber (reg:CC CC_REGNUM))])]
3315 if (operands[2] == const0_rtx)
3317 /* No need for a clobber of the condition code register here. */
3318 emit_insn (gen_rtx_SET (operands[0],
3319 gen_rtx_SMIN (SImode, operands[1],
3325 (define_insn "*smin_0"
3326 [(set (match_operand:SI 0 "s_register_operand" "=r")
3327 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3330 "and%?\\t%0, %1, %1, asr #31"
3331 [(set_attr "predicable" "yes")
3332 (set_attr "type" "logic_shift_reg")]
3335 (define_insn_and_split "*arm_smin_insn"
3336 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3337 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3338 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3339 (clobber (reg:CC CC_REGNUM))]
3342 ; cmp\\t%1, %2\;movge\\t%0, %2
3343 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3345 [(set (reg:CC CC_REGNUM)
3346 (compare:CC (match_dup 1) (match_dup 2)))
3348 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3352 [(set_attr "conds" "clob")
3353 (set_attr "length" "8,12")
3354 (set_attr "type" "multiple,multiple")]
3357 (define_expand "umaxsi3"
3359 (set (match_operand:SI 0 "s_register_operand")
3360 (umax:SI (match_operand:SI 1 "s_register_operand")
3361 (match_operand:SI 2 "arm_rhs_operand")))
3362 (clobber (reg:CC CC_REGNUM))])]
3367 (define_insn_and_split "*arm_umaxsi3"
3368 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3369 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3370 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3371 (clobber (reg:CC CC_REGNUM))]
3374 ; cmp\\t%1, %2\;movcc\\t%0, %2
3375 ; cmp\\t%1, %2\;movcs\\t%0, %1
3376 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3378 [(set (reg:CC CC_REGNUM)
3379 (compare:CC (match_dup 1) (match_dup 2)))
3381 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3385 [(set_attr "conds" "clob")
3386 (set_attr "length" "8,8,12")
3387 (set_attr "type" "store_4")]
3390 (define_expand "uminsi3"
3392 (set (match_operand:SI 0 "s_register_operand")
3393 (umin:SI (match_operand:SI 1 "s_register_operand")
3394 (match_operand:SI 2 "arm_rhs_operand")))
3395 (clobber (reg:CC CC_REGNUM))])]
3400 (define_insn_and_split "*arm_uminsi3"
3401 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3402 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3403 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3404 (clobber (reg:CC CC_REGNUM))]
3407 ; cmp\\t%1, %2\;movcs\\t%0, %2
3408 ; cmp\\t%1, %2\;movcc\\t%0, %1
3409 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3411 [(set (reg:CC CC_REGNUM)
3412 (compare:CC (match_dup 1) (match_dup 2)))
3414 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3418 [(set_attr "conds" "clob")
3419 (set_attr "length" "8,8,12")
3420 (set_attr "type" "store_4")]
3423 (define_insn "*store_minmaxsi"
3424 [(set (match_operand:SI 0 "memory_operand" "=m")
3425 (match_operator:SI 3 "minmax_operator"
3426 [(match_operand:SI 1 "s_register_operand" "r")
3427 (match_operand:SI 2 "s_register_operand" "r")]))
3428 (clobber (reg:CC CC_REGNUM))]
3429 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3431 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3432 operands[1], operands[2]);
3433 output_asm_insn (\"cmp\\t%1, %2\", operands);
3435 output_asm_insn (\"ite\t%d3\", operands);
3436 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3437 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3440 [(set_attr "conds" "clob")
3441 (set (attr "length")
3442 (if_then_else (eq_attr "is_thumb" "yes")
3445 (set_attr "type" "store_4")]
3448 ; Reject the frame pointer in operand[1], since reloading this after
3449 ; it has been eliminated can cause carnage.
3450 (define_insn "*minmax_arithsi"
3451 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3452 (match_operator:SI 4 "shiftable_operator"
3453 [(match_operator:SI 5 "minmax_operator"
3454 [(match_operand:SI 2 "s_register_operand" "r,r")
3455 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3456 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3457 (clobber (reg:CC CC_REGNUM))]
3458 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3461 enum rtx_code code = GET_CODE (operands[4]);
3464 if (which_alternative != 0 || operands[3] != const0_rtx
3465 || (code != PLUS && code != IOR && code != XOR))
3470 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3471 operands[2], operands[3]);
3472 output_asm_insn (\"cmp\\t%2, %3\", operands);
3476 output_asm_insn (\"ite\\t%d5\", operands);
3478 output_asm_insn (\"it\\t%d5\", operands);
3480 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3482 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3485 [(set_attr "conds" "clob")
3486 (set (attr "length")
3487 (if_then_else (eq_attr "is_thumb" "yes")
3490 (set_attr "type" "multiple")]
3493 ; Reject the frame pointer in operand[1], since reloading this after
3494 ; it has been eliminated can cause carnage.
3495 (define_insn_and_split "*minmax_arithsi_non_canon"
3496 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3498 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3499 (match_operator:SI 4 "minmax_operator"
3500 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3501 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3502 (clobber (reg:CC CC_REGNUM))]
3503 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3504 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3506 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3507 [(set (reg:CC CC_REGNUM)
3508 (compare:CC (match_dup 2) (match_dup 3)))
3510 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3512 (minus:SI (match_dup 1)
3514 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3518 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3519 operands[2], operands[3]);
3520 enum rtx_code rc = minmax_code (operands[4]);
3521 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3522 operands[2], operands[3]);
3524 if (mode == CCFPmode || mode == CCFPEmode)
3525 rc = reverse_condition_maybe_unordered (rc);
3527 rc = reverse_condition (rc);
3528 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3529 if (CONST_INT_P (operands[3]))
3530 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3532 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3534 [(set_attr "conds" "clob")
3535 (set (attr "length")
3536 (if_then_else (eq_attr "is_thumb" "yes")
3539 (set_attr "type" "multiple")]
3542 (define_code_iterator SAT [smin smax])
3543 (define_code_attr SATrev [(smin "smax") (smax "smin")])
3544 (define_code_attr SATlo [(smin "1") (smax "2")])
3545 (define_code_attr SAThi [(smin "2") (smax "1")])
3547 (define_insn "*satsi_<SAT:code>"
3548 [(set (match_operand:SI 0 "s_register_operand" "=r")
3549 (SAT:SI (<SATrev>:SI (match_operand:SI 3 "s_register_operand" "r")
3550 (match_operand:SI 1 "const_int_operand" "i"))
3551 (match_operand:SI 2 "const_int_operand" "i")))]
3552 "TARGET_32BIT && arm_arch6
3553 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3557 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3558 &mask, &signed_sat))
3561 operands[1] = GEN_INT (mask);
3563 return "ssat%?\t%0, %1, %3";
3565 return "usat%?\t%0, %1, %3";
3567 [(set_attr "predicable" "yes")
3568 (set_attr "type" "alus_imm")]
3571 (define_insn "*satsi_<SAT:code>_shift"
3572 [(set (match_operand:SI 0 "s_register_operand" "=r")
3573 (SAT:SI (<SATrev>:SI (match_operator:SI 3 "sat_shift_operator"
3574 [(match_operand:SI 4 "s_register_operand" "r")
3575 (match_operand:SI 5 "const_int_operand" "i")])
3576 (match_operand:SI 1 "const_int_operand" "i"))
3577 (match_operand:SI 2 "const_int_operand" "i")))]
3578 "TARGET_32BIT && arm_arch6
3579 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3583 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3584 &mask, &signed_sat))
3587 operands[1] = GEN_INT (mask);
3589 return "ssat%?\t%0, %1, %4%S3";
3591 return "usat%?\t%0, %1, %4%S3";
3593 [(set_attr "predicable" "yes")
3594 (set_attr "shift" "3")
3595 (set_attr "type" "logic_shift_reg")])
3597 ;; Shift and rotation insns
3599 (define_expand "ashldi3"
3600 [(set (match_operand:DI 0 "s_register_operand")
3601 (ashift:DI (match_operand:DI 1 "s_register_operand")
3602 (match_operand:SI 2 "reg_or_int_operand")))]
3605 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3606 operands[2], gen_reg_rtx (SImode),
3607 gen_reg_rtx (SImode));
3611 (define_expand "ashlsi3"
3612 [(set (match_operand:SI 0 "s_register_operand")
3613 (ashift:SI (match_operand:SI 1 "s_register_operand")
3614 (match_operand:SI 2 "arm_rhs_operand")))]
3617 if (CONST_INT_P (operands[2])
3618 && (UINTVAL (operands[2])) > 31)
3620 emit_insn (gen_movsi (operands[0], const0_rtx));
3626 (define_expand "ashrdi3"
3627 [(set (match_operand:DI 0 "s_register_operand")
3628 (ashiftrt:DI (match_operand:DI 1 "s_register_operand")
3629 (match_operand:SI 2 "reg_or_int_operand")))]
3632 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3633 operands[2], gen_reg_rtx (SImode),
3634 gen_reg_rtx (SImode));
3638 (define_expand "ashrsi3"
3639 [(set (match_operand:SI 0 "s_register_operand")
3640 (ashiftrt:SI (match_operand:SI 1 "s_register_operand")
3641 (match_operand:SI 2 "arm_rhs_operand")))]
3644 if (CONST_INT_P (operands[2])
3645 && UINTVAL (operands[2]) > 31)
3646 operands[2] = GEN_INT (31);
3650 (define_expand "lshrdi3"
3651 [(set (match_operand:DI 0 "s_register_operand")
3652 (lshiftrt:DI (match_operand:DI 1 "s_register_operand")
3653 (match_operand:SI 2 "reg_or_int_operand")))]
3656 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3657 operands[2], gen_reg_rtx (SImode),
3658 gen_reg_rtx (SImode));
3662 (define_expand "lshrsi3"
3663 [(set (match_operand:SI 0 "s_register_operand")
3664 (lshiftrt:SI (match_operand:SI 1 "s_register_operand")
3665 (match_operand:SI 2 "arm_rhs_operand")))]
3668 if (CONST_INT_P (operands[2])
3669 && (UINTVAL (operands[2])) > 31)
3671 emit_insn (gen_movsi (operands[0], const0_rtx));
3677 (define_expand "rotlsi3"
3678 [(set (match_operand:SI 0 "s_register_operand")
3679 (rotatert:SI (match_operand:SI 1 "s_register_operand")
3680 (match_operand:SI 2 "reg_or_int_operand")))]
3683 if (CONST_INT_P (operands[2]))
3684 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3687 rtx reg = gen_reg_rtx (SImode);
3688 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3694 (define_expand "rotrsi3"
3695 [(set (match_operand:SI 0 "s_register_operand")
3696 (rotatert:SI (match_operand:SI 1 "s_register_operand")
3697 (match_operand:SI 2 "arm_rhs_operand")))]
3702 if (CONST_INT_P (operands[2])
3703 && UINTVAL (operands[2]) > 31)
3704 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3706 else /* TARGET_THUMB1 */
3708 if (CONST_INT_P (operands [2]))
3709 operands [2] = force_reg (SImode, operands[2]);
3714 (define_insn "*arm_shiftsi3"
3715 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
3716 (match_operator:SI 3 "shift_operator"
3717 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
3718 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
3720 "* return arm_output_shift(operands, 0);"
3721 [(set_attr "predicable" "yes")
3722 (set_attr "arch" "t2,t2,*,*")
3723 (set_attr "predicable_short_it" "yes,yes,no,no")
3724 (set_attr "length" "4")
3725 (set_attr "shift" "1")
3726 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
3729 (define_insn "*shiftsi3_compare0"
3730 [(set (reg:CC_NOOV CC_REGNUM)
3731 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3732 [(match_operand:SI 1 "s_register_operand" "r,r")
3733 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3735 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3736 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
3738 "* return arm_output_shift(operands, 1);"
3739 [(set_attr "conds" "set")
3740 (set_attr "shift" "1")
3741 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
3744 (define_insn "*shiftsi3_compare0_scratch"
3745 [(set (reg:CC_NOOV CC_REGNUM)
3746 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3747 [(match_operand:SI 1 "s_register_operand" "r,r")
3748 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3750 (clobber (match_scratch:SI 0 "=r,r"))]
3752 "* return arm_output_shift(operands, 1);"
3753 [(set_attr "conds" "set")
3754 (set_attr "shift" "1")
3755 (set_attr "type" "shift_imm,shift_reg")]
3758 (define_insn "*not_shiftsi"
3759 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3760 (not:SI (match_operator:SI 3 "shift_operator"
3761 [(match_operand:SI 1 "s_register_operand" "r,r")
3762 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3765 [(set_attr "predicable" "yes")
3766 (set_attr "shift" "1")
3767 (set_attr "arch" "32,a")
3768 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3770 (define_insn "*not_shiftsi_compare0"
3771 [(set (reg:CC_NOOV CC_REGNUM)
3773 (not:SI (match_operator:SI 3 "shift_operator"
3774 [(match_operand:SI 1 "s_register_operand" "r,r")
3775 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3777 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3778 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
3780 "mvns%?\\t%0, %1%S3"
3781 [(set_attr "conds" "set")
3782 (set_attr "shift" "1")
3783 (set_attr "arch" "32,a")
3784 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3786 (define_insn "*not_shiftsi_compare0_scratch"
3787 [(set (reg:CC_NOOV CC_REGNUM)
3789 (not:SI (match_operator:SI 3 "shift_operator"
3790 [(match_operand:SI 1 "s_register_operand" "r,r")
3791 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3793 (clobber (match_scratch:SI 0 "=r,r"))]
3795 "mvns%?\\t%0, %1%S3"
3796 [(set_attr "conds" "set")
3797 (set_attr "shift" "1")
3798 (set_attr "arch" "32,a")
3799 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3801 ;; We don't really have extzv, but defining this using shifts helps
3802 ;; to reduce register pressure later on.
3804 (define_expand "extzv"
3805 [(set (match_operand 0 "s_register_operand")
3806 (zero_extract (match_operand 1 "nonimmediate_operand")
3807 (match_operand 2 "const_int_operand")
3808 (match_operand 3 "const_int_operand")))]
3809 "TARGET_THUMB1 || arm_arch_thumb2"
3812 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3813 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3815 if (arm_arch_thumb2)
3817 HOST_WIDE_INT width = INTVAL (operands[2]);
3818 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3820 if (unaligned_access && MEM_P (operands[1])
3821 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
3825 if (BYTES_BIG_ENDIAN)
3826 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
3831 base_addr = adjust_address (operands[1], SImode,
3832 bitpos / BITS_PER_UNIT);
3833 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
3837 rtx dest = operands[0];
3838 rtx tmp = gen_reg_rtx (SImode);
3840 /* We may get a paradoxical subreg here. Strip it off. */
3841 if (GET_CODE (dest) == SUBREG
3842 && GET_MODE (dest) == SImode
3843 && GET_MODE (SUBREG_REG (dest)) == HImode)
3844 dest = SUBREG_REG (dest);
3846 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
3849 base_addr = adjust_address (operands[1], HImode,
3850 bitpos / BITS_PER_UNIT);
3851 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
3852 emit_move_insn (gen_lowpart (SImode, dest), tmp);
3856 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
3858 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
3866 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
3869 operands[3] = GEN_INT (rshift);
3873 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
3877 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
3878 operands[3], gen_reg_rtx (SImode)));
3883 ;; Helper for extzv, for the Thumb-1 register-shifts case.
3885 (define_expand "extzv_t1"
3886 [(set (match_operand:SI 4 "s_register_operand")
3887 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
3888 (match_operand:SI 2 "const_int_operand")))
3889 (set (match_operand:SI 0 "s_register_operand")
3890 (lshiftrt:SI (match_dup 4)
3891 (match_operand:SI 3 "const_int_operand")))]
3895 (define_expand "extv"
3896 [(set (match_operand 0 "s_register_operand")
3897 (sign_extract (match_operand 1 "nonimmediate_operand")
3898 (match_operand 2 "const_int_operand")
3899 (match_operand 3 "const_int_operand")))]
3902 HOST_WIDE_INT width = INTVAL (operands[2]);
3903 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3905 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
3906 && (bitpos % BITS_PER_UNIT) == 0)
3910 if (BYTES_BIG_ENDIAN)
3911 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
3915 base_addr = adjust_address (operands[1], SImode,
3916 bitpos / BITS_PER_UNIT);
3917 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
3921 rtx dest = operands[0];
3922 rtx tmp = gen_reg_rtx (SImode);
3924 /* We may get a paradoxical subreg here. Strip it off. */
3925 if (GET_CODE (dest) == SUBREG
3926 && GET_MODE (dest) == SImode
3927 && GET_MODE (SUBREG_REG (dest)) == HImode)
3928 dest = SUBREG_REG (dest);
3930 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
3933 base_addr = adjust_address (operands[1], HImode,
3934 bitpos / BITS_PER_UNIT);
3935 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
3936 emit_move_insn (gen_lowpart (SImode, dest), tmp);
3941 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
3943 else if (GET_MODE (operands[0]) == SImode
3944 && GET_MODE (operands[1]) == SImode)
3946 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
3954 ; Helper to expand register forms of extv with the proper modes.
3956 (define_expand "extv_regsi"
3957 [(set (match_operand:SI 0 "s_register_operand")
3958 (sign_extract:SI (match_operand:SI 1 "s_register_operand")
3959 (match_operand 2 "const_int_operand")
3960 (match_operand 3 "const_int_operand")))]
3965 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
3967 (define_insn "unaligned_loaddi"
3968 [(set (match_operand:DI 0 "s_register_operand" "=r")
3969 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")]
3970 UNSPEC_UNALIGNED_LOAD))]
3971 "TARGET_32BIT && TARGET_LDRD"
3973 return output_move_double (operands, true, NULL);
3975 [(set_attr "length" "8")
3976 (set_attr "type" "load_8")])
3978 (define_insn "unaligned_loadsi"
3979 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
3980 (unspec:SI [(match_operand:SI 1 "memory_operand" "m,Uw,m")]
3981 UNSPEC_UNALIGNED_LOAD))]
3984 ldr\t%0, %1\t@ unaligned
3985 ldr%?\t%0, %1\t@ unaligned
3986 ldr%?\t%0, %1\t@ unaligned"
3987 [(set_attr "arch" "t1,t2,32")
3988 (set_attr "length" "2,2,4")
3989 (set_attr "predicable" "no,yes,yes")
3990 (set_attr "predicable_short_it" "no,yes,no")
3991 (set_attr "type" "load_4")])
3993 ;; The 16-bit Thumb1 variant of ldrsh requires two registers in the
3994 ;; address (there's no immediate format). That's tricky to support
3995 ;; here and we don't really need this pattern for that case, so only
3996 ;; enable for 32-bit ISAs.
3997 (define_insn "unaligned_loadhis"
3998 [(set (match_operand:SI 0 "s_register_operand" "=r")
4000 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
4001 UNSPEC_UNALIGNED_LOAD)))]
4002 "unaligned_access && TARGET_32BIT"
4003 "ldrsh%?\t%0, %1\t@ unaligned"
4004 [(set_attr "predicable" "yes")
4005 (set_attr "type" "load_byte")])
4007 (define_insn "unaligned_loadhiu"
4008 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
4010 (unspec:HI [(match_operand:HI 1 "memory_operand" "m,Uw,m")]
4011 UNSPEC_UNALIGNED_LOAD)))]
4014 ldrh\t%0, %1\t@ unaligned
4015 ldrh%?\t%0, %1\t@ unaligned
4016 ldrh%?\t%0, %1\t@ unaligned"
4017 [(set_attr "arch" "t1,t2,32")
4018 (set_attr "length" "2,2,4")
4019 (set_attr "predicable" "no,yes,yes")
4020 (set_attr "predicable_short_it" "no,yes,no")
4021 (set_attr "type" "load_byte")])
4023 (define_insn "unaligned_storedi"
4024 [(set (match_operand:DI 0 "memory_operand" "=m")
4025 (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")]
4026 UNSPEC_UNALIGNED_STORE))]
4027 "TARGET_32BIT && TARGET_LDRD"
4029 return output_move_double (operands, true, NULL);
4031 [(set_attr "length" "8")
4032 (set_attr "type" "store_8")])
4034 (define_insn "unaligned_storesi"
4035 [(set (match_operand:SI 0 "memory_operand" "=m,Uw,m")
4036 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,l,r")]
4037 UNSPEC_UNALIGNED_STORE))]
4040 str\t%1, %0\t@ unaligned
4041 str%?\t%1, %0\t@ unaligned
4042 str%?\t%1, %0\t@ unaligned"
4043 [(set_attr "arch" "t1,t2,32")
4044 (set_attr "length" "2,2,4")
4045 (set_attr "predicable" "no,yes,yes")
4046 (set_attr "predicable_short_it" "no,yes,no")
4047 (set_attr "type" "store_4")])
4049 (define_insn "unaligned_storehi"
4050 [(set (match_operand:HI 0 "memory_operand" "=m,Uw,m")
4051 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,l,r")]
4052 UNSPEC_UNALIGNED_STORE))]
4055 strh\t%1, %0\t@ unaligned
4056 strh%?\t%1, %0\t@ unaligned
4057 strh%?\t%1, %0\t@ unaligned"
4058 [(set_attr "arch" "t1,t2,32")
4059 (set_attr "length" "2,2,4")
4060 (set_attr "predicable" "no,yes,yes")
4061 (set_attr "predicable_short_it" "no,yes,no")
4062 (set_attr "type" "store_4")])
4065 (define_insn "*extv_reg"
4066 [(set (match_operand:SI 0 "s_register_operand" "=r")
4067 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4068 (match_operand:SI 2 "const_int_operand" "n")
4069 (match_operand:SI 3 "const_int_operand" "n")))]
4071 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4072 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4073 "sbfx%?\t%0, %1, %3, %2"
4074 [(set_attr "length" "4")
4075 (set_attr "predicable" "yes")
4076 (set_attr "type" "bfm")]
4079 (define_insn "extzv_t2"
4080 [(set (match_operand:SI 0 "s_register_operand" "=r")
4081 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4082 (match_operand:SI 2 "const_int_operand" "n")
4083 (match_operand:SI 3 "const_int_operand" "n")))]
4085 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4086 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4087 "ubfx%?\t%0, %1, %3, %2"
4088 [(set_attr "length" "4")
4089 (set_attr "predicable" "yes")
4090 (set_attr "type" "bfm")]
4094 ;; Division instructions
4095 (define_insn "divsi3"
4096 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4097 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4098 (match_operand:SI 2 "s_register_operand" "r,r")))]
4103 [(set_attr "arch" "32,v8mb")
4104 (set_attr "predicable" "yes")
4105 (set_attr "type" "sdiv")]
4108 (define_insn "udivsi3"
4109 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4110 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4111 (match_operand:SI 2 "s_register_operand" "r,r")))]
4116 [(set_attr "arch" "32,v8mb")
4117 (set_attr "predicable" "yes")
4118 (set_attr "type" "udiv")]
4122 ;; Unary arithmetic insns
4124 (define_expand "negvsi3"
4125 [(match_operand:SI 0 "register_operand")
4126 (match_operand:SI 1 "register_operand")
4127 (match_operand 2 "")]
4130 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4131 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4136 (define_expand "negvdi3"
4137 [(match_operand:DI 0 "register_operand")
4138 (match_operand:DI 1 "register_operand")
4139 (match_operand 2 "")]
4142 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4143 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4149 (define_insn_and_split "negdi2_compare"
4150 [(set (reg:CC CC_REGNUM)
4153 (match_operand:DI 1 "register_operand" "0,r")))
4154 (set (match_operand:DI 0 "register_operand" "=r,&r")
4155 (minus:DI (const_int 0) (match_dup 1)))]
4158 "&& reload_completed"
4159 [(parallel [(set (reg:CC CC_REGNUM)
4160 (compare:CC (const_int 0) (match_dup 1)))
4161 (set (match_dup 0) (minus:SI (const_int 0)
4163 (parallel [(set (reg:CC CC_REGNUM)
4164 (compare:CC (const_int 0) (match_dup 3)))
4167 (minus:SI (const_int 0) (match_dup 3))
4168 (ltu:SI (reg:CC CC_REGNUM)
4171 operands[2] = gen_highpart (SImode, operands[0]);
4172 operands[0] = gen_lowpart (SImode, operands[0]);
4173 operands[3] = gen_highpart (SImode, operands[1]);
4174 operands[1] = gen_lowpart (SImode, operands[1]);
4176 [(set_attr "conds" "set")
4177 (set_attr "length" "8")
4178 (set_attr "type" "multiple")]
4181 (define_expand "negdi2"
4183 [(set (match_operand:DI 0 "s_register_operand")
4184 (neg:DI (match_operand:DI 1 "s_register_operand")))
4185 (clobber (reg:CC CC_REGNUM))])]
4189 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4190 ;; The first alternative allows the common case of a *full* overlap.
4191 (define_insn_and_split "*negdi2_insn"
4192 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4193 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4194 (clobber (reg:CC CC_REGNUM))]
4196 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4197 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4199 [(parallel [(set (reg:CC CC_REGNUM)
4200 (compare:CC (const_int 0) (match_dup 1)))
4201 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4202 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4203 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
4205 operands[2] = gen_highpart (SImode, operands[0]);
4206 operands[0] = gen_lowpart (SImode, operands[0]);
4207 operands[3] = gen_highpart (SImode, operands[1]);
4208 operands[1] = gen_lowpart (SImode, operands[1]);
4210 [(set_attr "conds" "clob")
4211 (set_attr "length" "8")
4212 (set_attr "type" "multiple")]
4215 (define_insn "*negsi2_carryin_compare"
4216 [(set (reg:CC CC_REGNUM)
4217 (compare:CC (const_int 0)
4218 (match_operand:SI 1 "s_register_operand" "r")))
4219 (set (match_operand:SI 0 "s_register_operand" "=r")
4220 (minus:SI (minus:SI (const_int 0)
4222 (match_operand:SI 2 "arm_borrow_operation" "")))]
4225 [(set_attr "conds" "set")
4226 (set_attr "type" "alus_imm")]
4229 (define_expand "negsi2"
4230 [(set (match_operand:SI 0 "s_register_operand")
4231 (neg:SI (match_operand:SI 1 "s_register_operand")))]
4236 (define_insn "*arm_negsi2"
4237 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4238 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4240 "rsb%?\\t%0, %1, #0"
4241 [(set_attr "predicable" "yes")
4242 (set_attr "predicable_short_it" "yes,no")
4243 (set_attr "arch" "t2,*")
4244 (set_attr "length" "4")
4245 (set_attr "type" "alu_sreg")]
4248 (define_expand "negsf2"
4249 [(set (match_operand:SF 0 "s_register_operand")
4250 (neg:SF (match_operand:SF 1 "s_register_operand")))]
4251 "TARGET_32BIT && TARGET_HARD_FLOAT"
4255 (define_expand "negdf2"
4256 [(set (match_operand:DF 0 "s_register_operand")
4257 (neg:DF (match_operand:DF 1 "s_register_operand")))]
4258 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4261 (define_insn_and_split "*zextendsidi_negsi"
4262 [(set (match_operand:DI 0 "s_register_operand" "=r")
4263 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4268 (neg:SI (match_dup 1)))
4272 operands[2] = gen_lowpart (SImode, operands[0]);
4273 operands[3] = gen_highpart (SImode, operands[0]);
4275 [(set_attr "length" "8")
4276 (set_attr "type" "multiple")]
4279 ;; Negate an extended 32-bit value.
4280 (define_insn_and_split "*negdi_extendsidi"
4281 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4282 (neg:DI (sign_extend:DI
4283 (match_operand:SI 1 "s_register_operand" "l,r"))))
4284 (clobber (reg:CC CC_REGNUM))]
4287 "&& reload_completed"
4290 rtx low = gen_lowpart (SImode, operands[0]);
4291 rtx high = gen_highpart (SImode, operands[0]);
4293 if (reg_overlap_mentioned_p (low, operands[1]))
4295 /* Input overlaps the low word of the output. Use:
4298 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4299 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
4301 emit_insn (gen_rtx_SET (high,
4302 gen_rtx_ASHIFTRT (SImode, operands[1],
4305 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4307 emit_insn (gen_rtx_SET (high,
4308 gen_rtx_MINUS (SImode,
4309 gen_rtx_MINUS (SImode,
4312 gen_rtx_LTU (SImode,
4317 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4318 emit_insn (gen_rtx_SET (high,
4319 gen_rtx_MINUS (SImode,
4320 gen_rtx_MINUS (SImode,
4323 gen_rtx_LTU (SImode,
4330 /* No overlap, or overlap on high word. Use:
4334 Flags not needed for this sequence. */
4335 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4336 emit_insn (gen_rtx_SET (high,
4337 gen_rtx_AND (SImode,
4338 gen_rtx_NOT (SImode, operands[1]),
4340 emit_insn (gen_rtx_SET (high,
4341 gen_rtx_ASHIFTRT (SImode, high,
4346 [(set_attr "length" "12")
4347 (set_attr "arch" "t2,*")
4348 (set_attr "type" "multiple")]
4351 (define_insn_and_split "*negdi_zero_extendsidi"
4352 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4353 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4354 (clobber (reg:CC CC_REGNUM))]
4356 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4357 ;; Don't care what register is input to sbc,
4358 ;; since we just need to propagate the carry.
4359 "&& reload_completed"
4360 [(parallel [(set (reg:CC CC_REGNUM)
4361 (compare:CC (const_int 0) (match_dup 1)))
4362 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4363 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4364 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
4366 operands[2] = gen_highpart (SImode, operands[0]);
4367 operands[0] = gen_lowpart (SImode, operands[0]);
4369 [(set_attr "conds" "clob")
4370 (set_attr "length" "8")
4371 (set_attr "type" "multiple")] ;; length in thumb is 4
4374 ;; abssi2 doesn't really clobber the condition codes if a different register
4375 ;; is being set. To keep things simple, assume during rtl manipulations that
4376 ;; it does, but tell the final scan operator the truth. Similarly for
4379 (define_expand "abssi2"
4381 [(set (match_operand:SI 0 "s_register_operand")
4382 (abs:SI (match_operand:SI 1 "s_register_operand")))
4383 (clobber (match_dup 2))])]
4387 operands[2] = gen_rtx_SCRATCH (SImode);
4389 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4392 (define_insn_and_split "*arm_abssi2"
4393 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4394 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4395 (clobber (reg:CC CC_REGNUM))]
4398 "&& reload_completed"
4401 /* if (which_alternative == 0) */
4402 if (REGNO(operands[0]) == REGNO(operands[1]))
4404 /* Emit the pattern:
4405 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4406 [(set (reg:CC CC_REGNUM)
4407 (compare:CC (match_dup 0) (const_int 0)))
4408 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4409 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4411 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4412 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4413 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4414 (gen_rtx_LT (SImode,
4415 gen_rtx_REG (CCmode, CC_REGNUM),
4417 (gen_rtx_SET (operands[0],
4418 (gen_rtx_MINUS (SImode,
4425 /* Emit the pattern:
4426 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4428 (xor:SI (match_dup 1)
4429 (ashiftrt:SI (match_dup 1) (const_int 31))))
4431 (minus:SI (match_dup 0)
4432 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4434 emit_insn (gen_rtx_SET (operands[0],
4435 gen_rtx_XOR (SImode,
4436 gen_rtx_ASHIFTRT (SImode,
4440 emit_insn (gen_rtx_SET (operands[0],
4441 gen_rtx_MINUS (SImode,
4443 gen_rtx_ASHIFTRT (SImode,
4449 [(set_attr "conds" "clob,*")
4450 (set_attr "shift" "1")
4451 (set_attr "predicable" "no, yes")
4452 (set_attr "length" "8")
4453 (set_attr "type" "multiple")]
4456 (define_insn_and_split "*arm_neg_abssi2"
4457 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4458 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4459 (clobber (reg:CC CC_REGNUM))]
4462 "&& reload_completed"
4465 /* if (which_alternative == 0) */
4466 if (REGNO (operands[0]) == REGNO (operands[1]))
4468 /* Emit the pattern:
4469 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4471 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4472 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4473 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4475 gen_rtx_REG (CCmode, CC_REGNUM),
4477 gen_rtx_SET (operands[0],
4478 (gen_rtx_MINUS (SImode,
4484 /* Emit the pattern:
4485 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4487 emit_insn (gen_rtx_SET (operands[0],
4488 gen_rtx_XOR (SImode,
4489 gen_rtx_ASHIFTRT (SImode,
4493 emit_insn (gen_rtx_SET (operands[0],
4494 gen_rtx_MINUS (SImode,
4495 gen_rtx_ASHIFTRT (SImode,
4502 [(set_attr "conds" "clob,*")
4503 (set_attr "shift" "1")
4504 (set_attr "predicable" "no, yes")
4505 (set_attr "length" "8")
4506 (set_attr "type" "multiple")]
4509 (define_expand "abssf2"
4510 [(set (match_operand:SF 0 "s_register_operand")
4511 (abs:SF (match_operand:SF 1 "s_register_operand")))]
4512 "TARGET_32BIT && TARGET_HARD_FLOAT"
4515 (define_expand "absdf2"
4516 [(set (match_operand:DF 0 "s_register_operand")
4517 (abs:DF (match_operand:DF 1 "s_register_operand")))]
4518 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4521 (define_expand "sqrtsf2"
4522 [(set (match_operand:SF 0 "s_register_operand")
4523 (sqrt:SF (match_operand:SF 1 "s_register_operand")))]
4524 "TARGET_32BIT && TARGET_HARD_FLOAT"
4527 (define_expand "sqrtdf2"
4528 [(set (match_operand:DF 0 "s_register_operand")
4529 (sqrt:DF (match_operand:DF 1 "s_register_operand")))]
4530 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4533 (define_expand "one_cmplsi2"
4534 [(set (match_operand:SI 0 "s_register_operand")
4535 (not:SI (match_operand:SI 1 "s_register_operand")))]
4540 (define_insn "*arm_one_cmplsi2"
4541 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4542 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4545 [(set_attr "predicable" "yes")
4546 (set_attr "predicable_short_it" "yes,no")
4547 (set_attr "arch" "t2,*")
4548 (set_attr "length" "4")
4549 (set_attr "type" "mvn_reg")]
4552 (define_insn "*notsi_compare0"
4553 [(set (reg:CC_NOOV CC_REGNUM)
4554 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4556 (set (match_operand:SI 0 "s_register_operand" "=r")
4557 (not:SI (match_dup 1)))]
4560 [(set_attr "conds" "set")
4561 (set_attr "type" "mvn_reg")]
4564 (define_insn "*notsi_compare0_scratch"
4565 [(set (reg:CC_NOOV CC_REGNUM)
4566 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4568 (clobber (match_scratch:SI 0 "=r"))]
4571 [(set_attr "conds" "set")
4572 (set_attr "type" "mvn_reg")]
4575 ;; Fixed <--> Floating conversion insns
4577 (define_expand "floatsihf2"
4578 [(set (match_operand:HF 0 "general_operand")
4579 (float:HF (match_operand:SI 1 "general_operand")))]
4583 rtx op1 = gen_reg_rtx (SFmode);
4584 expand_float (op1, operands[1], 0);
4585 op1 = convert_to_mode (HFmode, op1, 0);
4586 emit_move_insn (operands[0], op1);
4591 (define_expand "floatdihf2"
4592 [(set (match_operand:HF 0 "general_operand")
4593 (float:HF (match_operand:DI 1 "general_operand")))]
4597 rtx op1 = gen_reg_rtx (SFmode);
4598 expand_float (op1, operands[1], 0);
4599 op1 = convert_to_mode (HFmode, op1, 0);
4600 emit_move_insn (operands[0], op1);
4605 (define_expand "floatsisf2"
4606 [(set (match_operand:SF 0 "s_register_operand")
4607 (float:SF (match_operand:SI 1 "s_register_operand")))]
4608 "TARGET_32BIT && TARGET_HARD_FLOAT"
4612 (define_expand "floatsidf2"
4613 [(set (match_operand:DF 0 "s_register_operand")
4614 (float:DF (match_operand:SI 1 "s_register_operand")))]
4615 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4619 (define_expand "fix_trunchfsi2"
4620 [(set (match_operand:SI 0 "general_operand")
4621 (fix:SI (fix:HF (match_operand:HF 1 "general_operand"))))]
4625 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4626 expand_fix (operands[0], op1, 0);
4631 (define_expand "fix_trunchfdi2"
4632 [(set (match_operand:DI 0 "general_operand")
4633 (fix:DI (fix:HF (match_operand:HF 1 "general_operand"))))]
4637 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4638 expand_fix (operands[0], op1, 0);
4643 (define_expand "fix_truncsfsi2"
4644 [(set (match_operand:SI 0 "s_register_operand")
4645 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"))))]
4646 "TARGET_32BIT && TARGET_HARD_FLOAT"
4650 (define_expand "fix_truncdfsi2"
4651 [(set (match_operand:SI 0 "s_register_operand")
4652 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"))))]
4653 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4659 (define_expand "truncdfsf2"
4660 [(set (match_operand:SF 0 "s_register_operand")
4662 (match_operand:DF 1 "s_register_operand")))]
4663 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4667 ;; DFmode to HFmode conversions on targets without a single-step hardware
4668 ;; instruction for it would have to go through SFmode. This is dangerous
4669 ;; as it introduces double rounding.
4671 ;; Disable this pattern unless we are in an unsafe math mode, or we have
4672 ;; a single-step instruction.
4674 (define_expand "truncdfhf2"
4675 [(set (match_operand:HF 0 "s_register_operand")
4677 (match_operand:DF 1 "s_register_operand")))]
4678 "(TARGET_EITHER && flag_unsafe_math_optimizations)
4679 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
4681 /* We don't have a direct instruction for this, so we must be in
4682 an unsafe math mode, and going via SFmode. */
4684 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
4687 op1 = convert_to_mode (SFmode, operands[1], 0);
4688 op1 = convert_to_mode (HFmode, op1, 0);
4689 emit_move_insn (operands[0], op1);
4692 /* Otherwise, we will pick this up as a single instruction with
4693 no intermediary rounding. */
4697 ;; Zero and sign extension instructions.
4699 (define_insn "zero_extend<mode>di2"
4700 [(set (match_operand:DI 0 "s_register_operand" "=r,?r")
4701 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4702 "<qhs_zextenddi_cstr>")))]
4703 "TARGET_32BIT <qhs_zextenddi_cond>"
4705 [(set_attr "length" "4,8")
4706 (set_attr "arch" "*,*")
4707 (set_attr "ce_count" "2")
4708 (set_attr "predicable" "yes")
4709 (set_attr "type" "mov_reg,multiple")]
4712 (define_insn "extend<mode>di2"
4713 [(set (match_operand:DI 0 "s_register_operand" "=r,?r,?r")
4714 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4715 "<qhs_extenddi_cstr>")))]
4716 "TARGET_32BIT <qhs_sextenddi_cond>"
4718 [(set_attr "length" "4,8,8")
4719 (set_attr "ce_count" "2")
4720 (set_attr "shift" "1")
4721 (set_attr "predicable" "yes")
4722 (set_attr "arch" "*,a,t")
4723 (set_attr "type" "mov_reg,multiple,multiple")]
4726 ;; Splits for all extensions to DImode
4728 [(set (match_operand:DI 0 "s_register_operand" "")
4729 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4731 [(set (match_dup 0) (match_dup 1))]
4733 rtx lo_part = gen_lowpart (SImode, operands[0]);
4734 machine_mode src_mode = GET_MODE (operands[1]);
4736 if (src_mode == SImode)
4737 emit_move_insn (lo_part, operands[1]);
4739 emit_insn (gen_rtx_SET (lo_part,
4740 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4741 operands[0] = gen_highpart (SImode, operands[0]);
4742 operands[1] = const0_rtx;
4746 [(set (match_operand:DI 0 "s_register_operand" "")
4747 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4749 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4751 rtx lo_part = gen_lowpart (SImode, operands[0]);
4752 machine_mode src_mode = GET_MODE (operands[1]);
4754 if (src_mode == SImode)
4755 emit_move_insn (lo_part, operands[1]);
4757 emit_insn (gen_rtx_SET (lo_part,
4758 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4759 operands[1] = lo_part;
4760 operands[0] = gen_highpart (SImode, operands[0]);
4763 (define_expand "zero_extendhisi2"
4764 [(set (match_operand:SI 0 "s_register_operand")
4765 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
4768 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4770 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4773 if (!arm_arch6 && !MEM_P (operands[1]))
4775 rtx t = gen_lowpart (SImode, operands[1]);
4776 rtx tmp = gen_reg_rtx (SImode);
4777 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4778 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4784 [(set (match_operand:SI 0 "s_register_operand" "")
4785 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4786 "!TARGET_THUMB2 && !arm_arch6"
4787 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4788 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4790 operands[2] = gen_lowpart (SImode, operands[1]);
4793 (define_insn "*arm_zero_extendhisi2"
4794 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4795 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4796 "TARGET_ARM && arm_arch4 && !arm_arch6"
4800 [(set_attr "type" "alu_shift_reg,load_byte")
4801 (set_attr "predicable" "yes")]
4804 (define_insn "*arm_zero_extendhisi2_v6"
4805 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4806 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4807 "TARGET_ARM && arm_arch6"
4811 [(set_attr "predicable" "yes")
4812 (set_attr "type" "extend,load_byte")]
4815 (define_insn "*arm_zero_extendhisi2addsi"
4816 [(set (match_operand:SI 0 "s_register_operand" "=r")
4817 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4818 (match_operand:SI 2 "s_register_operand" "r")))]
4820 "uxtah%?\\t%0, %2, %1"
4821 [(set_attr "type" "alu_shift_reg")
4822 (set_attr "predicable" "yes")]
4825 (define_expand "zero_extendqisi2"
4826 [(set (match_operand:SI 0 "s_register_operand")
4827 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
4830 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
4832 emit_insn (gen_andsi3 (operands[0],
4833 gen_lowpart (SImode, operands[1]),
4837 if (!arm_arch6 && !MEM_P (operands[1]))
4839 rtx t = gen_lowpart (SImode, operands[1]);
4840 rtx tmp = gen_reg_rtx (SImode);
4841 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
4842 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
4848 [(set (match_operand:SI 0 "s_register_operand" "")
4849 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
4851 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4852 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
4854 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
4857 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
4862 (define_insn "*arm_zero_extendqisi2"
4863 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4864 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
4865 "TARGET_ARM && !arm_arch6"
4868 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
4869 [(set_attr "length" "8,4")
4870 (set_attr "type" "alu_shift_reg,load_byte")
4871 (set_attr "predicable" "yes")]
4874 (define_insn "*arm_zero_extendqisi2_v6"
4875 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4876 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
4877 "TARGET_ARM && arm_arch6"
4880 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
4881 [(set_attr "type" "extend,load_byte")
4882 (set_attr "predicable" "yes")]
4885 (define_insn "*arm_zero_extendqisi2addsi"
4886 [(set (match_operand:SI 0 "s_register_operand" "=r")
4887 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
4888 (match_operand:SI 2 "s_register_operand" "r")))]
4890 "uxtab%?\\t%0, %2, %1"
4891 [(set_attr "predicable" "yes")
4892 (set_attr "type" "alu_shift_reg")]
4896 [(set (match_operand:SI 0 "s_register_operand" "")
4897 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
4898 (clobber (match_operand:SI 2 "s_register_operand" ""))]
4899 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
4900 [(set (match_dup 2) (match_dup 1))
4901 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
4906 [(set (match_operand:SI 0 "s_register_operand" "")
4907 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
4908 (clobber (match_operand:SI 2 "s_register_operand" ""))]
4909 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
4910 [(set (match_dup 2) (match_dup 1))
4911 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
4917 [(set (match_operand:SI 0 "s_register_operand" "")
4918 (IOR_XOR:SI (and:SI (ashift:SI
4919 (match_operand:SI 1 "s_register_operand" "")
4920 (match_operand:SI 2 "const_int_operand" ""))
4921 (match_operand:SI 3 "const_int_operand" ""))
4923 (match_operator 5 "subreg_lowpart_operator"
4924 [(match_operand:SI 4 "s_register_operand" "")]))))]
4926 && (UINTVAL (operands[3])
4927 == (GET_MODE_MASK (GET_MODE (operands[5]))
4928 & (GET_MODE_MASK (GET_MODE (operands[5]))
4929 << (INTVAL (operands[2])))))"
4930 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
4932 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
4933 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
4936 (define_insn "*compareqi_eq0"
4937 [(set (reg:CC_Z CC_REGNUM)
4938 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
4942 [(set_attr "conds" "set")
4943 (set_attr "predicable" "yes")
4944 (set_attr "type" "logic_imm")]
4947 (define_expand "extendhisi2"
4948 [(set (match_operand:SI 0 "s_register_operand")
4949 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
4954 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
4957 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
4959 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
4963 if (!arm_arch6 && !MEM_P (operands[1]))
4965 rtx t = gen_lowpart (SImode, operands[1]);
4966 rtx tmp = gen_reg_rtx (SImode);
4967 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4968 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
4975 [(set (match_operand:SI 0 "register_operand" "")
4976 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
4977 (clobber (match_scratch:SI 2 ""))])]
4979 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4980 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4982 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
4985 ;; This pattern will only be used when ldsh is not available
4986 (define_expand "extendhisi2_mem"
4987 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
4989 (zero_extend:SI (match_dup 7)))
4990 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
4991 (set (match_operand:SI 0 "" "")
4992 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
4997 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
4999 mem1 = change_address (operands[1], QImode, addr);
5000 mem2 = change_address (operands[1], QImode,
5001 plus_constant (Pmode, addr, 1));
5002 operands[0] = gen_lowpart (SImode, operands[0]);
5004 operands[2] = gen_reg_rtx (SImode);
5005 operands[3] = gen_reg_rtx (SImode);
5006 operands[6] = gen_reg_rtx (SImode);
5009 if (BYTES_BIG_ENDIAN)
5011 operands[4] = operands[2];
5012 operands[5] = operands[3];
5016 operands[4] = operands[3];
5017 operands[5] = operands[2];
5023 [(set (match_operand:SI 0 "register_operand" "")
5024 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5026 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5027 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5029 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5032 (define_insn "*arm_extendhisi2"
5033 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5034 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5035 "TARGET_ARM && arm_arch4 && !arm_arch6"
5039 [(set_attr "length" "8,4")
5040 (set_attr "type" "alu_shift_reg,load_byte")
5041 (set_attr "predicable" "yes")]
5044 ;; ??? Check Thumb-2 pool range
5045 (define_insn "*arm_extendhisi2_v6"
5046 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5047 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5048 "TARGET_32BIT && arm_arch6"
5052 [(set_attr "type" "extend,load_byte")
5053 (set_attr "predicable" "yes")]
5056 (define_insn "*arm_extendhisi2addsi"
5057 [(set (match_operand:SI 0 "s_register_operand" "=r")
5058 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5059 (match_operand:SI 2 "s_register_operand" "r")))]
5061 "sxtah%?\\t%0, %2, %1"
5062 [(set_attr "type" "alu_shift_reg")]
5065 (define_expand "extendqihi2"
5067 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op")
5069 (set (match_operand:HI 0 "s_register_operand")
5070 (ashiftrt:SI (match_dup 2)
5075 if (arm_arch4 && MEM_P (operands[1]))
5077 emit_insn (gen_rtx_SET (operands[0],
5078 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5081 if (!s_register_operand (operands[1], QImode))
5082 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5083 operands[0] = gen_lowpart (SImode, operands[0]);
5084 operands[1] = gen_lowpart (SImode, operands[1]);
5085 operands[2] = gen_reg_rtx (SImode);
5089 (define_insn "*arm_extendqihi_insn"
5090 [(set (match_operand:HI 0 "s_register_operand" "=r")
5091 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5092 "TARGET_ARM && arm_arch4"
5094 [(set_attr "type" "load_byte")
5095 (set_attr "predicable" "yes")]
5098 (define_expand "extendqisi2"
5099 [(set (match_operand:SI 0 "s_register_operand")
5100 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op")))]
5103 if (!arm_arch4 && MEM_P (operands[1]))
5104 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5106 if (!arm_arch6 && !MEM_P (operands[1]))
5108 rtx t = gen_lowpart (SImode, operands[1]);
5109 rtx tmp = gen_reg_rtx (SImode);
5110 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5111 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5117 [(set (match_operand:SI 0 "register_operand" "")
5118 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5120 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5121 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5123 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5126 (define_insn "*arm_extendqisi"
5127 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5128 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5129 "TARGET_ARM && arm_arch4 && !arm_arch6"
5133 [(set_attr "length" "8,4")
5134 (set_attr "type" "alu_shift_reg,load_byte")
5135 (set_attr "predicable" "yes")]
5138 (define_insn "*arm_extendqisi_v6"
5139 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5141 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5142 "TARGET_ARM && arm_arch6"
5146 [(set_attr "type" "extend,load_byte")
5147 (set_attr "predicable" "yes")]
5150 (define_insn "*arm_extendqisi2addsi"
5151 [(set (match_operand:SI 0 "s_register_operand" "=r")
5152 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5153 (match_operand:SI 2 "s_register_operand" "r")))]
5155 "sxtab%?\\t%0, %2, %1"
5156 [(set_attr "type" "alu_shift_reg")
5157 (set_attr "predicable" "yes")]
5160 (define_expand "extendsfdf2"
5161 [(set (match_operand:DF 0 "s_register_operand")
5162 (float_extend:DF (match_operand:SF 1 "s_register_operand")))]
5163 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5167 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5168 ;; must go through SFmode.
5170 ;; This is always safe for an extend.
5172 (define_expand "extendhfdf2"
5173 [(set (match_operand:DF 0 "s_register_operand")
5174 (float_extend:DF (match_operand:HF 1 "s_register_operand")))]
5177 /* We don't have a direct instruction for this, so go via SFmode. */
5178 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5181 op1 = convert_to_mode (SFmode, operands[1], 0);
5182 op1 = convert_to_mode (DFmode, op1, 0);
5183 emit_insn (gen_movdf (operands[0], op1));
5186 /* Otherwise, we're done producing RTL and will pick up the correct
5187 pattern to do this with one rounding-step in a single instruction. */
5191 ;; Move insns (including loads and stores)
5193 ;; XXX Just some ideas about movti.
5194 ;; I don't think these are a good idea on the arm, there just aren't enough
5196 ;;(define_expand "loadti"
5197 ;; [(set (match_operand:TI 0 "s_register_operand")
5198 ;; (mem:TI (match_operand:SI 1 "address_operand")))]
5201 ;;(define_expand "storeti"
5202 ;; [(set (mem:TI (match_operand:TI 0 "address_operand"))
5203 ;; (match_operand:TI 1 "s_register_operand"))]
5206 ;;(define_expand "movti"
5207 ;; [(set (match_operand:TI 0 "general_operand")
5208 ;; (match_operand:TI 1 "general_operand"))]
5214 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5215 ;; operands[1] = copy_to_reg (operands[1]);
5216 ;; if (MEM_P (operands[0]))
5217 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5218 ;; else if (MEM_P (operands[1]))
5219 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5223 ;; emit_insn (insn);
5227 ;; Recognize garbage generated above.
5230 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5231 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5235 ;; register mem = (which_alternative < 3);
5236 ;; register const char *template;
5238 ;; operands[mem] = XEXP (operands[mem], 0);
5239 ;; switch (which_alternative)
5241 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5242 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5243 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5244 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5245 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5246 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5248 ;; output_asm_insn (template, operands);
5252 (define_expand "movdi"
5253 [(set (match_operand:DI 0 "general_operand")
5254 (match_operand:DI 1 "general_operand"))]
5257 gcc_checking_assert (aligned_operand (operands[0], DImode));
5258 gcc_checking_assert (aligned_operand (operands[1], DImode));
5259 if (can_create_pseudo_p ())
5261 if (!REG_P (operands[0]))
5262 operands[1] = force_reg (DImode, operands[1]);
5264 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5265 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5267 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5268 when expanding function calls. */
5269 gcc_assert (can_create_pseudo_p ());
5270 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5272 /* Perform load into legal reg pair first, then move. */
5273 rtx reg = gen_reg_rtx (DImode);
5274 emit_insn (gen_movdi (reg, operands[1]));
5277 emit_move_insn (gen_lowpart (SImode, operands[0]),
5278 gen_lowpart (SImode, operands[1]));
5279 emit_move_insn (gen_highpart (SImode, operands[0]),
5280 gen_highpart (SImode, operands[1]));
5283 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5284 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5286 /* Avoid STRD's from an odd-numbered register pair in ARM state
5287 when expanding function prologue. */
5288 gcc_assert (can_create_pseudo_p ());
5289 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5290 ? gen_reg_rtx (DImode)
5292 emit_move_insn (gen_lowpart (SImode, split_dest),
5293 gen_lowpart (SImode, operands[1]));
5294 emit_move_insn (gen_highpart (SImode, split_dest),
5295 gen_highpart (SImode, operands[1]));
5296 if (split_dest != operands[0])
5297 emit_insn (gen_movdi (operands[0], split_dest));
5303 (define_insn "*arm_movdi"
5304 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
5305 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
5307 && !(TARGET_HARD_FLOAT)
5309 && ( register_operand (operands[0], DImode)
5310 || register_operand (operands[1], DImode))"
5312 switch (which_alternative)
5319 /* Cannot load it directly, split to load it via MOV / MOVT. */
5320 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
5324 return output_move_double (operands, true, NULL);
5327 [(set_attr "length" "8,12,16,8,8")
5328 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5329 (set_attr "arm_pool_range" "*,*,*,1020,*")
5330 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5331 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5332 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5336 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5337 (match_operand:ANY64 1 "immediate_operand" ""))]
5340 && (arm_disable_literal_pool
5341 || (arm_const_double_inline_cost (operands[1])
5342 <= arm_max_const_double_inline_cost ()))"
5345 arm_split_constant (SET, SImode, curr_insn,
5346 INTVAL (gen_lowpart (SImode, operands[1])),
5347 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5348 arm_split_constant (SET, SImode, curr_insn,
5349 INTVAL (gen_highpart_mode (SImode,
5350 GET_MODE (operands[0]),
5352 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5357 ; If optimizing for size, or if we have load delay slots, then
5358 ; we want to split the constant into two separate operations.
5359 ; In both cases this may split a trivial part into a single data op
5360 ; leaving a single complex constant to load. We can also get longer
5361 ; offsets in a LDR which means we get better chances of sharing the pool
5362 ; entries. Finally, we can normally do a better job of scheduling
5363 ; LDR instructions than we can with LDM.
5364 ; This pattern will only match if the one above did not.
5366 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5367 (match_operand:ANY64 1 "const_double_operand" ""))]
5368 "TARGET_ARM && reload_completed
5369 && arm_const_double_by_parts (operands[1])"
5370 [(set (match_dup 0) (match_dup 1))
5371 (set (match_dup 2) (match_dup 3))]
5373 operands[2] = gen_highpart (SImode, operands[0]);
5374 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5376 operands[0] = gen_lowpart (SImode, operands[0]);
5377 operands[1] = gen_lowpart (SImode, operands[1]);
5382 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5383 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5384 "TARGET_EITHER && reload_completed"
5385 [(set (match_dup 0) (match_dup 1))
5386 (set (match_dup 2) (match_dup 3))]
5388 operands[2] = gen_highpart (SImode, operands[0]);
5389 operands[3] = gen_highpart (SImode, operands[1]);
5390 operands[0] = gen_lowpart (SImode, operands[0]);
5391 operands[1] = gen_lowpart (SImode, operands[1]);
5393 /* Handle a partial overlap. */
5394 if (rtx_equal_p (operands[0], operands[3]))
5396 rtx tmp0 = operands[0];
5397 rtx tmp1 = operands[1];
5399 operands[0] = operands[2];
5400 operands[1] = operands[3];
5407 ;; We can't actually do base+index doubleword loads if the index and
5408 ;; destination overlap. Split here so that we at least have chance to
5411 [(set (match_operand:DI 0 "s_register_operand" "")
5412 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5413 (match_operand:SI 2 "s_register_operand" ""))))]
5415 && reg_overlap_mentioned_p (operands[0], operands[1])
5416 && reg_overlap_mentioned_p (operands[0], operands[2])"
5418 (plus:SI (match_dup 1)
5421 (mem:DI (match_dup 4)))]
5423 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5427 (define_expand "movsi"
5428 [(set (match_operand:SI 0 "general_operand")
5429 (match_operand:SI 1 "general_operand"))]
5433 rtx base, offset, tmp;
5435 gcc_checking_assert (aligned_operand (operands[0], SImode));
5436 gcc_checking_assert (aligned_operand (operands[1], SImode));
5437 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5439 /* Everything except mem = const or mem = mem can be done easily. */
5440 if (MEM_P (operands[0]))
5441 operands[1] = force_reg (SImode, operands[1]);
5442 if (arm_general_register_operand (operands[0], SImode)
5443 && CONST_INT_P (operands[1])
5444 && !(const_ok_for_arm (INTVAL (operands[1]))
5445 || const_ok_for_arm (~INTVAL (operands[1]))))
5447 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5449 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5454 arm_split_constant (SET, SImode, NULL_RTX,
5455 INTVAL (operands[1]), operands[0], NULL_RTX,
5456 optimize && can_create_pseudo_p ());
5461 else /* Target doesn't have MOVT... */
5463 if (can_create_pseudo_p ())
5465 if (!REG_P (operands[0]))
5466 operands[1] = force_reg (SImode, operands[1]);
5470 split_const (operands[1], &base, &offset);
5471 if (INTVAL (offset) != 0
5472 && targetm.cannot_force_const_mem (SImode, operands[1]))
5474 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5475 emit_move_insn (tmp, base);
5476 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5480 tmp = can_create_pseudo_p () ? NULL_RTX : operands[0];
5482 /* Recognize the case where operand[1] is a reference to thread-local
5483 data and load its address to a register. Offsets have been split off
5485 if (arm_tls_referenced_p (operands[1]))
5486 operands[1] = legitimize_tls_address (operands[1], tmp);
5488 && (CONSTANT_P (operands[1])
5489 || symbol_mentioned_p (operands[1])
5490 || label_mentioned_p (operands[1])))
5492 legitimize_pic_address (operands[1], SImode, tmp, NULL_RTX, false);
5497 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5498 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5499 ;; so this does not matter.
5500 (define_insn "*arm_movt"
5501 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
5502 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5503 (match_operand:SI 2 "general_operand" "i,i")))]
5504 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
5506 movt%?\t%0, #:upper16:%c2
5507 movt\t%0, #:upper16:%c2"
5508 [(set_attr "arch" "32,v8mb")
5509 (set_attr "predicable" "yes")
5510 (set_attr "length" "4")
5511 (set_attr "type" "alu_sreg")]
5514 (define_insn "*arm_movsi_insn"
5515 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5516 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
5517 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
5518 && ( register_operand (operands[0], SImode)
5519 || register_operand (operands[1], SImode))"
5527 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
5528 (set_attr "predicable" "yes")
5529 (set_attr "arch" "*,*,*,v6t2,*,*")
5530 (set_attr "pool_range" "*,*,*,*,4096,*")
5531 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5535 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5536 (match_operand:SI 1 "const_int_operand" ""))]
5537 "(TARGET_32BIT || TARGET_HAVE_MOVT)
5538 && (!(const_ok_for_arm (INTVAL (operands[1]))
5539 || const_ok_for_arm (~INTVAL (operands[1]))))"
5540 [(clobber (const_int 0))]
5542 arm_split_constant (SET, SImode, NULL_RTX,
5543 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5548 ;; A normal way to do (symbol + offset) requires three instructions at least
5549 ;; (depends on how big the offset is) as below:
5550 ;; movw r0, #:lower16:g
5551 ;; movw r0, #:upper16:g
5554 ;; A better way would be:
5555 ;; movw r0, #:lower16:g+4
5556 ;; movw r0, #:upper16:g+4
5558 ;; The limitation of this way is that the length of offset should be a 16-bit
5559 ;; signed value, because current assembler only supports REL type relocation for
5560 ;; such case. If the more powerful RELA type is supported in future, we should
5561 ;; update this pattern to go with better way.
5563 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5564 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5565 (match_operand:SI 2 "const_int_operand" ""))))]
5568 && arm_disable_literal_pool
5570 && GET_CODE (operands[1]) == SYMBOL_REF"
5571 [(clobber (const_int 0))]
5573 int offset = INTVAL (operands[2]);
5575 if (offset < -0x8000 || offset > 0x7fff)
5577 arm_emit_movpair (operands[0], operands[1]);
5578 emit_insn (gen_rtx_SET (operands[0],
5579 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5583 rtx op = gen_rtx_CONST (SImode,
5584 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5585 arm_emit_movpair (operands[0], op);
5590 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5591 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5592 ;; and lo_sum would be merged back into memory load at cprop. However,
5593 ;; if the default is to prefer movt/movw rather than a load from the constant
5594 ;; pool, the performance is better.
5596 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5597 (match_operand:SI 1 "general_operand" ""))]
5598 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5599 && !target_word_relocations
5600 && !arm_tls_referenced_p (operands[1])"
5601 [(clobber (const_int 0))]
5603 arm_emit_movpair (operands[0], operands[1]);
5607 ;; When generating pic, we need to load the symbol offset into a register.
5608 ;; So that the optimizer does not confuse this with a normal symbol load
5609 ;; we use an unspec. The offset will be loaded from a constant pool entry,
5610 ;; since that is the only type of relocation we can use.
5612 ;; Wrap calculation of the whole PIC address in a single pattern for the
5613 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5614 ;; a PIC address involves two loads from memory, so we want to CSE it
5615 ;; as often as possible.
5616 ;; This pattern will be split into one of the pic_load_addr_* patterns
5617 ;; and a move after GCSE optimizations.
5619 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5620 (define_expand "calculate_pic_address"
5621 [(set (match_operand:SI 0 "register_operand")
5622 (mem:SI (plus:SI (match_operand:SI 1 "register_operand")
5623 (unspec:SI [(match_operand:SI 2 "" "")]
5628 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5630 [(set (match_operand:SI 0 "register_operand" "")
5631 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5632 (unspec:SI [(match_operand:SI 2 "" "")]
5635 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5636 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5637 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5640 ;; operand1 is the memory address to go into
5641 ;; pic_load_addr_32bit.
5642 ;; operand2 is the PIC label to be emitted
5643 ;; from pic_add_dot_plus_eight.
5644 ;; We do this to allow hoisting of the entire insn.
5645 (define_insn_and_split "pic_load_addr_unified"
5646 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5647 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5648 (match_operand:SI 2 "" "")]
5649 UNSPEC_PIC_UNIFIED))]
5652 "&& reload_completed"
5653 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5654 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5655 (match_dup 2)] UNSPEC_PIC_BASE))]
5656 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5657 [(set_attr "type" "load_4,load_4,load_4")
5658 (set_attr "pool_range" "4096,4094,1022")
5659 (set_attr "neg_pool_range" "4084,0,0")
5660 (set_attr "arch" "a,t2,t1")
5661 (set_attr "length" "8,6,4")]
5664 ;; The rather odd constraints on the following are to force reload to leave
5665 ;; the insn alone, and to force the minipool generation pass to then move
5666 ;; the GOT symbol to memory.
5668 (define_insn "pic_load_addr_32bit"
5669 [(set (match_operand:SI 0 "s_register_operand" "=r")
5670 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5671 "TARGET_32BIT && flag_pic"
5673 [(set_attr "type" "load_4")
5674 (set (attr "pool_range")
5675 (if_then_else (eq_attr "is_thumb" "no")
5678 (set (attr "neg_pool_range")
5679 (if_then_else (eq_attr "is_thumb" "no")
5684 (define_insn "pic_load_addr_thumb1"
5685 [(set (match_operand:SI 0 "s_register_operand" "=l")
5686 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5687 "TARGET_THUMB1 && flag_pic"
5689 [(set_attr "type" "load_4")
5690 (set (attr "pool_range") (const_int 1018))]
5693 (define_insn "pic_add_dot_plus_four"
5694 [(set (match_operand:SI 0 "register_operand" "=r")
5695 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5697 (match_operand 2 "" "")]
5701 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5702 INTVAL (operands[2]));
5703 return \"add\\t%0, %|pc\";
5705 [(set_attr "length" "2")
5706 (set_attr "type" "alu_sreg")]
5709 (define_insn "pic_add_dot_plus_eight"
5710 [(set (match_operand:SI 0 "register_operand" "=r")
5711 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5713 (match_operand 2 "" "")]
5717 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5718 INTVAL (operands[2]));
5719 return \"add%?\\t%0, %|pc, %1\";
5721 [(set_attr "predicable" "yes")
5722 (set_attr "type" "alu_sreg")]
5725 (define_insn "tls_load_dot_plus_eight"
5726 [(set (match_operand:SI 0 "register_operand" "=r")
5727 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5729 (match_operand 2 "" "")]
5733 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5734 INTVAL (operands[2]));
5735 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5737 [(set_attr "predicable" "yes")
5738 (set_attr "type" "load_4")]
5741 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5742 ;; followed by a load. These sequences can be crunched down to
5743 ;; tls_load_dot_plus_eight by a peephole.
5746 [(set (match_operand:SI 0 "register_operand" "")
5747 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5749 (match_operand 1 "" "")]
5751 (set (match_operand:SI 2 "arm_general_register_operand" "")
5752 (mem:SI (match_dup 0)))]
5753 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5755 (mem:SI (unspec:SI [(match_dup 3)
5762 (define_insn "pic_offset_arm"
5763 [(set (match_operand:SI 0 "register_operand" "=r")
5764 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5765 (unspec:SI [(match_operand:SI 2 "" "X")]
5766 UNSPEC_PIC_OFFSET))))]
5767 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5768 "ldr%?\\t%0, [%1,%2]"
5769 [(set_attr "type" "load_4")]
5772 (define_expand "builtin_setjmp_receiver"
5773 [(label_ref (match_operand 0 "" ""))]
5777 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5779 if (arm_pic_register != INVALID_REGNUM)
5780 arm_load_pic_register (1UL << 3, NULL_RTX);
5784 ;; If copying one reg to another we can set the condition codes according to
5785 ;; its value. Such a move is common after a return from subroutine and the
5786 ;; result is being tested against zero.
5788 (define_insn "*movsi_compare0"
5789 [(set (reg:CC CC_REGNUM)
5790 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5792 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5797 subs%?\\t%0, %1, #0"
5798 [(set_attr "conds" "set")
5799 (set_attr "type" "alus_imm,alus_imm")]
5802 ;; Subroutine to store a half word from a register into memory.
5803 ;; Operand 0 is the source register (HImode)
5804 ;; Operand 1 is the destination address in a register (SImode)
5806 ;; In both this routine and the next, we must be careful not to spill
5807 ;; a memory address of reg+large_const into a separate PLUS insn, since this
5808 ;; can generate unrecognizable rtl.
5810 (define_expand "storehi"
5811 [;; store the low byte
5812 (set (match_operand 1 "" "") (match_dup 3))
5813 ;; extract the high byte
5815 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5816 ;; store the high byte
5817 (set (match_dup 4) (match_dup 5))]
5821 rtx op1 = operands[1];
5822 rtx addr = XEXP (op1, 0);
5823 enum rtx_code code = GET_CODE (addr);
5825 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5827 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
5829 operands[4] = adjust_address (op1, QImode, 1);
5830 operands[1] = adjust_address (operands[1], QImode, 0);
5831 operands[3] = gen_lowpart (QImode, operands[0]);
5832 operands[0] = gen_lowpart (SImode, operands[0]);
5833 operands[2] = gen_reg_rtx (SImode);
5834 operands[5] = gen_lowpart (QImode, operands[2]);
5838 (define_expand "storehi_bigend"
5839 [(set (match_dup 4) (match_dup 3))
5841 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5842 (set (match_operand 1 "" "") (match_dup 5))]
5846 rtx op1 = operands[1];
5847 rtx addr = XEXP (op1, 0);
5848 enum rtx_code code = GET_CODE (addr);
5850 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5852 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
5854 operands[4] = adjust_address (op1, QImode, 1);
5855 operands[1] = adjust_address (operands[1], QImode, 0);
5856 operands[3] = gen_lowpart (QImode, operands[0]);
5857 operands[0] = gen_lowpart (SImode, operands[0]);
5858 operands[2] = gen_reg_rtx (SImode);
5859 operands[5] = gen_lowpart (QImode, operands[2]);
5863 ;; Subroutine to store a half word integer constant into memory.
5864 (define_expand "storeinthi"
5865 [(set (match_operand 0 "" "")
5866 (match_operand 1 "" ""))
5867 (set (match_dup 3) (match_dup 2))]
5871 HOST_WIDE_INT value = INTVAL (operands[1]);
5872 rtx addr = XEXP (operands[0], 0);
5873 rtx op0 = operands[0];
5874 enum rtx_code code = GET_CODE (addr);
5876 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5878 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
5880 operands[1] = gen_reg_rtx (SImode);
5881 if (BYTES_BIG_ENDIAN)
5883 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
5884 if ((value & 255) == ((value >> 8) & 255))
5885 operands[2] = operands[1];
5888 operands[2] = gen_reg_rtx (SImode);
5889 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
5894 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
5895 if ((value & 255) == ((value >> 8) & 255))
5896 operands[2] = operands[1];
5899 operands[2] = gen_reg_rtx (SImode);
5900 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
5904 operands[3] = adjust_address (op0, QImode, 1);
5905 operands[0] = adjust_address (operands[0], QImode, 0);
5906 operands[2] = gen_lowpart (QImode, operands[2]);
5907 operands[1] = gen_lowpart (QImode, operands[1]);
5911 (define_expand "storehi_single_op"
5912 [(set (match_operand:HI 0 "memory_operand")
5913 (match_operand:HI 1 "general_operand"))]
5914 "TARGET_32BIT && arm_arch4"
5916 if (!s_register_operand (operands[1], HImode))
5917 operands[1] = copy_to_mode_reg (HImode, operands[1]);
5921 (define_expand "movhi"
5922 [(set (match_operand:HI 0 "general_operand")
5923 (match_operand:HI 1 "general_operand"))]
5926 gcc_checking_assert (aligned_operand (operands[0], HImode));
5927 gcc_checking_assert (aligned_operand (operands[1], HImode));
5930 if (can_create_pseudo_p ())
5932 if (MEM_P (operands[0]))
5936 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
5939 if (CONST_INT_P (operands[1]))
5940 emit_insn (gen_storeinthi (operands[0], operands[1]));
5943 if (MEM_P (operands[1]))
5944 operands[1] = force_reg (HImode, operands[1]);
5945 if (BYTES_BIG_ENDIAN)
5946 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
5948 emit_insn (gen_storehi (operands[1], operands[0]));
5952 /* Sign extend a constant, and keep it in an SImode reg. */
5953 else if (CONST_INT_P (operands[1]))
5955 rtx reg = gen_reg_rtx (SImode);
5956 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
5958 /* If the constant is already valid, leave it alone. */
5959 if (!const_ok_for_arm (val))
5961 /* If setting all the top bits will make the constant
5962 loadable in a single instruction, then set them.
5963 Otherwise, sign extend the number. */
5965 if (const_ok_for_arm (~(val | ~0xffff)))
5967 else if (val & 0x8000)
5971 emit_insn (gen_movsi (reg, GEN_INT (val)));
5972 operands[1] = gen_lowpart (HImode, reg);
5974 else if (arm_arch4 && optimize && can_create_pseudo_p ()
5975 && MEM_P (operands[1]))
5977 rtx reg = gen_reg_rtx (SImode);
5979 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
5980 operands[1] = gen_lowpart (HImode, reg);
5982 else if (!arm_arch4)
5984 if (MEM_P (operands[1]))
5987 rtx offset = const0_rtx;
5988 rtx reg = gen_reg_rtx (SImode);
5990 if ((REG_P (base = XEXP (operands[1], 0))
5991 || (GET_CODE (base) == PLUS
5992 && (CONST_INT_P (offset = XEXP (base, 1)))
5993 && ((INTVAL(offset) & 1) != 1)
5994 && REG_P (base = XEXP (base, 0))))
5995 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
5999 new_rtx = widen_memory_access (operands[1], SImode,
6000 ((INTVAL (offset) & ~3)
6001 - INTVAL (offset)));
6002 emit_insn (gen_movsi (reg, new_rtx));
6003 if (((INTVAL (offset) & 2) != 0)
6004 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6006 rtx reg2 = gen_reg_rtx (SImode);
6008 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6013 emit_insn (gen_movhi_bytes (reg, operands[1]));
6015 operands[1] = gen_lowpart (HImode, reg);
6019 /* Handle loading a large integer during reload. */
6020 else if (CONST_INT_P (operands[1])
6021 && !const_ok_for_arm (INTVAL (operands[1]))
6022 && !const_ok_for_arm (~INTVAL (operands[1])))
6024 /* Writing a constant to memory needs a scratch, which should
6025 be handled with SECONDARY_RELOADs. */
6026 gcc_assert (REG_P (operands[0]));
6028 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6029 emit_insn (gen_movsi (operands[0], operands[1]));
6033 else if (TARGET_THUMB2)
6035 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6036 if (can_create_pseudo_p ())
6038 if (!REG_P (operands[0]))
6039 operands[1] = force_reg (HImode, operands[1]);
6040 /* Zero extend a constant, and keep it in an SImode reg. */
6041 else if (CONST_INT_P (operands[1]))
6043 rtx reg = gen_reg_rtx (SImode);
6044 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6046 emit_insn (gen_movsi (reg, GEN_INT (val)));
6047 operands[1] = gen_lowpart (HImode, reg);
6051 else /* TARGET_THUMB1 */
6053 if (can_create_pseudo_p ())
6055 if (CONST_INT_P (operands[1]))
6057 rtx reg = gen_reg_rtx (SImode);
6059 emit_insn (gen_movsi (reg, operands[1]));
6060 operands[1] = gen_lowpart (HImode, reg);
6063 /* ??? We shouldn't really get invalid addresses here, but this can
6064 happen if we are passed a SP (never OK for HImode/QImode) or
6065 virtual register (also rejected as illegitimate for HImode/QImode)
6066 relative address. */
6067 /* ??? This should perhaps be fixed elsewhere, for instance, in
6068 fixup_stack_1, by checking for other kinds of invalid addresses,
6069 e.g. a bare reference to a virtual register. This may confuse the
6070 alpha though, which must handle this case differently. */
6071 if (MEM_P (operands[0])
6072 && !memory_address_p (GET_MODE (operands[0]),
6073 XEXP (operands[0], 0)))
6075 = replace_equiv_address (operands[0],
6076 copy_to_reg (XEXP (operands[0], 0)));
6078 if (MEM_P (operands[1])
6079 && !memory_address_p (GET_MODE (operands[1]),
6080 XEXP (operands[1], 0)))
6082 = replace_equiv_address (operands[1],
6083 copy_to_reg (XEXP (operands[1], 0)));
6085 if (MEM_P (operands[1]) && optimize > 0)
6087 rtx reg = gen_reg_rtx (SImode);
6089 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6090 operands[1] = gen_lowpart (HImode, reg);
6093 if (MEM_P (operands[0]))
6094 operands[1] = force_reg (HImode, operands[1]);
6096 else if (CONST_INT_P (operands[1])
6097 && !satisfies_constraint_I (operands[1]))
6099 /* Handle loading a large integer during reload. */
6101 /* Writing a constant to memory needs a scratch, which should
6102 be handled with SECONDARY_RELOADs. */
6103 gcc_assert (REG_P (operands[0]));
6105 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6106 emit_insn (gen_movsi (operands[0], operands[1]));
6113 (define_expand "movhi_bytes"
6114 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6116 (zero_extend:SI (match_dup 6)))
6117 (set (match_operand:SI 0 "" "")
6118 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6123 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6125 mem1 = change_address (operands[1], QImode, addr);
6126 mem2 = change_address (operands[1], QImode,
6127 plus_constant (Pmode, addr, 1));
6128 operands[0] = gen_lowpart (SImode, operands[0]);
6130 operands[2] = gen_reg_rtx (SImode);
6131 operands[3] = gen_reg_rtx (SImode);
6134 if (BYTES_BIG_ENDIAN)
6136 operands[4] = operands[2];
6137 operands[5] = operands[3];
6141 operands[4] = operands[3];
6142 operands[5] = operands[2];
6147 (define_expand "movhi_bigend"
6149 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand") 0)
6152 (ashiftrt:SI (match_dup 2) (const_int 16)))
6153 (set (match_operand:HI 0 "s_register_operand")
6157 operands[2] = gen_reg_rtx (SImode);
6158 operands[3] = gen_reg_rtx (SImode);
6159 operands[4] = gen_lowpart (HImode, operands[3]);
6163 ;; Pattern to recognize insn generated default case above
6164 (define_insn "*movhi_insn_arch4"
6165 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6166 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6168 && arm_arch4 && !TARGET_HARD_FLOAT
6169 && (register_operand (operands[0], HImode)
6170 || register_operand (operands[1], HImode))"
6172 mov%?\\t%0, %1\\t%@ movhi
6173 mvn%?\\t%0, #%B1\\t%@ movhi
6174 movw%?\\t%0, %L1\\t%@ movhi
6175 strh%?\\t%1, %0\\t%@ movhi
6176 ldrh%?\\t%0, %1\\t%@ movhi"
6177 [(set_attr "predicable" "yes")
6178 (set_attr "pool_range" "*,*,*,*,256")
6179 (set_attr "neg_pool_range" "*,*,*,*,244")
6180 (set_attr "arch" "*,*,v6t2,*,*")
6181 (set_attr_alternative "type"
6182 [(if_then_else (match_operand 1 "const_int_operand" "")
6183 (const_string "mov_imm" )
6184 (const_string "mov_reg"))
6185 (const_string "mvn_imm")
6186 (const_string "mov_imm")
6187 (const_string "store_4")
6188 (const_string "load_4")])]
6191 (define_insn "*movhi_bytes"
6192 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6193 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6194 "TARGET_ARM && !TARGET_HARD_FLOAT"
6196 mov%?\\t%0, %1\\t%@ movhi
6197 mov%?\\t%0, %1\\t%@ movhi
6198 mvn%?\\t%0, #%B1\\t%@ movhi"
6199 [(set_attr "predicable" "yes")
6200 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6203 ;; We use a DImode scratch because we may occasionally need an additional
6204 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6205 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6206 ;; The reload_in<m> and reload_out<m> patterns require special constraints
6207 ;; to be correctly handled in default_secondary_reload function.
6208 (define_expand "reload_outhi"
6209 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6210 (match_operand:HI 1 "s_register_operand" "r")
6211 (match_operand:DI 2 "s_register_operand" "=&l")])]
6214 arm_reload_out_hi (operands);
6216 thumb_reload_out_hi (operands);
6221 (define_expand "reload_inhi"
6222 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6223 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6224 (match_operand:DI 2 "s_register_operand" "=&r")])]
6228 arm_reload_in_hi (operands);
6230 thumb_reload_out_hi (operands);
6234 (define_expand "movqi"
6235 [(set (match_operand:QI 0 "general_operand")
6236 (match_operand:QI 1 "general_operand"))]
6239 /* Everything except mem = const or mem = mem can be done easily */
6241 if (can_create_pseudo_p ())
6243 if (CONST_INT_P (operands[1]))
6245 rtx reg = gen_reg_rtx (SImode);
6247 /* For thumb we want an unsigned immediate, then we are more likely
6248 to be able to use a movs insn. */
6250 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6252 emit_insn (gen_movsi (reg, operands[1]));
6253 operands[1] = gen_lowpart (QImode, reg);
6258 /* ??? We shouldn't really get invalid addresses here, but this can
6259 happen if we are passed a SP (never OK for HImode/QImode) or
6260 virtual register (also rejected as illegitimate for HImode/QImode)
6261 relative address. */
6262 /* ??? This should perhaps be fixed elsewhere, for instance, in
6263 fixup_stack_1, by checking for other kinds of invalid addresses,
6264 e.g. a bare reference to a virtual register. This may confuse the
6265 alpha though, which must handle this case differently. */
6266 if (MEM_P (operands[0])
6267 && !memory_address_p (GET_MODE (operands[0]),
6268 XEXP (operands[0], 0)))
6270 = replace_equiv_address (operands[0],
6271 copy_to_reg (XEXP (operands[0], 0)));
6272 if (MEM_P (operands[1])
6273 && !memory_address_p (GET_MODE (operands[1]),
6274 XEXP (operands[1], 0)))
6276 = replace_equiv_address (operands[1],
6277 copy_to_reg (XEXP (operands[1], 0)));
6280 if (MEM_P (operands[1]) && optimize > 0)
6282 rtx reg = gen_reg_rtx (SImode);
6284 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6285 operands[1] = gen_lowpart (QImode, reg);
6288 if (MEM_P (operands[0]))
6289 operands[1] = force_reg (QImode, operands[1]);
6291 else if (TARGET_THUMB
6292 && CONST_INT_P (operands[1])
6293 && !satisfies_constraint_I (operands[1]))
6295 /* Handle loading a large integer during reload. */
6297 /* Writing a constant to memory needs a scratch, which should
6298 be handled with SECONDARY_RELOADs. */
6299 gcc_assert (REG_P (operands[0]));
6301 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6302 emit_insn (gen_movsi (operands[0], operands[1]));
6308 (define_insn "*arm_movqi_insn"
6309 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6310 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6312 && ( register_operand (operands[0], QImode)
6313 || register_operand (operands[1], QImode))"
6324 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6325 (set_attr "predicable" "yes")
6326 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6327 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6328 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6332 (define_expand "movhf"
6333 [(set (match_operand:HF 0 "general_operand")
6334 (match_operand:HF 1 "general_operand"))]
6337 gcc_checking_assert (aligned_operand (operands[0], HFmode));
6338 gcc_checking_assert (aligned_operand (operands[1], HFmode));
6341 if (MEM_P (operands[0]))
6342 operands[1] = force_reg (HFmode, operands[1]);
6344 else /* TARGET_THUMB1 */
6346 if (can_create_pseudo_p ())
6348 if (!REG_P (operands[0]))
6349 operands[1] = force_reg (HFmode, operands[1]);
6355 (define_insn "*arm32_movhf"
6356 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6357 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6358 "TARGET_32BIT && !TARGET_HARD_FLOAT
6359 && ( s_register_operand (operands[0], HFmode)
6360 || s_register_operand (operands[1], HFmode))"
6362 switch (which_alternative)
6364 case 0: /* ARM register from memory */
6365 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6366 case 1: /* memory from ARM register */
6367 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6368 case 2: /* ARM register from ARM register */
6369 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6370 case 3: /* ARM register from constant */
6375 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6377 ops[0] = operands[0];
6378 ops[1] = GEN_INT (bits);
6379 ops[2] = GEN_INT (bits & 0xff00);
6380 ops[3] = GEN_INT (bits & 0x00ff);
6382 if (arm_arch_thumb2)
6383 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6385 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6392 [(set_attr "conds" "unconditional")
6393 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6394 (set_attr "length" "4,4,4,8")
6395 (set_attr "predicable" "yes")]
6398 (define_expand "movsf"
6399 [(set (match_operand:SF 0 "general_operand")
6400 (match_operand:SF 1 "general_operand"))]
6403 gcc_checking_assert (aligned_operand (operands[0], SFmode));
6404 gcc_checking_assert (aligned_operand (operands[1], SFmode));
6407 if (MEM_P (operands[0]))
6408 operands[1] = force_reg (SFmode, operands[1]);
6410 else /* TARGET_THUMB1 */
6412 if (can_create_pseudo_p ())
6414 if (!REG_P (operands[0]))
6415 operands[1] = force_reg (SFmode, operands[1]);
6419 /* Cannot load it directly, generate a load with clobber so that it can be
6420 loaded via GPR with MOV / MOVT. */
6421 if (arm_disable_literal_pool
6422 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6423 && CONST_DOUBLE_P (operands[1])
6424 && TARGET_HARD_FLOAT
6425 && !vfp3_const_double_rtx (operands[1]))
6427 rtx clobreg = gen_reg_rtx (SFmode);
6428 emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
6435 ;; Transform a floating-point move of a constant into a core register into
6436 ;; an SImode operation.
6438 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6439 (match_operand:SF 1 "immediate_operand" ""))]
6442 && CONST_DOUBLE_P (operands[1])"
6443 [(set (match_dup 2) (match_dup 3))]
6445 operands[2] = gen_lowpart (SImode, operands[0]);
6446 operands[3] = gen_lowpart (SImode, operands[1]);
6447 if (operands[2] == 0 || operands[3] == 0)
6452 (define_insn "*arm_movsf_soft_insn"
6453 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6454 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6456 && TARGET_SOFT_FLOAT
6457 && (!MEM_P (operands[0])
6458 || register_operand (operands[1], SFmode))"
6460 switch (which_alternative)
6462 case 0: return \"mov%?\\t%0, %1\";
6464 /* Cannot load it directly, split to load it via MOV / MOVT. */
6465 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
6467 return \"ldr%?\\t%0, %1\\t%@ float\";
6468 case 2: return \"str%?\\t%1, %0\\t%@ float\";
6469 default: gcc_unreachable ();
6472 [(set_attr "predicable" "yes")
6473 (set_attr "type" "mov_reg,load_4,store_4")
6474 (set_attr "arm_pool_range" "*,4096,*")
6475 (set_attr "thumb2_pool_range" "*,4094,*")
6476 (set_attr "arm_neg_pool_range" "*,4084,*")
6477 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6480 ;; Splitter for the above.
6482 [(set (match_operand:SF 0 "s_register_operand")
6483 (match_operand:SF 1 "const_double_operand"))]
6484 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
6488 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
6489 rtx cst = gen_int_mode (buf, SImode);
6490 emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
6495 (define_expand "movdf"
6496 [(set (match_operand:DF 0 "general_operand")
6497 (match_operand:DF 1 "general_operand"))]
6500 gcc_checking_assert (aligned_operand (operands[0], DFmode));
6501 gcc_checking_assert (aligned_operand (operands[1], DFmode));
6504 if (MEM_P (operands[0]))
6505 operands[1] = force_reg (DFmode, operands[1]);
6507 else /* TARGET_THUMB */
6509 if (can_create_pseudo_p ())
6511 if (!REG_P (operands[0]))
6512 operands[1] = force_reg (DFmode, operands[1]);
6516 /* Cannot load it directly, generate a load with clobber so that it can be
6517 loaded via GPR with MOV / MOVT. */
6518 if (arm_disable_literal_pool
6519 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6520 && CONSTANT_P (operands[1])
6521 && TARGET_HARD_FLOAT
6522 && !arm_const_double_rtx (operands[1])
6523 && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
6525 rtx clobreg = gen_reg_rtx (DFmode);
6526 emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
6533 ;; Reloading a df mode value stored in integer regs to memory can require a
6535 ;; Another reload_out<m> pattern that requires special constraints.
6536 (define_expand "reload_outdf"
6537 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6538 (match_operand:DF 1 "s_register_operand" "r")
6539 (match_operand:SI 2 "s_register_operand" "=&r")]
6543 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6546 operands[2] = XEXP (operands[0], 0);
6547 else if (code == POST_INC || code == PRE_DEC)
6549 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6550 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6551 emit_insn (gen_movdi (operands[0], operands[1]));
6554 else if (code == PRE_INC)
6556 rtx reg = XEXP (XEXP (operands[0], 0), 0);
6558 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6561 else if (code == POST_DEC)
6562 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6564 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6565 XEXP (XEXP (operands[0], 0), 1)));
6567 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
6570 if (code == POST_DEC)
6571 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6577 (define_insn "*movdf_soft_insn"
6578 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
6579 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
6580 "TARGET_32BIT && TARGET_SOFT_FLOAT
6581 && ( register_operand (operands[0], DFmode)
6582 || register_operand (operands[1], DFmode))"
6584 switch (which_alternative)
6591 /* Cannot load it directly, split to load it via MOV / MOVT. */
6592 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
6596 return output_move_double (operands, true, NULL);
6599 [(set_attr "length" "8,12,16,8,8")
6600 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
6601 (set_attr "arm_pool_range" "*,*,*,1020,*")
6602 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6603 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6604 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6607 ;; Splitter for the above.
6609 [(set (match_operand:DF 0 "s_register_operand")
6610 (match_operand:DF 1 "const_double_operand"))]
6611 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
6615 int order = BYTES_BIG_ENDIAN ? 1 : 0;
6616 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
6617 unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
6618 ival |= (zext_hwi (buf[1 - order], 32) << 32);
6619 rtx cst = gen_int_mode (ival, DImode);
6620 emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
6626 ;; load- and store-multiple insns
6627 ;; The arm can load/store any set of registers, provided that they are in
6628 ;; ascending order, but these expanders assume a contiguous set.
6630 (define_expand "load_multiple"
6631 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6632 (match_operand:SI 1 "" ""))
6633 (use (match_operand:SI 2 "" ""))])]
6636 HOST_WIDE_INT offset = 0;
6638 /* Support only fixed point registers. */
6639 if (!CONST_INT_P (operands[2])
6640 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6641 || INTVAL (operands[2]) < 2
6642 || !MEM_P (operands[1])
6643 || !REG_P (operands[0])
6644 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6645 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6649 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6650 INTVAL (operands[2]),
6651 force_reg (SImode, XEXP (operands[1], 0)),
6652 FALSE, operands[1], &offset);
6655 (define_expand "store_multiple"
6656 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6657 (match_operand:SI 1 "" ""))
6658 (use (match_operand:SI 2 "" ""))])]
6661 HOST_WIDE_INT offset = 0;
6663 /* Support only fixed point registers. */
6664 if (!CONST_INT_P (operands[2])
6665 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6666 || INTVAL (operands[2]) < 2
6667 || !REG_P (operands[1])
6668 || !MEM_P (operands[0])
6669 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6670 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6674 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6675 INTVAL (operands[2]),
6676 force_reg (SImode, XEXP (operands[0], 0)),
6677 FALSE, operands[0], &offset);
6681 (define_expand "setmemsi"
6682 [(match_operand:BLK 0 "general_operand")
6683 (match_operand:SI 1 "const_int_operand")
6684 (match_operand:SI 2 "const_int_operand")
6685 (match_operand:SI 3 "const_int_operand")]
6688 if (arm_gen_setmem (operands))
6695 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6696 ;; We could let this apply for blocks of less than this, but it clobbers so
6697 ;; many registers that there is then probably a better way.
6699 (define_expand "cpymemqi"
6700 [(match_operand:BLK 0 "general_operand")
6701 (match_operand:BLK 1 "general_operand")
6702 (match_operand:SI 2 "const_int_operand")
6703 (match_operand:SI 3 "const_int_operand")]
6708 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6709 && !optimize_function_for_size_p (cfun))
6711 if (gen_cpymem_ldrd_strd (operands))
6716 if (arm_gen_cpymemqi (operands))
6720 else /* TARGET_THUMB1 */
6722 if ( INTVAL (operands[3]) != 4
6723 || INTVAL (operands[2]) > 48)
6726 thumb_expand_cpymemqi (operands);
6733 ;; Compare & branch insns
6734 ;; The range calculations are based as follows:
6735 ;; For forward branches, the address calculation returns the address of
6736 ;; the next instruction. This is 2 beyond the branch instruction.
6737 ;; For backward branches, the address calculation returns the address of
6738 ;; the first instruction in this pattern (cmp). This is 2 before the branch
6739 ;; instruction for the shortest sequence, and 4 before the branch instruction
6740 ;; if we have to jump around an unconditional branch.
6741 ;; To the basic branch range the PC offset must be added (this is +4).
6742 ;; So for forward branches we have
6743 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6744 ;; And for backward branches we have
6745 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6747 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6748 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
6750 (define_expand "cbranchsi4"
6751 [(set (pc) (if_then_else
6752 (match_operator 0 "expandable_comparison_operator"
6753 [(match_operand:SI 1 "s_register_operand")
6754 (match_operand:SI 2 "nonmemory_operand")])
6755 (label_ref (match_operand 3 "" ""))
6761 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6763 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6767 if (thumb1_cmpneg_operand (operands[2], SImode))
6769 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6770 operands[3], operands[0]));
6773 if (!thumb1_cmp_operand (operands[2], SImode))
6774 operands[2] = force_reg (SImode, operands[2]);
6777 (define_expand "cbranchsf4"
6778 [(set (pc) (if_then_else
6779 (match_operator 0 "expandable_comparison_operator"
6780 [(match_operand:SF 1 "s_register_operand")
6781 (match_operand:SF 2 "vfp_compare_operand")])
6782 (label_ref (match_operand 3 "" ""))
6784 "TARGET_32BIT && TARGET_HARD_FLOAT"
6785 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6786 operands[3])); DONE;"
6789 (define_expand "cbranchdf4"
6790 [(set (pc) (if_then_else
6791 (match_operator 0 "expandable_comparison_operator"
6792 [(match_operand:DF 1 "s_register_operand")
6793 (match_operand:DF 2 "vfp_compare_operand")])
6794 (label_ref (match_operand 3 "" ""))
6796 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6797 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6798 operands[3])); DONE;"
6801 (define_expand "cbranchdi4"
6802 [(set (pc) (if_then_else
6803 (match_operator 0 "expandable_comparison_operator"
6804 [(match_operand:DI 1 "s_register_operand")
6805 (match_operand:DI 2 "cmpdi_operand")])
6806 (label_ref (match_operand 3 "" ""))
6810 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6812 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6818 ;; Comparison and test insns
6820 (define_insn "*arm_cmpsi_insn"
6821 [(set (reg:CC CC_REGNUM)
6822 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6823 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
6831 [(set_attr "conds" "set")
6832 (set_attr "arch" "t2,t2,any,any,any")
6833 (set_attr "length" "2,2,4,4,4")
6834 (set_attr "predicable" "yes")
6835 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6836 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6839 (define_insn "*cmpsi_shiftsi"
6840 [(set (reg:CC CC_REGNUM)
6841 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
6842 (match_operator:SI 3 "shift_operator"
6843 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6844 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6847 [(set_attr "conds" "set")
6848 (set_attr "shift" "1")
6849 (set_attr "arch" "32,a,a")
6850 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6852 (define_insn "*cmpsi_shiftsi_swp"
6853 [(set (reg:CC_SWP CC_REGNUM)
6854 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6855 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6856 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6857 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6860 [(set_attr "conds" "set")
6861 (set_attr "shift" "1")
6862 (set_attr "arch" "32,a,a")
6863 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6865 (define_insn "*arm_cmpsi_negshiftsi_si"
6866 [(set (reg:CC_Z CC_REGNUM)
6868 (neg:SI (match_operator:SI 1 "shift_operator"
6869 [(match_operand:SI 2 "s_register_operand" "r")
6870 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6871 (match_operand:SI 0 "s_register_operand" "r")))]
6874 [(set_attr "conds" "set")
6875 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6876 (const_string "alus_shift_imm")
6877 (const_string "alus_shift_reg")))
6878 (set_attr "predicable" "yes")]
6881 ;; DImode comparisons. The generic code generates branches that
6882 ;; if-conversion cannot reduce to a conditional compare, so we do
6885 (define_insn_and_split "*arm_cmpdi_insn"
6886 [(set (reg:CC_NCV CC_REGNUM)
6887 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6888 (match_operand:DI 1 "arm_di_operand" "rDi")))
6889 (clobber (match_scratch:SI 2 "=r"))]
6891 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6892 "&& reload_completed"
6893 [(set (reg:CC CC_REGNUM)
6894 (compare:CC (match_dup 0) (match_dup 1)))
6895 (parallel [(set (reg:CC CC_REGNUM)
6896 (compare:CC (match_dup 3) (match_dup 4)))
6898 (minus:SI (match_dup 5)
6899 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))])]
6901 operands[3] = gen_highpart (SImode, operands[0]);
6902 operands[0] = gen_lowpart (SImode, operands[0]);
6903 if (CONST_INT_P (operands[1]))
6905 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);
6906 if (operands[4] == const0_rtx)
6907 operands[5] = operands[3];
6909 operands[5] = gen_rtx_PLUS (SImode, operands[3],
6910 gen_int_mode (-UINTVAL (operands[4]),
6915 operands[4] = gen_highpart (SImode, operands[1]);
6916 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6918 operands[1] = gen_lowpart (SImode, operands[1]);
6919 operands[2] = gen_lowpart (SImode, operands[2]);
6921 [(set_attr "conds" "set")
6922 (set_attr "length" "8")
6923 (set_attr "type" "multiple")]
6926 (define_insn_and_split "*arm_cmpdi_unsigned"
6927 [(set (reg:CC_CZ CC_REGNUM)
6928 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6929 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
6932 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6933 "&& reload_completed"
6934 [(set (reg:CC CC_REGNUM)
6935 (compare:CC (match_dup 2) (match_dup 3)))
6936 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6937 (set (reg:CC CC_REGNUM)
6938 (compare:CC (match_dup 0) (match_dup 1))))]
6940 operands[2] = gen_highpart (SImode, operands[0]);
6941 operands[0] = gen_lowpart (SImode, operands[0]);
6942 if (CONST_INT_P (operands[1]))
6943 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6945 operands[3] = gen_highpart (SImode, operands[1]);
6946 operands[1] = gen_lowpart (SImode, operands[1]);
6948 [(set_attr "conds" "set")
6949 (set_attr "enabled_for_short_it" "yes,yes,no,*")
6950 (set_attr "arch" "t2,t2,t2,a")
6951 (set_attr "length" "6,6,10,8")
6952 (set_attr "type" "multiple")]
6955 (define_insn "*arm_cmpdi_zero"
6956 [(set (reg:CC_Z CC_REGNUM)
6957 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6959 (clobber (match_scratch:SI 1 "=r"))]
6961 "orrs%?\\t%1, %Q0, %R0"
6962 [(set_attr "conds" "set")
6963 (set_attr "type" "logics_reg")]
6966 ; This insn allows redundant compares to be removed by cse, nothing should
6967 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6968 ; is deleted later on. The match_dup will match the mode here, so that
6969 ; mode changes of the condition codes aren't lost by this even though we don't
6970 ; specify what they are.
6972 (define_insn "*deleted_compare"
6973 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6975 "\\t%@ deleted compare"
6976 [(set_attr "conds" "set")
6977 (set_attr "length" "0")
6978 (set_attr "type" "no_insn")]
6982 ;; Conditional branch insns
6984 (define_expand "cbranch_cc"
6986 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
6987 (match_operand 2 "" "")])
6988 (label_ref (match_operand 3 "" ""))
6991 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
6992 operands[1], operands[2], NULL_RTX);
6993 operands[2] = const0_rtx;"
6997 ;; Patterns to match conditional branch insns.
7000 (define_insn "arm_cond_branch"
7002 (if_then_else (match_operator 1 "arm_comparison_operator"
7003 [(match_operand 2 "cc_register" "") (const_int 0)])
7004 (label_ref (match_operand 0 "" ""))
7008 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7010 arm_ccfsm_state += 2;
7013 return \"b%d1\\t%l0\";
7015 [(set_attr "conds" "use")
7016 (set_attr "type" "branch")
7017 (set (attr "length")
7019 (and (match_test "TARGET_THUMB2")
7020 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7021 (le (minus (match_dup 0) (pc)) (const_int 256))))
7026 (define_insn "*arm_cond_branch_reversed"
7028 (if_then_else (match_operator 1 "arm_comparison_operator"
7029 [(match_operand 2 "cc_register" "") (const_int 0)])
7031 (label_ref (match_operand 0 "" ""))))]
7034 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7036 arm_ccfsm_state += 2;
7039 return \"b%D1\\t%l0\";
7041 [(set_attr "conds" "use")
7042 (set_attr "type" "branch")
7043 (set (attr "length")
7045 (and (match_test "TARGET_THUMB2")
7046 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7047 (le (minus (match_dup 0) (pc)) (const_int 256))))
7056 (define_expand "cstore_cc"
7057 [(set (match_operand:SI 0 "s_register_operand")
7058 (match_operator:SI 1 "" [(match_operand 2 "" "")
7059 (match_operand 3 "" "")]))]
7061 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7062 operands[2], operands[3], NULL_RTX);
7063 operands[3] = const0_rtx;"
7066 (define_insn_and_split "*mov_scc"
7067 [(set (match_operand:SI 0 "s_register_operand" "=r")
7068 (match_operator:SI 1 "arm_comparison_operator_mode"
7069 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7071 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7074 (if_then_else:SI (match_dup 1)
7078 [(set_attr "conds" "use")
7079 (set_attr "length" "8")
7080 (set_attr "type" "multiple")]
7083 (define_insn_and_split "*mov_negscc"
7084 [(set (match_operand:SI 0 "s_register_operand" "=r")
7085 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7086 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7088 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7091 (if_then_else:SI (match_dup 1)
7095 operands[3] = GEN_INT (~0);
7097 [(set_attr "conds" "use")
7098 (set_attr "length" "8")
7099 (set_attr "type" "multiple")]
7102 (define_insn_and_split "*mov_notscc"
7103 [(set (match_operand:SI 0 "s_register_operand" "=r")
7104 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7105 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7107 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7110 (if_then_else:SI (match_dup 1)
7114 operands[3] = GEN_INT (~1);
7115 operands[4] = GEN_INT (~0);
7117 [(set_attr "conds" "use")
7118 (set_attr "length" "8")
7119 (set_attr "type" "multiple")]
7122 (define_expand "cstoresi4"
7123 [(set (match_operand:SI 0 "s_register_operand")
7124 (match_operator:SI 1 "expandable_comparison_operator"
7125 [(match_operand:SI 2 "s_register_operand")
7126 (match_operand:SI 3 "reg_or_int_operand")]))]
7127 "TARGET_32BIT || TARGET_THUMB1"
7129 rtx op3, scratch, scratch2;
7133 if (!arm_add_operand (operands[3], SImode))
7134 operands[3] = force_reg (SImode, operands[3]);
7135 emit_insn (gen_cstore_cc (operands[0], operands[1],
7136 operands[2], operands[3]));
7140 if (operands[3] == const0_rtx)
7142 switch (GET_CODE (operands[1]))
7145 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7149 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7153 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7154 NULL_RTX, 0, OPTAB_WIDEN);
7155 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7156 NULL_RTX, 0, OPTAB_WIDEN);
7157 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7158 operands[0], 1, OPTAB_WIDEN);
7162 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7164 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7165 NULL_RTX, 1, OPTAB_WIDEN);
7169 scratch = expand_binop (SImode, ashr_optab, operands[2],
7170 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7171 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7172 NULL_RTX, 0, OPTAB_WIDEN);
7173 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7177 /* LT is handled by generic code. No need for unsigned with 0. */
7184 switch (GET_CODE (operands[1]))
7187 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7188 NULL_RTX, 0, OPTAB_WIDEN);
7189 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7193 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7194 NULL_RTX, 0, OPTAB_WIDEN);
7195 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7199 op3 = force_reg (SImode, operands[3]);
7201 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7202 NULL_RTX, 1, OPTAB_WIDEN);
7203 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7204 NULL_RTX, 0, OPTAB_WIDEN);
7205 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7211 if (!thumb1_cmp_operand (op3, SImode))
7212 op3 = force_reg (SImode, op3);
7213 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7214 NULL_RTX, 0, OPTAB_WIDEN);
7215 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7216 NULL_RTX, 1, OPTAB_WIDEN);
7217 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7222 op3 = force_reg (SImode, operands[3]);
7223 scratch = force_reg (SImode, const0_rtx);
7224 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7230 if (!thumb1_cmp_operand (op3, SImode))
7231 op3 = force_reg (SImode, op3);
7232 scratch = force_reg (SImode, const0_rtx);
7233 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7239 if (!thumb1_cmp_operand (op3, SImode))
7240 op3 = force_reg (SImode, op3);
7241 scratch = gen_reg_rtx (SImode);
7242 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7246 op3 = force_reg (SImode, operands[3]);
7247 scratch = gen_reg_rtx (SImode);
7248 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7251 /* No good sequences for GT, LT. */
7258 (define_expand "cstorehf4"
7259 [(set (match_operand:SI 0 "s_register_operand")
7260 (match_operator:SI 1 "expandable_comparison_operator"
7261 [(match_operand:HF 2 "s_register_operand")
7262 (match_operand:HF 3 "vfp_compare_operand")]))]
7263 "TARGET_VFP_FP16INST"
7265 if (!arm_validize_comparison (&operands[1],
7270 emit_insn (gen_cstore_cc (operands[0], operands[1],
7271 operands[2], operands[3]));
7276 (define_expand "cstoresf4"
7277 [(set (match_operand:SI 0 "s_register_operand")
7278 (match_operator:SI 1 "expandable_comparison_operator"
7279 [(match_operand:SF 2 "s_register_operand")
7280 (match_operand:SF 3 "vfp_compare_operand")]))]
7281 "TARGET_32BIT && TARGET_HARD_FLOAT"
7282 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7283 operands[2], operands[3])); DONE;"
7286 (define_expand "cstoredf4"
7287 [(set (match_operand:SI 0 "s_register_operand")
7288 (match_operator:SI 1 "expandable_comparison_operator"
7289 [(match_operand:DF 2 "s_register_operand")
7290 (match_operand:DF 3 "vfp_compare_operand")]))]
7291 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7292 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7293 operands[2], operands[3])); DONE;"
7296 (define_expand "cstoredi4"
7297 [(set (match_operand:SI 0 "s_register_operand")
7298 (match_operator:SI 1 "expandable_comparison_operator"
7299 [(match_operand:DI 2 "s_register_operand")
7300 (match_operand:DI 3 "cmpdi_operand")]))]
7303 if (!arm_validize_comparison (&operands[1],
7307 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7314 ;; Conditional move insns
7316 (define_expand "movsicc"
7317 [(set (match_operand:SI 0 "s_register_operand")
7318 (if_then_else:SI (match_operand 1 "expandable_comparison_operator")
7319 (match_operand:SI 2 "arm_not_operand")
7320 (match_operand:SI 3 "arm_not_operand")))]
7327 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7328 &XEXP (operands[1], 1)))
7331 code = GET_CODE (operands[1]);
7332 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7333 XEXP (operands[1], 1), NULL_RTX);
7334 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7338 (define_expand "movhfcc"
7339 [(set (match_operand:HF 0 "s_register_operand")
7340 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7341 (match_operand:HF 2 "s_register_operand")
7342 (match_operand:HF 3 "s_register_operand")))]
7343 "TARGET_VFP_FP16INST"
7346 enum rtx_code code = GET_CODE (operands[1]);
7349 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7350 &XEXP (operands[1], 1)))
7353 code = GET_CODE (operands[1]);
7354 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7355 XEXP (operands[1], 1), NULL_RTX);
7356 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7360 (define_expand "movsfcc"
7361 [(set (match_operand:SF 0 "s_register_operand")
7362 (if_then_else:SF (match_operand 1 "arm_cond_move_operator")
7363 (match_operand:SF 2 "s_register_operand")
7364 (match_operand:SF 3 "s_register_operand")))]
7365 "TARGET_32BIT && TARGET_HARD_FLOAT"
7368 enum rtx_code code = GET_CODE (operands[1]);
7371 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7372 &XEXP (operands[1], 1)))
7375 code = GET_CODE (operands[1]);
7376 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7377 XEXP (operands[1], 1), NULL_RTX);
7378 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7382 (define_expand "movdfcc"
7383 [(set (match_operand:DF 0 "s_register_operand")
7384 (if_then_else:DF (match_operand 1 "arm_cond_move_operator")
7385 (match_operand:DF 2 "s_register_operand")
7386 (match_operand:DF 3 "s_register_operand")))]
7387 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7390 enum rtx_code code = GET_CODE (operands[1]);
7393 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7394 &XEXP (operands[1], 1)))
7396 code = GET_CODE (operands[1]);
7397 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7398 XEXP (operands[1], 1), NULL_RTX);
7399 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7403 (define_insn "*cmov<mode>"
7404 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7405 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7406 [(match_operand 2 "cc_register" "") (const_int 0)])
7407 (match_operand:SDF 3 "s_register_operand"
7409 (match_operand:SDF 4 "s_register_operand"
7410 "<F_constraint>")))]
7411 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7414 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7421 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7426 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7432 [(set_attr "conds" "use")
7433 (set_attr "type" "fcsel")]
7436 (define_insn "*cmovhf"
7437 [(set (match_operand:HF 0 "s_register_operand" "=t")
7438 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7439 [(match_operand 2 "cc_register" "") (const_int 0)])
7440 (match_operand:HF 3 "s_register_operand" "t")
7441 (match_operand:HF 4 "s_register_operand" "t")))]
7442 "TARGET_VFP_FP16INST"
7445 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7452 return \"vsel%d1.f16\\t%0, %3, %4\";
7457 return \"vsel%D1.f16\\t%0, %4, %3\";
7463 [(set_attr "conds" "use")
7464 (set_attr "type" "fcsel")]
7467 (define_insn_and_split "*movsicc_insn"
7468 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7470 (match_operator 3 "arm_comparison_operator"
7471 [(match_operand 4 "cc_register" "") (const_int 0)])
7472 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7473 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7484 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7485 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7486 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7487 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7488 "&& reload_completed"
7491 enum rtx_code rev_code;
7495 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7497 gen_rtx_SET (operands[0], operands[1])));
7499 rev_code = GET_CODE (operands[3]);
7500 mode = GET_MODE (operands[4]);
7501 if (mode == CCFPmode || mode == CCFPEmode)
7502 rev_code = reverse_condition_maybe_unordered (rev_code);
7504 rev_code = reverse_condition (rev_code);
7506 rev_cond = gen_rtx_fmt_ee (rev_code,
7510 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7512 gen_rtx_SET (operands[0], operands[2])));
7515 [(set_attr "length" "4,4,4,4,8,8,8,8")
7516 (set_attr "conds" "use")
7517 (set_attr_alternative "type"
7518 [(if_then_else (match_operand 2 "const_int_operand" "")
7519 (const_string "mov_imm")
7520 (const_string "mov_reg"))
7521 (const_string "mvn_imm")
7522 (if_then_else (match_operand 1 "const_int_operand" "")
7523 (const_string "mov_imm")
7524 (const_string "mov_reg"))
7525 (const_string "mvn_imm")
7526 (const_string "multiple")
7527 (const_string "multiple")
7528 (const_string "multiple")
7529 (const_string "multiple")])]
7532 (define_insn "*movsfcc_soft_insn"
7533 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7534 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7535 [(match_operand 4 "cc_register" "") (const_int 0)])
7536 (match_operand:SF 1 "s_register_operand" "0,r")
7537 (match_operand:SF 2 "s_register_operand" "r,0")))]
7538 "TARGET_ARM && TARGET_SOFT_FLOAT"
7542 [(set_attr "conds" "use")
7543 (set_attr "type" "mov_reg")]
7547 ;; Jump and linkage insns
7549 (define_expand "jump"
7551 (label_ref (match_operand 0 "" "")))]
7556 (define_insn "*arm_jump"
7558 (label_ref (match_operand 0 "" "")))]
7562 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7564 arm_ccfsm_state += 2;
7567 return \"b%?\\t%l0\";
7570 [(set_attr "predicable" "yes")
7571 (set (attr "length")
7573 (and (match_test "TARGET_THUMB2")
7574 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7575 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7578 (set_attr "type" "branch")]
7581 (define_expand "call"
7582 [(parallel [(call (match_operand 0 "memory_operand")
7583 (match_operand 1 "general_operand"))
7584 (use (match_operand 2 "" ""))
7585 (clobber (reg:SI LR_REGNUM))])]
7590 tree addr = MEM_EXPR (operands[0]);
7592 /* In an untyped call, we can get NULL for operand 2. */
7593 if (operands[2] == NULL_RTX)
7594 operands[2] = const0_rtx;
7596 /* Decide if we should generate indirect calls by loading the
7597 32-bit address of the callee into a register before performing the
7599 callee = XEXP (operands[0], 0);
7600 if (GET_CODE (callee) == SYMBOL_REF
7601 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7603 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7605 if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[0], 0)))
7606 /* Indirect call: set r9 with FDPIC value of callee. */
7607 XEXP (operands[0], 0)
7608 = arm_load_function_descriptor (XEXP (operands[0], 0));
7610 if (detect_cmse_nonsecure_call (addr))
7612 pat = gen_nonsecure_call_internal (operands[0], operands[1],
7614 emit_call_insn (pat);
7618 pat = gen_call_internal (operands[0], operands[1], operands[2]);
7619 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7622 /* Restore FDPIC register (r9) after call. */
7625 rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
7626 rtx initial_fdpic_reg
7627 = get_hard_reg_initial_val (Pmode, FDPIC_REGNUM);
7629 emit_insn (gen_restore_pic_register_after_call (fdpic_reg,
7630 initial_fdpic_reg));
7637 (define_insn "restore_pic_register_after_call"
7638 [(set (match_operand:SI 0 "s_register_operand" "+r,r")
7639 (unspec:SI [(match_dup 0)
7640 (match_operand:SI 1 "nonimmediate_operand" "r,m")]
7641 UNSPEC_PIC_RESTORE))]
7648 (define_expand "call_internal"
7649 [(parallel [(call (match_operand 0 "memory_operand")
7650 (match_operand 1 "general_operand"))
7651 (use (match_operand 2 "" ""))
7652 (clobber (reg:SI LR_REGNUM))])])
7654 (define_expand "nonsecure_call_internal"
7655 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand")]
7656 UNSPEC_NONSECURE_MEM)
7657 (match_operand 1 "general_operand"))
7658 (use (match_operand 2 "" ""))
7659 (clobber (reg:SI LR_REGNUM))])]
7664 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
7665 gen_rtx_REG (SImode, R4_REGNUM),
7668 operands[0] = replace_equiv_address (operands[0], tmp);
7671 (define_insn "*call_reg_armv5"
7672 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7673 (match_operand 1 "" ""))
7674 (use (match_operand 2 "" ""))
7675 (clobber (reg:SI LR_REGNUM))]
7676 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
7678 [(set_attr "type" "call")]
7681 (define_insn "*call_reg_arm"
7682 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7683 (match_operand 1 "" ""))
7684 (use (match_operand 2 "" ""))
7685 (clobber (reg:SI LR_REGNUM))]
7686 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
7688 return output_call (operands);
7690 ;; length is worst case, normally it is only two
7691 [(set_attr "length" "12")
7692 (set_attr "type" "call")]
7696 (define_expand "call_value"
7697 [(parallel [(set (match_operand 0 "" "")
7698 (call (match_operand 1 "memory_operand")
7699 (match_operand 2 "general_operand")))
7700 (use (match_operand 3 "" ""))
7701 (clobber (reg:SI LR_REGNUM))])]
7706 tree addr = MEM_EXPR (operands[1]);
7708 /* In an untyped call, we can get NULL for operand 2. */
7709 if (operands[3] == 0)
7710 operands[3] = const0_rtx;
7712 /* Decide if we should generate indirect calls by loading the
7713 32-bit address of the callee into a register before performing the
7715 callee = XEXP (operands[1], 0);
7716 if (GET_CODE (callee) == SYMBOL_REF
7717 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7719 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7721 if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[1], 0)))
7722 /* Indirect call: set r9 with FDPIC value of callee. */
7723 XEXP (operands[1], 0)
7724 = arm_load_function_descriptor (XEXP (operands[1], 0));
7726 if (detect_cmse_nonsecure_call (addr))
7728 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
7729 operands[2], operands[3]);
7730 emit_call_insn (pat);
7734 pat = gen_call_value_internal (operands[0], operands[1],
7735 operands[2], operands[3]);
7736 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7739 /* Restore FDPIC register (r9) after call. */
7742 rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
7743 rtx initial_fdpic_reg
7744 = get_hard_reg_initial_val (Pmode, FDPIC_REGNUM);
7746 emit_insn (gen_restore_pic_register_after_call (fdpic_reg,
7747 initial_fdpic_reg));
7754 (define_expand "call_value_internal"
7755 [(parallel [(set (match_operand 0 "" "")
7756 (call (match_operand 1 "memory_operand")
7757 (match_operand 2 "general_operand")))
7758 (use (match_operand 3 "" ""))
7759 (clobber (reg:SI LR_REGNUM))])])
7761 (define_expand "nonsecure_call_value_internal"
7762 [(parallel [(set (match_operand 0 "" "")
7763 (call (unspec:SI [(match_operand 1 "memory_operand")]
7764 UNSPEC_NONSECURE_MEM)
7765 (match_operand 2 "general_operand")))
7766 (use (match_operand 3 "" ""))
7767 (clobber (reg:SI LR_REGNUM))])]
7772 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
7773 gen_rtx_REG (SImode, R4_REGNUM),
7776 operands[1] = replace_equiv_address (operands[1], tmp);
7779 (define_insn "*call_value_reg_armv5"
7780 [(set (match_operand 0 "" "")
7781 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7782 (match_operand 2 "" "")))
7783 (use (match_operand 3 "" ""))
7784 (clobber (reg:SI LR_REGNUM))]
7785 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
7787 [(set_attr "type" "call")]
7790 (define_insn "*call_value_reg_arm"
7791 [(set (match_operand 0 "" "")
7792 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7793 (match_operand 2 "" "")))
7794 (use (match_operand 3 "" ""))
7795 (clobber (reg:SI LR_REGNUM))]
7796 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
7798 return output_call (&operands[1]);
7800 [(set_attr "length" "12")
7801 (set_attr "type" "call")]
7804 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7805 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7807 (define_insn "*call_symbol"
7808 [(call (mem:SI (match_operand:SI 0 "" ""))
7809 (match_operand 1 "" ""))
7810 (use (match_operand 2 "" ""))
7811 (clobber (reg:SI LR_REGNUM))]
7813 && !SIBLING_CALL_P (insn)
7814 && (GET_CODE (operands[0]) == SYMBOL_REF)
7815 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7818 rtx op = operands[0];
7820 /* Switch mode now when possible. */
7821 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7822 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7823 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7825 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7827 [(set_attr "type" "call")]
7830 (define_insn "*call_value_symbol"
7831 [(set (match_operand 0 "" "")
7832 (call (mem:SI (match_operand:SI 1 "" ""))
7833 (match_operand:SI 2 "" "")))
7834 (use (match_operand 3 "" ""))
7835 (clobber (reg:SI LR_REGNUM))]
7837 && !SIBLING_CALL_P (insn)
7838 && (GET_CODE (operands[1]) == SYMBOL_REF)
7839 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7842 rtx op = operands[1];
7844 /* Switch mode now when possible. */
7845 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7846 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7847 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
7849 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7851 [(set_attr "type" "call")]
7854 (define_expand "sibcall_internal"
7855 [(parallel [(call (match_operand 0 "memory_operand")
7856 (match_operand 1 "general_operand"))
7858 (use (match_operand 2 "" ""))])])
7860 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7861 (define_expand "sibcall"
7862 [(parallel [(call (match_operand 0 "memory_operand")
7863 (match_operand 1 "general_operand"))
7865 (use (match_operand 2 "" ""))])]
7871 if ((!REG_P (XEXP (operands[0], 0))
7872 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7873 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7874 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7875 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7877 if (operands[2] == NULL_RTX)
7878 operands[2] = const0_rtx;
7880 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7881 arm_emit_call_insn (pat, operands[0], true);
7886 (define_expand "sibcall_value_internal"
7887 [(parallel [(set (match_operand 0 "" "")
7888 (call (match_operand 1 "memory_operand")
7889 (match_operand 2 "general_operand")))
7891 (use (match_operand 3 "" ""))])])
7893 (define_expand "sibcall_value"
7894 [(parallel [(set (match_operand 0 "" "")
7895 (call (match_operand 1 "memory_operand")
7896 (match_operand 2 "general_operand")))
7898 (use (match_operand 3 "" ""))])]
7904 if ((!REG_P (XEXP (operands[1], 0))
7905 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7906 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7907 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7908 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7910 if (operands[3] == NULL_RTX)
7911 operands[3] = const0_rtx;
7913 pat = gen_sibcall_value_internal (operands[0], operands[1],
7914 operands[2], operands[3]);
7915 arm_emit_call_insn (pat, operands[1], true);
7920 (define_insn "*sibcall_insn"
7921 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7922 (match_operand 1 "" ""))
7924 (use (match_operand 2 "" ""))]
7925 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7927 if (which_alternative == 1)
7928 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7931 if (arm_arch5t || arm_arch4t)
7932 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7934 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7937 [(set_attr "type" "call")]
7940 (define_insn "*sibcall_value_insn"
7941 [(set (match_operand 0 "" "")
7942 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7943 (match_operand 2 "" "")))
7945 (use (match_operand 3 "" ""))]
7946 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7948 if (which_alternative == 1)
7949 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7952 if (arm_arch5t || arm_arch4t)
7953 return \"bx%?\\t%1\";
7955 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7958 [(set_attr "type" "call")]
7961 (define_expand "<return_str>return"
7963 "(TARGET_ARM || (TARGET_THUMB2
7964 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7965 && !IS_STACKALIGN (arm_current_func_type ())))
7966 <return_cond_false>"
7971 thumb2_expand_return (<return_simple_p>);
7978 ;; Often the return insn will be the same as loading from memory, so set attr
7979 (define_insn "*arm_return"
7981 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7984 if (arm_ccfsm_state == 2)
7986 arm_ccfsm_state += 2;
7989 return output_return_instruction (const_true_rtx, true, false, false);
7991 [(set_attr "type" "load_4")
7992 (set_attr "length" "12")
7993 (set_attr "predicable" "yes")]
7996 (define_insn "*cond_<return_str>return"
7998 (if_then_else (match_operator 0 "arm_comparison_operator"
7999 [(match_operand 1 "cc_register" "") (const_int 0)])
8002 "TARGET_ARM <return_cond_true>"
8005 if (arm_ccfsm_state == 2)
8007 arm_ccfsm_state += 2;
8010 return output_return_instruction (operands[0], true, false,
8013 [(set_attr "conds" "use")
8014 (set_attr "length" "12")
8015 (set_attr "type" "load_4")]
8018 (define_insn "*cond_<return_str>return_inverted"
8020 (if_then_else (match_operator 0 "arm_comparison_operator"
8021 [(match_operand 1 "cc_register" "") (const_int 0)])
8024 "TARGET_ARM <return_cond_true>"
8027 if (arm_ccfsm_state == 2)
8029 arm_ccfsm_state += 2;
8032 return output_return_instruction (operands[0], true, true,
8035 [(set_attr "conds" "use")
8036 (set_attr "length" "12")
8037 (set_attr "type" "load_4")]
8040 (define_insn "*arm_simple_return"
8045 if (arm_ccfsm_state == 2)
8047 arm_ccfsm_state += 2;
8050 return output_return_instruction (const_true_rtx, true, false, true);
8052 [(set_attr "type" "branch")
8053 (set_attr "length" "4")
8054 (set_attr "predicable" "yes")]
8057 ;; Generate a sequence of instructions to determine if the processor is
8058 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8061 (define_expand "return_addr_mask"
8063 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8065 (set (match_operand:SI 0 "s_register_operand")
8066 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8068 (const_int 67108860)))] ; 0x03fffffc
8071 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8074 (define_insn "*check_arch2"
8075 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8076 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8079 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8080 [(set_attr "length" "8")
8081 (set_attr "conds" "set")
8082 (set_attr "type" "multiple")]
8085 ;; Call subroutine returning any type.
8087 (define_expand "untyped_call"
8088 [(parallel [(call (match_operand 0 "" "")
8090 (match_operand 1 "" "")
8091 (match_operand 2 "" "")])]
8092 "TARGET_EITHER && !TARGET_FDPIC"
8096 rtx par = gen_rtx_PARALLEL (VOIDmode,
8097 rtvec_alloc (XVECLEN (operands[2], 0)));
8098 rtx addr = gen_reg_rtx (Pmode);
8102 emit_move_insn (addr, XEXP (operands[1], 0));
8103 mem = change_address (operands[1], BLKmode, addr);
8105 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8107 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8109 /* Default code only uses r0 as a return value, but we could
8110 be using anything up to 4 registers. */
8111 if (REGNO (src) == R0_REGNUM)
8112 src = gen_rtx_REG (TImode, R0_REGNUM);
8114 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8116 size += GET_MODE_SIZE (GET_MODE (src));
8119 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8123 for (i = 0; i < XVECLEN (par, 0); i++)
8125 HOST_WIDE_INT offset = 0;
8126 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8129 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8131 mem = change_address (mem, GET_MODE (reg), NULL);
8132 if (REGNO (reg) == R0_REGNUM)
8134 /* On thumb we have to use a write-back instruction. */
8135 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8136 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8137 size = TARGET_ARM ? 16 : 0;
8141 emit_move_insn (mem, reg);
8142 size = GET_MODE_SIZE (GET_MODE (reg));
8146 /* The optimizer does not know that the call sets the function value
8147 registers we stored in the result block. We avoid problems by
8148 claiming that all hard registers are used and clobbered at this
8150 emit_insn (gen_blockage ());
8156 (define_expand "untyped_return"
8157 [(match_operand:BLK 0 "memory_operand")
8158 (match_operand 1 "" "")]
8159 "TARGET_EITHER && !TARGET_FDPIC"
8163 rtx addr = gen_reg_rtx (Pmode);
8167 emit_move_insn (addr, XEXP (operands[0], 0));
8168 mem = change_address (operands[0], BLKmode, addr);
8170 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8172 HOST_WIDE_INT offset = 0;
8173 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8176 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8178 mem = change_address (mem, GET_MODE (reg), NULL);
8179 if (REGNO (reg) == R0_REGNUM)
8181 /* On thumb we have to use a write-back instruction. */
8182 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8183 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8184 size = TARGET_ARM ? 16 : 0;
8188 emit_move_insn (reg, mem);
8189 size = GET_MODE_SIZE (GET_MODE (reg));
8193 /* Emit USE insns before the return. */
8194 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8195 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8197 /* Construct the return. */
8198 expand_naked_return ();
8204 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8205 ;; all of memory. This blocks insns from being moved across this point.
8207 (define_insn "blockage"
8208 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8211 [(set_attr "length" "0")
8212 (set_attr "type" "block")]
8215 ;; Since we hard code r0 here use the 'o' constraint to prevent
8216 ;; provoking undefined behaviour in the hardware with putting out
8217 ;; auto-increment operations with potentially r0 as the base register.
8218 (define_insn "probe_stack"
8219 [(set (match_operand:SI 0 "memory_operand" "=o")
8220 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8223 [(set_attr "type" "store_4")
8224 (set_attr "predicable" "yes")]
8227 (define_insn "probe_stack_range"
8228 [(set (match_operand:SI 0 "register_operand" "=r")
8229 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8230 (match_operand:SI 2 "register_operand" "r")]
8231 VUNSPEC_PROBE_STACK_RANGE))]
8234 return output_probe_stack_range (operands[0], operands[2]);
8236 [(set_attr "type" "multiple")
8237 (set_attr "conds" "clob")]
8240 ;; Named patterns for stack smashing protection.
8241 (define_expand "stack_protect_combined_set"
8243 [(set (match_operand:SI 0 "memory_operand")
8244 (unspec:SI [(match_operand:SI 1 "guard_operand")]
8246 (clobber (match_scratch:SI 2 ""))
8247 (clobber (match_scratch:SI 3 ""))])]
8252 ;; Use a separate insn from the above expand to be able to have the mem outside
8253 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8254 ;; try to reload the guard since we need to control how PIC access is done in
8255 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8256 ;; legitimize_pic_address ()).
8257 (define_insn_and_split "*stack_protect_combined_set_insn"
8258 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8259 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8261 (clobber (match_scratch:SI 2 "=&l,&r"))
8262 (clobber (match_scratch:SI 3 "=&l,&r"))]
8266 [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))]
8268 (clobber (match_dup 2))])]
8276 pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
8278 pic_reg = operands[3];
8280 /* Forces recomputing of GOT base now. */
8281 legitimize_pic_address (operands[1], SImode, operands[2], pic_reg,
8282 true /*compute_now*/);
8286 if (address_operand (operands[1], SImode))
8287 operands[2] = operands[1];
8290 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8291 emit_move_insn (operands[2], mem);
8295 [(set_attr "arch" "t1,32")]
8298 ;; DO NOT SPLIT THIS INSN. It's important for security reasons that the
8299 ;; canary value does not live beyond the life of this sequence.
8300 (define_insn "*stack_protect_set_insn"
8301 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8302 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))]
8304 (clobber (match_dup 1))]
8307 ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1, #0
8308 ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1, #0"
8309 [(set_attr "length" "8,12")
8310 (set_attr "conds" "clob,nocond")
8311 (set_attr "type" "multiple")
8312 (set_attr "arch" "t1,32")]
8315 (define_expand "stack_protect_combined_test"
8319 (eq (match_operand:SI 0 "memory_operand")
8320 (unspec:SI [(match_operand:SI 1 "guard_operand")]
8322 (label_ref (match_operand 2))
8324 (clobber (match_scratch:SI 3 ""))
8325 (clobber (match_scratch:SI 4 ""))
8326 (clobber (reg:CC CC_REGNUM))])]
8331 ;; Use a separate insn from the above expand to be able to have the mem outside
8332 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8333 ;; try to reload the guard since we need to control how PIC access is done in
8334 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8335 ;; legitimize_pic_address ()).
8336 (define_insn_and_split "*stack_protect_combined_test_insn"
8339 (eq (match_operand:SI 0 "memory_operand" "m,m")
8340 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8342 (label_ref (match_operand 2))
8344 (clobber (match_scratch:SI 3 "=&l,&r"))
8345 (clobber (match_scratch:SI 4 "=&l,&r"))
8346 (clobber (reg:CC CC_REGNUM))]
8359 pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
8361 pic_reg = operands[4];
8363 /* Forces recomputing of GOT base now. */
8364 legitimize_pic_address (operands[1], SImode, operands[3], pic_reg,
8365 true /*compute_now*/);
8369 if (address_operand (operands[1], SImode))
8370 operands[3] = operands[1];
8373 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8374 emit_move_insn (operands[3], mem);
8379 emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0],
8381 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
8382 eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx);
8383 emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg));
8387 emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0],
8389 eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
8390 emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx,
8395 [(set_attr "arch" "t1,32")]
8398 (define_insn "arm_stack_protect_test_insn"
8399 [(set (reg:CC_Z CC_REGNUM)
8400 (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m")
8401 (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))]
8404 (clobber (match_operand:SI 0 "register_operand" "=&l,&r"))
8405 (clobber (match_dup 2))]
8407 "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0"
8408 [(set_attr "length" "8,12")
8409 (set_attr "conds" "set")
8410 (set_attr "type" "multiple")
8411 (set_attr "arch" "t,32")]
8414 (define_expand "casesi"
8415 [(match_operand:SI 0 "s_register_operand") ; index to jump on
8416 (match_operand:SI 1 "const_int_operand") ; lower bound
8417 (match_operand:SI 2 "const_int_operand") ; total range
8418 (match_operand:SI 3 "" "") ; table label
8419 (match_operand:SI 4 "" "")] ; Out of range label
8420 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8423 enum insn_code code;
8424 if (operands[1] != const0_rtx)
8426 rtx reg = gen_reg_rtx (SImode);
8428 emit_insn (gen_addsi3 (reg, operands[0],
8429 gen_int_mode (-INTVAL (operands[1]),
8435 code = CODE_FOR_arm_casesi_internal;
8436 else if (TARGET_THUMB1)
8437 code = CODE_FOR_thumb1_casesi_internal_pic;
8439 code = CODE_FOR_thumb2_casesi_internal_pic;
8441 code = CODE_FOR_thumb2_casesi_internal;
8443 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8444 operands[2] = force_reg (SImode, operands[2]);
8446 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8447 operands[3], operands[4]));
8452 ;; The USE in this pattern is needed to tell flow analysis that this is
8453 ;; a CASESI insn. It has no other purpose.
8454 (define_expand "arm_casesi_internal"
8455 [(parallel [(set (pc)
8457 (leu (match_operand:SI 0 "s_register_operand")
8458 (match_operand:SI 1 "arm_rhs_operand"))
8460 (label_ref:SI (match_operand 3 ""))))
8461 (clobber (reg:CC CC_REGNUM))
8462 (use (label_ref:SI (match_operand 2 "")))])]
8465 operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
8466 operands[4] = gen_rtx_PLUS (SImode, operands[4],
8467 gen_rtx_LABEL_REF (SImode, operands[2]));
8468 operands[4] = gen_rtx_MEM (SImode, operands[4]);
8469 MEM_READONLY_P (operands[4]) = 1;
8470 MEM_NOTRAP_P (operands[4]) = 1;
8473 (define_insn "*arm_casesi_internal"
8474 [(parallel [(set (pc)
8476 (leu (match_operand:SI 0 "s_register_operand" "r")
8477 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8478 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8479 (label_ref:SI (match_operand 2 "" ""))))
8480 (label_ref:SI (match_operand 3 "" ""))))
8481 (clobber (reg:CC CC_REGNUM))
8482 (use (label_ref:SI (match_dup 2)))])]
8486 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8487 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8489 [(set_attr "conds" "clob")
8490 (set_attr "length" "12")
8491 (set_attr "type" "multiple")]
8494 (define_expand "indirect_jump"
8496 (match_operand:SI 0 "s_register_operand"))]
8499 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8500 address and use bx. */
8504 tmp = gen_reg_rtx (SImode);
8505 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8511 ;; NB Never uses BX.
8512 (define_insn "*arm_indirect_jump"
8514 (match_operand:SI 0 "s_register_operand" "r"))]
8516 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8517 [(set_attr "predicable" "yes")
8518 (set_attr "type" "branch")]
8521 (define_insn "*load_indirect_jump"
8523 (match_operand:SI 0 "memory_operand" "m"))]
8525 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8526 [(set_attr "type" "load_4")
8527 (set_attr "pool_range" "4096")
8528 (set_attr "neg_pool_range" "4084")
8529 (set_attr "predicable" "yes")]
8539 [(set (attr "length")
8540 (if_then_else (eq_attr "is_thumb" "yes")
8543 (set_attr "type" "mov_reg")]
8547 [(trap_if (const_int 1) (const_int 0))]
8551 return \".inst\\t0xe7f000f0\";
8553 return \".inst\\t0xdeff\";
8555 [(set (attr "length")
8556 (if_then_else (eq_attr "is_thumb" "yes")
8559 (set_attr "type" "trap")
8560 (set_attr "conds" "unconditional")]
8564 ;; Patterns to allow combination of arithmetic, cond code and shifts
8566 (define_insn "*<arith_shift_insn>_multsi"
8567 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8569 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8570 (match_operand:SI 3 "power_of_two_operand" ""))
8571 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8573 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8574 [(set_attr "predicable" "yes")
8575 (set_attr "shift" "2")
8576 (set_attr "arch" "a,t2")
8577 (set_attr "type" "alu_shift_imm")])
8579 (define_insn "*<arith_shift_insn>_shiftsi"
8580 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8582 (match_operator:SI 2 "shift_nomul_operator"
8583 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8584 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8585 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8586 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8587 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8588 [(set_attr "predicable" "yes")
8589 (set_attr "shift" "3")
8590 (set_attr "arch" "a,t2,a")
8591 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8594 [(set (match_operand:SI 0 "s_register_operand" "")
8595 (match_operator:SI 1 "shiftable_operator"
8596 [(match_operator:SI 2 "shiftable_operator"
8597 [(match_operator:SI 3 "shift_operator"
8598 [(match_operand:SI 4 "s_register_operand" "")
8599 (match_operand:SI 5 "reg_or_int_operand" "")])
8600 (match_operand:SI 6 "s_register_operand" "")])
8601 (match_operand:SI 7 "arm_rhs_operand" "")]))
8602 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8605 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8608 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8611 (define_insn "*arith_shiftsi_compare0"
8612 [(set (reg:CC_NOOV CC_REGNUM)
8614 (match_operator:SI 1 "shiftable_operator"
8615 [(match_operator:SI 3 "shift_operator"
8616 [(match_operand:SI 4 "s_register_operand" "r,r")
8617 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8618 (match_operand:SI 2 "s_register_operand" "r,r")])
8620 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8621 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8624 "%i1s%?\\t%0, %2, %4%S3"
8625 [(set_attr "conds" "set")
8626 (set_attr "shift" "4")
8627 (set_attr "arch" "32,a")
8628 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8630 (define_insn "*arith_shiftsi_compare0_scratch"
8631 [(set (reg:CC_NOOV CC_REGNUM)
8633 (match_operator:SI 1 "shiftable_operator"
8634 [(match_operator:SI 3 "shift_operator"
8635 [(match_operand:SI 4 "s_register_operand" "r,r")
8636 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8637 (match_operand:SI 2 "s_register_operand" "r,r")])
8639 (clobber (match_scratch:SI 0 "=r,r"))]
8641 "%i1s%?\\t%0, %2, %4%S3"
8642 [(set_attr "conds" "set")
8643 (set_attr "shift" "4")
8644 (set_attr "arch" "32,a")
8645 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8647 (define_insn "*sub_shiftsi"
8648 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8649 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8650 (match_operator:SI 2 "shift_operator"
8651 [(match_operand:SI 3 "s_register_operand" "r,r")
8652 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8654 "sub%?\\t%0, %1, %3%S2"
8655 [(set_attr "predicable" "yes")
8656 (set_attr "predicable_short_it" "no")
8657 (set_attr "shift" "3")
8658 (set_attr "arch" "32,a")
8659 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8661 (define_insn "*sub_shiftsi_compare0"
8662 [(set (reg:CC_NOOV CC_REGNUM)
8664 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8665 (match_operator:SI 2 "shift_operator"
8666 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8667 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8669 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8670 (minus:SI (match_dup 1)
8671 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8673 "subs%?\\t%0, %1, %3%S2"
8674 [(set_attr "conds" "set")
8675 (set_attr "shift" "3")
8676 (set_attr "arch" "32,a,a")
8677 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8679 (define_insn "*sub_shiftsi_compare0_scratch"
8680 [(set (reg:CC_NOOV CC_REGNUM)
8682 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8683 (match_operator:SI 2 "shift_operator"
8684 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8685 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8687 (clobber (match_scratch:SI 0 "=r,r,r"))]
8689 "subs%?\\t%0, %1, %3%S2"
8690 [(set_attr "conds" "set")
8691 (set_attr "shift" "3")
8692 (set_attr "arch" "32,a,a")
8693 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8696 (define_insn_and_split "*and_scc"
8697 [(set (match_operand:SI 0 "s_register_operand" "=r")
8698 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8699 [(match_operand 2 "cc_register" "") (const_int 0)])
8700 (match_operand:SI 3 "s_register_operand" "r")))]
8702 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8703 "&& reload_completed"
8704 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8705 (cond_exec (match_dup 4) (set (match_dup 0)
8706 (and:SI (match_dup 3) (const_int 1))))]
8708 machine_mode mode = GET_MODE (operands[2]);
8709 enum rtx_code rc = GET_CODE (operands[1]);
8711 /* Note that operands[4] is the same as operands[1],
8712 but with VOIDmode as the result. */
8713 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8714 if (mode == CCFPmode || mode == CCFPEmode)
8715 rc = reverse_condition_maybe_unordered (rc);
8717 rc = reverse_condition (rc);
8718 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8720 [(set_attr "conds" "use")
8721 (set_attr "type" "multiple")
8722 (set_attr "length" "8")]
8725 (define_insn_and_split "*ior_scc"
8726 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8727 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8728 [(match_operand 2 "cc_register" "") (const_int 0)])
8729 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8734 "&& reload_completed
8735 && REGNO (operands [0]) != REGNO (operands[3])"
8736 ;; && which_alternative == 1
8737 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8738 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8739 (cond_exec (match_dup 4) (set (match_dup 0)
8740 (ior:SI (match_dup 3) (const_int 1))))]
8742 machine_mode mode = GET_MODE (operands[2]);
8743 enum rtx_code rc = GET_CODE (operands[1]);
8745 /* Note that operands[4] is the same as operands[1],
8746 but with VOIDmode as the result. */
8747 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8748 if (mode == CCFPmode || mode == CCFPEmode)
8749 rc = reverse_condition_maybe_unordered (rc);
8751 rc = reverse_condition (rc);
8752 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8754 [(set_attr "conds" "use")
8755 (set_attr "length" "4,8")
8756 (set_attr "type" "logic_imm,multiple")]
8759 ; A series of splitters for the compare_scc pattern below. Note that
8760 ; order is important.
8762 [(set (match_operand:SI 0 "s_register_operand" "")
8763 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8765 (clobber (reg:CC CC_REGNUM))]
8766 "TARGET_32BIT && reload_completed"
8767 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8770 [(set (match_operand:SI 0 "s_register_operand" "")
8771 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8773 (clobber (reg:CC CC_REGNUM))]
8774 "TARGET_32BIT && reload_completed"
8775 [(set (match_dup 0) (not:SI (match_dup 1)))
8776 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8779 [(set (match_operand:SI 0 "s_register_operand" "")
8780 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8782 (clobber (reg:CC CC_REGNUM))]
8783 "arm_arch5t && TARGET_32BIT"
8784 [(set (match_dup 0) (clz:SI (match_dup 1)))
8785 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8789 [(set (match_operand:SI 0 "s_register_operand" "")
8790 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8792 (clobber (reg:CC CC_REGNUM))]
8793 "TARGET_32BIT && reload_completed"
8795 [(set (reg:CC CC_REGNUM)
8796 (compare:CC (const_int 1) (match_dup 1)))
8798 (minus:SI (const_int 1) (match_dup 1)))])
8799 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8800 (set (match_dup 0) (const_int 0)))])
8803 [(set (match_operand:SI 0 "s_register_operand" "")
8804 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8805 (match_operand:SI 2 "const_int_operand" "")))
8806 (clobber (reg:CC CC_REGNUM))]
8807 "TARGET_32BIT && reload_completed"
8809 [(set (reg:CC CC_REGNUM)
8810 (compare:CC (match_dup 1) (match_dup 2)))
8811 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8812 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8813 (set (match_dup 0) (const_int 1)))]
8815 operands[3] = gen_int_mode (-INTVAL (operands[2]), SImode);
8819 [(set (match_operand:SI 0 "s_register_operand" "")
8820 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8821 (match_operand:SI 2 "arm_add_operand" "")))
8822 (clobber (reg:CC CC_REGNUM))]
8823 "TARGET_32BIT && reload_completed"
8825 [(set (reg:CC_NOOV CC_REGNUM)
8826 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8828 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8829 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8830 (set (match_dup 0) (const_int 1)))])
8832 (define_insn_and_split "*compare_scc"
8833 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8834 (match_operator:SI 1 "arm_comparison_operator"
8835 [(match_operand:SI 2 "s_register_operand" "r,r")
8836 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8837 (clobber (reg:CC CC_REGNUM))]
8840 "&& reload_completed"
8841 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8842 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8843 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8846 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8847 operands[2], operands[3]);
8848 enum rtx_code rc = GET_CODE (operands[1]);
8850 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8852 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8853 if (mode == CCFPmode || mode == CCFPEmode)
8854 rc = reverse_condition_maybe_unordered (rc);
8856 rc = reverse_condition (rc);
8857 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8859 [(set_attr "type" "multiple")]
8862 ;; Attempt to improve the sequence generated by the compare_scc splitters
8863 ;; not to use conditional execution.
8865 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
8869 [(set (reg:CC CC_REGNUM)
8870 (compare:CC (match_operand:SI 1 "register_operand" "")
8872 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8873 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8874 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8875 (set (match_dup 0) (const_int 1)))]
8876 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8877 [(set (match_dup 0) (clz:SI (match_dup 1)))
8878 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8881 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8885 [(set (reg:CC CC_REGNUM)
8886 (compare:CC (match_operand:SI 1 "register_operand" "")
8888 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8889 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8890 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8891 (set (match_dup 0) (const_int 1)))
8892 (match_scratch:SI 2 "r")]
8893 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8895 [(set (reg:CC CC_REGNUM)
8896 (compare:CC (const_int 0) (match_dup 1)))
8897 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8899 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8900 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8903 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
8904 ;; sub Rd, Reg1, reg2
8908 [(set (reg:CC CC_REGNUM)
8909 (compare:CC (match_operand:SI 1 "register_operand" "")
8910 (match_operand:SI 2 "arm_rhs_operand" "")))
8911 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8912 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8913 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8914 (set (match_dup 0) (const_int 1)))]
8915 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8916 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8917 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8918 (set (match_dup 0) (clz:SI (match_dup 0)))
8919 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8923 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
8924 ;; sub T1, Reg1, reg2
8928 [(set (reg:CC CC_REGNUM)
8929 (compare:CC (match_operand:SI 1 "register_operand" "")
8930 (match_operand:SI 2 "arm_rhs_operand" "")))
8931 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8932 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8933 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8934 (set (match_dup 0) (const_int 1)))
8935 (match_scratch:SI 3 "r")]
8936 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8937 [(set (match_dup 3) (match_dup 4))
8939 [(set (reg:CC CC_REGNUM)
8940 (compare:CC (const_int 0) (match_dup 3)))
8941 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8943 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8944 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8946 if (CONST_INT_P (operands[2]))
8947 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8949 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8952 (define_insn "*cond_move"
8953 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8954 (if_then_else:SI (match_operator 3 "equality_operator"
8955 [(match_operator 4 "arm_comparison_operator"
8956 [(match_operand 5 "cc_register" "") (const_int 0)])
8958 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8959 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8962 if (GET_CODE (operands[3]) == NE)
8964 if (which_alternative != 1)
8965 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8966 if (which_alternative != 0)
8967 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8970 if (which_alternative != 0)
8971 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8972 if (which_alternative != 1)
8973 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8976 [(set_attr "conds" "use")
8977 (set_attr_alternative "type"
8978 [(if_then_else (match_operand 2 "const_int_operand" "")
8979 (const_string "mov_imm")
8980 (const_string "mov_reg"))
8981 (if_then_else (match_operand 1 "const_int_operand" "")
8982 (const_string "mov_imm")
8983 (const_string "mov_reg"))
8984 (const_string "multiple")])
8985 (set_attr "length" "4,4,8")]
8988 (define_insn "*cond_arith"
8989 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8990 (match_operator:SI 5 "shiftable_operator"
8991 [(match_operator:SI 4 "arm_comparison_operator"
8992 [(match_operand:SI 2 "s_register_operand" "r,r")
8993 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8994 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8995 (clobber (reg:CC CC_REGNUM))]
8998 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8999 return \"%i5\\t%0, %1, %2, lsr #31\";
9001 output_asm_insn (\"cmp\\t%2, %3\", operands);
9002 if (GET_CODE (operands[5]) == AND)
9003 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9004 else if (GET_CODE (operands[5]) == MINUS)
9005 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9006 else if (which_alternative != 0)
9007 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9008 return \"%i5%d4\\t%0, %1, #1\";
9010 [(set_attr "conds" "clob")
9011 (set_attr "length" "12")
9012 (set_attr "type" "multiple")]
9015 (define_insn "*cond_sub"
9016 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9017 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9018 (match_operator:SI 4 "arm_comparison_operator"
9019 [(match_operand:SI 2 "s_register_operand" "r,r")
9020 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9021 (clobber (reg:CC CC_REGNUM))]
9024 output_asm_insn (\"cmp\\t%2, %3\", operands);
9025 if (which_alternative != 0)
9026 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9027 return \"sub%d4\\t%0, %1, #1\";
9029 [(set_attr "conds" "clob")
9030 (set_attr "length" "8,12")
9031 (set_attr "type" "multiple")]
9034 (define_insn "*cmp_ite0"
9035 [(set (match_operand 6 "dominant_cc_register" "")
9038 (match_operator 4 "arm_comparison_operator"
9039 [(match_operand:SI 0 "s_register_operand"
9040 "l,l,l,r,r,r,r,r,r")
9041 (match_operand:SI 1 "arm_add_operand"
9042 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9043 (match_operator:SI 5 "arm_comparison_operator"
9044 [(match_operand:SI 2 "s_register_operand"
9045 "l,r,r,l,l,r,r,r,r")
9046 (match_operand:SI 3 "arm_add_operand"
9047 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9053 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9055 {\"cmp%d5\\t%0, %1\",
9056 \"cmp%d4\\t%2, %3\"},
9057 {\"cmn%d5\\t%0, #%n1\",
9058 \"cmp%d4\\t%2, %3\"},
9059 {\"cmp%d5\\t%0, %1\",
9060 \"cmn%d4\\t%2, #%n3\"},
9061 {\"cmn%d5\\t%0, #%n1\",
9062 \"cmn%d4\\t%2, #%n3\"}
9064 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9069 \"cmn\\t%0, #%n1\"},
9070 {\"cmn\\t%2, #%n3\",
9072 {\"cmn\\t%2, #%n3\",
9075 static const char * const ite[2] =
9080 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9081 CMP_CMP, CMN_CMP, CMP_CMP,
9082 CMN_CMP, CMP_CMN, CMN_CMN};
9084 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9086 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9087 if (TARGET_THUMB2) {
9088 output_asm_insn (ite[swap], operands);
9090 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9093 [(set_attr "conds" "set")
9094 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9095 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9096 (set_attr "type" "multiple")
9097 (set_attr_alternative "length"
9103 (if_then_else (eq_attr "is_thumb" "no")
9106 (if_then_else (eq_attr "is_thumb" "no")
9109 (if_then_else (eq_attr "is_thumb" "no")
9112 (if_then_else (eq_attr "is_thumb" "no")
9117 (define_insn "*cmp_ite1"
9118 [(set (match_operand 6 "dominant_cc_register" "")
9121 (match_operator 4 "arm_comparison_operator"
9122 [(match_operand:SI 0 "s_register_operand"
9123 "l,l,l,r,r,r,r,r,r")
9124 (match_operand:SI 1 "arm_add_operand"
9125 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9126 (match_operator:SI 5 "arm_comparison_operator"
9127 [(match_operand:SI 2 "s_register_operand"
9128 "l,r,r,l,l,r,r,r,r")
9129 (match_operand:SI 3 "arm_add_operand"
9130 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9136 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9140 {\"cmn\\t%0, #%n1\",
9143 \"cmn\\t%2, #%n3\"},
9144 {\"cmn\\t%0, #%n1\",
9147 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9149 {\"cmp%d4\\t%2, %3\",
9150 \"cmp%D5\\t%0, %1\"},
9151 {\"cmp%d4\\t%2, %3\",
9152 \"cmn%D5\\t%0, #%n1\"},
9153 {\"cmn%d4\\t%2, #%n3\",
9154 \"cmp%D5\\t%0, %1\"},
9155 {\"cmn%d4\\t%2, #%n3\",
9156 \"cmn%D5\\t%0, #%n1\"}
9158 static const char * const ite[2] =
9163 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9164 CMP_CMP, CMN_CMP, CMP_CMP,
9165 CMN_CMP, CMP_CMN, CMN_CMN};
9167 comparison_dominates_p (GET_CODE (operands[5]),
9168 reverse_condition (GET_CODE (operands[4])));
9170 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9171 if (TARGET_THUMB2) {
9172 output_asm_insn (ite[swap], operands);
9174 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9177 [(set_attr "conds" "set")
9178 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9179 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9180 (set_attr_alternative "length"
9186 (if_then_else (eq_attr "is_thumb" "no")
9189 (if_then_else (eq_attr "is_thumb" "no")
9192 (if_then_else (eq_attr "is_thumb" "no")
9195 (if_then_else (eq_attr "is_thumb" "no")
9198 (set_attr "type" "multiple")]
9201 (define_insn "*cmp_and"
9202 [(set (match_operand 6 "dominant_cc_register" "")
9205 (match_operator 4 "arm_comparison_operator"
9206 [(match_operand:SI 0 "s_register_operand"
9207 "l,l,l,r,r,r,r,r,r,r")
9208 (match_operand:SI 1 "arm_add_operand"
9209 "lPy,lPy,lPy,rI,L,r,rI,L,rI,L")])
9210 (match_operator:SI 5 "arm_comparison_operator"
9211 [(match_operand:SI 2 "s_register_operand"
9212 "l,r,r,l,l,r,r,r,r,r")
9213 (match_operand:SI 3 "arm_add_operand"
9214 "lPy,rI,L,lPy,lPy,r,rI,rI,L,L")]))
9219 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9221 {\"cmp%d5\\t%0, %1\",
9222 \"cmp%d4\\t%2, %3\"},
9223 {\"cmn%d5\\t%0, #%n1\",
9224 \"cmp%d4\\t%2, %3\"},
9225 {\"cmp%d5\\t%0, %1\",
9226 \"cmn%d4\\t%2, #%n3\"},
9227 {\"cmn%d5\\t%0, #%n1\",
9228 \"cmn%d4\\t%2, #%n3\"}
9230 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9235 \"cmn\\t%0, #%n1\"},
9236 {\"cmn\\t%2, #%n3\",
9238 {\"cmn\\t%2, #%n3\",
9241 static const char *const ite[2] =
9246 static const int cmp_idx[] = {CMP_CMP, CMP_CMP, CMP_CMN,
9247 CMP_CMP, CMN_CMP, CMP_CMP,
9248 CMP_CMP, CMN_CMP, CMP_CMN,
9251 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9253 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9254 if (TARGET_THUMB2) {
9255 output_asm_insn (ite[swap], operands);
9257 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9260 [(set_attr "conds" "set")
9261 (set_attr "predicable" "no")
9262 (set_attr "arch" "t2,t2,t2,t2,t2,t2,any,any,any,any")
9263 (set_attr "enabled_for_short_it" "yes,no,no,no,no,yes,no,no,no,no")
9264 (set_attr_alternative "length"
9271 (if_then_else (eq_attr "is_thumb" "no")
9274 (if_then_else (eq_attr "is_thumb" "no")
9277 (if_then_else (eq_attr "is_thumb" "no")
9280 (if_then_else (eq_attr "is_thumb" "no")
9283 (set_attr "type" "multiple")]
9286 (define_insn "*cmp_ior"
9287 [(set (match_operand 6 "dominant_cc_register" "")
9290 (match_operator 4 "arm_comparison_operator"
9291 [(match_operand:SI 0 "s_register_operand"
9292 "l,l,l,r,r,r,r,r,r,r")
9293 (match_operand:SI 1 "arm_add_operand"
9294 "lPy,lPy,lPy,rI,L,r,rI,L,rI,L")])
9295 (match_operator:SI 5 "arm_comparison_operator"
9296 [(match_operand:SI 2 "s_register_operand"
9297 "l,r,r,l,l,r,r,r,r,r")
9298 (match_operand:SI 3 "arm_add_operand"
9299 "lPy,rI,L,lPy,lPy,r,rI,rI,L,L")]))
9304 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9308 {\"cmn\\t%0, #%n1\",
9311 \"cmn\\t%2, #%n3\"},
9312 {\"cmn\\t%0, #%n1\",
9315 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9317 {\"cmp%D4\\t%2, %3\",
9318 \"cmp%D5\\t%0, %1\"},
9319 {\"cmp%D4\\t%2, %3\",
9320 \"cmn%D5\\t%0, #%n1\"},
9321 {\"cmn%D4\\t%2, #%n3\",
9322 \"cmp%D5\\t%0, %1\"},
9323 {\"cmn%D4\\t%2, #%n3\",
9324 \"cmn%D5\\t%0, #%n1\"}
9326 static const char *const ite[2] =
9331 static const int cmp_idx[] = {CMP_CMP, CMP_CMP, CMP_CMN,
9332 CMP_CMP, CMN_CMP, CMP_CMP,
9333 CMP_CMP, CMN_CMP, CMP_CMN,
9336 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9338 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9339 if (TARGET_THUMB2) {
9340 output_asm_insn (ite[swap], operands);
9342 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9346 [(set_attr "conds" "set")
9347 (set_attr "arch" "t2,t2,t2,t2,t2,t2,any,any,any,any")
9348 (set_attr "enabled_for_short_it" "yes,no,no,no,no,yes,no,no,no,no")
9349 (set_attr_alternative "length"
9356 (if_then_else (eq_attr "is_thumb" "no")
9359 (if_then_else (eq_attr "is_thumb" "no")
9362 (if_then_else (eq_attr "is_thumb" "no")
9365 (if_then_else (eq_attr "is_thumb" "no")
9368 (set_attr "type" "multiple")]
9371 (define_insn_and_split "*ior_scc_scc"
9372 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9373 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9374 [(match_operand:SI 1 "s_register_operand" "l,r")
9375 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9376 (match_operator:SI 6 "arm_comparison_operator"
9377 [(match_operand:SI 4 "s_register_operand" "l,r")
9378 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9379 (clobber (reg:CC CC_REGNUM))]
9381 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9384 "TARGET_32BIT && reload_completed"
9388 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9389 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9391 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9393 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9396 [(set_attr "conds" "clob")
9397 (set_attr "enabled_for_short_it" "yes,no")
9398 (set_attr "length" "16")
9399 (set_attr "type" "multiple")]
9402 ; If the above pattern is followed by a CMP insn, then the compare is
9403 ; redundant, since we can rework the conditional instruction that follows.
9404 (define_insn_and_split "*ior_scc_scc_cmp"
9405 [(set (match_operand 0 "dominant_cc_register" "")
9406 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9407 [(match_operand:SI 1 "s_register_operand" "l,r")
9408 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9409 (match_operator:SI 6 "arm_comparison_operator"
9410 [(match_operand:SI 4 "s_register_operand" "l,r")
9411 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9413 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9414 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9415 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9418 "TARGET_32BIT && reload_completed"
9422 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9423 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9425 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9427 [(set_attr "conds" "set")
9428 (set_attr "enabled_for_short_it" "yes,no")
9429 (set_attr "length" "16")
9430 (set_attr "type" "multiple")]
9433 (define_insn_and_split "*and_scc_scc"
9434 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9435 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9436 [(match_operand:SI 1 "s_register_operand" "l,r")
9437 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9438 (match_operator:SI 6 "arm_comparison_operator"
9439 [(match_operand:SI 4 "s_register_operand" "l,r")
9440 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9441 (clobber (reg:CC CC_REGNUM))]
9443 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9446 "TARGET_32BIT && reload_completed
9447 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9452 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9453 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9455 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9457 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9460 [(set_attr "conds" "clob")
9461 (set_attr "enabled_for_short_it" "yes,no")
9462 (set_attr "length" "16")
9463 (set_attr "type" "multiple")]
9466 ; If the above pattern is followed by a CMP insn, then the compare is
9467 ; redundant, since we can rework the conditional instruction that follows.
9468 (define_insn_and_split "*and_scc_scc_cmp"
9469 [(set (match_operand 0 "dominant_cc_register" "")
9470 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9471 [(match_operand:SI 1 "s_register_operand" "l,r")
9472 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9473 (match_operator:SI 6 "arm_comparison_operator"
9474 [(match_operand:SI 4 "s_register_operand" "l,r")
9475 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9477 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9478 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9479 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9482 "TARGET_32BIT && reload_completed"
9486 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9487 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9489 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9491 [(set_attr "conds" "set")
9492 (set_attr "enabled_for_short_it" "yes,no")
9493 (set_attr "length" "16")
9494 (set_attr "type" "multiple")]
9497 ;; If there is no dominance in the comparison, then we can still save an
9498 ;; instruction in the AND case, since we can know that the second compare
9499 ;; need only zero the value if false (if true, then the value is already
9501 (define_insn_and_split "*and_scc_scc_nodom"
9502 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9503 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9504 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9505 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9506 (match_operator:SI 6 "arm_comparison_operator"
9507 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9508 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9509 (clobber (reg:CC CC_REGNUM))]
9511 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9514 "TARGET_32BIT && reload_completed"
9515 [(parallel [(set (match_dup 0)
9516 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9517 (clobber (reg:CC CC_REGNUM))])
9518 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9520 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9523 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9524 operands[4], operands[5]),
9526 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9528 [(set_attr "conds" "clob")
9529 (set_attr "length" "20")
9530 (set_attr "type" "multiple")]
9534 [(set (reg:CC_NOOV CC_REGNUM)
9535 (compare:CC_NOOV (ior:SI
9536 (and:SI (match_operand:SI 0 "s_register_operand" "")
9538 (match_operator:SI 1 "arm_comparison_operator"
9539 [(match_operand:SI 2 "s_register_operand" "")
9540 (match_operand:SI 3 "arm_add_operand" "")]))
9542 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9545 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9547 (set (reg:CC_NOOV CC_REGNUM)
9548 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9553 [(set (reg:CC_NOOV CC_REGNUM)
9554 (compare:CC_NOOV (ior:SI
9555 (match_operator:SI 1 "arm_comparison_operator"
9556 [(match_operand:SI 2 "s_register_operand" "")
9557 (match_operand:SI 3 "arm_add_operand" "")])
9558 (and:SI (match_operand:SI 0 "s_register_operand" "")
9561 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9564 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9566 (set (reg:CC_NOOV CC_REGNUM)
9567 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9570 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9572 (define_insn_and_split "*negscc"
9573 [(set (match_operand:SI 0 "s_register_operand" "=r")
9574 (neg:SI (match_operator 3 "arm_comparison_operator"
9575 [(match_operand:SI 1 "s_register_operand" "r")
9576 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9577 (clobber (reg:CC CC_REGNUM))]
9580 "&& reload_completed"
9583 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9585 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9587 /* Emit mov\\t%0, %1, asr #31 */
9588 emit_insn (gen_rtx_SET (operands[0],
9589 gen_rtx_ASHIFTRT (SImode,
9594 else if (GET_CODE (operands[3]) == NE)
9596 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9597 if (CONST_INT_P (operands[2]))
9598 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9599 gen_int_mode (-INTVAL (operands[2]),
9602 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9604 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9608 gen_rtx_SET (operands[0],
9614 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9615 emit_insn (gen_rtx_SET (cc_reg,
9616 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9617 enum rtx_code rc = GET_CODE (operands[3]);
9619 rc = reverse_condition (rc);
9620 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9625 gen_rtx_SET (operands[0], const0_rtx)));
9626 rc = GET_CODE (operands[3]);
9627 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9632 gen_rtx_SET (operands[0],
9638 [(set_attr "conds" "clob")
9639 (set_attr "length" "12")
9640 (set_attr "type" "multiple")]
9643 (define_insn_and_split "movcond_addsi"
9644 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9646 (match_operator 5 "comparison_operator"
9647 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9648 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9650 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9651 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9652 (clobber (reg:CC CC_REGNUM))]
9655 "&& reload_completed"
9656 [(set (reg:CC_NOOV CC_REGNUM)
9658 (plus:SI (match_dup 3)
9661 (set (match_dup 0) (match_dup 1))
9662 (cond_exec (match_dup 6)
9663 (set (match_dup 0) (match_dup 2)))]
9666 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9667 operands[3], operands[4]);
9668 enum rtx_code rc = GET_CODE (operands[5]);
9669 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9670 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9671 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9672 rc = reverse_condition (rc);
9674 std::swap (operands[1], operands[2]);
9676 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9679 [(set_attr "conds" "clob")
9680 (set_attr "enabled_for_short_it" "no,yes,yes")
9681 (set_attr "type" "multiple")]
9684 (define_insn "movcond"
9685 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9687 (match_operator 5 "arm_comparison_operator"
9688 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9689 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9690 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9691 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9692 (clobber (reg:CC CC_REGNUM))]
9695 if (GET_CODE (operands[5]) == LT
9696 && (operands[4] == const0_rtx))
9698 if (which_alternative != 1 && REG_P (operands[1]))
9700 if (operands[2] == const0_rtx)
9701 return \"and\\t%0, %1, %3, asr #31\";
9702 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9704 else if (which_alternative != 0 && REG_P (operands[2]))
9706 if (operands[1] == const0_rtx)
9707 return \"bic\\t%0, %2, %3, asr #31\";
9708 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9710 /* The only case that falls through to here is when both ops 1 & 2
9714 if (GET_CODE (operands[5]) == GE
9715 && (operands[4] == const0_rtx))
9717 if (which_alternative != 1 && REG_P (operands[1]))
9719 if (operands[2] == const0_rtx)
9720 return \"bic\\t%0, %1, %3, asr #31\";
9721 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9723 else if (which_alternative != 0 && REG_P (operands[2]))
9725 if (operands[1] == const0_rtx)
9726 return \"and\\t%0, %2, %3, asr #31\";
9727 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9729 /* The only case that falls through to here is when both ops 1 & 2
9732 if (CONST_INT_P (operands[4])
9733 && !const_ok_for_arm (INTVAL (operands[4])))
9734 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9736 output_asm_insn (\"cmp\\t%3, %4\", operands);
9737 if (which_alternative != 0)
9738 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9739 if (which_alternative != 1)
9740 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9743 [(set_attr "conds" "clob")
9744 (set_attr "length" "8,8,12")
9745 (set_attr "type" "multiple")]
9748 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9750 (define_insn "*ifcompare_plus_move"
9751 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9752 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9753 [(match_operand:SI 4 "s_register_operand" "r,r")
9754 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9756 (match_operand:SI 2 "s_register_operand" "r,r")
9757 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9758 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9759 (clobber (reg:CC CC_REGNUM))]
9762 [(set_attr "conds" "clob")
9763 (set_attr "length" "8,12")
9764 (set_attr "type" "multiple")]
9767 (define_insn "*if_plus_move"
9768 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9770 (match_operator 4 "arm_comparison_operator"
9771 [(match_operand 5 "cc_register" "") (const_int 0)])
9773 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9774 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9775 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9779 sub%d4\\t%0, %2, #%n3
9780 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9781 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9782 [(set_attr "conds" "use")
9783 (set_attr "length" "4,4,8,8")
9784 (set_attr_alternative "type"
9785 [(if_then_else (match_operand 3 "const_int_operand" "")
9786 (const_string "alu_imm" )
9787 (const_string "alu_sreg"))
9788 (const_string "alu_imm")
9789 (const_string "multiple")
9790 (const_string "multiple")])]
9793 (define_insn "*ifcompare_move_plus"
9794 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9795 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9796 [(match_operand:SI 4 "s_register_operand" "r,r")
9797 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9798 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9800 (match_operand:SI 2 "s_register_operand" "r,r")
9801 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9802 (clobber (reg:CC CC_REGNUM))]
9805 [(set_attr "conds" "clob")
9806 (set_attr "length" "8,12")
9807 (set_attr "type" "multiple")]
9810 (define_insn "*if_move_plus"
9811 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9813 (match_operator 4 "arm_comparison_operator"
9814 [(match_operand 5 "cc_register" "") (const_int 0)])
9815 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9817 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9818 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9822 sub%D4\\t%0, %2, #%n3
9823 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9824 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9825 [(set_attr "conds" "use")
9826 (set_attr "length" "4,4,8,8")
9827 (set_attr_alternative "type"
9828 [(if_then_else (match_operand 3 "const_int_operand" "")
9829 (const_string "alu_imm" )
9830 (const_string "alu_sreg"))
9831 (const_string "alu_imm")
9832 (const_string "multiple")
9833 (const_string "multiple")])]
9836 (define_insn "*ifcompare_arith_arith"
9837 [(set (match_operand:SI 0 "s_register_operand" "=r")
9838 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9839 [(match_operand:SI 5 "s_register_operand" "r")
9840 (match_operand:SI 6 "arm_add_operand" "rIL")])
9841 (match_operator:SI 8 "shiftable_operator"
9842 [(match_operand:SI 1 "s_register_operand" "r")
9843 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9844 (match_operator:SI 7 "shiftable_operator"
9845 [(match_operand:SI 3 "s_register_operand" "r")
9846 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9847 (clobber (reg:CC CC_REGNUM))]
9850 [(set_attr "conds" "clob")
9851 (set_attr "length" "12")
9852 (set_attr "type" "multiple")]
9855 (define_insn "*if_arith_arith"
9856 [(set (match_operand:SI 0 "s_register_operand" "=r")
9857 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9858 [(match_operand 8 "cc_register" "") (const_int 0)])
9859 (match_operator:SI 6 "shiftable_operator"
9860 [(match_operand:SI 1 "s_register_operand" "r")
9861 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9862 (match_operator:SI 7 "shiftable_operator"
9863 [(match_operand:SI 3 "s_register_operand" "r")
9864 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9866 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9867 [(set_attr "conds" "use")
9868 (set_attr "length" "8")
9869 (set_attr "type" "multiple")]
9872 (define_insn "*ifcompare_arith_move"
9873 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9874 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9875 [(match_operand:SI 2 "s_register_operand" "r,r")
9876 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9877 (match_operator:SI 7 "shiftable_operator"
9878 [(match_operand:SI 4 "s_register_operand" "r,r")
9879 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9880 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9881 (clobber (reg:CC CC_REGNUM))]
9884 /* If we have an operation where (op x 0) is the identity operation and
9885 the conditional operator is LT or GE and we are comparing against zero and
9886 everything is in registers then we can do this in two instructions. */
9887 if (operands[3] == const0_rtx
9888 && GET_CODE (operands[7]) != AND
9889 && REG_P (operands[5])
9890 && REG_P (operands[1])
9891 && REGNO (operands[1]) == REGNO (operands[4])
9892 && REGNO (operands[4]) != REGNO (operands[0]))
9894 if (GET_CODE (operands[6]) == LT)
9895 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9896 else if (GET_CODE (operands[6]) == GE)
9897 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9899 if (CONST_INT_P (operands[3])
9900 && !const_ok_for_arm (INTVAL (operands[3])))
9901 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9903 output_asm_insn (\"cmp\\t%2, %3\", operands);
9904 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9905 if (which_alternative != 0)
9906 return \"mov%D6\\t%0, %1\";
9909 [(set_attr "conds" "clob")
9910 (set_attr "length" "8,12")
9911 (set_attr "type" "multiple")]
9914 (define_insn "*if_arith_move"
9915 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9916 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9917 [(match_operand 6 "cc_register" "") (const_int 0)])
9918 (match_operator:SI 5 "shiftable_operator"
9919 [(match_operand:SI 2 "s_register_operand" "r,r")
9920 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9921 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9925 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9926 [(set_attr "conds" "use")
9927 (set_attr "length" "4,8")
9928 (set_attr_alternative "type"
9929 [(if_then_else (match_operand 3 "const_int_operand" "")
9930 (const_string "alu_shift_imm" )
9931 (const_string "alu_shift_reg"))
9932 (const_string "multiple")])]
9935 (define_insn "*ifcompare_move_arith"
9936 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9937 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9938 [(match_operand:SI 4 "s_register_operand" "r,r")
9939 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9940 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9941 (match_operator:SI 7 "shiftable_operator"
9942 [(match_operand:SI 2 "s_register_operand" "r,r")
9943 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9944 (clobber (reg:CC CC_REGNUM))]
9947 /* If we have an operation where (op x 0) is the identity operation and
9948 the conditional operator is LT or GE and we are comparing against zero and
9949 everything is in registers then we can do this in two instructions */
9950 if (operands[5] == const0_rtx
9951 && GET_CODE (operands[7]) != AND
9952 && REG_P (operands[3])
9953 && REG_P (operands[1])
9954 && REGNO (operands[1]) == REGNO (operands[2])
9955 && REGNO (operands[2]) != REGNO (operands[0]))
9957 if (GET_CODE (operands[6]) == GE)
9958 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9959 else if (GET_CODE (operands[6]) == LT)
9960 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9963 if (CONST_INT_P (operands[5])
9964 && !const_ok_for_arm (INTVAL (operands[5])))
9965 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9967 output_asm_insn (\"cmp\\t%4, %5\", operands);
9969 if (which_alternative != 0)
9970 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9971 return \"%I7%D6\\t%0, %2, %3\";
9973 [(set_attr "conds" "clob")
9974 (set_attr "length" "8,12")
9975 (set_attr "type" "multiple")]
9978 (define_insn "*if_move_arith"
9979 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9981 (match_operator 4 "arm_comparison_operator"
9982 [(match_operand 6 "cc_register" "") (const_int 0)])
9983 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9984 (match_operator:SI 5 "shiftable_operator"
9985 [(match_operand:SI 2 "s_register_operand" "r,r")
9986 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9990 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9991 [(set_attr "conds" "use")
9992 (set_attr "length" "4,8")
9993 (set_attr_alternative "type"
9994 [(if_then_else (match_operand 3 "const_int_operand" "")
9995 (const_string "alu_shift_imm" )
9996 (const_string "alu_shift_reg"))
9997 (const_string "multiple")])]
10000 (define_insn "*ifcompare_move_not"
10001 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10003 (match_operator 5 "arm_comparison_operator"
10004 [(match_operand:SI 3 "s_register_operand" "r,r")
10005 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10006 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10008 (match_operand:SI 2 "s_register_operand" "r,r"))))
10009 (clobber (reg:CC CC_REGNUM))]
10012 [(set_attr "conds" "clob")
10013 (set_attr "length" "8,12")
10014 (set_attr "type" "multiple")]
10017 (define_insn "*if_move_not"
10018 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10020 (match_operator 4 "arm_comparison_operator"
10021 [(match_operand 3 "cc_register" "") (const_int 0)])
10022 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10023 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10027 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10028 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10029 [(set_attr "conds" "use")
10030 (set_attr "type" "mvn_reg")
10031 (set_attr "length" "4,8,8")
10032 (set_attr "type" "mvn_reg,multiple,multiple")]
10035 (define_insn "*ifcompare_not_move"
10036 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10038 (match_operator 5 "arm_comparison_operator"
10039 [(match_operand:SI 3 "s_register_operand" "r,r")
10040 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10042 (match_operand:SI 2 "s_register_operand" "r,r"))
10043 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10044 (clobber (reg:CC CC_REGNUM))]
10047 [(set_attr "conds" "clob")
10048 (set_attr "length" "8,12")
10049 (set_attr "type" "multiple")]
10052 (define_insn "*if_not_move"
10053 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10055 (match_operator 4 "arm_comparison_operator"
10056 [(match_operand 3 "cc_register" "") (const_int 0)])
10057 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10058 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10062 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10063 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10064 [(set_attr "conds" "use")
10065 (set_attr "type" "mvn_reg,multiple,multiple")
10066 (set_attr "length" "4,8,8")]
10069 (define_insn "*ifcompare_shift_move"
10070 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10072 (match_operator 6 "arm_comparison_operator"
10073 [(match_operand:SI 4 "s_register_operand" "r,r")
10074 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10075 (match_operator:SI 7 "shift_operator"
10076 [(match_operand:SI 2 "s_register_operand" "r,r")
10077 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10078 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10079 (clobber (reg:CC CC_REGNUM))]
10082 [(set_attr "conds" "clob")
10083 (set_attr "length" "8,12")
10084 (set_attr "type" "multiple")]
10087 (define_insn "*if_shift_move"
10088 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10090 (match_operator 5 "arm_comparison_operator"
10091 [(match_operand 6 "cc_register" "") (const_int 0)])
10092 (match_operator:SI 4 "shift_operator"
10093 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10094 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10095 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10099 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10100 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10101 [(set_attr "conds" "use")
10102 (set_attr "shift" "2")
10103 (set_attr "length" "4,8,8")
10104 (set_attr_alternative "type"
10105 [(if_then_else (match_operand 3 "const_int_operand" "")
10106 (const_string "mov_shift" )
10107 (const_string "mov_shift_reg"))
10108 (const_string "multiple")
10109 (const_string "multiple")])]
10112 (define_insn "*ifcompare_move_shift"
10113 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10115 (match_operator 6 "arm_comparison_operator"
10116 [(match_operand:SI 4 "s_register_operand" "r,r")
10117 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10118 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10119 (match_operator:SI 7 "shift_operator"
10120 [(match_operand:SI 2 "s_register_operand" "r,r")
10121 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10122 (clobber (reg:CC CC_REGNUM))]
10125 [(set_attr "conds" "clob")
10126 (set_attr "length" "8,12")
10127 (set_attr "type" "multiple")]
10130 (define_insn "*if_move_shift"
10131 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10133 (match_operator 5 "arm_comparison_operator"
10134 [(match_operand 6 "cc_register" "") (const_int 0)])
10135 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10136 (match_operator:SI 4 "shift_operator"
10137 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10138 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10142 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10143 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10144 [(set_attr "conds" "use")
10145 (set_attr "shift" "2")
10146 (set_attr "length" "4,8,8")
10147 (set_attr_alternative "type"
10148 [(if_then_else (match_operand 3 "const_int_operand" "")
10149 (const_string "mov_shift" )
10150 (const_string "mov_shift_reg"))
10151 (const_string "multiple")
10152 (const_string "multiple")])]
10155 (define_insn "*ifcompare_shift_shift"
10156 [(set (match_operand:SI 0 "s_register_operand" "=r")
10158 (match_operator 7 "arm_comparison_operator"
10159 [(match_operand:SI 5 "s_register_operand" "r")
10160 (match_operand:SI 6 "arm_add_operand" "rIL")])
10161 (match_operator:SI 8 "shift_operator"
10162 [(match_operand:SI 1 "s_register_operand" "r")
10163 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10164 (match_operator:SI 9 "shift_operator"
10165 [(match_operand:SI 3 "s_register_operand" "r")
10166 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10167 (clobber (reg:CC CC_REGNUM))]
10170 [(set_attr "conds" "clob")
10171 (set_attr "length" "12")
10172 (set_attr "type" "multiple")]
10175 (define_insn "*if_shift_shift"
10176 [(set (match_operand:SI 0 "s_register_operand" "=r")
10178 (match_operator 5 "arm_comparison_operator"
10179 [(match_operand 8 "cc_register" "") (const_int 0)])
10180 (match_operator:SI 6 "shift_operator"
10181 [(match_operand:SI 1 "s_register_operand" "r")
10182 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10183 (match_operator:SI 7 "shift_operator"
10184 [(match_operand:SI 3 "s_register_operand" "r")
10185 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10187 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10188 [(set_attr "conds" "use")
10189 (set_attr "shift" "1")
10190 (set_attr "length" "8")
10191 (set (attr "type") (if_then_else
10192 (and (match_operand 2 "const_int_operand" "")
10193 (match_operand 4 "const_int_operand" ""))
10194 (const_string "mov_shift")
10195 (const_string "mov_shift_reg")))]
10198 (define_insn "*ifcompare_not_arith"
10199 [(set (match_operand:SI 0 "s_register_operand" "=r")
10201 (match_operator 6 "arm_comparison_operator"
10202 [(match_operand:SI 4 "s_register_operand" "r")
10203 (match_operand:SI 5 "arm_add_operand" "rIL")])
10204 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10205 (match_operator:SI 7 "shiftable_operator"
10206 [(match_operand:SI 2 "s_register_operand" "r")
10207 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10208 (clobber (reg:CC CC_REGNUM))]
10211 [(set_attr "conds" "clob")
10212 (set_attr "length" "12")
10213 (set_attr "type" "multiple")]
10216 (define_insn "*if_not_arith"
10217 [(set (match_operand:SI 0 "s_register_operand" "=r")
10219 (match_operator 5 "arm_comparison_operator"
10220 [(match_operand 4 "cc_register" "") (const_int 0)])
10221 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10222 (match_operator:SI 6 "shiftable_operator"
10223 [(match_operand:SI 2 "s_register_operand" "r")
10224 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10226 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10227 [(set_attr "conds" "use")
10228 (set_attr "type" "mvn_reg")
10229 (set_attr "length" "8")]
10232 (define_insn "*ifcompare_arith_not"
10233 [(set (match_operand:SI 0 "s_register_operand" "=r")
10235 (match_operator 6 "arm_comparison_operator"
10236 [(match_operand:SI 4 "s_register_operand" "r")
10237 (match_operand:SI 5 "arm_add_operand" "rIL")])
10238 (match_operator:SI 7 "shiftable_operator"
10239 [(match_operand:SI 2 "s_register_operand" "r")
10240 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10241 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10242 (clobber (reg:CC CC_REGNUM))]
10245 [(set_attr "conds" "clob")
10246 (set_attr "length" "12")
10247 (set_attr "type" "multiple")]
10250 (define_insn "*if_arith_not"
10251 [(set (match_operand:SI 0 "s_register_operand" "=r")
10253 (match_operator 5 "arm_comparison_operator"
10254 [(match_operand 4 "cc_register" "") (const_int 0)])
10255 (match_operator:SI 6 "shiftable_operator"
10256 [(match_operand:SI 2 "s_register_operand" "r")
10257 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10258 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10260 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10261 [(set_attr "conds" "use")
10262 (set_attr "type" "multiple")
10263 (set_attr "length" "8")]
10266 (define_insn "*ifcompare_neg_move"
10267 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10269 (match_operator 5 "arm_comparison_operator"
10270 [(match_operand:SI 3 "s_register_operand" "r,r")
10271 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10272 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10273 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10274 (clobber (reg:CC CC_REGNUM))]
10277 [(set_attr "conds" "clob")
10278 (set_attr "length" "8,12")
10279 (set_attr "type" "multiple")]
10282 (define_insn_and_split "*if_neg_move"
10283 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10285 (match_operator 4 "arm_comparison_operator"
10286 [(match_operand 3 "cc_register" "") (const_int 0)])
10287 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10288 (match_operand:SI 1 "s_register_operand" "0,0")))]
10291 "&& reload_completed"
10292 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10293 (set (match_dup 0) (neg:SI (match_dup 2))))]
10295 [(set_attr "conds" "use")
10296 (set_attr "length" "4")
10297 (set_attr "arch" "t2,32")
10298 (set_attr "enabled_for_short_it" "yes,no")
10299 (set_attr "type" "logic_shift_imm")]
10302 (define_insn "*ifcompare_move_neg"
10303 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10305 (match_operator 5 "arm_comparison_operator"
10306 [(match_operand:SI 3 "s_register_operand" "r,r")
10307 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10308 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10309 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10310 (clobber (reg:CC CC_REGNUM))]
10313 [(set_attr "conds" "clob")
10314 (set_attr "length" "8,12")
10315 (set_attr "type" "multiple")]
10318 (define_insn_and_split "*if_move_neg"
10319 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10321 (match_operator 4 "arm_comparison_operator"
10322 [(match_operand 3 "cc_register" "") (const_int 0)])
10323 (match_operand:SI 1 "s_register_operand" "0,0")
10324 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10327 "&& reload_completed"
10328 [(cond_exec (match_dup 5)
10329 (set (match_dup 0) (neg:SI (match_dup 2))))]
10331 machine_mode mode = GET_MODE (operands[3]);
10332 rtx_code rc = GET_CODE (operands[4]);
10334 if (mode == CCFPmode || mode == CCFPEmode)
10335 rc = reverse_condition_maybe_unordered (rc);
10337 rc = reverse_condition (rc);
10339 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10341 [(set_attr "conds" "use")
10342 (set_attr "length" "4")
10343 (set_attr "arch" "t2,32")
10344 (set_attr "enabled_for_short_it" "yes,no")
10345 (set_attr "type" "logic_shift_imm")]
10348 (define_insn "*arith_adjacentmem"
10349 [(set (match_operand:SI 0 "s_register_operand" "=r")
10350 (match_operator:SI 1 "shiftable_operator"
10351 [(match_operand:SI 2 "memory_operand" "m")
10352 (match_operand:SI 3 "memory_operand" "m")]))
10353 (clobber (match_scratch:SI 4 "=r"))]
10354 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10360 HOST_WIDE_INT val1 = 0, val2 = 0;
10362 if (REGNO (operands[0]) > REGNO (operands[4]))
10364 ldm[1] = operands[4];
10365 ldm[2] = operands[0];
10369 ldm[1] = operands[0];
10370 ldm[2] = operands[4];
10373 base_reg = XEXP (operands[2], 0);
10375 if (!REG_P (base_reg))
10377 val1 = INTVAL (XEXP (base_reg, 1));
10378 base_reg = XEXP (base_reg, 0);
10381 if (!REG_P (XEXP (operands[3], 0)))
10382 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10384 arith[0] = operands[0];
10385 arith[3] = operands[1];
10399 if (val1 !=0 && val2 != 0)
10403 if (val1 == 4 || val2 == 4)
10404 /* Other val must be 8, since we know they are adjacent and neither
10406 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10407 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10409 ldm[0] = ops[0] = operands[4];
10411 ops[2] = GEN_INT (val1);
10412 output_add_immediate (ops);
10414 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10416 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10420 /* Offset is out of range for a single add, so use two ldr. */
10423 ops[2] = GEN_INT (val1);
10424 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10426 ops[2] = GEN_INT (val2);
10427 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10430 else if (val1 != 0)
10433 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10435 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10440 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10442 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10444 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10447 [(set_attr "length" "12")
10448 (set_attr "predicable" "yes")
10449 (set_attr "type" "load_4")]
10452 ; This pattern is never tried by combine, so do it as a peephole
10455 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10456 (match_operand:SI 1 "arm_general_register_operand" ""))
10457 (set (reg:CC CC_REGNUM)
10458 (compare:CC (match_dup 1) (const_int 0)))]
10460 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10461 (set (match_dup 0) (match_dup 1))])]
10466 [(set (match_operand:SI 0 "s_register_operand" "")
10467 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10469 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10470 [(match_operand:SI 3 "s_register_operand" "")
10471 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10472 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10474 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10475 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10480 ;; This split can be used because CC_Z mode implies that the following
10481 ;; branch will be an equality, or an unsigned inequality, so the sign
10482 ;; extension is not needed.
10485 [(set (reg:CC_Z CC_REGNUM)
10487 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10489 (match_operand 1 "const_int_operand" "")))
10490 (clobber (match_scratch:SI 2 ""))]
10492 && ((UINTVAL (operands[1]))
10493 == ((UINTVAL (operands[1])) >> 24) << 24)"
10494 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10495 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10497 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10500 ;; ??? Check the patterns above for Thumb-2 usefulness
10502 (define_expand "prologue"
10503 [(clobber (const_int 0))]
10506 arm_expand_prologue ();
10508 thumb1_expand_prologue ();
10513 (define_expand "epilogue"
10514 [(clobber (const_int 0))]
10517 if (crtl->calls_eh_return)
10518 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10521 thumb1_expand_epilogue ();
10522 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10523 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10525 else if (HAVE_return)
10527 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10528 no need for explicit testing again. */
10529 emit_jump_insn (gen_return ());
10531 else if (TARGET_32BIT)
10533 arm_expand_epilogue (true);
10539 ;; Note - although unspec_volatile's USE all hard registers,
10540 ;; USEs are ignored after relaod has completed. Thus we need
10541 ;; to add an unspec of the link register to ensure that flow
10542 ;; does not think that it is unused by the sibcall branch that
10543 ;; will replace the standard function epilogue.
10544 (define_expand "sibcall_epilogue"
10545 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10546 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10549 arm_expand_epilogue (false);
10554 (define_expand "eh_epilogue"
10555 [(use (match_operand:SI 0 "register_operand"))
10556 (use (match_operand:SI 1 "register_operand"))
10557 (use (match_operand:SI 2 "register_operand"))]
10561 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10562 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10564 rtx ra = gen_rtx_REG (Pmode, 2);
10566 emit_move_insn (ra, operands[2]);
10569 /* This is a hack -- we may have crystalized the function type too
10571 cfun->machine->func_type = 0;
10575 ;; This split is only used during output to reduce the number of patterns
10576 ;; that need assembler instructions adding to them. We allowed the setting
10577 ;; of the conditions to be implicit during rtl generation so that
10578 ;; the conditional compare patterns would work. However this conflicts to
10579 ;; some extent with the conditional data operations, so we have to split them
10582 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10583 ;; conditional execution sufficient?
10586 [(set (match_operand:SI 0 "s_register_operand" "")
10587 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10588 [(match_operand 2 "" "") (match_operand 3 "" "")])
10590 (match_operand 4 "" "")))
10591 (clobber (reg:CC CC_REGNUM))]
10592 "TARGET_ARM && reload_completed"
10593 [(set (match_dup 5) (match_dup 6))
10594 (cond_exec (match_dup 7)
10595 (set (match_dup 0) (match_dup 4)))]
10598 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10599 operands[2], operands[3]);
10600 enum rtx_code rc = GET_CODE (operands[1]);
10602 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10603 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10604 if (mode == CCFPmode || mode == CCFPEmode)
10605 rc = reverse_condition_maybe_unordered (rc);
10607 rc = reverse_condition (rc);
10609 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10614 [(set (match_operand:SI 0 "s_register_operand" "")
10615 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10616 [(match_operand 2 "" "") (match_operand 3 "" "")])
10617 (match_operand 4 "" "")
10619 (clobber (reg:CC CC_REGNUM))]
10620 "TARGET_ARM && reload_completed"
10621 [(set (match_dup 5) (match_dup 6))
10622 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10623 (set (match_dup 0) (match_dup 4)))]
10626 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10627 operands[2], operands[3]);
10629 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10630 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10635 [(set (match_operand:SI 0 "s_register_operand" "")
10636 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10637 [(match_operand 2 "" "") (match_operand 3 "" "")])
10638 (match_operand 4 "" "")
10639 (match_operand 5 "" "")))
10640 (clobber (reg:CC CC_REGNUM))]
10641 "TARGET_ARM && reload_completed"
10642 [(set (match_dup 6) (match_dup 7))
10643 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10644 (set (match_dup 0) (match_dup 4)))
10645 (cond_exec (match_dup 8)
10646 (set (match_dup 0) (match_dup 5)))]
10649 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10650 operands[2], operands[3]);
10651 enum rtx_code rc = GET_CODE (operands[1]);
10653 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10654 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10655 if (mode == CCFPmode || mode == CCFPEmode)
10656 rc = reverse_condition_maybe_unordered (rc);
10658 rc = reverse_condition (rc);
10660 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10665 [(set (match_operand:SI 0 "s_register_operand" "")
10666 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10667 [(match_operand:SI 2 "s_register_operand" "")
10668 (match_operand:SI 3 "arm_add_operand" "")])
10669 (match_operand:SI 4 "arm_rhs_operand" "")
10671 (match_operand:SI 5 "s_register_operand" ""))))
10672 (clobber (reg:CC CC_REGNUM))]
10673 "TARGET_ARM && reload_completed"
10674 [(set (match_dup 6) (match_dup 7))
10675 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10676 (set (match_dup 0) (match_dup 4)))
10677 (cond_exec (match_dup 8)
10678 (set (match_dup 0) (not:SI (match_dup 5))))]
10681 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10682 operands[2], operands[3]);
10683 enum rtx_code rc = GET_CODE (operands[1]);
10685 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10686 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10687 if (mode == CCFPmode || mode == CCFPEmode)
10688 rc = reverse_condition_maybe_unordered (rc);
10690 rc = reverse_condition (rc);
10692 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10696 (define_insn "*cond_move_not"
10697 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10698 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10699 [(match_operand 3 "cc_register" "") (const_int 0)])
10700 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10702 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10706 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10707 [(set_attr "conds" "use")
10708 (set_attr "type" "mvn_reg,multiple")
10709 (set_attr "length" "4,8")]
10712 ;; The next two patterns occur when an AND operation is followed by a
10713 ;; scc insn sequence
10715 (define_insn "*sign_extract_onebit"
10716 [(set (match_operand:SI 0 "s_register_operand" "=r")
10717 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10719 (match_operand:SI 2 "const_int_operand" "n")))
10720 (clobber (reg:CC CC_REGNUM))]
10723 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10724 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10725 return \"mvnne\\t%0, #0\";
10727 [(set_attr "conds" "clob")
10728 (set_attr "length" "8")
10729 (set_attr "type" "multiple")]
10732 (define_insn "*not_signextract_onebit"
10733 [(set (match_operand:SI 0 "s_register_operand" "=r")
10735 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10737 (match_operand:SI 2 "const_int_operand" "n"))))
10738 (clobber (reg:CC CC_REGNUM))]
10741 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10742 output_asm_insn (\"tst\\t%1, %2\", operands);
10743 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10744 return \"movne\\t%0, #0\";
10746 [(set_attr "conds" "clob")
10747 (set_attr "length" "12")
10748 (set_attr "type" "multiple")]
10750 ;; ??? The above patterns need auditing for Thumb-2
10752 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10753 ;; expressions. For simplicity, the first register is also in the unspec
10755 ;; To avoid the usage of GNU extension, the length attribute is computed
10756 ;; in a C function arm_attr_length_push_multi.
10757 (define_insn "*push_multi"
10758 [(match_parallel 2 "multi_register_push"
10759 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10760 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10761 UNSPEC_PUSH_MULT))])]
10765 int num_saves = XVECLEN (operands[2], 0);
10767 /* For the StrongARM at least it is faster to
10768 use STR to store only a single register.
10769 In Thumb mode always use push, and the assembler will pick
10770 something appropriate. */
10771 if (num_saves == 1 && TARGET_ARM)
10772 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10779 strcpy (pattern, \"push%?\\t{%1\");
10781 strcpy (pattern, \"push\\t{%1\");
10783 for (i = 1; i < num_saves; i++)
10785 strcat (pattern, \", %|\");
10787 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10790 strcat (pattern, \"}\");
10791 output_asm_insn (pattern, operands);
10796 [(set_attr "type" "store_16")
10797 (set (attr "length")
10798 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10801 (define_insn "stack_tie"
10802 [(set (mem:BLK (scratch))
10803 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10804 (match_operand:SI 1 "s_register_operand" "rk")]
10808 [(set_attr "length" "0")
10809 (set_attr "type" "block")]
10812 ;; Pop (as used in epilogue RTL)
10814 (define_insn "*load_multiple_with_writeback"
10815 [(match_parallel 0 "load_multiple_operation"
10816 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10817 (plus:SI (match_dup 1)
10818 (match_operand:SI 2 "const_int_I_operand" "I")))
10819 (set (match_operand:SI 3 "s_register_operand" "=rk")
10820 (mem:SI (match_dup 1)))
10822 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10825 arm_output_multireg_pop (operands, /*return_pc=*/false,
10826 /*cond=*/const_true_rtx,
10832 [(set_attr "type" "load_16")
10833 (set_attr "predicable" "yes")
10834 (set (attr "length")
10835 (symbol_ref "arm_attr_length_pop_multi (operands,
10836 /*return_pc=*/false,
10837 /*write_back_p=*/true)"))]
10840 ;; Pop with return (as used in epilogue RTL)
10842 ;; This instruction is generated when the registers are popped at the end of
10843 ;; epilogue. Here, instead of popping the value into LR and then generating
10844 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10846 (define_insn "*pop_multiple_with_writeback_and_return"
10847 [(match_parallel 0 "pop_multiple_return"
10849 (set (match_operand:SI 1 "s_register_operand" "+rk")
10850 (plus:SI (match_dup 1)
10851 (match_operand:SI 2 "const_int_I_operand" "I")))
10852 (set (match_operand:SI 3 "s_register_operand" "=rk")
10853 (mem:SI (match_dup 1)))
10855 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10858 arm_output_multireg_pop (operands, /*return_pc=*/true,
10859 /*cond=*/const_true_rtx,
10865 [(set_attr "type" "load_16")
10866 (set_attr "predicable" "yes")
10867 (set (attr "length")
10868 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10869 /*write_back_p=*/true)"))]
10872 (define_insn "*pop_multiple_with_return"
10873 [(match_parallel 0 "pop_multiple_return"
10875 (set (match_operand:SI 2 "s_register_operand" "=rk")
10876 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10878 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10881 arm_output_multireg_pop (operands, /*return_pc=*/true,
10882 /*cond=*/const_true_rtx,
10888 [(set_attr "type" "load_16")
10889 (set_attr "predicable" "yes")
10890 (set (attr "length")
10891 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10892 /*write_back_p=*/false)"))]
10895 ;; Load into PC and return
10896 (define_insn "*ldr_with_return"
10898 (set (reg:SI PC_REGNUM)
10899 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10900 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10901 "ldr%?\t%|pc, [%0], #4"
10902 [(set_attr "type" "load_4")
10903 (set_attr "predicable" "yes")]
10905 ;; Pop for floating point registers (as used in epilogue RTL)
10906 (define_insn "*vfp_pop_multiple_with_writeback"
10907 [(match_parallel 0 "pop_multiple_fp"
10908 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10909 (plus:SI (match_dup 1)
10910 (match_operand:SI 2 "const_int_I_operand" "I")))
10911 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10912 (mem:DF (match_dup 1)))])]
10913 "TARGET_32BIT && TARGET_HARD_FLOAT"
10916 int num_regs = XVECLEN (operands[0], 0);
10919 strcpy (pattern, \"vldm\\t\");
10920 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10921 strcat (pattern, \"!, {\");
10922 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10923 strcat (pattern, \"%P0\");
10924 if ((num_regs - 1) > 1)
10926 strcat (pattern, \"-%P1\");
10927 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10930 strcat (pattern, \"}\");
10931 output_asm_insn (pattern, op_list);
10935 [(set_attr "type" "load_16")
10936 (set_attr "conds" "unconditional")
10937 (set_attr "predicable" "no")]
10940 ;; Special patterns for dealing with the constant pool
10942 (define_insn "align_4"
10943 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10946 assemble_align (32);
10949 [(set_attr "type" "no_insn")]
10952 (define_insn "align_8"
10953 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10956 assemble_align (64);
10959 [(set_attr "type" "no_insn")]
10962 (define_insn "consttable_end"
10963 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10966 making_const_table = FALSE;
10969 [(set_attr "type" "no_insn")]
10972 (define_insn "consttable_1"
10973 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10976 making_const_table = TRUE;
10977 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10978 assemble_zeros (3);
10981 [(set_attr "length" "4")
10982 (set_attr "type" "no_insn")]
10985 (define_insn "consttable_2"
10986 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10990 rtx x = operands[0];
10991 making_const_table = TRUE;
10992 switch (GET_MODE_CLASS (GET_MODE (x)))
10995 arm_emit_fp16_const (x);
10998 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10999 assemble_zeros (2);
11004 [(set_attr "length" "4")
11005 (set_attr "type" "no_insn")]
11008 (define_insn "consttable_4"
11009 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11013 rtx x = operands[0];
11014 making_const_table = TRUE;
11015 scalar_float_mode float_mode;
11016 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11017 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11020 /* XXX: Sometimes gcc does something really dumb and ends up with
11021 a HIGH in a constant pool entry, usually because it's trying to
11022 load into a VFP register. We know this will always be used in
11023 combination with a LO_SUM which ignores the high bits, so just
11024 strip off the HIGH. */
11025 if (GET_CODE (x) == HIGH)
11027 assemble_integer (x, 4, BITS_PER_WORD, 1);
11028 mark_symbol_refs_as_used (x);
11032 [(set_attr "length" "4")
11033 (set_attr "type" "no_insn")]
11036 (define_insn "consttable_8"
11037 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11041 making_const_table = TRUE;
11042 scalar_float_mode float_mode;
11043 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11044 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11045 float_mode, BITS_PER_WORD);
11047 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11050 [(set_attr "length" "8")
11051 (set_attr "type" "no_insn")]
11054 (define_insn "consttable_16"
11055 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11059 making_const_table = TRUE;
11060 scalar_float_mode float_mode;
11061 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11062 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11063 float_mode, BITS_PER_WORD);
11065 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11068 [(set_attr "length" "16")
11069 (set_attr "type" "no_insn")]
11072 ;; V5 Instructions,
11074 (define_insn "clzsi2"
11075 [(set (match_operand:SI 0 "s_register_operand" "=r")
11076 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11077 "TARGET_32BIT && arm_arch5t"
11079 [(set_attr "predicable" "yes")
11080 (set_attr "type" "clz")])
11082 (define_insn "rbitsi2"
11083 [(set (match_operand:SI 0 "s_register_operand" "=r")
11084 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11085 "TARGET_32BIT && arm_arch_thumb2"
11087 [(set_attr "predicable" "yes")
11088 (set_attr "type" "clz")])
11090 ;; Keep this as a CTZ expression until after reload and then split
11091 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11092 ;; to fold with any other expression.
11094 (define_insn_and_split "ctzsi2"
11095 [(set (match_operand:SI 0 "s_register_operand" "=r")
11096 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11097 "TARGET_32BIT && arm_arch_thumb2"
11099 "&& reload_completed"
11102 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11103 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11107 ;; V5E instructions.
11109 (define_insn "prefetch"
11110 [(prefetch (match_operand:SI 0 "address_operand" "p")
11111 (match_operand:SI 1 "" "")
11112 (match_operand:SI 2 "" ""))]
11113 "TARGET_32BIT && arm_arch5te"
11115 [(set_attr "type" "load_4")]
11118 ;; General predication pattern
11121 [(match_operator 0 "arm_comparison_operator"
11122 [(match_operand 1 "cc_register" "")
11125 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11127 [(set_attr "predicated" "yes")]
11130 (define_insn "force_register_use"
11131 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11134 [(set_attr "length" "0")
11135 (set_attr "type" "no_insn")]
11139 ;; Patterns for exception handling
11141 (define_expand "eh_return"
11142 [(use (match_operand 0 "general_operand"))]
11147 emit_insn (gen_arm_eh_return (operands[0]));
11149 emit_insn (gen_thumb_eh_return (operands[0]));
11154 ;; We can't expand this before we know where the link register is stored.
11155 (define_insn_and_split "arm_eh_return"
11156 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11158 (clobber (match_scratch:SI 1 "=&r"))]
11161 "&& reload_completed"
11165 arm_set_return_address (operands[0], operands[1]);
11173 (define_insn "load_tp_hard"
11174 [(set (match_operand:SI 0 "register_operand" "=r")
11175 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11177 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11178 [(set_attr "predicable" "yes")
11179 (set_attr "type" "mrs")]
11182 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11183 (define_insn "load_tp_soft_fdpic"
11184 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11185 (clobber (reg:SI FDPIC_REGNUM))
11186 (clobber (reg:SI LR_REGNUM))
11187 (clobber (reg:SI IP_REGNUM))
11188 (clobber (reg:CC CC_REGNUM))]
11189 "TARGET_SOFT_TP && TARGET_FDPIC"
11190 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11191 [(set_attr "conds" "clob")
11192 (set_attr "type" "branch")]
11195 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11196 (define_insn "load_tp_soft"
11197 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11198 (clobber (reg:SI LR_REGNUM))
11199 (clobber (reg:SI IP_REGNUM))
11200 (clobber (reg:CC CC_REGNUM))]
11201 "TARGET_SOFT_TP && !TARGET_FDPIC"
11202 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11203 [(set_attr "conds" "clob")
11204 (set_attr "type" "branch")]
11207 ;; tls descriptor call
11208 (define_insn "tlscall"
11209 [(set (reg:SI R0_REGNUM)
11210 (unspec:SI [(reg:SI R0_REGNUM)
11211 (match_operand:SI 0 "" "X")
11212 (match_operand 1 "" "")] UNSPEC_TLS))
11213 (clobber (reg:SI R1_REGNUM))
11214 (clobber (reg:SI LR_REGNUM))
11215 (clobber (reg:SI CC_REGNUM))]
11218 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11219 INTVAL (operands[1]));
11220 return "bl\\t%c0(tlscall)";
11222 [(set_attr "conds" "clob")
11223 (set_attr "length" "4")
11224 (set_attr "type" "branch")]
11227 ;; For thread pointer builtin
11228 (define_expand "get_thread_pointersi"
11229 [(match_operand:SI 0 "s_register_operand")]
11233 arm_load_tp (operands[0]);
11239 ;; We only care about the lower 16 bits of the constant
11240 ;; being inserted into the upper 16 bits of the register.
11241 (define_insn "*arm_movtas_ze"
11242 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11245 (match_operand:SI 1 "const_int_operand" ""))]
11250 [(set_attr "arch" "32,v8mb")
11251 (set_attr "predicable" "yes")
11252 (set_attr "length" "4")
11253 (set_attr "type" "alu_sreg")]
11256 (define_insn "*arm_rev"
11257 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11258 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11264 [(set_attr "arch" "t1,t2,32")
11265 (set_attr "length" "2,2,4")
11266 (set_attr "predicable" "no,yes,yes")
11267 (set_attr "type" "rev")]
11270 (define_expand "arm_legacy_rev"
11271 [(set (match_operand:SI 2 "s_register_operand")
11272 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand")
11276 (lshiftrt:SI (match_dup 2)
11278 (set (match_operand:SI 3 "s_register_operand")
11279 (rotatert:SI (match_dup 1)
11282 (and:SI (match_dup 2)
11283 (const_int -65281)))
11284 (set (match_operand:SI 0 "s_register_operand")
11285 (xor:SI (match_dup 3)
11291 ;; Reuse temporaries to keep register pressure down.
11292 (define_expand "thumb_legacy_rev"
11293 [(set (match_operand:SI 2 "s_register_operand")
11294 (ashift:SI (match_operand:SI 1 "s_register_operand")
11296 (set (match_operand:SI 3 "s_register_operand")
11297 (lshiftrt:SI (match_dup 1)
11300 (ior:SI (match_dup 3)
11302 (set (match_operand:SI 4 "s_register_operand")
11304 (set (match_operand:SI 5 "s_register_operand")
11305 (rotatert:SI (match_dup 1)
11308 (ashift:SI (match_dup 5)
11311 (lshiftrt:SI (match_dup 5)
11314 (ior:SI (match_dup 5)
11317 (rotatert:SI (match_dup 5)
11319 (set (match_operand:SI 0 "s_register_operand")
11320 (ior:SI (match_dup 5)
11326 ;; ARM-specific expansion of signed mod by power of 2
11327 ;; using conditional negate.
11328 ;; For r0 % n where n is a power of 2 produce:
11330 ;; and r0, r0, #(n - 1)
11331 ;; and r1, r1, #(n - 1)
11332 ;; rsbpl r0, r1, #0
11334 (define_expand "modsi3"
11335 [(match_operand:SI 0 "register_operand")
11336 (match_operand:SI 1 "register_operand")
11337 (match_operand:SI 2 "const_int_operand")]
11340 HOST_WIDE_INT val = INTVAL (operands[2]);
11343 || exact_log2 (val) <= 0)
11346 rtx mask = GEN_INT (val - 1);
11348 /* In the special case of x0 % 2 we can do the even shorter:
11351 rsblt r0, r0, #0. */
11355 rtx cc_reg = arm_gen_compare_reg (LT,
11356 operands[1], const0_rtx, NULL_RTX);
11357 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11358 rtx masked = gen_reg_rtx (SImode);
11360 emit_insn (gen_andsi3 (masked, operands[1], mask));
11361 emit_move_insn (operands[0],
11362 gen_rtx_IF_THEN_ELSE (SImode, cond,
11363 gen_rtx_NEG (SImode,
11369 rtx neg_op = gen_reg_rtx (SImode);
11370 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11373 /* Extract the condition register and mode. */
11374 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11375 rtx cc_reg = SET_DEST (cmp);
11376 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11378 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11380 rtx masked_neg = gen_reg_rtx (SImode);
11381 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11383 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11384 during expand does not always work. Do an IF_THEN_ELSE instead. */
11385 emit_move_insn (operands[0],
11386 gen_rtx_IF_THEN_ELSE (SImode, cond,
11387 gen_rtx_NEG (SImode, masked_neg),
11395 (define_expand "bswapsi2"
11396 [(set (match_operand:SI 0 "s_register_operand")
11397 (bswap:SI (match_operand:SI 1 "s_register_operand")))]
11398 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11402 rtx op2 = gen_reg_rtx (SImode);
11403 rtx op3 = gen_reg_rtx (SImode);
11407 rtx op4 = gen_reg_rtx (SImode);
11408 rtx op5 = gen_reg_rtx (SImode);
11410 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11411 op2, op3, op4, op5));
11415 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11424 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11425 ;; and unsigned variants, respectively. For rev16, expose
11426 ;; byte-swapping in the lower 16 bits only.
11427 (define_insn "*arm_revsh"
11428 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11429 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11435 [(set_attr "arch" "t1,t2,32")
11436 (set_attr "length" "2,2,4")
11437 (set_attr "type" "rev")]
11440 (define_insn "*arm_rev16"
11441 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11442 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11448 [(set_attr "arch" "t1,t2,32")
11449 (set_attr "length" "2,2,4")
11450 (set_attr "type" "rev")]
11453 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11454 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11455 ;; each valid permutation.
11457 (define_insn "arm_rev16si2"
11458 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11459 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11461 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11462 (and:SI (lshiftrt:SI (match_dup 1)
11464 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11466 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11467 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11469 [(set_attr "arch" "t1,t2,32")
11470 (set_attr "length" "2,2,4")
11471 (set_attr "type" "rev")]
11474 (define_insn "arm_rev16si2_alt"
11475 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11476 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11478 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11479 (and:SI (ashift:SI (match_dup 1)
11481 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11483 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11484 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11486 [(set_attr "arch" "t1,t2,32")
11487 (set_attr "length" "2,2,4")
11488 (set_attr "type" "rev")]
11491 (define_expand "bswaphi2"
11492 [(set (match_operand:HI 0 "s_register_operand")
11493 (bswap:HI (match_operand:HI 1 "s_register_operand")))]
11498 ;; Patterns for LDRD/STRD in Thumb2 mode
11500 (define_insn "*thumb2_ldrd"
11501 [(set (match_operand:SI 0 "s_register_operand" "=r")
11502 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11503 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11504 (set (match_operand:SI 3 "s_register_operand" "=r")
11505 (mem:SI (plus:SI (match_dup 1)
11506 (match_operand:SI 4 "const_int_operand" ""))))]
11507 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11508 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11509 && (operands_ok_ldrd_strd (operands[0], operands[3],
11510 operands[1], INTVAL (operands[2]),
11512 "ldrd%?\t%0, %3, [%1, %2]"
11513 [(set_attr "type" "load_8")
11514 (set_attr "predicable" "yes")])
11516 (define_insn "*thumb2_ldrd_base"
11517 [(set (match_operand:SI 0 "s_register_operand" "=r")
11518 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11519 (set (match_operand:SI 2 "s_register_operand" "=r")
11520 (mem:SI (plus:SI (match_dup 1)
11522 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11523 && (operands_ok_ldrd_strd (operands[0], operands[2],
11524 operands[1], 0, false, true))"
11525 "ldrd%?\t%0, %2, [%1]"
11526 [(set_attr "type" "load_8")
11527 (set_attr "predicable" "yes")])
11529 (define_insn "*thumb2_ldrd_base_neg"
11530 [(set (match_operand:SI 0 "s_register_operand" "=r")
11531 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11533 (set (match_operand:SI 2 "s_register_operand" "=r")
11534 (mem:SI (match_dup 1)))]
11535 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11536 && (operands_ok_ldrd_strd (operands[0], operands[2],
11537 operands[1], -4, false, true))"
11538 "ldrd%?\t%0, %2, [%1, #-4]"
11539 [(set_attr "type" "load_8")
11540 (set_attr "predicable" "yes")])
11542 (define_insn "*thumb2_strd"
11543 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11544 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11545 (match_operand:SI 2 "s_register_operand" "r"))
11546 (set (mem:SI (plus:SI (match_dup 0)
11547 (match_operand:SI 3 "const_int_operand" "")))
11548 (match_operand:SI 4 "s_register_operand" "r"))]
11549 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11550 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11551 && (operands_ok_ldrd_strd (operands[2], operands[4],
11552 operands[0], INTVAL (operands[1]),
11554 "strd%?\t%2, %4, [%0, %1]"
11555 [(set_attr "type" "store_8")
11556 (set_attr "predicable" "yes")])
11558 (define_insn "*thumb2_strd_base"
11559 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11560 (match_operand:SI 1 "s_register_operand" "r"))
11561 (set (mem:SI (plus:SI (match_dup 0)
11563 (match_operand:SI 2 "s_register_operand" "r"))]
11564 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11565 && (operands_ok_ldrd_strd (operands[1], operands[2],
11566 operands[0], 0, false, false))"
11567 "strd%?\t%1, %2, [%0]"
11568 [(set_attr "type" "store_8")
11569 (set_attr "predicable" "yes")])
11571 (define_insn "*thumb2_strd_base_neg"
11572 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11574 (match_operand:SI 1 "s_register_operand" "r"))
11575 (set (mem:SI (match_dup 0))
11576 (match_operand:SI 2 "s_register_operand" "r"))]
11577 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11578 && (operands_ok_ldrd_strd (operands[1], operands[2],
11579 operands[0], -4, false, false))"
11580 "strd%?\t%1, %2, [%0, #-4]"
11581 [(set_attr "type" "store_8")
11582 (set_attr "predicable" "yes")])
11584 ;; ARMv8 CRC32 instructions.
11585 (define_insn "arm_<crc_variant>"
11586 [(set (match_operand:SI 0 "s_register_operand" "=r")
11587 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11588 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11591 "<crc_variant>\\t%0, %1, %2"
11592 [(set_attr "type" "crc")
11593 (set_attr "conds" "unconditional")]
11596 ;; Load the load/store double peephole optimizations.
11597 (include "ldrdstrd.md")
11599 ;; Load the load/store multiple patterns
11600 (include "ldmstm.md")
11602 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11603 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11604 ;; The operands are validated through the load_multiple_operation
11605 ;; match_parallel predicate rather than through constraints so enable it only
11607 (define_insn "*load_multiple"
11608 [(match_parallel 0 "load_multiple_operation"
11609 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11610 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11612 "TARGET_32BIT && reload_completed"
11615 arm_output_multireg_pop (operands, /*return_pc=*/false,
11616 /*cond=*/const_true_rtx,
11622 [(set_attr "predicable" "yes")]
11625 (define_expand "copysignsf3"
11626 [(match_operand:SF 0 "register_operand")
11627 (match_operand:SF 1 "register_operand")
11628 (match_operand:SF 2 "register_operand")]
11629 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11631 emit_move_insn (operands[0], operands[2]);
11632 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11633 GEN_INT (31), GEN_INT (0),
11634 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11639 (define_expand "copysigndf3"
11640 [(match_operand:DF 0 "register_operand")
11641 (match_operand:DF 1 "register_operand")
11642 (match_operand:DF 2 "register_operand")]
11643 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11645 rtx op0_low = gen_lowpart (SImode, operands[0]);
11646 rtx op0_high = gen_highpart (SImode, operands[0]);
11647 rtx op1_low = gen_lowpart (SImode, operands[1]);
11648 rtx op1_high = gen_highpart (SImode, operands[1]);
11649 rtx op2_high = gen_highpart (SImode, operands[2]);
11651 rtx scratch1 = gen_reg_rtx (SImode);
11652 rtx scratch2 = gen_reg_rtx (SImode);
11653 emit_move_insn (scratch1, op2_high);
11654 emit_move_insn (scratch2, op1_high);
11656 emit_insn(gen_rtx_SET(scratch1,
11657 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11658 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11659 emit_move_insn (op0_low, op1_low);
11660 emit_move_insn (op0_high, scratch2);
11666 ;; movmisalign patterns for HImode and SImode.
11667 (define_expand "movmisalign<mode>"
11668 [(match_operand:HSI 0 "general_operand")
11669 (match_operand:HSI 1 "general_operand")]
11672 /* This pattern is not permitted to fail during expansion: if both arguments
11673 are non-registers (e.g. memory := constant), force operand 1 into a
11675 rtx (* gen_unaligned_load)(rtx, rtx);
11676 rtx tmp_dest = operands[0];
11677 if (!s_register_operand (operands[0], <MODE>mode)
11678 && !s_register_operand (operands[1], <MODE>mode))
11679 operands[1] = force_reg (<MODE>mode, operands[1]);
11681 if (<MODE>mode == HImode)
11683 gen_unaligned_load = gen_unaligned_loadhiu;
11684 tmp_dest = gen_reg_rtx (SImode);
11687 gen_unaligned_load = gen_unaligned_loadsi;
11689 if (MEM_P (operands[1]))
11691 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11692 if (<MODE>mode == HImode)
11693 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11696 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11701 (define_insn "arm_<cdp>"
11702 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11703 (match_operand:SI 1 "immediate_operand" "n")
11704 (match_operand:SI 2 "immediate_operand" "n")
11705 (match_operand:SI 3 "immediate_operand" "n")
11706 (match_operand:SI 4 "immediate_operand" "n")
11707 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11708 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11710 arm_const_bounds (operands[0], 0, 16);
11711 arm_const_bounds (operands[1], 0, 16);
11712 arm_const_bounds (operands[2], 0, (1 << 5));
11713 arm_const_bounds (operands[3], 0, (1 << 5));
11714 arm_const_bounds (operands[4], 0, (1 << 5));
11715 arm_const_bounds (operands[5], 0, 8);
11716 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11718 [(set_attr "length" "4")
11719 (set_attr "type" "coproc")])
11721 (define_insn "*ldc"
11722 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11723 (match_operand:SI 1 "immediate_operand" "n")
11724 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11725 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11727 arm_const_bounds (operands[0], 0, 16);
11728 arm_const_bounds (operands[1], 0, (1 << 5));
11729 return "<ldc>\\tp%c0, CR%c1, %2";
11731 [(set_attr "length" "4")
11732 (set_attr "type" "coproc")])
11734 (define_insn "*stc"
11735 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11736 (match_operand:SI 1 "immediate_operand" "n")
11737 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11738 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11740 arm_const_bounds (operands[0], 0, 16);
11741 arm_const_bounds (operands[1], 0, (1 << 5));
11742 return "<stc>\\tp%c0, CR%c1, %2";
11744 [(set_attr "length" "4")
11745 (set_attr "type" "coproc")])
11747 (define_expand "arm_<ldc>"
11748 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11749 (match_operand:SI 1 "immediate_operand")
11750 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11751 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11753 (define_expand "arm_<stc>"
11754 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11755 (match_operand:SI 1 "immediate_operand")
11756 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11757 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
11759 (define_insn "arm_<mcr>"
11760 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11761 (match_operand:SI 1 "immediate_operand" "n")
11762 (match_operand:SI 2 "s_register_operand" "r")
11763 (match_operand:SI 3 "immediate_operand" "n")
11764 (match_operand:SI 4 "immediate_operand" "n")
11765 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
11766 (use (match_dup 2))]
11767 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
11769 arm_const_bounds (operands[0], 0, 16);
11770 arm_const_bounds (operands[1], 0, 8);
11771 arm_const_bounds (operands[3], 0, (1 << 5));
11772 arm_const_bounds (operands[4], 0, (1 << 5));
11773 arm_const_bounds (operands[5], 0, 8);
11774 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
11776 [(set_attr "length" "4")
11777 (set_attr "type" "coproc")])
11779 (define_insn "arm_<mrc>"
11780 [(set (match_operand:SI 0 "s_register_operand" "=r")
11781 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
11782 (match_operand:SI 2 "immediate_operand" "n")
11783 (match_operand:SI 3 "immediate_operand" "n")
11784 (match_operand:SI 4 "immediate_operand" "n")
11785 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
11786 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
11788 arm_const_bounds (operands[1], 0, 16);
11789 arm_const_bounds (operands[2], 0, 8);
11790 arm_const_bounds (operands[3], 0, (1 << 5));
11791 arm_const_bounds (operands[4], 0, (1 << 5));
11792 arm_const_bounds (operands[5], 0, 8);
11793 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
11795 [(set_attr "length" "4")
11796 (set_attr "type" "coproc")])
11798 (define_insn "arm_<mcrr>"
11799 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11800 (match_operand:SI 1 "immediate_operand" "n")
11801 (match_operand:DI 2 "s_register_operand" "r")
11802 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
11803 (use (match_dup 2))]
11804 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
11806 arm_const_bounds (operands[0], 0, 16);
11807 arm_const_bounds (operands[1], 0, 8);
11808 arm_const_bounds (operands[3], 0, (1 << 5));
11809 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
11811 [(set_attr "length" "4")
11812 (set_attr "type" "coproc")])
11814 (define_insn "arm_<mrrc>"
11815 [(set (match_operand:DI 0 "s_register_operand" "=r")
11816 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
11817 (match_operand:SI 2 "immediate_operand" "n")
11818 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
11819 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
11821 arm_const_bounds (operands[1], 0, 16);
11822 arm_const_bounds (operands[2], 0, 8);
11823 arm_const_bounds (operands[3], 0, (1 << 5));
11824 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
11826 [(set_attr "length" "4")
11827 (set_attr "type" "coproc")])
11829 (define_expand "speculation_barrier"
11830 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
11833 /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
11834 have a usable barrier (and probably don't need one in practice).
11835 But to be safe if such code is run on later architectures, call a
11836 helper function in libgcc that will do the thing for the active
11838 if (!(arm_arch7 || arm_arch8))
11840 arm_emit_speculation_barrier_function ();
11846 ;; Generate a hard speculation barrier when we have not enabled speculation
11848 (define_insn "*speculation_barrier_insn"
11849 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
11850 "arm_arch7 || arm_arch8"
11852 [(set_attr "type" "block")
11853 (set_attr "length" "8")]
11856 ;; Vector bits common to IWMMXT and Neon
11857 (include "vec-common.md")
11858 ;; Load the Intel Wireless Multimedia Extension patterns
11859 (include "iwmmxt.md")
11860 ;; Load the VFP co-processor patterns
11862 ;; Thumb-1 patterns
11863 (include "thumb1.md")
11864 ;; Thumb-2 patterns
11865 (include "thumb2.md")
11867 (include "neon.md")
11869 (include "crypto.md")
11870 ;; Synchronization Primitives
11871 (include "sync.md")
11872 ;; Fixed-point patterns
11873 (include "arm-fixed.md")