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 (IP_REGNUM 12) ; Scratch register
35 (SP_REGNUM 13) ; Stack pointer
36 (LR_REGNUM 14) ; Return address register
37 (PC_REGNUM 15) ; Program counter
38 (LAST_ARM_REGNUM 15) ;
39 (CC_REGNUM 100) ; Condition code pseudo register
40 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
43 ;; 3rd operand to select_dominance_cc_mode
50 ;; conditional compare combination
61 ;;---------------------------------------------------------------------------
64 ;; Processor type. This is created automatically from arm-cores.def.
65 (include "arm-tune.md")
67 ;; Instruction classification types
70 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
71 ; generating ARM code. This is used to control the length of some insn
72 ; patterns that share the same RTL in both ARM and Thumb code.
73 (define_attr "is_thumb" "yes,no"
74 (const (if_then_else (symbol_ref "TARGET_THUMB")
75 (const_string "yes") (const_string "no"))))
77 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
78 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
80 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
81 (define_attr "is_thumb1" "yes,no"
82 (const (if_then_else (symbol_ref "TARGET_THUMB1")
83 (const_string "yes") (const_string "no"))))
85 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
86 ; The arm_restrict_it flag enables the "short IT" feature which
87 ; restricts IT blocks to a single 16-bit instruction.
88 ; This attribute should only be used on 16-bit Thumb-2 instructions
89 ; which may be predicated (the "predicable" attribute must be set).
90 (define_attr "predicable_short_it" "no,yes" (const_string "no"))
92 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
93 ; This attribute should only be used on instructions which may emit
94 ; an IT block in their expansion which is not a short IT.
95 (define_attr "enabled_for_short_it" "no,yes" (const_string "yes"))
97 ;; Operand number of an input operand that is shifted. Zero if the
98 ;; given instruction does not shift one of its input operands.
99 (define_attr "shift" "" (const_int 0))
101 ;; [For compatibility with AArch64 in pipeline models]
102 ;; Attribute that specifies whether or not the instruction touches fp
104 (define_attr "fp" "no,yes" (const_string "no"))
106 ; Floating Point Unit. If we only have floating point emulation, then there
107 ; is no point in scheduling the floating point insns. (Well, for best
108 ; performance we should try and group them together).
109 (define_attr "fpu" "none,vfp"
110 (const (symbol_ref "arm_fpu_attr")))
112 ; Predicated means that the insn form is conditionally executed based on a
113 ; predicate. We default to 'no' because no Thumb patterns match this rule
114 ; and not all ARM insns do.
115 (define_attr "predicated" "yes,no" (const_string "no"))
117 ; LENGTH of an instruction (in bytes)
118 (define_attr "length" ""
121 ; The architecture which supports the instruction (or alternative).
122 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
123 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
124 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
125 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
126 ; Baseline. This attribute is used to compute attribute "enabled",
127 ; use type "any" to enable an alternative in all cases.
128 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
129 (const_string "any"))
131 (define_attr "arch_enabled" "no,yes"
132 (cond [(eq_attr "arch" "any")
135 (and (eq_attr "arch" "a")
136 (match_test "TARGET_ARM"))
139 (and (eq_attr "arch" "t")
140 (match_test "TARGET_THUMB"))
143 (and (eq_attr "arch" "t1")
144 (match_test "TARGET_THUMB1"))
147 (and (eq_attr "arch" "t2")
148 (match_test "TARGET_THUMB2"))
151 (and (eq_attr "arch" "32")
152 (match_test "TARGET_32BIT"))
155 (and (eq_attr "arch" "v6")
156 (match_test "TARGET_32BIT && arm_arch6"))
159 (and (eq_attr "arch" "nov6")
160 (match_test "TARGET_32BIT && !arm_arch6"))
163 (and (eq_attr "arch" "v6t2")
164 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
167 (and (eq_attr "arch" "v8mb")
168 (match_test "TARGET_THUMB1 && arm_arch8"))
171 (and (eq_attr "arch" "avoid_neon_for_64bits")
172 (match_test "TARGET_NEON")
173 (not (match_test "TARGET_PREFER_NEON_64BITS")))
176 (and (eq_attr "arch" "neon_for_64bits")
177 (match_test "TARGET_NEON")
178 (match_test "TARGET_PREFER_NEON_64BITS"))
181 (and (eq_attr "arch" "iwmmxt2")
182 (match_test "TARGET_REALLY_IWMMXT2"))
185 (and (eq_attr "arch" "armv6_or_vfpv3")
186 (match_test "arm_arch6 || TARGET_VFP3"))
189 (and (eq_attr "arch" "neon")
190 (match_test "TARGET_NEON"))
194 (const_string "no")))
196 (define_attr "opt" "any,speed,size"
197 (const_string "any"))
199 (define_attr "opt_enabled" "no,yes"
200 (cond [(eq_attr "opt" "any")
203 (and (eq_attr "opt" "speed")
204 (match_test "optimize_function_for_speed_p (cfun)"))
207 (and (eq_attr "opt" "size")
208 (match_test "optimize_function_for_size_p (cfun)"))
209 (const_string "yes")]
210 (const_string "no")))
212 (define_attr "use_literal_pool" "no,yes"
213 (cond [(and (eq_attr "type" "f_loads,f_loadd")
214 (match_test "CONSTANT_P (operands[1])"))
215 (const_string "yes")]
216 (const_string "no")))
218 ; Enable all alternatives that are both arch_enabled and insn_enabled.
219 ; FIXME:: opt_enabled has been temporarily removed till the time we have
220 ; an attribute that allows the use of such alternatives.
221 ; This depends on caching of speed_p, size_p on a per
222 ; alternative basis. The problem is that the enabled attribute
223 ; cannot depend on any state that is not cached or is not constant
224 ; for a compilation unit. We probably need a generic "hot/cold"
225 ; alternative which if implemented can help with this. We disable this
226 ; until such a time as this is implemented and / or the improvements or
227 ; regressions with removing this attribute are double checked.
228 ; See ashldi3_neon and <shift>di3_neon in neon.md.
230 (define_attr "enabled" "no,yes"
231 (cond [(and (eq_attr "predicable_short_it" "no")
232 (and (eq_attr "predicated" "yes")
233 (match_test "arm_restrict_it")))
236 (and (eq_attr "enabled_for_short_it" "no")
237 (match_test "arm_restrict_it"))
240 (eq_attr "arch_enabled" "no")
242 (const_string "yes")))
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed. If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address. It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
257 (define_attr "pool_range" ""
258 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259 (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262 (attr "arm_neg_pool_range")))
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268 [(set_attr "conds" "clob")
269 (set_attr "length" "4")
270 (set_attr "pool_range" "250")])
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions. It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
280 ; USE means that the condition codes are used by the insn in the process of
281 ; outputting code, this means (at present) that we can't use the insn in
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ; well defined manner.
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ; they are altered at all
290 ; UNCONDITIONAL means the instruction cannot be conditionally executed and
291 ; that the instruction does not use or alter the condition codes.
293 ; NOCOND means that the instruction does not use or alter the condition
294 ; codes but can be converted into a conditionally exectuted instruction.
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
298 (ior (eq_attr "is_thumb1" "yes")
299 (eq_attr "type" "call"))
300 (const_string "clob")
301 (if_then_else (eq_attr "is_neon_type" "no")
302 (const_string "nocond")
303 (const_string "unconditional"))))
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by
307 ; gen...). We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
311 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
312 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor. Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320 (if_then_else (eq_attr "type"
323 (const_string "no")))
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328 (if_then_else (eq_attr "type"
329 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345 (const_string "single")
346 (const_string "multi")))
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label. Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
357 ;;---------------------------------------------------------------------------
360 (include "unspecs.md")
362 ;;---------------------------------------------------------------------------
365 (include "iterators.md")
367 ;;---------------------------------------------------------------------------
370 (include "predicates.md")
371 (include "constraints.md")
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
376 (define_attr "tune_cortexr4" "yes,no"
378 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
380 (const_string "no"))))
382 ;; True if the generic scheduling description should be used.
384 (define_attr "generic_sched" "yes,no"
386 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387 arm926ejs,arm10e,arm1026ejs,arm1136js,\
388 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389 cortexa9,cortexa12,cortexa15,cortexa17,\
390 cortexa53,cortexa57,cortexm4,cortexm7,\
391 exynosm1,marvell_pj4,xgene1")
392 (eq_attr "tune_cortexr4" "yes"))
394 (const_string "yes"))))
396 (define_attr "generic_vfp" "yes,no"
398 (and (eq_attr "fpu" "vfp")
399 (eq_attr "tune" "!arm10e,cortexa5,cortexa7,\
400 cortexa8,cortexa9,cortexa53,cortexm4,\
401 cortexm7,marvell_pj4,xgene1")
402 (eq_attr "tune_cortexr4" "no"))
404 (const_string "no"))))
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
436 ;;---------------------------------------------------------------------------
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
445 (define_expand "adddi3"
447 [(set (match_operand:DI 0 "s_register_operand" "")
448 (plus:DI (match_operand:DI 1 "s_register_operand" "")
449 (match_operand:DI 2 "arm_adddi_operand" "")))
450 (clobber (reg:CC CC_REGNUM))])]
455 if (!REG_P (operands[1]))
456 operands[1] = force_reg (DImode, operands[1]);
457 if (!REG_P (operands[2]))
458 operands[2] = force_reg (DImode, operands[2]);
463 (define_insn_and_split "*arm_adddi3"
464 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r,&r,&r")
465 (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r")
466 (match_operand:DI 2 "arm_general_adddi_operand" "r, 0, r, Dd, Dd")))
467 (clobber (reg:CC CC_REGNUM))]
468 "TARGET_32BIT && !TARGET_NEON"
470 "TARGET_32BIT && ((!TARGET_NEON && !TARGET_IWMMXT) || reload_completed)"
471 [(parallel [(set (reg:CC_C CC_REGNUM)
472 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
474 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
475 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
476 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
479 operands[3] = gen_highpart (SImode, operands[0]);
480 operands[0] = gen_lowpart (SImode, operands[0]);
481 operands[4] = gen_highpart (SImode, operands[1]);
482 operands[1] = gen_lowpart (SImode, operands[1]);
483 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
484 operands[2] = gen_lowpart (SImode, operands[2]);
486 [(set_attr "conds" "clob")
487 (set_attr "length" "8")
488 (set_attr "type" "multiple")]
491 (define_insn_and_split "*adddi_sesidi_di"
492 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
493 (plus:DI (sign_extend:DI
494 (match_operand:SI 2 "s_register_operand" "r,r"))
495 (match_operand:DI 1 "s_register_operand" "0,r")))
496 (clobber (reg:CC CC_REGNUM))]
499 "TARGET_32BIT && reload_completed"
500 [(parallel [(set (reg:CC_C CC_REGNUM)
501 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
503 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
504 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
507 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
510 operands[3] = gen_highpart (SImode, operands[0]);
511 operands[0] = gen_lowpart (SImode, operands[0]);
512 operands[4] = gen_highpart (SImode, operands[1]);
513 operands[1] = gen_lowpart (SImode, operands[1]);
514 operands[2] = gen_lowpart (SImode, operands[2]);
516 [(set_attr "conds" "clob")
517 (set_attr "length" "8")
518 (set_attr "type" "multiple")]
521 (define_insn_and_split "*adddi_zesidi_di"
522 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
523 (plus:DI (zero_extend:DI
524 (match_operand:SI 2 "s_register_operand" "r,r"))
525 (match_operand:DI 1 "s_register_operand" "0,r")))
526 (clobber (reg:CC CC_REGNUM))]
529 "TARGET_32BIT && reload_completed"
530 [(parallel [(set (reg:CC_C CC_REGNUM)
531 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
533 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
534 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
535 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
538 operands[3] = gen_highpart (SImode, operands[0]);
539 operands[0] = gen_lowpart (SImode, operands[0]);
540 operands[4] = gen_highpart (SImode, operands[1]);
541 operands[1] = gen_lowpart (SImode, operands[1]);
542 operands[2] = gen_lowpart (SImode, operands[2]);
544 [(set_attr "conds" "clob")
545 (set_attr "length" "8")
546 (set_attr "type" "multiple")]
549 (define_expand "addv<mode>4"
550 [(match_operand:SIDI 0 "register_operand")
551 (match_operand:SIDI 1 "register_operand")
552 (match_operand:SIDI 2 "register_operand")
553 (match_operand 3 "")]
556 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
557 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
562 (define_expand "uaddv<mode>4"
563 [(match_operand:SIDI 0 "register_operand")
564 (match_operand:SIDI 1 "register_operand")
565 (match_operand:SIDI 2 "register_operand")
566 (match_operand 3 "")]
569 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
570 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
575 (define_expand "addsi3"
576 [(set (match_operand:SI 0 "s_register_operand" "")
577 (plus:SI (match_operand:SI 1 "s_register_operand" "")
578 (match_operand:SI 2 "reg_or_int_operand" "")))]
581 if (TARGET_32BIT && CONST_INT_P (operands[2]))
583 arm_split_constant (PLUS, SImode, NULL_RTX,
584 INTVAL (operands[2]), operands[0], operands[1],
585 optimize && can_create_pseudo_p ());
591 ; If there is a scratch available, this will be faster than synthesizing the
594 [(match_scratch:SI 3 "r")
595 (set (match_operand:SI 0 "arm_general_register_operand" "")
596 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
597 (match_operand:SI 2 "const_int_operand" "")))]
599 !(const_ok_for_arm (INTVAL (operands[2]))
600 || const_ok_for_arm (-INTVAL (operands[2])))
601 && const_ok_for_arm (~INTVAL (operands[2]))"
602 [(set (match_dup 3) (match_dup 2))
603 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
607 ;; The r/r/k alternative is required when reloading the address
608 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
609 ;; put the duplicated register first, and not try the commutative version.
610 (define_insn_and_split "*arm_addsi3"
611 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
612 (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")
613 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
629 subw%?\\t%0, %1, #%n2
630 subw%?\\t%0, %1, #%n2
633 && CONST_INT_P (operands[2])
634 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
635 && (reload_completed || !arm_eliminable_register (operands[1]))"
636 [(clobber (const_int 0))]
638 arm_split_constant (PLUS, SImode, curr_insn,
639 INTVAL (operands[2]), operands[0],
643 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
644 (set_attr "predicable" "yes")
645 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
646 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
647 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
648 (const_string "alu_imm")
649 (const_string "alu_sreg")))
653 (define_insn_and_split "adddi3_compareV"
654 [(set (reg:CC_V CC_REGNUM)
657 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
658 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
659 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
660 (set (match_operand:DI 0 "register_operand" "=&r")
661 (plus:DI (match_dup 1) (match_dup 2)))]
664 "&& reload_completed"
665 [(parallel [(set (reg:CC_C CC_REGNUM)
666 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
668 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
669 (parallel [(set (reg:CC_V CC_REGNUM)
672 (sign_extend:DI (match_dup 4))
673 (sign_extend:DI (match_dup 5)))
674 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
675 (plus:DI (sign_extend:DI
676 (plus:SI (match_dup 4) (match_dup 5)))
677 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
678 (set (match_dup 3) (plus:SI (plus:SI
679 (match_dup 4) (match_dup 5))
680 (ltu:SI (reg:CC_C CC_REGNUM)
684 operands[3] = gen_highpart (SImode, operands[0]);
685 operands[0] = gen_lowpart (SImode, operands[0]);
686 operands[4] = gen_highpart (SImode, operands[1]);
687 operands[1] = gen_lowpart (SImode, operands[1]);
688 operands[5] = gen_highpart (SImode, operands[2]);
689 operands[2] = gen_lowpart (SImode, operands[2]);
691 [(set_attr "conds" "set")
692 (set_attr "length" "8")
693 (set_attr "type" "multiple")]
696 (define_insn "addsi3_compareV"
697 [(set (reg:CC_V CC_REGNUM)
700 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
701 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
702 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
703 (set (match_operand:SI 0 "register_operand" "=r")
704 (plus:SI (match_dup 1) (match_dup 2)))]
706 "adds%?\\t%0, %1, %2"
707 [(set_attr "conds" "set")
708 (set_attr "type" "alus_sreg")]
711 (define_insn "*addsi3_compareV_upper"
712 [(set (reg:CC_V CC_REGNUM)
716 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
717 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
718 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
719 (plus:DI (sign_extend:DI
720 (plus:SI (match_dup 1) (match_dup 2)))
721 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
722 (set (match_operand:SI 0 "register_operand" "=r")
724 (plus:SI (match_dup 1) (match_dup 2))
725 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
727 "adcs%?\\t%0, %1, %2"
728 [(set_attr "conds" "set")
729 (set_attr "type" "adcs_reg")]
732 (define_insn_and_split "adddi3_compareC"
733 [(set (reg:CC_C CC_REGNUM)
736 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
737 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
738 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
739 (set (match_operand:DI 0 "register_operand" "=&r")
740 (plus:DI (match_dup 1) (match_dup 2)))]
743 "&& reload_completed"
744 [(parallel [(set (reg:CC_C CC_REGNUM)
745 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
747 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
748 (parallel [(set (reg:CC_C CC_REGNUM)
751 (zero_extend:DI (match_dup 4))
752 (zero_extend:DI (match_dup 5)))
753 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
754 (plus:DI (zero_extend:DI
755 (plus:SI (match_dup 4) (match_dup 5)))
756 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
757 (set (match_dup 3) (plus:SI
758 (plus:SI (match_dup 4) (match_dup 5))
759 (ltu:SI (reg:CC_C CC_REGNUM)
763 operands[3] = gen_highpart (SImode, operands[0]);
764 operands[0] = gen_lowpart (SImode, operands[0]);
765 operands[4] = gen_highpart (SImode, operands[1]);
766 operands[5] = gen_highpart (SImode, operands[2]);
767 operands[1] = gen_lowpart (SImode, operands[1]);
768 operands[2] = gen_lowpart (SImode, operands[2]);
770 [(set_attr "conds" "set")
771 (set_attr "length" "8")
772 (set_attr "type" "multiple")]
775 (define_insn "*addsi3_compareC_upper"
776 [(set (reg:CC_C CC_REGNUM)
780 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
781 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
782 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
783 (plus:DI (zero_extend:DI
784 (plus:SI (match_dup 1) (match_dup 2)))
785 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
786 (set (match_operand:SI 0 "register_operand" "=r")
788 (plus:SI (match_dup 1) (match_dup 2))
789 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
791 "adcs%?\\t%0, %1, %2"
792 [(set_attr "conds" "set")
793 (set_attr "type" "adcs_reg")]
796 (define_insn "addsi3_compareC"
797 [(set (reg:CC_C CC_REGNUM)
800 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
801 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
803 (plus:SI (match_dup 1) (match_dup 2)))))
804 (set (match_operand:SI 0 "register_operand" "=r")
805 (plus:SI (match_dup 1) (match_dup 2)))]
807 "adds%?\\t%0, %1, %2"
808 [(set_attr "conds" "set")
809 (set_attr "type" "alus_sreg")]
812 (define_insn "addsi3_compare0"
813 [(set (reg:CC_NOOV CC_REGNUM)
815 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
816 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
818 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
819 (plus:SI (match_dup 1) (match_dup 2)))]
823 subs%?\\t%0, %1, #%n2
825 [(set_attr "conds" "set")
826 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
829 (define_insn "*addsi3_compare0_scratch"
830 [(set (reg:CC_NOOV CC_REGNUM)
832 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
833 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
840 [(set_attr "conds" "set")
841 (set_attr "predicable" "yes")
842 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
845 (define_insn "*compare_negsi_si"
846 [(set (reg:CC_Z CC_REGNUM)
848 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
849 (match_operand:SI 1 "s_register_operand" "l,r")))]
852 [(set_attr "conds" "set")
853 (set_attr "predicable" "yes")
854 (set_attr "arch" "t2,*")
855 (set_attr "length" "2,4")
856 (set_attr "predicable_short_it" "yes,no")
857 (set_attr "type" "alus_sreg")]
860 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
861 ;; addend is a constant.
862 (define_insn "cmpsi2_addneg"
863 [(set (reg:CC CC_REGNUM)
865 (match_operand:SI 1 "s_register_operand" "r,r")
866 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
867 (set (match_operand:SI 0 "s_register_operand" "=r,r")
868 (plus:SI (match_dup 1)
869 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
871 && (INTVAL (operands[2])
872 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
874 /* For 0 and INT_MIN it is essential that we use subs, as adds
875 will result in different condition codes (like cmn rather than
876 like cmp). For other immediates, we should choose whatever
877 will have smaller encoding. */
878 if (operands[2] == const0_rtx
879 || INTVAL (operands[2]) == -HOST_WIDE_INT_C (0x80000000)
880 || which_alternative == 1)
881 return "subs%?\\t%0, %1, #%n3";
883 return "adds%?\\t%0, %1, %3";
885 [(set_attr "conds" "set")
886 (set_attr "type" "alus_sreg")]
889 ;; Convert the sequence
891 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
895 ;; bcs dest ((unsigned)rn >= 1)
896 ;; similarly for the beq variant using bcc.
897 ;; This is a common looping idiom (while (n--))
899 [(set (match_operand:SI 0 "arm_general_register_operand" "")
900 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
902 (set (match_operand 2 "cc_register" "")
903 (compare (match_dup 0) (const_int -1)))
905 (if_then_else (match_operator 3 "equality_operator"
906 [(match_dup 2) (const_int 0)])
907 (match_operand 4 "" "")
908 (match_operand 5 "" "")))]
909 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
913 (match_dup 1) (const_int 1)))
914 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
916 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
919 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
920 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
923 operands[2], const0_rtx);"
926 ;; The next four insns work because they compare the result with one of
927 ;; the operands, and we know that the use of the condition code is
928 ;; either GEU or LTU, so we can use the carry flag from the addition
929 ;; instead of doing the compare a second time.
930 (define_insn "*addsi3_compare_op1"
931 [(set (reg:CC_C CC_REGNUM)
933 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
934 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
936 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
937 (plus:SI (match_dup 1) (match_dup 2)))]
941 subs%?\\t%0, %1, #%n2
943 [(set_attr "conds" "set")
944 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
947 (define_insn "*addsi3_compare_op2"
948 [(set (reg:CC_C CC_REGNUM)
950 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
951 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
953 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
954 (plus:SI (match_dup 1) (match_dup 2)))]
958 subs%?\\t%0, %1, #%n2
960 [(set_attr "conds" "set")
961 (set_attr "type" "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_C 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 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
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")
1158 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1159 (match_operand:SI 2 "arm_neg_immediate_operand" "L"))
1160 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1162 "sbc\\t%0, %1, #%n2"
1163 [(set_attr "conds" "use")
1164 (set_attr "type" "adc_imm")]
1167 (define_insn "*subsi3_carryin_const0"
1168 [(set (match_operand:SI 0 "s_register_operand" "=r")
1169 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
1170 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1173 [(set_attr "conds" "use")
1174 (set_attr "type" "adc_imm")]
1177 (define_insn "*subsi3_carryin_compare"
1178 [(set (reg:CC CC_REGNUM)
1179 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1180 (match_operand:SI 2 "s_register_operand" "r")))
1181 (set (match_operand:SI 0 "s_register_operand" "=r")
1182 (minus:SI (minus:SI (match_dup 1)
1184 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
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")
1196 (minus:SI (plus:SI (match_dup 1)
1197 (match_operand:SI 3 "arm_neg_immediate_operand" "L"))
1198 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1200 && (INTVAL (operands[2])
1201 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
1202 "sbcs\\t%0, %1, #%n3"
1203 [(set_attr "conds" "set")
1204 (set_attr "type" "adcs_imm")]
1207 (define_insn "*subsi3_carryin_compare_const0"
1208 [(set (reg:CC CC_REGNUM)
1209 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1211 (set (match_operand:SI 0 "s_register_operand" "=r")
1212 (minus:SI (match_dup 1)
1213 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1216 [(set_attr "conds" "set")
1217 (set_attr "type" "adcs_imm")]
1220 (define_insn "*subsi3_carryin_shift"
1221 [(set (match_operand:SI 0 "s_register_operand" "=r")
1223 (match_operand:SI 1 "s_register_operand" "r")
1224 (match_operator:SI 2 "shift_operator"
1225 [(match_operand:SI 3 "s_register_operand" "r")
1226 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1227 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1229 "sbc%?\\t%0, %1, %3%S2"
1230 [(set_attr "conds" "use")
1231 (set_attr "predicable" "yes")
1232 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1233 (const_string "alu_shift_imm")
1234 (const_string "alu_shift_reg")))]
1237 (define_insn "*rsbsi3_carryin_shift"
1238 [(set (match_operand:SI 0 "s_register_operand" "=r")
1240 (match_operator:SI 2 "shift_operator"
1241 [(match_operand:SI 3 "s_register_operand" "r")
1242 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1243 (match_operand:SI 1 "s_register_operand" "r"))
1244 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1246 "rsc%?\\t%0, %1, %3%S2"
1247 [(set_attr "conds" "use")
1248 (set_attr "predicable" "yes")
1249 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1250 (const_string "alu_shift_imm")
1251 (const_string "alu_shift_reg")))]
1254 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1256 [(set (match_operand:SI 0 "s_register_operand" "")
1257 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1258 (match_operand:SI 2 "s_register_operand" ""))
1260 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1262 [(set (match_dup 3) (match_dup 1))
1263 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1265 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1268 (define_expand "addsf3"
1269 [(set (match_operand:SF 0 "s_register_operand" "")
1270 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1271 (match_operand:SF 2 "s_register_operand" "")))]
1272 "TARGET_32BIT && TARGET_HARD_FLOAT"
1276 (define_expand "adddf3"
1277 [(set (match_operand:DF 0 "s_register_operand" "")
1278 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1279 (match_operand:DF 2 "s_register_operand" "")))]
1280 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1284 (define_expand "subdi3"
1286 [(set (match_operand:DI 0 "s_register_operand" "")
1287 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1288 (match_operand:DI 2 "s_register_operand" "")))
1289 (clobber (reg:CC CC_REGNUM))])]
1294 if (!REG_P (operands[1]))
1295 operands[1] = force_reg (DImode, operands[1]);
1296 if (!REG_P (operands[2]))
1297 operands[2] = force_reg (DImode, operands[2]);
1302 (define_insn_and_split "*arm_subdi3"
1303 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
1304 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1305 (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1306 (clobber (reg:CC CC_REGNUM))]
1307 "TARGET_32BIT && !TARGET_NEON"
1308 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1309 "&& (!TARGET_IWMMXT || reload_completed)"
1310 [(parallel [(set (reg:CC CC_REGNUM)
1311 (compare:CC (match_dup 1) (match_dup 2)))
1312 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1313 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1314 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1316 operands[3] = gen_highpart (SImode, operands[0]);
1317 operands[0] = gen_lowpart (SImode, operands[0]);
1318 operands[4] = gen_highpart (SImode, operands[1]);
1319 operands[1] = gen_lowpart (SImode, operands[1]);
1320 operands[5] = gen_highpart (SImode, operands[2]);
1321 operands[2] = gen_lowpart (SImode, operands[2]);
1323 [(set_attr "conds" "clob")
1324 (set_attr "length" "8")
1325 (set_attr "type" "multiple")]
1328 (define_insn_and_split "*subdi_di_zesidi"
1329 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1330 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1332 (match_operand:SI 2 "s_register_operand" "r,r"))))
1333 (clobber (reg:CC CC_REGNUM))]
1335 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1336 "&& reload_completed"
1337 [(parallel [(set (reg:CC CC_REGNUM)
1338 (compare:CC (match_dup 1) (match_dup 2)))
1339 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1340 (set (match_dup 3) (minus:SI (match_dup 4)
1341 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1343 operands[3] = gen_highpart (SImode, operands[0]);
1344 operands[0] = gen_lowpart (SImode, operands[0]);
1345 operands[4] = gen_highpart (SImode, operands[1]);
1346 operands[1] = gen_lowpart (SImode, operands[1]);
1348 [(set_attr "conds" "clob")
1349 (set_attr "length" "8")
1350 (set_attr "type" "multiple")]
1353 (define_insn_and_split "*subdi_di_sesidi"
1354 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1355 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1357 (match_operand:SI 2 "s_register_operand" "r,r"))))
1358 (clobber (reg:CC CC_REGNUM))]
1360 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1361 "&& reload_completed"
1362 [(parallel [(set (reg:CC CC_REGNUM)
1363 (compare:CC (match_dup 1) (match_dup 2)))
1364 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1365 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1366 (ashiftrt:SI (match_dup 2)
1368 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1370 operands[3] = gen_highpart (SImode, operands[0]);
1371 operands[0] = gen_lowpart (SImode, operands[0]);
1372 operands[4] = gen_highpart (SImode, operands[1]);
1373 operands[1] = gen_lowpart (SImode, operands[1]);
1375 [(set_attr "conds" "clob")
1376 (set_attr "length" "8")
1377 (set_attr "type" "multiple")]
1380 (define_insn_and_split "*subdi_zesidi_di"
1381 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1382 (minus:DI (zero_extend:DI
1383 (match_operand:SI 2 "s_register_operand" "r,r"))
1384 (match_operand:DI 1 "s_register_operand" "0,r")))
1385 (clobber (reg:CC CC_REGNUM))]
1387 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1389 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1390 "&& reload_completed"
1391 [(parallel [(set (reg:CC CC_REGNUM)
1392 (compare:CC (match_dup 2) (match_dup 1)))
1393 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1394 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1395 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1397 operands[3] = gen_highpart (SImode, operands[0]);
1398 operands[0] = gen_lowpart (SImode, operands[0]);
1399 operands[4] = gen_highpart (SImode, operands[1]);
1400 operands[1] = gen_lowpart (SImode, operands[1]);
1402 [(set_attr "conds" "clob")
1403 (set_attr "length" "8")
1404 (set_attr "type" "multiple")]
1407 (define_insn_and_split "*subdi_sesidi_di"
1408 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1409 (minus:DI (sign_extend:DI
1410 (match_operand:SI 2 "s_register_operand" "r,r"))
1411 (match_operand:DI 1 "s_register_operand" "0,r")))
1412 (clobber (reg:CC CC_REGNUM))]
1414 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1416 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1417 "&& reload_completed"
1418 [(parallel [(set (reg:CC CC_REGNUM)
1419 (compare:CC (match_dup 2) (match_dup 1)))
1420 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1421 (set (match_dup 3) (minus:SI (minus:SI
1422 (ashiftrt:SI (match_dup 2)
1425 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1427 operands[3] = gen_highpart (SImode, operands[0]);
1428 operands[0] = gen_lowpart (SImode, operands[0]);
1429 operands[4] = gen_highpart (SImode, operands[1]);
1430 operands[1] = gen_lowpart (SImode, operands[1]);
1432 [(set_attr "conds" "clob")
1433 (set_attr "length" "8")
1434 (set_attr "type" "multiple")]
1437 (define_insn_and_split "*subdi_zesidi_zesidi"
1438 [(set (match_operand:DI 0 "s_register_operand" "=r")
1439 (minus:DI (zero_extend:DI
1440 (match_operand:SI 1 "s_register_operand" "r"))
1442 (match_operand:SI 2 "s_register_operand" "r"))))
1443 (clobber (reg:CC CC_REGNUM))]
1445 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1446 "&& reload_completed"
1447 [(parallel [(set (reg:CC CC_REGNUM)
1448 (compare:CC (match_dup 1) (match_dup 2)))
1449 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1450 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1451 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1453 operands[3] = gen_highpart (SImode, operands[0]);
1454 operands[0] = gen_lowpart (SImode, operands[0]);
1456 [(set_attr "conds" "clob")
1457 (set_attr "length" "8")
1458 (set_attr "type" "multiple")]
1461 (define_expand "subsi3"
1462 [(set (match_operand:SI 0 "s_register_operand" "")
1463 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1464 (match_operand:SI 2 "s_register_operand" "")))]
1467 if (CONST_INT_P (operands[1]))
1471 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1472 operands[1] = force_reg (SImode, operands[1]);
1475 arm_split_constant (MINUS, SImode, NULL_RTX,
1476 INTVAL (operands[1]), operands[0],
1478 optimize && can_create_pseudo_p ());
1482 else /* TARGET_THUMB1 */
1483 operands[1] = force_reg (SImode, operands[1]);
1488 ; ??? Check Thumb-2 split length
1489 (define_insn_and_split "*arm_subsi3_insn"
1490 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1491 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1492 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1504 "&& (CONST_INT_P (operands[1])
1505 && !const_ok_for_arm (INTVAL (operands[1])))"
1506 [(clobber (const_int 0))]
1508 arm_split_constant (MINUS, SImode, curr_insn,
1509 INTVAL (operands[1]), operands[0], operands[2], 0);
1512 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1513 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1514 (set_attr "predicable" "yes")
1515 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1516 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1520 [(match_scratch:SI 3 "r")
1521 (set (match_operand:SI 0 "arm_general_register_operand" "")
1522 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1523 (match_operand:SI 2 "arm_general_register_operand" "")))]
1525 && !const_ok_for_arm (INTVAL (operands[1]))
1526 && const_ok_for_arm (~INTVAL (operands[1]))"
1527 [(set (match_dup 3) (match_dup 1))
1528 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1532 (define_insn "subsi3_compare0"
1533 [(set (reg:CC_NOOV CC_REGNUM)
1535 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1536 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1538 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1539 (minus:SI (match_dup 1) (match_dup 2)))]
1544 rsbs%?\\t%0, %2, %1"
1545 [(set_attr "conds" "set")
1546 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1549 (define_insn "subsi3_compare"
1550 [(set (reg:CC CC_REGNUM)
1551 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1552 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1553 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1554 (minus:SI (match_dup 1) (match_dup 2)))]
1559 rsbs%?\\t%0, %2, %1"
1560 [(set_attr "conds" "set")
1561 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1564 (define_expand "subsf3"
1565 [(set (match_operand:SF 0 "s_register_operand" "")
1566 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1567 (match_operand:SF 2 "s_register_operand" "")))]
1568 "TARGET_32BIT && TARGET_HARD_FLOAT"
1572 (define_expand "subdf3"
1573 [(set (match_operand:DF 0 "s_register_operand" "")
1574 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1575 (match_operand:DF 2 "s_register_operand" "")))]
1576 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1581 ;; Multiplication insns
1583 (define_expand "mulhi3"
1584 [(set (match_operand:HI 0 "s_register_operand" "")
1585 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1586 (match_operand:HI 2 "s_register_operand" "")))]
1587 "TARGET_DSP_MULTIPLY"
1590 rtx result = gen_reg_rtx (SImode);
1591 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1592 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1597 (define_expand "mulsi3"
1598 [(set (match_operand:SI 0 "s_register_operand" "")
1599 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1600 (match_operand:SI 1 "s_register_operand" "")))]
1605 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1606 (define_insn "*arm_mulsi3"
1607 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1608 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1609 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1610 "TARGET_32BIT && !arm_arch6"
1611 "mul%?\\t%0, %2, %1"
1612 [(set_attr "type" "mul")
1613 (set_attr "predicable" "yes")]
1616 (define_insn "*arm_mulsi3_v6"
1617 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1618 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1619 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1620 "TARGET_32BIT && arm_arch6"
1621 "mul%?\\t%0, %1, %2"
1622 [(set_attr "type" "mul")
1623 (set_attr "predicable" "yes")
1624 (set_attr "arch" "t2,t2,*")
1625 (set_attr "length" "4")
1626 (set_attr "predicable_short_it" "yes,yes,no")]
1629 (define_insn "*mulsi3_compare0"
1630 [(set (reg:CC_NOOV CC_REGNUM)
1631 (compare:CC_NOOV (mult:SI
1632 (match_operand:SI 2 "s_register_operand" "r,r")
1633 (match_operand:SI 1 "s_register_operand" "%0,r"))
1635 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1636 (mult:SI (match_dup 2) (match_dup 1)))]
1637 "TARGET_ARM && !arm_arch6"
1638 "muls%?\\t%0, %2, %1"
1639 [(set_attr "conds" "set")
1640 (set_attr "type" "muls")]
1643 (define_insn "*mulsi3_compare0_v6"
1644 [(set (reg:CC_NOOV CC_REGNUM)
1645 (compare:CC_NOOV (mult:SI
1646 (match_operand:SI 2 "s_register_operand" "r")
1647 (match_operand:SI 1 "s_register_operand" "r"))
1649 (set (match_operand:SI 0 "s_register_operand" "=r")
1650 (mult:SI (match_dup 2) (match_dup 1)))]
1651 "TARGET_ARM && arm_arch6 && optimize_size"
1652 "muls%?\\t%0, %2, %1"
1653 [(set_attr "conds" "set")
1654 (set_attr "type" "muls")]
1657 (define_insn "*mulsi_compare0_scratch"
1658 [(set (reg:CC_NOOV CC_REGNUM)
1659 (compare:CC_NOOV (mult:SI
1660 (match_operand:SI 2 "s_register_operand" "r,r")
1661 (match_operand:SI 1 "s_register_operand" "%0,r"))
1663 (clobber (match_scratch:SI 0 "=&r,&r"))]
1664 "TARGET_ARM && !arm_arch6"
1665 "muls%?\\t%0, %2, %1"
1666 [(set_attr "conds" "set")
1667 (set_attr "type" "muls")]
1670 (define_insn "*mulsi_compare0_scratch_v6"
1671 [(set (reg:CC_NOOV CC_REGNUM)
1672 (compare:CC_NOOV (mult:SI
1673 (match_operand:SI 2 "s_register_operand" "r")
1674 (match_operand:SI 1 "s_register_operand" "r"))
1676 (clobber (match_scratch:SI 0 "=r"))]
1677 "TARGET_ARM && arm_arch6 && optimize_size"
1678 "muls%?\\t%0, %2, %1"
1679 [(set_attr "conds" "set")
1680 (set_attr "type" "muls")]
1683 ;; Unnamed templates to match MLA instruction.
1685 (define_insn "*mulsi3addsi"
1686 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1688 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1689 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1690 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1691 "TARGET_32BIT && !arm_arch6"
1692 "mla%?\\t%0, %2, %1, %3"
1693 [(set_attr "type" "mla")
1694 (set_attr "predicable" "yes")]
1697 (define_insn "*mulsi3addsi_v6"
1698 [(set (match_operand:SI 0 "s_register_operand" "=r")
1700 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1701 (match_operand:SI 1 "s_register_operand" "r"))
1702 (match_operand:SI 3 "s_register_operand" "r")))]
1703 "TARGET_32BIT && arm_arch6"
1704 "mla%?\\t%0, %2, %1, %3"
1705 [(set_attr "type" "mla")
1706 (set_attr "predicable" "yes")]
1709 (define_insn "*mulsi3addsi_compare0"
1710 [(set (reg:CC_NOOV CC_REGNUM)
1713 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1714 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1715 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1717 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1718 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1720 "TARGET_ARM && arm_arch6"
1721 "mlas%?\\t%0, %2, %1, %3"
1722 [(set_attr "conds" "set")
1723 (set_attr "type" "mlas")]
1726 (define_insn "*mulsi3addsi_compare0_v6"
1727 [(set (reg:CC_NOOV CC_REGNUM)
1730 (match_operand:SI 2 "s_register_operand" "r")
1731 (match_operand:SI 1 "s_register_operand" "r"))
1732 (match_operand:SI 3 "s_register_operand" "r"))
1734 (set (match_operand:SI 0 "s_register_operand" "=r")
1735 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1737 "TARGET_ARM && arm_arch6 && optimize_size"
1738 "mlas%?\\t%0, %2, %1, %3"
1739 [(set_attr "conds" "set")
1740 (set_attr "type" "mlas")]
1743 (define_insn "*mulsi3addsi_compare0_scratch"
1744 [(set (reg:CC_NOOV CC_REGNUM)
1747 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1748 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1749 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1751 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1752 "TARGET_ARM && !arm_arch6"
1753 "mlas%?\\t%0, %2, %1, %3"
1754 [(set_attr "conds" "set")
1755 (set_attr "type" "mlas")]
1758 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1759 [(set (reg:CC_NOOV CC_REGNUM)
1762 (match_operand:SI 2 "s_register_operand" "r")
1763 (match_operand:SI 1 "s_register_operand" "r"))
1764 (match_operand:SI 3 "s_register_operand" "r"))
1766 (clobber (match_scratch:SI 0 "=r"))]
1767 "TARGET_ARM && arm_arch6 && optimize_size"
1768 "mlas%?\\t%0, %2, %1, %3"
1769 [(set_attr "conds" "set")
1770 (set_attr "type" "mlas")]
1773 (define_insn "*mulsi3subsi"
1774 [(set (match_operand:SI 0 "s_register_operand" "=r")
1776 (match_operand:SI 3 "s_register_operand" "r")
1777 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1778 (match_operand:SI 1 "s_register_operand" "r"))))]
1779 "TARGET_32BIT && arm_arch_thumb2"
1780 "mls%?\\t%0, %2, %1, %3"
1781 [(set_attr "type" "mla")
1782 (set_attr "predicable" "yes")]
1785 (define_expand "maddsidi4"
1786 [(set (match_operand:DI 0 "s_register_operand" "")
1789 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1790 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1791 (match_operand:DI 3 "s_register_operand" "")))]
1795 (define_insn "*mulsidi3adddi"
1796 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1799 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1800 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1801 (match_operand:DI 1 "s_register_operand" "0")))]
1802 "TARGET_32BIT && !arm_arch6"
1803 "smlal%?\\t%Q0, %R0, %3, %2"
1804 [(set_attr "type" "smlal")
1805 (set_attr "predicable" "yes")]
1808 (define_insn "*mulsidi3adddi_v6"
1809 [(set (match_operand:DI 0 "s_register_operand" "=r")
1812 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1813 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1814 (match_operand:DI 1 "s_register_operand" "0")))]
1815 "TARGET_32BIT && arm_arch6"
1816 "smlal%?\\t%Q0, %R0, %3, %2"
1817 [(set_attr "type" "smlal")
1818 (set_attr "predicable" "yes")]
1821 ;; 32x32->64 widening multiply.
1822 ;; As with mulsi3, the only difference between the v3-5 and v6+
1823 ;; versions of these patterns is the requirement that the output not
1824 ;; overlap the inputs, but that still means we have to have a named
1825 ;; expander and two different starred insns.
1827 (define_expand "mulsidi3"
1828 [(set (match_operand:DI 0 "s_register_operand" "")
1830 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1831 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1836 (define_insn "*mulsidi3_nov6"
1837 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1839 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1840 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1841 "TARGET_32BIT && !arm_arch6"
1842 "smull%?\\t%Q0, %R0, %1, %2"
1843 [(set_attr "type" "smull")
1844 (set_attr "predicable" "yes")]
1847 (define_insn "*mulsidi3_v6"
1848 [(set (match_operand:DI 0 "s_register_operand" "=r")
1850 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1851 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1852 "TARGET_32BIT && arm_arch6"
1853 "smull%?\\t%Q0, %R0, %1, %2"
1854 [(set_attr "type" "smull")
1855 (set_attr "predicable" "yes")]
1858 (define_expand "umulsidi3"
1859 [(set (match_operand:DI 0 "s_register_operand" "")
1861 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1862 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1867 (define_insn "*umulsidi3_nov6"
1868 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1870 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1871 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1872 "TARGET_32BIT && !arm_arch6"
1873 "umull%?\\t%Q0, %R0, %1, %2"
1874 [(set_attr "type" "umull")
1875 (set_attr "predicable" "yes")]
1878 (define_insn "*umulsidi3_v6"
1879 [(set (match_operand:DI 0 "s_register_operand" "=r")
1881 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1882 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1883 "TARGET_32BIT && arm_arch6"
1884 "umull%?\\t%Q0, %R0, %1, %2"
1885 [(set_attr "type" "umull")
1886 (set_attr "predicable" "yes")]
1889 (define_expand "umaddsidi4"
1890 [(set (match_operand:DI 0 "s_register_operand" "")
1893 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1894 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1895 (match_operand:DI 3 "s_register_operand" "")))]
1899 (define_insn "*umulsidi3adddi"
1900 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1903 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1904 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1905 (match_operand:DI 1 "s_register_operand" "0")))]
1906 "TARGET_32BIT && !arm_arch6"
1907 "umlal%?\\t%Q0, %R0, %3, %2"
1908 [(set_attr "type" "umlal")
1909 (set_attr "predicable" "yes")]
1912 (define_insn "*umulsidi3adddi_v6"
1913 [(set (match_operand:DI 0 "s_register_operand" "=r")
1916 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1917 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1918 (match_operand:DI 1 "s_register_operand" "0")))]
1919 "TARGET_32BIT && arm_arch6"
1920 "umlal%?\\t%Q0, %R0, %3, %2"
1921 [(set_attr "type" "umlal")
1922 (set_attr "predicable" "yes")]
1925 (define_expand "smulsi3_highpart"
1927 [(set (match_operand:SI 0 "s_register_operand" "")
1931 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1932 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1934 (clobber (match_scratch:SI 3 ""))])]
1939 (define_insn "*smulsi3_highpart_nov6"
1940 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1944 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1945 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1947 (clobber (match_scratch:SI 3 "=&r,&r"))]
1948 "TARGET_32BIT && !arm_arch6"
1949 "smull%?\\t%3, %0, %2, %1"
1950 [(set_attr "type" "smull")
1951 (set_attr "predicable" "yes")]
1954 (define_insn "*smulsi3_highpart_v6"
1955 [(set (match_operand:SI 0 "s_register_operand" "=r")
1959 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1960 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1962 (clobber (match_scratch:SI 3 "=r"))]
1963 "TARGET_32BIT && arm_arch6"
1964 "smull%?\\t%3, %0, %2, %1"
1965 [(set_attr "type" "smull")
1966 (set_attr "predicable" "yes")]
1969 (define_expand "umulsi3_highpart"
1971 [(set (match_operand:SI 0 "s_register_operand" "")
1975 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1976 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1978 (clobber (match_scratch:SI 3 ""))])]
1983 (define_insn "*umulsi3_highpart_nov6"
1984 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1988 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1989 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1991 (clobber (match_scratch:SI 3 "=&r,&r"))]
1992 "TARGET_32BIT && !arm_arch6"
1993 "umull%?\\t%3, %0, %2, %1"
1994 [(set_attr "type" "umull")
1995 (set_attr "predicable" "yes")]
1998 (define_insn "*umulsi3_highpart_v6"
1999 [(set (match_operand:SI 0 "s_register_operand" "=r")
2003 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
2004 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
2006 (clobber (match_scratch:SI 3 "=r"))]
2007 "TARGET_32BIT && arm_arch6"
2008 "umull%?\\t%3, %0, %2, %1"
2009 [(set_attr "type" "umull")
2010 (set_attr "predicable" "yes")]
2013 (define_insn "mulhisi3"
2014 [(set (match_operand:SI 0 "s_register_operand" "=r")
2015 (mult:SI (sign_extend:SI
2016 (match_operand:HI 1 "s_register_operand" "%r"))
2018 (match_operand:HI 2 "s_register_operand" "r"))))]
2019 "TARGET_DSP_MULTIPLY"
2020 "smulbb%?\\t%0, %1, %2"
2021 [(set_attr "type" "smulxy")
2022 (set_attr "predicable" "yes")]
2025 (define_insn "*mulhisi3tb"
2026 [(set (match_operand:SI 0 "s_register_operand" "=r")
2027 (mult:SI (ashiftrt:SI
2028 (match_operand:SI 1 "s_register_operand" "r")
2031 (match_operand:HI 2 "s_register_operand" "r"))))]
2032 "TARGET_DSP_MULTIPLY"
2033 "smultb%?\\t%0, %1, %2"
2034 [(set_attr "type" "smulxy")
2035 (set_attr "predicable" "yes")]
2038 (define_insn "*mulhisi3bt"
2039 [(set (match_operand:SI 0 "s_register_operand" "=r")
2040 (mult:SI (sign_extend:SI
2041 (match_operand:HI 1 "s_register_operand" "r"))
2043 (match_operand:SI 2 "s_register_operand" "r")
2045 "TARGET_DSP_MULTIPLY"
2046 "smulbt%?\\t%0, %1, %2"
2047 [(set_attr "type" "smulxy")
2048 (set_attr "predicable" "yes")]
2051 (define_insn "*mulhisi3tt"
2052 [(set (match_operand:SI 0 "s_register_operand" "=r")
2053 (mult:SI (ashiftrt:SI
2054 (match_operand:SI 1 "s_register_operand" "r")
2057 (match_operand:SI 2 "s_register_operand" "r")
2059 "TARGET_DSP_MULTIPLY"
2060 "smultt%?\\t%0, %1, %2"
2061 [(set_attr "type" "smulxy")
2062 (set_attr "predicable" "yes")]
2065 (define_insn "maddhisi4"
2066 [(set (match_operand:SI 0 "s_register_operand" "=r")
2067 (plus:SI (mult:SI (sign_extend:SI
2068 (match_operand:HI 1 "s_register_operand" "r"))
2070 (match_operand:HI 2 "s_register_operand" "r")))
2071 (match_operand:SI 3 "s_register_operand" "r")))]
2072 "TARGET_DSP_MULTIPLY"
2073 "smlabb%?\\t%0, %1, %2, %3"
2074 [(set_attr "type" "smlaxy")
2075 (set_attr "predicable" "yes")]
2078 ;; Note: there is no maddhisi4ibt because this one is canonical form
2079 (define_insn "*maddhisi4tb"
2080 [(set (match_operand:SI 0 "s_register_operand" "=r")
2081 (plus:SI (mult:SI (ashiftrt:SI
2082 (match_operand:SI 1 "s_register_operand" "r")
2085 (match_operand:HI 2 "s_register_operand" "r")))
2086 (match_operand:SI 3 "s_register_operand" "r")))]
2087 "TARGET_DSP_MULTIPLY"
2088 "smlatb%?\\t%0, %1, %2, %3"
2089 [(set_attr "type" "smlaxy")
2090 (set_attr "predicable" "yes")]
2093 (define_insn "*maddhisi4tt"
2094 [(set (match_operand:SI 0 "s_register_operand" "=r")
2095 (plus:SI (mult:SI (ashiftrt:SI
2096 (match_operand:SI 1 "s_register_operand" "r")
2099 (match_operand:SI 2 "s_register_operand" "r")
2101 (match_operand:SI 3 "s_register_operand" "r")))]
2102 "TARGET_DSP_MULTIPLY"
2103 "smlatt%?\\t%0, %1, %2, %3"
2104 [(set_attr "type" "smlaxy")
2105 (set_attr "predicable" "yes")]
2108 (define_insn "maddhidi4"
2109 [(set (match_operand:DI 0 "s_register_operand" "=r")
2111 (mult:DI (sign_extend:DI
2112 (match_operand:HI 1 "s_register_operand" "r"))
2114 (match_operand:HI 2 "s_register_operand" "r")))
2115 (match_operand:DI 3 "s_register_operand" "0")))]
2116 "TARGET_DSP_MULTIPLY"
2117 "smlalbb%?\\t%Q0, %R0, %1, %2"
2118 [(set_attr "type" "smlalxy")
2119 (set_attr "predicable" "yes")])
2121 ;; Note: there is no maddhidi4ibt because this one is canonical form
2122 (define_insn "*maddhidi4tb"
2123 [(set (match_operand:DI 0 "s_register_operand" "=r")
2125 (mult:DI (sign_extend:DI
2127 (match_operand:SI 1 "s_register_operand" "r")
2130 (match_operand:HI 2 "s_register_operand" "r")))
2131 (match_operand:DI 3 "s_register_operand" "0")))]
2132 "TARGET_DSP_MULTIPLY"
2133 "smlaltb%?\\t%Q0, %R0, %1, %2"
2134 [(set_attr "type" "smlalxy")
2135 (set_attr "predicable" "yes")])
2137 (define_insn "*maddhidi4tt"
2138 [(set (match_operand:DI 0 "s_register_operand" "=r")
2140 (mult:DI (sign_extend:DI
2142 (match_operand:SI 1 "s_register_operand" "r")
2146 (match_operand:SI 2 "s_register_operand" "r")
2148 (match_operand:DI 3 "s_register_operand" "0")))]
2149 "TARGET_DSP_MULTIPLY"
2150 "smlaltt%?\\t%Q0, %R0, %1, %2"
2151 [(set_attr "type" "smlalxy")
2152 (set_attr "predicable" "yes")])
2154 (define_expand "mulsf3"
2155 [(set (match_operand:SF 0 "s_register_operand" "")
2156 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2157 (match_operand:SF 2 "s_register_operand" "")))]
2158 "TARGET_32BIT && TARGET_HARD_FLOAT"
2162 (define_expand "muldf3"
2163 [(set (match_operand:DF 0 "s_register_operand" "")
2164 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2165 (match_operand:DF 2 "s_register_operand" "")))]
2166 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2172 (define_expand "divsf3"
2173 [(set (match_operand:SF 0 "s_register_operand" "")
2174 (div:SF (match_operand:SF 1 "s_register_operand" "")
2175 (match_operand:SF 2 "s_register_operand" "")))]
2176 "TARGET_32BIT && TARGET_HARD_FLOAT"
2179 (define_expand "divdf3"
2180 [(set (match_operand:DF 0 "s_register_operand" "")
2181 (div:DF (match_operand:DF 1 "s_register_operand" "")
2182 (match_operand:DF 2 "s_register_operand" "")))]
2183 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2186 ;; Boolean and,ior,xor insns
2188 ;; Split up double word logical operations
2190 ;; Split up simple DImode logical operations. Simply perform the logical
2191 ;; operation on the upper and lower halves of the registers.
2193 [(set (match_operand:DI 0 "s_register_operand" "")
2194 (match_operator:DI 6 "logical_binary_operator"
2195 [(match_operand:DI 1 "s_register_operand" "")
2196 (match_operand:DI 2 "s_register_operand" "")]))]
2197 "TARGET_32BIT && reload_completed
2198 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2199 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2200 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2201 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2204 operands[3] = gen_highpart (SImode, operands[0]);
2205 operands[0] = gen_lowpart (SImode, operands[0]);
2206 operands[4] = gen_highpart (SImode, operands[1]);
2207 operands[1] = gen_lowpart (SImode, operands[1]);
2208 operands[5] = gen_highpart (SImode, operands[2]);
2209 operands[2] = gen_lowpart (SImode, operands[2]);
2214 [(set (match_operand:DI 0 "s_register_operand" "")
2215 (match_operator:DI 6 "logical_binary_operator"
2216 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2217 (match_operand:DI 1 "s_register_operand" "")]))]
2218 "TARGET_32BIT && reload_completed"
2219 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2220 (set (match_dup 3) (match_op_dup:SI 6
2221 [(ashiftrt:SI (match_dup 2) (const_int 31))
2225 operands[3] = gen_highpart (SImode, operands[0]);
2226 operands[0] = gen_lowpart (SImode, operands[0]);
2227 operands[4] = gen_highpart (SImode, operands[1]);
2228 operands[1] = gen_lowpart (SImode, operands[1]);
2229 operands[5] = gen_highpart (SImode, operands[2]);
2230 operands[2] = gen_lowpart (SImode, operands[2]);
2234 ;; The zero extend of operand 2 means we can just copy the high part of
2235 ;; operand1 into operand0.
2237 [(set (match_operand:DI 0 "s_register_operand" "")
2239 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2240 (match_operand:DI 1 "s_register_operand" "")))]
2241 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2242 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2243 (set (match_dup 3) (match_dup 4))]
2246 operands[4] = gen_highpart (SImode, operands[1]);
2247 operands[3] = gen_highpart (SImode, operands[0]);
2248 operands[0] = gen_lowpart (SImode, operands[0]);
2249 operands[1] = gen_lowpart (SImode, operands[1]);
2253 ;; The zero extend of operand 2 means we can just copy the high part of
2254 ;; operand1 into operand0.
2256 [(set (match_operand:DI 0 "s_register_operand" "")
2258 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2259 (match_operand:DI 1 "s_register_operand" "")))]
2260 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2261 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2262 (set (match_dup 3) (match_dup 4))]
2265 operands[4] = gen_highpart (SImode, operands[1]);
2266 operands[3] = gen_highpart (SImode, operands[0]);
2267 operands[0] = gen_lowpart (SImode, operands[0]);
2268 operands[1] = gen_lowpart (SImode, operands[1]);
2272 (define_expand "anddi3"
2273 [(set (match_operand:DI 0 "s_register_operand" "")
2274 (and:DI (match_operand:DI 1 "s_register_operand" "")
2275 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2278 if (!TARGET_NEON && !TARGET_IWMMXT)
2280 rtx low = simplify_gen_binary (AND, SImode,
2281 gen_lowpart (SImode, operands[1]),
2282 gen_lowpart (SImode, operands[2]));
2283 rtx high = simplify_gen_binary (AND, SImode,
2284 gen_highpart (SImode, operands[1]),
2285 gen_highpart_mode (SImode, DImode,
2288 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2289 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2293 /* Otherwise expand pattern as above. */
2297 (define_insn_and_split "*anddi3_insn"
2298 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2299 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2300 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2301 "TARGET_32BIT && !TARGET_IWMMXT"
2303 switch (which_alternative)
2305 case 0: /* fall through */
2306 case 6: return "vand\t%P0, %P1, %P2";
2307 case 1: /* fall through */
2308 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2309 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2313 case 5: /* fall through */
2315 default: gcc_unreachable ();
2318 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2319 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2320 [(set (match_dup 3) (match_dup 4))
2321 (set (match_dup 5) (match_dup 6))]
2324 operands[3] = gen_lowpart (SImode, operands[0]);
2325 operands[5] = gen_highpart (SImode, operands[0]);
2327 operands[4] = simplify_gen_binary (AND, SImode,
2328 gen_lowpart (SImode, operands[1]),
2329 gen_lowpart (SImode, operands[2]));
2330 operands[6] = simplify_gen_binary (AND, SImode,
2331 gen_highpart (SImode, operands[1]),
2332 gen_highpart_mode (SImode, DImode, operands[2]));
2335 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2336 multiple,multiple,neon_logic,neon_logic")
2337 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2338 avoid_neon_for_64bits,avoid_neon_for_64bits")
2339 (set_attr "length" "*,*,8,8,8,8,*,*")
2343 (define_insn_and_split "*anddi_zesidi_di"
2344 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2345 (and:DI (zero_extend:DI
2346 (match_operand:SI 2 "s_register_operand" "r,r"))
2347 (match_operand:DI 1 "s_register_operand" "0,r")))]
2350 "TARGET_32BIT && reload_completed"
2351 ; The zero extend of operand 2 clears the high word of the output
2353 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2354 (set (match_dup 3) (const_int 0))]
2357 operands[3] = gen_highpart (SImode, operands[0]);
2358 operands[0] = gen_lowpart (SImode, operands[0]);
2359 operands[1] = gen_lowpart (SImode, operands[1]);
2361 [(set_attr "length" "8")
2362 (set_attr "type" "multiple")]
2365 (define_insn "*anddi_sesdi_di"
2366 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2367 (and:DI (sign_extend:DI
2368 (match_operand:SI 2 "s_register_operand" "r,r"))
2369 (match_operand:DI 1 "s_register_operand" "0,r")))]
2372 [(set_attr "length" "8")
2373 (set_attr "type" "multiple")]
2376 (define_expand "andsi3"
2377 [(set (match_operand:SI 0 "s_register_operand" "")
2378 (and:SI (match_operand:SI 1 "s_register_operand" "")
2379 (match_operand:SI 2 "reg_or_int_operand" "")))]
2384 if (CONST_INT_P (operands[2]))
2386 if (INTVAL (operands[2]) == 255 && arm_arch6)
2388 operands[1] = convert_to_mode (QImode, operands[1], 1);
2389 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2393 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2394 operands[2] = force_reg (SImode, operands[2]);
2397 arm_split_constant (AND, SImode, NULL_RTX,
2398 INTVAL (operands[2]), operands[0],
2400 optimize && can_create_pseudo_p ());
2406 else /* TARGET_THUMB1 */
2408 if (!CONST_INT_P (operands[2]))
2410 rtx tmp = force_reg (SImode, operands[2]);
2411 if (rtx_equal_p (operands[0], operands[1]))
2415 operands[2] = operands[1];
2423 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2425 operands[2] = force_reg (SImode,
2426 GEN_INT (~INTVAL (operands[2])));
2428 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2433 for (i = 9; i <= 31; i++)
2435 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2437 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2441 else if ((HOST_WIDE_INT_1 << i) - 1
2442 == ~INTVAL (operands[2]))
2444 rtx shift = GEN_INT (i);
2445 rtx reg = gen_reg_rtx (SImode);
2447 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2448 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2454 operands[2] = force_reg (SImode, operands[2]);
2460 ; ??? Check split length for Thumb-2
2461 (define_insn_and_split "*arm_andsi3_insn"
2462 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2463 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2464 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2469 bic%?\\t%0, %1, #%B2
2473 && CONST_INT_P (operands[2])
2474 && !(const_ok_for_arm (INTVAL (operands[2]))
2475 || const_ok_for_arm (~INTVAL (operands[2])))"
2476 [(clobber (const_int 0))]
2478 arm_split_constant (AND, SImode, curr_insn,
2479 INTVAL (operands[2]), operands[0], operands[1], 0);
2482 [(set_attr "length" "4,4,4,4,16")
2483 (set_attr "predicable" "yes")
2484 (set_attr "predicable_short_it" "no,yes,no,no,no")
2485 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2488 (define_insn "*andsi3_compare0"
2489 [(set (reg:CC_NOOV CC_REGNUM)
2491 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2492 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2494 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2495 (and:SI (match_dup 1) (match_dup 2)))]
2499 bics%?\\t%0, %1, #%B2
2500 ands%?\\t%0, %1, %2"
2501 [(set_attr "conds" "set")
2502 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2505 (define_insn "*andsi3_compare0_scratch"
2506 [(set (reg:CC_NOOV CC_REGNUM)
2508 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2509 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2511 (clobber (match_scratch:SI 2 "=X,r,X"))]
2515 bics%?\\t%2, %0, #%B1
2517 [(set_attr "conds" "set")
2518 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2521 (define_insn "*zeroextractsi_compare0_scratch"
2522 [(set (reg:CC_NOOV CC_REGNUM)
2523 (compare:CC_NOOV (zero_extract:SI
2524 (match_operand:SI 0 "s_register_operand" "r")
2525 (match_operand 1 "const_int_operand" "n")
2526 (match_operand 2 "const_int_operand" "n"))
2529 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2530 && INTVAL (operands[1]) > 0
2531 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2532 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2534 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2535 << INTVAL (operands[2]));
2536 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2539 [(set_attr "conds" "set")
2540 (set_attr "predicable" "yes")
2541 (set_attr "type" "logics_imm")]
2544 (define_insn_and_split "*ne_zeroextractsi"
2545 [(set (match_operand:SI 0 "s_register_operand" "=r")
2546 (ne:SI (zero_extract:SI
2547 (match_operand:SI 1 "s_register_operand" "r")
2548 (match_operand:SI 2 "const_int_operand" "n")
2549 (match_operand:SI 3 "const_int_operand" "n"))
2551 (clobber (reg:CC CC_REGNUM))]
2553 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2554 && INTVAL (operands[2]) > 0
2555 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2556 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2559 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2560 && INTVAL (operands[2]) > 0
2561 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2562 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2563 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2564 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2566 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2568 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2569 (match_dup 0) (const_int 1)))]
2571 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2572 << INTVAL (operands[3]));
2574 [(set_attr "conds" "clob")
2575 (set (attr "length")
2576 (if_then_else (eq_attr "is_thumb" "yes")
2579 (set_attr "type" "multiple")]
2582 (define_insn_and_split "*ne_zeroextractsi_shifted"
2583 [(set (match_operand:SI 0 "s_register_operand" "=r")
2584 (ne:SI (zero_extract:SI
2585 (match_operand:SI 1 "s_register_operand" "r")
2586 (match_operand:SI 2 "const_int_operand" "n")
2589 (clobber (reg:CC CC_REGNUM))]
2593 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2594 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2596 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2598 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2599 (match_dup 0) (const_int 1)))]
2601 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2603 [(set_attr "conds" "clob")
2604 (set_attr "length" "8")
2605 (set_attr "type" "multiple")]
2608 (define_insn_and_split "*ite_ne_zeroextractsi"
2609 [(set (match_operand:SI 0 "s_register_operand" "=r")
2610 (if_then_else:SI (ne (zero_extract:SI
2611 (match_operand:SI 1 "s_register_operand" "r")
2612 (match_operand:SI 2 "const_int_operand" "n")
2613 (match_operand:SI 3 "const_int_operand" "n"))
2615 (match_operand:SI 4 "arm_not_operand" "rIK")
2617 (clobber (reg:CC CC_REGNUM))]
2619 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2620 && INTVAL (operands[2]) > 0
2621 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2622 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2623 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2626 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2627 && INTVAL (operands[2]) > 0
2628 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2629 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2630 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2631 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2632 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2634 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2636 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2637 (match_dup 0) (match_dup 4)))]
2639 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2640 << INTVAL (operands[3]));
2642 [(set_attr "conds" "clob")
2643 (set_attr "length" "8")
2644 (set_attr "type" "multiple")]
2647 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2648 [(set (match_operand:SI 0 "s_register_operand" "=r")
2649 (if_then_else:SI (ne (zero_extract:SI
2650 (match_operand:SI 1 "s_register_operand" "r")
2651 (match_operand:SI 2 "const_int_operand" "n")
2654 (match_operand:SI 3 "arm_not_operand" "rIK")
2656 (clobber (reg:CC CC_REGNUM))]
2657 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2659 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2660 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2661 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2663 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2665 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2666 (match_dup 0) (match_dup 3)))]
2668 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2670 [(set_attr "conds" "clob")
2671 (set_attr "length" "8")
2672 (set_attr "type" "multiple")]
2675 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2677 [(set (match_operand:SI 0 "s_register_operand" "")
2678 (match_operator:SI 1 "shiftable_operator"
2679 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2680 (match_operand:SI 3 "const_int_operand" "")
2681 (match_operand:SI 4 "const_int_operand" ""))
2682 (match_operand:SI 5 "s_register_operand" "")]))
2683 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2685 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2688 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2691 HOST_WIDE_INT temp = INTVAL (operands[3]);
2693 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2694 operands[4] = GEN_INT (32 - temp);
2699 [(set (match_operand:SI 0 "s_register_operand" "")
2700 (match_operator:SI 1 "shiftable_operator"
2701 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2702 (match_operand:SI 3 "const_int_operand" "")
2703 (match_operand:SI 4 "const_int_operand" ""))
2704 (match_operand:SI 5 "s_register_operand" "")]))
2705 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2707 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2710 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2713 HOST_WIDE_INT temp = INTVAL (operands[3]);
2715 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2716 operands[4] = GEN_INT (32 - temp);
2720 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2721 ;;; represented by the bitfield, then this will produce incorrect results.
2722 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2723 ;;; which have a real bit-field insert instruction, the truncation happens
2724 ;;; in the bit-field insert instruction itself. Since arm does not have a
2725 ;;; bit-field insert instruction, we would have to emit code here to truncate
2726 ;;; the value before we insert. This loses some of the advantage of having
2727 ;;; this insv pattern, so this pattern needs to be reevalutated.
2729 (define_expand "insv"
2730 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2731 (match_operand 1 "general_operand" "")
2732 (match_operand 2 "general_operand" ""))
2733 (match_operand 3 "reg_or_int_operand" ""))]
2734 "TARGET_ARM || arm_arch_thumb2"
2737 int start_bit = INTVAL (operands[2]);
2738 int width = INTVAL (operands[1]);
2739 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2740 rtx target, subtarget;
2742 if (arm_arch_thumb2)
2744 if (unaligned_access && MEM_P (operands[0])
2745 && s_register_operand (operands[3], GET_MODE (operands[3]))
2746 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2750 if (BYTES_BIG_ENDIAN)
2751 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2756 base_addr = adjust_address (operands[0], SImode,
2757 start_bit / BITS_PER_UNIT);
2758 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2762 rtx tmp = gen_reg_rtx (HImode);
2764 base_addr = adjust_address (operands[0], HImode,
2765 start_bit / BITS_PER_UNIT);
2766 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2767 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2771 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2773 bool use_bfi = TRUE;
2775 if (CONST_INT_P (operands[3]))
2777 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2781 emit_insn (gen_insv_zero (operands[0], operands[1],
2786 /* See if the set can be done with a single orr instruction. */
2787 if (val == mask && const_ok_for_arm (val << start_bit))
2793 if (!REG_P (operands[3]))
2794 operands[3] = force_reg (SImode, operands[3]);
2796 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2805 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2808 target = copy_rtx (operands[0]);
2809 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2810 subreg as the final target. */
2811 if (GET_CODE (target) == SUBREG)
2813 subtarget = gen_reg_rtx (SImode);
2814 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2815 < GET_MODE_SIZE (SImode))
2816 target = SUBREG_REG (target);
2821 if (CONST_INT_P (operands[3]))
2823 /* Since we are inserting a known constant, we may be able to
2824 reduce the number of bits that we have to clear so that
2825 the mask becomes simple. */
2826 /* ??? This code does not check to see if the new mask is actually
2827 simpler. It may not be. */
2828 rtx op1 = gen_reg_rtx (SImode);
2829 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2830 start of this pattern. */
2831 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2832 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2834 emit_insn (gen_andsi3 (op1, operands[0],
2835 gen_int_mode (~mask2, SImode)));
2836 emit_insn (gen_iorsi3 (subtarget, op1,
2837 gen_int_mode (op3_value << start_bit, SImode)));
2839 else if (start_bit == 0
2840 && !(const_ok_for_arm (mask)
2841 || const_ok_for_arm (~mask)))
2843 /* A Trick, since we are setting the bottom bits in the word,
2844 we can shift operand[3] up, operand[0] down, OR them together
2845 and rotate the result back again. This takes 3 insns, and
2846 the third might be mergeable into another op. */
2847 /* The shift up copes with the possibility that operand[3] is
2848 wider than the bitfield. */
2849 rtx op0 = gen_reg_rtx (SImode);
2850 rtx op1 = gen_reg_rtx (SImode);
2852 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2853 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2854 emit_insn (gen_iorsi3 (op1, op1, op0));
2855 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2857 else if ((width + start_bit == 32)
2858 && !(const_ok_for_arm (mask)
2859 || const_ok_for_arm (~mask)))
2861 /* Similar trick, but slightly less efficient. */
2863 rtx op0 = gen_reg_rtx (SImode);
2864 rtx op1 = gen_reg_rtx (SImode);
2866 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2867 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2868 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2869 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2873 rtx op0 = gen_int_mode (mask, SImode);
2874 rtx op1 = gen_reg_rtx (SImode);
2875 rtx op2 = gen_reg_rtx (SImode);
2877 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2879 rtx tmp = gen_reg_rtx (SImode);
2881 emit_insn (gen_movsi (tmp, op0));
2885 /* Mask out any bits in operand[3] that are not needed. */
2886 emit_insn (gen_andsi3 (op1, operands[3], op0));
2888 if (CONST_INT_P (op0)
2889 && (const_ok_for_arm (mask << start_bit)
2890 || const_ok_for_arm (~(mask << start_bit))))
2892 op0 = gen_int_mode (~(mask << start_bit), SImode);
2893 emit_insn (gen_andsi3 (op2, operands[0], op0));
2897 if (CONST_INT_P (op0))
2899 rtx tmp = gen_reg_rtx (SImode);
2901 emit_insn (gen_movsi (tmp, op0));
2906 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2908 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2912 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2914 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2917 if (subtarget != target)
2919 /* If TARGET is still a SUBREG, then it must be wider than a word,
2920 so we must be careful only to set the subword we were asked to. */
2921 if (GET_CODE (target) == SUBREG)
2922 emit_move_insn (target, subtarget);
2924 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2931 (define_insn "insv_zero"
2932 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2933 (match_operand:SI 1 "const_int_M_operand" "M")
2934 (match_operand:SI 2 "const_int_M_operand" "M"))
2938 [(set_attr "length" "4")
2939 (set_attr "predicable" "yes")
2940 (set_attr "type" "bfm")]
2943 (define_insn "insv_t2"
2944 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2945 (match_operand:SI 1 "const_int_M_operand" "M")
2946 (match_operand:SI 2 "const_int_M_operand" "M"))
2947 (match_operand:SI 3 "s_register_operand" "r"))]
2949 "bfi%?\t%0, %3, %2, %1"
2950 [(set_attr "length" "4")
2951 (set_attr "predicable" "yes")
2952 (set_attr "type" "bfm")]
2955 ; constants for op 2 will never be given to these patterns.
2956 (define_insn_and_split "*anddi_notdi_di"
2957 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2958 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2959 (match_operand:DI 2 "s_register_operand" "r,0")))]
2962 "TARGET_32BIT && reload_completed
2963 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2964 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2965 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2966 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2969 operands[3] = gen_highpart (SImode, operands[0]);
2970 operands[0] = gen_lowpart (SImode, operands[0]);
2971 operands[4] = gen_highpart (SImode, operands[1]);
2972 operands[1] = gen_lowpart (SImode, operands[1]);
2973 operands[5] = gen_highpart (SImode, operands[2]);
2974 operands[2] = gen_lowpart (SImode, operands[2]);
2976 [(set_attr "length" "8")
2977 (set_attr "predicable" "yes")
2978 (set_attr "type" "multiple")]
2981 (define_insn_and_split "*anddi_notzesidi_di"
2982 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2983 (and:DI (not:DI (zero_extend:DI
2984 (match_operand:SI 2 "s_register_operand" "r,r")))
2985 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2988 bic%?\\t%Q0, %Q1, %2
2990 ; (not (zero_extend ...)) allows us to just copy the high word from
2991 ; operand1 to operand0.
2994 && operands[0] != operands[1]"
2995 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2996 (set (match_dup 3) (match_dup 4))]
2999 operands[3] = gen_highpart (SImode, operands[0]);
3000 operands[0] = gen_lowpart (SImode, operands[0]);
3001 operands[4] = gen_highpart (SImode, operands[1]);
3002 operands[1] = gen_lowpart (SImode, operands[1]);
3004 [(set_attr "length" "4,8")
3005 (set_attr "predicable" "yes")
3006 (set_attr "type" "multiple")]
3009 (define_insn_and_split "*anddi_notdi_zesidi"
3010 [(set (match_operand:DI 0 "s_register_operand" "=r")
3011 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
3013 (match_operand:SI 1 "s_register_operand" "r"))))]
3016 "TARGET_32BIT && reload_completed"
3017 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3018 (set (match_dup 3) (const_int 0))]
3021 operands[3] = gen_highpart (SImode, operands[0]);
3022 operands[0] = gen_lowpart (SImode, operands[0]);
3023 operands[2] = gen_lowpart (SImode, operands[2]);
3025 [(set_attr "length" "8")
3026 (set_attr "predicable" "yes")
3027 (set_attr "type" "multiple")]
3030 (define_insn_and_split "*anddi_notsesidi_di"
3031 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3032 (and:DI (not:DI (sign_extend:DI
3033 (match_operand:SI 2 "s_register_operand" "r,r")))
3034 (match_operand:DI 1 "s_register_operand" "0,r")))]
3037 "TARGET_32BIT && reload_completed"
3038 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3039 (set (match_dup 3) (and:SI (not:SI
3040 (ashiftrt:SI (match_dup 2) (const_int 31)))
3044 operands[3] = gen_highpart (SImode, operands[0]);
3045 operands[0] = gen_lowpart (SImode, operands[0]);
3046 operands[4] = gen_highpart (SImode, operands[1]);
3047 operands[1] = gen_lowpart (SImode, operands[1]);
3049 [(set_attr "length" "8")
3050 (set_attr "predicable" "yes")
3051 (set_attr "type" "multiple")]
3054 (define_insn "andsi_notsi_si"
3055 [(set (match_operand:SI 0 "s_register_operand" "=r")
3056 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3057 (match_operand:SI 1 "s_register_operand" "r")))]
3059 "bic%?\\t%0, %1, %2"
3060 [(set_attr "predicable" "yes")
3061 (set_attr "type" "logic_reg")]
3064 (define_insn "andsi_not_shiftsi_si"
3065 [(set (match_operand:SI 0 "s_register_operand" "=r")
3066 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3067 [(match_operand:SI 2 "s_register_operand" "r")
3068 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3069 (match_operand:SI 1 "s_register_operand" "r")))]
3071 "bic%?\\t%0, %1, %2%S4"
3072 [(set_attr "predicable" "yes")
3073 (set_attr "shift" "2")
3074 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3075 (const_string "logic_shift_imm")
3076 (const_string "logic_shift_reg")))]
3079 ;; Shifted bics pattern used to set up CC status register and not reusing
3080 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3081 ;; does not support shift by register.
3082 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3083 [(set (reg:CC_NOOV CC_REGNUM)
3085 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3086 [(match_operand:SI 1 "s_register_operand" "r")
3087 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3088 (match_operand:SI 3 "s_register_operand" "r"))
3090 (clobber (match_scratch:SI 4 "=r"))]
3091 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3092 "bics%?\\t%4, %3, %1%S0"
3093 [(set_attr "predicable" "yes")
3094 (set_attr "conds" "set")
3095 (set_attr "shift" "1")
3096 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3097 (const_string "logic_shift_imm")
3098 (const_string "logic_shift_reg")))]
3101 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3102 ;; getting reused later.
3103 (define_insn "andsi_not_shiftsi_si_scc"
3104 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3106 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3107 [(match_operand:SI 1 "s_register_operand" "r")
3108 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3109 (match_operand:SI 3 "s_register_operand" "r"))
3111 (set (match_operand:SI 4 "s_register_operand" "=r")
3112 (and:SI (not:SI (match_op_dup 0
3116 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3117 "bics%?\\t%4, %3, %1%S0"
3118 [(set_attr "predicable" "yes")
3119 (set_attr "conds" "set")
3120 (set_attr "shift" "1")
3121 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3122 (const_string "logic_shift_imm")
3123 (const_string "logic_shift_reg")))]
3126 (define_insn "*andsi_notsi_si_compare0"
3127 [(set (reg:CC_NOOV CC_REGNUM)
3129 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3130 (match_operand:SI 1 "s_register_operand" "r"))
3132 (set (match_operand:SI 0 "s_register_operand" "=r")
3133 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3136 [(set_attr "conds" "set")
3137 (set_attr "type" "logics_shift_reg")]
3140 (define_insn "*andsi_notsi_si_compare0_scratch"
3141 [(set (reg:CC_NOOV CC_REGNUM)
3143 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3144 (match_operand:SI 1 "s_register_operand" "r"))
3146 (clobber (match_scratch:SI 0 "=r"))]
3149 [(set_attr "conds" "set")
3150 (set_attr "type" "logics_shift_reg")]
3153 (define_expand "iordi3"
3154 [(set (match_operand:DI 0 "s_register_operand" "")
3155 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3156 (match_operand:DI 2 "neon_logic_op2" "")))]
3159 if (!TARGET_NEON && !TARGET_IWMMXT)
3161 rtx low = simplify_gen_binary (IOR, SImode,
3162 gen_lowpart (SImode, operands[1]),
3163 gen_lowpart (SImode, operands[2]));
3164 rtx high = simplify_gen_binary (IOR, SImode,
3165 gen_highpart (SImode, operands[1]),
3166 gen_highpart_mode (SImode, DImode,
3169 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3170 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3174 /* Otherwise expand pattern as above. */
3178 (define_insn_and_split "*iordi3_insn"
3179 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3180 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3181 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3182 "TARGET_32BIT && !TARGET_IWMMXT"
3184 switch (which_alternative)
3186 case 0: /* fall through */
3187 case 6: return "vorr\t%P0, %P1, %P2";
3188 case 1: /* fall through */
3189 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3190 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3196 default: gcc_unreachable ();
3199 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3200 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3201 [(set (match_dup 3) (match_dup 4))
3202 (set (match_dup 5) (match_dup 6))]
3205 operands[3] = gen_lowpart (SImode, operands[0]);
3206 operands[5] = gen_highpart (SImode, operands[0]);
3208 operands[4] = simplify_gen_binary (IOR, SImode,
3209 gen_lowpart (SImode, operands[1]),
3210 gen_lowpart (SImode, operands[2]));
3211 operands[6] = simplify_gen_binary (IOR, SImode,
3212 gen_highpart (SImode, operands[1]),
3213 gen_highpart_mode (SImode, DImode, operands[2]));
3216 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3217 multiple,neon_logic,neon_logic")
3218 (set_attr "length" "*,*,8,8,8,8,*,*")
3219 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3222 (define_insn "*iordi_zesidi_di"
3223 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3224 (ior:DI (zero_extend:DI
3225 (match_operand:SI 2 "s_register_operand" "r,r"))
3226 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3229 orr%?\\t%Q0, %Q1, %2
3231 [(set_attr "length" "4,8")
3232 (set_attr "predicable" "yes")
3233 (set_attr "type" "logic_reg,multiple")]
3236 (define_insn "*iordi_sesidi_di"
3237 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3238 (ior:DI (sign_extend:DI
3239 (match_operand:SI 2 "s_register_operand" "r,r"))
3240 (match_operand:DI 1 "s_register_operand" "0,r")))]
3243 [(set_attr "length" "8")
3244 (set_attr "predicable" "yes")
3245 (set_attr "type" "multiple")]
3248 (define_expand "iorsi3"
3249 [(set (match_operand:SI 0 "s_register_operand" "")
3250 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3251 (match_operand:SI 2 "reg_or_int_operand" "")))]
3254 if (CONST_INT_P (operands[2]))
3258 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3259 operands[2] = force_reg (SImode, operands[2]);
3262 arm_split_constant (IOR, SImode, NULL_RTX,
3263 INTVAL (operands[2]), operands[0],
3265 optimize && can_create_pseudo_p ());
3269 else /* TARGET_THUMB1 */
3271 rtx tmp = force_reg (SImode, operands[2]);
3272 if (rtx_equal_p (operands[0], operands[1]))
3276 operands[2] = operands[1];
3284 (define_insn_and_split "*iorsi3_insn"
3285 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3286 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3287 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3292 orn%?\\t%0, %1, #%B2
3296 && CONST_INT_P (operands[2])
3297 && !(const_ok_for_arm (INTVAL (operands[2]))
3298 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3299 [(clobber (const_int 0))]
3301 arm_split_constant (IOR, SImode, curr_insn,
3302 INTVAL (operands[2]), operands[0], operands[1], 0);
3305 [(set_attr "length" "4,4,4,4,16")
3306 (set_attr "arch" "32,t2,t2,32,32")
3307 (set_attr "predicable" "yes")
3308 (set_attr "predicable_short_it" "no,yes,no,no,no")
3309 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3313 [(match_scratch:SI 3 "r")
3314 (set (match_operand:SI 0 "arm_general_register_operand" "")
3315 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3316 (match_operand:SI 2 "const_int_operand" "")))]
3318 && !const_ok_for_arm (INTVAL (operands[2]))
3319 && const_ok_for_arm (~INTVAL (operands[2]))"
3320 [(set (match_dup 3) (match_dup 2))
3321 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3325 (define_insn "*iorsi3_compare0"
3326 [(set (reg:CC_NOOV CC_REGNUM)
3327 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3328 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3330 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3331 (ior:SI (match_dup 1) (match_dup 2)))]
3333 "orrs%?\\t%0, %1, %2"
3334 [(set_attr "conds" "set")
3335 (set_attr "type" "logics_imm,logics_reg")]
3338 (define_insn "*iorsi3_compare0_scratch"
3339 [(set (reg:CC_NOOV CC_REGNUM)
3340 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3341 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3343 (clobber (match_scratch:SI 0 "=r,r"))]
3345 "orrs%?\\t%0, %1, %2"
3346 [(set_attr "conds" "set")
3347 (set_attr "type" "logics_imm,logics_reg")]
3350 (define_expand "xordi3"
3351 [(set (match_operand:DI 0 "s_register_operand" "")
3352 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3353 (match_operand:DI 2 "arm_xordi_operand" "")))]
3356 /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3357 to reuse this expander for all TARGET_32BIT targets so just force the
3358 constants into a register. Unlike for the anddi3 and iordi3 there are
3359 no NEON instructions that take an immediate. */
3360 if (TARGET_IWMMXT && !REG_P (operands[2]))
3361 operands[2] = force_reg (DImode, operands[2]);
3362 if (!TARGET_NEON && !TARGET_IWMMXT)
3364 rtx low = simplify_gen_binary (XOR, SImode,
3365 gen_lowpart (SImode, operands[1]),
3366 gen_lowpart (SImode, operands[2]));
3367 rtx high = simplify_gen_binary (XOR, SImode,
3368 gen_highpart (SImode, operands[1]),
3369 gen_highpart_mode (SImode, DImode,
3372 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3373 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3377 /* Otherwise expand pattern as above. */
3381 (define_insn_and_split "*xordi3_insn"
3382 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3383 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3384 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3385 "TARGET_32BIT && !TARGET_IWMMXT"
3387 switch (which_alternative)
3392 case 4: /* fall through */
3394 case 0: /* fall through */
3395 case 5: return "veor\t%P0, %P1, %P2";
3396 default: gcc_unreachable ();
3399 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3400 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3401 [(set (match_dup 3) (match_dup 4))
3402 (set (match_dup 5) (match_dup 6))]
3405 operands[3] = gen_lowpart (SImode, operands[0]);
3406 operands[5] = gen_highpart (SImode, operands[0]);
3408 operands[4] = simplify_gen_binary (XOR, SImode,
3409 gen_lowpart (SImode, operands[1]),
3410 gen_lowpart (SImode, operands[2]));
3411 operands[6] = simplify_gen_binary (XOR, SImode,
3412 gen_highpart (SImode, operands[1]),
3413 gen_highpart_mode (SImode, DImode, operands[2]));
3416 [(set_attr "length" "*,8,8,8,8,*")
3417 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3418 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3421 (define_insn "*xordi_zesidi_di"
3422 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3423 (xor:DI (zero_extend:DI
3424 (match_operand:SI 2 "s_register_operand" "r,r"))
3425 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3428 eor%?\\t%Q0, %Q1, %2
3430 [(set_attr "length" "4,8")
3431 (set_attr "predicable" "yes")
3432 (set_attr "type" "logic_reg")]
3435 (define_insn "*xordi_sesidi_di"
3436 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3437 (xor:DI (sign_extend:DI
3438 (match_operand:SI 2 "s_register_operand" "r,r"))
3439 (match_operand:DI 1 "s_register_operand" "0,r")))]
3442 [(set_attr "length" "8")
3443 (set_attr "predicable" "yes")
3444 (set_attr "type" "multiple")]
3447 (define_expand "xorsi3"
3448 [(set (match_operand:SI 0 "s_register_operand" "")
3449 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3450 (match_operand:SI 2 "reg_or_int_operand" "")))]
3452 "if (CONST_INT_P (operands[2]))
3456 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3457 operands[2] = force_reg (SImode, operands[2]);
3460 arm_split_constant (XOR, SImode, NULL_RTX,
3461 INTVAL (operands[2]), operands[0],
3463 optimize && can_create_pseudo_p ());
3467 else /* TARGET_THUMB1 */
3469 rtx tmp = force_reg (SImode, operands[2]);
3470 if (rtx_equal_p (operands[0], operands[1]))
3474 operands[2] = operands[1];
3481 (define_insn_and_split "*arm_xorsi3"
3482 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3483 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3484 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3492 && CONST_INT_P (operands[2])
3493 && !const_ok_for_arm (INTVAL (operands[2]))"
3494 [(clobber (const_int 0))]
3496 arm_split_constant (XOR, SImode, curr_insn,
3497 INTVAL (operands[2]), operands[0], operands[1], 0);
3500 [(set_attr "length" "4,4,4,16")
3501 (set_attr "predicable" "yes")
3502 (set_attr "predicable_short_it" "no,yes,no,no")
3503 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3506 (define_insn "*xorsi3_compare0"
3507 [(set (reg:CC_NOOV CC_REGNUM)
3508 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3509 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3511 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3512 (xor:SI (match_dup 1) (match_dup 2)))]
3514 "eors%?\\t%0, %1, %2"
3515 [(set_attr "conds" "set")
3516 (set_attr "type" "logics_imm,logics_reg")]
3519 (define_insn "*xorsi3_compare0_scratch"
3520 [(set (reg:CC_NOOV CC_REGNUM)
3521 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3522 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3526 [(set_attr "conds" "set")
3527 (set_attr "type" "logics_imm,logics_reg")]
3530 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3531 ; (NOT D) we can sometimes merge the final NOT into one of the following
3535 [(set (match_operand:SI 0 "s_register_operand" "")
3536 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3537 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3538 (match_operand:SI 3 "arm_rhs_operand" "")))
3539 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3541 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3542 (not:SI (match_dup 3))))
3543 (set (match_dup 0) (not:SI (match_dup 4)))]
3547 (define_insn_and_split "*andsi_iorsi3_notsi"
3548 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3549 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3550 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3551 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3553 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3554 "&& reload_completed"
3555 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3556 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3558 /* If operands[3] is a constant make sure to fold the NOT into it
3559 to avoid creating a NOT of a CONST_INT. */
3560 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3561 if (CONST_INT_P (not_rtx))
3563 operands[4] = operands[0];
3564 operands[5] = not_rtx;
3568 operands[5] = operands[0];
3569 operands[4] = not_rtx;
3572 [(set_attr "length" "8")
3573 (set_attr "ce_count" "2")
3574 (set_attr "predicable" "yes")
3575 (set_attr "type" "multiple")]
3578 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3579 ; insns are available?
3581 [(set (match_operand:SI 0 "s_register_operand" "")
3582 (match_operator:SI 1 "logical_binary_operator"
3583 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3584 (match_operand:SI 3 "const_int_operand" "")
3585 (match_operand:SI 4 "const_int_operand" ""))
3586 (match_operator:SI 9 "logical_binary_operator"
3587 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3588 (match_operand:SI 6 "const_int_operand" ""))
3589 (match_operand:SI 7 "s_register_operand" "")])]))
3590 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3592 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3593 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3596 [(ashift:SI (match_dup 2) (match_dup 4))
3600 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3603 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3607 [(set (match_operand:SI 0 "s_register_operand" "")
3608 (match_operator:SI 1 "logical_binary_operator"
3609 [(match_operator:SI 9 "logical_binary_operator"
3610 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3611 (match_operand:SI 6 "const_int_operand" ""))
3612 (match_operand:SI 7 "s_register_operand" "")])
3613 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3614 (match_operand:SI 3 "const_int_operand" "")
3615 (match_operand:SI 4 "const_int_operand" ""))]))
3616 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3618 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3619 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3622 [(ashift:SI (match_dup 2) (match_dup 4))
3626 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3629 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3633 [(set (match_operand:SI 0 "s_register_operand" "")
3634 (match_operator:SI 1 "logical_binary_operator"
3635 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3636 (match_operand:SI 3 "const_int_operand" "")
3637 (match_operand:SI 4 "const_int_operand" ""))
3638 (match_operator:SI 9 "logical_binary_operator"
3639 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3640 (match_operand:SI 6 "const_int_operand" ""))
3641 (match_operand:SI 7 "s_register_operand" "")])]))
3642 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3644 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3645 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3648 [(ashift:SI (match_dup 2) (match_dup 4))
3652 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3655 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3659 [(set (match_operand:SI 0 "s_register_operand" "")
3660 (match_operator:SI 1 "logical_binary_operator"
3661 [(match_operator:SI 9 "logical_binary_operator"
3662 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3663 (match_operand:SI 6 "const_int_operand" ""))
3664 (match_operand:SI 7 "s_register_operand" "")])
3665 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3666 (match_operand:SI 3 "const_int_operand" "")
3667 (match_operand:SI 4 "const_int_operand" ""))]))
3668 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3670 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3671 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3674 [(ashift:SI (match_dup 2) (match_dup 4))
3678 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3681 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3685 ;; Minimum and maximum insns
3687 (define_expand "smaxsi3"
3689 (set (match_operand:SI 0 "s_register_operand" "")
3690 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3691 (match_operand:SI 2 "arm_rhs_operand" "")))
3692 (clobber (reg:CC CC_REGNUM))])]
3695 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3697 /* No need for a clobber of the condition code register here. */
3698 emit_insn (gen_rtx_SET (operands[0],
3699 gen_rtx_SMAX (SImode, operands[1],
3705 (define_insn "*smax_0"
3706 [(set (match_operand:SI 0 "s_register_operand" "=r")
3707 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3710 "bic%?\\t%0, %1, %1, asr #31"
3711 [(set_attr "predicable" "yes")
3712 (set_attr "type" "logic_shift_reg")]
3715 (define_insn "*smax_m1"
3716 [(set (match_operand:SI 0 "s_register_operand" "=r")
3717 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3720 "orr%?\\t%0, %1, %1, asr #31"
3721 [(set_attr "predicable" "yes")
3722 (set_attr "type" "logic_shift_reg")]
3725 (define_insn_and_split "*arm_smax_insn"
3726 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3727 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3728 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3729 (clobber (reg:CC CC_REGNUM))]
3732 ; cmp\\t%1, %2\;movlt\\t%0, %2
3733 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3735 [(set (reg:CC CC_REGNUM)
3736 (compare:CC (match_dup 1) (match_dup 2)))
3738 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3742 [(set_attr "conds" "clob")
3743 (set_attr "length" "8,12")
3744 (set_attr "type" "multiple")]
3747 (define_expand "sminsi3"
3749 (set (match_operand:SI 0 "s_register_operand" "")
3750 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3751 (match_operand:SI 2 "arm_rhs_operand" "")))
3752 (clobber (reg:CC CC_REGNUM))])]
3755 if (operands[2] == const0_rtx)
3757 /* No need for a clobber of the condition code register here. */
3758 emit_insn (gen_rtx_SET (operands[0],
3759 gen_rtx_SMIN (SImode, operands[1],
3765 (define_insn "*smin_0"
3766 [(set (match_operand:SI 0 "s_register_operand" "=r")
3767 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3770 "and%?\\t%0, %1, %1, asr #31"
3771 [(set_attr "predicable" "yes")
3772 (set_attr "type" "logic_shift_reg")]
3775 (define_insn_and_split "*arm_smin_insn"
3776 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3777 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3778 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3779 (clobber (reg:CC CC_REGNUM))]
3782 ; cmp\\t%1, %2\;movge\\t%0, %2
3783 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3785 [(set (reg:CC CC_REGNUM)
3786 (compare:CC (match_dup 1) (match_dup 2)))
3788 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3792 [(set_attr "conds" "clob")
3793 (set_attr "length" "8,12")
3794 (set_attr "type" "multiple,multiple")]
3797 (define_expand "umaxsi3"
3799 (set (match_operand:SI 0 "s_register_operand" "")
3800 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3801 (match_operand:SI 2 "arm_rhs_operand" "")))
3802 (clobber (reg:CC CC_REGNUM))])]
3807 (define_insn_and_split "*arm_umaxsi3"
3808 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3809 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3810 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3811 (clobber (reg:CC CC_REGNUM))]
3814 ; cmp\\t%1, %2\;movcc\\t%0, %2
3815 ; cmp\\t%1, %2\;movcs\\t%0, %1
3816 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3818 [(set (reg:CC CC_REGNUM)
3819 (compare:CC (match_dup 1) (match_dup 2)))
3821 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3825 [(set_attr "conds" "clob")
3826 (set_attr "length" "8,8,12")
3827 (set_attr "type" "store_4")]
3830 (define_expand "uminsi3"
3832 (set (match_operand:SI 0 "s_register_operand" "")
3833 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3834 (match_operand:SI 2 "arm_rhs_operand" "")))
3835 (clobber (reg:CC CC_REGNUM))])]
3840 (define_insn_and_split "*arm_uminsi3"
3841 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3842 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3843 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3844 (clobber (reg:CC CC_REGNUM))]
3847 ; cmp\\t%1, %2\;movcs\\t%0, %2
3848 ; cmp\\t%1, %2\;movcc\\t%0, %1
3849 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3851 [(set (reg:CC CC_REGNUM)
3852 (compare:CC (match_dup 1) (match_dup 2)))
3854 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3858 [(set_attr "conds" "clob")
3859 (set_attr "length" "8,8,12")
3860 (set_attr "type" "store_4")]
3863 (define_insn "*store_minmaxsi"
3864 [(set (match_operand:SI 0 "memory_operand" "=m")
3865 (match_operator:SI 3 "minmax_operator"
3866 [(match_operand:SI 1 "s_register_operand" "r")
3867 (match_operand:SI 2 "s_register_operand" "r")]))
3868 (clobber (reg:CC CC_REGNUM))]
3869 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3871 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3872 operands[1], operands[2]);
3873 output_asm_insn (\"cmp\\t%1, %2\", operands);
3875 output_asm_insn (\"ite\t%d3\", operands);
3876 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3877 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3880 [(set_attr "conds" "clob")
3881 (set (attr "length")
3882 (if_then_else (eq_attr "is_thumb" "yes")
3885 (set_attr "type" "store_4")]
3888 ; Reject the frame pointer in operand[1], since reloading this after
3889 ; it has been eliminated can cause carnage.
3890 (define_insn "*minmax_arithsi"
3891 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3892 (match_operator:SI 4 "shiftable_operator"
3893 [(match_operator:SI 5 "minmax_operator"
3894 [(match_operand:SI 2 "s_register_operand" "r,r")
3895 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3896 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3897 (clobber (reg:CC CC_REGNUM))]
3898 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3901 enum rtx_code code = GET_CODE (operands[4]);
3904 if (which_alternative != 0 || operands[3] != const0_rtx
3905 || (code != PLUS && code != IOR && code != XOR))
3910 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3911 operands[2], operands[3]);
3912 output_asm_insn (\"cmp\\t%2, %3\", operands);
3916 output_asm_insn (\"ite\\t%d5\", operands);
3918 output_asm_insn (\"it\\t%d5\", operands);
3920 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3922 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3925 [(set_attr "conds" "clob")
3926 (set (attr "length")
3927 (if_then_else (eq_attr "is_thumb" "yes")
3930 (set_attr "type" "multiple")]
3933 ; Reject the frame pointer in operand[1], since reloading this after
3934 ; it has been eliminated can cause carnage.
3935 (define_insn_and_split "*minmax_arithsi_non_canon"
3936 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3938 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3939 (match_operator:SI 4 "minmax_operator"
3940 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3941 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3942 (clobber (reg:CC CC_REGNUM))]
3943 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3944 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3946 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3947 [(set (reg:CC CC_REGNUM)
3948 (compare:CC (match_dup 2) (match_dup 3)))
3950 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3952 (minus:SI (match_dup 1)
3954 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3958 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3959 operands[2], operands[3]);
3960 enum rtx_code rc = minmax_code (operands[4]);
3961 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3962 operands[2], operands[3]);
3964 if (mode == CCFPmode || mode == CCFPEmode)
3965 rc = reverse_condition_maybe_unordered (rc);
3967 rc = reverse_condition (rc);
3968 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3969 if (CONST_INT_P (operands[3]))
3970 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3972 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3974 [(set_attr "conds" "clob")
3975 (set (attr "length")
3976 (if_then_else (eq_attr "is_thumb" "yes")
3979 (set_attr "type" "multiple")]
3982 (define_code_iterator SAT [smin smax])
3983 (define_code_iterator SATrev [smin smax])
3984 (define_code_attr SATlo [(smin "1") (smax "2")])
3985 (define_code_attr SAThi [(smin "2") (smax "1")])
3987 (define_insn "*satsi_<SAT:code>"
3988 [(set (match_operand:SI 0 "s_register_operand" "=r")
3989 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3990 (match_operand:SI 1 "const_int_operand" "i"))
3991 (match_operand:SI 2 "const_int_operand" "i")))]
3992 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3993 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3997 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3998 &mask, &signed_sat))
4001 operands[1] = GEN_INT (mask);
4003 return "ssat%?\t%0, %1, %3";
4005 return "usat%?\t%0, %1, %3";
4007 [(set_attr "predicable" "yes")
4008 (set_attr "type" "alus_imm")]
4011 (define_insn "*satsi_<SAT:code>_shift"
4012 [(set (match_operand:SI 0 "s_register_operand" "=r")
4013 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
4014 [(match_operand:SI 4 "s_register_operand" "r")
4015 (match_operand:SI 5 "const_int_operand" "i")])
4016 (match_operand:SI 1 "const_int_operand" "i"))
4017 (match_operand:SI 2 "const_int_operand" "i")))]
4018 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
4019 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
4023 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
4024 &mask, &signed_sat))
4027 operands[1] = GEN_INT (mask);
4029 return "ssat%?\t%0, %1, %4%S3";
4031 return "usat%?\t%0, %1, %4%S3";
4033 [(set_attr "predicable" "yes")
4034 (set_attr "shift" "3")
4035 (set_attr "type" "logic_shift_reg")])
4037 ;; Shift and rotation insns
4039 (define_expand "ashldi3"
4040 [(set (match_operand:DI 0 "s_register_operand" "")
4041 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
4042 (match_operand:SI 2 "general_operand" "")))]
4047 /* Delay the decision whether to use NEON or core-regs until
4048 register allocation. */
4049 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4054 /* Only the NEON case can handle in-memory shift counts. */
4055 if (!reg_or_int_operand (operands[2], SImode))
4056 operands[2] = force_reg (SImode, operands[2]);
4059 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4060 ; /* No special preparation statements; expand pattern as above. */
4063 rtx scratch1, scratch2;
4065 /* Ideally we should use iwmmxt here if we could know that operands[1]
4066 ends up already living in an iwmmxt register. Otherwise it's
4067 cheaper to have the alternate code being generated than moving
4068 values to iwmmxt regs and back. */
4070 /* Expand operation using core-registers.
4071 'FAIL' would achieve the same thing, but this is a bit smarter. */
4072 scratch1 = gen_reg_rtx (SImode);
4073 scratch2 = gen_reg_rtx (SImode);
4074 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4075 operands[2], scratch1, scratch2);
4081 (define_expand "ashlsi3"
4082 [(set (match_operand:SI 0 "s_register_operand" "")
4083 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4084 (match_operand:SI 2 "arm_rhs_operand" "")))]
4087 if (CONST_INT_P (operands[2])
4088 && (UINTVAL (operands[2])) > 31)
4090 emit_insn (gen_movsi (operands[0], const0_rtx));
4096 (define_expand "ashrdi3"
4097 [(set (match_operand:DI 0 "s_register_operand" "")
4098 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4099 (match_operand:SI 2 "reg_or_int_operand" "")))]
4104 /* Delay the decision whether to use NEON or core-regs until
4105 register allocation. */
4106 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4110 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4111 ; /* No special preparation statements; expand pattern as above. */
4114 rtx scratch1, scratch2;
4116 /* Ideally we should use iwmmxt here if we could know that operands[1]
4117 ends up already living in an iwmmxt register. Otherwise it's
4118 cheaper to have the alternate code being generated than moving
4119 values to iwmmxt regs and back. */
4121 /* Expand operation using core-registers.
4122 'FAIL' would achieve the same thing, but this is a bit smarter. */
4123 scratch1 = gen_reg_rtx (SImode);
4124 scratch2 = gen_reg_rtx (SImode);
4125 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4126 operands[2], scratch1, scratch2);
4132 (define_expand "ashrsi3"
4133 [(set (match_operand:SI 0 "s_register_operand" "")
4134 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4135 (match_operand:SI 2 "arm_rhs_operand" "")))]
4138 if (CONST_INT_P (operands[2])
4139 && UINTVAL (operands[2]) > 31)
4140 operands[2] = GEN_INT (31);
4144 (define_expand "lshrdi3"
4145 [(set (match_operand:DI 0 "s_register_operand" "")
4146 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4147 (match_operand:SI 2 "reg_or_int_operand" "")))]
4152 /* Delay the decision whether to use NEON or core-regs until
4153 register allocation. */
4154 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4158 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4159 ; /* No special preparation statements; expand pattern as above. */
4162 rtx scratch1, scratch2;
4164 /* Ideally we should use iwmmxt here if we could know that operands[1]
4165 ends up already living in an iwmmxt register. Otherwise it's
4166 cheaper to have the alternate code being generated than moving
4167 values to iwmmxt regs and back. */
4169 /* Expand operation using core-registers.
4170 'FAIL' would achieve the same thing, but this is a bit smarter. */
4171 scratch1 = gen_reg_rtx (SImode);
4172 scratch2 = gen_reg_rtx (SImode);
4173 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4174 operands[2], scratch1, scratch2);
4180 (define_expand "lshrsi3"
4181 [(set (match_operand:SI 0 "s_register_operand" "")
4182 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4183 (match_operand:SI 2 "arm_rhs_operand" "")))]
4186 if (CONST_INT_P (operands[2])
4187 && (UINTVAL (operands[2])) > 31)
4189 emit_insn (gen_movsi (operands[0], const0_rtx));
4195 (define_expand "rotlsi3"
4196 [(set (match_operand:SI 0 "s_register_operand" "")
4197 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4198 (match_operand:SI 2 "reg_or_int_operand" "")))]
4201 if (CONST_INT_P (operands[2]))
4202 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4205 rtx reg = gen_reg_rtx (SImode);
4206 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4212 (define_expand "rotrsi3"
4213 [(set (match_operand:SI 0 "s_register_operand" "")
4214 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4215 (match_operand:SI 2 "arm_rhs_operand" "")))]
4220 if (CONST_INT_P (operands[2])
4221 && UINTVAL (operands[2]) > 31)
4222 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4224 else /* TARGET_THUMB1 */
4226 if (CONST_INT_P (operands [2]))
4227 operands [2] = force_reg (SImode, operands[2]);
4232 (define_insn "*arm_shiftsi3"
4233 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4234 (match_operator:SI 3 "shift_operator"
4235 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4236 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4238 "* return arm_output_shift(operands, 0);"
4239 [(set_attr "predicable" "yes")
4240 (set_attr "arch" "t2,t2,*,*")
4241 (set_attr "predicable_short_it" "yes,yes,no,no")
4242 (set_attr "length" "4")
4243 (set_attr "shift" "1")
4244 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4247 (define_insn "*shiftsi3_compare0"
4248 [(set (reg:CC_NOOV CC_REGNUM)
4249 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4250 [(match_operand:SI 1 "s_register_operand" "r,r")
4251 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4253 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4254 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4256 "* return arm_output_shift(operands, 1);"
4257 [(set_attr "conds" "set")
4258 (set_attr "shift" "1")
4259 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4262 (define_insn "*shiftsi3_compare0_scratch"
4263 [(set (reg:CC_NOOV CC_REGNUM)
4264 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4265 [(match_operand:SI 1 "s_register_operand" "r,r")
4266 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4268 (clobber (match_scratch:SI 0 "=r,r"))]
4270 "* return arm_output_shift(operands, 1);"
4271 [(set_attr "conds" "set")
4272 (set_attr "shift" "1")
4273 (set_attr "type" "shift_imm,shift_reg")]
4276 (define_insn "*not_shiftsi"
4277 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4278 (not:SI (match_operator:SI 3 "shift_operator"
4279 [(match_operand:SI 1 "s_register_operand" "r,r")
4280 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4283 [(set_attr "predicable" "yes")
4284 (set_attr "shift" "1")
4285 (set_attr "arch" "32,a")
4286 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4288 (define_insn "*not_shiftsi_compare0"
4289 [(set (reg:CC_NOOV CC_REGNUM)
4291 (not:SI (match_operator:SI 3 "shift_operator"
4292 [(match_operand:SI 1 "s_register_operand" "r,r")
4293 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4295 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4296 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4298 "mvns%?\\t%0, %1%S3"
4299 [(set_attr "conds" "set")
4300 (set_attr "shift" "1")
4301 (set_attr "arch" "32,a")
4302 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4304 (define_insn "*not_shiftsi_compare0_scratch"
4305 [(set (reg:CC_NOOV CC_REGNUM)
4307 (not:SI (match_operator:SI 3 "shift_operator"
4308 [(match_operand:SI 1 "s_register_operand" "r,r")
4309 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4311 (clobber (match_scratch:SI 0 "=r,r"))]
4313 "mvns%?\\t%0, %1%S3"
4314 [(set_attr "conds" "set")
4315 (set_attr "shift" "1")
4316 (set_attr "arch" "32,a")
4317 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4319 ;; We don't really have extzv, but defining this using shifts helps
4320 ;; to reduce register pressure later on.
4322 (define_expand "extzv"
4323 [(set (match_operand 0 "s_register_operand" "")
4324 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4325 (match_operand 2 "const_int_operand" "")
4326 (match_operand 3 "const_int_operand" "")))]
4327 "TARGET_THUMB1 || arm_arch_thumb2"
4330 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4331 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4333 if (arm_arch_thumb2)
4335 HOST_WIDE_INT width = INTVAL (operands[2]);
4336 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4338 if (unaligned_access && MEM_P (operands[1])
4339 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4343 if (BYTES_BIG_ENDIAN)
4344 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4349 base_addr = adjust_address (operands[1], SImode,
4350 bitpos / BITS_PER_UNIT);
4351 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4355 rtx dest = operands[0];
4356 rtx tmp = gen_reg_rtx (SImode);
4358 /* We may get a paradoxical subreg here. Strip it off. */
4359 if (GET_CODE (dest) == SUBREG
4360 && GET_MODE (dest) == SImode
4361 && GET_MODE (SUBREG_REG (dest)) == HImode)
4362 dest = SUBREG_REG (dest);
4364 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4367 base_addr = adjust_address (operands[1], HImode,
4368 bitpos / BITS_PER_UNIT);
4369 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4370 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4374 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4376 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4384 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4387 operands[3] = GEN_INT (rshift);
4391 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4395 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4396 operands[3], gen_reg_rtx (SImode)));
4401 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4403 (define_expand "extzv_t1"
4404 [(set (match_operand:SI 4 "s_register_operand" "")
4405 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4406 (match_operand:SI 2 "const_int_operand" "")))
4407 (set (match_operand:SI 0 "s_register_operand" "")
4408 (lshiftrt:SI (match_dup 4)
4409 (match_operand:SI 3 "const_int_operand" "")))]
4413 (define_expand "extv"
4414 [(set (match_operand 0 "s_register_operand" "")
4415 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4416 (match_operand 2 "const_int_operand" "")
4417 (match_operand 3 "const_int_operand" "")))]
4420 HOST_WIDE_INT width = INTVAL (operands[2]);
4421 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4423 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4424 && (bitpos % BITS_PER_UNIT) == 0)
4428 if (BYTES_BIG_ENDIAN)
4429 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4433 base_addr = adjust_address (operands[1], SImode,
4434 bitpos / BITS_PER_UNIT);
4435 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4439 rtx dest = operands[0];
4440 rtx tmp = gen_reg_rtx (SImode);
4442 /* We may get a paradoxical subreg here. Strip it off. */
4443 if (GET_CODE (dest) == SUBREG
4444 && GET_MODE (dest) == SImode
4445 && GET_MODE (SUBREG_REG (dest)) == HImode)
4446 dest = SUBREG_REG (dest);
4448 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4451 base_addr = adjust_address (operands[1], HImode,
4452 bitpos / BITS_PER_UNIT);
4453 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4454 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4459 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4461 else if (GET_MODE (operands[0]) == SImode
4462 && GET_MODE (operands[1]) == SImode)
4464 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4472 ; Helper to expand register forms of extv with the proper modes.
4474 (define_expand "extv_regsi"
4475 [(set (match_operand:SI 0 "s_register_operand" "")
4476 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4477 (match_operand 2 "const_int_operand" "")
4478 (match_operand 3 "const_int_operand" "")))]
4483 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4485 (define_insn "unaligned_loadsi"
4486 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4487 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4488 UNSPEC_UNALIGNED_LOAD))]
4490 "ldr%?\t%0, %1\t@ unaligned"
4491 [(set_attr "arch" "t2,any")
4492 (set_attr "length" "2,4")
4493 (set_attr "predicable" "yes")
4494 (set_attr "predicable_short_it" "yes,no")
4495 (set_attr "type" "load_4")])
4497 (define_insn "unaligned_loadhis"
4498 [(set (match_operand:SI 0 "s_register_operand" "=r")
4500 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
4501 UNSPEC_UNALIGNED_LOAD)))]
4503 "ldrsh%?\t%0, %1\t@ unaligned"
4504 [(set_attr "predicable" "yes")
4505 (set_attr "type" "load_byte")])
4507 (define_insn "unaligned_loadhiu"
4508 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4510 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4511 UNSPEC_UNALIGNED_LOAD)))]
4513 "ldrh%?\t%0, %1\t@ unaligned"
4514 [(set_attr "arch" "t2,any")
4515 (set_attr "length" "2,4")
4516 (set_attr "predicable" "yes")
4517 (set_attr "predicable_short_it" "yes,no")
4518 (set_attr "type" "load_byte")])
4520 (define_insn "unaligned_storesi"
4521 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4522 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4523 UNSPEC_UNALIGNED_STORE))]
4525 "str%?\t%1, %0\t@ unaligned"
4526 [(set_attr "arch" "t2,any")
4527 (set_attr "length" "2,4")
4528 (set_attr "predicable" "yes")
4529 (set_attr "predicable_short_it" "yes,no")
4530 (set_attr "type" "store_4")])
4532 (define_insn "unaligned_storehi"
4533 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4534 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4535 UNSPEC_UNALIGNED_STORE))]
4537 "strh%?\t%1, %0\t@ unaligned"
4538 [(set_attr "arch" "t2,any")
4539 (set_attr "length" "2,4")
4540 (set_attr "predicable" "yes")
4541 (set_attr "predicable_short_it" "yes,no")
4542 (set_attr "type" "store_4")])
4545 (define_insn "*extv_reg"
4546 [(set (match_operand:SI 0 "s_register_operand" "=r")
4547 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4548 (match_operand:SI 2 "const_int_operand" "n")
4549 (match_operand:SI 3 "const_int_operand" "n")))]
4551 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4552 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4553 "sbfx%?\t%0, %1, %3, %2"
4554 [(set_attr "length" "4")
4555 (set_attr "predicable" "yes")
4556 (set_attr "type" "bfm")]
4559 (define_insn "extzv_t2"
4560 [(set (match_operand:SI 0 "s_register_operand" "=r")
4561 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4562 (match_operand:SI 2 "const_int_operand" "n")
4563 (match_operand:SI 3 "const_int_operand" "n")))]
4565 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4566 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4567 "ubfx%?\t%0, %1, %3, %2"
4568 [(set_attr "length" "4")
4569 (set_attr "predicable" "yes")
4570 (set_attr "type" "bfm")]
4574 ;; Division instructions
4575 (define_insn "divsi3"
4576 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4577 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4578 (match_operand:SI 2 "s_register_operand" "r,r")))]
4583 [(set_attr "arch" "32,v8mb")
4584 (set_attr "predicable" "yes")
4585 (set_attr "type" "sdiv")]
4588 (define_insn "udivsi3"
4589 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4590 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4591 (match_operand:SI 2 "s_register_operand" "r,r")))]
4596 [(set_attr "arch" "32,v8mb")
4597 (set_attr "predicable" "yes")
4598 (set_attr "type" "udiv")]
4602 ;; Unary arithmetic insns
4604 (define_expand "negvsi3"
4605 [(match_operand:SI 0 "register_operand")
4606 (match_operand:SI 1 "register_operand")
4607 (match_operand 2 "")]
4610 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4611 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4616 (define_expand "negvdi3"
4617 [(match_operand:DI 0 "register_operand")
4618 (match_operand:DI 1 "register_operand")
4619 (match_operand 2 "")]
4622 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4623 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4629 (define_insn_and_split "negdi2_compare"
4630 [(set (reg:CC CC_REGNUM)
4633 (match_operand:DI 1 "register_operand" "0,r")))
4634 (set (match_operand:DI 0 "register_operand" "=r,&r")
4635 (minus:DI (const_int 0) (match_dup 1)))]
4638 "&& reload_completed"
4639 [(parallel [(set (reg:CC CC_REGNUM)
4640 (compare:CC (const_int 0) (match_dup 1)))
4641 (set (match_dup 0) (minus:SI (const_int 0)
4643 (parallel [(set (reg:CC CC_REGNUM)
4644 (compare:CC (const_int 0) (match_dup 3)))
4647 (minus:SI (const_int 0) (match_dup 3))
4648 (ltu:SI (reg:CC_C CC_REGNUM)
4651 operands[2] = gen_highpart (SImode, operands[0]);
4652 operands[0] = gen_lowpart (SImode, operands[0]);
4653 operands[3] = gen_highpart (SImode, operands[1]);
4654 operands[1] = gen_lowpart (SImode, operands[1]);
4656 [(set_attr "conds" "set")
4657 (set_attr "length" "8")
4658 (set_attr "type" "multiple")]
4661 (define_expand "negdi2"
4663 [(set (match_operand:DI 0 "s_register_operand" "")
4664 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4665 (clobber (reg:CC CC_REGNUM))])]
4670 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4676 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4677 ;; The first alternative allows the common case of a *full* overlap.
4678 (define_insn_and_split "*negdi2_insn"
4679 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4680 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4681 (clobber (reg:CC CC_REGNUM))]
4683 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4684 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4685 "&& reload_completed"
4686 [(parallel [(set (reg:CC CC_REGNUM)
4687 (compare:CC (const_int 0) (match_dup 1)))
4688 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4689 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4690 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4692 operands[2] = gen_highpart (SImode, operands[0]);
4693 operands[0] = gen_lowpart (SImode, operands[0]);
4694 operands[3] = gen_highpart (SImode, operands[1]);
4695 operands[1] = gen_lowpart (SImode, operands[1]);
4697 [(set_attr "conds" "clob")
4698 (set_attr "length" "8")
4699 (set_attr "type" "multiple")]
4702 (define_insn "*negsi2_carryin_compare"
4703 [(set (reg:CC CC_REGNUM)
4704 (compare:CC (const_int 0)
4705 (match_operand:SI 1 "s_register_operand" "r")))
4706 (set (match_operand:SI 0 "s_register_operand" "=r")
4707 (minus:SI (minus:SI (const_int 0)
4709 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4712 [(set_attr "conds" "set")
4713 (set_attr "type" "alus_imm")]
4716 (define_expand "negsi2"
4717 [(set (match_operand:SI 0 "s_register_operand" "")
4718 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4723 (define_insn "*arm_negsi2"
4724 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4725 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4727 "rsb%?\\t%0, %1, #0"
4728 [(set_attr "predicable" "yes")
4729 (set_attr "predicable_short_it" "yes,no")
4730 (set_attr "arch" "t2,*")
4731 (set_attr "length" "4")
4732 (set_attr "type" "alu_sreg")]
4735 (define_expand "negsf2"
4736 [(set (match_operand:SF 0 "s_register_operand" "")
4737 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4738 "TARGET_32BIT && TARGET_HARD_FLOAT"
4742 (define_expand "negdf2"
4743 [(set (match_operand:DF 0 "s_register_operand" "")
4744 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4745 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4748 (define_insn_and_split "*zextendsidi_negsi"
4749 [(set (match_operand:DI 0 "s_register_operand" "=r")
4750 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4755 (neg:SI (match_dup 1)))
4759 operands[2] = gen_lowpart (SImode, operands[0]);
4760 operands[3] = gen_highpart (SImode, operands[0]);
4762 [(set_attr "length" "8")
4763 (set_attr "type" "multiple")]
4766 ;; Negate an extended 32-bit value.
4767 (define_insn_and_split "*negdi_extendsidi"
4768 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4769 (neg:DI (sign_extend:DI
4770 (match_operand:SI 1 "s_register_operand" "l,r"))))
4771 (clobber (reg:CC CC_REGNUM))]
4774 "&& reload_completed"
4777 rtx low = gen_lowpart (SImode, operands[0]);
4778 rtx high = gen_highpart (SImode, operands[0]);
4780 if (reg_overlap_mentioned_p (low, operands[1]))
4782 /* Input overlaps the low word of the output. Use:
4785 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4786 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4788 emit_insn (gen_rtx_SET (high,
4789 gen_rtx_ASHIFTRT (SImode, operands[1],
4792 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4794 emit_insn (gen_rtx_SET (high,
4795 gen_rtx_MINUS (SImode,
4796 gen_rtx_MINUS (SImode,
4799 gen_rtx_LTU (SImode,
4804 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4805 emit_insn (gen_rtx_SET (high,
4806 gen_rtx_MINUS (SImode,
4807 gen_rtx_MINUS (SImode,
4810 gen_rtx_LTU (SImode,
4817 /* No overlap, or overlap on high word. Use:
4821 Flags not needed for this sequence. */
4822 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4823 emit_insn (gen_rtx_SET (high,
4824 gen_rtx_AND (SImode,
4825 gen_rtx_NOT (SImode, operands[1]),
4827 emit_insn (gen_rtx_SET (high,
4828 gen_rtx_ASHIFTRT (SImode, high,
4833 [(set_attr "length" "12")
4834 (set_attr "arch" "t2,*")
4835 (set_attr "type" "multiple")]
4838 (define_insn_and_split "*negdi_zero_extendsidi"
4839 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4840 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4841 (clobber (reg:CC CC_REGNUM))]
4843 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4844 ;; Don't care what register is input to sbc,
4845 ;; since we just need to propagate the carry.
4846 "&& reload_completed"
4847 [(parallel [(set (reg:CC CC_REGNUM)
4848 (compare:CC (const_int 0) (match_dup 1)))
4849 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4850 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4851 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4853 operands[2] = gen_highpart (SImode, operands[0]);
4854 operands[0] = gen_lowpart (SImode, operands[0]);
4856 [(set_attr "conds" "clob")
4857 (set_attr "length" "8")
4858 (set_attr "type" "multiple")] ;; length in thumb is 4
4861 ;; abssi2 doesn't really clobber the condition codes if a different register
4862 ;; is being set. To keep things simple, assume during rtl manipulations that
4863 ;; it does, but tell the final scan operator the truth. Similarly for
4866 (define_expand "abssi2"
4868 [(set (match_operand:SI 0 "s_register_operand" "")
4869 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4870 (clobber (match_dup 2))])]
4874 operands[2] = gen_rtx_SCRATCH (SImode);
4876 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4879 (define_insn_and_split "*arm_abssi2"
4880 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4881 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4882 (clobber (reg:CC CC_REGNUM))]
4885 "&& reload_completed"
4888 /* if (which_alternative == 0) */
4889 if (REGNO(operands[0]) == REGNO(operands[1]))
4891 /* Emit the pattern:
4892 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4893 [(set (reg:CC CC_REGNUM)
4894 (compare:CC (match_dup 0) (const_int 0)))
4895 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4896 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4898 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4899 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4900 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4901 (gen_rtx_LT (SImode,
4902 gen_rtx_REG (CCmode, CC_REGNUM),
4904 (gen_rtx_SET (operands[0],
4905 (gen_rtx_MINUS (SImode,
4912 /* Emit the pattern:
4913 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4915 (xor:SI (match_dup 1)
4916 (ashiftrt:SI (match_dup 1) (const_int 31))))
4918 (minus:SI (match_dup 0)
4919 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4921 emit_insn (gen_rtx_SET (operands[0],
4922 gen_rtx_XOR (SImode,
4923 gen_rtx_ASHIFTRT (SImode,
4927 emit_insn (gen_rtx_SET (operands[0],
4928 gen_rtx_MINUS (SImode,
4930 gen_rtx_ASHIFTRT (SImode,
4936 [(set_attr "conds" "clob,*")
4937 (set_attr "shift" "1")
4938 (set_attr "predicable" "no, yes")
4939 (set_attr "length" "8")
4940 (set_attr "type" "multiple")]
4943 (define_insn_and_split "*arm_neg_abssi2"
4944 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4945 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4946 (clobber (reg:CC CC_REGNUM))]
4949 "&& reload_completed"
4952 /* if (which_alternative == 0) */
4953 if (REGNO (operands[0]) == REGNO (operands[1]))
4955 /* Emit the pattern:
4956 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4958 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4959 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4960 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4962 gen_rtx_REG (CCmode, CC_REGNUM),
4964 gen_rtx_SET (operands[0],
4965 (gen_rtx_MINUS (SImode,
4971 /* Emit the pattern:
4972 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4974 emit_insn (gen_rtx_SET (operands[0],
4975 gen_rtx_XOR (SImode,
4976 gen_rtx_ASHIFTRT (SImode,
4980 emit_insn (gen_rtx_SET (operands[0],
4981 gen_rtx_MINUS (SImode,
4982 gen_rtx_ASHIFTRT (SImode,
4989 [(set_attr "conds" "clob,*")
4990 (set_attr "shift" "1")
4991 (set_attr "predicable" "no, yes")
4992 (set_attr "length" "8")
4993 (set_attr "type" "multiple")]
4996 (define_expand "abssf2"
4997 [(set (match_operand:SF 0 "s_register_operand" "")
4998 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4999 "TARGET_32BIT && TARGET_HARD_FLOAT"
5002 (define_expand "absdf2"
5003 [(set (match_operand:DF 0 "s_register_operand" "")
5004 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5005 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5008 (define_expand "sqrtsf2"
5009 [(set (match_operand:SF 0 "s_register_operand" "")
5010 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5011 "TARGET_32BIT && TARGET_HARD_FLOAT"
5014 (define_expand "sqrtdf2"
5015 [(set (match_operand:DF 0 "s_register_operand" "")
5016 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5017 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5020 (define_expand "one_cmpldi2"
5021 [(set (match_operand:DI 0 "s_register_operand" "")
5022 (not:DI (match_operand:DI 1 "s_register_operand" "")))]
5025 if (!TARGET_NEON && !TARGET_IWMMXT)
5027 rtx low = simplify_gen_unary (NOT, SImode,
5028 gen_lowpart (SImode, operands[1]),
5030 rtx high = simplify_gen_unary (NOT, SImode,
5031 gen_highpart_mode (SImode, DImode,
5035 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5036 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5040 /* Otherwise expand pattern as above. */
5044 (define_insn_and_split "*one_cmpldi2_insn"
5045 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5046 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5053 "TARGET_32BIT && reload_completed
5054 && arm_general_register_operand (operands[0], DImode)"
5055 [(set (match_dup 0) (not:SI (match_dup 1)))
5056 (set (match_dup 2) (not:SI (match_dup 3)))]
5059 operands[2] = gen_highpart (SImode, operands[0]);
5060 operands[0] = gen_lowpart (SImode, operands[0]);
5061 operands[3] = gen_highpart (SImode, operands[1]);
5062 operands[1] = gen_lowpart (SImode, operands[1]);
5064 [(set_attr "length" "*,8,8,*")
5065 (set_attr "predicable" "no,yes,yes,no")
5066 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5067 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5070 (define_expand "one_cmplsi2"
5071 [(set (match_operand:SI 0 "s_register_operand" "")
5072 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5077 (define_insn "*arm_one_cmplsi2"
5078 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5079 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5082 [(set_attr "predicable" "yes")
5083 (set_attr "predicable_short_it" "yes,no")
5084 (set_attr "arch" "t2,*")
5085 (set_attr "length" "4")
5086 (set_attr "type" "mvn_reg")]
5089 (define_insn "*notsi_compare0"
5090 [(set (reg:CC_NOOV CC_REGNUM)
5091 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5093 (set (match_operand:SI 0 "s_register_operand" "=r")
5094 (not:SI (match_dup 1)))]
5097 [(set_attr "conds" "set")
5098 (set_attr "type" "mvn_reg")]
5101 (define_insn "*notsi_compare0_scratch"
5102 [(set (reg:CC_NOOV CC_REGNUM)
5103 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5105 (clobber (match_scratch:SI 0 "=r"))]
5108 [(set_attr "conds" "set")
5109 (set_attr "type" "mvn_reg")]
5112 ;; Fixed <--> Floating conversion insns
5114 (define_expand "floatsihf2"
5115 [(set (match_operand:HF 0 "general_operand" "")
5116 (float:HF (match_operand:SI 1 "general_operand" "")))]
5120 rtx op1 = gen_reg_rtx (SFmode);
5121 expand_float (op1, operands[1], 0);
5122 op1 = convert_to_mode (HFmode, op1, 0);
5123 emit_move_insn (operands[0], op1);
5128 (define_expand "floatdihf2"
5129 [(set (match_operand:HF 0 "general_operand" "")
5130 (float:HF (match_operand:DI 1 "general_operand" "")))]
5134 rtx op1 = gen_reg_rtx (SFmode);
5135 expand_float (op1, operands[1], 0);
5136 op1 = convert_to_mode (HFmode, op1, 0);
5137 emit_move_insn (operands[0], op1);
5142 (define_expand "floatsisf2"
5143 [(set (match_operand:SF 0 "s_register_operand" "")
5144 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5145 "TARGET_32BIT && TARGET_HARD_FLOAT"
5149 (define_expand "floatsidf2"
5150 [(set (match_operand:DF 0 "s_register_operand" "")
5151 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5152 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5156 (define_expand "fix_trunchfsi2"
5157 [(set (match_operand:SI 0 "general_operand" "")
5158 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5162 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5163 expand_fix (operands[0], op1, 0);
5168 (define_expand "fix_trunchfdi2"
5169 [(set (match_operand:DI 0 "general_operand" "")
5170 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5174 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5175 expand_fix (operands[0], op1, 0);
5180 (define_expand "fix_truncsfsi2"
5181 [(set (match_operand:SI 0 "s_register_operand" "")
5182 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5183 "TARGET_32BIT && TARGET_HARD_FLOAT"
5187 (define_expand "fix_truncdfsi2"
5188 [(set (match_operand:SI 0 "s_register_operand" "")
5189 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5190 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5196 (define_expand "truncdfsf2"
5197 [(set (match_operand:SF 0 "s_register_operand" "")
5199 (match_operand:DF 1 "s_register_operand" "")))]
5200 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5204 ;; DFmode to HFmode conversions on targets without a single-step hardware
5205 ;; instruction for it would have to go through SFmode. This is dangerous
5206 ;; as it introduces double rounding.
5208 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5209 ;; a single-step instruction.
5211 (define_expand "truncdfhf2"
5212 [(set (match_operand:HF 0 "s_register_operand" "")
5214 (match_operand:DF 1 "s_register_operand" "")))]
5215 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5216 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5218 /* We don't have a direct instruction for this, so we must be in
5219 an unsafe math mode, and going via SFmode. */
5221 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5224 op1 = convert_to_mode (SFmode, operands[1], 0);
5225 op1 = convert_to_mode (HFmode, op1, 0);
5226 emit_move_insn (operands[0], op1);
5229 /* Otherwise, we will pick this up as a single instruction with
5230 no intermediary rounding. */
5234 ;; Zero and sign extension instructions.
5236 (define_insn "zero_extend<mode>di2"
5237 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5238 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5239 "<qhs_zextenddi_cstr>")))]
5240 "TARGET_32BIT <qhs_zextenddi_cond>"
5242 [(set_attr "length" "8,4,8,8")
5243 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5244 (set_attr "ce_count" "2")
5245 (set_attr "predicable" "yes")
5246 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5249 (define_insn "extend<mode>di2"
5250 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5251 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5252 "<qhs_extenddi_cstr>")))]
5253 "TARGET_32BIT <qhs_sextenddi_cond>"
5255 [(set_attr "length" "8,4,8,8,8")
5256 (set_attr "ce_count" "2")
5257 (set_attr "shift" "1")
5258 (set_attr "predicable" "yes")
5259 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5260 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5263 ;; Splits for all extensions to DImode
5265 [(set (match_operand:DI 0 "s_register_operand" "")
5266 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5267 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5268 [(set (match_dup 0) (match_dup 1))]
5270 rtx lo_part = gen_lowpart (SImode, operands[0]);
5271 machine_mode src_mode = GET_MODE (operands[1]);
5273 if (REG_P (operands[0])
5274 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5275 emit_clobber (operands[0]);
5276 if (!REG_P (lo_part) || src_mode != SImode
5277 || !rtx_equal_p (lo_part, operands[1]))
5279 if (src_mode == SImode)
5280 emit_move_insn (lo_part, operands[1]);
5282 emit_insn (gen_rtx_SET (lo_part,
5283 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5284 operands[1] = lo_part;
5286 operands[0] = gen_highpart (SImode, operands[0]);
5287 operands[1] = const0_rtx;
5291 [(set (match_operand:DI 0 "s_register_operand" "")
5292 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5293 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5294 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5296 rtx lo_part = gen_lowpart (SImode, operands[0]);
5297 machine_mode src_mode = GET_MODE (operands[1]);
5299 if (REG_P (operands[0])
5300 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5301 emit_clobber (operands[0]);
5303 if (!REG_P (lo_part) || src_mode != SImode
5304 || !rtx_equal_p (lo_part, operands[1]))
5306 if (src_mode == SImode)
5307 emit_move_insn (lo_part, operands[1]);
5309 emit_insn (gen_rtx_SET (lo_part,
5310 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5311 operands[1] = lo_part;
5313 operands[0] = gen_highpart (SImode, operands[0]);
5316 (define_expand "zero_extendhisi2"
5317 [(set (match_operand:SI 0 "s_register_operand" "")
5318 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5321 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5323 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5326 if (!arm_arch6 && !MEM_P (operands[1]))
5328 rtx t = gen_lowpart (SImode, operands[1]);
5329 rtx tmp = gen_reg_rtx (SImode);
5330 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5331 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5337 [(set (match_operand:SI 0 "s_register_operand" "")
5338 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5339 "!TARGET_THUMB2 && !arm_arch6"
5340 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5341 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5343 operands[2] = gen_lowpart (SImode, operands[1]);
5346 (define_insn "*arm_zero_extendhisi2"
5347 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5348 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5349 "TARGET_ARM && arm_arch4 && !arm_arch6"
5353 [(set_attr "type" "alu_shift_reg,load_byte")
5354 (set_attr "predicable" "yes")]
5357 (define_insn "*arm_zero_extendhisi2_v6"
5358 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5359 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5360 "TARGET_ARM && arm_arch6"
5364 [(set_attr "predicable" "yes")
5365 (set_attr "type" "extend,load_byte")]
5368 (define_insn "*arm_zero_extendhisi2addsi"
5369 [(set (match_operand:SI 0 "s_register_operand" "=r")
5370 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5371 (match_operand:SI 2 "s_register_operand" "r")))]
5373 "uxtah%?\\t%0, %2, %1"
5374 [(set_attr "type" "alu_shift_reg")
5375 (set_attr "predicable" "yes")]
5378 (define_expand "zero_extendqisi2"
5379 [(set (match_operand:SI 0 "s_register_operand" "")
5380 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5383 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5385 emit_insn (gen_andsi3 (operands[0],
5386 gen_lowpart (SImode, operands[1]),
5390 if (!arm_arch6 && !MEM_P (operands[1]))
5392 rtx t = gen_lowpart (SImode, operands[1]);
5393 rtx tmp = gen_reg_rtx (SImode);
5394 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5395 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5401 [(set (match_operand:SI 0 "s_register_operand" "")
5402 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5404 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5405 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5407 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5410 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5415 (define_insn "*arm_zero_extendqisi2"
5416 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5417 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5418 "TARGET_ARM && !arm_arch6"
5421 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5422 [(set_attr "length" "8,4")
5423 (set_attr "type" "alu_shift_reg,load_byte")
5424 (set_attr "predicable" "yes")]
5427 (define_insn "*arm_zero_extendqisi2_v6"
5428 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5429 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5430 "TARGET_ARM && arm_arch6"
5433 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5434 [(set_attr "type" "extend,load_byte")
5435 (set_attr "predicable" "yes")]
5438 (define_insn "*arm_zero_extendqisi2addsi"
5439 [(set (match_operand:SI 0 "s_register_operand" "=r")
5440 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5441 (match_operand:SI 2 "s_register_operand" "r")))]
5443 "uxtab%?\\t%0, %2, %1"
5444 [(set_attr "predicable" "yes")
5445 (set_attr "type" "alu_shift_reg")]
5449 [(set (match_operand:SI 0 "s_register_operand" "")
5450 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5451 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5452 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5453 [(set (match_dup 2) (match_dup 1))
5454 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5459 [(set (match_operand:SI 0 "s_register_operand" "")
5460 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5461 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5462 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5463 [(set (match_dup 2) (match_dup 1))
5464 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5470 [(set (match_operand:SI 0 "s_register_operand" "")
5471 (IOR_XOR:SI (and:SI (ashift:SI
5472 (match_operand:SI 1 "s_register_operand" "")
5473 (match_operand:SI 2 "const_int_operand" ""))
5474 (match_operand:SI 3 "const_int_operand" ""))
5476 (match_operator 5 "subreg_lowpart_operator"
5477 [(match_operand:SI 4 "s_register_operand" "")]))))]
5479 && (UINTVAL (operands[3])
5480 == (GET_MODE_MASK (GET_MODE (operands[5]))
5481 & (GET_MODE_MASK (GET_MODE (operands[5]))
5482 << (INTVAL (operands[2])))))"
5483 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5485 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5486 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5489 (define_insn "*compareqi_eq0"
5490 [(set (reg:CC_Z CC_REGNUM)
5491 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5495 [(set_attr "conds" "set")
5496 (set_attr "predicable" "yes")
5497 (set_attr "type" "logic_imm")]
5500 (define_expand "extendhisi2"
5501 [(set (match_operand:SI 0 "s_register_operand" "")
5502 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5507 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5510 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5512 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5516 if (!arm_arch6 && !MEM_P (operands[1]))
5518 rtx t = gen_lowpart (SImode, operands[1]);
5519 rtx tmp = gen_reg_rtx (SImode);
5520 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5521 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5528 [(set (match_operand:SI 0 "register_operand" "")
5529 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5530 (clobber (match_scratch:SI 2 ""))])]
5532 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5533 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5535 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5538 ;; This pattern will only be used when ldsh is not available
5539 (define_expand "extendhisi2_mem"
5540 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5542 (zero_extend:SI (match_dup 7)))
5543 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5544 (set (match_operand:SI 0 "" "")
5545 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5550 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5552 mem1 = change_address (operands[1], QImode, addr);
5553 mem2 = change_address (operands[1], QImode,
5554 plus_constant (Pmode, addr, 1));
5555 operands[0] = gen_lowpart (SImode, operands[0]);
5557 operands[2] = gen_reg_rtx (SImode);
5558 operands[3] = gen_reg_rtx (SImode);
5559 operands[6] = gen_reg_rtx (SImode);
5562 if (BYTES_BIG_ENDIAN)
5564 operands[4] = operands[2];
5565 operands[5] = operands[3];
5569 operands[4] = operands[3];
5570 operands[5] = operands[2];
5576 [(set (match_operand:SI 0 "register_operand" "")
5577 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5579 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5580 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5582 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5585 (define_insn "*arm_extendhisi2"
5586 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5587 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5588 "TARGET_ARM && arm_arch4 && !arm_arch6"
5592 [(set_attr "length" "8,4")
5593 (set_attr "type" "alu_shift_reg,load_byte")
5594 (set_attr "predicable" "yes")]
5597 ;; ??? Check Thumb-2 pool range
5598 (define_insn "*arm_extendhisi2_v6"
5599 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5600 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5601 "TARGET_32BIT && arm_arch6"
5605 [(set_attr "type" "extend,load_byte")
5606 (set_attr "predicable" "yes")]
5609 (define_insn "*arm_extendhisi2addsi"
5610 [(set (match_operand:SI 0 "s_register_operand" "=r")
5611 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5612 (match_operand:SI 2 "s_register_operand" "r")))]
5614 "sxtah%?\\t%0, %2, %1"
5615 [(set_attr "type" "alu_shift_reg")]
5618 (define_expand "extendqihi2"
5620 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5622 (set (match_operand:HI 0 "s_register_operand" "")
5623 (ashiftrt:SI (match_dup 2)
5628 if (arm_arch4 && MEM_P (operands[1]))
5630 emit_insn (gen_rtx_SET (operands[0],
5631 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5634 if (!s_register_operand (operands[1], QImode))
5635 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5636 operands[0] = gen_lowpart (SImode, operands[0]);
5637 operands[1] = gen_lowpart (SImode, operands[1]);
5638 operands[2] = gen_reg_rtx (SImode);
5642 (define_insn "*arm_extendqihi_insn"
5643 [(set (match_operand:HI 0 "s_register_operand" "=r")
5644 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5645 "TARGET_ARM && arm_arch4"
5647 [(set_attr "type" "load_byte")
5648 (set_attr "predicable" "yes")]
5651 (define_expand "extendqisi2"
5652 [(set (match_operand:SI 0 "s_register_operand" "")
5653 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5656 if (!arm_arch4 && MEM_P (operands[1]))
5657 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5659 if (!arm_arch6 && !MEM_P (operands[1]))
5661 rtx t = gen_lowpart (SImode, operands[1]);
5662 rtx tmp = gen_reg_rtx (SImode);
5663 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5664 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5670 [(set (match_operand:SI 0 "register_operand" "")
5671 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5673 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5674 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5676 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5679 (define_insn "*arm_extendqisi"
5680 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5681 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5682 "TARGET_ARM && arm_arch4 && !arm_arch6"
5686 [(set_attr "length" "8,4")
5687 (set_attr "type" "alu_shift_reg,load_byte")
5688 (set_attr "predicable" "yes")]
5691 (define_insn "*arm_extendqisi_v6"
5692 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5694 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5695 "TARGET_ARM && arm_arch6"
5699 [(set_attr "type" "extend,load_byte")
5700 (set_attr "predicable" "yes")]
5703 (define_insn "*arm_extendqisi2addsi"
5704 [(set (match_operand:SI 0 "s_register_operand" "=r")
5705 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5706 (match_operand:SI 2 "s_register_operand" "r")))]
5708 "sxtab%?\\t%0, %2, %1"
5709 [(set_attr "type" "alu_shift_reg")
5710 (set_attr "predicable" "yes")]
5713 (define_expand "extendsfdf2"
5714 [(set (match_operand:DF 0 "s_register_operand" "")
5715 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5716 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5720 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5721 ;; must go through SFmode.
5723 ;; This is always safe for an extend.
5725 (define_expand "extendhfdf2"
5726 [(set (match_operand:DF 0 "s_register_operand" "")
5727 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5730 /* We don't have a direct instruction for this, so go via SFmode. */
5731 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5734 op1 = convert_to_mode (SFmode, operands[1], 0);
5735 op1 = convert_to_mode (DFmode, op1, 0);
5736 emit_insn (gen_movdf (operands[0], op1));
5739 /* Otherwise, we're done producing RTL and will pick up the correct
5740 pattern to do this with one rounding-step in a single instruction. */
5744 ;; Move insns (including loads and stores)
5746 ;; XXX Just some ideas about movti.
5747 ;; I don't think these are a good idea on the arm, there just aren't enough
5749 ;;(define_expand "loadti"
5750 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5751 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5754 ;;(define_expand "storeti"
5755 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5756 ;; (match_operand:TI 1 "s_register_operand" ""))]
5759 ;;(define_expand "movti"
5760 ;; [(set (match_operand:TI 0 "general_operand" "")
5761 ;; (match_operand:TI 1 "general_operand" ""))]
5767 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5768 ;; operands[1] = copy_to_reg (operands[1]);
5769 ;; if (MEM_P (operands[0]))
5770 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5771 ;; else if (MEM_P (operands[1]))
5772 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5776 ;; emit_insn (insn);
5780 ;; Recognize garbage generated above.
5783 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5784 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5788 ;; register mem = (which_alternative < 3);
5789 ;; register const char *template;
5791 ;; operands[mem] = XEXP (operands[mem], 0);
5792 ;; switch (which_alternative)
5794 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5795 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5796 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5797 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5798 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5799 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5801 ;; output_asm_insn (template, operands);
5805 (define_expand "movdi"
5806 [(set (match_operand:DI 0 "general_operand" "")
5807 (match_operand:DI 1 "general_operand" ""))]
5810 if (can_create_pseudo_p ())
5812 if (!REG_P (operands[0]))
5813 operands[1] = force_reg (DImode, operands[1]);
5815 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5816 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5818 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5819 when expanding function calls. */
5820 gcc_assert (can_create_pseudo_p ());
5821 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5823 /* Perform load into legal reg pair first, then move. */
5824 rtx reg = gen_reg_rtx (DImode);
5825 emit_insn (gen_movdi (reg, operands[1]));
5828 emit_move_insn (gen_lowpart (SImode, operands[0]),
5829 gen_lowpart (SImode, operands[1]));
5830 emit_move_insn (gen_highpart (SImode, operands[0]),
5831 gen_highpart (SImode, operands[1]));
5834 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5835 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5837 /* Avoid STRD's from an odd-numbered register pair in ARM state
5838 when expanding function prologue. */
5839 gcc_assert (can_create_pseudo_p ());
5840 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5841 ? gen_reg_rtx (DImode)
5843 emit_move_insn (gen_lowpart (SImode, split_dest),
5844 gen_lowpart (SImode, operands[1]));
5845 emit_move_insn (gen_highpart (SImode, split_dest),
5846 gen_highpart (SImode, operands[1]));
5847 if (split_dest != operands[0])
5848 emit_insn (gen_movdi (operands[0], split_dest));
5854 (define_insn "*arm_movdi"
5855 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
5856 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
5858 && !(TARGET_HARD_FLOAT)
5860 && ( register_operand (operands[0], DImode)
5861 || register_operand (operands[1], DImode))"
5863 switch (which_alternative)
5870 /* Cannot load it directly, split to load it via MOV / MOVT. */
5871 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
5875 return output_move_double (operands, true, NULL);
5878 [(set_attr "length" "8,12,16,8,8")
5879 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5880 (set_attr "arm_pool_range" "*,*,*,1020,*")
5881 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5882 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5883 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5887 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5888 (match_operand:ANY64 1 "immediate_operand" ""))]
5891 && (arm_disable_literal_pool
5892 || (arm_const_double_inline_cost (operands[1])
5893 <= arm_max_const_double_inline_cost ()))"
5896 arm_split_constant (SET, SImode, curr_insn,
5897 INTVAL (gen_lowpart (SImode, operands[1])),
5898 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5899 arm_split_constant (SET, SImode, curr_insn,
5900 INTVAL (gen_highpart_mode (SImode,
5901 GET_MODE (operands[0]),
5903 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5908 ; If optimizing for size, or if we have load delay slots, then
5909 ; we want to split the constant into two separate operations.
5910 ; In both cases this may split a trivial part into a single data op
5911 ; leaving a single complex constant to load. We can also get longer
5912 ; offsets in a LDR which means we get better chances of sharing the pool
5913 ; entries. Finally, we can normally do a better job of scheduling
5914 ; LDR instructions than we can with LDM.
5915 ; This pattern will only match if the one above did not.
5917 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5918 (match_operand:ANY64 1 "const_double_operand" ""))]
5919 "TARGET_ARM && reload_completed
5920 && arm_const_double_by_parts (operands[1])"
5921 [(set (match_dup 0) (match_dup 1))
5922 (set (match_dup 2) (match_dup 3))]
5924 operands[2] = gen_highpart (SImode, operands[0]);
5925 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5927 operands[0] = gen_lowpart (SImode, operands[0]);
5928 operands[1] = gen_lowpart (SImode, operands[1]);
5933 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5934 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5935 "TARGET_EITHER && reload_completed"
5936 [(set (match_dup 0) (match_dup 1))
5937 (set (match_dup 2) (match_dup 3))]
5939 operands[2] = gen_highpart (SImode, operands[0]);
5940 operands[3] = gen_highpart (SImode, operands[1]);
5941 operands[0] = gen_lowpart (SImode, operands[0]);
5942 operands[1] = gen_lowpart (SImode, operands[1]);
5944 /* Handle a partial overlap. */
5945 if (rtx_equal_p (operands[0], operands[3]))
5947 rtx tmp0 = operands[0];
5948 rtx tmp1 = operands[1];
5950 operands[0] = operands[2];
5951 operands[1] = operands[3];
5958 ;; We can't actually do base+index doubleword loads if the index and
5959 ;; destination overlap. Split here so that we at least have chance to
5962 [(set (match_operand:DI 0 "s_register_operand" "")
5963 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5964 (match_operand:SI 2 "s_register_operand" ""))))]
5966 && reg_overlap_mentioned_p (operands[0], operands[1])
5967 && reg_overlap_mentioned_p (operands[0], operands[2])"
5969 (plus:SI (match_dup 1)
5972 (mem:DI (match_dup 4)))]
5974 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5978 (define_expand "movsi"
5979 [(set (match_operand:SI 0 "general_operand" "")
5980 (match_operand:SI 1 "general_operand" ""))]
5984 rtx base, offset, tmp;
5986 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5988 /* Everything except mem = const or mem = mem can be done easily. */
5989 if (MEM_P (operands[0]))
5990 operands[1] = force_reg (SImode, operands[1]);
5991 if (arm_general_register_operand (operands[0], SImode)
5992 && CONST_INT_P (operands[1])
5993 && !(const_ok_for_arm (INTVAL (operands[1]))
5994 || const_ok_for_arm (~INTVAL (operands[1]))))
5996 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5998 emit_insn (gen_rtx_SET (operands[0], operands[1]));
6003 arm_split_constant (SET, SImode, NULL_RTX,
6004 INTVAL (operands[1]), operands[0], NULL_RTX,
6005 optimize && can_create_pseudo_p ());
6010 else /* Target doesn't have MOVT... */
6012 if (can_create_pseudo_p ())
6014 if (!REG_P (operands[0]))
6015 operands[1] = force_reg (SImode, operands[1]);
6019 split_const (operands[1], &base, &offset);
6020 if (INTVAL (offset) != 0
6021 && targetm.cannot_force_const_mem (SImode, operands[1]))
6023 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6024 emit_move_insn (tmp, base);
6025 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6029 tmp = can_create_pseudo_p () ? NULL_RTX : operands[0];
6031 /* Recognize the case where operand[1] is a reference to thread-local
6032 data and load its address to a register. Offsets have been split off
6034 if (arm_tls_referenced_p (operands[1]))
6035 operands[1] = legitimize_tls_address (operands[1], tmp);
6037 && (CONSTANT_P (operands[1])
6038 || symbol_mentioned_p (operands[1])
6039 || label_mentioned_p (operands[1])))
6041 legitimize_pic_address (operands[1], SImode, tmp, NULL_RTX, false);
6046 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6047 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6048 ;; so this does not matter.
6049 (define_insn "*arm_movt"
6050 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6051 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6052 (match_operand:SI 2 "general_operand" "i,i")))]
6053 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6055 movt%?\t%0, #:upper16:%c2
6056 movt\t%0, #:upper16:%c2"
6057 [(set_attr "arch" "32,v8mb")
6058 (set_attr "predicable" "yes")
6059 (set_attr "length" "4")
6060 (set_attr "type" "alu_sreg")]
6063 (define_insn "*arm_movsi_insn"
6064 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6065 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6066 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6067 && ( register_operand (operands[0], SImode)
6068 || register_operand (operands[1], SImode))"
6076 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6077 (set_attr "predicable" "yes")
6078 (set_attr "arch" "*,*,*,v6t2,*,*")
6079 (set_attr "pool_range" "*,*,*,*,4096,*")
6080 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6084 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6085 (match_operand:SI 1 "const_int_operand" ""))]
6086 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6087 && (!(const_ok_for_arm (INTVAL (operands[1]))
6088 || const_ok_for_arm (~INTVAL (operands[1]))))"
6089 [(clobber (const_int 0))]
6091 arm_split_constant (SET, SImode, NULL_RTX,
6092 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6097 ;; A normal way to do (symbol + offset) requires three instructions at least
6098 ;; (depends on how big the offset is) as below:
6099 ;; movw r0, #:lower16:g
6100 ;; movw r0, #:upper16:g
6103 ;; A better way would be:
6104 ;; movw r0, #:lower16:g+4
6105 ;; movw r0, #:upper16:g+4
6107 ;; The limitation of this way is that the length of offset should be a 16-bit
6108 ;; signed value, because current assembler only supports REL type relocation for
6109 ;; such case. If the more powerful RELA type is supported in future, we should
6110 ;; update this pattern to go with better way.
6112 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6113 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6114 (match_operand:SI 2 "const_int_operand" ""))))]
6117 && arm_disable_literal_pool
6119 && GET_CODE (operands[1]) == SYMBOL_REF"
6120 [(clobber (const_int 0))]
6122 int offset = INTVAL (operands[2]);
6124 if (offset < -0x8000 || offset > 0x7fff)
6126 arm_emit_movpair (operands[0], operands[1]);
6127 emit_insn (gen_rtx_SET (operands[0],
6128 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6132 rtx op = gen_rtx_CONST (SImode,
6133 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6134 arm_emit_movpair (operands[0], op);
6139 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6140 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6141 ;; and lo_sum would be merged back into memory load at cprop. However,
6142 ;; if the default is to prefer movt/movw rather than a load from the constant
6143 ;; pool, the performance is better.
6145 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6146 (match_operand:SI 1 "general_operand" ""))]
6147 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6148 && !target_word_relocations
6149 && !arm_tls_referenced_p (operands[1])"
6150 [(clobber (const_int 0))]
6152 arm_emit_movpair (operands[0], operands[1]);
6156 ;; When generating pic, we need to load the symbol offset into a register.
6157 ;; So that the optimizer does not confuse this with a normal symbol load
6158 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6159 ;; since that is the only type of relocation we can use.
6161 ;; Wrap calculation of the whole PIC address in a single pattern for the
6162 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6163 ;; a PIC address involves two loads from memory, so we want to CSE it
6164 ;; as often as possible.
6165 ;; This pattern will be split into one of the pic_load_addr_* patterns
6166 ;; and a move after GCSE optimizations.
6168 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6169 (define_expand "calculate_pic_address"
6170 [(set (match_operand:SI 0 "register_operand" "")
6171 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6172 (unspec:SI [(match_operand:SI 2 "" "")]
6177 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6179 [(set (match_operand:SI 0 "register_operand" "")
6180 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6181 (unspec:SI [(match_operand:SI 2 "" "")]
6184 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6185 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6186 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6189 ;; operand1 is the memory address to go into
6190 ;; pic_load_addr_32bit.
6191 ;; operand2 is the PIC label to be emitted
6192 ;; from pic_add_dot_plus_eight.
6193 ;; We do this to allow hoisting of the entire insn.
6194 (define_insn_and_split "pic_load_addr_unified"
6195 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6196 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6197 (match_operand:SI 2 "" "")]
6198 UNSPEC_PIC_UNIFIED))]
6201 "&& reload_completed"
6202 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6203 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6204 (match_dup 2)] UNSPEC_PIC_BASE))]
6205 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6206 [(set_attr "type" "load_4,load_4,load_4")
6207 (set_attr "pool_range" "4096,4094,1022")
6208 (set_attr "neg_pool_range" "4084,0,0")
6209 (set_attr "arch" "a,t2,t1")
6210 (set_attr "length" "8,6,4")]
6213 ;; The rather odd constraints on the following are to force reload to leave
6214 ;; the insn alone, and to force the minipool generation pass to then move
6215 ;; the GOT symbol to memory.
6217 (define_insn "pic_load_addr_32bit"
6218 [(set (match_operand:SI 0 "s_register_operand" "=r")
6219 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6220 "TARGET_32BIT && flag_pic"
6222 [(set_attr "type" "load_4")
6223 (set (attr "pool_range")
6224 (if_then_else (eq_attr "is_thumb" "no")
6227 (set (attr "neg_pool_range")
6228 (if_then_else (eq_attr "is_thumb" "no")
6233 (define_insn "pic_load_addr_thumb1"
6234 [(set (match_operand:SI 0 "s_register_operand" "=l")
6235 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6236 "TARGET_THUMB1 && flag_pic"
6238 [(set_attr "type" "load_4")
6239 (set (attr "pool_range") (const_int 1018))]
6242 (define_insn "pic_add_dot_plus_four"
6243 [(set (match_operand:SI 0 "register_operand" "=r")
6244 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6246 (match_operand 2 "" "")]
6250 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6251 INTVAL (operands[2]));
6252 return \"add\\t%0, %|pc\";
6254 [(set_attr "length" "2")
6255 (set_attr "type" "alu_sreg")]
6258 (define_insn "pic_add_dot_plus_eight"
6259 [(set (match_operand:SI 0 "register_operand" "=r")
6260 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6262 (match_operand 2 "" "")]
6266 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6267 INTVAL (operands[2]));
6268 return \"add%?\\t%0, %|pc, %1\";
6270 [(set_attr "predicable" "yes")
6271 (set_attr "type" "alu_sreg")]
6274 (define_insn "tls_load_dot_plus_eight"
6275 [(set (match_operand:SI 0 "register_operand" "=r")
6276 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6278 (match_operand 2 "" "")]
6282 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6283 INTVAL (operands[2]));
6284 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6286 [(set_attr "predicable" "yes")
6287 (set_attr "type" "load_4")]
6290 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6291 ;; followed by a load. These sequences can be crunched down to
6292 ;; tls_load_dot_plus_eight by a peephole.
6295 [(set (match_operand:SI 0 "register_operand" "")
6296 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6298 (match_operand 1 "" "")]
6300 (set (match_operand:SI 2 "arm_general_register_operand" "")
6301 (mem:SI (match_dup 0)))]
6302 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6304 (mem:SI (unspec:SI [(match_dup 3)
6311 (define_insn "pic_offset_arm"
6312 [(set (match_operand:SI 0 "register_operand" "=r")
6313 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6314 (unspec:SI [(match_operand:SI 2 "" "X")]
6315 UNSPEC_PIC_OFFSET))))]
6316 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6317 "ldr%?\\t%0, [%1,%2]"
6318 [(set_attr "type" "load_4")]
6321 (define_expand "builtin_setjmp_receiver"
6322 [(label_ref (match_operand 0 "" ""))]
6326 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6328 if (arm_pic_register != INVALID_REGNUM)
6329 arm_load_pic_register (1UL << 3, NULL_RTX);
6333 ;; If copying one reg to another we can set the condition codes according to
6334 ;; its value. Such a move is common after a return from subroutine and the
6335 ;; result is being tested against zero.
6337 (define_insn "*movsi_compare0"
6338 [(set (reg:CC CC_REGNUM)
6339 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6341 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6346 subs%?\\t%0, %1, #0"
6347 [(set_attr "conds" "set")
6348 (set_attr "type" "alus_imm,alus_imm")]
6351 ;; Subroutine to store a half word from a register into memory.
6352 ;; Operand 0 is the source register (HImode)
6353 ;; Operand 1 is the destination address in a register (SImode)
6355 ;; In both this routine and the next, we must be careful not to spill
6356 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6357 ;; can generate unrecognizable rtl.
6359 (define_expand "storehi"
6360 [;; store the low byte
6361 (set (match_operand 1 "" "") (match_dup 3))
6362 ;; extract the high byte
6364 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6365 ;; store the high byte
6366 (set (match_dup 4) (match_dup 5))]
6370 rtx op1 = operands[1];
6371 rtx addr = XEXP (op1, 0);
6372 enum rtx_code code = GET_CODE (addr);
6374 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6376 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6378 operands[4] = adjust_address (op1, QImode, 1);
6379 operands[1] = adjust_address (operands[1], QImode, 0);
6380 operands[3] = gen_lowpart (QImode, operands[0]);
6381 operands[0] = gen_lowpart (SImode, operands[0]);
6382 operands[2] = gen_reg_rtx (SImode);
6383 operands[5] = gen_lowpart (QImode, operands[2]);
6387 (define_expand "storehi_bigend"
6388 [(set (match_dup 4) (match_dup 3))
6390 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6391 (set (match_operand 1 "" "") (match_dup 5))]
6395 rtx op1 = operands[1];
6396 rtx addr = XEXP (op1, 0);
6397 enum rtx_code code = GET_CODE (addr);
6399 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6401 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6403 operands[4] = adjust_address (op1, QImode, 1);
6404 operands[1] = adjust_address (operands[1], QImode, 0);
6405 operands[3] = gen_lowpart (QImode, operands[0]);
6406 operands[0] = gen_lowpart (SImode, operands[0]);
6407 operands[2] = gen_reg_rtx (SImode);
6408 operands[5] = gen_lowpart (QImode, operands[2]);
6412 ;; Subroutine to store a half word integer constant into memory.
6413 (define_expand "storeinthi"
6414 [(set (match_operand 0 "" "")
6415 (match_operand 1 "" ""))
6416 (set (match_dup 3) (match_dup 2))]
6420 HOST_WIDE_INT value = INTVAL (operands[1]);
6421 rtx addr = XEXP (operands[0], 0);
6422 rtx op0 = operands[0];
6423 enum rtx_code code = GET_CODE (addr);
6425 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6427 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6429 operands[1] = gen_reg_rtx (SImode);
6430 if (BYTES_BIG_ENDIAN)
6432 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6433 if ((value & 255) == ((value >> 8) & 255))
6434 operands[2] = operands[1];
6437 operands[2] = gen_reg_rtx (SImode);
6438 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6443 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6444 if ((value & 255) == ((value >> 8) & 255))
6445 operands[2] = operands[1];
6448 operands[2] = gen_reg_rtx (SImode);
6449 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6453 operands[3] = adjust_address (op0, QImode, 1);
6454 operands[0] = adjust_address (operands[0], QImode, 0);
6455 operands[2] = gen_lowpart (QImode, operands[2]);
6456 operands[1] = gen_lowpart (QImode, operands[1]);
6460 (define_expand "storehi_single_op"
6461 [(set (match_operand:HI 0 "memory_operand" "")
6462 (match_operand:HI 1 "general_operand" ""))]
6463 "TARGET_32BIT && arm_arch4"
6465 if (!s_register_operand (operands[1], HImode))
6466 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6470 (define_expand "movhi"
6471 [(set (match_operand:HI 0 "general_operand" "")
6472 (match_operand:HI 1 "general_operand" ""))]
6477 if (can_create_pseudo_p ())
6479 if (MEM_P (operands[0]))
6483 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6486 if (CONST_INT_P (operands[1]))
6487 emit_insn (gen_storeinthi (operands[0], operands[1]));
6490 if (MEM_P (operands[1]))
6491 operands[1] = force_reg (HImode, operands[1]);
6492 if (BYTES_BIG_ENDIAN)
6493 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6495 emit_insn (gen_storehi (operands[1], operands[0]));
6499 /* Sign extend a constant, and keep it in an SImode reg. */
6500 else if (CONST_INT_P (operands[1]))
6502 rtx reg = gen_reg_rtx (SImode);
6503 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6505 /* If the constant is already valid, leave it alone. */
6506 if (!const_ok_for_arm (val))
6508 /* If setting all the top bits will make the constant
6509 loadable in a single instruction, then set them.
6510 Otherwise, sign extend the number. */
6512 if (const_ok_for_arm (~(val | ~0xffff)))
6514 else if (val & 0x8000)
6518 emit_insn (gen_movsi (reg, GEN_INT (val)));
6519 operands[1] = gen_lowpart (HImode, reg);
6521 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6522 && MEM_P (operands[1]))
6524 rtx reg = gen_reg_rtx (SImode);
6526 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6527 operands[1] = gen_lowpart (HImode, reg);
6529 else if (!arm_arch4)
6531 if (MEM_P (operands[1]))
6534 rtx offset = const0_rtx;
6535 rtx reg = gen_reg_rtx (SImode);
6537 if ((REG_P (base = XEXP (operands[1], 0))
6538 || (GET_CODE (base) == PLUS
6539 && (CONST_INT_P (offset = XEXP (base, 1)))
6540 && ((INTVAL(offset) & 1) != 1)
6541 && REG_P (base = XEXP (base, 0))))
6542 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6546 new_rtx = widen_memory_access (operands[1], SImode,
6547 ((INTVAL (offset) & ~3)
6548 - INTVAL (offset)));
6549 emit_insn (gen_movsi (reg, new_rtx));
6550 if (((INTVAL (offset) & 2) != 0)
6551 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6553 rtx reg2 = gen_reg_rtx (SImode);
6555 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6560 emit_insn (gen_movhi_bytes (reg, operands[1]));
6562 operands[1] = gen_lowpart (HImode, reg);
6566 /* Handle loading a large integer during reload. */
6567 else if (CONST_INT_P (operands[1])
6568 && !const_ok_for_arm (INTVAL (operands[1]))
6569 && !const_ok_for_arm (~INTVAL (operands[1])))
6571 /* Writing a constant to memory needs a scratch, which should
6572 be handled with SECONDARY_RELOADs. */
6573 gcc_assert (REG_P (operands[0]));
6575 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6576 emit_insn (gen_movsi (operands[0], operands[1]));
6580 else if (TARGET_THUMB2)
6582 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6583 if (can_create_pseudo_p ())
6585 if (!REG_P (operands[0]))
6586 operands[1] = force_reg (HImode, operands[1]);
6587 /* Zero extend a constant, and keep it in an SImode reg. */
6588 else if (CONST_INT_P (operands[1]))
6590 rtx reg = gen_reg_rtx (SImode);
6591 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6593 emit_insn (gen_movsi (reg, GEN_INT (val)));
6594 operands[1] = gen_lowpart (HImode, reg);
6598 else /* TARGET_THUMB1 */
6600 if (can_create_pseudo_p ())
6602 if (CONST_INT_P (operands[1]))
6604 rtx reg = gen_reg_rtx (SImode);
6606 emit_insn (gen_movsi (reg, operands[1]));
6607 operands[1] = gen_lowpart (HImode, reg);
6610 /* ??? We shouldn't really get invalid addresses here, but this can
6611 happen if we are passed a SP (never OK for HImode/QImode) or
6612 virtual register (also rejected as illegitimate for HImode/QImode)
6613 relative address. */
6614 /* ??? This should perhaps be fixed elsewhere, for instance, in
6615 fixup_stack_1, by checking for other kinds of invalid addresses,
6616 e.g. a bare reference to a virtual register. This may confuse the
6617 alpha though, which must handle this case differently. */
6618 if (MEM_P (operands[0])
6619 && !memory_address_p (GET_MODE (operands[0]),
6620 XEXP (operands[0], 0)))
6622 = replace_equiv_address (operands[0],
6623 copy_to_reg (XEXP (operands[0], 0)));
6625 if (MEM_P (operands[1])
6626 && !memory_address_p (GET_MODE (operands[1]),
6627 XEXP (operands[1], 0)))
6629 = replace_equiv_address (operands[1],
6630 copy_to_reg (XEXP (operands[1], 0)));
6632 if (MEM_P (operands[1]) && optimize > 0)
6634 rtx reg = gen_reg_rtx (SImode);
6636 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6637 operands[1] = gen_lowpart (HImode, reg);
6640 if (MEM_P (operands[0]))
6641 operands[1] = force_reg (HImode, operands[1]);
6643 else if (CONST_INT_P (operands[1])
6644 && !satisfies_constraint_I (operands[1]))
6646 /* Handle loading a large integer during reload. */
6648 /* Writing a constant to memory needs a scratch, which should
6649 be handled with SECONDARY_RELOADs. */
6650 gcc_assert (REG_P (operands[0]));
6652 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6653 emit_insn (gen_movsi (operands[0], operands[1]));
6660 (define_expand "movhi_bytes"
6661 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6663 (zero_extend:SI (match_dup 6)))
6664 (set (match_operand:SI 0 "" "")
6665 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6670 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6672 mem1 = change_address (operands[1], QImode, addr);
6673 mem2 = change_address (operands[1], QImode,
6674 plus_constant (Pmode, addr, 1));
6675 operands[0] = gen_lowpart (SImode, operands[0]);
6677 operands[2] = gen_reg_rtx (SImode);
6678 operands[3] = gen_reg_rtx (SImode);
6681 if (BYTES_BIG_ENDIAN)
6683 operands[4] = operands[2];
6684 operands[5] = operands[3];
6688 operands[4] = operands[3];
6689 operands[5] = operands[2];
6694 (define_expand "movhi_bigend"
6696 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6699 (ashiftrt:SI (match_dup 2) (const_int 16)))
6700 (set (match_operand:HI 0 "s_register_operand" "")
6704 operands[2] = gen_reg_rtx (SImode);
6705 operands[3] = gen_reg_rtx (SImode);
6706 operands[4] = gen_lowpart (HImode, operands[3]);
6710 ;; Pattern to recognize insn generated default case above
6711 (define_insn "*movhi_insn_arch4"
6712 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6713 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6715 && arm_arch4 && !TARGET_HARD_FLOAT
6716 && (register_operand (operands[0], HImode)
6717 || register_operand (operands[1], HImode))"
6719 mov%?\\t%0, %1\\t%@ movhi
6720 mvn%?\\t%0, #%B1\\t%@ movhi
6721 movw%?\\t%0, %L1\\t%@ movhi
6722 strh%?\\t%1, %0\\t%@ movhi
6723 ldrh%?\\t%0, %1\\t%@ movhi"
6724 [(set_attr "predicable" "yes")
6725 (set_attr "pool_range" "*,*,*,*,256")
6726 (set_attr "neg_pool_range" "*,*,*,*,244")
6727 (set_attr "arch" "*,*,v6t2,*,*")
6728 (set_attr_alternative "type"
6729 [(if_then_else (match_operand 1 "const_int_operand" "")
6730 (const_string "mov_imm" )
6731 (const_string "mov_reg"))
6732 (const_string "mvn_imm")
6733 (const_string "mov_imm")
6734 (const_string "store_4")
6735 (const_string "load_4")])]
6738 (define_insn "*movhi_bytes"
6739 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6740 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6741 "TARGET_ARM && !TARGET_HARD_FLOAT"
6743 mov%?\\t%0, %1\\t%@ movhi
6744 mov%?\\t%0, %1\\t%@ movhi
6745 mvn%?\\t%0, #%B1\\t%@ movhi"
6746 [(set_attr "predicable" "yes")
6747 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6750 ;; We use a DImode scratch because we may occasionally need an additional
6751 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6752 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6753 (define_expand "reload_outhi"
6754 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6755 (match_operand:HI 1 "s_register_operand" "r")
6756 (match_operand:DI 2 "s_register_operand" "=&l")])]
6759 arm_reload_out_hi (operands);
6761 thumb_reload_out_hi (operands);
6766 (define_expand "reload_inhi"
6767 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6768 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6769 (match_operand:DI 2 "s_register_operand" "=&r")])]
6773 arm_reload_in_hi (operands);
6775 thumb_reload_out_hi (operands);
6779 (define_expand "movqi"
6780 [(set (match_operand:QI 0 "general_operand" "")
6781 (match_operand:QI 1 "general_operand" ""))]
6784 /* Everything except mem = const or mem = mem can be done easily */
6786 if (can_create_pseudo_p ())
6788 if (CONST_INT_P (operands[1]))
6790 rtx reg = gen_reg_rtx (SImode);
6792 /* For thumb we want an unsigned immediate, then we are more likely
6793 to be able to use a movs insn. */
6795 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6797 emit_insn (gen_movsi (reg, operands[1]));
6798 operands[1] = gen_lowpart (QImode, reg);
6803 /* ??? We shouldn't really get invalid addresses here, but this can
6804 happen if we are passed a SP (never OK for HImode/QImode) or
6805 virtual register (also rejected as illegitimate for HImode/QImode)
6806 relative address. */
6807 /* ??? This should perhaps be fixed elsewhere, for instance, in
6808 fixup_stack_1, by checking for other kinds of invalid addresses,
6809 e.g. a bare reference to a virtual register. This may confuse the
6810 alpha though, which must handle this case differently. */
6811 if (MEM_P (operands[0])
6812 && !memory_address_p (GET_MODE (operands[0]),
6813 XEXP (operands[0], 0)))
6815 = replace_equiv_address (operands[0],
6816 copy_to_reg (XEXP (operands[0], 0)));
6817 if (MEM_P (operands[1])
6818 && !memory_address_p (GET_MODE (operands[1]),
6819 XEXP (operands[1], 0)))
6821 = replace_equiv_address (operands[1],
6822 copy_to_reg (XEXP (operands[1], 0)));
6825 if (MEM_P (operands[1]) && optimize > 0)
6827 rtx reg = gen_reg_rtx (SImode);
6829 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6830 operands[1] = gen_lowpart (QImode, reg);
6833 if (MEM_P (operands[0]))
6834 operands[1] = force_reg (QImode, operands[1]);
6836 else if (TARGET_THUMB
6837 && CONST_INT_P (operands[1])
6838 && !satisfies_constraint_I (operands[1]))
6840 /* Handle loading a large integer during reload. */
6842 /* Writing a constant to memory needs a scratch, which should
6843 be handled with SECONDARY_RELOADs. */
6844 gcc_assert (REG_P (operands[0]));
6846 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6847 emit_insn (gen_movsi (operands[0], operands[1]));
6853 (define_insn "*arm_movqi_insn"
6854 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6855 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6857 && ( register_operand (operands[0], QImode)
6858 || register_operand (operands[1], QImode))"
6869 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6870 (set_attr "predicable" "yes")
6871 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6872 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6873 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6877 (define_expand "movhf"
6878 [(set (match_operand:HF 0 "general_operand" "")
6879 (match_operand:HF 1 "general_operand" ""))]
6884 if (MEM_P (operands[0]))
6885 operands[1] = force_reg (HFmode, operands[1]);
6887 else /* TARGET_THUMB1 */
6889 if (can_create_pseudo_p ())
6891 if (!REG_P (operands[0]))
6892 operands[1] = force_reg (HFmode, operands[1]);
6898 (define_insn "*arm32_movhf"
6899 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6900 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6901 "TARGET_32BIT && !TARGET_HARD_FLOAT
6902 && ( s_register_operand (operands[0], HFmode)
6903 || s_register_operand (operands[1], HFmode))"
6905 switch (which_alternative)
6907 case 0: /* ARM register from memory */
6908 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6909 case 1: /* memory from ARM register */
6910 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6911 case 2: /* ARM register from ARM register */
6912 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6913 case 3: /* ARM register from constant */
6918 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6920 ops[0] = operands[0];
6921 ops[1] = GEN_INT (bits);
6922 ops[2] = GEN_INT (bits & 0xff00);
6923 ops[3] = GEN_INT (bits & 0x00ff);
6925 if (arm_arch_thumb2)
6926 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6928 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6935 [(set_attr "conds" "unconditional")
6936 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6937 (set_attr "length" "4,4,4,8")
6938 (set_attr "predicable" "yes")]
6941 (define_expand "movsf"
6942 [(set (match_operand:SF 0 "general_operand" "")
6943 (match_operand:SF 1 "general_operand" ""))]
6948 if (MEM_P (operands[0]))
6949 operands[1] = force_reg (SFmode, operands[1]);
6951 else /* TARGET_THUMB1 */
6953 if (can_create_pseudo_p ())
6955 if (!REG_P (operands[0]))
6956 operands[1] = force_reg (SFmode, operands[1]);
6960 /* Cannot load it directly, generate a load with clobber so that it can be
6961 loaded via GPR with MOV / MOVT. */
6962 if (arm_disable_literal_pool
6963 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6964 && CONST_DOUBLE_P (operands[1])
6965 && TARGET_HARD_FLOAT
6966 && !vfp3_const_double_rtx (operands[1]))
6968 rtx clobreg = gen_reg_rtx (SFmode);
6969 emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
6976 ;; Transform a floating-point move of a constant into a core register into
6977 ;; an SImode operation.
6979 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6980 (match_operand:SF 1 "immediate_operand" ""))]
6983 && CONST_DOUBLE_P (operands[1])"
6984 [(set (match_dup 2) (match_dup 3))]
6986 operands[2] = gen_lowpart (SImode, operands[0]);
6987 operands[3] = gen_lowpart (SImode, operands[1]);
6988 if (operands[2] == 0 || operands[3] == 0)
6993 (define_insn "*arm_movsf_soft_insn"
6994 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6995 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6997 && TARGET_SOFT_FLOAT
6998 && (!MEM_P (operands[0])
6999 || register_operand (operands[1], SFmode))"
7001 switch (which_alternative)
7003 case 0: return \"mov%?\\t%0, %1\";
7005 /* Cannot load it directly, split to load it via MOV / MOVT. */
7006 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7008 return \"ldr%?\\t%0, %1\\t%@ float\";
7009 case 2: return \"str%?\\t%1, %0\\t%@ float\";
7010 default: gcc_unreachable ();
7013 [(set_attr "predicable" "yes")
7014 (set_attr "type" "mov_reg,load_4,store_4")
7015 (set_attr "arm_pool_range" "*,4096,*")
7016 (set_attr "thumb2_pool_range" "*,4094,*")
7017 (set_attr "arm_neg_pool_range" "*,4084,*")
7018 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7021 ;; Splitter for the above.
7023 [(set (match_operand:SF 0 "s_register_operand")
7024 (match_operand:SF 1 "const_double_operand"))]
7025 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7029 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
7030 rtx cst = gen_int_mode (buf, SImode);
7031 emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
7036 (define_expand "movdf"
7037 [(set (match_operand:DF 0 "general_operand" "")
7038 (match_operand:DF 1 "general_operand" ""))]
7043 if (MEM_P (operands[0]))
7044 operands[1] = force_reg (DFmode, operands[1]);
7046 else /* TARGET_THUMB */
7048 if (can_create_pseudo_p ())
7050 if (!REG_P (operands[0]))
7051 operands[1] = force_reg (DFmode, operands[1]);
7055 /* Cannot load it directly, generate a load with clobber so that it can be
7056 loaded via GPR with MOV / MOVT. */
7057 if (arm_disable_literal_pool
7058 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
7059 && CONSTANT_P (operands[1])
7060 && TARGET_HARD_FLOAT
7061 && !arm_const_double_rtx (operands[1])
7062 && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
7064 rtx clobreg = gen_reg_rtx (DFmode);
7065 emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
7072 ;; Reloading a df mode value stored in integer regs to memory can require a
7074 (define_expand "reload_outdf"
7075 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7076 (match_operand:DF 1 "s_register_operand" "r")
7077 (match_operand:SI 2 "s_register_operand" "=&r")]
7081 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7084 operands[2] = XEXP (operands[0], 0);
7085 else if (code == POST_INC || code == PRE_DEC)
7087 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7088 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7089 emit_insn (gen_movdi (operands[0], operands[1]));
7092 else if (code == PRE_INC)
7094 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7096 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7099 else if (code == POST_DEC)
7100 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7102 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7103 XEXP (XEXP (operands[0], 0), 1)));
7105 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7108 if (code == POST_DEC)
7109 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7115 (define_insn "*movdf_soft_insn"
7116 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
7117 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
7118 "TARGET_32BIT && TARGET_SOFT_FLOAT
7119 && ( register_operand (operands[0], DFmode)
7120 || register_operand (operands[1], DFmode))"
7122 switch (which_alternative)
7129 /* Cannot load it directly, split to load it via MOV / MOVT. */
7130 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7134 return output_move_double (operands, true, NULL);
7137 [(set_attr "length" "8,12,16,8,8")
7138 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7139 (set_attr "arm_pool_range" "*,*,*,1020,*")
7140 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7141 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7142 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7145 ;; Splitter for the above.
7147 [(set (match_operand:DF 0 "s_register_operand")
7148 (match_operand:DF 1 "const_double_operand"))]
7149 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7153 int order = BYTES_BIG_ENDIAN ? 1 : 0;
7154 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
7155 unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
7156 ival |= (zext_hwi (buf[1 - order], 32) << 32);
7157 rtx cst = gen_int_mode (ival, DImode);
7158 emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
7164 ;; load- and store-multiple insns
7165 ;; The arm can load/store any set of registers, provided that they are in
7166 ;; ascending order, but these expanders assume a contiguous set.
7168 (define_expand "load_multiple"
7169 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7170 (match_operand:SI 1 "" ""))
7171 (use (match_operand:SI 2 "" ""))])]
7174 HOST_WIDE_INT offset = 0;
7176 /* Support only fixed point registers. */
7177 if (!CONST_INT_P (operands[2])
7178 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7179 || INTVAL (operands[2]) < 2
7180 || !MEM_P (operands[1])
7181 || !REG_P (operands[0])
7182 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7183 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7187 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7188 INTVAL (operands[2]),
7189 force_reg (SImode, XEXP (operands[1], 0)),
7190 FALSE, operands[1], &offset);
7193 (define_expand "store_multiple"
7194 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7195 (match_operand:SI 1 "" ""))
7196 (use (match_operand:SI 2 "" ""))])]
7199 HOST_WIDE_INT offset = 0;
7201 /* Support only fixed point registers. */
7202 if (!CONST_INT_P (operands[2])
7203 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7204 || INTVAL (operands[2]) < 2
7205 || !REG_P (operands[1])
7206 || !MEM_P (operands[0])
7207 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7208 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7212 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7213 INTVAL (operands[2]),
7214 force_reg (SImode, XEXP (operands[0], 0)),
7215 FALSE, operands[0], &offset);
7219 (define_expand "setmemsi"
7220 [(match_operand:BLK 0 "general_operand" "")
7221 (match_operand:SI 1 "const_int_operand" "")
7222 (match_operand:SI 2 "const_int_operand" "")
7223 (match_operand:SI 3 "const_int_operand" "")]
7226 if (arm_gen_setmem (operands))
7233 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7234 ;; We could let this apply for blocks of less than this, but it clobbers so
7235 ;; many registers that there is then probably a better way.
7237 (define_expand "movmemqi"
7238 [(match_operand:BLK 0 "general_operand" "")
7239 (match_operand:BLK 1 "general_operand" "")
7240 (match_operand:SI 2 "const_int_operand" "")
7241 (match_operand:SI 3 "const_int_operand" "")]
7246 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7247 && !optimize_function_for_size_p (cfun))
7249 if (gen_movmem_ldrd_strd (operands))
7254 if (arm_gen_movmemqi (operands))
7258 else /* TARGET_THUMB1 */
7260 if ( INTVAL (operands[3]) != 4
7261 || INTVAL (operands[2]) > 48)
7264 thumb_expand_movmemqi (operands);
7271 ;; Compare & branch insns
7272 ;; The range calculations are based as follows:
7273 ;; For forward branches, the address calculation returns the address of
7274 ;; the next instruction. This is 2 beyond the branch instruction.
7275 ;; For backward branches, the address calculation returns the address of
7276 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7277 ;; instruction for the shortest sequence, and 4 before the branch instruction
7278 ;; if we have to jump around an unconditional branch.
7279 ;; To the basic branch range the PC offset must be added (this is +4).
7280 ;; So for forward branches we have
7281 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7282 ;; And for backward branches we have
7283 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7285 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7286 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7288 (define_expand "cbranchsi4"
7289 [(set (pc) (if_then_else
7290 (match_operator 0 "expandable_comparison_operator"
7291 [(match_operand:SI 1 "s_register_operand" "")
7292 (match_operand:SI 2 "nonmemory_operand" "")])
7293 (label_ref (match_operand 3 "" ""))
7299 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7301 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7305 if (thumb1_cmpneg_operand (operands[2], SImode))
7307 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7308 operands[3], operands[0]));
7311 if (!thumb1_cmp_operand (operands[2], SImode))
7312 operands[2] = force_reg (SImode, operands[2]);
7315 (define_expand "cbranchsf4"
7316 [(set (pc) (if_then_else
7317 (match_operator 0 "expandable_comparison_operator"
7318 [(match_operand:SF 1 "s_register_operand" "")
7319 (match_operand:SF 2 "vfp_compare_operand" "")])
7320 (label_ref (match_operand 3 "" ""))
7322 "TARGET_32BIT && TARGET_HARD_FLOAT"
7323 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7324 operands[3])); DONE;"
7327 (define_expand "cbranchdf4"
7328 [(set (pc) (if_then_else
7329 (match_operator 0 "expandable_comparison_operator"
7330 [(match_operand:DF 1 "s_register_operand" "")
7331 (match_operand:DF 2 "vfp_compare_operand" "")])
7332 (label_ref (match_operand 3 "" ""))
7334 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7335 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7336 operands[3])); DONE;"
7339 (define_expand "cbranchdi4"
7340 [(set (pc) (if_then_else
7341 (match_operator 0 "expandable_comparison_operator"
7342 [(match_operand:DI 1 "s_register_operand" "")
7343 (match_operand:DI 2 "cmpdi_operand" "")])
7344 (label_ref (match_operand 3 "" ""))
7348 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7350 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7356 ;; Comparison and test insns
7358 (define_insn "*arm_cmpsi_insn"
7359 [(set (reg:CC CC_REGNUM)
7360 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7361 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7369 [(set_attr "conds" "set")
7370 (set_attr "arch" "t2,t2,any,any,any")
7371 (set_attr "length" "2,2,4,4,4")
7372 (set_attr "predicable" "yes")
7373 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7374 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7377 (define_insn "*cmpsi_shiftsi"
7378 [(set (reg:CC CC_REGNUM)
7379 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7380 (match_operator:SI 3 "shift_operator"
7381 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7382 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7385 [(set_attr "conds" "set")
7386 (set_attr "shift" "1")
7387 (set_attr "arch" "32,a,a")
7388 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7390 (define_insn "*cmpsi_shiftsi_swp"
7391 [(set (reg:CC_SWP CC_REGNUM)
7392 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7393 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7394 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7395 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7398 [(set_attr "conds" "set")
7399 (set_attr "shift" "1")
7400 (set_attr "arch" "32,a,a")
7401 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7403 (define_insn "*arm_cmpsi_negshiftsi_si"
7404 [(set (reg:CC_Z CC_REGNUM)
7406 (neg:SI (match_operator:SI 1 "shift_operator"
7407 [(match_operand:SI 2 "s_register_operand" "r")
7408 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7409 (match_operand:SI 0 "s_register_operand" "r")))]
7412 [(set_attr "conds" "set")
7413 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7414 (const_string "alus_shift_imm")
7415 (const_string "alus_shift_reg")))
7416 (set_attr "predicable" "yes")]
7419 ;; DImode comparisons. The generic code generates branches that
7420 ;; if-conversion cannot reduce to a conditional compare, so we do
7423 (define_insn_and_split "*arm_cmpdi_insn"
7424 [(set (reg:CC_NCV CC_REGNUM)
7425 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7426 (match_operand:DI 1 "arm_di_operand" "rDi")))
7427 (clobber (match_scratch:SI 2 "=r"))]
7429 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7430 "&& reload_completed"
7431 [(set (reg:CC CC_REGNUM)
7432 (compare:CC (match_dup 0) (match_dup 1)))
7433 (parallel [(set (reg:CC CC_REGNUM)
7434 (compare:CC (match_dup 3) (match_dup 4)))
7436 (minus:SI (match_dup 5)
7437 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7439 operands[3] = gen_highpart (SImode, operands[0]);
7440 operands[0] = gen_lowpart (SImode, operands[0]);
7441 if (CONST_INT_P (operands[1]))
7443 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);
7444 if (operands[4] == const0_rtx)
7445 operands[5] = operands[3];
7447 operands[5] = gen_rtx_PLUS (SImode, operands[3],
7448 gen_int_mode (-UINTVAL (operands[4]),
7453 operands[4] = gen_highpart (SImode, operands[1]);
7454 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7456 operands[1] = gen_lowpart (SImode, operands[1]);
7457 operands[2] = gen_lowpart (SImode, operands[2]);
7459 [(set_attr "conds" "set")
7460 (set_attr "length" "8")
7461 (set_attr "type" "multiple")]
7464 (define_insn_and_split "*arm_cmpdi_unsigned"
7465 [(set (reg:CC_CZ CC_REGNUM)
7466 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7467 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7470 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7471 "&& reload_completed"
7472 [(set (reg:CC CC_REGNUM)
7473 (compare:CC (match_dup 2) (match_dup 3)))
7474 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7475 (set (reg:CC CC_REGNUM)
7476 (compare:CC (match_dup 0) (match_dup 1))))]
7478 operands[2] = gen_highpart (SImode, operands[0]);
7479 operands[0] = gen_lowpart (SImode, operands[0]);
7480 if (CONST_INT_P (operands[1]))
7481 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7483 operands[3] = gen_highpart (SImode, operands[1]);
7484 operands[1] = gen_lowpart (SImode, operands[1]);
7486 [(set_attr "conds" "set")
7487 (set_attr "enabled_for_short_it" "yes,yes,no,*")
7488 (set_attr "arch" "t2,t2,t2,a")
7489 (set_attr "length" "6,6,10,8")
7490 (set_attr "type" "multiple")]
7493 (define_insn "*arm_cmpdi_zero"
7494 [(set (reg:CC_Z CC_REGNUM)
7495 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7497 (clobber (match_scratch:SI 1 "=r"))]
7499 "orrs%?\\t%1, %Q0, %R0"
7500 [(set_attr "conds" "set")
7501 (set_attr "type" "logics_reg")]
7504 ; This insn allows redundant compares to be removed by cse, nothing should
7505 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7506 ; is deleted later on. The match_dup will match the mode here, so that
7507 ; mode changes of the condition codes aren't lost by this even though we don't
7508 ; specify what they are.
7510 (define_insn "*deleted_compare"
7511 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7513 "\\t%@ deleted compare"
7514 [(set_attr "conds" "set")
7515 (set_attr "length" "0")
7516 (set_attr "type" "no_insn")]
7520 ;; Conditional branch insns
7522 (define_expand "cbranch_cc"
7524 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7525 (match_operand 2 "" "")])
7526 (label_ref (match_operand 3 "" ""))
7529 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7530 operands[1], operands[2], NULL_RTX);
7531 operands[2] = const0_rtx;"
7535 ;; Patterns to match conditional branch insns.
7538 (define_insn "arm_cond_branch"
7540 (if_then_else (match_operator 1 "arm_comparison_operator"
7541 [(match_operand 2 "cc_register" "") (const_int 0)])
7542 (label_ref (match_operand 0 "" ""))
7546 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7548 arm_ccfsm_state += 2;
7551 return \"b%d1\\t%l0\";
7553 [(set_attr "conds" "use")
7554 (set_attr "type" "branch")
7555 (set (attr "length")
7557 (and (match_test "TARGET_THUMB2")
7558 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7559 (le (minus (match_dup 0) (pc)) (const_int 256))))
7564 (define_insn "*arm_cond_branch_reversed"
7566 (if_then_else (match_operator 1 "arm_comparison_operator"
7567 [(match_operand 2 "cc_register" "") (const_int 0)])
7569 (label_ref (match_operand 0 "" ""))))]
7572 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7574 arm_ccfsm_state += 2;
7577 return \"b%D1\\t%l0\";
7579 [(set_attr "conds" "use")
7580 (set_attr "type" "branch")
7581 (set (attr "length")
7583 (and (match_test "TARGET_THUMB2")
7584 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7585 (le (minus (match_dup 0) (pc)) (const_int 256))))
7594 (define_expand "cstore_cc"
7595 [(set (match_operand:SI 0 "s_register_operand" "")
7596 (match_operator:SI 1 "" [(match_operand 2 "" "")
7597 (match_operand 3 "" "")]))]
7599 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7600 operands[2], operands[3], NULL_RTX);
7601 operands[3] = const0_rtx;"
7604 (define_insn_and_split "*mov_scc"
7605 [(set (match_operand:SI 0 "s_register_operand" "=r")
7606 (match_operator:SI 1 "arm_comparison_operator_mode"
7607 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7609 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7612 (if_then_else:SI (match_dup 1)
7616 [(set_attr "conds" "use")
7617 (set_attr "length" "8")
7618 (set_attr "type" "multiple")]
7621 (define_insn_and_split "*mov_negscc"
7622 [(set (match_operand:SI 0 "s_register_operand" "=r")
7623 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7624 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7626 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7629 (if_then_else:SI (match_dup 1)
7633 operands[3] = GEN_INT (~0);
7635 [(set_attr "conds" "use")
7636 (set_attr "length" "8")
7637 (set_attr "type" "multiple")]
7640 (define_insn_and_split "*mov_notscc"
7641 [(set (match_operand:SI 0 "s_register_operand" "=r")
7642 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7643 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7645 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7648 (if_then_else:SI (match_dup 1)
7652 operands[3] = GEN_INT (~1);
7653 operands[4] = GEN_INT (~0);
7655 [(set_attr "conds" "use")
7656 (set_attr "length" "8")
7657 (set_attr "type" "multiple")]
7660 (define_expand "cstoresi4"
7661 [(set (match_operand:SI 0 "s_register_operand" "")
7662 (match_operator:SI 1 "expandable_comparison_operator"
7663 [(match_operand:SI 2 "s_register_operand" "")
7664 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7665 "TARGET_32BIT || TARGET_THUMB1"
7667 rtx op3, scratch, scratch2;
7671 if (!arm_add_operand (operands[3], SImode))
7672 operands[3] = force_reg (SImode, operands[3]);
7673 emit_insn (gen_cstore_cc (operands[0], operands[1],
7674 operands[2], operands[3]));
7678 if (operands[3] == const0_rtx)
7680 switch (GET_CODE (operands[1]))
7683 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7687 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7691 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7692 NULL_RTX, 0, OPTAB_WIDEN);
7693 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7694 NULL_RTX, 0, OPTAB_WIDEN);
7695 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7696 operands[0], 1, OPTAB_WIDEN);
7700 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7702 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7703 NULL_RTX, 1, OPTAB_WIDEN);
7707 scratch = expand_binop (SImode, ashr_optab, operands[2],
7708 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7709 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7710 NULL_RTX, 0, OPTAB_WIDEN);
7711 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7715 /* LT is handled by generic code. No need for unsigned with 0. */
7722 switch (GET_CODE (operands[1]))
7725 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7726 NULL_RTX, 0, OPTAB_WIDEN);
7727 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7731 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7732 NULL_RTX, 0, OPTAB_WIDEN);
7733 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7737 op3 = force_reg (SImode, operands[3]);
7739 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7740 NULL_RTX, 1, OPTAB_WIDEN);
7741 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7742 NULL_RTX, 0, OPTAB_WIDEN);
7743 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7749 if (!thumb1_cmp_operand (op3, SImode))
7750 op3 = force_reg (SImode, op3);
7751 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7752 NULL_RTX, 0, OPTAB_WIDEN);
7753 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7754 NULL_RTX, 1, OPTAB_WIDEN);
7755 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7760 op3 = force_reg (SImode, operands[3]);
7761 scratch = force_reg (SImode, const0_rtx);
7762 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7768 if (!thumb1_cmp_operand (op3, SImode))
7769 op3 = force_reg (SImode, op3);
7770 scratch = force_reg (SImode, const0_rtx);
7771 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7777 if (!thumb1_cmp_operand (op3, SImode))
7778 op3 = force_reg (SImode, op3);
7779 scratch = gen_reg_rtx (SImode);
7780 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7784 op3 = force_reg (SImode, operands[3]);
7785 scratch = gen_reg_rtx (SImode);
7786 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7789 /* No good sequences for GT, LT. */
7796 (define_expand "cstorehf4"
7797 [(set (match_operand:SI 0 "s_register_operand")
7798 (match_operator:SI 1 "expandable_comparison_operator"
7799 [(match_operand:HF 2 "s_register_operand")
7800 (match_operand:HF 3 "vfp_compare_operand")]))]
7801 "TARGET_VFP_FP16INST"
7803 if (!arm_validize_comparison (&operands[1],
7808 emit_insn (gen_cstore_cc (operands[0], operands[1],
7809 operands[2], operands[3]));
7814 (define_expand "cstoresf4"
7815 [(set (match_operand:SI 0 "s_register_operand" "")
7816 (match_operator:SI 1 "expandable_comparison_operator"
7817 [(match_operand:SF 2 "s_register_operand" "")
7818 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7819 "TARGET_32BIT && TARGET_HARD_FLOAT"
7820 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7821 operands[2], operands[3])); DONE;"
7824 (define_expand "cstoredf4"
7825 [(set (match_operand:SI 0 "s_register_operand" "")
7826 (match_operator:SI 1 "expandable_comparison_operator"
7827 [(match_operand:DF 2 "s_register_operand" "")
7828 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7829 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7830 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7831 operands[2], operands[3])); DONE;"
7834 (define_expand "cstoredi4"
7835 [(set (match_operand:SI 0 "s_register_operand" "")
7836 (match_operator:SI 1 "expandable_comparison_operator"
7837 [(match_operand:DI 2 "s_register_operand" "")
7838 (match_operand:DI 3 "cmpdi_operand" "")]))]
7841 if (!arm_validize_comparison (&operands[1],
7845 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7852 ;; Conditional move insns
7854 (define_expand "movsicc"
7855 [(set (match_operand:SI 0 "s_register_operand" "")
7856 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7857 (match_operand:SI 2 "arm_not_operand" "")
7858 (match_operand:SI 3 "arm_not_operand" "")))]
7865 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7866 &XEXP (operands[1], 1)))
7869 code = GET_CODE (operands[1]);
7870 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7871 XEXP (operands[1], 1), NULL_RTX);
7872 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7876 (define_expand "movhfcc"
7877 [(set (match_operand:HF 0 "s_register_operand")
7878 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7879 (match_operand:HF 2 "s_register_operand")
7880 (match_operand:HF 3 "s_register_operand")))]
7881 "TARGET_VFP_FP16INST"
7884 enum rtx_code code = GET_CODE (operands[1]);
7887 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7888 &XEXP (operands[1], 1)))
7891 code = GET_CODE (operands[1]);
7892 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7893 XEXP (operands[1], 1), NULL_RTX);
7894 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7898 (define_expand "movsfcc"
7899 [(set (match_operand:SF 0 "s_register_operand" "")
7900 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7901 (match_operand:SF 2 "s_register_operand" "")
7902 (match_operand:SF 3 "s_register_operand" "")))]
7903 "TARGET_32BIT && TARGET_HARD_FLOAT"
7906 enum rtx_code code = GET_CODE (operands[1]);
7909 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7910 &XEXP (operands[1], 1)))
7913 code = GET_CODE (operands[1]);
7914 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7915 XEXP (operands[1], 1), NULL_RTX);
7916 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7920 (define_expand "movdfcc"
7921 [(set (match_operand:DF 0 "s_register_operand" "")
7922 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7923 (match_operand:DF 2 "s_register_operand" "")
7924 (match_operand:DF 3 "s_register_operand" "")))]
7925 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7928 enum rtx_code code = GET_CODE (operands[1]);
7931 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7932 &XEXP (operands[1], 1)))
7934 code = GET_CODE (operands[1]);
7935 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7936 XEXP (operands[1], 1), NULL_RTX);
7937 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7941 (define_insn "*cmov<mode>"
7942 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7943 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7944 [(match_operand 2 "cc_register" "") (const_int 0)])
7945 (match_operand:SDF 3 "s_register_operand"
7947 (match_operand:SDF 4 "s_register_operand"
7948 "<F_constraint>")))]
7949 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7952 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7959 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7964 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7970 [(set_attr "conds" "use")
7971 (set_attr "type" "fcsel")]
7974 (define_insn "*cmovhf"
7975 [(set (match_operand:HF 0 "s_register_operand" "=t")
7976 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7977 [(match_operand 2 "cc_register" "") (const_int 0)])
7978 (match_operand:HF 3 "s_register_operand" "t")
7979 (match_operand:HF 4 "s_register_operand" "t")))]
7980 "TARGET_VFP_FP16INST"
7983 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7990 return \"vsel%d1.f16\\t%0, %3, %4\";
7995 return \"vsel%D1.f16\\t%0, %4, %3\";
8001 [(set_attr "conds" "use")
8002 (set_attr "type" "fcsel")]
8005 (define_insn_and_split "*movsicc_insn"
8006 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8008 (match_operator 3 "arm_comparison_operator"
8009 [(match_operand 4 "cc_register" "") (const_int 0)])
8010 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8011 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8022 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8023 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8024 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8025 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8026 "&& reload_completed"
8029 enum rtx_code rev_code;
8033 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8035 gen_rtx_SET (operands[0], operands[1])));
8037 rev_code = GET_CODE (operands[3]);
8038 mode = GET_MODE (operands[4]);
8039 if (mode == CCFPmode || mode == CCFPEmode)
8040 rev_code = reverse_condition_maybe_unordered (rev_code);
8042 rev_code = reverse_condition (rev_code);
8044 rev_cond = gen_rtx_fmt_ee (rev_code,
8048 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8050 gen_rtx_SET (operands[0], operands[2])));
8053 [(set_attr "length" "4,4,4,4,8,8,8,8")
8054 (set_attr "conds" "use")
8055 (set_attr_alternative "type"
8056 [(if_then_else (match_operand 2 "const_int_operand" "")
8057 (const_string "mov_imm")
8058 (const_string "mov_reg"))
8059 (const_string "mvn_imm")
8060 (if_then_else (match_operand 1 "const_int_operand" "")
8061 (const_string "mov_imm")
8062 (const_string "mov_reg"))
8063 (const_string "mvn_imm")
8064 (const_string "multiple")
8065 (const_string "multiple")
8066 (const_string "multiple")
8067 (const_string "multiple")])]
8070 (define_insn "*movsfcc_soft_insn"
8071 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8072 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8073 [(match_operand 4 "cc_register" "") (const_int 0)])
8074 (match_operand:SF 1 "s_register_operand" "0,r")
8075 (match_operand:SF 2 "s_register_operand" "r,0")))]
8076 "TARGET_ARM && TARGET_SOFT_FLOAT"
8080 [(set_attr "conds" "use")
8081 (set_attr "type" "mov_reg")]
8085 ;; Jump and linkage insns
8087 (define_expand "jump"
8089 (label_ref (match_operand 0 "" "")))]
8094 (define_insn "*arm_jump"
8096 (label_ref (match_operand 0 "" "")))]
8100 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8102 arm_ccfsm_state += 2;
8105 return \"b%?\\t%l0\";
8108 [(set_attr "predicable" "yes")
8109 (set (attr "length")
8111 (and (match_test "TARGET_THUMB2")
8112 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8113 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8116 (set_attr "type" "branch")]
8119 (define_expand "call"
8120 [(parallel [(call (match_operand 0 "memory_operand" "")
8121 (match_operand 1 "general_operand" ""))
8122 (use (match_operand 2 "" ""))
8123 (clobber (reg:SI LR_REGNUM))])]
8128 tree addr = MEM_EXPR (operands[0]);
8130 /* In an untyped call, we can get NULL for operand 2. */
8131 if (operands[2] == NULL_RTX)
8132 operands[2] = const0_rtx;
8134 /* Decide if we should generate indirect calls by loading the
8135 32-bit address of the callee into a register before performing the
8137 callee = XEXP (operands[0], 0);
8138 if (GET_CODE (callee) == SYMBOL_REF
8139 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8141 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8143 if (detect_cmse_nonsecure_call (addr))
8145 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8147 emit_call_insn (pat);
8151 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8152 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8158 (define_expand "call_internal"
8159 [(parallel [(call (match_operand 0 "memory_operand" "")
8160 (match_operand 1 "general_operand" ""))
8161 (use (match_operand 2 "" ""))
8162 (clobber (reg:SI LR_REGNUM))])])
8164 (define_expand "nonsecure_call_internal"
8165 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8166 UNSPEC_NONSECURE_MEM)
8167 (match_operand 1 "general_operand" ""))
8168 (use (match_operand 2 "" ""))
8169 (clobber (reg:SI LR_REGNUM))])]
8174 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8175 gen_rtx_REG (SImode, R4_REGNUM),
8178 operands[0] = replace_equiv_address (operands[0], tmp);
8181 (define_insn "*call_reg_armv5"
8182 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8183 (match_operand 1 "" ""))
8184 (use (match_operand 2 "" ""))
8185 (clobber (reg:SI LR_REGNUM))]
8186 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8188 [(set_attr "type" "call")]
8191 (define_insn "*call_reg_arm"
8192 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8193 (match_operand 1 "" ""))
8194 (use (match_operand 2 "" ""))
8195 (clobber (reg:SI LR_REGNUM))]
8196 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8198 return output_call (operands);
8200 ;; length is worst case, normally it is only two
8201 [(set_attr "length" "12")
8202 (set_attr "type" "call")]
8206 (define_expand "call_value"
8207 [(parallel [(set (match_operand 0 "" "")
8208 (call (match_operand 1 "memory_operand" "")
8209 (match_operand 2 "general_operand" "")))
8210 (use (match_operand 3 "" ""))
8211 (clobber (reg:SI LR_REGNUM))])]
8216 tree addr = MEM_EXPR (operands[1]);
8218 /* In an untyped call, we can get NULL for operand 2. */
8219 if (operands[3] == 0)
8220 operands[3] = const0_rtx;
8222 /* Decide if we should generate indirect calls by loading the
8223 32-bit address of the callee into a register before performing the
8225 callee = XEXP (operands[1], 0);
8226 if (GET_CODE (callee) == SYMBOL_REF
8227 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8229 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8231 if (detect_cmse_nonsecure_call (addr))
8233 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8234 operands[2], operands[3]);
8235 emit_call_insn (pat);
8239 pat = gen_call_value_internal (operands[0], operands[1],
8240 operands[2], operands[3]);
8241 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8247 (define_expand "call_value_internal"
8248 [(parallel [(set (match_operand 0 "" "")
8249 (call (match_operand 1 "memory_operand" "")
8250 (match_operand 2 "general_operand" "")))
8251 (use (match_operand 3 "" ""))
8252 (clobber (reg:SI LR_REGNUM))])])
8254 (define_expand "nonsecure_call_value_internal"
8255 [(parallel [(set (match_operand 0 "" "")
8256 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8257 UNSPEC_NONSECURE_MEM)
8258 (match_operand 2 "general_operand" "")))
8259 (use (match_operand 3 "" ""))
8260 (clobber (reg:SI LR_REGNUM))])]
8265 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8266 gen_rtx_REG (SImode, R4_REGNUM),
8269 operands[1] = replace_equiv_address (operands[1], tmp);
8272 (define_insn "*call_value_reg_armv5"
8273 [(set (match_operand 0 "" "")
8274 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8275 (match_operand 2 "" "")))
8276 (use (match_operand 3 "" ""))
8277 (clobber (reg:SI LR_REGNUM))]
8278 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8280 [(set_attr "type" "call")]
8283 (define_insn "*call_value_reg_arm"
8284 [(set (match_operand 0 "" "")
8285 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8286 (match_operand 2 "" "")))
8287 (use (match_operand 3 "" ""))
8288 (clobber (reg:SI LR_REGNUM))]
8289 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8291 return output_call (&operands[1]);
8293 [(set_attr "length" "12")
8294 (set_attr "type" "call")]
8297 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8298 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8300 (define_insn "*call_symbol"
8301 [(call (mem:SI (match_operand:SI 0 "" ""))
8302 (match_operand 1 "" ""))
8303 (use (match_operand 2 "" ""))
8304 (clobber (reg:SI LR_REGNUM))]
8306 && !SIBLING_CALL_P (insn)
8307 && (GET_CODE (operands[0]) == SYMBOL_REF)
8308 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8311 rtx op = operands[0];
8313 /* Switch mode now when possible. */
8314 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8315 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8316 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8318 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8320 [(set_attr "type" "call")]
8323 (define_insn "*call_value_symbol"
8324 [(set (match_operand 0 "" "")
8325 (call (mem:SI (match_operand:SI 1 "" ""))
8326 (match_operand:SI 2 "" "")))
8327 (use (match_operand 3 "" ""))
8328 (clobber (reg:SI LR_REGNUM))]
8330 && !SIBLING_CALL_P (insn)
8331 && (GET_CODE (operands[1]) == SYMBOL_REF)
8332 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8335 rtx op = operands[1];
8337 /* Switch mode now when possible. */
8338 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8339 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8340 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8342 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8344 [(set_attr "type" "call")]
8347 (define_expand "sibcall_internal"
8348 [(parallel [(call (match_operand 0 "memory_operand" "")
8349 (match_operand 1 "general_operand" ""))
8351 (use (match_operand 2 "" ""))])])
8353 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8354 (define_expand "sibcall"
8355 [(parallel [(call (match_operand 0 "memory_operand" "")
8356 (match_operand 1 "general_operand" ""))
8358 (use (match_operand 2 "" ""))])]
8364 if ((!REG_P (XEXP (operands[0], 0))
8365 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8366 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8367 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8368 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8370 if (operands[2] == NULL_RTX)
8371 operands[2] = const0_rtx;
8373 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8374 arm_emit_call_insn (pat, operands[0], true);
8379 (define_expand "sibcall_value_internal"
8380 [(parallel [(set (match_operand 0 "" "")
8381 (call (match_operand 1 "memory_operand" "")
8382 (match_operand 2 "general_operand" "")))
8384 (use (match_operand 3 "" ""))])])
8386 (define_expand "sibcall_value"
8387 [(parallel [(set (match_operand 0 "" "")
8388 (call (match_operand 1 "memory_operand" "")
8389 (match_operand 2 "general_operand" "")))
8391 (use (match_operand 3 "" ""))])]
8397 if ((!REG_P (XEXP (operands[1], 0))
8398 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8399 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8400 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8401 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8403 if (operands[3] == NULL_RTX)
8404 operands[3] = const0_rtx;
8406 pat = gen_sibcall_value_internal (operands[0], operands[1],
8407 operands[2], operands[3]);
8408 arm_emit_call_insn (pat, operands[1], true);
8413 (define_insn "*sibcall_insn"
8414 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8415 (match_operand 1 "" ""))
8417 (use (match_operand 2 "" ""))]
8418 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8420 if (which_alternative == 1)
8421 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8424 if (arm_arch5t || arm_arch4t)
8425 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8427 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8430 [(set_attr "type" "call")]
8433 (define_insn "*sibcall_value_insn"
8434 [(set (match_operand 0 "" "")
8435 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8436 (match_operand 2 "" "")))
8438 (use (match_operand 3 "" ""))]
8439 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8441 if (which_alternative == 1)
8442 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8445 if (arm_arch5t || arm_arch4t)
8446 return \"bx%?\\t%1\";
8448 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8451 [(set_attr "type" "call")]
8454 (define_expand "<return_str>return"
8456 "(TARGET_ARM || (TARGET_THUMB2
8457 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8458 && !IS_STACKALIGN (arm_current_func_type ())))
8459 <return_cond_false>"
8464 thumb2_expand_return (<return_simple_p>);
8471 ;; Often the return insn will be the same as loading from memory, so set attr
8472 (define_insn "*arm_return"
8474 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8477 if (arm_ccfsm_state == 2)
8479 arm_ccfsm_state += 2;
8482 return output_return_instruction (const_true_rtx, true, false, false);
8484 [(set_attr "type" "load_4")
8485 (set_attr "length" "12")
8486 (set_attr "predicable" "yes")]
8489 (define_insn "*cond_<return_str>return"
8491 (if_then_else (match_operator 0 "arm_comparison_operator"
8492 [(match_operand 1 "cc_register" "") (const_int 0)])
8495 "TARGET_ARM <return_cond_true>"
8498 if (arm_ccfsm_state == 2)
8500 arm_ccfsm_state += 2;
8503 return output_return_instruction (operands[0], true, false,
8506 [(set_attr "conds" "use")
8507 (set_attr "length" "12")
8508 (set_attr "type" "load_4")]
8511 (define_insn "*cond_<return_str>return_inverted"
8513 (if_then_else (match_operator 0 "arm_comparison_operator"
8514 [(match_operand 1 "cc_register" "") (const_int 0)])
8517 "TARGET_ARM <return_cond_true>"
8520 if (arm_ccfsm_state == 2)
8522 arm_ccfsm_state += 2;
8525 return output_return_instruction (operands[0], true, true,
8528 [(set_attr "conds" "use")
8529 (set_attr "length" "12")
8530 (set_attr "type" "load_4")]
8533 (define_insn "*arm_simple_return"
8538 if (arm_ccfsm_state == 2)
8540 arm_ccfsm_state += 2;
8543 return output_return_instruction (const_true_rtx, true, false, true);
8545 [(set_attr "type" "branch")
8546 (set_attr "length" "4")
8547 (set_attr "predicable" "yes")]
8550 ;; Generate a sequence of instructions to determine if the processor is
8551 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8554 (define_expand "return_addr_mask"
8556 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8558 (set (match_operand:SI 0 "s_register_operand" "")
8559 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8561 (const_int 67108860)))] ; 0x03fffffc
8564 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8567 (define_insn "*check_arch2"
8568 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8569 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8572 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8573 [(set_attr "length" "8")
8574 (set_attr "conds" "set")
8575 (set_attr "type" "multiple")]
8578 ;; Call subroutine returning any type.
8580 (define_expand "untyped_call"
8581 [(parallel [(call (match_operand 0 "" "")
8583 (match_operand 1 "" "")
8584 (match_operand 2 "" "")])]
8589 rtx par = gen_rtx_PARALLEL (VOIDmode,
8590 rtvec_alloc (XVECLEN (operands[2], 0)));
8591 rtx addr = gen_reg_rtx (Pmode);
8595 emit_move_insn (addr, XEXP (operands[1], 0));
8596 mem = change_address (operands[1], BLKmode, addr);
8598 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8600 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8602 /* Default code only uses r0 as a return value, but we could
8603 be using anything up to 4 registers. */
8604 if (REGNO (src) == R0_REGNUM)
8605 src = gen_rtx_REG (TImode, R0_REGNUM);
8607 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8609 size += GET_MODE_SIZE (GET_MODE (src));
8612 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8616 for (i = 0; i < XVECLEN (par, 0); i++)
8618 HOST_WIDE_INT offset = 0;
8619 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8622 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8624 mem = change_address (mem, GET_MODE (reg), NULL);
8625 if (REGNO (reg) == R0_REGNUM)
8627 /* On thumb we have to use a write-back instruction. */
8628 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8629 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8630 size = TARGET_ARM ? 16 : 0;
8634 emit_move_insn (mem, reg);
8635 size = GET_MODE_SIZE (GET_MODE (reg));
8639 /* The optimizer does not know that the call sets the function value
8640 registers we stored in the result block. We avoid problems by
8641 claiming that all hard registers are used and clobbered at this
8643 emit_insn (gen_blockage ());
8649 (define_expand "untyped_return"
8650 [(match_operand:BLK 0 "memory_operand" "")
8651 (match_operand 1 "" "")]
8656 rtx addr = gen_reg_rtx (Pmode);
8660 emit_move_insn (addr, XEXP (operands[0], 0));
8661 mem = change_address (operands[0], BLKmode, addr);
8663 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8665 HOST_WIDE_INT offset = 0;
8666 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8669 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8671 mem = change_address (mem, GET_MODE (reg), NULL);
8672 if (REGNO (reg) == R0_REGNUM)
8674 /* On thumb we have to use a write-back instruction. */
8675 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8676 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8677 size = TARGET_ARM ? 16 : 0;
8681 emit_move_insn (reg, mem);
8682 size = GET_MODE_SIZE (GET_MODE (reg));
8686 /* Emit USE insns before the return. */
8687 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8688 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8690 /* Construct the return. */
8691 expand_naked_return ();
8697 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8698 ;; all of memory. This blocks insns from being moved across this point.
8700 (define_insn "blockage"
8701 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8704 [(set_attr "length" "0")
8705 (set_attr "type" "block")]
8708 ;; Since we hard code r0 here use the 'o' constraint to prevent
8709 ;; provoking undefined behaviour in the hardware with putting out
8710 ;; auto-increment operations with potentially r0 as the base register.
8711 (define_insn "probe_stack"
8712 [(set (match_operand:SI 0 "memory_operand" "=o")
8713 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8716 [(set_attr "type" "store_4")
8717 (set_attr "predicable" "yes")]
8720 (define_insn "probe_stack_range"
8721 [(set (match_operand:SI 0 "register_operand" "=r")
8722 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8723 (match_operand:SI 2 "register_operand" "r")]
8724 VUNSPEC_PROBE_STACK_RANGE))]
8727 return output_probe_stack_range (operands[0], operands[2]);
8729 [(set_attr "type" "multiple")
8730 (set_attr "conds" "clob")]
8733 ;; Named patterns for stack smashing protection.
8734 (define_expand "stack_protect_combined_set"
8736 [(set (match_operand:SI 0 "memory_operand" "")
8737 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8739 (clobber (match_scratch:SI 2 ""))
8740 (clobber (match_scratch:SI 3 ""))])]
8745 ;; Use a separate insn from the above expand to be able to have the mem outside
8746 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8747 ;; try to reload the guard since we need to control how PIC access is done in
8748 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8749 ;; legitimize_pic_address ()).
8750 (define_insn_and_split "*stack_protect_combined_set_insn"
8751 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8752 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8754 (clobber (match_scratch:SI 2 "=&l,&r"))
8755 (clobber (match_scratch:SI 3 "=&l,&r"))]
8759 [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))]
8761 (clobber (match_dup 2))])]
8766 /* Forces recomputing of GOT base now. */
8767 legitimize_pic_address (operands[1], SImode, operands[2], operands[3],
8768 true /*compute_now*/);
8772 if (address_operand (operands[1], SImode))
8773 operands[2] = operands[1];
8776 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8777 emit_move_insn (operands[2], mem);
8781 [(set_attr "arch" "t1,32")]
8784 (define_insn "*stack_protect_set_insn"
8785 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8786 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))]
8788 (clobber (match_dup 1))]
8791 ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1,#0
8792 ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1,#0"
8793 [(set_attr "length" "8,12")
8794 (set_attr "conds" "clob,nocond")
8795 (set_attr "type" "multiple")
8796 (set_attr "arch" "t1,32")]
8799 (define_expand "stack_protect_combined_test"
8803 (eq (match_operand:SI 0 "memory_operand" "")
8804 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8806 (label_ref (match_operand 2))
8808 (clobber (match_scratch:SI 3 ""))
8809 (clobber (match_scratch:SI 4 ""))
8810 (clobber (reg:CC CC_REGNUM))])]
8815 ;; Use a separate insn from the above expand to be able to have the mem outside
8816 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8817 ;; try to reload the guard since we need to control how PIC access is done in
8818 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8819 ;; legitimize_pic_address ()).
8820 (define_insn_and_split "*stack_protect_combined_test_insn"
8823 (eq (match_operand:SI 0 "memory_operand" "m,m")
8824 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8826 (label_ref (match_operand 2))
8828 (clobber (match_scratch:SI 3 "=&l,&r"))
8829 (clobber (match_scratch:SI 4 "=&l,&r"))
8830 (clobber (reg:CC CC_REGNUM))]
8840 /* Forces recomputing of GOT base now. */
8841 legitimize_pic_address (operands[1], SImode, operands[3], operands[4],
8842 true /*compute_now*/);
8846 if (address_operand (operands[1], SImode))
8847 operands[3] = operands[1];
8850 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8851 emit_move_insn (operands[3], mem);
8856 emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0],
8858 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
8859 eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx);
8860 emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg));
8864 emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0],
8866 eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
8867 emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx,
8872 [(set_attr "arch" "t1,32")]
8875 (define_insn "arm_stack_protect_test_insn"
8876 [(set (reg:CC_Z CC_REGNUM)
8877 (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m")
8878 (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))]
8881 (clobber (match_operand:SI 0 "register_operand" "=&l,&r"))
8882 (clobber (match_dup 2))]
8884 "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0"
8885 [(set_attr "length" "8,12")
8886 (set_attr "conds" "set")
8887 (set_attr "type" "multiple")
8888 (set_attr "arch" "t,32")]
8891 (define_expand "casesi"
8892 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8893 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8894 (match_operand:SI 2 "const_int_operand" "") ; total range
8895 (match_operand:SI 3 "" "") ; table label
8896 (match_operand:SI 4 "" "")] ; Out of range label
8897 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8900 enum insn_code code;
8901 if (operands[1] != const0_rtx)
8903 rtx reg = gen_reg_rtx (SImode);
8905 emit_insn (gen_addsi3 (reg, operands[0],
8906 gen_int_mode (-INTVAL (operands[1]),
8912 code = CODE_FOR_arm_casesi_internal;
8913 else if (TARGET_THUMB1)
8914 code = CODE_FOR_thumb1_casesi_internal_pic;
8916 code = CODE_FOR_thumb2_casesi_internal_pic;
8918 code = CODE_FOR_thumb2_casesi_internal;
8920 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8921 operands[2] = force_reg (SImode, operands[2]);
8923 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8924 operands[3], operands[4]));
8929 ;; The USE in this pattern is needed to tell flow analysis that this is
8930 ;; a CASESI insn. It has no other purpose.
8931 (define_expand "arm_casesi_internal"
8932 [(parallel [(set (pc)
8934 (leu (match_operand:SI 0 "s_register_operand")
8935 (match_operand:SI 1 "arm_rhs_operand"))
8937 (label_ref:SI (match_operand 3 ""))))
8938 (clobber (reg:CC CC_REGNUM))
8939 (use (label_ref:SI (match_operand 2 "")))])]
8942 operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
8943 operands[4] = gen_rtx_PLUS (SImode, operands[4],
8944 gen_rtx_LABEL_REF (SImode, operands[2]));
8945 operands[4] = gen_rtx_MEM (SImode, operands[4]);
8946 MEM_READONLY_P (operands[4]) = 1;
8947 MEM_NOTRAP_P (operands[4]) = 1;
8950 (define_insn "*arm_casesi_internal"
8951 [(parallel [(set (pc)
8953 (leu (match_operand:SI 0 "s_register_operand" "r")
8954 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8955 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8956 (label_ref:SI (match_operand 2 "" ""))))
8957 (label_ref:SI (match_operand 3 "" ""))))
8958 (clobber (reg:CC CC_REGNUM))
8959 (use (label_ref:SI (match_dup 2)))])]
8963 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8964 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8966 [(set_attr "conds" "clob")
8967 (set_attr "length" "12")
8968 (set_attr "type" "multiple")]
8971 (define_expand "indirect_jump"
8973 (match_operand:SI 0 "s_register_operand" ""))]
8976 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8977 address and use bx. */
8981 tmp = gen_reg_rtx (SImode);
8982 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8988 ;; NB Never uses BX.
8989 (define_insn "*arm_indirect_jump"
8991 (match_operand:SI 0 "s_register_operand" "r"))]
8993 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8994 [(set_attr "predicable" "yes")
8995 (set_attr "type" "branch")]
8998 (define_insn "*load_indirect_jump"
9000 (match_operand:SI 0 "memory_operand" "m"))]
9002 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
9003 [(set_attr "type" "load_4")
9004 (set_attr "pool_range" "4096")
9005 (set_attr "neg_pool_range" "4084")
9006 (set_attr "predicable" "yes")]
9016 [(set (attr "length")
9017 (if_then_else (eq_attr "is_thumb" "yes")
9020 (set_attr "type" "mov_reg")]
9024 [(trap_if (const_int 1) (const_int 0))]
9028 return \".inst\\t0xe7f000f0\";
9030 return \".inst\\t0xdeff\";
9032 [(set (attr "length")
9033 (if_then_else (eq_attr "is_thumb" "yes")
9036 (set_attr "type" "trap")
9037 (set_attr "conds" "unconditional")]
9041 ;; Patterns to allow combination of arithmetic, cond code and shifts
9043 (define_insn "*<arith_shift_insn>_multsi"
9044 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9046 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
9047 (match_operand:SI 3 "power_of_two_operand" ""))
9048 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
9050 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
9051 [(set_attr "predicable" "yes")
9052 (set_attr "shift" "2")
9053 (set_attr "arch" "a,t2")
9054 (set_attr "type" "alu_shift_imm")])
9056 (define_insn "*<arith_shift_insn>_shiftsi"
9057 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9059 (match_operator:SI 2 "shift_nomul_operator"
9060 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9061 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
9062 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
9063 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
9064 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
9065 [(set_attr "predicable" "yes")
9066 (set_attr "shift" "3")
9067 (set_attr "arch" "a,t2,a")
9068 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9071 [(set (match_operand:SI 0 "s_register_operand" "")
9072 (match_operator:SI 1 "shiftable_operator"
9073 [(match_operator:SI 2 "shiftable_operator"
9074 [(match_operator:SI 3 "shift_operator"
9075 [(match_operand:SI 4 "s_register_operand" "")
9076 (match_operand:SI 5 "reg_or_int_operand" "")])
9077 (match_operand:SI 6 "s_register_operand" "")])
9078 (match_operand:SI 7 "arm_rhs_operand" "")]))
9079 (clobber (match_operand:SI 8 "s_register_operand" ""))]
9082 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9085 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
9088 (define_insn "*arith_shiftsi_compare0"
9089 [(set (reg:CC_NOOV CC_REGNUM)
9091 (match_operator:SI 1 "shiftable_operator"
9092 [(match_operator:SI 3 "shift_operator"
9093 [(match_operand:SI 4 "s_register_operand" "r,r")
9094 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9095 (match_operand:SI 2 "s_register_operand" "r,r")])
9097 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9098 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9101 "%i1s%?\\t%0, %2, %4%S3"
9102 [(set_attr "conds" "set")
9103 (set_attr "shift" "4")
9104 (set_attr "arch" "32,a")
9105 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9107 (define_insn "*arith_shiftsi_compare0_scratch"
9108 [(set (reg:CC_NOOV CC_REGNUM)
9110 (match_operator:SI 1 "shiftable_operator"
9111 [(match_operator:SI 3 "shift_operator"
9112 [(match_operand:SI 4 "s_register_operand" "r,r")
9113 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9114 (match_operand:SI 2 "s_register_operand" "r,r")])
9116 (clobber (match_scratch:SI 0 "=r,r"))]
9118 "%i1s%?\\t%0, %2, %4%S3"
9119 [(set_attr "conds" "set")
9120 (set_attr "shift" "4")
9121 (set_attr "arch" "32,a")
9122 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9124 (define_insn "*sub_shiftsi"
9125 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9126 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9127 (match_operator:SI 2 "shift_operator"
9128 [(match_operand:SI 3 "s_register_operand" "r,r")
9129 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
9131 "sub%?\\t%0, %1, %3%S2"
9132 [(set_attr "predicable" "yes")
9133 (set_attr "predicable_short_it" "no")
9134 (set_attr "shift" "3")
9135 (set_attr "arch" "32,a")
9136 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9138 (define_insn "*sub_shiftsi_compare0"
9139 [(set (reg:CC_NOOV CC_REGNUM)
9141 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9142 (match_operator:SI 2 "shift_operator"
9143 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9144 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9146 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9147 (minus:SI (match_dup 1)
9148 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
9150 "subs%?\\t%0, %1, %3%S2"
9151 [(set_attr "conds" "set")
9152 (set_attr "shift" "3")
9153 (set_attr "arch" "32,a,a")
9154 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9156 (define_insn "*sub_shiftsi_compare0_scratch"
9157 [(set (reg:CC_NOOV CC_REGNUM)
9159 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9160 (match_operator:SI 2 "shift_operator"
9161 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9162 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9164 (clobber (match_scratch:SI 0 "=r,r,r"))]
9166 "subs%?\\t%0, %1, %3%S2"
9167 [(set_attr "conds" "set")
9168 (set_attr "shift" "3")
9169 (set_attr "arch" "32,a,a")
9170 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9173 (define_insn_and_split "*and_scc"
9174 [(set (match_operand:SI 0 "s_register_operand" "=r")
9175 (and:SI (match_operator:SI 1 "arm_comparison_operator"
9176 [(match_operand 2 "cc_register" "") (const_int 0)])
9177 (match_operand:SI 3 "s_register_operand" "r")))]
9179 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
9180 "&& reload_completed"
9181 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
9182 (cond_exec (match_dup 4) (set (match_dup 0)
9183 (and:SI (match_dup 3) (const_int 1))))]
9185 machine_mode mode = GET_MODE (operands[2]);
9186 enum rtx_code rc = GET_CODE (operands[1]);
9188 /* Note that operands[4] is the same as operands[1],
9189 but with VOIDmode as the result. */
9190 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9191 if (mode == CCFPmode || mode == CCFPEmode)
9192 rc = reverse_condition_maybe_unordered (rc);
9194 rc = reverse_condition (rc);
9195 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9197 [(set_attr "conds" "use")
9198 (set_attr "type" "multiple")
9199 (set_attr "length" "8")]
9202 (define_insn_and_split "*ior_scc"
9203 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9204 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
9205 [(match_operand 2 "cc_register" "") (const_int 0)])
9206 (match_operand:SI 3 "s_register_operand" "0,?r")))]
9211 "&& reload_completed
9212 && REGNO (operands [0]) != REGNO (operands[3])"
9213 ;; && which_alternative == 1
9214 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
9215 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
9216 (cond_exec (match_dup 4) (set (match_dup 0)
9217 (ior:SI (match_dup 3) (const_int 1))))]
9219 machine_mode mode = GET_MODE (operands[2]);
9220 enum rtx_code rc = GET_CODE (operands[1]);
9222 /* Note that operands[4] is the same as operands[1],
9223 but with VOIDmode as the result. */
9224 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9225 if (mode == CCFPmode || mode == CCFPEmode)
9226 rc = reverse_condition_maybe_unordered (rc);
9228 rc = reverse_condition (rc);
9229 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9231 [(set_attr "conds" "use")
9232 (set_attr "length" "4,8")
9233 (set_attr "type" "logic_imm,multiple")]
9236 ; A series of splitters for the compare_scc pattern below. Note that
9237 ; order is important.
9239 [(set (match_operand:SI 0 "s_register_operand" "")
9240 (lt:SI (match_operand:SI 1 "s_register_operand" "")
9242 (clobber (reg:CC CC_REGNUM))]
9243 "TARGET_32BIT && reload_completed"
9244 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9247 [(set (match_operand:SI 0 "s_register_operand" "")
9248 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9250 (clobber (reg:CC CC_REGNUM))]
9251 "TARGET_32BIT && reload_completed"
9252 [(set (match_dup 0) (not:SI (match_dup 1)))
9253 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9256 [(set (match_operand:SI 0 "s_register_operand" "")
9257 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9259 (clobber (reg:CC CC_REGNUM))]
9260 "arm_arch5t && TARGET_32BIT"
9261 [(set (match_dup 0) (clz:SI (match_dup 1)))
9262 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9266 [(set (match_operand:SI 0 "s_register_operand" "")
9267 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9269 (clobber (reg:CC CC_REGNUM))]
9270 "TARGET_32BIT && reload_completed"
9272 [(set (reg:CC CC_REGNUM)
9273 (compare:CC (const_int 1) (match_dup 1)))
9275 (minus:SI (const_int 1) (match_dup 1)))])
9276 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9277 (set (match_dup 0) (const_int 0)))])
9280 [(set (match_operand:SI 0 "s_register_operand" "")
9281 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9282 (match_operand:SI 2 "const_int_operand" "")))
9283 (clobber (reg:CC CC_REGNUM))]
9284 "TARGET_32BIT && reload_completed"
9286 [(set (reg:CC CC_REGNUM)
9287 (compare:CC (match_dup 1) (match_dup 2)))
9288 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9289 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9290 (set (match_dup 0) (const_int 1)))]
9292 operands[3] = gen_int_mode (-INTVAL (operands[2]), SImode);
9296 [(set (match_operand:SI 0 "s_register_operand" "")
9297 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9298 (match_operand:SI 2 "arm_add_operand" "")))
9299 (clobber (reg:CC CC_REGNUM))]
9300 "TARGET_32BIT && reload_completed"
9302 [(set (reg:CC_NOOV CC_REGNUM)
9303 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9305 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9306 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9307 (set (match_dup 0) (const_int 1)))])
9309 (define_insn_and_split "*compare_scc"
9310 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9311 (match_operator:SI 1 "arm_comparison_operator"
9312 [(match_operand:SI 2 "s_register_operand" "r,r")
9313 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9314 (clobber (reg:CC CC_REGNUM))]
9317 "&& reload_completed"
9318 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9319 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9320 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9323 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9324 operands[2], operands[3]);
9325 enum rtx_code rc = GET_CODE (operands[1]);
9327 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9329 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9330 if (mode == CCFPmode || mode == CCFPEmode)
9331 rc = reverse_condition_maybe_unordered (rc);
9333 rc = reverse_condition (rc);
9334 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9336 [(set_attr "type" "multiple")]
9339 ;; Attempt to improve the sequence generated by the compare_scc splitters
9340 ;; not to use conditional execution.
9342 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9346 [(set (reg:CC CC_REGNUM)
9347 (compare:CC (match_operand:SI 1 "register_operand" "")
9349 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9350 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9351 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9352 (set (match_dup 0) (const_int 1)))]
9353 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9354 [(set (match_dup 0) (clz:SI (match_dup 1)))
9355 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9358 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9362 [(set (reg:CC CC_REGNUM)
9363 (compare:CC (match_operand:SI 1 "register_operand" "")
9365 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9366 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9367 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9368 (set (match_dup 0) (const_int 1)))
9369 (match_scratch:SI 2 "r")]
9370 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9372 [(set (reg:CC CC_REGNUM)
9373 (compare:CC (const_int 0) (match_dup 1)))
9374 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9376 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9377 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9380 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9381 ;; sub Rd, Reg1, reg2
9385 [(set (reg:CC CC_REGNUM)
9386 (compare:CC (match_operand:SI 1 "register_operand" "")
9387 (match_operand:SI 2 "arm_rhs_operand" "")))
9388 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9389 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9390 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9391 (set (match_dup 0) (const_int 1)))]
9392 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9393 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9394 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9395 (set (match_dup 0) (clz:SI (match_dup 0)))
9396 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9400 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9401 ;; sub T1, Reg1, reg2
9405 [(set (reg:CC CC_REGNUM)
9406 (compare:CC (match_operand:SI 1 "register_operand" "")
9407 (match_operand:SI 2 "arm_rhs_operand" "")))
9408 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9409 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9410 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9411 (set (match_dup 0) (const_int 1)))
9412 (match_scratch:SI 3 "r")]
9413 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9414 [(set (match_dup 3) (match_dup 4))
9416 [(set (reg:CC CC_REGNUM)
9417 (compare:CC (const_int 0) (match_dup 3)))
9418 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9420 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9421 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9423 if (CONST_INT_P (operands[2]))
9424 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9426 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9429 (define_insn "*cond_move"
9430 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9431 (if_then_else:SI (match_operator 3 "equality_operator"
9432 [(match_operator 4 "arm_comparison_operator"
9433 [(match_operand 5 "cc_register" "") (const_int 0)])
9435 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9436 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9439 if (GET_CODE (operands[3]) == NE)
9441 if (which_alternative != 1)
9442 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9443 if (which_alternative != 0)
9444 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9447 if (which_alternative != 0)
9448 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9449 if (which_alternative != 1)
9450 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9453 [(set_attr "conds" "use")
9454 (set_attr_alternative "type"
9455 [(if_then_else (match_operand 2 "const_int_operand" "")
9456 (const_string "mov_imm")
9457 (const_string "mov_reg"))
9458 (if_then_else (match_operand 1 "const_int_operand" "")
9459 (const_string "mov_imm")
9460 (const_string "mov_reg"))
9461 (const_string "multiple")])
9462 (set_attr "length" "4,4,8")]
9465 (define_insn "*cond_arith"
9466 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9467 (match_operator:SI 5 "shiftable_operator"
9468 [(match_operator:SI 4 "arm_comparison_operator"
9469 [(match_operand:SI 2 "s_register_operand" "r,r")
9470 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9471 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9472 (clobber (reg:CC CC_REGNUM))]
9475 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9476 return \"%i5\\t%0, %1, %2, lsr #31\";
9478 output_asm_insn (\"cmp\\t%2, %3\", operands);
9479 if (GET_CODE (operands[5]) == AND)
9480 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9481 else if (GET_CODE (operands[5]) == MINUS)
9482 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9483 else if (which_alternative != 0)
9484 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9485 return \"%i5%d4\\t%0, %1, #1\";
9487 [(set_attr "conds" "clob")
9488 (set_attr "length" "12")
9489 (set_attr "type" "multiple")]
9492 (define_insn "*cond_sub"
9493 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9494 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9495 (match_operator:SI 4 "arm_comparison_operator"
9496 [(match_operand:SI 2 "s_register_operand" "r,r")
9497 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9498 (clobber (reg:CC CC_REGNUM))]
9501 output_asm_insn (\"cmp\\t%2, %3\", operands);
9502 if (which_alternative != 0)
9503 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9504 return \"sub%d4\\t%0, %1, #1\";
9506 [(set_attr "conds" "clob")
9507 (set_attr "length" "8,12")
9508 (set_attr "type" "multiple")]
9511 (define_insn "*cmp_ite0"
9512 [(set (match_operand 6 "dominant_cc_register" "")
9515 (match_operator 4 "arm_comparison_operator"
9516 [(match_operand:SI 0 "s_register_operand"
9517 "l,l,l,r,r,r,r,r,r")
9518 (match_operand:SI 1 "arm_add_operand"
9519 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9520 (match_operator:SI 5 "arm_comparison_operator"
9521 [(match_operand:SI 2 "s_register_operand"
9522 "l,r,r,l,l,r,r,r,r")
9523 (match_operand:SI 3 "arm_add_operand"
9524 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9530 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9532 {\"cmp%d5\\t%0, %1\",
9533 \"cmp%d4\\t%2, %3\"},
9534 {\"cmn%d5\\t%0, #%n1\",
9535 \"cmp%d4\\t%2, %3\"},
9536 {\"cmp%d5\\t%0, %1\",
9537 \"cmn%d4\\t%2, #%n3\"},
9538 {\"cmn%d5\\t%0, #%n1\",
9539 \"cmn%d4\\t%2, #%n3\"}
9541 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9546 \"cmn\\t%0, #%n1\"},
9547 {\"cmn\\t%2, #%n3\",
9549 {\"cmn\\t%2, #%n3\",
9552 static const char * const ite[2] =
9557 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9558 CMP_CMP, CMN_CMP, CMP_CMP,
9559 CMN_CMP, CMP_CMN, CMN_CMN};
9561 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9563 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9564 if (TARGET_THUMB2) {
9565 output_asm_insn (ite[swap], operands);
9567 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9570 [(set_attr "conds" "set")
9571 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9572 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9573 (set_attr "type" "multiple")
9574 (set_attr_alternative "length"
9580 (if_then_else (eq_attr "is_thumb" "no")
9583 (if_then_else (eq_attr "is_thumb" "no")
9586 (if_then_else (eq_attr "is_thumb" "no")
9589 (if_then_else (eq_attr "is_thumb" "no")
9594 (define_insn "*cmp_ite1"
9595 [(set (match_operand 6 "dominant_cc_register" "")
9598 (match_operator 4 "arm_comparison_operator"
9599 [(match_operand:SI 0 "s_register_operand"
9600 "l,l,l,r,r,r,r,r,r")
9601 (match_operand:SI 1 "arm_add_operand"
9602 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9603 (match_operator:SI 5 "arm_comparison_operator"
9604 [(match_operand:SI 2 "s_register_operand"
9605 "l,r,r,l,l,r,r,r,r")
9606 (match_operand:SI 3 "arm_add_operand"
9607 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9613 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9617 {\"cmn\\t%0, #%n1\",
9620 \"cmn\\t%2, #%n3\"},
9621 {\"cmn\\t%0, #%n1\",
9624 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9626 {\"cmp%d4\\t%2, %3\",
9627 \"cmp%D5\\t%0, %1\"},
9628 {\"cmp%d4\\t%2, %3\",
9629 \"cmn%D5\\t%0, #%n1\"},
9630 {\"cmn%d4\\t%2, #%n3\",
9631 \"cmp%D5\\t%0, %1\"},
9632 {\"cmn%d4\\t%2, #%n3\",
9633 \"cmn%D5\\t%0, #%n1\"}
9635 static const char * const ite[2] =
9640 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9641 CMP_CMP, CMN_CMP, CMP_CMP,
9642 CMN_CMP, CMP_CMN, CMN_CMN};
9644 comparison_dominates_p (GET_CODE (operands[5]),
9645 reverse_condition (GET_CODE (operands[4])));
9647 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9648 if (TARGET_THUMB2) {
9649 output_asm_insn (ite[swap], operands);
9651 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9654 [(set_attr "conds" "set")
9655 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9656 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9657 (set_attr_alternative "length"
9663 (if_then_else (eq_attr "is_thumb" "no")
9666 (if_then_else (eq_attr "is_thumb" "no")
9669 (if_then_else (eq_attr "is_thumb" "no")
9672 (if_then_else (eq_attr "is_thumb" "no")
9675 (set_attr "type" "multiple")]
9678 (define_insn "*cmp_and"
9679 [(set (match_operand 6 "dominant_cc_register" "")
9682 (match_operator 4 "arm_comparison_operator"
9683 [(match_operand:SI 0 "s_register_operand"
9684 "l,l,l,r,r,r,r,r,r")
9685 (match_operand:SI 1 "arm_add_operand"
9686 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9687 (match_operator:SI 5 "arm_comparison_operator"
9688 [(match_operand:SI 2 "s_register_operand"
9689 "l,r,r,l,l,r,r,r,r")
9690 (match_operand:SI 3 "arm_add_operand"
9691 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9696 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9698 {\"cmp%d5\\t%0, %1\",
9699 \"cmp%d4\\t%2, %3\"},
9700 {\"cmn%d5\\t%0, #%n1\",
9701 \"cmp%d4\\t%2, %3\"},
9702 {\"cmp%d5\\t%0, %1\",
9703 \"cmn%d4\\t%2, #%n3\"},
9704 {\"cmn%d5\\t%0, #%n1\",
9705 \"cmn%d4\\t%2, #%n3\"}
9707 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9712 \"cmn\\t%0, #%n1\"},
9713 {\"cmn\\t%2, #%n3\",
9715 {\"cmn\\t%2, #%n3\",
9718 static const char *const ite[2] =
9723 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9724 CMP_CMP, CMN_CMP, CMP_CMP,
9725 CMN_CMP, CMP_CMN, CMN_CMN};
9727 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9729 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9730 if (TARGET_THUMB2) {
9731 output_asm_insn (ite[swap], operands);
9733 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9736 [(set_attr "conds" "set")
9737 (set_attr "predicable" "no")
9738 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9739 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9740 (set_attr_alternative "length"
9746 (if_then_else (eq_attr "is_thumb" "no")
9749 (if_then_else (eq_attr "is_thumb" "no")
9752 (if_then_else (eq_attr "is_thumb" "no")
9755 (if_then_else (eq_attr "is_thumb" "no")
9758 (set_attr "type" "multiple")]
9761 (define_insn "*cmp_ior"
9762 [(set (match_operand 6 "dominant_cc_register" "")
9765 (match_operator 4 "arm_comparison_operator"
9766 [(match_operand:SI 0 "s_register_operand"
9767 "l,l,l,r,r,r,r,r,r")
9768 (match_operand:SI 1 "arm_add_operand"
9769 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9770 (match_operator:SI 5 "arm_comparison_operator"
9771 [(match_operand:SI 2 "s_register_operand"
9772 "l,r,r,l,l,r,r,r,r")
9773 (match_operand:SI 3 "arm_add_operand"
9774 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9779 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9783 {\"cmn\\t%0, #%n1\",
9786 \"cmn\\t%2, #%n3\"},
9787 {\"cmn\\t%0, #%n1\",
9790 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9792 {\"cmp%D4\\t%2, %3\",
9793 \"cmp%D5\\t%0, %1\"},
9794 {\"cmp%D4\\t%2, %3\",
9795 \"cmn%D5\\t%0, #%n1\"},
9796 {\"cmn%D4\\t%2, #%n3\",
9797 \"cmp%D5\\t%0, %1\"},
9798 {\"cmn%D4\\t%2, #%n3\",
9799 \"cmn%D5\\t%0, #%n1\"}
9801 static const char *const ite[2] =
9806 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9807 CMP_CMP, CMN_CMP, CMP_CMP,
9808 CMN_CMP, CMP_CMN, CMN_CMN};
9810 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9812 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9813 if (TARGET_THUMB2) {
9814 output_asm_insn (ite[swap], operands);
9816 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9820 [(set_attr "conds" "set")
9821 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9822 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9823 (set_attr_alternative "length"
9829 (if_then_else (eq_attr "is_thumb" "no")
9832 (if_then_else (eq_attr "is_thumb" "no")
9835 (if_then_else (eq_attr "is_thumb" "no")
9838 (if_then_else (eq_attr "is_thumb" "no")
9841 (set_attr "type" "multiple")]
9844 (define_insn_and_split "*ior_scc_scc"
9845 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9846 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9847 [(match_operand:SI 1 "s_register_operand" "l,r")
9848 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9849 (match_operator:SI 6 "arm_comparison_operator"
9850 [(match_operand:SI 4 "s_register_operand" "l,r")
9851 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9852 (clobber (reg:CC CC_REGNUM))]
9854 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9857 "TARGET_32BIT && reload_completed"
9861 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9862 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9864 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9866 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9869 [(set_attr "conds" "clob")
9870 (set_attr "enabled_for_short_it" "yes,no")
9871 (set_attr "length" "16")
9872 (set_attr "type" "multiple")]
9875 ; If the above pattern is followed by a CMP insn, then the compare is
9876 ; redundant, since we can rework the conditional instruction that follows.
9877 (define_insn_and_split "*ior_scc_scc_cmp"
9878 [(set (match_operand 0 "dominant_cc_register" "")
9879 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9880 [(match_operand:SI 1 "s_register_operand" "l,r")
9881 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9882 (match_operator:SI 6 "arm_comparison_operator"
9883 [(match_operand:SI 4 "s_register_operand" "l,r")
9884 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9886 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9887 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9888 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9891 "TARGET_32BIT && reload_completed"
9895 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9896 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9898 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9900 [(set_attr "conds" "set")
9901 (set_attr "enabled_for_short_it" "yes,no")
9902 (set_attr "length" "16")
9903 (set_attr "type" "multiple")]
9906 (define_insn_and_split "*and_scc_scc"
9907 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9908 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9909 [(match_operand:SI 1 "s_register_operand" "l,r")
9910 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9911 (match_operator:SI 6 "arm_comparison_operator"
9912 [(match_operand:SI 4 "s_register_operand" "l,r")
9913 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9914 (clobber (reg:CC CC_REGNUM))]
9916 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9919 "TARGET_32BIT && reload_completed
9920 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9925 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9926 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9928 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9930 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9933 [(set_attr "conds" "clob")
9934 (set_attr "enabled_for_short_it" "yes,no")
9935 (set_attr "length" "16")
9936 (set_attr "type" "multiple")]
9939 ; If the above pattern is followed by a CMP insn, then the compare is
9940 ; redundant, since we can rework the conditional instruction that follows.
9941 (define_insn_and_split "*and_scc_scc_cmp"
9942 [(set (match_operand 0 "dominant_cc_register" "")
9943 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9944 [(match_operand:SI 1 "s_register_operand" "l,r")
9945 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9946 (match_operator:SI 6 "arm_comparison_operator"
9947 [(match_operand:SI 4 "s_register_operand" "l,r")
9948 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9950 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9951 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9952 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9955 "TARGET_32BIT && reload_completed"
9959 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9960 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9962 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9964 [(set_attr "conds" "set")
9965 (set_attr "enabled_for_short_it" "yes,no")
9966 (set_attr "length" "16")
9967 (set_attr "type" "multiple")]
9970 ;; If there is no dominance in the comparison, then we can still save an
9971 ;; instruction in the AND case, since we can know that the second compare
9972 ;; need only zero the value if false (if true, then the value is already
9974 (define_insn_and_split "*and_scc_scc_nodom"
9975 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9976 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9977 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9978 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9979 (match_operator:SI 6 "arm_comparison_operator"
9980 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9981 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9982 (clobber (reg:CC CC_REGNUM))]
9984 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9987 "TARGET_32BIT && reload_completed"
9988 [(parallel [(set (match_dup 0)
9989 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9990 (clobber (reg:CC CC_REGNUM))])
9991 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9993 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9996 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9997 operands[4], operands[5]),
9999 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
10001 [(set_attr "conds" "clob")
10002 (set_attr "length" "20")
10003 (set_attr "type" "multiple")]
10007 [(set (reg:CC_NOOV CC_REGNUM)
10008 (compare:CC_NOOV (ior:SI
10009 (and:SI (match_operand:SI 0 "s_register_operand" "")
10011 (match_operator:SI 1 "arm_comparison_operator"
10012 [(match_operand:SI 2 "s_register_operand" "")
10013 (match_operand:SI 3 "arm_add_operand" "")]))
10015 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10017 [(set (match_dup 4)
10018 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10020 (set (reg:CC_NOOV CC_REGNUM)
10021 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10026 [(set (reg:CC_NOOV CC_REGNUM)
10027 (compare:CC_NOOV (ior:SI
10028 (match_operator:SI 1 "arm_comparison_operator"
10029 [(match_operand:SI 2 "s_register_operand" "")
10030 (match_operand:SI 3 "arm_add_operand" "")])
10031 (and:SI (match_operand:SI 0 "s_register_operand" "")
10034 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10036 [(set (match_dup 4)
10037 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10039 (set (reg:CC_NOOV CC_REGNUM)
10040 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10043 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10045 (define_insn_and_split "*negscc"
10046 [(set (match_operand:SI 0 "s_register_operand" "=r")
10047 (neg:SI (match_operator 3 "arm_comparison_operator"
10048 [(match_operand:SI 1 "s_register_operand" "r")
10049 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10050 (clobber (reg:CC CC_REGNUM))]
10053 "&& reload_completed"
10056 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10058 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10060 /* Emit mov\\t%0, %1, asr #31 */
10061 emit_insn (gen_rtx_SET (operands[0],
10062 gen_rtx_ASHIFTRT (SImode,
10067 else if (GET_CODE (operands[3]) == NE)
10069 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10070 if (CONST_INT_P (operands[2]))
10071 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10072 gen_int_mode (-INTVAL (operands[2]),
10075 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10077 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10078 gen_rtx_NE (SImode,
10081 gen_rtx_SET (operands[0],
10087 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10088 emit_insn (gen_rtx_SET (cc_reg,
10089 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10090 enum rtx_code rc = GET_CODE (operands[3]);
10092 rc = reverse_condition (rc);
10093 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10094 gen_rtx_fmt_ee (rc,
10098 gen_rtx_SET (operands[0], const0_rtx)));
10099 rc = GET_CODE (operands[3]);
10100 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10101 gen_rtx_fmt_ee (rc,
10105 gen_rtx_SET (operands[0],
10111 [(set_attr "conds" "clob")
10112 (set_attr "length" "12")
10113 (set_attr "type" "multiple")]
10116 (define_insn_and_split "movcond_addsi"
10117 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
10119 (match_operator 5 "comparison_operator"
10120 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
10121 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
10123 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
10124 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
10125 (clobber (reg:CC CC_REGNUM))]
10128 "&& reload_completed"
10129 [(set (reg:CC_NOOV CC_REGNUM)
10131 (plus:SI (match_dup 3)
10134 (set (match_dup 0) (match_dup 1))
10135 (cond_exec (match_dup 6)
10136 (set (match_dup 0) (match_dup 2)))]
10139 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
10140 operands[3], operands[4]);
10141 enum rtx_code rc = GET_CODE (operands[5]);
10142 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10143 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
10144 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
10145 rc = reverse_condition (rc);
10147 std::swap (operands[1], operands[2]);
10149 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10152 [(set_attr "conds" "clob")
10153 (set_attr "enabled_for_short_it" "no,yes,yes")
10154 (set_attr "type" "multiple")]
10157 (define_insn "movcond"
10158 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10160 (match_operator 5 "arm_comparison_operator"
10161 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10162 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
10163 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10164 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
10165 (clobber (reg:CC CC_REGNUM))]
10168 if (GET_CODE (operands[5]) == LT
10169 && (operands[4] == const0_rtx))
10171 if (which_alternative != 1 && REG_P (operands[1]))
10173 if (operands[2] == const0_rtx)
10174 return \"and\\t%0, %1, %3, asr #31\";
10175 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
10177 else if (which_alternative != 0 && REG_P (operands[2]))
10179 if (operands[1] == const0_rtx)
10180 return \"bic\\t%0, %2, %3, asr #31\";
10181 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
10183 /* The only case that falls through to here is when both ops 1 & 2
10187 if (GET_CODE (operands[5]) == GE
10188 && (operands[4] == const0_rtx))
10190 if (which_alternative != 1 && REG_P (operands[1]))
10192 if (operands[2] == const0_rtx)
10193 return \"bic\\t%0, %1, %3, asr #31\";
10194 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
10196 else if (which_alternative != 0 && REG_P (operands[2]))
10198 if (operands[1] == const0_rtx)
10199 return \"and\\t%0, %2, %3, asr #31\";
10200 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
10202 /* The only case that falls through to here is when both ops 1 & 2
10205 if (CONST_INT_P (operands[4])
10206 && !const_ok_for_arm (INTVAL (operands[4])))
10207 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
10209 output_asm_insn (\"cmp\\t%3, %4\", operands);
10210 if (which_alternative != 0)
10211 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
10212 if (which_alternative != 1)
10213 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
10216 [(set_attr "conds" "clob")
10217 (set_attr "length" "8,8,12")
10218 (set_attr "type" "multiple")]
10221 ;; ??? The patterns below need checking for Thumb-2 usefulness.
10223 (define_insn "*ifcompare_plus_move"
10224 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10225 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10226 [(match_operand:SI 4 "s_register_operand" "r,r")
10227 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10229 (match_operand:SI 2 "s_register_operand" "r,r")
10230 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10231 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10232 (clobber (reg:CC CC_REGNUM))]
10235 [(set_attr "conds" "clob")
10236 (set_attr "length" "8,12")
10237 (set_attr "type" "multiple")]
10240 (define_insn "*if_plus_move"
10241 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10243 (match_operator 4 "arm_comparison_operator"
10244 [(match_operand 5 "cc_register" "") (const_int 0)])
10246 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10247 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10248 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10251 add%d4\\t%0, %2, %3
10252 sub%d4\\t%0, %2, #%n3
10253 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10254 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10255 [(set_attr "conds" "use")
10256 (set_attr "length" "4,4,8,8")
10257 (set_attr_alternative "type"
10258 [(if_then_else (match_operand 3 "const_int_operand" "")
10259 (const_string "alu_imm" )
10260 (const_string "alu_sreg"))
10261 (const_string "alu_imm")
10262 (const_string "multiple")
10263 (const_string "multiple")])]
10266 (define_insn "*ifcompare_move_plus"
10267 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10268 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10269 [(match_operand:SI 4 "s_register_operand" "r,r")
10270 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10271 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10273 (match_operand:SI 2 "s_register_operand" "r,r")
10274 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10275 (clobber (reg:CC CC_REGNUM))]
10278 [(set_attr "conds" "clob")
10279 (set_attr "length" "8,12")
10280 (set_attr "type" "multiple")]
10283 (define_insn "*if_move_plus"
10284 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10286 (match_operator 4 "arm_comparison_operator"
10287 [(match_operand 5 "cc_register" "") (const_int 0)])
10288 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10290 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10291 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10294 add%D4\\t%0, %2, %3
10295 sub%D4\\t%0, %2, #%n3
10296 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10297 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10298 [(set_attr "conds" "use")
10299 (set_attr "length" "4,4,8,8")
10300 (set_attr_alternative "type"
10301 [(if_then_else (match_operand 3 "const_int_operand" "")
10302 (const_string "alu_imm" )
10303 (const_string "alu_sreg"))
10304 (const_string "alu_imm")
10305 (const_string "multiple")
10306 (const_string "multiple")])]
10309 (define_insn "*ifcompare_arith_arith"
10310 [(set (match_operand:SI 0 "s_register_operand" "=r")
10311 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10312 [(match_operand:SI 5 "s_register_operand" "r")
10313 (match_operand:SI 6 "arm_add_operand" "rIL")])
10314 (match_operator:SI 8 "shiftable_operator"
10315 [(match_operand:SI 1 "s_register_operand" "r")
10316 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10317 (match_operator:SI 7 "shiftable_operator"
10318 [(match_operand:SI 3 "s_register_operand" "r")
10319 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10320 (clobber (reg:CC CC_REGNUM))]
10323 [(set_attr "conds" "clob")
10324 (set_attr "length" "12")
10325 (set_attr "type" "multiple")]
10328 (define_insn "*if_arith_arith"
10329 [(set (match_operand:SI 0 "s_register_operand" "=r")
10330 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10331 [(match_operand 8 "cc_register" "") (const_int 0)])
10332 (match_operator:SI 6 "shiftable_operator"
10333 [(match_operand:SI 1 "s_register_operand" "r")
10334 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10335 (match_operator:SI 7 "shiftable_operator"
10336 [(match_operand:SI 3 "s_register_operand" "r")
10337 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10339 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10340 [(set_attr "conds" "use")
10341 (set_attr "length" "8")
10342 (set_attr "type" "multiple")]
10345 (define_insn "*ifcompare_arith_move"
10346 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10347 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10348 [(match_operand:SI 2 "s_register_operand" "r,r")
10349 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10350 (match_operator:SI 7 "shiftable_operator"
10351 [(match_operand:SI 4 "s_register_operand" "r,r")
10352 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10353 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10354 (clobber (reg:CC CC_REGNUM))]
10357 /* If we have an operation where (op x 0) is the identity operation and
10358 the conditional operator is LT or GE and we are comparing against zero and
10359 everything is in registers then we can do this in two instructions. */
10360 if (operands[3] == const0_rtx
10361 && GET_CODE (operands[7]) != AND
10362 && REG_P (operands[5])
10363 && REG_P (operands[1])
10364 && REGNO (operands[1]) == REGNO (operands[4])
10365 && REGNO (operands[4]) != REGNO (operands[0]))
10367 if (GET_CODE (operands[6]) == LT)
10368 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10369 else if (GET_CODE (operands[6]) == GE)
10370 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10372 if (CONST_INT_P (operands[3])
10373 && !const_ok_for_arm (INTVAL (operands[3])))
10374 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10376 output_asm_insn (\"cmp\\t%2, %3\", operands);
10377 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10378 if (which_alternative != 0)
10379 return \"mov%D6\\t%0, %1\";
10382 [(set_attr "conds" "clob")
10383 (set_attr "length" "8,12")
10384 (set_attr "type" "multiple")]
10387 (define_insn "*if_arith_move"
10388 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10389 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10390 [(match_operand 6 "cc_register" "") (const_int 0)])
10391 (match_operator:SI 5 "shiftable_operator"
10392 [(match_operand:SI 2 "s_register_operand" "r,r")
10393 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10394 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10397 %I5%d4\\t%0, %2, %3
10398 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10399 [(set_attr "conds" "use")
10400 (set_attr "length" "4,8")
10401 (set_attr_alternative "type"
10402 [(if_then_else (match_operand 3 "const_int_operand" "")
10403 (const_string "alu_shift_imm" )
10404 (const_string "alu_shift_reg"))
10405 (const_string "multiple")])]
10408 (define_insn "*ifcompare_move_arith"
10409 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10410 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10411 [(match_operand:SI 4 "s_register_operand" "r,r")
10412 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10413 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10414 (match_operator:SI 7 "shiftable_operator"
10415 [(match_operand:SI 2 "s_register_operand" "r,r")
10416 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10417 (clobber (reg:CC CC_REGNUM))]
10420 /* If we have an operation where (op x 0) is the identity operation and
10421 the conditional operator is LT or GE and we are comparing against zero and
10422 everything is in registers then we can do this in two instructions */
10423 if (operands[5] == const0_rtx
10424 && GET_CODE (operands[7]) != AND
10425 && REG_P (operands[3])
10426 && REG_P (operands[1])
10427 && REGNO (operands[1]) == REGNO (operands[2])
10428 && REGNO (operands[2]) != REGNO (operands[0]))
10430 if (GET_CODE (operands[6]) == GE)
10431 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10432 else if (GET_CODE (operands[6]) == LT)
10433 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10436 if (CONST_INT_P (operands[5])
10437 && !const_ok_for_arm (INTVAL (operands[5])))
10438 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10440 output_asm_insn (\"cmp\\t%4, %5\", operands);
10442 if (which_alternative != 0)
10443 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10444 return \"%I7%D6\\t%0, %2, %3\";
10446 [(set_attr "conds" "clob")
10447 (set_attr "length" "8,12")
10448 (set_attr "type" "multiple")]
10451 (define_insn "*if_move_arith"
10452 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10454 (match_operator 4 "arm_comparison_operator"
10455 [(match_operand 6 "cc_register" "") (const_int 0)])
10456 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10457 (match_operator:SI 5 "shiftable_operator"
10458 [(match_operand:SI 2 "s_register_operand" "r,r")
10459 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10462 %I5%D4\\t%0, %2, %3
10463 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10464 [(set_attr "conds" "use")
10465 (set_attr "length" "4,8")
10466 (set_attr_alternative "type"
10467 [(if_then_else (match_operand 3 "const_int_operand" "")
10468 (const_string "alu_shift_imm" )
10469 (const_string "alu_shift_reg"))
10470 (const_string "multiple")])]
10473 (define_insn "*ifcompare_move_not"
10474 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10476 (match_operator 5 "arm_comparison_operator"
10477 [(match_operand:SI 3 "s_register_operand" "r,r")
10478 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10479 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10481 (match_operand:SI 2 "s_register_operand" "r,r"))))
10482 (clobber (reg:CC CC_REGNUM))]
10485 [(set_attr "conds" "clob")
10486 (set_attr "length" "8,12")
10487 (set_attr "type" "multiple")]
10490 (define_insn "*if_move_not"
10491 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10493 (match_operator 4 "arm_comparison_operator"
10494 [(match_operand 3 "cc_register" "") (const_int 0)])
10495 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10496 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10500 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10501 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10502 [(set_attr "conds" "use")
10503 (set_attr "type" "mvn_reg")
10504 (set_attr "length" "4,8,8")
10505 (set_attr "type" "mvn_reg,multiple,multiple")]
10508 (define_insn "*ifcompare_not_move"
10509 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10511 (match_operator 5 "arm_comparison_operator"
10512 [(match_operand:SI 3 "s_register_operand" "r,r")
10513 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10515 (match_operand:SI 2 "s_register_operand" "r,r"))
10516 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10517 (clobber (reg:CC CC_REGNUM))]
10520 [(set_attr "conds" "clob")
10521 (set_attr "length" "8,12")
10522 (set_attr "type" "multiple")]
10525 (define_insn "*if_not_move"
10526 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10528 (match_operator 4 "arm_comparison_operator"
10529 [(match_operand 3 "cc_register" "") (const_int 0)])
10530 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10531 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10535 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10536 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10537 [(set_attr "conds" "use")
10538 (set_attr "type" "mvn_reg,multiple,multiple")
10539 (set_attr "length" "4,8,8")]
10542 (define_insn "*ifcompare_shift_move"
10543 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10545 (match_operator 6 "arm_comparison_operator"
10546 [(match_operand:SI 4 "s_register_operand" "r,r")
10547 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10548 (match_operator:SI 7 "shift_operator"
10549 [(match_operand:SI 2 "s_register_operand" "r,r")
10550 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10551 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10552 (clobber (reg:CC CC_REGNUM))]
10555 [(set_attr "conds" "clob")
10556 (set_attr "length" "8,12")
10557 (set_attr "type" "multiple")]
10560 (define_insn "*if_shift_move"
10561 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10563 (match_operator 5 "arm_comparison_operator"
10564 [(match_operand 6 "cc_register" "") (const_int 0)])
10565 (match_operator:SI 4 "shift_operator"
10566 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10567 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10568 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10572 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10573 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10574 [(set_attr "conds" "use")
10575 (set_attr "shift" "2")
10576 (set_attr "length" "4,8,8")
10577 (set_attr_alternative "type"
10578 [(if_then_else (match_operand 3 "const_int_operand" "")
10579 (const_string "mov_shift" )
10580 (const_string "mov_shift_reg"))
10581 (const_string "multiple")
10582 (const_string "multiple")])]
10585 (define_insn "*ifcompare_move_shift"
10586 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10588 (match_operator 6 "arm_comparison_operator"
10589 [(match_operand:SI 4 "s_register_operand" "r,r")
10590 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10591 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10592 (match_operator:SI 7 "shift_operator"
10593 [(match_operand:SI 2 "s_register_operand" "r,r")
10594 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10595 (clobber (reg:CC CC_REGNUM))]
10598 [(set_attr "conds" "clob")
10599 (set_attr "length" "8,12")
10600 (set_attr "type" "multiple")]
10603 (define_insn "*if_move_shift"
10604 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10606 (match_operator 5 "arm_comparison_operator"
10607 [(match_operand 6 "cc_register" "") (const_int 0)])
10608 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10609 (match_operator:SI 4 "shift_operator"
10610 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10611 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10615 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10616 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10617 [(set_attr "conds" "use")
10618 (set_attr "shift" "2")
10619 (set_attr "length" "4,8,8")
10620 (set_attr_alternative "type"
10621 [(if_then_else (match_operand 3 "const_int_operand" "")
10622 (const_string "mov_shift" )
10623 (const_string "mov_shift_reg"))
10624 (const_string "multiple")
10625 (const_string "multiple")])]
10628 (define_insn "*ifcompare_shift_shift"
10629 [(set (match_operand:SI 0 "s_register_operand" "=r")
10631 (match_operator 7 "arm_comparison_operator"
10632 [(match_operand:SI 5 "s_register_operand" "r")
10633 (match_operand:SI 6 "arm_add_operand" "rIL")])
10634 (match_operator:SI 8 "shift_operator"
10635 [(match_operand:SI 1 "s_register_operand" "r")
10636 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10637 (match_operator:SI 9 "shift_operator"
10638 [(match_operand:SI 3 "s_register_operand" "r")
10639 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10640 (clobber (reg:CC CC_REGNUM))]
10643 [(set_attr "conds" "clob")
10644 (set_attr "length" "12")
10645 (set_attr "type" "multiple")]
10648 (define_insn "*if_shift_shift"
10649 [(set (match_operand:SI 0 "s_register_operand" "=r")
10651 (match_operator 5 "arm_comparison_operator"
10652 [(match_operand 8 "cc_register" "") (const_int 0)])
10653 (match_operator:SI 6 "shift_operator"
10654 [(match_operand:SI 1 "s_register_operand" "r")
10655 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10656 (match_operator:SI 7 "shift_operator"
10657 [(match_operand:SI 3 "s_register_operand" "r")
10658 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10660 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10661 [(set_attr "conds" "use")
10662 (set_attr "shift" "1")
10663 (set_attr "length" "8")
10664 (set (attr "type") (if_then_else
10665 (and (match_operand 2 "const_int_operand" "")
10666 (match_operand 4 "const_int_operand" ""))
10667 (const_string "mov_shift")
10668 (const_string "mov_shift_reg")))]
10671 (define_insn "*ifcompare_not_arith"
10672 [(set (match_operand:SI 0 "s_register_operand" "=r")
10674 (match_operator 6 "arm_comparison_operator"
10675 [(match_operand:SI 4 "s_register_operand" "r")
10676 (match_operand:SI 5 "arm_add_operand" "rIL")])
10677 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10678 (match_operator:SI 7 "shiftable_operator"
10679 [(match_operand:SI 2 "s_register_operand" "r")
10680 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10681 (clobber (reg:CC CC_REGNUM))]
10684 [(set_attr "conds" "clob")
10685 (set_attr "length" "12")
10686 (set_attr "type" "multiple")]
10689 (define_insn "*if_not_arith"
10690 [(set (match_operand:SI 0 "s_register_operand" "=r")
10692 (match_operator 5 "arm_comparison_operator"
10693 [(match_operand 4 "cc_register" "") (const_int 0)])
10694 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10695 (match_operator:SI 6 "shiftable_operator"
10696 [(match_operand:SI 2 "s_register_operand" "r")
10697 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10699 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10700 [(set_attr "conds" "use")
10701 (set_attr "type" "mvn_reg")
10702 (set_attr "length" "8")]
10705 (define_insn "*ifcompare_arith_not"
10706 [(set (match_operand:SI 0 "s_register_operand" "=r")
10708 (match_operator 6 "arm_comparison_operator"
10709 [(match_operand:SI 4 "s_register_operand" "r")
10710 (match_operand:SI 5 "arm_add_operand" "rIL")])
10711 (match_operator:SI 7 "shiftable_operator"
10712 [(match_operand:SI 2 "s_register_operand" "r")
10713 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10714 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10715 (clobber (reg:CC CC_REGNUM))]
10718 [(set_attr "conds" "clob")
10719 (set_attr "length" "12")
10720 (set_attr "type" "multiple")]
10723 (define_insn "*if_arith_not"
10724 [(set (match_operand:SI 0 "s_register_operand" "=r")
10726 (match_operator 5 "arm_comparison_operator"
10727 [(match_operand 4 "cc_register" "") (const_int 0)])
10728 (match_operator:SI 6 "shiftable_operator"
10729 [(match_operand:SI 2 "s_register_operand" "r")
10730 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10731 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10733 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10734 [(set_attr "conds" "use")
10735 (set_attr "type" "multiple")
10736 (set_attr "length" "8")]
10739 (define_insn "*ifcompare_neg_move"
10740 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10742 (match_operator 5 "arm_comparison_operator"
10743 [(match_operand:SI 3 "s_register_operand" "r,r")
10744 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10745 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10746 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10747 (clobber (reg:CC CC_REGNUM))]
10750 [(set_attr "conds" "clob")
10751 (set_attr "length" "8,12")
10752 (set_attr "type" "multiple")]
10755 (define_insn_and_split "*if_neg_move"
10756 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10758 (match_operator 4 "arm_comparison_operator"
10759 [(match_operand 3 "cc_register" "") (const_int 0)])
10760 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10761 (match_operand:SI 1 "s_register_operand" "0,0")))]
10764 "&& reload_completed"
10765 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10766 (set (match_dup 0) (neg:SI (match_dup 2))))]
10768 [(set_attr "conds" "use")
10769 (set_attr "length" "4")
10770 (set_attr "arch" "t2,32")
10771 (set_attr "enabled_for_short_it" "yes,no")
10772 (set_attr "type" "logic_shift_imm")]
10775 (define_insn "*ifcompare_move_neg"
10776 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10778 (match_operator 5 "arm_comparison_operator"
10779 [(match_operand:SI 3 "s_register_operand" "r,r")
10780 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10781 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10782 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10783 (clobber (reg:CC CC_REGNUM))]
10786 [(set_attr "conds" "clob")
10787 (set_attr "length" "8,12")
10788 (set_attr "type" "multiple")]
10791 (define_insn_and_split "*if_move_neg"
10792 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10794 (match_operator 4 "arm_comparison_operator"
10795 [(match_operand 3 "cc_register" "") (const_int 0)])
10796 (match_operand:SI 1 "s_register_operand" "0,0")
10797 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10800 "&& reload_completed"
10801 [(cond_exec (match_dup 5)
10802 (set (match_dup 0) (neg:SI (match_dup 2))))]
10804 machine_mode mode = GET_MODE (operands[3]);
10805 rtx_code rc = GET_CODE (operands[4]);
10807 if (mode == CCFPmode || mode == CCFPEmode)
10808 rc = reverse_condition_maybe_unordered (rc);
10810 rc = reverse_condition (rc);
10812 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10814 [(set_attr "conds" "use")
10815 (set_attr "length" "4")
10816 (set_attr "arch" "t2,32")
10817 (set_attr "enabled_for_short_it" "yes,no")
10818 (set_attr "type" "logic_shift_imm")]
10821 (define_insn "*arith_adjacentmem"
10822 [(set (match_operand:SI 0 "s_register_operand" "=r")
10823 (match_operator:SI 1 "shiftable_operator"
10824 [(match_operand:SI 2 "memory_operand" "m")
10825 (match_operand:SI 3 "memory_operand" "m")]))
10826 (clobber (match_scratch:SI 4 "=r"))]
10827 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10833 HOST_WIDE_INT val1 = 0, val2 = 0;
10835 if (REGNO (operands[0]) > REGNO (operands[4]))
10837 ldm[1] = operands[4];
10838 ldm[2] = operands[0];
10842 ldm[1] = operands[0];
10843 ldm[2] = operands[4];
10846 base_reg = XEXP (operands[2], 0);
10848 if (!REG_P (base_reg))
10850 val1 = INTVAL (XEXP (base_reg, 1));
10851 base_reg = XEXP (base_reg, 0);
10854 if (!REG_P (XEXP (operands[3], 0)))
10855 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10857 arith[0] = operands[0];
10858 arith[3] = operands[1];
10872 if (val1 !=0 && val2 != 0)
10876 if (val1 == 4 || val2 == 4)
10877 /* Other val must be 8, since we know they are adjacent and neither
10879 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10880 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10882 ldm[0] = ops[0] = operands[4];
10884 ops[2] = GEN_INT (val1);
10885 output_add_immediate (ops);
10887 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10889 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10893 /* Offset is out of range for a single add, so use two ldr. */
10896 ops[2] = GEN_INT (val1);
10897 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10899 ops[2] = GEN_INT (val2);
10900 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10903 else if (val1 != 0)
10906 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10908 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10913 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10915 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10917 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10920 [(set_attr "length" "12")
10921 (set_attr "predicable" "yes")
10922 (set_attr "type" "load_4")]
10925 ; This pattern is never tried by combine, so do it as a peephole
10928 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10929 (match_operand:SI 1 "arm_general_register_operand" ""))
10930 (set (reg:CC CC_REGNUM)
10931 (compare:CC (match_dup 1) (const_int 0)))]
10933 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10934 (set (match_dup 0) (match_dup 1))])]
10939 [(set (match_operand:SI 0 "s_register_operand" "")
10940 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10942 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10943 [(match_operand:SI 3 "s_register_operand" "")
10944 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10945 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10947 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10948 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10953 ;; This split can be used because CC_Z mode implies that the following
10954 ;; branch will be an equality, or an unsigned inequality, so the sign
10955 ;; extension is not needed.
10958 [(set (reg:CC_Z CC_REGNUM)
10960 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10962 (match_operand 1 "const_int_operand" "")))
10963 (clobber (match_scratch:SI 2 ""))]
10965 && ((UINTVAL (operands[1]))
10966 == ((UINTVAL (operands[1])) >> 24) << 24)"
10967 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10968 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10970 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10973 ;; ??? Check the patterns above for Thumb-2 usefulness
10975 (define_expand "prologue"
10976 [(clobber (const_int 0))]
10979 arm_expand_prologue ();
10981 thumb1_expand_prologue ();
10986 (define_expand "epilogue"
10987 [(clobber (const_int 0))]
10990 if (crtl->calls_eh_return)
10991 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10994 thumb1_expand_epilogue ();
10995 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10996 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10998 else if (HAVE_return)
11000 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
11001 no need for explicit testing again. */
11002 emit_jump_insn (gen_return ());
11004 else if (TARGET_32BIT)
11006 arm_expand_epilogue (true);
11012 ;; Note - although unspec_volatile's USE all hard registers,
11013 ;; USEs are ignored after relaod has completed. Thus we need
11014 ;; to add an unspec of the link register to ensure that flow
11015 ;; does not think that it is unused by the sibcall branch that
11016 ;; will replace the standard function epilogue.
11017 (define_expand "sibcall_epilogue"
11018 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
11019 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
11022 arm_expand_epilogue (false);
11027 (define_expand "eh_epilogue"
11028 [(use (match_operand:SI 0 "register_operand" ""))
11029 (use (match_operand:SI 1 "register_operand" ""))
11030 (use (match_operand:SI 2 "register_operand" ""))]
11034 cfun->machine->eh_epilogue_sp_ofs = operands[1];
11035 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11037 rtx ra = gen_rtx_REG (Pmode, 2);
11039 emit_move_insn (ra, operands[2]);
11042 /* This is a hack -- we may have crystalized the function type too
11044 cfun->machine->func_type = 0;
11048 ;; This split is only used during output to reduce the number of patterns
11049 ;; that need assembler instructions adding to them. We allowed the setting
11050 ;; of the conditions to be implicit during rtl generation so that
11051 ;; the conditional compare patterns would work. However this conflicts to
11052 ;; some extent with the conditional data operations, so we have to split them
11055 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
11056 ;; conditional execution sufficient?
11059 [(set (match_operand:SI 0 "s_register_operand" "")
11060 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11061 [(match_operand 2 "" "") (match_operand 3 "" "")])
11063 (match_operand 4 "" "")))
11064 (clobber (reg:CC CC_REGNUM))]
11065 "TARGET_ARM && reload_completed"
11066 [(set (match_dup 5) (match_dup 6))
11067 (cond_exec (match_dup 7)
11068 (set (match_dup 0) (match_dup 4)))]
11071 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11072 operands[2], operands[3]);
11073 enum rtx_code rc = GET_CODE (operands[1]);
11075 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11076 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11077 if (mode == CCFPmode || mode == CCFPEmode)
11078 rc = reverse_condition_maybe_unordered (rc);
11080 rc = reverse_condition (rc);
11082 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11087 [(set (match_operand:SI 0 "s_register_operand" "")
11088 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11089 [(match_operand 2 "" "") (match_operand 3 "" "")])
11090 (match_operand 4 "" "")
11092 (clobber (reg:CC CC_REGNUM))]
11093 "TARGET_ARM && reload_completed"
11094 [(set (match_dup 5) (match_dup 6))
11095 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11096 (set (match_dup 0) (match_dup 4)))]
11099 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11100 operands[2], operands[3]);
11102 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11103 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11108 [(set (match_operand:SI 0 "s_register_operand" "")
11109 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11110 [(match_operand 2 "" "") (match_operand 3 "" "")])
11111 (match_operand 4 "" "")
11112 (match_operand 5 "" "")))
11113 (clobber (reg:CC CC_REGNUM))]
11114 "TARGET_ARM && reload_completed"
11115 [(set (match_dup 6) (match_dup 7))
11116 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11117 (set (match_dup 0) (match_dup 4)))
11118 (cond_exec (match_dup 8)
11119 (set (match_dup 0) (match_dup 5)))]
11122 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11123 operands[2], operands[3]);
11124 enum rtx_code rc = GET_CODE (operands[1]);
11126 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11127 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11128 if (mode == CCFPmode || mode == CCFPEmode)
11129 rc = reverse_condition_maybe_unordered (rc);
11131 rc = reverse_condition (rc);
11133 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11138 [(set (match_operand:SI 0 "s_register_operand" "")
11139 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11140 [(match_operand:SI 2 "s_register_operand" "")
11141 (match_operand:SI 3 "arm_add_operand" "")])
11142 (match_operand:SI 4 "arm_rhs_operand" "")
11144 (match_operand:SI 5 "s_register_operand" ""))))
11145 (clobber (reg:CC CC_REGNUM))]
11146 "TARGET_ARM && reload_completed"
11147 [(set (match_dup 6) (match_dup 7))
11148 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11149 (set (match_dup 0) (match_dup 4)))
11150 (cond_exec (match_dup 8)
11151 (set (match_dup 0) (not:SI (match_dup 5))))]
11154 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11155 operands[2], operands[3]);
11156 enum rtx_code rc = GET_CODE (operands[1]);
11158 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11159 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11160 if (mode == CCFPmode || mode == CCFPEmode)
11161 rc = reverse_condition_maybe_unordered (rc);
11163 rc = reverse_condition (rc);
11165 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11169 (define_insn "*cond_move_not"
11170 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11171 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11172 [(match_operand 3 "cc_register" "") (const_int 0)])
11173 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11175 (match_operand:SI 2 "s_register_operand" "r,r"))))]
11179 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11180 [(set_attr "conds" "use")
11181 (set_attr "type" "mvn_reg,multiple")
11182 (set_attr "length" "4,8")]
11185 ;; The next two patterns occur when an AND operation is followed by a
11186 ;; scc insn sequence
11188 (define_insn "*sign_extract_onebit"
11189 [(set (match_operand:SI 0 "s_register_operand" "=r")
11190 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11192 (match_operand:SI 2 "const_int_operand" "n")))
11193 (clobber (reg:CC CC_REGNUM))]
11196 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11197 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
11198 return \"mvnne\\t%0, #0\";
11200 [(set_attr "conds" "clob")
11201 (set_attr "length" "8")
11202 (set_attr "type" "multiple")]
11205 (define_insn "*not_signextract_onebit"
11206 [(set (match_operand:SI 0 "s_register_operand" "=r")
11208 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11210 (match_operand:SI 2 "const_int_operand" "n"))))
11211 (clobber (reg:CC CC_REGNUM))]
11214 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11215 output_asm_insn (\"tst\\t%1, %2\", operands);
11216 output_asm_insn (\"mvneq\\t%0, #0\", operands);
11217 return \"movne\\t%0, #0\";
11219 [(set_attr "conds" "clob")
11220 (set_attr "length" "12")
11221 (set_attr "type" "multiple")]
11223 ;; ??? The above patterns need auditing for Thumb-2
11225 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
11226 ;; expressions. For simplicity, the first register is also in the unspec
11228 ;; To avoid the usage of GNU extension, the length attribute is computed
11229 ;; in a C function arm_attr_length_push_multi.
11230 (define_insn "*push_multi"
11231 [(match_parallel 2 "multi_register_push"
11232 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11233 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11234 UNSPEC_PUSH_MULT))])]
11238 int num_saves = XVECLEN (operands[2], 0);
11240 /* For the StrongARM at least it is faster to
11241 use STR to store only a single register.
11242 In Thumb mode always use push, and the assembler will pick
11243 something appropriate. */
11244 if (num_saves == 1 && TARGET_ARM)
11245 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11252 strcpy (pattern, \"push%?\\t{%1\");
11254 strcpy (pattern, \"push\\t{%1\");
11256 for (i = 1; i < num_saves; i++)
11258 strcat (pattern, \", %|\");
11260 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11263 strcat (pattern, \"}\");
11264 output_asm_insn (pattern, operands);
11269 [(set_attr "type" "store_16")
11270 (set (attr "length")
11271 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11274 (define_insn "stack_tie"
11275 [(set (mem:BLK (scratch))
11276 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11277 (match_operand:SI 1 "s_register_operand" "rk")]
11281 [(set_attr "length" "0")
11282 (set_attr "type" "block")]
11285 ;; Pop (as used in epilogue RTL)
11287 (define_insn "*load_multiple_with_writeback"
11288 [(match_parallel 0 "load_multiple_operation"
11289 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11290 (plus:SI (match_dup 1)
11291 (match_operand:SI 2 "const_int_I_operand" "I")))
11292 (set (match_operand:SI 3 "s_register_operand" "=rk")
11293 (mem:SI (match_dup 1)))
11295 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11298 arm_output_multireg_pop (operands, /*return_pc=*/false,
11299 /*cond=*/const_true_rtx,
11305 [(set_attr "type" "load_16")
11306 (set_attr "predicable" "yes")
11307 (set (attr "length")
11308 (symbol_ref "arm_attr_length_pop_multi (operands,
11309 /*return_pc=*/false,
11310 /*write_back_p=*/true)"))]
11313 ;; Pop with return (as used in epilogue RTL)
11315 ;; This instruction is generated when the registers are popped at the end of
11316 ;; epilogue. Here, instead of popping the value into LR and then generating
11317 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11319 (define_insn "*pop_multiple_with_writeback_and_return"
11320 [(match_parallel 0 "pop_multiple_return"
11322 (set (match_operand:SI 1 "s_register_operand" "+rk")
11323 (plus:SI (match_dup 1)
11324 (match_operand:SI 2 "const_int_I_operand" "I")))
11325 (set (match_operand:SI 3 "s_register_operand" "=rk")
11326 (mem:SI (match_dup 1)))
11328 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11331 arm_output_multireg_pop (operands, /*return_pc=*/true,
11332 /*cond=*/const_true_rtx,
11338 [(set_attr "type" "load_16")
11339 (set_attr "predicable" "yes")
11340 (set (attr "length")
11341 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11342 /*write_back_p=*/true)"))]
11345 (define_insn "*pop_multiple_with_return"
11346 [(match_parallel 0 "pop_multiple_return"
11348 (set (match_operand:SI 2 "s_register_operand" "=rk")
11349 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11351 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11354 arm_output_multireg_pop (operands, /*return_pc=*/true,
11355 /*cond=*/const_true_rtx,
11361 [(set_attr "type" "load_16")
11362 (set_attr "predicable" "yes")
11363 (set (attr "length")
11364 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11365 /*write_back_p=*/false)"))]
11368 ;; Load into PC and return
11369 (define_insn "*ldr_with_return"
11371 (set (reg:SI PC_REGNUM)
11372 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11373 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11374 "ldr%?\t%|pc, [%0], #4"
11375 [(set_attr "type" "load_4")
11376 (set_attr "predicable" "yes")]
11378 ;; Pop for floating point registers (as used in epilogue RTL)
11379 (define_insn "*vfp_pop_multiple_with_writeback"
11380 [(match_parallel 0 "pop_multiple_fp"
11381 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11382 (plus:SI (match_dup 1)
11383 (match_operand:SI 2 "const_int_I_operand" "I")))
11384 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11385 (mem:DF (match_dup 1)))])]
11386 "TARGET_32BIT && TARGET_HARD_FLOAT"
11389 int num_regs = XVECLEN (operands[0], 0);
11392 strcpy (pattern, \"vldm\\t\");
11393 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11394 strcat (pattern, \"!, {\");
11395 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11396 strcat (pattern, \"%P0\");
11397 if ((num_regs - 1) > 1)
11399 strcat (pattern, \"-%P1\");
11400 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11403 strcat (pattern, \"}\");
11404 output_asm_insn (pattern, op_list);
11408 [(set_attr "type" "load_16")
11409 (set_attr "conds" "unconditional")
11410 (set_attr "predicable" "no")]
11413 ;; Special patterns for dealing with the constant pool
11415 (define_insn "align_4"
11416 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11419 assemble_align (32);
11422 [(set_attr "type" "no_insn")]
11425 (define_insn "align_8"
11426 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11429 assemble_align (64);
11432 [(set_attr "type" "no_insn")]
11435 (define_insn "consttable_end"
11436 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11439 making_const_table = FALSE;
11442 [(set_attr "type" "no_insn")]
11445 (define_insn "consttable_1"
11446 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11449 making_const_table = TRUE;
11450 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11451 assemble_zeros (3);
11454 [(set_attr "length" "4")
11455 (set_attr "type" "no_insn")]
11458 (define_insn "consttable_2"
11459 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11463 rtx x = operands[0];
11464 making_const_table = TRUE;
11465 switch (GET_MODE_CLASS (GET_MODE (x)))
11468 arm_emit_fp16_const (x);
11471 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11472 assemble_zeros (2);
11477 [(set_attr "length" "4")
11478 (set_attr "type" "no_insn")]
11481 (define_insn "consttable_4"
11482 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11486 rtx x = operands[0];
11487 making_const_table = TRUE;
11488 scalar_float_mode float_mode;
11489 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11490 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11493 /* XXX: Sometimes gcc does something really dumb and ends up with
11494 a HIGH in a constant pool entry, usually because it's trying to
11495 load into a VFP register. We know this will always be used in
11496 combination with a LO_SUM which ignores the high bits, so just
11497 strip off the HIGH. */
11498 if (GET_CODE (x) == HIGH)
11500 assemble_integer (x, 4, BITS_PER_WORD, 1);
11501 mark_symbol_refs_as_used (x);
11505 [(set_attr "length" "4")
11506 (set_attr "type" "no_insn")]
11509 (define_insn "consttable_8"
11510 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11514 making_const_table = TRUE;
11515 scalar_float_mode float_mode;
11516 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11517 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11518 float_mode, BITS_PER_WORD);
11520 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11523 [(set_attr "length" "8")
11524 (set_attr "type" "no_insn")]
11527 (define_insn "consttable_16"
11528 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11532 making_const_table = TRUE;
11533 scalar_float_mode float_mode;
11534 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11535 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11536 float_mode, BITS_PER_WORD);
11538 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11541 [(set_attr "length" "16")
11542 (set_attr "type" "no_insn")]
11545 ;; V5 Instructions,
11547 (define_insn "clzsi2"
11548 [(set (match_operand:SI 0 "s_register_operand" "=r")
11549 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11550 "TARGET_32BIT && arm_arch5t"
11552 [(set_attr "predicable" "yes")
11553 (set_attr "type" "clz")])
11555 (define_insn "rbitsi2"
11556 [(set (match_operand:SI 0 "s_register_operand" "=r")
11557 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11558 "TARGET_32BIT && arm_arch_thumb2"
11560 [(set_attr "predicable" "yes")
11561 (set_attr "type" "clz")])
11563 ;; Keep this as a CTZ expression until after reload and then split
11564 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11565 ;; to fold with any other expression.
11567 (define_insn_and_split "ctzsi2"
11568 [(set (match_operand:SI 0 "s_register_operand" "=r")
11569 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11570 "TARGET_32BIT && arm_arch_thumb2"
11572 "&& reload_completed"
11575 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11576 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11580 ;; V5E instructions.
11582 (define_insn "prefetch"
11583 [(prefetch (match_operand:SI 0 "address_operand" "p")
11584 (match_operand:SI 1 "" "")
11585 (match_operand:SI 2 "" ""))]
11586 "TARGET_32BIT && arm_arch5te"
11588 [(set_attr "type" "load_4")]
11591 ;; General predication pattern
11594 [(match_operator 0 "arm_comparison_operator"
11595 [(match_operand 1 "cc_register" "")
11598 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11600 [(set_attr "predicated" "yes")]
11603 (define_insn "force_register_use"
11604 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11607 [(set_attr "length" "0")
11608 (set_attr "type" "no_insn")]
11612 ;; Patterns for exception handling
11614 (define_expand "eh_return"
11615 [(use (match_operand 0 "general_operand" ""))]
11620 emit_insn (gen_arm_eh_return (operands[0]));
11622 emit_insn (gen_thumb_eh_return (operands[0]));
11627 ;; We can't expand this before we know where the link register is stored.
11628 (define_insn_and_split "arm_eh_return"
11629 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11631 (clobber (match_scratch:SI 1 "=&r"))]
11634 "&& reload_completed"
11638 arm_set_return_address (operands[0], operands[1]);
11646 (define_insn "load_tp_hard"
11647 [(set (match_operand:SI 0 "register_operand" "=r")
11648 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11650 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11651 [(set_attr "predicable" "yes")
11652 (set_attr "type" "mrs")]
11655 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11656 (define_insn "load_tp_soft"
11657 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11658 (clobber (reg:SI LR_REGNUM))
11659 (clobber (reg:SI IP_REGNUM))
11660 (clobber (reg:CC CC_REGNUM))]
11662 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11663 [(set_attr "conds" "clob")
11664 (set_attr "type" "branch")]
11667 ;; tls descriptor call
11668 (define_insn "tlscall"
11669 [(set (reg:SI R0_REGNUM)
11670 (unspec:SI [(reg:SI R0_REGNUM)
11671 (match_operand:SI 0 "" "X")
11672 (match_operand 1 "" "")] UNSPEC_TLS))
11673 (clobber (reg:SI R1_REGNUM))
11674 (clobber (reg:SI LR_REGNUM))
11675 (clobber (reg:SI CC_REGNUM))]
11678 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11679 INTVAL (operands[1]));
11680 return "bl\\t%c0(tlscall)";
11682 [(set_attr "conds" "clob")
11683 (set_attr "length" "4")
11684 (set_attr "type" "branch")]
11687 ;; For thread pointer builtin
11688 (define_expand "get_thread_pointersi"
11689 [(match_operand:SI 0 "s_register_operand" "=r")]
11693 arm_load_tp (operands[0]);
11699 ;; We only care about the lower 16 bits of the constant
11700 ;; being inserted into the upper 16 bits of the register.
11701 (define_insn "*arm_movtas_ze"
11702 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11705 (match_operand:SI 1 "const_int_operand" ""))]
11710 [(set_attr "arch" "32,v8mb")
11711 (set_attr "predicable" "yes")
11712 (set_attr "length" "4")
11713 (set_attr "type" "alu_sreg")]
11716 (define_insn "*arm_rev"
11717 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11718 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11724 [(set_attr "arch" "t1,t2,32")
11725 (set_attr "length" "2,2,4")
11726 (set_attr "predicable" "no,yes,yes")
11727 (set_attr "type" "rev")]
11730 (define_expand "arm_legacy_rev"
11731 [(set (match_operand:SI 2 "s_register_operand" "")
11732 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11736 (lshiftrt:SI (match_dup 2)
11738 (set (match_operand:SI 3 "s_register_operand" "")
11739 (rotatert:SI (match_dup 1)
11742 (and:SI (match_dup 2)
11743 (const_int -65281)))
11744 (set (match_operand:SI 0 "s_register_operand" "")
11745 (xor:SI (match_dup 3)
11751 ;; Reuse temporaries to keep register pressure down.
11752 (define_expand "thumb_legacy_rev"
11753 [(set (match_operand:SI 2 "s_register_operand" "")
11754 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11756 (set (match_operand:SI 3 "s_register_operand" "")
11757 (lshiftrt:SI (match_dup 1)
11760 (ior:SI (match_dup 3)
11762 (set (match_operand:SI 4 "s_register_operand" "")
11764 (set (match_operand:SI 5 "s_register_operand" "")
11765 (rotatert:SI (match_dup 1)
11768 (ashift:SI (match_dup 5)
11771 (lshiftrt:SI (match_dup 5)
11774 (ior:SI (match_dup 5)
11777 (rotatert:SI (match_dup 5)
11779 (set (match_operand:SI 0 "s_register_operand" "")
11780 (ior:SI (match_dup 5)
11786 ;; ARM-specific expansion of signed mod by power of 2
11787 ;; using conditional negate.
11788 ;; For r0 % n where n is a power of 2 produce:
11790 ;; and r0, r0, #(n - 1)
11791 ;; and r1, r1, #(n - 1)
11792 ;; rsbpl r0, r1, #0
11794 (define_expand "modsi3"
11795 [(match_operand:SI 0 "register_operand" "")
11796 (match_operand:SI 1 "register_operand" "")
11797 (match_operand:SI 2 "const_int_operand" "")]
11800 HOST_WIDE_INT val = INTVAL (operands[2]);
11803 || exact_log2 (val) <= 0)
11806 rtx mask = GEN_INT (val - 1);
11808 /* In the special case of x0 % 2 we can do the even shorter:
11811 rsblt r0, r0, #0. */
11815 rtx cc_reg = arm_gen_compare_reg (LT,
11816 operands[1], const0_rtx, NULL_RTX);
11817 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11818 rtx masked = gen_reg_rtx (SImode);
11820 emit_insn (gen_andsi3 (masked, operands[1], mask));
11821 emit_move_insn (operands[0],
11822 gen_rtx_IF_THEN_ELSE (SImode, cond,
11823 gen_rtx_NEG (SImode,
11829 rtx neg_op = gen_reg_rtx (SImode);
11830 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11833 /* Extract the condition register and mode. */
11834 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11835 rtx cc_reg = SET_DEST (cmp);
11836 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11838 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11840 rtx masked_neg = gen_reg_rtx (SImode);
11841 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11843 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11844 during expand does not always work. Do an IF_THEN_ELSE instead. */
11845 emit_move_insn (operands[0],
11846 gen_rtx_IF_THEN_ELSE (SImode, cond,
11847 gen_rtx_NEG (SImode, masked_neg),
11855 (define_expand "bswapsi2"
11856 [(set (match_operand:SI 0 "s_register_operand" "=r")
11857 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11858 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11862 rtx op2 = gen_reg_rtx (SImode);
11863 rtx op3 = gen_reg_rtx (SImode);
11867 rtx op4 = gen_reg_rtx (SImode);
11868 rtx op5 = gen_reg_rtx (SImode);
11870 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11871 op2, op3, op4, op5));
11875 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11884 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11885 ;; and unsigned variants, respectively. For rev16, expose
11886 ;; byte-swapping in the lower 16 bits only.
11887 (define_insn "*arm_revsh"
11888 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11889 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11895 [(set_attr "arch" "t1,t2,32")
11896 (set_attr "length" "2,2,4")
11897 (set_attr "type" "rev")]
11900 (define_insn "*arm_rev16"
11901 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11902 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11908 [(set_attr "arch" "t1,t2,32")
11909 (set_attr "length" "2,2,4")
11910 (set_attr "type" "rev")]
11913 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11914 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11915 ;; each valid permutation.
11917 (define_insn "arm_rev16si2"
11918 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11919 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11921 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11922 (and:SI (lshiftrt:SI (match_dup 1)
11924 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11926 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11927 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11929 [(set_attr "arch" "t1,t2,32")
11930 (set_attr "length" "2,2,4")
11931 (set_attr "type" "rev")]
11934 (define_insn "arm_rev16si2_alt"
11935 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11936 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11938 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11939 (and:SI (ashift:SI (match_dup 1)
11941 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11943 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11944 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11946 [(set_attr "arch" "t1,t2,32")
11947 (set_attr "length" "2,2,4")
11948 (set_attr "type" "rev")]
11951 (define_expand "bswaphi2"
11952 [(set (match_operand:HI 0 "s_register_operand" "=r")
11953 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11958 ;; Patterns for LDRD/STRD in Thumb2 mode
11960 (define_insn "*thumb2_ldrd"
11961 [(set (match_operand:SI 0 "s_register_operand" "=r")
11962 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11963 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11964 (set (match_operand:SI 3 "s_register_operand" "=r")
11965 (mem:SI (plus:SI (match_dup 1)
11966 (match_operand:SI 4 "const_int_operand" ""))))]
11967 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11968 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11969 && (operands_ok_ldrd_strd (operands[0], operands[3],
11970 operands[1], INTVAL (operands[2]),
11972 "ldrd%?\t%0, %3, [%1, %2]"
11973 [(set_attr "type" "load_8")
11974 (set_attr "predicable" "yes")])
11976 (define_insn "*thumb2_ldrd_base"
11977 [(set (match_operand:SI 0 "s_register_operand" "=r")
11978 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11979 (set (match_operand:SI 2 "s_register_operand" "=r")
11980 (mem:SI (plus:SI (match_dup 1)
11982 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11983 && (operands_ok_ldrd_strd (operands[0], operands[2],
11984 operands[1], 0, false, true))"
11985 "ldrd%?\t%0, %2, [%1]"
11986 [(set_attr "type" "load_8")
11987 (set_attr "predicable" "yes")])
11989 (define_insn "*thumb2_ldrd_base_neg"
11990 [(set (match_operand:SI 0 "s_register_operand" "=r")
11991 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11993 (set (match_operand:SI 2 "s_register_operand" "=r")
11994 (mem:SI (match_dup 1)))]
11995 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11996 && (operands_ok_ldrd_strd (operands[0], operands[2],
11997 operands[1], -4, false, true))"
11998 "ldrd%?\t%0, %2, [%1, #-4]"
11999 [(set_attr "type" "load_8")
12000 (set_attr "predicable" "yes")])
12002 (define_insn "*thumb2_strd"
12003 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12004 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
12005 (match_operand:SI 2 "s_register_operand" "r"))
12006 (set (mem:SI (plus:SI (match_dup 0)
12007 (match_operand:SI 3 "const_int_operand" "")))
12008 (match_operand:SI 4 "s_register_operand" "r"))]
12009 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12010 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
12011 && (operands_ok_ldrd_strd (operands[2], operands[4],
12012 operands[0], INTVAL (operands[1]),
12014 "strd%?\t%2, %4, [%0, %1]"
12015 [(set_attr "type" "store_8")
12016 (set_attr "predicable" "yes")])
12018 (define_insn "*thumb2_strd_base"
12019 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
12020 (match_operand:SI 1 "s_register_operand" "r"))
12021 (set (mem:SI (plus:SI (match_dup 0)
12023 (match_operand:SI 2 "s_register_operand" "r"))]
12024 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12025 && (operands_ok_ldrd_strd (operands[1], operands[2],
12026 operands[0], 0, false, false))"
12027 "strd%?\t%1, %2, [%0]"
12028 [(set_attr "type" "store_8")
12029 (set_attr "predicable" "yes")])
12031 (define_insn "*thumb2_strd_base_neg"
12032 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12034 (match_operand:SI 1 "s_register_operand" "r"))
12035 (set (mem:SI (match_dup 0))
12036 (match_operand:SI 2 "s_register_operand" "r"))]
12037 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12038 && (operands_ok_ldrd_strd (operands[1], operands[2],
12039 operands[0], -4, false, false))"
12040 "strd%?\t%1, %2, [%0, #-4]"
12041 [(set_attr "type" "store_8")
12042 (set_attr "predicable" "yes")])
12044 ;; ARMv8 CRC32 instructions.
12045 (define_insn "<crc_variant>"
12046 [(set (match_operand:SI 0 "s_register_operand" "=r")
12047 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
12048 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
12051 "<crc_variant>\\t%0, %1, %2"
12052 [(set_attr "type" "crc")
12053 (set_attr "conds" "unconditional")]
12056 ;; Load the load/store double peephole optimizations.
12057 (include "ldrdstrd.md")
12059 ;; Load the load/store multiple patterns
12060 (include "ldmstm.md")
12062 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12063 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12064 ;; The operands are validated through the load_multiple_operation
12065 ;; match_parallel predicate rather than through constraints so enable it only
12067 (define_insn "*load_multiple"
12068 [(match_parallel 0 "load_multiple_operation"
12069 [(set (match_operand:SI 2 "s_register_operand" "=rk")
12070 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12072 "TARGET_32BIT && reload_completed"
12075 arm_output_multireg_pop (operands, /*return_pc=*/false,
12076 /*cond=*/const_true_rtx,
12082 [(set_attr "predicable" "yes")]
12085 (define_expand "copysignsf3"
12086 [(match_operand:SF 0 "register_operand")
12087 (match_operand:SF 1 "register_operand")
12088 (match_operand:SF 2 "register_operand")]
12089 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12091 emit_move_insn (operands[0], operands[2]);
12092 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
12093 GEN_INT (31), GEN_INT (0),
12094 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
12099 (define_expand "copysigndf3"
12100 [(match_operand:DF 0 "register_operand")
12101 (match_operand:DF 1 "register_operand")
12102 (match_operand:DF 2 "register_operand")]
12103 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12105 rtx op0_low = gen_lowpart (SImode, operands[0]);
12106 rtx op0_high = gen_highpart (SImode, operands[0]);
12107 rtx op1_low = gen_lowpart (SImode, operands[1]);
12108 rtx op1_high = gen_highpart (SImode, operands[1]);
12109 rtx op2_high = gen_highpart (SImode, operands[2]);
12111 rtx scratch1 = gen_reg_rtx (SImode);
12112 rtx scratch2 = gen_reg_rtx (SImode);
12113 emit_move_insn (scratch1, op2_high);
12114 emit_move_insn (scratch2, op1_high);
12116 emit_insn(gen_rtx_SET(scratch1,
12117 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
12118 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
12119 emit_move_insn (op0_low, op1_low);
12120 emit_move_insn (op0_high, scratch2);
12126 ;; movmisalign patterns for HImode and SImode.
12127 (define_expand "movmisalign<mode>"
12128 [(match_operand:HSI 0 "general_operand")
12129 (match_operand:HSI 1 "general_operand")]
12132 /* This pattern is not permitted to fail during expansion: if both arguments
12133 are non-registers (e.g. memory := constant), force operand 1 into a
12135 rtx (* gen_unaligned_load)(rtx, rtx);
12136 rtx tmp_dest = operands[0];
12137 if (!s_register_operand (operands[0], <MODE>mode)
12138 && !s_register_operand (operands[1], <MODE>mode))
12139 operands[1] = force_reg (<MODE>mode, operands[1]);
12141 if (<MODE>mode == HImode)
12143 gen_unaligned_load = gen_unaligned_loadhiu;
12144 tmp_dest = gen_reg_rtx (SImode);
12147 gen_unaligned_load = gen_unaligned_loadsi;
12149 if (MEM_P (operands[1]))
12151 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
12152 if (<MODE>mode == HImode)
12153 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
12156 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
12161 (define_insn "<cdp>"
12162 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12163 (match_operand:SI 1 "immediate_operand" "n")
12164 (match_operand:SI 2 "immediate_operand" "n")
12165 (match_operand:SI 3 "immediate_operand" "n")
12166 (match_operand:SI 4 "immediate_operand" "n")
12167 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
12168 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
12170 arm_const_bounds (operands[0], 0, 16);
12171 arm_const_bounds (operands[1], 0, 16);
12172 arm_const_bounds (operands[2], 0, (1 << 5));
12173 arm_const_bounds (operands[3], 0, (1 << 5));
12174 arm_const_bounds (operands[4], 0, (1 << 5));
12175 arm_const_bounds (operands[5], 0, 8);
12176 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
12178 [(set_attr "length" "4")
12179 (set_attr "type" "coproc")])
12181 (define_insn "*ldc"
12182 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12183 (match_operand:SI 1 "immediate_operand" "n")
12184 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
12185 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
12187 arm_const_bounds (operands[0], 0, 16);
12188 arm_const_bounds (operands[1], 0, (1 << 5));
12189 return "<ldc>\\tp%c0, CR%c1, %2";
12191 [(set_attr "length" "4")
12192 (set_attr "type" "coproc")])
12194 (define_insn "*stc"
12195 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12196 (match_operand:SI 1 "immediate_operand" "n")
12197 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
12198 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
12200 arm_const_bounds (operands[0], 0, 16);
12201 arm_const_bounds (operands[1], 0, (1 << 5));
12202 return "<stc>\\tp%c0, CR%c1, %2";
12204 [(set_attr "length" "4")
12205 (set_attr "type" "coproc")])
12207 (define_expand "<ldc>"
12208 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12209 (match_operand:SI 1 "immediate_operand")
12210 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
12211 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
12213 (define_expand "<stc>"
12214 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12215 (match_operand:SI 1 "immediate_operand")
12216 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12217 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12219 (define_insn "<mcr>"
12220 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12221 (match_operand:SI 1 "immediate_operand" "n")
12222 (match_operand:SI 2 "s_register_operand" "r")
12223 (match_operand:SI 3 "immediate_operand" "n")
12224 (match_operand:SI 4 "immediate_operand" "n")
12225 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12226 (use (match_dup 2))]
12227 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12229 arm_const_bounds (operands[0], 0, 16);
12230 arm_const_bounds (operands[1], 0, 8);
12231 arm_const_bounds (operands[3], 0, (1 << 5));
12232 arm_const_bounds (operands[4], 0, (1 << 5));
12233 arm_const_bounds (operands[5], 0, 8);
12234 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12236 [(set_attr "length" "4")
12237 (set_attr "type" "coproc")])
12239 (define_insn "<mrc>"
12240 [(set (match_operand:SI 0 "s_register_operand" "=r")
12241 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12242 (match_operand:SI 2 "immediate_operand" "n")
12243 (match_operand:SI 3 "immediate_operand" "n")
12244 (match_operand:SI 4 "immediate_operand" "n")
12245 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12246 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12248 arm_const_bounds (operands[1], 0, 16);
12249 arm_const_bounds (operands[2], 0, 8);
12250 arm_const_bounds (operands[3], 0, (1 << 5));
12251 arm_const_bounds (operands[4], 0, (1 << 5));
12252 arm_const_bounds (operands[5], 0, 8);
12253 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12255 [(set_attr "length" "4")
12256 (set_attr "type" "coproc")])
12258 (define_insn "<mcrr>"
12259 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12260 (match_operand:SI 1 "immediate_operand" "n")
12261 (match_operand:DI 2 "s_register_operand" "r")
12262 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12263 (use (match_dup 2))]
12264 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12266 arm_const_bounds (operands[0], 0, 16);
12267 arm_const_bounds (operands[1], 0, 8);
12268 arm_const_bounds (operands[3], 0, (1 << 5));
12269 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12271 [(set_attr "length" "4")
12272 (set_attr "type" "coproc")])
12274 (define_insn "<mrrc>"
12275 [(set (match_operand:DI 0 "s_register_operand" "=r")
12276 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12277 (match_operand:SI 2 "immediate_operand" "n")
12278 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12279 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12281 arm_const_bounds (operands[1], 0, 16);
12282 arm_const_bounds (operands[2], 0, 8);
12283 arm_const_bounds (operands[3], 0, (1 << 5));
12284 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12286 [(set_attr "length" "4")
12287 (set_attr "type" "coproc")])
12289 (define_expand "speculation_barrier"
12290 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12293 /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
12294 have a usable barrier (and probably don't need one in practice).
12295 But to be safe if such code is run on later architectures, call a
12296 helper function in libgcc that will do the thing for the active
12298 if (!(arm_arch7 || arm_arch8))
12300 arm_emit_speculation_barrier_function ();
12306 ;; Generate a hard speculation barrier when we have not enabled speculation
12308 (define_insn "*speculation_barrier_insn"
12309 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12310 "arm_arch7 || arm_arch8"
12312 [(set_attr "type" "block")
12313 (set_attr "length" "8")]
12316 ;; Vector bits common to IWMMXT and Neon
12317 (include "vec-common.md")
12318 ;; Load the Intel Wireless Multimedia Extension patterns
12319 (include "iwmmxt.md")
12320 ;; Load the VFP co-processor patterns
12322 ;; Thumb-1 patterns
12323 (include "thumb1.md")
12324 ;; Thumb-2 patterns
12325 (include "thumb2.md")
12327 (include "neon.md")
12329 (include "crypto.md")
12330 ;; Synchronization Primitives
12331 (include "sync.md")
12332 ;; Fixed-point patterns
12333 (include "arm-fixed.md")