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")))]
870 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
873 subs%?\\t%0, %1, #%n3"
874 [(set_attr "conds" "set")
875 (set_attr "type" "alus_sreg")]
878 ;; Convert the sequence
880 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
884 ;; bcs dest ((unsigned)rn >= 1)
885 ;; similarly for the beq variant using bcc.
886 ;; This is a common looping idiom (while (n--))
888 [(set (match_operand:SI 0 "arm_general_register_operand" "")
889 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
891 (set (match_operand 2 "cc_register" "")
892 (compare (match_dup 0) (const_int -1)))
894 (if_then_else (match_operator 3 "equality_operator"
895 [(match_dup 2) (const_int 0)])
896 (match_operand 4 "" "")
897 (match_operand 5 "" "")))]
898 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
902 (match_dup 1) (const_int 1)))
903 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
905 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
908 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
909 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
912 operands[2], const0_rtx);"
915 ;; The next four insns work because they compare the result with one of
916 ;; the operands, and we know that the use of the condition code is
917 ;; either GEU or LTU, so we can use the carry flag from the addition
918 ;; instead of doing the compare a second time.
919 (define_insn "*addsi3_compare_op1"
920 [(set (reg:CC_C CC_REGNUM)
922 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
923 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
925 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
926 (plus:SI (match_dup 1) (match_dup 2)))]
930 subs%?\\t%0, %1, #%n2
932 [(set_attr "conds" "set")
933 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
936 (define_insn "*addsi3_compare_op2"
937 [(set (reg:CC_C CC_REGNUM)
939 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
940 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
942 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
943 (plus:SI (match_dup 1) (match_dup 2)))]
947 subs%?\\t%0, %1, #%n2
949 [(set_attr "conds" "set")
950 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
953 (define_insn "*compare_addsi2_op0"
954 [(set (reg:CC_C CC_REGNUM)
956 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
957 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
966 [(set_attr "conds" "set")
967 (set_attr "predicable" "yes")
968 (set_attr "arch" "t2,t2,*,*,*")
969 (set_attr "predicable_short_it" "yes,yes,no,no,no")
970 (set_attr "length" "2,2,4,4,4")
971 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
974 (define_insn "*compare_addsi2_op1"
975 [(set (reg:CC_C CC_REGNUM)
977 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
978 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
987 [(set_attr "conds" "set")
988 (set_attr "predicable" "yes")
989 (set_attr "arch" "t2,t2,*,*,*")
990 (set_attr "predicable_short_it" "yes,yes,no,no,no")
991 (set_attr "length" "2,2,4,4,4")
992 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
995 (define_insn "*addsi3_carryin_<optab>"
996 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
997 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
998 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
999 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1004 sbc%?\\t%0, %1, #%B2"
1005 [(set_attr "conds" "use")
1006 (set_attr "predicable" "yes")
1007 (set_attr "arch" "t2,*,*")
1008 (set_attr "length" "4")
1009 (set_attr "predicable_short_it" "yes,no,no")
1010 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1013 (define_insn "*addsi3_carryin_alt2_<optab>"
1014 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1015 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1016 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1017 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1022 sbc%?\\t%0, %1, #%B2"
1023 [(set_attr "conds" "use")
1024 (set_attr "predicable" "yes")
1025 (set_attr "arch" "t2,*,*")
1026 (set_attr "length" "4")
1027 (set_attr "predicable_short_it" "yes,no,no")
1028 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1031 (define_insn "*addsi3_carryin_shift_<optab>"
1032 [(set (match_operand:SI 0 "s_register_operand" "=r")
1034 (match_operator:SI 2 "shift_operator"
1035 [(match_operand:SI 3 "s_register_operand" "r")
1036 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1037 (match_operand:SI 1 "s_register_operand" "r"))
1038 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1040 "adc%?\\t%0, %1, %3%S2"
1041 [(set_attr "conds" "use")
1042 (set_attr "predicable" "yes")
1043 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1044 (const_string "alu_shift_imm")
1045 (const_string "alu_shift_reg")))]
1048 (define_insn "*addsi3_carryin_clobercc_<optab>"
1049 [(set (match_operand:SI 0 "s_register_operand" "=r")
1050 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1051 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1052 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1053 (clobber (reg:CC CC_REGNUM))]
1055 "adcs%?\\t%0, %1, %2"
1056 [(set_attr "conds" "set")
1057 (set_attr "type" "adcs_reg")]
1060 (define_expand "subv<mode>4"
1061 [(match_operand:SIDI 0 "register_operand")
1062 (match_operand:SIDI 1 "register_operand")
1063 (match_operand:SIDI 2 "register_operand")
1064 (match_operand 3 "")]
1067 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1068 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1073 (define_expand "usubv<mode>4"
1074 [(match_operand:SIDI 0 "register_operand")
1075 (match_operand:SIDI 1 "register_operand")
1076 (match_operand:SIDI 2 "register_operand")
1077 (match_operand 3 "")]
1080 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1081 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1086 (define_insn_and_split "subdi3_compare1"
1087 [(set (reg:CC CC_REGNUM)
1089 (match_operand:DI 1 "register_operand" "r")
1090 (match_operand:DI 2 "register_operand" "r")))
1091 (set (match_operand:DI 0 "register_operand" "=&r")
1092 (minus:DI (match_dup 1) (match_dup 2)))]
1095 "&& reload_completed"
1096 [(parallel [(set (reg:CC CC_REGNUM)
1097 (compare:CC (match_dup 1) (match_dup 2)))
1098 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1099 (parallel [(set (reg:CC CC_REGNUM)
1100 (compare:CC (match_dup 4) (match_dup 5)))
1101 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1102 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1104 operands[3] = gen_highpart (SImode, operands[0]);
1105 operands[0] = gen_lowpart (SImode, operands[0]);
1106 operands[4] = gen_highpart (SImode, operands[1]);
1107 operands[1] = gen_lowpart (SImode, operands[1]);
1108 operands[5] = gen_highpart (SImode, operands[2]);
1109 operands[2] = gen_lowpart (SImode, operands[2]);
1111 [(set_attr "conds" "set")
1112 (set_attr "length" "8")
1113 (set_attr "type" "multiple")]
1116 (define_insn "subsi3_compare1"
1117 [(set (reg:CC CC_REGNUM)
1119 (match_operand:SI 1 "register_operand" "r")
1120 (match_operand:SI 2 "register_operand" "r")))
1121 (set (match_operand:SI 0 "register_operand" "=r")
1122 (minus:SI (match_dup 1) (match_dup 2)))]
1124 "subs%?\\t%0, %1, %2"
1125 [(set_attr "conds" "set")
1126 (set_attr "type" "alus_sreg")]
1129 (define_insn "*subsi3_carryin"
1130 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1131 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1132 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1133 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1138 sbc%?\\t%0, %2, %2, lsl #1"
1139 [(set_attr "conds" "use")
1140 (set_attr "arch" "*,a,t2")
1141 (set_attr "predicable" "yes")
1142 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1145 (define_insn "*subsi3_carryin_const"
1146 [(set (match_operand:SI 0 "s_register_operand" "=r")
1147 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1148 (match_operand:SI 2 "arm_neg_immediate_operand" "L"))
1149 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1151 "sbc\\t%0, %1, #%n2"
1152 [(set_attr "conds" "use")
1153 (set_attr "type" "adc_imm")]
1156 (define_insn "*subsi3_carryin_const0"
1157 [(set (match_operand:SI 0 "s_register_operand" "=r")
1158 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
1159 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1162 [(set_attr "conds" "use")
1163 (set_attr "type" "adc_imm")]
1166 (define_insn "*subsi3_carryin_compare"
1167 [(set (reg:CC CC_REGNUM)
1168 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1169 (match_operand:SI 2 "s_register_operand" "r")))
1170 (set (match_operand:SI 0 "s_register_operand" "=r")
1171 (minus:SI (minus:SI (match_dup 1)
1173 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1176 [(set_attr "conds" "set")
1177 (set_attr "type" "adcs_reg")]
1180 (define_insn "*subsi3_carryin_compare_const"
1181 [(set (reg:CC CC_REGNUM)
1182 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1183 (match_operand:SI 2 "const_int_I_operand" "I")))
1184 (set (match_operand:SI 0 "s_register_operand" "=r")
1185 (minus:SI (plus:SI (match_dup 1)
1186 (match_operand:SI 3 "arm_neg_immediate_operand" "L"))
1187 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1188 "TARGET_32BIT && UINTVAL (operands[2]) == -UINTVAL (operands[3])"
1189 "sbcs\\t%0, %1, #%n3"
1190 [(set_attr "conds" "set")
1191 (set_attr "type" "adcs_imm")]
1194 (define_insn "*subsi3_carryin_compare_const0"
1195 [(set (reg:CC CC_REGNUM)
1196 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1198 (set (match_operand:SI 0 "s_register_operand" "=r")
1199 (minus:SI (match_dup 1)
1200 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1203 [(set_attr "conds" "set")
1204 (set_attr "type" "adcs_imm")]
1207 (define_insn "*subsi3_carryin_shift"
1208 [(set (match_operand:SI 0 "s_register_operand" "=r")
1210 (match_operand:SI 1 "s_register_operand" "r")
1211 (match_operator:SI 2 "shift_operator"
1212 [(match_operand:SI 3 "s_register_operand" "r")
1213 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1214 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1216 "sbc%?\\t%0, %1, %3%S2"
1217 [(set_attr "conds" "use")
1218 (set_attr "predicable" "yes")
1219 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1220 (const_string "alu_shift_imm")
1221 (const_string "alu_shift_reg")))]
1224 (define_insn "*rsbsi3_carryin_shift"
1225 [(set (match_operand:SI 0 "s_register_operand" "=r")
1227 (match_operator:SI 2 "shift_operator"
1228 [(match_operand:SI 3 "s_register_operand" "r")
1229 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1230 (match_operand:SI 1 "s_register_operand" "r"))
1231 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1233 "rsc%?\\t%0, %1, %3%S2"
1234 [(set_attr "conds" "use")
1235 (set_attr "predicable" "yes")
1236 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1237 (const_string "alu_shift_imm")
1238 (const_string "alu_shift_reg")))]
1241 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1243 [(set (match_operand:SI 0 "s_register_operand" "")
1244 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1245 (match_operand:SI 2 "s_register_operand" ""))
1247 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1249 [(set (match_dup 3) (match_dup 1))
1250 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1252 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1255 (define_expand "addsf3"
1256 [(set (match_operand:SF 0 "s_register_operand" "")
1257 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1258 (match_operand:SF 2 "s_register_operand" "")))]
1259 "TARGET_32BIT && TARGET_HARD_FLOAT"
1263 (define_expand "adddf3"
1264 [(set (match_operand:DF 0 "s_register_operand" "")
1265 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1266 (match_operand:DF 2 "s_register_operand" "")))]
1267 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1271 (define_expand "subdi3"
1273 [(set (match_operand:DI 0 "s_register_operand" "")
1274 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1275 (match_operand:DI 2 "s_register_operand" "")))
1276 (clobber (reg:CC CC_REGNUM))])]
1281 if (!REG_P (operands[1]))
1282 operands[1] = force_reg (DImode, operands[1]);
1283 if (!REG_P (operands[2]))
1284 operands[2] = force_reg (DImode, operands[2]);
1289 (define_insn_and_split "*arm_subdi3"
1290 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
1291 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1292 (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1293 (clobber (reg:CC CC_REGNUM))]
1294 "TARGET_32BIT && !TARGET_NEON"
1295 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1296 "&& (!TARGET_IWMMXT || reload_completed)"
1297 [(parallel [(set (reg:CC CC_REGNUM)
1298 (compare:CC (match_dup 1) (match_dup 2)))
1299 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1300 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1301 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1303 operands[3] = gen_highpart (SImode, operands[0]);
1304 operands[0] = gen_lowpart (SImode, operands[0]);
1305 operands[4] = gen_highpart (SImode, operands[1]);
1306 operands[1] = gen_lowpart (SImode, operands[1]);
1307 operands[5] = gen_highpart (SImode, operands[2]);
1308 operands[2] = gen_lowpart (SImode, operands[2]);
1310 [(set_attr "conds" "clob")
1311 (set_attr "length" "8")
1312 (set_attr "type" "multiple")]
1315 (define_insn_and_split "*subdi_di_zesidi"
1316 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1317 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1319 (match_operand:SI 2 "s_register_operand" "r,r"))))
1320 (clobber (reg:CC CC_REGNUM))]
1322 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1323 "&& reload_completed"
1324 [(parallel [(set (reg:CC CC_REGNUM)
1325 (compare:CC (match_dup 1) (match_dup 2)))
1326 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1327 (set (match_dup 3) (minus:SI (match_dup 4)
1328 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1330 operands[3] = gen_highpart (SImode, operands[0]);
1331 operands[0] = gen_lowpart (SImode, operands[0]);
1332 operands[4] = gen_highpart (SImode, operands[1]);
1333 operands[1] = gen_lowpart (SImode, operands[1]);
1335 [(set_attr "conds" "clob")
1336 (set_attr "length" "8")
1337 (set_attr "type" "multiple")]
1340 (define_insn_and_split "*subdi_di_sesidi"
1341 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1342 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1344 (match_operand:SI 2 "s_register_operand" "r,r"))))
1345 (clobber (reg:CC CC_REGNUM))]
1347 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1348 "&& reload_completed"
1349 [(parallel [(set (reg:CC CC_REGNUM)
1350 (compare:CC (match_dup 1) (match_dup 2)))
1351 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1352 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1353 (ashiftrt:SI (match_dup 2)
1355 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1357 operands[3] = gen_highpart (SImode, operands[0]);
1358 operands[0] = gen_lowpart (SImode, operands[0]);
1359 operands[4] = gen_highpart (SImode, operands[1]);
1360 operands[1] = gen_lowpart (SImode, operands[1]);
1362 [(set_attr "conds" "clob")
1363 (set_attr "length" "8")
1364 (set_attr "type" "multiple")]
1367 (define_insn_and_split "*subdi_zesidi_di"
1368 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1369 (minus:DI (zero_extend:DI
1370 (match_operand:SI 2 "s_register_operand" "r,r"))
1371 (match_operand:DI 1 "s_register_operand" "0,r")))
1372 (clobber (reg:CC CC_REGNUM))]
1374 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1376 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1377 "&& reload_completed"
1378 [(parallel [(set (reg:CC CC_REGNUM)
1379 (compare:CC (match_dup 2) (match_dup 1)))
1380 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1381 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1382 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1384 operands[3] = gen_highpart (SImode, operands[0]);
1385 operands[0] = gen_lowpart (SImode, operands[0]);
1386 operands[4] = gen_highpart (SImode, operands[1]);
1387 operands[1] = gen_lowpart (SImode, operands[1]);
1389 [(set_attr "conds" "clob")
1390 (set_attr "length" "8")
1391 (set_attr "type" "multiple")]
1394 (define_insn_and_split "*subdi_sesidi_di"
1395 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1396 (minus:DI (sign_extend:DI
1397 (match_operand:SI 2 "s_register_operand" "r,r"))
1398 (match_operand:DI 1 "s_register_operand" "0,r")))
1399 (clobber (reg:CC CC_REGNUM))]
1401 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1403 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1404 "&& reload_completed"
1405 [(parallel [(set (reg:CC CC_REGNUM)
1406 (compare:CC (match_dup 2) (match_dup 1)))
1407 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1408 (set (match_dup 3) (minus:SI (minus:SI
1409 (ashiftrt:SI (match_dup 2)
1412 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1414 operands[3] = gen_highpart (SImode, operands[0]);
1415 operands[0] = gen_lowpart (SImode, operands[0]);
1416 operands[4] = gen_highpart (SImode, operands[1]);
1417 operands[1] = gen_lowpart (SImode, operands[1]);
1419 [(set_attr "conds" "clob")
1420 (set_attr "length" "8")
1421 (set_attr "type" "multiple")]
1424 (define_insn_and_split "*subdi_zesidi_zesidi"
1425 [(set (match_operand:DI 0 "s_register_operand" "=r")
1426 (minus:DI (zero_extend:DI
1427 (match_operand:SI 1 "s_register_operand" "r"))
1429 (match_operand:SI 2 "s_register_operand" "r"))))
1430 (clobber (reg:CC CC_REGNUM))]
1432 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1433 "&& reload_completed"
1434 [(parallel [(set (reg:CC CC_REGNUM)
1435 (compare:CC (match_dup 1) (match_dup 2)))
1436 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1437 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1438 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1440 operands[3] = gen_highpart (SImode, operands[0]);
1441 operands[0] = gen_lowpart (SImode, operands[0]);
1443 [(set_attr "conds" "clob")
1444 (set_attr "length" "8")
1445 (set_attr "type" "multiple")]
1448 (define_expand "subsi3"
1449 [(set (match_operand:SI 0 "s_register_operand" "")
1450 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1451 (match_operand:SI 2 "s_register_operand" "")))]
1454 if (CONST_INT_P (operands[1]))
1458 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1459 operands[1] = force_reg (SImode, operands[1]);
1462 arm_split_constant (MINUS, SImode, NULL_RTX,
1463 INTVAL (operands[1]), operands[0],
1465 optimize && can_create_pseudo_p ());
1469 else /* TARGET_THUMB1 */
1470 operands[1] = force_reg (SImode, operands[1]);
1475 ; ??? Check Thumb-2 split length
1476 (define_insn_and_split "*arm_subsi3_insn"
1477 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1478 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1479 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1491 "&& (CONST_INT_P (operands[1])
1492 && !const_ok_for_arm (INTVAL (operands[1])))"
1493 [(clobber (const_int 0))]
1495 arm_split_constant (MINUS, SImode, curr_insn,
1496 INTVAL (operands[1]), operands[0], operands[2], 0);
1499 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1500 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1501 (set_attr "predicable" "yes")
1502 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1503 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1507 [(match_scratch:SI 3 "r")
1508 (set (match_operand:SI 0 "arm_general_register_operand" "")
1509 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1510 (match_operand:SI 2 "arm_general_register_operand" "")))]
1512 && !const_ok_for_arm (INTVAL (operands[1]))
1513 && const_ok_for_arm (~INTVAL (operands[1]))"
1514 [(set (match_dup 3) (match_dup 1))
1515 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1519 (define_insn "subsi3_compare0"
1520 [(set (reg:CC_NOOV CC_REGNUM)
1522 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1523 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1525 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1526 (minus:SI (match_dup 1) (match_dup 2)))]
1531 rsbs%?\\t%0, %2, %1"
1532 [(set_attr "conds" "set")
1533 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1536 (define_insn "subsi3_compare"
1537 [(set (reg:CC CC_REGNUM)
1538 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1539 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1540 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1541 (minus:SI (match_dup 1) (match_dup 2)))]
1546 rsbs%?\\t%0, %2, %1"
1547 [(set_attr "conds" "set")
1548 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1551 (define_expand "subsf3"
1552 [(set (match_operand:SF 0 "s_register_operand" "")
1553 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1554 (match_operand:SF 2 "s_register_operand" "")))]
1555 "TARGET_32BIT && TARGET_HARD_FLOAT"
1559 (define_expand "subdf3"
1560 [(set (match_operand:DF 0 "s_register_operand" "")
1561 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1562 (match_operand:DF 2 "s_register_operand" "")))]
1563 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1568 ;; Multiplication insns
1570 (define_expand "mulhi3"
1571 [(set (match_operand:HI 0 "s_register_operand" "")
1572 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1573 (match_operand:HI 2 "s_register_operand" "")))]
1574 "TARGET_DSP_MULTIPLY"
1577 rtx result = gen_reg_rtx (SImode);
1578 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1579 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1584 (define_expand "mulsi3"
1585 [(set (match_operand:SI 0 "s_register_operand" "")
1586 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1587 (match_operand:SI 1 "s_register_operand" "")))]
1592 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1593 (define_insn "*arm_mulsi3"
1594 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1595 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1596 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1597 "TARGET_32BIT && !arm_arch6"
1598 "mul%?\\t%0, %2, %1"
1599 [(set_attr "type" "mul")
1600 (set_attr "predicable" "yes")]
1603 (define_insn "*arm_mulsi3_v6"
1604 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1605 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1606 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1607 "TARGET_32BIT && arm_arch6"
1608 "mul%?\\t%0, %1, %2"
1609 [(set_attr "type" "mul")
1610 (set_attr "predicable" "yes")
1611 (set_attr "arch" "t2,t2,*")
1612 (set_attr "length" "4")
1613 (set_attr "predicable_short_it" "yes,yes,no")]
1616 (define_insn "*mulsi3_compare0"
1617 [(set (reg:CC_NOOV CC_REGNUM)
1618 (compare:CC_NOOV (mult:SI
1619 (match_operand:SI 2 "s_register_operand" "r,r")
1620 (match_operand:SI 1 "s_register_operand" "%0,r"))
1622 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1623 (mult:SI (match_dup 2) (match_dup 1)))]
1624 "TARGET_ARM && !arm_arch6"
1625 "muls%?\\t%0, %2, %1"
1626 [(set_attr "conds" "set")
1627 (set_attr "type" "muls")]
1630 (define_insn "*mulsi3_compare0_v6"
1631 [(set (reg:CC_NOOV CC_REGNUM)
1632 (compare:CC_NOOV (mult:SI
1633 (match_operand:SI 2 "s_register_operand" "r")
1634 (match_operand:SI 1 "s_register_operand" "r"))
1636 (set (match_operand:SI 0 "s_register_operand" "=r")
1637 (mult:SI (match_dup 2) (match_dup 1)))]
1638 "TARGET_ARM && arm_arch6 && optimize_size"
1639 "muls%?\\t%0, %2, %1"
1640 [(set_attr "conds" "set")
1641 (set_attr "type" "muls")]
1644 (define_insn "*mulsi_compare0_scratch"
1645 [(set (reg:CC_NOOV CC_REGNUM)
1646 (compare:CC_NOOV (mult:SI
1647 (match_operand:SI 2 "s_register_operand" "r,r")
1648 (match_operand:SI 1 "s_register_operand" "%0,r"))
1650 (clobber (match_scratch:SI 0 "=&r,&r"))]
1651 "TARGET_ARM && !arm_arch6"
1652 "muls%?\\t%0, %2, %1"
1653 [(set_attr "conds" "set")
1654 (set_attr "type" "muls")]
1657 (define_insn "*mulsi_compare0_scratch_v6"
1658 [(set (reg:CC_NOOV CC_REGNUM)
1659 (compare:CC_NOOV (mult:SI
1660 (match_operand:SI 2 "s_register_operand" "r")
1661 (match_operand:SI 1 "s_register_operand" "r"))
1663 (clobber (match_scratch:SI 0 "=r"))]
1664 "TARGET_ARM && arm_arch6 && optimize_size"
1665 "muls%?\\t%0, %2, %1"
1666 [(set_attr "conds" "set")
1667 (set_attr "type" "muls")]
1670 ;; Unnamed templates to match MLA instruction.
1672 (define_insn "*mulsi3addsi"
1673 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1675 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1676 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1677 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1678 "TARGET_32BIT && !arm_arch6"
1679 "mla%?\\t%0, %2, %1, %3"
1680 [(set_attr "type" "mla")
1681 (set_attr "predicable" "yes")]
1684 (define_insn "*mulsi3addsi_v6"
1685 [(set (match_operand:SI 0 "s_register_operand" "=r")
1687 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1688 (match_operand:SI 1 "s_register_operand" "r"))
1689 (match_operand:SI 3 "s_register_operand" "r")))]
1690 "TARGET_32BIT && arm_arch6"
1691 "mla%?\\t%0, %2, %1, %3"
1692 [(set_attr "type" "mla")
1693 (set_attr "predicable" "yes")]
1696 (define_insn "*mulsi3addsi_compare0"
1697 [(set (reg:CC_NOOV CC_REGNUM)
1700 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1701 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1702 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1704 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1705 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1707 "TARGET_ARM && arm_arch6"
1708 "mlas%?\\t%0, %2, %1, %3"
1709 [(set_attr "conds" "set")
1710 (set_attr "type" "mlas")]
1713 (define_insn "*mulsi3addsi_compare0_v6"
1714 [(set (reg:CC_NOOV CC_REGNUM)
1717 (match_operand:SI 2 "s_register_operand" "r")
1718 (match_operand:SI 1 "s_register_operand" "r"))
1719 (match_operand:SI 3 "s_register_operand" "r"))
1721 (set (match_operand:SI 0 "s_register_operand" "=r")
1722 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1724 "TARGET_ARM && arm_arch6 && optimize_size"
1725 "mlas%?\\t%0, %2, %1, %3"
1726 [(set_attr "conds" "set")
1727 (set_attr "type" "mlas")]
1730 (define_insn "*mulsi3addsi_compare0_scratch"
1731 [(set (reg:CC_NOOV CC_REGNUM)
1734 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1735 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1736 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1738 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1739 "TARGET_ARM && !arm_arch6"
1740 "mlas%?\\t%0, %2, %1, %3"
1741 [(set_attr "conds" "set")
1742 (set_attr "type" "mlas")]
1745 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1746 [(set (reg:CC_NOOV CC_REGNUM)
1749 (match_operand:SI 2 "s_register_operand" "r")
1750 (match_operand:SI 1 "s_register_operand" "r"))
1751 (match_operand:SI 3 "s_register_operand" "r"))
1753 (clobber (match_scratch:SI 0 "=r"))]
1754 "TARGET_ARM && arm_arch6 && optimize_size"
1755 "mlas%?\\t%0, %2, %1, %3"
1756 [(set_attr "conds" "set")
1757 (set_attr "type" "mlas")]
1760 (define_insn "*mulsi3subsi"
1761 [(set (match_operand:SI 0 "s_register_operand" "=r")
1763 (match_operand:SI 3 "s_register_operand" "r")
1764 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1765 (match_operand:SI 1 "s_register_operand" "r"))))]
1766 "TARGET_32BIT && arm_arch_thumb2"
1767 "mls%?\\t%0, %2, %1, %3"
1768 [(set_attr "type" "mla")
1769 (set_attr "predicable" "yes")]
1772 (define_expand "maddsidi4"
1773 [(set (match_operand:DI 0 "s_register_operand" "")
1776 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1777 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1778 (match_operand:DI 3 "s_register_operand" "")))]
1782 (define_insn "*mulsidi3adddi"
1783 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1786 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1787 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1788 (match_operand:DI 1 "s_register_operand" "0")))]
1789 "TARGET_32BIT && !arm_arch6"
1790 "smlal%?\\t%Q0, %R0, %3, %2"
1791 [(set_attr "type" "smlal")
1792 (set_attr "predicable" "yes")]
1795 (define_insn "*mulsidi3adddi_v6"
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 ;; 32x32->64 widening multiply.
1809 ;; As with mulsi3, the only difference between the v3-5 and v6+
1810 ;; versions of these patterns is the requirement that the output not
1811 ;; overlap the inputs, but that still means we have to have a named
1812 ;; expander and two different starred insns.
1814 (define_expand "mulsidi3"
1815 [(set (match_operand:DI 0 "s_register_operand" "")
1817 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1818 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1823 (define_insn "*mulsidi3_nov6"
1824 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1826 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1827 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1828 "TARGET_32BIT && !arm_arch6"
1829 "smull%?\\t%Q0, %R0, %1, %2"
1830 [(set_attr "type" "smull")
1831 (set_attr "predicable" "yes")]
1834 (define_insn "*mulsidi3_v6"
1835 [(set (match_operand:DI 0 "s_register_operand" "=r")
1837 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1838 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1839 "TARGET_32BIT && arm_arch6"
1840 "smull%?\\t%Q0, %R0, %1, %2"
1841 [(set_attr "type" "smull")
1842 (set_attr "predicable" "yes")]
1845 (define_expand "umulsidi3"
1846 [(set (match_operand:DI 0 "s_register_operand" "")
1848 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1849 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1854 (define_insn "*umulsidi3_nov6"
1855 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1857 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1858 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1859 "TARGET_32BIT && !arm_arch6"
1860 "umull%?\\t%Q0, %R0, %1, %2"
1861 [(set_attr "type" "umull")
1862 (set_attr "predicable" "yes")]
1865 (define_insn "*umulsidi3_v6"
1866 [(set (match_operand:DI 0 "s_register_operand" "=r")
1868 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1869 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1870 "TARGET_32BIT && arm_arch6"
1871 "umull%?\\t%Q0, %R0, %1, %2"
1872 [(set_attr "type" "umull")
1873 (set_attr "predicable" "yes")]
1876 (define_expand "umaddsidi4"
1877 [(set (match_operand:DI 0 "s_register_operand" "")
1880 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1881 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1882 (match_operand:DI 3 "s_register_operand" "")))]
1886 (define_insn "*umulsidi3adddi"
1887 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1890 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1891 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1892 (match_operand:DI 1 "s_register_operand" "0")))]
1893 "TARGET_32BIT && !arm_arch6"
1894 "umlal%?\\t%Q0, %R0, %3, %2"
1895 [(set_attr "type" "umlal")
1896 (set_attr "predicable" "yes")]
1899 (define_insn "*umulsidi3adddi_v6"
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_expand "smulsi3_highpart"
1914 [(set (match_operand:SI 0 "s_register_operand" "")
1918 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1919 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1921 (clobber (match_scratch:SI 3 ""))])]
1926 (define_insn "*smulsi3_highpart_nov6"
1927 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1931 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1932 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1934 (clobber (match_scratch:SI 3 "=&r,&r"))]
1935 "TARGET_32BIT && !arm_arch6"
1936 "smull%?\\t%3, %0, %2, %1"
1937 [(set_attr "type" "smull")
1938 (set_attr "predicable" "yes")]
1941 (define_insn "*smulsi3_highpart_v6"
1942 [(set (match_operand:SI 0 "s_register_operand" "=r")
1946 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1947 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1949 (clobber (match_scratch:SI 3 "=r"))]
1950 "TARGET_32BIT && arm_arch6"
1951 "smull%?\\t%3, %0, %2, %1"
1952 [(set_attr "type" "smull")
1953 (set_attr "predicable" "yes")]
1956 (define_expand "umulsi3_highpart"
1958 [(set (match_operand:SI 0 "s_register_operand" "")
1962 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1963 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1965 (clobber (match_scratch:SI 3 ""))])]
1970 (define_insn "*umulsi3_highpart_nov6"
1971 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1975 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1976 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1978 (clobber (match_scratch:SI 3 "=&r,&r"))]
1979 "TARGET_32BIT && !arm_arch6"
1980 "umull%?\\t%3, %0, %2, %1"
1981 [(set_attr "type" "umull")
1982 (set_attr "predicable" "yes")]
1985 (define_insn "*umulsi3_highpart_v6"
1986 [(set (match_operand:SI 0 "s_register_operand" "=r")
1990 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1991 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1993 (clobber (match_scratch:SI 3 "=r"))]
1994 "TARGET_32BIT && arm_arch6"
1995 "umull%?\\t%3, %0, %2, %1"
1996 [(set_attr "type" "umull")
1997 (set_attr "predicable" "yes")]
2000 (define_insn "mulhisi3"
2001 [(set (match_operand:SI 0 "s_register_operand" "=r")
2002 (mult:SI (sign_extend:SI
2003 (match_operand:HI 1 "s_register_operand" "%r"))
2005 (match_operand:HI 2 "s_register_operand" "r"))))]
2006 "TARGET_DSP_MULTIPLY"
2007 "smulbb%?\\t%0, %1, %2"
2008 [(set_attr "type" "smulxy")
2009 (set_attr "predicable" "yes")]
2012 (define_insn "*mulhisi3tb"
2013 [(set (match_operand:SI 0 "s_register_operand" "=r")
2014 (mult:SI (ashiftrt:SI
2015 (match_operand:SI 1 "s_register_operand" "r")
2018 (match_operand:HI 2 "s_register_operand" "r"))))]
2019 "TARGET_DSP_MULTIPLY"
2020 "smultb%?\\t%0, %1, %2"
2021 [(set_attr "type" "smulxy")
2022 (set_attr "predicable" "yes")]
2025 (define_insn "*mulhisi3bt"
2026 [(set (match_operand:SI 0 "s_register_operand" "=r")
2027 (mult:SI (sign_extend:SI
2028 (match_operand:HI 1 "s_register_operand" "r"))
2030 (match_operand:SI 2 "s_register_operand" "r")
2032 "TARGET_DSP_MULTIPLY"
2033 "smulbt%?\\t%0, %1, %2"
2034 [(set_attr "type" "smulxy")
2035 (set_attr "predicable" "yes")]
2038 (define_insn "*mulhisi3tt"
2039 [(set (match_operand:SI 0 "s_register_operand" "=r")
2040 (mult:SI (ashiftrt:SI
2041 (match_operand:SI 1 "s_register_operand" "r")
2044 (match_operand:SI 2 "s_register_operand" "r")
2046 "TARGET_DSP_MULTIPLY"
2047 "smultt%?\\t%0, %1, %2"
2048 [(set_attr "type" "smulxy")
2049 (set_attr "predicable" "yes")]
2052 (define_insn "maddhisi4"
2053 [(set (match_operand:SI 0 "s_register_operand" "=r")
2054 (plus:SI (mult:SI (sign_extend:SI
2055 (match_operand:HI 1 "s_register_operand" "r"))
2057 (match_operand:HI 2 "s_register_operand" "r")))
2058 (match_operand:SI 3 "s_register_operand" "r")))]
2059 "TARGET_DSP_MULTIPLY"
2060 "smlabb%?\\t%0, %1, %2, %3"
2061 [(set_attr "type" "smlaxy")
2062 (set_attr "predicable" "yes")]
2065 ;; Note: there is no maddhisi4ibt because this one is canonical form
2066 (define_insn "*maddhisi4tb"
2067 [(set (match_operand:SI 0 "s_register_operand" "=r")
2068 (plus:SI (mult:SI (ashiftrt:SI
2069 (match_operand:SI 1 "s_register_operand" "r")
2072 (match_operand:HI 2 "s_register_operand" "r")))
2073 (match_operand:SI 3 "s_register_operand" "r")))]
2074 "TARGET_DSP_MULTIPLY"
2075 "smlatb%?\\t%0, %1, %2, %3"
2076 [(set_attr "type" "smlaxy")
2077 (set_attr "predicable" "yes")]
2080 (define_insn "*maddhisi4tt"
2081 [(set (match_operand:SI 0 "s_register_operand" "=r")
2082 (plus:SI (mult:SI (ashiftrt:SI
2083 (match_operand:SI 1 "s_register_operand" "r")
2086 (match_operand:SI 2 "s_register_operand" "r")
2088 (match_operand:SI 3 "s_register_operand" "r")))]
2089 "TARGET_DSP_MULTIPLY"
2090 "smlatt%?\\t%0, %1, %2, %3"
2091 [(set_attr "type" "smlaxy")
2092 (set_attr "predicable" "yes")]
2095 (define_insn "maddhidi4"
2096 [(set (match_operand:DI 0 "s_register_operand" "=r")
2098 (mult:DI (sign_extend:DI
2099 (match_operand:HI 1 "s_register_operand" "r"))
2101 (match_operand:HI 2 "s_register_operand" "r")))
2102 (match_operand:DI 3 "s_register_operand" "0")))]
2103 "TARGET_DSP_MULTIPLY"
2104 "smlalbb%?\\t%Q0, %R0, %1, %2"
2105 [(set_attr "type" "smlalxy")
2106 (set_attr "predicable" "yes")])
2108 ;; Note: there is no maddhidi4ibt because this one is canonical form
2109 (define_insn "*maddhidi4tb"
2110 [(set (match_operand:DI 0 "s_register_operand" "=r")
2112 (mult:DI (sign_extend:DI
2114 (match_operand:SI 1 "s_register_operand" "r")
2117 (match_operand:HI 2 "s_register_operand" "r")))
2118 (match_operand:DI 3 "s_register_operand" "0")))]
2119 "TARGET_DSP_MULTIPLY"
2120 "smlaltb%?\\t%Q0, %R0, %1, %2"
2121 [(set_attr "type" "smlalxy")
2122 (set_attr "predicable" "yes")])
2124 (define_insn "*maddhidi4tt"
2125 [(set (match_operand:DI 0 "s_register_operand" "=r")
2127 (mult:DI (sign_extend:DI
2129 (match_operand:SI 1 "s_register_operand" "r")
2133 (match_operand:SI 2 "s_register_operand" "r")
2135 (match_operand:DI 3 "s_register_operand" "0")))]
2136 "TARGET_DSP_MULTIPLY"
2137 "smlaltt%?\\t%Q0, %R0, %1, %2"
2138 [(set_attr "type" "smlalxy")
2139 (set_attr "predicable" "yes")])
2141 (define_expand "mulsf3"
2142 [(set (match_operand:SF 0 "s_register_operand" "")
2143 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2144 (match_operand:SF 2 "s_register_operand" "")))]
2145 "TARGET_32BIT && TARGET_HARD_FLOAT"
2149 (define_expand "muldf3"
2150 [(set (match_operand:DF 0 "s_register_operand" "")
2151 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2152 (match_operand:DF 2 "s_register_operand" "")))]
2153 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2159 (define_expand "divsf3"
2160 [(set (match_operand:SF 0 "s_register_operand" "")
2161 (div:SF (match_operand:SF 1 "s_register_operand" "")
2162 (match_operand:SF 2 "s_register_operand" "")))]
2163 "TARGET_32BIT && TARGET_HARD_FLOAT"
2166 (define_expand "divdf3"
2167 [(set (match_operand:DF 0 "s_register_operand" "")
2168 (div:DF (match_operand:DF 1 "s_register_operand" "")
2169 (match_operand:DF 2 "s_register_operand" "")))]
2170 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2173 ;; Boolean and,ior,xor insns
2175 ;; Split up double word logical operations
2177 ;; Split up simple DImode logical operations. Simply perform the logical
2178 ;; operation on the upper and lower halves of the registers.
2180 [(set (match_operand:DI 0 "s_register_operand" "")
2181 (match_operator:DI 6 "logical_binary_operator"
2182 [(match_operand:DI 1 "s_register_operand" "")
2183 (match_operand:DI 2 "s_register_operand" "")]))]
2184 "TARGET_32BIT && reload_completed
2185 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2186 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2187 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2188 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2191 operands[3] = gen_highpart (SImode, operands[0]);
2192 operands[0] = gen_lowpart (SImode, operands[0]);
2193 operands[4] = gen_highpart (SImode, operands[1]);
2194 operands[1] = gen_lowpart (SImode, operands[1]);
2195 operands[5] = gen_highpart (SImode, operands[2]);
2196 operands[2] = gen_lowpart (SImode, operands[2]);
2201 [(set (match_operand:DI 0 "s_register_operand" "")
2202 (match_operator:DI 6 "logical_binary_operator"
2203 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2204 (match_operand:DI 1 "s_register_operand" "")]))]
2205 "TARGET_32BIT && reload_completed"
2206 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2207 (set (match_dup 3) (match_op_dup:SI 6
2208 [(ashiftrt:SI (match_dup 2) (const_int 31))
2212 operands[3] = gen_highpart (SImode, operands[0]);
2213 operands[0] = gen_lowpart (SImode, operands[0]);
2214 operands[4] = gen_highpart (SImode, operands[1]);
2215 operands[1] = gen_lowpart (SImode, operands[1]);
2216 operands[5] = gen_highpart (SImode, operands[2]);
2217 operands[2] = gen_lowpart (SImode, operands[2]);
2221 ;; The zero extend of operand 2 means we can just copy the high part of
2222 ;; operand1 into operand0.
2224 [(set (match_operand:DI 0 "s_register_operand" "")
2226 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2227 (match_operand:DI 1 "s_register_operand" "")))]
2228 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2229 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2230 (set (match_dup 3) (match_dup 4))]
2233 operands[4] = gen_highpart (SImode, operands[1]);
2234 operands[3] = gen_highpart (SImode, operands[0]);
2235 operands[0] = gen_lowpart (SImode, operands[0]);
2236 operands[1] = gen_lowpart (SImode, operands[1]);
2240 ;; The zero extend of operand 2 means we can just copy the high part of
2241 ;; operand1 into operand0.
2243 [(set (match_operand:DI 0 "s_register_operand" "")
2245 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2246 (match_operand:DI 1 "s_register_operand" "")))]
2247 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2248 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2249 (set (match_dup 3) (match_dup 4))]
2252 operands[4] = gen_highpart (SImode, operands[1]);
2253 operands[3] = gen_highpart (SImode, operands[0]);
2254 operands[0] = gen_lowpart (SImode, operands[0]);
2255 operands[1] = gen_lowpart (SImode, operands[1]);
2259 (define_expand "anddi3"
2260 [(set (match_operand:DI 0 "s_register_operand" "")
2261 (and:DI (match_operand:DI 1 "s_register_operand" "")
2262 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2265 if (!TARGET_NEON && !TARGET_IWMMXT)
2267 rtx low = simplify_gen_binary (AND, SImode,
2268 gen_lowpart (SImode, operands[1]),
2269 gen_lowpart (SImode, operands[2]));
2270 rtx high = simplify_gen_binary (AND, SImode,
2271 gen_highpart (SImode, operands[1]),
2272 gen_highpart_mode (SImode, DImode,
2275 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2276 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2280 /* Otherwise expand pattern as above. */
2284 (define_insn_and_split "*anddi3_insn"
2285 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2286 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2287 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2288 "TARGET_32BIT && !TARGET_IWMMXT"
2290 switch (which_alternative)
2292 case 0: /* fall through */
2293 case 6: return "vand\t%P0, %P1, %P2";
2294 case 1: /* fall through */
2295 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2296 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2300 case 5: /* fall through */
2302 default: gcc_unreachable ();
2305 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2306 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2307 [(set (match_dup 3) (match_dup 4))
2308 (set (match_dup 5) (match_dup 6))]
2311 operands[3] = gen_lowpart (SImode, operands[0]);
2312 operands[5] = gen_highpart (SImode, operands[0]);
2314 operands[4] = simplify_gen_binary (AND, SImode,
2315 gen_lowpart (SImode, operands[1]),
2316 gen_lowpart (SImode, operands[2]));
2317 operands[6] = simplify_gen_binary (AND, SImode,
2318 gen_highpart (SImode, operands[1]),
2319 gen_highpart_mode (SImode, DImode, operands[2]));
2322 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2323 multiple,multiple,neon_logic,neon_logic")
2324 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2325 avoid_neon_for_64bits,avoid_neon_for_64bits")
2326 (set_attr "length" "*,*,8,8,8,8,*,*")
2330 (define_insn_and_split "*anddi_zesidi_di"
2331 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2332 (and:DI (zero_extend:DI
2333 (match_operand:SI 2 "s_register_operand" "r,r"))
2334 (match_operand:DI 1 "s_register_operand" "0,r")))]
2337 "TARGET_32BIT && reload_completed"
2338 ; The zero extend of operand 2 clears the high word of the output
2340 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2341 (set (match_dup 3) (const_int 0))]
2344 operands[3] = gen_highpart (SImode, operands[0]);
2345 operands[0] = gen_lowpart (SImode, operands[0]);
2346 operands[1] = gen_lowpart (SImode, operands[1]);
2348 [(set_attr "length" "8")
2349 (set_attr "type" "multiple")]
2352 (define_insn "*anddi_sesdi_di"
2353 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2354 (and:DI (sign_extend:DI
2355 (match_operand:SI 2 "s_register_operand" "r,r"))
2356 (match_operand:DI 1 "s_register_operand" "0,r")))]
2359 [(set_attr "length" "8")
2360 (set_attr "type" "multiple")]
2363 (define_expand "andsi3"
2364 [(set (match_operand:SI 0 "s_register_operand" "")
2365 (and:SI (match_operand:SI 1 "s_register_operand" "")
2366 (match_operand:SI 2 "reg_or_int_operand" "")))]
2371 if (CONST_INT_P (operands[2]))
2373 if (INTVAL (operands[2]) == 255 && arm_arch6)
2375 operands[1] = convert_to_mode (QImode, operands[1], 1);
2376 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2380 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2381 operands[2] = force_reg (SImode, operands[2]);
2384 arm_split_constant (AND, SImode, NULL_RTX,
2385 INTVAL (operands[2]), operands[0],
2387 optimize && can_create_pseudo_p ());
2393 else /* TARGET_THUMB1 */
2395 if (!CONST_INT_P (operands[2]))
2397 rtx tmp = force_reg (SImode, operands[2]);
2398 if (rtx_equal_p (operands[0], operands[1]))
2402 operands[2] = operands[1];
2410 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2412 operands[2] = force_reg (SImode,
2413 GEN_INT (~INTVAL (operands[2])));
2415 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2420 for (i = 9; i <= 31; i++)
2422 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2424 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2428 else if ((HOST_WIDE_INT_1 << i) - 1
2429 == ~INTVAL (operands[2]))
2431 rtx shift = GEN_INT (i);
2432 rtx reg = gen_reg_rtx (SImode);
2434 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2435 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2441 operands[2] = force_reg (SImode, operands[2]);
2447 ; ??? Check split length for Thumb-2
2448 (define_insn_and_split "*arm_andsi3_insn"
2449 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2450 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2451 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2456 bic%?\\t%0, %1, #%B2
2460 && CONST_INT_P (operands[2])
2461 && !(const_ok_for_arm (INTVAL (operands[2]))
2462 || const_ok_for_arm (~INTVAL (operands[2])))"
2463 [(clobber (const_int 0))]
2465 arm_split_constant (AND, SImode, curr_insn,
2466 INTVAL (operands[2]), operands[0], operands[1], 0);
2469 [(set_attr "length" "4,4,4,4,16")
2470 (set_attr "predicable" "yes")
2471 (set_attr "predicable_short_it" "no,yes,no,no,no")
2472 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2475 (define_insn "*andsi3_compare0"
2476 [(set (reg:CC_NOOV CC_REGNUM)
2478 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2479 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2481 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2482 (and:SI (match_dup 1) (match_dup 2)))]
2486 bics%?\\t%0, %1, #%B2
2487 ands%?\\t%0, %1, %2"
2488 [(set_attr "conds" "set")
2489 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2492 (define_insn "*andsi3_compare0_scratch"
2493 [(set (reg:CC_NOOV CC_REGNUM)
2495 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2496 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2498 (clobber (match_scratch:SI 2 "=X,r,X"))]
2502 bics%?\\t%2, %0, #%B1
2504 [(set_attr "conds" "set")
2505 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2508 (define_insn "*zeroextractsi_compare0_scratch"
2509 [(set (reg:CC_NOOV CC_REGNUM)
2510 (compare:CC_NOOV (zero_extract:SI
2511 (match_operand:SI 0 "s_register_operand" "r")
2512 (match_operand 1 "const_int_operand" "n")
2513 (match_operand 2 "const_int_operand" "n"))
2516 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2517 && INTVAL (operands[1]) > 0
2518 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2519 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2521 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2522 << INTVAL (operands[2]));
2523 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2526 [(set_attr "conds" "set")
2527 (set_attr "predicable" "yes")
2528 (set_attr "type" "logics_imm")]
2531 (define_insn_and_split "*ne_zeroextractsi"
2532 [(set (match_operand:SI 0 "s_register_operand" "=r")
2533 (ne:SI (zero_extract:SI
2534 (match_operand:SI 1 "s_register_operand" "r")
2535 (match_operand:SI 2 "const_int_operand" "n")
2536 (match_operand:SI 3 "const_int_operand" "n"))
2538 (clobber (reg:CC CC_REGNUM))]
2540 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2541 && INTVAL (operands[2]) > 0
2542 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2543 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2546 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2547 && INTVAL (operands[2]) > 0
2548 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2549 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2550 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2551 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2553 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2555 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2556 (match_dup 0) (const_int 1)))]
2558 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2559 << INTVAL (operands[3]));
2561 [(set_attr "conds" "clob")
2562 (set (attr "length")
2563 (if_then_else (eq_attr "is_thumb" "yes")
2566 (set_attr "type" "multiple")]
2569 (define_insn_and_split "*ne_zeroextractsi_shifted"
2570 [(set (match_operand:SI 0 "s_register_operand" "=r")
2571 (ne:SI (zero_extract:SI
2572 (match_operand:SI 1 "s_register_operand" "r")
2573 (match_operand:SI 2 "const_int_operand" "n")
2576 (clobber (reg:CC CC_REGNUM))]
2580 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2581 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2583 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2585 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2586 (match_dup 0) (const_int 1)))]
2588 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2590 [(set_attr "conds" "clob")
2591 (set_attr "length" "8")
2592 (set_attr "type" "multiple")]
2595 (define_insn_and_split "*ite_ne_zeroextractsi"
2596 [(set (match_operand:SI 0 "s_register_operand" "=r")
2597 (if_then_else:SI (ne (zero_extract:SI
2598 (match_operand:SI 1 "s_register_operand" "r")
2599 (match_operand:SI 2 "const_int_operand" "n")
2600 (match_operand:SI 3 "const_int_operand" "n"))
2602 (match_operand:SI 4 "arm_not_operand" "rIK")
2604 (clobber (reg:CC CC_REGNUM))]
2606 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2607 && INTVAL (operands[2]) > 0
2608 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2609 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2610 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2613 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2614 && INTVAL (operands[2]) > 0
2615 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2616 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2617 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2618 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2619 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2621 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2623 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2624 (match_dup 0) (match_dup 4)))]
2626 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2627 << INTVAL (operands[3]));
2629 [(set_attr "conds" "clob")
2630 (set_attr "length" "8")
2631 (set_attr "type" "multiple")]
2634 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2635 [(set (match_operand:SI 0 "s_register_operand" "=r")
2636 (if_then_else:SI (ne (zero_extract:SI
2637 (match_operand:SI 1 "s_register_operand" "r")
2638 (match_operand:SI 2 "const_int_operand" "n")
2641 (match_operand:SI 3 "arm_not_operand" "rIK")
2643 (clobber (reg:CC CC_REGNUM))]
2644 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2646 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2647 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2648 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2650 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2652 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2653 (match_dup 0) (match_dup 3)))]
2655 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2657 [(set_attr "conds" "clob")
2658 (set_attr "length" "8")
2659 (set_attr "type" "multiple")]
2662 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2664 [(set (match_operand:SI 0 "s_register_operand" "")
2665 (match_operator:SI 1 "shiftable_operator"
2666 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2667 (match_operand:SI 3 "const_int_operand" "")
2668 (match_operand:SI 4 "const_int_operand" ""))
2669 (match_operand:SI 5 "s_register_operand" "")]))
2670 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2672 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2675 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2678 HOST_WIDE_INT temp = INTVAL (operands[3]);
2680 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2681 operands[4] = GEN_INT (32 - temp);
2686 [(set (match_operand:SI 0 "s_register_operand" "")
2687 (match_operator:SI 1 "shiftable_operator"
2688 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2689 (match_operand:SI 3 "const_int_operand" "")
2690 (match_operand:SI 4 "const_int_operand" ""))
2691 (match_operand:SI 5 "s_register_operand" "")]))
2692 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2694 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2697 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2700 HOST_WIDE_INT temp = INTVAL (operands[3]);
2702 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2703 operands[4] = GEN_INT (32 - temp);
2707 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2708 ;;; represented by the bitfield, then this will produce incorrect results.
2709 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2710 ;;; which have a real bit-field insert instruction, the truncation happens
2711 ;;; in the bit-field insert instruction itself. Since arm does not have a
2712 ;;; bit-field insert instruction, we would have to emit code here to truncate
2713 ;;; the value before we insert. This loses some of the advantage of having
2714 ;;; this insv pattern, so this pattern needs to be reevalutated.
2716 (define_expand "insv"
2717 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2718 (match_operand 1 "general_operand" "")
2719 (match_operand 2 "general_operand" ""))
2720 (match_operand 3 "reg_or_int_operand" ""))]
2721 "TARGET_ARM || arm_arch_thumb2"
2724 int start_bit = INTVAL (operands[2]);
2725 int width = INTVAL (operands[1]);
2726 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2727 rtx target, subtarget;
2729 if (arm_arch_thumb2)
2731 if (unaligned_access && MEM_P (operands[0])
2732 && s_register_operand (operands[3], GET_MODE (operands[3]))
2733 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2737 if (BYTES_BIG_ENDIAN)
2738 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2743 base_addr = adjust_address (operands[0], SImode,
2744 start_bit / BITS_PER_UNIT);
2745 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2749 rtx tmp = gen_reg_rtx (HImode);
2751 base_addr = adjust_address (operands[0], HImode,
2752 start_bit / BITS_PER_UNIT);
2753 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2754 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2758 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2760 bool use_bfi = TRUE;
2762 if (CONST_INT_P (operands[3]))
2764 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2768 emit_insn (gen_insv_zero (operands[0], operands[1],
2773 /* See if the set can be done with a single orr instruction. */
2774 if (val == mask && const_ok_for_arm (val << start_bit))
2780 if (!REG_P (operands[3]))
2781 operands[3] = force_reg (SImode, operands[3]);
2783 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2792 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2795 target = copy_rtx (operands[0]);
2796 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2797 subreg as the final target. */
2798 if (GET_CODE (target) == SUBREG)
2800 subtarget = gen_reg_rtx (SImode);
2801 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2802 < GET_MODE_SIZE (SImode))
2803 target = SUBREG_REG (target);
2808 if (CONST_INT_P (operands[3]))
2810 /* Since we are inserting a known constant, we may be able to
2811 reduce the number of bits that we have to clear so that
2812 the mask becomes simple. */
2813 /* ??? This code does not check to see if the new mask is actually
2814 simpler. It may not be. */
2815 rtx op1 = gen_reg_rtx (SImode);
2816 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2817 start of this pattern. */
2818 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2819 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2821 emit_insn (gen_andsi3 (op1, operands[0],
2822 gen_int_mode (~mask2, SImode)));
2823 emit_insn (gen_iorsi3 (subtarget, op1,
2824 gen_int_mode (op3_value << start_bit, SImode)));
2826 else if (start_bit == 0
2827 && !(const_ok_for_arm (mask)
2828 || const_ok_for_arm (~mask)))
2830 /* A Trick, since we are setting the bottom bits in the word,
2831 we can shift operand[3] up, operand[0] down, OR them together
2832 and rotate the result back again. This takes 3 insns, and
2833 the third might be mergeable into another op. */
2834 /* The shift up copes with the possibility that operand[3] is
2835 wider than the bitfield. */
2836 rtx op0 = gen_reg_rtx (SImode);
2837 rtx op1 = gen_reg_rtx (SImode);
2839 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2840 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2841 emit_insn (gen_iorsi3 (op1, op1, op0));
2842 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2844 else if ((width + start_bit == 32)
2845 && !(const_ok_for_arm (mask)
2846 || const_ok_for_arm (~mask)))
2848 /* Similar trick, but slightly less efficient. */
2850 rtx op0 = gen_reg_rtx (SImode);
2851 rtx op1 = gen_reg_rtx (SImode);
2853 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2854 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2855 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2856 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2860 rtx op0 = gen_int_mode (mask, SImode);
2861 rtx op1 = gen_reg_rtx (SImode);
2862 rtx op2 = gen_reg_rtx (SImode);
2864 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2866 rtx tmp = gen_reg_rtx (SImode);
2868 emit_insn (gen_movsi (tmp, op0));
2872 /* Mask out any bits in operand[3] that are not needed. */
2873 emit_insn (gen_andsi3 (op1, operands[3], op0));
2875 if (CONST_INT_P (op0)
2876 && (const_ok_for_arm (mask << start_bit)
2877 || const_ok_for_arm (~(mask << start_bit))))
2879 op0 = gen_int_mode (~(mask << start_bit), SImode);
2880 emit_insn (gen_andsi3 (op2, operands[0], op0));
2884 if (CONST_INT_P (op0))
2886 rtx tmp = gen_reg_rtx (SImode);
2888 emit_insn (gen_movsi (tmp, op0));
2893 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2895 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2899 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2901 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2904 if (subtarget != target)
2906 /* If TARGET is still a SUBREG, then it must be wider than a word,
2907 so we must be careful only to set the subword we were asked to. */
2908 if (GET_CODE (target) == SUBREG)
2909 emit_move_insn (target, subtarget);
2911 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2918 (define_insn "insv_zero"
2919 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2920 (match_operand:SI 1 "const_int_M_operand" "M")
2921 (match_operand:SI 2 "const_int_M_operand" "M"))
2925 [(set_attr "length" "4")
2926 (set_attr "predicable" "yes")
2927 (set_attr "type" "bfm")]
2930 (define_insn "insv_t2"
2931 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2932 (match_operand:SI 1 "const_int_M_operand" "M")
2933 (match_operand:SI 2 "const_int_M_operand" "M"))
2934 (match_operand:SI 3 "s_register_operand" "r"))]
2936 "bfi%?\t%0, %3, %2, %1"
2937 [(set_attr "length" "4")
2938 (set_attr "predicable" "yes")
2939 (set_attr "type" "bfm")]
2942 ; constants for op 2 will never be given to these patterns.
2943 (define_insn_and_split "*anddi_notdi_di"
2944 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2945 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2946 (match_operand:DI 2 "s_register_operand" "r,0")))]
2949 "TARGET_32BIT && reload_completed
2950 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2951 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2952 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2953 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2956 operands[3] = gen_highpart (SImode, operands[0]);
2957 operands[0] = gen_lowpart (SImode, operands[0]);
2958 operands[4] = gen_highpart (SImode, operands[1]);
2959 operands[1] = gen_lowpart (SImode, operands[1]);
2960 operands[5] = gen_highpart (SImode, operands[2]);
2961 operands[2] = gen_lowpart (SImode, operands[2]);
2963 [(set_attr "length" "8")
2964 (set_attr "predicable" "yes")
2965 (set_attr "type" "multiple")]
2968 (define_insn_and_split "*anddi_notzesidi_di"
2969 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2970 (and:DI (not:DI (zero_extend:DI
2971 (match_operand:SI 2 "s_register_operand" "r,r")))
2972 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2975 bic%?\\t%Q0, %Q1, %2
2977 ; (not (zero_extend ...)) allows us to just copy the high word from
2978 ; operand1 to operand0.
2981 && operands[0] != operands[1]"
2982 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2983 (set (match_dup 3) (match_dup 4))]
2986 operands[3] = gen_highpart (SImode, operands[0]);
2987 operands[0] = gen_lowpart (SImode, operands[0]);
2988 operands[4] = gen_highpart (SImode, operands[1]);
2989 operands[1] = gen_lowpart (SImode, operands[1]);
2991 [(set_attr "length" "4,8")
2992 (set_attr "predicable" "yes")
2993 (set_attr "type" "multiple")]
2996 (define_insn_and_split "*anddi_notdi_zesidi"
2997 [(set (match_operand:DI 0 "s_register_operand" "=r")
2998 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
3000 (match_operand:SI 1 "s_register_operand" "r"))))]
3003 "TARGET_32BIT && reload_completed"
3004 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3005 (set (match_dup 3) (const_int 0))]
3008 operands[3] = gen_highpart (SImode, operands[0]);
3009 operands[0] = gen_lowpart (SImode, operands[0]);
3010 operands[2] = gen_lowpart (SImode, operands[2]);
3012 [(set_attr "length" "8")
3013 (set_attr "predicable" "yes")
3014 (set_attr "type" "multiple")]
3017 (define_insn_and_split "*anddi_notsesidi_di"
3018 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3019 (and:DI (not:DI (sign_extend:DI
3020 (match_operand:SI 2 "s_register_operand" "r,r")))
3021 (match_operand:DI 1 "s_register_operand" "0,r")))]
3024 "TARGET_32BIT && reload_completed"
3025 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3026 (set (match_dup 3) (and:SI (not:SI
3027 (ashiftrt:SI (match_dup 2) (const_int 31)))
3031 operands[3] = gen_highpart (SImode, operands[0]);
3032 operands[0] = gen_lowpart (SImode, operands[0]);
3033 operands[4] = gen_highpart (SImode, operands[1]);
3034 operands[1] = gen_lowpart (SImode, operands[1]);
3036 [(set_attr "length" "8")
3037 (set_attr "predicable" "yes")
3038 (set_attr "type" "multiple")]
3041 (define_insn "andsi_notsi_si"
3042 [(set (match_operand:SI 0 "s_register_operand" "=r")
3043 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3044 (match_operand:SI 1 "s_register_operand" "r")))]
3046 "bic%?\\t%0, %1, %2"
3047 [(set_attr "predicable" "yes")
3048 (set_attr "type" "logic_reg")]
3051 (define_insn "andsi_not_shiftsi_si"
3052 [(set (match_operand:SI 0 "s_register_operand" "=r")
3053 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3054 [(match_operand:SI 2 "s_register_operand" "r")
3055 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3056 (match_operand:SI 1 "s_register_operand" "r")))]
3058 "bic%?\\t%0, %1, %2%S4"
3059 [(set_attr "predicable" "yes")
3060 (set_attr "shift" "2")
3061 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3062 (const_string "logic_shift_imm")
3063 (const_string "logic_shift_reg")))]
3066 ;; Shifted bics pattern used to set up CC status register and not reusing
3067 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3068 ;; does not support shift by register.
3069 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3070 [(set (reg:CC_NOOV CC_REGNUM)
3072 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3073 [(match_operand:SI 1 "s_register_operand" "r")
3074 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3075 (match_operand:SI 3 "s_register_operand" "r"))
3077 (clobber (match_scratch:SI 4 "=r"))]
3078 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3079 "bics%?\\t%4, %3, %1%S0"
3080 [(set_attr "predicable" "yes")
3081 (set_attr "conds" "set")
3082 (set_attr "shift" "1")
3083 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3084 (const_string "logic_shift_imm")
3085 (const_string "logic_shift_reg")))]
3088 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3089 ;; getting reused later.
3090 (define_insn "andsi_not_shiftsi_si_scc"
3091 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3093 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3094 [(match_operand:SI 1 "s_register_operand" "r")
3095 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3096 (match_operand:SI 3 "s_register_operand" "r"))
3098 (set (match_operand:SI 4 "s_register_operand" "=r")
3099 (and:SI (not:SI (match_op_dup 0
3103 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3104 "bics%?\\t%4, %3, %1%S0"
3105 [(set_attr "predicable" "yes")
3106 (set_attr "conds" "set")
3107 (set_attr "shift" "1")
3108 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3109 (const_string "logic_shift_imm")
3110 (const_string "logic_shift_reg")))]
3113 (define_insn "*andsi_notsi_si_compare0"
3114 [(set (reg:CC_NOOV CC_REGNUM)
3116 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3117 (match_operand:SI 1 "s_register_operand" "r"))
3119 (set (match_operand:SI 0 "s_register_operand" "=r")
3120 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3123 [(set_attr "conds" "set")
3124 (set_attr "type" "logics_shift_reg")]
3127 (define_insn "*andsi_notsi_si_compare0_scratch"
3128 [(set (reg:CC_NOOV CC_REGNUM)
3130 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3131 (match_operand:SI 1 "s_register_operand" "r"))
3133 (clobber (match_scratch:SI 0 "=r"))]
3136 [(set_attr "conds" "set")
3137 (set_attr "type" "logics_shift_reg")]
3140 (define_expand "iordi3"
3141 [(set (match_operand:DI 0 "s_register_operand" "")
3142 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3143 (match_operand:DI 2 "neon_logic_op2" "")))]
3146 if (!TARGET_NEON && !TARGET_IWMMXT)
3148 rtx low = simplify_gen_binary (IOR, SImode,
3149 gen_lowpart (SImode, operands[1]),
3150 gen_lowpart (SImode, operands[2]));
3151 rtx high = simplify_gen_binary (IOR, SImode,
3152 gen_highpart (SImode, operands[1]),
3153 gen_highpart_mode (SImode, DImode,
3156 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3157 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3161 /* Otherwise expand pattern as above. */
3165 (define_insn_and_split "*iordi3_insn"
3166 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3167 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3168 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3169 "TARGET_32BIT && !TARGET_IWMMXT"
3171 switch (which_alternative)
3173 case 0: /* fall through */
3174 case 6: return "vorr\t%P0, %P1, %P2";
3175 case 1: /* fall through */
3176 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3177 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3183 default: gcc_unreachable ();
3186 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3187 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3188 [(set (match_dup 3) (match_dup 4))
3189 (set (match_dup 5) (match_dup 6))]
3192 operands[3] = gen_lowpart (SImode, operands[0]);
3193 operands[5] = gen_highpart (SImode, operands[0]);
3195 operands[4] = simplify_gen_binary (IOR, SImode,
3196 gen_lowpart (SImode, operands[1]),
3197 gen_lowpart (SImode, operands[2]));
3198 operands[6] = simplify_gen_binary (IOR, SImode,
3199 gen_highpart (SImode, operands[1]),
3200 gen_highpart_mode (SImode, DImode, operands[2]));
3203 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3204 multiple,neon_logic,neon_logic")
3205 (set_attr "length" "*,*,8,8,8,8,*,*")
3206 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3209 (define_insn "*iordi_zesidi_di"
3210 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3211 (ior:DI (zero_extend:DI
3212 (match_operand:SI 2 "s_register_operand" "r,r"))
3213 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3216 orr%?\\t%Q0, %Q1, %2
3218 [(set_attr "length" "4,8")
3219 (set_attr "predicable" "yes")
3220 (set_attr "type" "logic_reg,multiple")]
3223 (define_insn "*iordi_sesidi_di"
3224 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3225 (ior:DI (sign_extend:DI
3226 (match_operand:SI 2 "s_register_operand" "r,r"))
3227 (match_operand:DI 1 "s_register_operand" "0,r")))]
3230 [(set_attr "length" "8")
3231 (set_attr "predicable" "yes")
3232 (set_attr "type" "multiple")]
3235 (define_expand "iorsi3"
3236 [(set (match_operand:SI 0 "s_register_operand" "")
3237 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3238 (match_operand:SI 2 "reg_or_int_operand" "")))]
3241 if (CONST_INT_P (operands[2]))
3245 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3246 operands[2] = force_reg (SImode, operands[2]);
3249 arm_split_constant (IOR, SImode, NULL_RTX,
3250 INTVAL (operands[2]), operands[0],
3252 optimize && can_create_pseudo_p ());
3256 else /* TARGET_THUMB1 */
3258 rtx tmp = force_reg (SImode, operands[2]);
3259 if (rtx_equal_p (operands[0], operands[1]))
3263 operands[2] = operands[1];
3271 (define_insn_and_split "*iorsi3_insn"
3272 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3273 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3274 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3279 orn%?\\t%0, %1, #%B2
3283 && CONST_INT_P (operands[2])
3284 && !(const_ok_for_arm (INTVAL (operands[2]))
3285 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3286 [(clobber (const_int 0))]
3288 arm_split_constant (IOR, SImode, curr_insn,
3289 INTVAL (operands[2]), operands[0], operands[1], 0);
3292 [(set_attr "length" "4,4,4,4,16")
3293 (set_attr "arch" "32,t2,t2,32,32")
3294 (set_attr "predicable" "yes")
3295 (set_attr "predicable_short_it" "no,yes,no,no,no")
3296 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3300 [(match_scratch:SI 3 "r")
3301 (set (match_operand:SI 0 "arm_general_register_operand" "")
3302 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3303 (match_operand:SI 2 "const_int_operand" "")))]
3305 && !const_ok_for_arm (INTVAL (operands[2]))
3306 && const_ok_for_arm (~INTVAL (operands[2]))"
3307 [(set (match_dup 3) (match_dup 2))
3308 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3312 (define_insn "*iorsi3_compare0"
3313 [(set (reg:CC_NOOV CC_REGNUM)
3314 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3315 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3317 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3318 (ior:SI (match_dup 1) (match_dup 2)))]
3320 "orrs%?\\t%0, %1, %2"
3321 [(set_attr "conds" "set")
3322 (set_attr "type" "logics_imm,logics_reg")]
3325 (define_insn "*iorsi3_compare0_scratch"
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 (clobber (match_scratch:SI 0 "=r,r"))]
3332 "orrs%?\\t%0, %1, %2"
3333 [(set_attr "conds" "set")
3334 (set_attr "type" "logics_imm,logics_reg")]
3337 (define_expand "xordi3"
3338 [(set (match_operand:DI 0 "s_register_operand" "")
3339 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3340 (match_operand:DI 2 "arm_xordi_operand" "")))]
3343 /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3344 to reuse this expander for all TARGET_32BIT targets so just force the
3345 constants into a register. Unlike for the anddi3 and iordi3 there are
3346 no NEON instructions that take an immediate. */
3347 if (TARGET_IWMMXT && !REG_P (operands[2]))
3348 operands[2] = force_reg (DImode, operands[2]);
3349 if (!TARGET_NEON && !TARGET_IWMMXT)
3351 rtx low = simplify_gen_binary (XOR, SImode,
3352 gen_lowpart (SImode, operands[1]),
3353 gen_lowpart (SImode, operands[2]));
3354 rtx high = simplify_gen_binary (XOR, SImode,
3355 gen_highpart (SImode, operands[1]),
3356 gen_highpart_mode (SImode, DImode,
3359 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3360 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3364 /* Otherwise expand pattern as above. */
3368 (define_insn_and_split "*xordi3_insn"
3369 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3370 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3371 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3372 "TARGET_32BIT && !TARGET_IWMMXT"
3374 switch (which_alternative)
3379 case 4: /* fall through */
3381 case 0: /* fall through */
3382 case 5: return "veor\t%P0, %P1, %P2";
3383 default: gcc_unreachable ();
3386 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3387 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3388 [(set (match_dup 3) (match_dup 4))
3389 (set (match_dup 5) (match_dup 6))]
3392 operands[3] = gen_lowpart (SImode, operands[0]);
3393 operands[5] = gen_highpart (SImode, operands[0]);
3395 operands[4] = simplify_gen_binary (XOR, SImode,
3396 gen_lowpart (SImode, operands[1]),
3397 gen_lowpart (SImode, operands[2]));
3398 operands[6] = simplify_gen_binary (XOR, SImode,
3399 gen_highpart (SImode, operands[1]),
3400 gen_highpart_mode (SImode, DImode, operands[2]));
3403 [(set_attr "length" "*,8,8,8,8,*")
3404 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3405 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3408 (define_insn "*xordi_zesidi_di"
3409 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3410 (xor:DI (zero_extend:DI
3411 (match_operand:SI 2 "s_register_operand" "r,r"))
3412 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3415 eor%?\\t%Q0, %Q1, %2
3417 [(set_attr "length" "4,8")
3418 (set_attr "predicable" "yes")
3419 (set_attr "type" "logic_reg")]
3422 (define_insn "*xordi_sesidi_di"
3423 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3424 (xor:DI (sign_extend:DI
3425 (match_operand:SI 2 "s_register_operand" "r,r"))
3426 (match_operand:DI 1 "s_register_operand" "0,r")))]
3429 [(set_attr "length" "8")
3430 (set_attr "predicable" "yes")
3431 (set_attr "type" "multiple")]
3434 (define_expand "xorsi3"
3435 [(set (match_operand:SI 0 "s_register_operand" "")
3436 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3437 (match_operand:SI 2 "reg_or_int_operand" "")))]
3439 "if (CONST_INT_P (operands[2]))
3443 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3444 operands[2] = force_reg (SImode, operands[2]);
3447 arm_split_constant (XOR, SImode, NULL_RTX,
3448 INTVAL (operands[2]), operands[0],
3450 optimize && can_create_pseudo_p ());
3454 else /* TARGET_THUMB1 */
3456 rtx tmp = force_reg (SImode, operands[2]);
3457 if (rtx_equal_p (operands[0], operands[1]))
3461 operands[2] = operands[1];
3468 (define_insn_and_split "*arm_xorsi3"
3469 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3470 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3471 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3479 && CONST_INT_P (operands[2])
3480 && !const_ok_for_arm (INTVAL (operands[2]))"
3481 [(clobber (const_int 0))]
3483 arm_split_constant (XOR, SImode, curr_insn,
3484 INTVAL (operands[2]), operands[0], operands[1], 0);
3487 [(set_attr "length" "4,4,4,16")
3488 (set_attr "predicable" "yes")
3489 (set_attr "predicable_short_it" "no,yes,no,no")
3490 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3493 (define_insn "*xorsi3_compare0"
3494 [(set (reg:CC_NOOV CC_REGNUM)
3495 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3496 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3498 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3499 (xor:SI (match_dup 1) (match_dup 2)))]
3501 "eors%?\\t%0, %1, %2"
3502 [(set_attr "conds" "set")
3503 (set_attr "type" "logics_imm,logics_reg")]
3506 (define_insn "*xorsi3_compare0_scratch"
3507 [(set (reg:CC_NOOV CC_REGNUM)
3508 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3509 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3513 [(set_attr "conds" "set")
3514 (set_attr "type" "logics_imm,logics_reg")]
3517 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3518 ; (NOT D) we can sometimes merge the final NOT into one of the following
3522 [(set (match_operand:SI 0 "s_register_operand" "")
3523 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3524 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3525 (match_operand:SI 3 "arm_rhs_operand" "")))
3526 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3528 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3529 (not:SI (match_dup 3))))
3530 (set (match_dup 0) (not:SI (match_dup 4)))]
3534 (define_insn_and_split "*andsi_iorsi3_notsi"
3535 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3536 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3537 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3538 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3540 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3541 "&& reload_completed"
3542 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3543 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3545 /* If operands[3] is a constant make sure to fold the NOT into it
3546 to avoid creating a NOT of a CONST_INT. */
3547 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3548 if (CONST_INT_P (not_rtx))
3550 operands[4] = operands[0];
3551 operands[5] = not_rtx;
3555 operands[5] = operands[0];
3556 operands[4] = not_rtx;
3559 [(set_attr "length" "8")
3560 (set_attr "ce_count" "2")
3561 (set_attr "predicable" "yes")
3562 (set_attr "type" "multiple")]
3565 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3566 ; insns are available?
3568 [(set (match_operand:SI 0 "s_register_operand" "")
3569 (match_operator:SI 1 "logical_binary_operator"
3570 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3571 (match_operand:SI 3 "const_int_operand" "")
3572 (match_operand:SI 4 "const_int_operand" ""))
3573 (match_operator:SI 9 "logical_binary_operator"
3574 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3575 (match_operand:SI 6 "const_int_operand" ""))
3576 (match_operand:SI 7 "s_register_operand" "")])]))
3577 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3579 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3580 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3583 [(ashift:SI (match_dup 2) (match_dup 4))
3587 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3590 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3594 [(set (match_operand:SI 0 "s_register_operand" "")
3595 (match_operator:SI 1 "logical_binary_operator"
3596 [(match_operator:SI 9 "logical_binary_operator"
3597 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3598 (match_operand:SI 6 "const_int_operand" ""))
3599 (match_operand:SI 7 "s_register_operand" "")])
3600 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3601 (match_operand:SI 3 "const_int_operand" "")
3602 (match_operand:SI 4 "const_int_operand" ""))]))
3603 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3605 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3606 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3609 [(ashift:SI (match_dup 2) (match_dup 4))
3613 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3616 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3620 [(set (match_operand:SI 0 "s_register_operand" "")
3621 (match_operator:SI 1 "logical_binary_operator"
3622 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3623 (match_operand:SI 3 "const_int_operand" "")
3624 (match_operand:SI 4 "const_int_operand" ""))
3625 (match_operator:SI 9 "logical_binary_operator"
3626 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3627 (match_operand:SI 6 "const_int_operand" ""))
3628 (match_operand:SI 7 "s_register_operand" "")])]))
3629 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3631 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3632 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3635 [(ashift:SI (match_dup 2) (match_dup 4))
3639 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3642 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3646 [(set (match_operand:SI 0 "s_register_operand" "")
3647 (match_operator:SI 1 "logical_binary_operator"
3648 [(match_operator:SI 9 "logical_binary_operator"
3649 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3650 (match_operand:SI 6 "const_int_operand" ""))
3651 (match_operand:SI 7 "s_register_operand" "")])
3652 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3653 (match_operand:SI 3 "const_int_operand" "")
3654 (match_operand:SI 4 "const_int_operand" ""))]))
3655 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3657 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3658 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3661 [(ashift:SI (match_dup 2) (match_dup 4))
3665 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3668 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3672 ;; Minimum and maximum insns
3674 (define_expand "smaxsi3"
3676 (set (match_operand:SI 0 "s_register_operand" "")
3677 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3678 (match_operand:SI 2 "arm_rhs_operand" "")))
3679 (clobber (reg:CC CC_REGNUM))])]
3682 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3684 /* No need for a clobber of the condition code register here. */
3685 emit_insn (gen_rtx_SET (operands[0],
3686 gen_rtx_SMAX (SImode, operands[1],
3692 (define_insn "*smax_0"
3693 [(set (match_operand:SI 0 "s_register_operand" "=r")
3694 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3697 "bic%?\\t%0, %1, %1, asr #31"
3698 [(set_attr "predicable" "yes")
3699 (set_attr "type" "logic_shift_reg")]
3702 (define_insn "*smax_m1"
3703 [(set (match_operand:SI 0 "s_register_operand" "=r")
3704 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3707 "orr%?\\t%0, %1, %1, asr #31"
3708 [(set_attr "predicable" "yes")
3709 (set_attr "type" "logic_shift_reg")]
3712 (define_insn_and_split "*arm_smax_insn"
3713 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3714 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3715 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3716 (clobber (reg:CC CC_REGNUM))]
3719 ; cmp\\t%1, %2\;movlt\\t%0, %2
3720 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3722 [(set (reg:CC CC_REGNUM)
3723 (compare:CC (match_dup 1) (match_dup 2)))
3725 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3729 [(set_attr "conds" "clob")
3730 (set_attr "length" "8,12")
3731 (set_attr "type" "multiple")]
3734 (define_expand "sminsi3"
3736 (set (match_operand:SI 0 "s_register_operand" "")
3737 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3738 (match_operand:SI 2 "arm_rhs_operand" "")))
3739 (clobber (reg:CC CC_REGNUM))])]
3742 if (operands[2] == const0_rtx)
3744 /* No need for a clobber of the condition code register here. */
3745 emit_insn (gen_rtx_SET (operands[0],
3746 gen_rtx_SMIN (SImode, operands[1],
3752 (define_insn "*smin_0"
3753 [(set (match_operand:SI 0 "s_register_operand" "=r")
3754 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3757 "and%?\\t%0, %1, %1, asr #31"
3758 [(set_attr "predicable" "yes")
3759 (set_attr "type" "logic_shift_reg")]
3762 (define_insn_and_split "*arm_smin_insn"
3763 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3764 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3765 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3766 (clobber (reg:CC CC_REGNUM))]
3769 ; cmp\\t%1, %2\;movge\\t%0, %2
3770 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3772 [(set (reg:CC CC_REGNUM)
3773 (compare:CC (match_dup 1) (match_dup 2)))
3775 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3779 [(set_attr "conds" "clob")
3780 (set_attr "length" "8,12")
3781 (set_attr "type" "multiple,multiple")]
3784 (define_expand "umaxsi3"
3786 (set (match_operand:SI 0 "s_register_operand" "")
3787 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3788 (match_operand:SI 2 "arm_rhs_operand" "")))
3789 (clobber (reg:CC CC_REGNUM))])]
3794 (define_insn_and_split "*arm_umaxsi3"
3795 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3796 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3797 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3798 (clobber (reg:CC CC_REGNUM))]
3801 ; cmp\\t%1, %2\;movcc\\t%0, %2
3802 ; cmp\\t%1, %2\;movcs\\t%0, %1
3803 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3805 [(set (reg:CC CC_REGNUM)
3806 (compare:CC (match_dup 1) (match_dup 2)))
3808 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3812 [(set_attr "conds" "clob")
3813 (set_attr "length" "8,8,12")
3814 (set_attr "type" "store_4")]
3817 (define_expand "uminsi3"
3819 (set (match_operand:SI 0 "s_register_operand" "")
3820 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3821 (match_operand:SI 2 "arm_rhs_operand" "")))
3822 (clobber (reg:CC CC_REGNUM))])]
3827 (define_insn_and_split "*arm_uminsi3"
3828 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3829 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3830 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3831 (clobber (reg:CC CC_REGNUM))]
3834 ; cmp\\t%1, %2\;movcs\\t%0, %2
3835 ; cmp\\t%1, %2\;movcc\\t%0, %1
3836 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3838 [(set (reg:CC CC_REGNUM)
3839 (compare:CC (match_dup 1) (match_dup 2)))
3841 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3845 [(set_attr "conds" "clob")
3846 (set_attr "length" "8,8,12")
3847 (set_attr "type" "store_4")]
3850 (define_insn "*store_minmaxsi"
3851 [(set (match_operand:SI 0 "memory_operand" "=m")
3852 (match_operator:SI 3 "minmax_operator"
3853 [(match_operand:SI 1 "s_register_operand" "r")
3854 (match_operand:SI 2 "s_register_operand" "r")]))
3855 (clobber (reg:CC CC_REGNUM))]
3856 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3858 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3859 operands[1], operands[2]);
3860 output_asm_insn (\"cmp\\t%1, %2\", operands);
3862 output_asm_insn (\"ite\t%d3\", operands);
3863 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3864 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3867 [(set_attr "conds" "clob")
3868 (set (attr "length")
3869 (if_then_else (eq_attr "is_thumb" "yes")
3872 (set_attr "type" "store_4")]
3875 ; Reject the frame pointer in operand[1], since reloading this after
3876 ; it has been eliminated can cause carnage.
3877 (define_insn "*minmax_arithsi"
3878 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3879 (match_operator:SI 4 "shiftable_operator"
3880 [(match_operator:SI 5 "minmax_operator"
3881 [(match_operand:SI 2 "s_register_operand" "r,r")
3882 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3883 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3884 (clobber (reg:CC CC_REGNUM))]
3885 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3888 enum rtx_code code = GET_CODE (operands[4]);
3891 if (which_alternative != 0 || operands[3] != const0_rtx
3892 || (code != PLUS && code != IOR && code != XOR))
3897 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3898 operands[2], operands[3]);
3899 output_asm_insn (\"cmp\\t%2, %3\", operands);
3903 output_asm_insn (\"ite\\t%d5\", operands);
3905 output_asm_insn (\"it\\t%d5\", operands);
3907 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3909 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3912 [(set_attr "conds" "clob")
3913 (set (attr "length")
3914 (if_then_else (eq_attr "is_thumb" "yes")
3917 (set_attr "type" "multiple")]
3920 ; Reject the frame pointer in operand[1], since reloading this after
3921 ; it has been eliminated can cause carnage.
3922 (define_insn_and_split "*minmax_arithsi_non_canon"
3923 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3925 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3926 (match_operator:SI 4 "minmax_operator"
3927 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3928 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3929 (clobber (reg:CC CC_REGNUM))]
3930 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3931 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3933 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3934 [(set (reg:CC CC_REGNUM)
3935 (compare:CC (match_dup 2) (match_dup 3)))
3937 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3939 (minus:SI (match_dup 1)
3941 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3945 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3946 operands[2], operands[3]);
3947 enum rtx_code rc = minmax_code (operands[4]);
3948 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3949 operands[2], operands[3]);
3951 if (mode == CCFPmode || mode == CCFPEmode)
3952 rc = reverse_condition_maybe_unordered (rc);
3954 rc = reverse_condition (rc);
3955 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3956 if (CONST_INT_P (operands[3]))
3957 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3959 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3961 [(set_attr "conds" "clob")
3962 (set (attr "length")
3963 (if_then_else (eq_attr "is_thumb" "yes")
3966 (set_attr "type" "multiple")]
3969 (define_code_iterator SAT [smin smax])
3970 (define_code_iterator SATrev [smin smax])
3971 (define_code_attr SATlo [(smin "1") (smax "2")])
3972 (define_code_attr SAThi [(smin "2") (smax "1")])
3974 (define_insn "*satsi_<SAT:code>"
3975 [(set (match_operand:SI 0 "s_register_operand" "=r")
3976 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3977 (match_operand:SI 1 "const_int_operand" "i"))
3978 (match_operand:SI 2 "const_int_operand" "i")))]
3979 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3980 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3984 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3985 &mask, &signed_sat))
3988 operands[1] = GEN_INT (mask);
3990 return "ssat%?\t%0, %1, %3";
3992 return "usat%?\t%0, %1, %3";
3994 [(set_attr "predicable" "yes")
3995 (set_attr "type" "alus_imm")]
3998 (define_insn "*satsi_<SAT:code>_shift"
3999 [(set (match_operand:SI 0 "s_register_operand" "=r")
4000 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
4001 [(match_operand:SI 4 "s_register_operand" "r")
4002 (match_operand:SI 5 "const_int_operand" "i")])
4003 (match_operand:SI 1 "const_int_operand" "i"))
4004 (match_operand:SI 2 "const_int_operand" "i")))]
4005 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
4006 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
4010 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
4011 &mask, &signed_sat))
4014 operands[1] = GEN_INT (mask);
4016 return "ssat%?\t%0, %1, %4%S3";
4018 return "usat%?\t%0, %1, %4%S3";
4020 [(set_attr "predicable" "yes")
4021 (set_attr "shift" "3")
4022 (set_attr "type" "logic_shift_reg")])
4024 ;; Shift and rotation insns
4026 (define_expand "ashldi3"
4027 [(set (match_operand:DI 0 "s_register_operand" "")
4028 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
4029 (match_operand:SI 2 "general_operand" "")))]
4034 /* Delay the decision whether to use NEON or core-regs until
4035 register allocation. */
4036 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4041 /* Only the NEON case can handle in-memory shift counts. */
4042 if (!reg_or_int_operand (operands[2], SImode))
4043 operands[2] = force_reg (SImode, operands[2]);
4046 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4047 ; /* No special preparation statements; expand pattern as above. */
4050 rtx scratch1, scratch2;
4052 /* Ideally we should use iwmmxt here if we could know that operands[1]
4053 ends up already living in an iwmmxt register. Otherwise it's
4054 cheaper to have the alternate code being generated than moving
4055 values to iwmmxt regs and back. */
4057 /* Expand operation using core-registers.
4058 'FAIL' would achieve the same thing, but this is a bit smarter. */
4059 scratch1 = gen_reg_rtx (SImode);
4060 scratch2 = gen_reg_rtx (SImode);
4061 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4062 operands[2], scratch1, scratch2);
4068 (define_expand "ashlsi3"
4069 [(set (match_operand:SI 0 "s_register_operand" "")
4070 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4071 (match_operand:SI 2 "arm_rhs_operand" "")))]
4074 if (CONST_INT_P (operands[2])
4075 && (UINTVAL (operands[2])) > 31)
4077 emit_insn (gen_movsi (operands[0], const0_rtx));
4083 (define_expand "ashrdi3"
4084 [(set (match_operand:DI 0 "s_register_operand" "")
4085 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4086 (match_operand:SI 2 "reg_or_int_operand" "")))]
4091 /* Delay the decision whether to use NEON or core-regs until
4092 register allocation. */
4093 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4097 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4098 ; /* No special preparation statements; expand pattern as above. */
4101 rtx scratch1, scratch2;
4103 /* Ideally we should use iwmmxt here if we could know that operands[1]
4104 ends up already living in an iwmmxt register. Otherwise it's
4105 cheaper to have the alternate code being generated than moving
4106 values to iwmmxt regs and back. */
4108 /* Expand operation using core-registers.
4109 'FAIL' would achieve the same thing, but this is a bit smarter. */
4110 scratch1 = gen_reg_rtx (SImode);
4111 scratch2 = gen_reg_rtx (SImode);
4112 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4113 operands[2], scratch1, scratch2);
4119 (define_expand "ashrsi3"
4120 [(set (match_operand:SI 0 "s_register_operand" "")
4121 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4122 (match_operand:SI 2 "arm_rhs_operand" "")))]
4125 if (CONST_INT_P (operands[2])
4126 && UINTVAL (operands[2]) > 31)
4127 operands[2] = GEN_INT (31);
4131 (define_expand "lshrdi3"
4132 [(set (match_operand:DI 0 "s_register_operand" "")
4133 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4134 (match_operand:SI 2 "reg_or_int_operand" "")))]
4139 /* Delay the decision whether to use NEON or core-regs until
4140 register allocation. */
4141 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4145 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4146 ; /* No special preparation statements; expand pattern as above. */
4149 rtx scratch1, scratch2;
4151 /* Ideally we should use iwmmxt here if we could know that operands[1]
4152 ends up already living in an iwmmxt register. Otherwise it's
4153 cheaper to have the alternate code being generated than moving
4154 values to iwmmxt regs and back. */
4156 /* Expand operation using core-registers.
4157 'FAIL' would achieve the same thing, but this is a bit smarter. */
4158 scratch1 = gen_reg_rtx (SImode);
4159 scratch2 = gen_reg_rtx (SImode);
4160 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4161 operands[2], scratch1, scratch2);
4167 (define_expand "lshrsi3"
4168 [(set (match_operand:SI 0 "s_register_operand" "")
4169 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4170 (match_operand:SI 2 "arm_rhs_operand" "")))]
4173 if (CONST_INT_P (operands[2])
4174 && (UINTVAL (operands[2])) > 31)
4176 emit_insn (gen_movsi (operands[0], const0_rtx));
4182 (define_expand "rotlsi3"
4183 [(set (match_operand:SI 0 "s_register_operand" "")
4184 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4185 (match_operand:SI 2 "reg_or_int_operand" "")))]
4188 if (CONST_INT_P (operands[2]))
4189 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4192 rtx reg = gen_reg_rtx (SImode);
4193 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4199 (define_expand "rotrsi3"
4200 [(set (match_operand:SI 0 "s_register_operand" "")
4201 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4202 (match_operand:SI 2 "arm_rhs_operand" "")))]
4207 if (CONST_INT_P (operands[2])
4208 && UINTVAL (operands[2]) > 31)
4209 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4211 else /* TARGET_THUMB1 */
4213 if (CONST_INT_P (operands [2]))
4214 operands [2] = force_reg (SImode, operands[2]);
4219 (define_insn "*arm_shiftsi3"
4220 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4221 (match_operator:SI 3 "shift_operator"
4222 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4223 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4225 "* return arm_output_shift(operands, 0);"
4226 [(set_attr "predicable" "yes")
4227 (set_attr "arch" "t2,t2,*,*")
4228 (set_attr "predicable_short_it" "yes,yes,no,no")
4229 (set_attr "length" "4")
4230 (set_attr "shift" "1")
4231 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4234 (define_insn "*shiftsi3_compare0"
4235 [(set (reg:CC_NOOV CC_REGNUM)
4236 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4237 [(match_operand:SI 1 "s_register_operand" "r,r")
4238 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4240 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4241 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4243 "* return arm_output_shift(operands, 1);"
4244 [(set_attr "conds" "set")
4245 (set_attr "shift" "1")
4246 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4249 (define_insn "*shiftsi3_compare0_scratch"
4250 [(set (reg:CC_NOOV CC_REGNUM)
4251 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4252 [(match_operand:SI 1 "s_register_operand" "r,r")
4253 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4255 (clobber (match_scratch:SI 0 "=r,r"))]
4257 "* return arm_output_shift(operands, 1);"
4258 [(set_attr "conds" "set")
4259 (set_attr "shift" "1")
4260 (set_attr "type" "shift_imm,shift_reg")]
4263 (define_insn "*not_shiftsi"
4264 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4265 (not:SI (match_operator:SI 3 "shift_operator"
4266 [(match_operand:SI 1 "s_register_operand" "r,r")
4267 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4270 [(set_attr "predicable" "yes")
4271 (set_attr "shift" "1")
4272 (set_attr "arch" "32,a")
4273 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4275 (define_insn "*not_shiftsi_compare0"
4276 [(set (reg:CC_NOOV CC_REGNUM)
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")]))
4282 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4283 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4285 "mvns%?\\t%0, %1%S3"
4286 [(set_attr "conds" "set")
4287 (set_attr "shift" "1")
4288 (set_attr "arch" "32,a")
4289 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4291 (define_insn "*not_shiftsi_compare0_scratch"
4292 [(set (reg:CC_NOOV CC_REGNUM)
4294 (not:SI (match_operator:SI 3 "shift_operator"
4295 [(match_operand:SI 1 "s_register_operand" "r,r")
4296 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4298 (clobber (match_scratch:SI 0 "=r,r"))]
4300 "mvns%?\\t%0, %1%S3"
4301 [(set_attr "conds" "set")
4302 (set_attr "shift" "1")
4303 (set_attr "arch" "32,a")
4304 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4306 ;; We don't really have extzv, but defining this using shifts helps
4307 ;; to reduce register pressure later on.
4309 (define_expand "extzv"
4310 [(set (match_operand 0 "s_register_operand" "")
4311 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4312 (match_operand 2 "const_int_operand" "")
4313 (match_operand 3 "const_int_operand" "")))]
4314 "TARGET_THUMB1 || arm_arch_thumb2"
4317 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4318 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4320 if (arm_arch_thumb2)
4322 HOST_WIDE_INT width = INTVAL (operands[2]);
4323 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4325 if (unaligned_access && MEM_P (operands[1])
4326 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4330 if (BYTES_BIG_ENDIAN)
4331 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4336 base_addr = adjust_address (operands[1], SImode,
4337 bitpos / BITS_PER_UNIT);
4338 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4342 rtx dest = operands[0];
4343 rtx tmp = gen_reg_rtx (SImode);
4345 /* We may get a paradoxical subreg here. Strip it off. */
4346 if (GET_CODE (dest) == SUBREG
4347 && GET_MODE (dest) == SImode
4348 && GET_MODE (SUBREG_REG (dest)) == HImode)
4349 dest = SUBREG_REG (dest);
4351 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4354 base_addr = adjust_address (operands[1], HImode,
4355 bitpos / BITS_PER_UNIT);
4356 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4357 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4361 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4363 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4371 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4374 operands[3] = GEN_INT (rshift);
4378 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4382 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4383 operands[3], gen_reg_rtx (SImode)));
4388 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4390 (define_expand "extzv_t1"
4391 [(set (match_operand:SI 4 "s_register_operand" "")
4392 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4393 (match_operand:SI 2 "const_int_operand" "")))
4394 (set (match_operand:SI 0 "s_register_operand" "")
4395 (lshiftrt:SI (match_dup 4)
4396 (match_operand:SI 3 "const_int_operand" "")))]
4400 (define_expand "extv"
4401 [(set (match_operand 0 "s_register_operand" "")
4402 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4403 (match_operand 2 "const_int_operand" "")
4404 (match_operand 3 "const_int_operand" "")))]
4407 HOST_WIDE_INT width = INTVAL (operands[2]);
4408 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4410 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4411 && (bitpos % BITS_PER_UNIT) == 0)
4415 if (BYTES_BIG_ENDIAN)
4416 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4420 base_addr = adjust_address (operands[1], SImode,
4421 bitpos / BITS_PER_UNIT);
4422 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4426 rtx dest = operands[0];
4427 rtx tmp = gen_reg_rtx (SImode);
4429 /* We may get a paradoxical subreg here. Strip it off. */
4430 if (GET_CODE (dest) == SUBREG
4431 && GET_MODE (dest) == SImode
4432 && GET_MODE (SUBREG_REG (dest)) == HImode)
4433 dest = SUBREG_REG (dest);
4435 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4438 base_addr = adjust_address (operands[1], HImode,
4439 bitpos / BITS_PER_UNIT);
4440 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4441 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4446 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4448 else if (GET_MODE (operands[0]) == SImode
4449 && GET_MODE (operands[1]) == SImode)
4451 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4459 ; Helper to expand register forms of extv with the proper modes.
4461 (define_expand "extv_regsi"
4462 [(set (match_operand:SI 0 "s_register_operand" "")
4463 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4464 (match_operand 2 "const_int_operand" "")
4465 (match_operand 3 "const_int_operand" "")))]
4470 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4472 (define_insn "unaligned_loadsi"
4473 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4474 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4475 UNSPEC_UNALIGNED_LOAD))]
4477 "ldr%?\t%0, %1\t@ unaligned"
4478 [(set_attr "arch" "t2,any")
4479 (set_attr "length" "2,4")
4480 (set_attr "predicable" "yes")
4481 (set_attr "predicable_short_it" "yes,no")
4482 (set_attr "type" "load_4")])
4484 (define_insn "unaligned_loadhis"
4485 [(set (match_operand:SI 0 "s_register_operand" "=r")
4487 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
4488 UNSPEC_UNALIGNED_LOAD)))]
4490 "ldrsh%?\t%0, %1\t@ unaligned"
4491 [(set_attr "predicable" "yes")
4492 (set_attr "type" "load_byte")])
4494 (define_insn "unaligned_loadhiu"
4495 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4497 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4498 UNSPEC_UNALIGNED_LOAD)))]
4500 "ldrh%?\t%0, %1\t@ unaligned"
4501 [(set_attr "arch" "t2,any")
4502 (set_attr "length" "2,4")
4503 (set_attr "predicable" "yes")
4504 (set_attr "predicable_short_it" "yes,no")
4505 (set_attr "type" "load_byte")])
4507 (define_insn "unaligned_storesi"
4508 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4509 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4510 UNSPEC_UNALIGNED_STORE))]
4512 "str%?\t%1, %0\t@ unaligned"
4513 [(set_attr "arch" "t2,any")
4514 (set_attr "length" "2,4")
4515 (set_attr "predicable" "yes")
4516 (set_attr "predicable_short_it" "yes,no")
4517 (set_attr "type" "store_4")])
4519 (define_insn "unaligned_storehi"
4520 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4521 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4522 UNSPEC_UNALIGNED_STORE))]
4524 "strh%?\t%1, %0\t@ unaligned"
4525 [(set_attr "arch" "t2,any")
4526 (set_attr "length" "2,4")
4527 (set_attr "predicable" "yes")
4528 (set_attr "predicable_short_it" "yes,no")
4529 (set_attr "type" "store_4")])
4532 (define_insn "*extv_reg"
4533 [(set (match_operand:SI 0 "s_register_operand" "=r")
4534 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4535 (match_operand:SI 2 "const_int_operand" "n")
4536 (match_operand:SI 3 "const_int_operand" "n")))]
4538 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4539 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4540 "sbfx%?\t%0, %1, %3, %2"
4541 [(set_attr "length" "4")
4542 (set_attr "predicable" "yes")
4543 (set_attr "type" "bfm")]
4546 (define_insn "extzv_t2"
4547 [(set (match_operand:SI 0 "s_register_operand" "=r")
4548 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4549 (match_operand:SI 2 "const_int_operand" "n")
4550 (match_operand:SI 3 "const_int_operand" "n")))]
4552 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4553 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4554 "ubfx%?\t%0, %1, %3, %2"
4555 [(set_attr "length" "4")
4556 (set_attr "predicable" "yes")
4557 (set_attr "type" "bfm")]
4561 ;; Division instructions
4562 (define_insn "divsi3"
4563 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4564 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4565 (match_operand:SI 2 "s_register_operand" "r,r")))]
4570 [(set_attr "arch" "32,v8mb")
4571 (set_attr "predicable" "yes")
4572 (set_attr "type" "sdiv")]
4575 (define_insn "udivsi3"
4576 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4577 (udiv: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" "udiv")]
4589 ;; Unary arithmetic insns
4591 (define_expand "negvsi3"
4592 [(match_operand:SI 0 "register_operand")
4593 (match_operand:SI 1 "register_operand")
4594 (match_operand 2 "")]
4597 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4598 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4603 (define_expand "negvdi3"
4604 [(match_operand:DI 0 "register_operand")
4605 (match_operand:DI 1 "register_operand")
4606 (match_operand 2 "")]
4609 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4610 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4616 (define_insn_and_split "negdi2_compare"
4617 [(set (reg:CC CC_REGNUM)
4620 (match_operand:DI 1 "register_operand" "0,r")))
4621 (set (match_operand:DI 0 "register_operand" "=r,&r")
4622 (minus:DI (const_int 0) (match_dup 1)))]
4625 "&& reload_completed"
4626 [(parallel [(set (reg:CC CC_REGNUM)
4627 (compare:CC (const_int 0) (match_dup 1)))
4628 (set (match_dup 0) (minus:SI (const_int 0)
4630 (parallel [(set (reg:CC CC_REGNUM)
4631 (compare:CC (const_int 0) (match_dup 3)))
4634 (minus:SI (const_int 0) (match_dup 3))
4635 (ltu:SI (reg:CC_C CC_REGNUM)
4638 operands[2] = gen_highpart (SImode, operands[0]);
4639 operands[0] = gen_lowpart (SImode, operands[0]);
4640 operands[3] = gen_highpart (SImode, operands[1]);
4641 operands[1] = gen_lowpart (SImode, operands[1]);
4643 [(set_attr "conds" "set")
4644 (set_attr "length" "8")
4645 (set_attr "type" "multiple")]
4648 (define_expand "negdi2"
4650 [(set (match_operand:DI 0 "s_register_operand" "")
4651 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4652 (clobber (reg:CC CC_REGNUM))])]
4657 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4663 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4664 ;; The first alternative allows the common case of a *full* overlap.
4665 (define_insn_and_split "*negdi2_insn"
4666 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4667 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4668 (clobber (reg:CC CC_REGNUM))]
4670 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4671 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4672 "&& reload_completed"
4673 [(parallel [(set (reg:CC CC_REGNUM)
4674 (compare:CC (const_int 0) (match_dup 1)))
4675 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4676 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4677 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4679 operands[2] = gen_highpart (SImode, operands[0]);
4680 operands[0] = gen_lowpart (SImode, operands[0]);
4681 operands[3] = gen_highpart (SImode, operands[1]);
4682 operands[1] = gen_lowpart (SImode, operands[1]);
4684 [(set_attr "conds" "clob")
4685 (set_attr "length" "8")
4686 (set_attr "type" "multiple")]
4689 (define_insn "*negsi2_carryin_compare"
4690 [(set (reg:CC CC_REGNUM)
4691 (compare:CC (const_int 0)
4692 (match_operand:SI 1 "s_register_operand" "r")))
4693 (set (match_operand:SI 0 "s_register_operand" "=r")
4694 (minus:SI (minus:SI (const_int 0)
4696 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4699 [(set_attr "conds" "set")
4700 (set_attr "type" "alus_imm")]
4703 (define_expand "negsi2"
4704 [(set (match_operand:SI 0 "s_register_operand" "")
4705 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4710 (define_insn "*arm_negsi2"
4711 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4712 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4714 "rsb%?\\t%0, %1, #0"
4715 [(set_attr "predicable" "yes")
4716 (set_attr "predicable_short_it" "yes,no")
4717 (set_attr "arch" "t2,*")
4718 (set_attr "length" "4")
4719 (set_attr "type" "alu_sreg")]
4722 (define_expand "negsf2"
4723 [(set (match_operand:SF 0 "s_register_operand" "")
4724 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4725 "TARGET_32BIT && TARGET_HARD_FLOAT"
4729 (define_expand "negdf2"
4730 [(set (match_operand:DF 0 "s_register_operand" "")
4731 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4732 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4735 (define_insn_and_split "*zextendsidi_negsi"
4736 [(set (match_operand:DI 0 "s_register_operand" "=r")
4737 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4742 (neg:SI (match_dup 1)))
4746 operands[2] = gen_lowpart (SImode, operands[0]);
4747 operands[3] = gen_highpart (SImode, operands[0]);
4749 [(set_attr "length" "8")
4750 (set_attr "type" "multiple")]
4753 ;; Negate an extended 32-bit value.
4754 (define_insn_and_split "*negdi_extendsidi"
4755 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4756 (neg:DI (sign_extend:DI
4757 (match_operand:SI 1 "s_register_operand" "l,r"))))
4758 (clobber (reg:CC CC_REGNUM))]
4761 "&& reload_completed"
4764 rtx low = gen_lowpart (SImode, operands[0]);
4765 rtx high = gen_highpart (SImode, operands[0]);
4767 if (reg_overlap_mentioned_p (low, operands[1]))
4769 /* Input overlaps the low word of the output. Use:
4772 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4773 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4775 emit_insn (gen_rtx_SET (high,
4776 gen_rtx_ASHIFTRT (SImode, operands[1],
4779 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4781 emit_insn (gen_rtx_SET (high,
4782 gen_rtx_MINUS (SImode,
4783 gen_rtx_MINUS (SImode,
4786 gen_rtx_LTU (SImode,
4791 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4792 emit_insn (gen_rtx_SET (high,
4793 gen_rtx_MINUS (SImode,
4794 gen_rtx_MINUS (SImode,
4797 gen_rtx_LTU (SImode,
4804 /* No overlap, or overlap on high word. Use:
4808 Flags not needed for this sequence. */
4809 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4810 emit_insn (gen_rtx_SET (high,
4811 gen_rtx_AND (SImode,
4812 gen_rtx_NOT (SImode, operands[1]),
4814 emit_insn (gen_rtx_SET (high,
4815 gen_rtx_ASHIFTRT (SImode, high,
4820 [(set_attr "length" "12")
4821 (set_attr "arch" "t2,*")
4822 (set_attr "type" "multiple")]
4825 (define_insn_and_split "*negdi_zero_extendsidi"
4826 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4827 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4828 (clobber (reg:CC CC_REGNUM))]
4830 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4831 ;; Don't care what register is input to sbc,
4832 ;; since we just need to propagate the carry.
4833 "&& reload_completed"
4834 [(parallel [(set (reg:CC CC_REGNUM)
4835 (compare:CC (const_int 0) (match_dup 1)))
4836 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4837 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4838 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4840 operands[2] = gen_highpart (SImode, operands[0]);
4841 operands[0] = gen_lowpart (SImode, operands[0]);
4843 [(set_attr "conds" "clob")
4844 (set_attr "length" "8")
4845 (set_attr "type" "multiple")] ;; length in thumb is 4
4848 ;; abssi2 doesn't really clobber the condition codes if a different register
4849 ;; is being set. To keep things simple, assume during rtl manipulations that
4850 ;; it does, but tell the final scan operator the truth. Similarly for
4853 (define_expand "abssi2"
4855 [(set (match_operand:SI 0 "s_register_operand" "")
4856 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4857 (clobber (match_dup 2))])]
4861 operands[2] = gen_rtx_SCRATCH (SImode);
4863 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4866 (define_insn_and_split "*arm_abssi2"
4867 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4868 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4869 (clobber (reg:CC CC_REGNUM))]
4872 "&& reload_completed"
4875 /* if (which_alternative == 0) */
4876 if (REGNO(operands[0]) == REGNO(operands[1]))
4878 /* Emit the pattern:
4879 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4880 [(set (reg:CC CC_REGNUM)
4881 (compare:CC (match_dup 0) (const_int 0)))
4882 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4883 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4885 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4886 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4887 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4888 (gen_rtx_LT (SImode,
4889 gen_rtx_REG (CCmode, CC_REGNUM),
4891 (gen_rtx_SET (operands[0],
4892 (gen_rtx_MINUS (SImode,
4899 /* Emit the pattern:
4900 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4902 (xor:SI (match_dup 1)
4903 (ashiftrt:SI (match_dup 1) (const_int 31))))
4905 (minus:SI (match_dup 0)
4906 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4908 emit_insn (gen_rtx_SET (operands[0],
4909 gen_rtx_XOR (SImode,
4910 gen_rtx_ASHIFTRT (SImode,
4914 emit_insn (gen_rtx_SET (operands[0],
4915 gen_rtx_MINUS (SImode,
4917 gen_rtx_ASHIFTRT (SImode,
4923 [(set_attr "conds" "clob,*")
4924 (set_attr "shift" "1")
4925 (set_attr "predicable" "no, yes")
4926 (set_attr "length" "8")
4927 (set_attr "type" "multiple")]
4930 (define_insn_and_split "*arm_neg_abssi2"
4931 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4932 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4933 (clobber (reg:CC CC_REGNUM))]
4936 "&& reload_completed"
4939 /* if (which_alternative == 0) */
4940 if (REGNO (operands[0]) == REGNO (operands[1]))
4942 /* Emit the pattern:
4943 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4945 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4946 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4947 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4949 gen_rtx_REG (CCmode, CC_REGNUM),
4951 gen_rtx_SET (operands[0],
4952 (gen_rtx_MINUS (SImode,
4958 /* Emit the pattern:
4959 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4961 emit_insn (gen_rtx_SET (operands[0],
4962 gen_rtx_XOR (SImode,
4963 gen_rtx_ASHIFTRT (SImode,
4967 emit_insn (gen_rtx_SET (operands[0],
4968 gen_rtx_MINUS (SImode,
4969 gen_rtx_ASHIFTRT (SImode,
4976 [(set_attr "conds" "clob,*")
4977 (set_attr "shift" "1")
4978 (set_attr "predicable" "no, yes")
4979 (set_attr "length" "8")
4980 (set_attr "type" "multiple")]
4983 (define_expand "abssf2"
4984 [(set (match_operand:SF 0 "s_register_operand" "")
4985 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4986 "TARGET_32BIT && TARGET_HARD_FLOAT"
4989 (define_expand "absdf2"
4990 [(set (match_operand:DF 0 "s_register_operand" "")
4991 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4992 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4995 (define_expand "sqrtsf2"
4996 [(set (match_operand:SF 0 "s_register_operand" "")
4997 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4998 "TARGET_32BIT && TARGET_HARD_FLOAT"
5001 (define_expand "sqrtdf2"
5002 [(set (match_operand:DF 0 "s_register_operand" "")
5003 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5004 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5007 (define_expand "one_cmpldi2"
5008 [(set (match_operand:DI 0 "s_register_operand" "")
5009 (not:DI (match_operand:DI 1 "s_register_operand" "")))]
5012 if (!TARGET_NEON && !TARGET_IWMMXT)
5014 rtx low = simplify_gen_unary (NOT, SImode,
5015 gen_lowpart (SImode, operands[1]),
5017 rtx high = simplify_gen_unary (NOT, SImode,
5018 gen_highpart_mode (SImode, DImode,
5022 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5023 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5027 /* Otherwise expand pattern as above. */
5031 (define_insn_and_split "*one_cmpldi2_insn"
5032 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5033 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5040 "TARGET_32BIT && reload_completed
5041 && arm_general_register_operand (operands[0], DImode)"
5042 [(set (match_dup 0) (not:SI (match_dup 1)))
5043 (set (match_dup 2) (not:SI (match_dup 3)))]
5046 operands[2] = gen_highpart (SImode, operands[0]);
5047 operands[0] = gen_lowpart (SImode, operands[0]);
5048 operands[3] = gen_highpart (SImode, operands[1]);
5049 operands[1] = gen_lowpart (SImode, operands[1]);
5051 [(set_attr "length" "*,8,8,*")
5052 (set_attr "predicable" "no,yes,yes,no")
5053 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5054 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5057 (define_expand "one_cmplsi2"
5058 [(set (match_operand:SI 0 "s_register_operand" "")
5059 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5064 (define_insn "*arm_one_cmplsi2"
5065 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5066 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5069 [(set_attr "predicable" "yes")
5070 (set_attr "predicable_short_it" "yes,no")
5071 (set_attr "arch" "t2,*")
5072 (set_attr "length" "4")
5073 (set_attr "type" "mvn_reg")]
5076 (define_insn "*notsi_compare0"
5077 [(set (reg:CC_NOOV CC_REGNUM)
5078 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5080 (set (match_operand:SI 0 "s_register_operand" "=r")
5081 (not:SI (match_dup 1)))]
5084 [(set_attr "conds" "set")
5085 (set_attr "type" "mvn_reg")]
5088 (define_insn "*notsi_compare0_scratch"
5089 [(set (reg:CC_NOOV CC_REGNUM)
5090 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5092 (clobber (match_scratch:SI 0 "=r"))]
5095 [(set_attr "conds" "set")
5096 (set_attr "type" "mvn_reg")]
5099 ;; Fixed <--> Floating conversion insns
5101 (define_expand "floatsihf2"
5102 [(set (match_operand:HF 0 "general_operand" "")
5103 (float:HF (match_operand:SI 1 "general_operand" "")))]
5107 rtx op1 = gen_reg_rtx (SFmode);
5108 expand_float (op1, operands[1], 0);
5109 op1 = convert_to_mode (HFmode, op1, 0);
5110 emit_move_insn (operands[0], op1);
5115 (define_expand "floatdihf2"
5116 [(set (match_operand:HF 0 "general_operand" "")
5117 (float:HF (match_operand:DI 1 "general_operand" "")))]
5121 rtx op1 = gen_reg_rtx (SFmode);
5122 expand_float (op1, operands[1], 0);
5123 op1 = convert_to_mode (HFmode, op1, 0);
5124 emit_move_insn (operands[0], op1);
5129 (define_expand "floatsisf2"
5130 [(set (match_operand:SF 0 "s_register_operand" "")
5131 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5132 "TARGET_32BIT && TARGET_HARD_FLOAT"
5136 (define_expand "floatsidf2"
5137 [(set (match_operand:DF 0 "s_register_operand" "")
5138 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5139 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5143 (define_expand "fix_trunchfsi2"
5144 [(set (match_operand:SI 0 "general_operand" "")
5145 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5149 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5150 expand_fix (operands[0], op1, 0);
5155 (define_expand "fix_trunchfdi2"
5156 [(set (match_operand:DI 0 "general_operand" "")
5157 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5161 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5162 expand_fix (operands[0], op1, 0);
5167 (define_expand "fix_truncsfsi2"
5168 [(set (match_operand:SI 0 "s_register_operand" "")
5169 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5170 "TARGET_32BIT && TARGET_HARD_FLOAT"
5174 (define_expand "fix_truncdfsi2"
5175 [(set (match_operand:SI 0 "s_register_operand" "")
5176 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5177 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5183 (define_expand "truncdfsf2"
5184 [(set (match_operand:SF 0 "s_register_operand" "")
5186 (match_operand:DF 1 "s_register_operand" "")))]
5187 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5191 ;; DFmode to HFmode conversions on targets without a single-step hardware
5192 ;; instruction for it would have to go through SFmode. This is dangerous
5193 ;; as it introduces double rounding.
5195 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5196 ;; a single-step instruction.
5198 (define_expand "truncdfhf2"
5199 [(set (match_operand:HF 0 "s_register_operand" "")
5201 (match_operand:DF 1 "s_register_operand" "")))]
5202 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5203 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5205 /* We don't have a direct instruction for this, so we must be in
5206 an unsafe math mode, and going via SFmode. */
5208 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5211 op1 = convert_to_mode (SFmode, operands[1], 0);
5212 op1 = convert_to_mode (HFmode, op1, 0);
5213 emit_move_insn (operands[0], op1);
5216 /* Otherwise, we will pick this up as a single instruction with
5217 no intermediary rounding. */
5221 ;; Zero and sign extension instructions.
5223 (define_insn "zero_extend<mode>di2"
5224 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5225 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5226 "<qhs_zextenddi_cstr>")))]
5227 "TARGET_32BIT <qhs_zextenddi_cond>"
5229 [(set_attr "length" "8,4,8,8")
5230 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5231 (set_attr "ce_count" "2")
5232 (set_attr "predicable" "yes")
5233 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5236 (define_insn "extend<mode>di2"
5237 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5238 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5239 "<qhs_extenddi_cstr>")))]
5240 "TARGET_32BIT <qhs_sextenddi_cond>"
5242 [(set_attr "length" "8,4,8,8,8")
5243 (set_attr "ce_count" "2")
5244 (set_attr "shift" "1")
5245 (set_attr "predicable" "yes")
5246 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5247 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5250 ;; Splits for all extensions to DImode
5252 [(set (match_operand:DI 0 "s_register_operand" "")
5253 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5254 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5255 [(set (match_dup 0) (match_dup 1))]
5257 rtx lo_part = gen_lowpart (SImode, operands[0]);
5258 machine_mode src_mode = GET_MODE (operands[1]);
5260 if (REG_P (operands[0])
5261 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5262 emit_clobber (operands[0]);
5263 if (!REG_P (lo_part) || src_mode != SImode
5264 || !rtx_equal_p (lo_part, operands[1]))
5266 if (src_mode == SImode)
5267 emit_move_insn (lo_part, operands[1]);
5269 emit_insn (gen_rtx_SET (lo_part,
5270 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5271 operands[1] = lo_part;
5273 operands[0] = gen_highpart (SImode, operands[0]);
5274 operands[1] = const0_rtx;
5278 [(set (match_operand:DI 0 "s_register_operand" "")
5279 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5280 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5281 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5283 rtx lo_part = gen_lowpart (SImode, operands[0]);
5284 machine_mode src_mode = GET_MODE (operands[1]);
5286 if (REG_P (operands[0])
5287 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5288 emit_clobber (operands[0]);
5290 if (!REG_P (lo_part) || src_mode != SImode
5291 || !rtx_equal_p (lo_part, operands[1]))
5293 if (src_mode == SImode)
5294 emit_move_insn (lo_part, operands[1]);
5296 emit_insn (gen_rtx_SET (lo_part,
5297 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5298 operands[1] = lo_part;
5300 operands[0] = gen_highpart (SImode, operands[0]);
5303 (define_expand "zero_extendhisi2"
5304 [(set (match_operand:SI 0 "s_register_operand" "")
5305 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5308 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5310 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5313 if (!arm_arch6 && !MEM_P (operands[1]))
5315 rtx t = gen_lowpart (SImode, operands[1]);
5316 rtx tmp = gen_reg_rtx (SImode);
5317 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5318 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5324 [(set (match_operand:SI 0 "s_register_operand" "")
5325 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5326 "!TARGET_THUMB2 && !arm_arch6"
5327 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5328 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5330 operands[2] = gen_lowpart (SImode, operands[1]);
5333 (define_insn "*arm_zero_extendhisi2"
5334 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5335 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5336 "TARGET_ARM && arm_arch4 && !arm_arch6"
5340 [(set_attr "type" "alu_shift_reg,load_byte")
5341 (set_attr "predicable" "yes")]
5344 (define_insn "*arm_zero_extendhisi2_v6"
5345 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5346 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5347 "TARGET_ARM && arm_arch6"
5351 [(set_attr "predicable" "yes")
5352 (set_attr "type" "extend,load_byte")]
5355 (define_insn "*arm_zero_extendhisi2addsi"
5356 [(set (match_operand:SI 0 "s_register_operand" "=r")
5357 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5358 (match_operand:SI 2 "s_register_operand" "r")))]
5360 "uxtah%?\\t%0, %2, %1"
5361 [(set_attr "type" "alu_shift_reg")
5362 (set_attr "predicable" "yes")]
5365 (define_expand "zero_extendqisi2"
5366 [(set (match_operand:SI 0 "s_register_operand" "")
5367 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5370 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5372 emit_insn (gen_andsi3 (operands[0],
5373 gen_lowpart (SImode, operands[1]),
5377 if (!arm_arch6 && !MEM_P (operands[1]))
5379 rtx t = gen_lowpart (SImode, operands[1]);
5380 rtx tmp = gen_reg_rtx (SImode);
5381 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5382 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5388 [(set (match_operand:SI 0 "s_register_operand" "")
5389 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5391 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5392 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5394 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5397 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5402 (define_insn "*arm_zero_extendqisi2"
5403 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5404 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5405 "TARGET_ARM && !arm_arch6"
5408 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5409 [(set_attr "length" "8,4")
5410 (set_attr "type" "alu_shift_reg,load_byte")
5411 (set_attr "predicable" "yes")]
5414 (define_insn "*arm_zero_extendqisi2_v6"
5415 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5416 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5417 "TARGET_ARM && arm_arch6"
5420 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5421 [(set_attr "type" "extend,load_byte")
5422 (set_attr "predicable" "yes")]
5425 (define_insn "*arm_zero_extendqisi2addsi"
5426 [(set (match_operand:SI 0 "s_register_operand" "=r")
5427 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5428 (match_operand:SI 2 "s_register_operand" "r")))]
5430 "uxtab%?\\t%0, %2, %1"
5431 [(set_attr "predicable" "yes")
5432 (set_attr "type" "alu_shift_reg")]
5436 [(set (match_operand:SI 0 "s_register_operand" "")
5437 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5438 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5439 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5440 [(set (match_dup 2) (match_dup 1))
5441 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5446 [(set (match_operand:SI 0 "s_register_operand" "")
5447 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5448 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5449 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5450 [(set (match_dup 2) (match_dup 1))
5451 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5457 [(set (match_operand:SI 0 "s_register_operand" "")
5458 (IOR_XOR:SI (and:SI (ashift:SI
5459 (match_operand:SI 1 "s_register_operand" "")
5460 (match_operand:SI 2 "const_int_operand" ""))
5461 (match_operand:SI 3 "const_int_operand" ""))
5463 (match_operator 5 "subreg_lowpart_operator"
5464 [(match_operand:SI 4 "s_register_operand" "")]))))]
5466 && (UINTVAL (operands[3])
5467 == (GET_MODE_MASK (GET_MODE (operands[5]))
5468 & (GET_MODE_MASK (GET_MODE (operands[5]))
5469 << (INTVAL (operands[2])))))"
5470 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5472 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5473 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5476 (define_insn "*compareqi_eq0"
5477 [(set (reg:CC_Z CC_REGNUM)
5478 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5482 [(set_attr "conds" "set")
5483 (set_attr "predicable" "yes")
5484 (set_attr "type" "logic_imm")]
5487 (define_expand "extendhisi2"
5488 [(set (match_operand:SI 0 "s_register_operand" "")
5489 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5494 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5497 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5499 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5503 if (!arm_arch6 && !MEM_P (operands[1]))
5505 rtx t = gen_lowpart (SImode, operands[1]);
5506 rtx tmp = gen_reg_rtx (SImode);
5507 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5508 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5515 [(set (match_operand:SI 0 "register_operand" "")
5516 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5517 (clobber (match_scratch:SI 2 ""))])]
5519 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5520 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5522 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5525 ;; This pattern will only be used when ldsh is not available
5526 (define_expand "extendhisi2_mem"
5527 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5529 (zero_extend:SI (match_dup 7)))
5530 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5531 (set (match_operand:SI 0 "" "")
5532 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5537 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5539 mem1 = change_address (operands[1], QImode, addr);
5540 mem2 = change_address (operands[1], QImode,
5541 plus_constant (Pmode, addr, 1));
5542 operands[0] = gen_lowpart (SImode, operands[0]);
5544 operands[2] = gen_reg_rtx (SImode);
5545 operands[3] = gen_reg_rtx (SImode);
5546 operands[6] = gen_reg_rtx (SImode);
5549 if (BYTES_BIG_ENDIAN)
5551 operands[4] = operands[2];
5552 operands[5] = operands[3];
5556 operands[4] = operands[3];
5557 operands[5] = operands[2];
5563 [(set (match_operand:SI 0 "register_operand" "")
5564 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5566 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5567 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5569 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5572 (define_insn "*arm_extendhisi2"
5573 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5574 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5575 "TARGET_ARM && arm_arch4 && !arm_arch6"
5579 [(set_attr "length" "8,4")
5580 (set_attr "type" "alu_shift_reg,load_byte")
5581 (set_attr "predicable" "yes")]
5584 ;; ??? Check Thumb-2 pool range
5585 (define_insn "*arm_extendhisi2_v6"
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_32BIT && arm_arch6"
5592 [(set_attr "type" "extend,load_byte")
5593 (set_attr "predicable" "yes")]
5596 (define_insn "*arm_extendhisi2addsi"
5597 [(set (match_operand:SI 0 "s_register_operand" "=r")
5598 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5599 (match_operand:SI 2 "s_register_operand" "r")))]
5601 "sxtah%?\\t%0, %2, %1"
5602 [(set_attr "type" "alu_shift_reg")]
5605 (define_expand "extendqihi2"
5607 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5609 (set (match_operand:HI 0 "s_register_operand" "")
5610 (ashiftrt:SI (match_dup 2)
5615 if (arm_arch4 && MEM_P (operands[1]))
5617 emit_insn (gen_rtx_SET (operands[0],
5618 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5621 if (!s_register_operand (operands[1], QImode))
5622 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5623 operands[0] = gen_lowpart (SImode, operands[0]);
5624 operands[1] = gen_lowpart (SImode, operands[1]);
5625 operands[2] = gen_reg_rtx (SImode);
5629 (define_insn "*arm_extendqihi_insn"
5630 [(set (match_operand:HI 0 "s_register_operand" "=r")
5631 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5632 "TARGET_ARM && arm_arch4"
5634 [(set_attr "type" "load_byte")
5635 (set_attr "predicable" "yes")]
5638 (define_expand "extendqisi2"
5639 [(set (match_operand:SI 0 "s_register_operand" "")
5640 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5643 if (!arm_arch4 && MEM_P (operands[1]))
5644 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5646 if (!arm_arch6 && !MEM_P (operands[1]))
5648 rtx t = gen_lowpart (SImode, operands[1]);
5649 rtx tmp = gen_reg_rtx (SImode);
5650 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5651 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5657 [(set (match_operand:SI 0 "register_operand" "")
5658 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5660 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5661 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5663 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5666 (define_insn "*arm_extendqisi"
5667 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5668 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5669 "TARGET_ARM && arm_arch4 && !arm_arch6"
5673 [(set_attr "length" "8,4")
5674 (set_attr "type" "alu_shift_reg,load_byte")
5675 (set_attr "predicable" "yes")]
5678 (define_insn "*arm_extendqisi_v6"
5679 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5681 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5682 "TARGET_ARM && arm_arch6"
5686 [(set_attr "type" "extend,load_byte")
5687 (set_attr "predicable" "yes")]
5690 (define_insn "*arm_extendqisi2addsi"
5691 [(set (match_operand:SI 0 "s_register_operand" "=r")
5692 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5693 (match_operand:SI 2 "s_register_operand" "r")))]
5695 "sxtab%?\\t%0, %2, %1"
5696 [(set_attr "type" "alu_shift_reg")
5697 (set_attr "predicable" "yes")]
5700 (define_expand "extendsfdf2"
5701 [(set (match_operand:DF 0 "s_register_operand" "")
5702 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5703 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5707 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5708 ;; must go through SFmode.
5710 ;; This is always safe for an extend.
5712 (define_expand "extendhfdf2"
5713 [(set (match_operand:DF 0 "s_register_operand" "")
5714 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5717 /* We don't have a direct instruction for this, so go via SFmode. */
5718 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5721 op1 = convert_to_mode (SFmode, operands[1], 0);
5722 op1 = convert_to_mode (DFmode, op1, 0);
5723 emit_insn (gen_movdf (operands[0], op1));
5726 /* Otherwise, we're done producing RTL and will pick up the correct
5727 pattern to do this with one rounding-step in a single instruction. */
5731 ;; Move insns (including loads and stores)
5733 ;; XXX Just some ideas about movti.
5734 ;; I don't think these are a good idea on the arm, there just aren't enough
5736 ;;(define_expand "loadti"
5737 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5738 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5741 ;;(define_expand "storeti"
5742 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5743 ;; (match_operand:TI 1 "s_register_operand" ""))]
5746 ;;(define_expand "movti"
5747 ;; [(set (match_operand:TI 0 "general_operand" "")
5748 ;; (match_operand:TI 1 "general_operand" ""))]
5754 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5755 ;; operands[1] = copy_to_reg (operands[1]);
5756 ;; if (MEM_P (operands[0]))
5757 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5758 ;; else if (MEM_P (operands[1]))
5759 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5763 ;; emit_insn (insn);
5767 ;; Recognize garbage generated above.
5770 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5771 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5775 ;; register mem = (which_alternative < 3);
5776 ;; register const char *template;
5778 ;; operands[mem] = XEXP (operands[mem], 0);
5779 ;; switch (which_alternative)
5781 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5782 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5783 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5784 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5785 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5786 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5788 ;; output_asm_insn (template, operands);
5792 (define_expand "movdi"
5793 [(set (match_operand:DI 0 "general_operand" "")
5794 (match_operand:DI 1 "general_operand" ""))]
5797 if (can_create_pseudo_p ())
5799 if (!REG_P (operands[0]))
5800 operands[1] = force_reg (DImode, operands[1]);
5802 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5803 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5805 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5806 when expanding function calls. */
5807 gcc_assert (can_create_pseudo_p ());
5808 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5810 /* Perform load into legal reg pair first, then move. */
5811 rtx reg = gen_reg_rtx (DImode);
5812 emit_insn (gen_movdi (reg, operands[1]));
5815 emit_move_insn (gen_lowpart (SImode, operands[0]),
5816 gen_lowpart (SImode, operands[1]));
5817 emit_move_insn (gen_highpart (SImode, operands[0]),
5818 gen_highpart (SImode, operands[1]));
5821 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5822 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5824 /* Avoid STRD's from an odd-numbered register pair in ARM state
5825 when expanding function prologue. */
5826 gcc_assert (can_create_pseudo_p ());
5827 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5828 ? gen_reg_rtx (DImode)
5830 emit_move_insn (gen_lowpart (SImode, split_dest),
5831 gen_lowpart (SImode, operands[1]));
5832 emit_move_insn (gen_highpart (SImode, split_dest),
5833 gen_highpart (SImode, operands[1]));
5834 if (split_dest != operands[0])
5835 emit_insn (gen_movdi (operands[0], split_dest));
5841 (define_insn "*arm_movdi"
5842 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
5843 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
5845 && !(TARGET_HARD_FLOAT)
5847 && ( register_operand (operands[0], DImode)
5848 || register_operand (operands[1], DImode))"
5850 switch (which_alternative)
5857 /* Cannot load it directly, split to load it via MOV / MOVT. */
5858 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
5862 return output_move_double (operands, true, NULL);
5865 [(set_attr "length" "8,12,16,8,8")
5866 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5867 (set_attr "arm_pool_range" "*,*,*,1020,*")
5868 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5869 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5870 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5874 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5875 (match_operand:ANY64 1 "immediate_operand" ""))]
5878 && (arm_disable_literal_pool
5879 || (arm_const_double_inline_cost (operands[1])
5880 <= arm_max_const_double_inline_cost ()))"
5883 arm_split_constant (SET, SImode, curr_insn,
5884 INTVAL (gen_lowpart (SImode, operands[1])),
5885 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5886 arm_split_constant (SET, SImode, curr_insn,
5887 INTVAL (gen_highpart_mode (SImode,
5888 GET_MODE (operands[0]),
5890 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5895 ; If optimizing for size, or if we have load delay slots, then
5896 ; we want to split the constant into two separate operations.
5897 ; In both cases this may split a trivial part into a single data op
5898 ; leaving a single complex constant to load. We can also get longer
5899 ; offsets in a LDR which means we get better chances of sharing the pool
5900 ; entries. Finally, we can normally do a better job of scheduling
5901 ; LDR instructions than we can with LDM.
5902 ; This pattern will only match if the one above did not.
5904 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5905 (match_operand:ANY64 1 "const_double_operand" ""))]
5906 "TARGET_ARM && reload_completed
5907 && arm_const_double_by_parts (operands[1])"
5908 [(set (match_dup 0) (match_dup 1))
5909 (set (match_dup 2) (match_dup 3))]
5911 operands[2] = gen_highpart (SImode, operands[0]);
5912 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5914 operands[0] = gen_lowpart (SImode, operands[0]);
5915 operands[1] = gen_lowpart (SImode, operands[1]);
5920 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5921 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5922 "TARGET_EITHER && reload_completed"
5923 [(set (match_dup 0) (match_dup 1))
5924 (set (match_dup 2) (match_dup 3))]
5926 operands[2] = gen_highpart (SImode, operands[0]);
5927 operands[3] = gen_highpart (SImode, operands[1]);
5928 operands[0] = gen_lowpart (SImode, operands[0]);
5929 operands[1] = gen_lowpart (SImode, operands[1]);
5931 /* Handle a partial overlap. */
5932 if (rtx_equal_p (operands[0], operands[3]))
5934 rtx tmp0 = operands[0];
5935 rtx tmp1 = operands[1];
5937 operands[0] = operands[2];
5938 operands[1] = operands[3];
5945 ;; We can't actually do base+index doubleword loads if the index and
5946 ;; destination overlap. Split here so that we at least have chance to
5949 [(set (match_operand:DI 0 "s_register_operand" "")
5950 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5951 (match_operand:SI 2 "s_register_operand" ""))))]
5953 && reg_overlap_mentioned_p (operands[0], operands[1])
5954 && reg_overlap_mentioned_p (operands[0], operands[2])"
5956 (plus:SI (match_dup 1)
5959 (mem:DI (match_dup 4)))]
5961 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5965 (define_expand "movsi"
5966 [(set (match_operand:SI 0 "general_operand" "")
5967 (match_operand:SI 1 "general_operand" ""))]
5971 rtx base, offset, tmp;
5973 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5975 /* Everything except mem = const or mem = mem can be done easily. */
5976 if (MEM_P (operands[0]))
5977 operands[1] = force_reg (SImode, operands[1]);
5978 if (arm_general_register_operand (operands[0], SImode)
5979 && CONST_INT_P (operands[1])
5980 && !(const_ok_for_arm (INTVAL (operands[1]))
5981 || const_ok_for_arm (~INTVAL (operands[1]))))
5983 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5985 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5990 arm_split_constant (SET, SImode, NULL_RTX,
5991 INTVAL (operands[1]), operands[0], NULL_RTX,
5992 optimize && can_create_pseudo_p ());
5997 else /* Target doesn't have MOVT... */
5999 if (can_create_pseudo_p ())
6001 if (!REG_P (operands[0]))
6002 operands[1] = force_reg (SImode, operands[1]);
6006 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6008 split_const (operands[1], &base, &offset);
6009 if (GET_CODE (base) == SYMBOL_REF
6010 && !offset_within_block_p (base, INTVAL (offset)))
6012 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6013 emit_move_insn (tmp, base);
6014 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6019 /* Recognize the case where operand[1] is a reference to thread-local
6020 data and load its address to a register. */
6021 if (arm_tls_referenced_p (operands[1]))
6023 rtx tmp = operands[1];
6026 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6028 addend = XEXP (XEXP (tmp, 0), 1);
6029 tmp = XEXP (XEXP (tmp, 0), 0);
6032 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6033 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6035 tmp = legitimize_tls_address (tmp,
6036 !can_create_pseudo_p () ? operands[0] : 0);
6039 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6040 tmp = force_operand (tmp, operands[0]);
6045 && (CONSTANT_P (operands[1])
6046 || symbol_mentioned_p (operands[1])
6047 || label_mentioned_p (operands[1])))
6048 operands[1] = legitimize_pic_address (operands[1], SImode,
6049 (!can_create_pseudo_p ()
6051 : NULL_RTX), NULL_RTX,
6052 false /*compute_now*/);
6057 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6058 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6059 ;; so this does not matter.
6060 (define_insn "*arm_movt"
6061 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6062 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6063 (match_operand:SI 2 "general_operand" "i,i")))]
6064 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6066 movt%?\t%0, #:upper16:%c2
6067 movt\t%0, #:upper16:%c2"
6068 [(set_attr "arch" "32,v8mb")
6069 (set_attr "predicable" "yes")
6070 (set_attr "length" "4")
6071 (set_attr "type" "alu_sreg")]
6074 (define_insn "*arm_movsi_insn"
6075 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6076 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6077 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6078 && ( register_operand (operands[0], SImode)
6079 || register_operand (operands[1], SImode))"
6087 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6088 (set_attr "predicable" "yes")
6089 (set_attr "arch" "*,*,*,v6t2,*,*")
6090 (set_attr "pool_range" "*,*,*,*,4096,*")
6091 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6095 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6096 (match_operand:SI 1 "const_int_operand" ""))]
6097 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6098 && (!(const_ok_for_arm (INTVAL (operands[1]))
6099 || const_ok_for_arm (~INTVAL (operands[1]))))"
6100 [(clobber (const_int 0))]
6102 arm_split_constant (SET, SImode, NULL_RTX,
6103 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6108 ;; A normal way to do (symbol + offset) requires three instructions at least
6109 ;; (depends on how big the offset is) as below:
6110 ;; movw r0, #:lower16:g
6111 ;; movw r0, #:upper16:g
6114 ;; A better way would be:
6115 ;; movw r0, #:lower16:g+4
6116 ;; movw r0, #:upper16:g+4
6118 ;; The limitation of this way is that the length of offset should be a 16-bit
6119 ;; signed value, because current assembler only supports REL type relocation for
6120 ;; such case. If the more powerful RELA type is supported in future, we should
6121 ;; update this pattern to go with better way.
6123 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6124 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6125 (match_operand:SI 2 "const_int_operand" ""))))]
6128 && arm_disable_literal_pool
6130 && GET_CODE (operands[1]) == SYMBOL_REF"
6131 [(clobber (const_int 0))]
6133 int offset = INTVAL (operands[2]);
6135 if (offset < -0x8000 || offset > 0x7fff)
6137 arm_emit_movpair (operands[0], operands[1]);
6138 emit_insn (gen_rtx_SET (operands[0],
6139 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6143 rtx op = gen_rtx_CONST (SImode,
6144 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6145 arm_emit_movpair (operands[0], op);
6150 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6151 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6152 ;; and lo_sum would be merged back into memory load at cprop. However,
6153 ;; if the default is to prefer movt/movw rather than a load from the constant
6154 ;; pool, the performance is better.
6156 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6157 (match_operand:SI 1 "general_operand" ""))]
6158 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6159 && !target_word_relocations
6160 && !arm_tls_referenced_p (operands[1])"
6161 [(clobber (const_int 0))]
6163 arm_emit_movpair (operands[0], operands[1]);
6167 ;; When generating pic, we need to load the symbol offset into a register.
6168 ;; So that the optimizer does not confuse this with a normal symbol load
6169 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6170 ;; since that is the only type of relocation we can use.
6172 ;; Wrap calculation of the whole PIC address in a single pattern for the
6173 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6174 ;; a PIC address involves two loads from memory, so we want to CSE it
6175 ;; as often as possible.
6176 ;; This pattern will be split into one of the pic_load_addr_* patterns
6177 ;; and a move after GCSE optimizations.
6179 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6180 (define_expand "calculate_pic_address"
6181 [(set (match_operand:SI 0 "register_operand" "")
6182 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6183 (unspec:SI [(match_operand:SI 2 "" "")]
6188 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6190 [(set (match_operand:SI 0 "register_operand" "")
6191 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6192 (unspec:SI [(match_operand:SI 2 "" "")]
6195 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6196 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6197 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6200 ;; operand1 is the memory address to go into
6201 ;; pic_load_addr_32bit.
6202 ;; operand2 is the PIC label to be emitted
6203 ;; from pic_add_dot_plus_eight.
6204 ;; We do this to allow hoisting of the entire insn.
6205 (define_insn_and_split "pic_load_addr_unified"
6206 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6207 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6208 (match_operand:SI 2 "" "")]
6209 UNSPEC_PIC_UNIFIED))]
6212 "&& reload_completed"
6213 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6214 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6215 (match_dup 2)] UNSPEC_PIC_BASE))]
6216 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6217 [(set_attr "type" "load_4,load_4,load_4")
6218 (set_attr "pool_range" "4096,4094,1022")
6219 (set_attr "neg_pool_range" "4084,0,0")
6220 (set_attr "arch" "a,t2,t1")
6221 (set_attr "length" "8,6,4")]
6224 ;; The rather odd constraints on the following are to force reload to leave
6225 ;; the insn alone, and to force the minipool generation pass to then move
6226 ;; the GOT symbol to memory.
6228 (define_insn "pic_load_addr_32bit"
6229 [(set (match_operand:SI 0 "s_register_operand" "=r")
6230 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6231 "TARGET_32BIT && flag_pic"
6233 [(set_attr "type" "load_4")
6234 (set (attr "pool_range")
6235 (if_then_else (eq_attr "is_thumb" "no")
6238 (set (attr "neg_pool_range")
6239 (if_then_else (eq_attr "is_thumb" "no")
6244 (define_insn "pic_load_addr_thumb1"
6245 [(set (match_operand:SI 0 "s_register_operand" "=l")
6246 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6247 "TARGET_THUMB1 && flag_pic"
6249 [(set_attr "type" "load_4")
6250 (set (attr "pool_range") (const_int 1018))]
6253 (define_insn "pic_add_dot_plus_four"
6254 [(set (match_operand:SI 0 "register_operand" "=r")
6255 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6257 (match_operand 2 "" "")]
6261 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6262 INTVAL (operands[2]));
6263 return \"add\\t%0, %|pc\";
6265 [(set_attr "length" "2")
6266 (set_attr "type" "alu_sreg")]
6269 (define_insn "pic_add_dot_plus_eight"
6270 [(set (match_operand:SI 0 "register_operand" "=r")
6271 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6273 (match_operand 2 "" "")]
6277 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6278 INTVAL (operands[2]));
6279 return \"add%?\\t%0, %|pc, %1\";
6281 [(set_attr "predicable" "yes")
6282 (set_attr "type" "alu_sreg")]
6285 (define_insn "tls_load_dot_plus_eight"
6286 [(set (match_operand:SI 0 "register_operand" "=r")
6287 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6289 (match_operand 2 "" "")]
6293 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6294 INTVAL (operands[2]));
6295 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6297 [(set_attr "predicable" "yes")
6298 (set_attr "type" "load_4")]
6301 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6302 ;; followed by a load. These sequences can be crunched down to
6303 ;; tls_load_dot_plus_eight by a peephole.
6306 [(set (match_operand:SI 0 "register_operand" "")
6307 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6309 (match_operand 1 "" "")]
6311 (set (match_operand:SI 2 "arm_general_register_operand" "")
6312 (mem:SI (match_dup 0)))]
6313 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6315 (mem:SI (unspec:SI [(match_dup 3)
6322 (define_insn "pic_offset_arm"
6323 [(set (match_operand:SI 0 "register_operand" "=r")
6324 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6325 (unspec:SI [(match_operand:SI 2 "" "X")]
6326 UNSPEC_PIC_OFFSET))))]
6327 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6328 "ldr%?\\t%0, [%1,%2]"
6329 [(set_attr "type" "load_4")]
6332 (define_expand "builtin_setjmp_receiver"
6333 [(label_ref (match_operand 0 "" ""))]
6337 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6339 if (arm_pic_register != INVALID_REGNUM)
6340 arm_load_pic_register (1UL << 3, NULL_RTX);
6344 ;; If copying one reg to another we can set the condition codes according to
6345 ;; its value. Such a move is common after a return from subroutine and the
6346 ;; result is being tested against zero.
6348 (define_insn "*movsi_compare0"
6349 [(set (reg:CC CC_REGNUM)
6350 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6352 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6357 subs%?\\t%0, %1, #0"
6358 [(set_attr "conds" "set")
6359 (set_attr "type" "alus_imm,alus_imm")]
6362 ;; Subroutine to store a half word from a register into memory.
6363 ;; Operand 0 is the source register (HImode)
6364 ;; Operand 1 is the destination address in a register (SImode)
6366 ;; In both this routine and the next, we must be careful not to spill
6367 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6368 ;; can generate unrecognizable rtl.
6370 (define_expand "storehi"
6371 [;; store the low byte
6372 (set (match_operand 1 "" "") (match_dup 3))
6373 ;; extract the high byte
6375 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6376 ;; store the high byte
6377 (set (match_dup 4) (match_dup 5))]
6381 rtx op1 = operands[1];
6382 rtx addr = XEXP (op1, 0);
6383 enum rtx_code code = GET_CODE (addr);
6385 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6387 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6389 operands[4] = adjust_address (op1, QImode, 1);
6390 operands[1] = adjust_address (operands[1], QImode, 0);
6391 operands[3] = gen_lowpart (QImode, operands[0]);
6392 operands[0] = gen_lowpart (SImode, operands[0]);
6393 operands[2] = gen_reg_rtx (SImode);
6394 operands[5] = gen_lowpart (QImode, operands[2]);
6398 (define_expand "storehi_bigend"
6399 [(set (match_dup 4) (match_dup 3))
6401 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6402 (set (match_operand 1 "" "") (match_dup 5))]
6406 rtx op1 = operands[1];
6407 rtx addr = XEXP (op1, 0);
6408 enum rtx_code code = GET_CODE (addr);
6410 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6412 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6414 operands[4] = adjust_address (op1, QImode, 1);
6415 operands[1] = adjust_address (operands[1], QImode, 0);
6416 operands[3] = gen_lowpart (QImode, operands[0]);
6417 operands[0] = gen_lowpart (SImode, operands[0]);
6418 operands[2] = gen_reg_rtx (SImode);
6419 operands[5] = gen_lowpart (QImode, operands[2]);
6423 ;; Subroutine to store a half word integer constant into memory.
6424 (define_expand "storeinthi"
6425 [(set (match_operand 0 "" "")
6426 (match_operand 1 "" ""))
6427 (set (match_dup 3) (match_dup 2))]
6431 HOST_WIDE_INT value = INTVAL (operands[1]);
6432 rtx addr = XEXP (operands[0], 0);
6433 rtx op0 = operands[0];
6434 enum rtx_code code = GET_CODE (addr);
6436 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6438 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6440 operands[1] = gen_reg_rtx (SImode);
6441 if (BYTES_BIG_ENDIAN)
6443 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 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 & 255)));
6454 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6455 if ((value & 255) == ((value >> 8) & 255))
6456 operands[2] = operands[1];
6459 operands[2] = gen_reg_rtx (SImode);
6460 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6464 operands[3] = adjust_address (op0, QImode, 1);
6465 operands[0] = adjust_address (operands[0], QImode, 0);
6466 operands[2] = gen_lowpart (QImode, operands[2]);
6467 operands[1] = gen_lowpart (QImode, operands[1]);
6471 (define_expand "storehi_single_op"
6472 [(set (match_operand:HI 0 "memory_operand" "")
6473 (match_operand:HI 1 "general_operand" ""))]
6474 "TARGET_32BIT && arm_arch4"
6476 if (!s_register_operand (operands[1], HImode))
6477 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6481 (define_expand "movhi"
6482 [(set (match_operand:HI 0 "general_operand" "")
6483 (match_operand:HI 1 "general_operand" ""))]
6488 if (can_create_pseudo_p ())
6490 if (MEM_P (operands[0]))
6494 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6497 if (CONST_INT_P (operands[1]))
6498 emit_insn (gen_storeinthi (operands[0], operands[1]));
6501 if (MEM_P (operands[1]))
6502 operands[1] = force_reg (HImode, operands[1]);
6503 if (BYTES_BIG_ENDIAN)
6504 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6506 emit_insn (gen_storehi (operands[1], operands[0]));
6510 /* Sign extend a constant, and keep it in an SImode reg. */
6511 else if (CONST_INT_P (operands[1]))
6513 rtx reg = gen_reg_rtx (SImode);
6514 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6516 /* If the constant is already valid, leave it alone. */
6517 if (!const_ok_for_arm (val))
6519 /* If setting all the top bits will make the constant
6520 loadable in a single instruction, then set them.
6521 Otherwise, sign extend the number. */
6523 if (const_ok_for_arm (~(val | ~0xffff)))
6525 else if (val & 0x8000)
6529 emit_insn (gen_movsi (reg, GEN_INT (val)));
6530 operands[1] = gen_lowpart (HImode, reg);
6532 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6533 && MEM_P (operands[1]))
6535 rtx reg = gen_reg_rtx (SImode);
6537 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6538 operands[1] = gen_lowpart (HImode, reg);
6540 else if (!arm_arch4)
6542 if (MEM_P (operands[1]))
6545 rtx offset = const0_rtx;
6546 rtx reg = gen_reg_rtx (SImode);
6548 if ((REG_P (base = XEXP (operands[1], 0))
6549 || (GET_CODE (base) == PLUS
6550 && (CONST_INT_P (offset = XEXP (base, 1)))
6551 && ((INTVAL(offset) & 1) != 1)
6552 && REG_P (base = XEXP (base, 0))))
6553 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6557 new_rtx = widen_memory_access (operands[1], SImode,
6558 ((INTVAL (offset) & ~3)
6559 - INTVAL (offset)));
6560 emit_insn (gen_movsi (reg, new_rtx));
6561 if (((INTVAL (offset) & 2) != 0)
6562 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6564 rtx reg2 = gen_reg_rtx (SImode);
6566 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6571 emit_insn (gen_movhi_bytes (reg, operands[1]));
6573 operands[1] = gen_lowpart (HImode, reg);
6577 /* Handle loading a large integer during reload. */
6578 else if (CONST_INT_P (operands[1])
6579 && !const_ok_for_arm (INTVAL (operands[1]))
6580 && !const_ok_for_arm (~INTVAL (operands[1])))
6582 /* Writing a constant to memory needs a scratch, which should
6583 be handled with SECONDARY_RELOADs. */
6584 gcc_assert (REG_P (operands[0]));
6586 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6587 emit_insn (gen_movsi (operands[0], operands[1]));
6591 else if (TARGET_THUMB2)
6593 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6594 if (can_create_pseudo_p ())
6596 if (!REG_P (operands[0]))
6597 operands[1] = force_reg (HImode, operands[1]);
6598 /* Zero extend a constant, and keep it in an SImode reg. */
6599 else if (CONST_INT_P (operands[1]))
6601 rtx reg = gen_reg_rtx (SImode);
6602 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6604 emit_insn (gen_movsi (reg, GEN_INT (val)));
6605 operands[1] = gen_lowpart (HImode, reg);
6609 else /* TARGET_THUMB1 */
6611 if (can_create_pseudo_p ())
6613 if (CONST_INT_P (operands[1]))
6615 rtx reg = gen_reg_rtx (SImode);
6617 emit_insn (gen_movsi (reg, operands[1]));
6618 operands[1] = gen_lowpart (HImode, reg);
6621 /* ??? We shouldn't really get invalid addresses here, but this can
6622 happen if we are passed a SP (never OK for HImode/QImode) or
6623 virtual register (also rejected as illegitimate for HImode/QImode)
6624 relative address. */
6625 /* ??? This should perhaps be fixed elsewhere, for instance, in
6626 fixup_stack_1, by checking for other kinds of invalid addresses,
6627 e.g. a bare reference to a virtual register. This may confuse the
6628 alpha though, which must handle this case differently. */
6629 if (MEM_P (operands[0])
6630 && !memory_address_p (GET_MODE (operands[0]),
6631 XEXP (operands[0], 0)))
6633 = replace_equiv_address (operands[0],
6634 copy_to_reg (XEXP (operands[0], 0)));
6636 if (MEM_P (operands[1])
6637 && !memory_address_p (GET_MODE (operands[1]),
6638 XEXP (operands[1], 0)))
6640 = replace_equiv_address (operands[1],
6641 copy_to_reg (XEXP (operands[1], 0)));
6643 if (MEM_P (operands[1]) && optimize > 0)
6645 rtx reg = gen_reg_rtx (SImode);
6647 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6648 operands[1] = gen_lowpart (HImode, reg);
6651 if (MEM_P (operands[0]))
6652 operands[1] = force_reg (HImode, operands[1]);
6654 else if (CONST_INT_P (operands[1])
6655 && !satisfies_constraint_I (operands[1]))
6657 /* Handle loading a large integer during reload. */
6659 /* Writing a constant to memory needs a scratch, which should
6660 be handled with SECONDARY_RELOADs. */
6661 gcc_assert (REG_P (operands[0]));
6663 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6664 emit_insn (gen_movsi (operands[0], operands[1]));
6671 (define_expand "movhi_bytes"
6672 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6674 (zero_extend:SI (match_dup 6)))
6675 (set (match_operand:SI 0 "" "")
6676 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6681 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6683 mem1 = change_address (operands[1], QImode, addr);
6684 mem2 = change_address (operands[1], QImode,
6685 plus_constant (Pmode, addr, 1));
6686 operands[0] = gen_lowpart (SImode, operands[0]);
6688 operands[2] = gen_reg_rtx (SImode);
6689 operands[3] = gen_reg_rtx (SImode);
6692 if (BYTES_BIG_ENDIAN)
6694 operands[4] = operands[2];
6695 operands[5] = operands[3];
6699 operands[4] = operands[3];
6700 operands[5] = operands[2];
6705 (define_expand "movhi_bigend"
6707 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6710 (ashiftrt:SI (match_dup 2) (const_int 16)))
6711 (set (match_operand:HI 0 "s_register_operand" "")
6715 operands[2] = gen_reg_rtx (SImode);
6716 operands[3] = gen_reg_rtx (SImode);
6717 operands[4] = gen_lowpart (HImode, operands[3]);
6721 ;; Pattern to recognize insn generated default case above
6722 (define_insn "*movhi_insn_arch4"
6723 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6724 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6726 && arm_arch4 && !TARGET_HARD_FLOAT
6727 && (register_operand (operands[0], HImode)
6728 || register_operand (operands[1], HImode))"
6730 mov%?\\t%0, %1\\t%@ movhi
6731 mvn%?\\t%0, #%B1\\t%@ movhi
6732 movw%?\\t%0, %L1\\t%@ movhi
6733 strh%?\\t%1, %0\\t%@ movhi
6734 ldrh%?\\t%0, %1\\t%@ movhi"
6735 [(set_attr "predicable" "yes")
6736 (set_attr "pool_range" "*,*,*,*,256")
6737 (set_attr "neg_pool_range" "*,*,*,*,244")
6738 (set_attr "arch" "*,*,v6t2,*,*")
6739 (set_attr_alternative "type"
6740 [(if_then_else (match_operand 1 "const_int_operand" "")
6741 (const_string "mov_imm" )
6742 (const_string "mov_reg"))
6743 (const_string "mvn_imm")
6744 (const_string "mov_imm")
6745 (const_string "store_4")
6746 (const_string "load_4")])]
6749 (define_insn "*movhi_bytes"
6750 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6751 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6752 "TARGET_ARM && !TARGET_HARD_FLOAT"
6754 mov%?\\t%0, %1\\t%@ movhi
6755 mov%?\\t%0, %1\\t%@ movhi
6756 mvn%?\\t%0, #%B1\\t%@ movhi"
6757 [(set_attr "predicable" "yes")
6758 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6761 ;; We use a DImode scratch because we may occasionally need an additional
6762 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6763 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6764 (define_expand "reload_outhi"
6765 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6766 (match_operand:HI 1 "s_register_operand" "r")
6767 (match_operand:DI 2 "s_register_operand" "=&l")])]
6770 arm_reload_out_hi (operands);
6772 thumb_reload_out_hi (operands);
6777 (define_expand "reload_inhi"
6778 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6779 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6780 (match_operand:DI 2 "s_register_operand" "=&r")])]
6784 arm_reload_in_hi (operands);
6786 thumb_reload_out_hi (operands);
6790 (define_expand "movqi"
6791 [(set (match_operand:QI 0 "general_operand" "")
6792 (match_operand:QI 1 "general_operand" ""))]
6795 /* Everything except mem = const or mem = mem can be done easily */
6797 if (can_create_pseudo_p ())
6799 if (CONST_INT_P (operands[1]))
6801 rtx reg = gen_reg_rtx (SImode);
6803 /* For thumb we want an unsigned immediate, then we are more likely
6804 to be able to use a movs insn. */
6806 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6808 emit_insn (gen_movsi (reg, operands[1]));
6809 operands[1] = gen_lowpart (QImode, reg);
6814 /* ??? We shouldn't really get invalid addresses here, but this can
6815 happen if we are passed a SP (never OK for HImode/QImode) or
6816 virtual register (also rejected as illegitimate for HImode/QImode)
6817 relative address. */
6818 /* ??? This should perhaps be fixed elsewhere, for instance, in
6819 fixup_stack_1, by checking for other kinds of invalid addresses,
6820 e.g. a bare reference to a virtual register. This may confuse the
6821 alpha though, which must handle this case differently. */
6822 if (MEM_P (operands[0])
6823 && !memory_address_p (GET_MODE (operands[0]),
6824 XEXP (operands[0], 0)))
6826 = replace_equiv_address (operands[0],
6827 copy_to_reg (XEXP (operands[0], 0)));
6828 if (MEM_P (operands[1])
6829 && !memory_address_p (GET_MODE (operands[1]),
6830 XEXP (operands[1], 0)))
6832 = replace_equiv_address (operands[1],
6833 copy_to_reg (XEXP (operands[1], 0)));
6836 if (MEM_P (operands[1]) && optimize > 0)
6838 rtx reg = gen_reg_rtx (SImode);
6840 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6841 operands[1] = gen_lowpart (QImode, reg);
6844 if (MEM_P (operands[0]))
6845 operands[1] = force_reg (QImode, operands[1]);
6847 else if (TARGET_THUMB
6848 && CONST_INT_P (operands[1])
6849 && !satisfies_constraint_I (operands[1]))
6851 /* Handle loading a large integer during reload. */
6853 /* Writing a constant to memory needs a scratch, which should
6854 be handled with SECONDARY_RELOADs. */
6855 gcc_assert (REG_P (operands[0]));
6857 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6858 emit_insn (gen_movsi (operands[0], operands[1]));
6864 (define_insn "*arm_movqi_insn"
6865 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6866 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6868 && ( register_operand (operands[0], QImode)
6869 || register_operand (operands[1], QImode))"
6880 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6881 (set_attr "predicable" "yes")
6882 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6883 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6884 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6888 (define_expand "movhf"
6889 [(set (match_operand:HF 0 "general_operand" "")
6890 (match_operand:HF 1 "general_operand" ""))]
6895 if (MEM_P (operands[0]))
6896 operands[1] = force_reg (HFmode, operands[1]);
6898 else /* TARGET_THUMB1 */
6900 if (can_create_pseudo_p ())
6902 if (!REG_P (operands[0]))
6903 operands[1] = force_reg (HFmode, operands[1]);
6909 (define_insn "*arm32_movhf"
6910 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6911 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6912 "TARGET_32BIT && !TARGET_HARD_FLOAT
6913 && ( s_register_operand (operands[0], HFmode)
6914 || s_register_operand (operands[1], HFmode))"
6916 switch (which_alternative)
6918 case 0: /* ARM register from memory */
6919 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6920 case 1: /* memory from ARM register */
6921 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6922 case 2: /* ARM register from ARM register */
6923 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6924 case 3: /* ARM register from constant */
6929 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6931 ops[0] = operands[0];
6932 ops[1] = GEN_INT (bits);
6933 ops[2] = GEN_INT (bits & 0xff00);
6934 ops[3] = GEN_INT (bits & 0x00ff);
6936 if (arm_arch_thumb2)
6937 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6939 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6946 [(set_attr "conds" "unconditional")
6947 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6948 (set_attr "length" "4,4,4,8")
6949 (set_attr "predicable" "yes")]
6952 (define_expand "movsf"
6953 [(set (match_operand:SF 0 "general_operand" "")
6954 (match_operand:SF 1 "general_operand" ""))]
6959 if (MEM_P (operands[0]))
6960 operands[1] = force_reg (SFmode, operands[1]);
6962 else /* TARGET_THUMB1 */
6964 if (can_create_pseudo_p ())
6966 if (!REG_P (operands[0]))
6967 operands[1] = force_reg (SFmode, operands[1]);
6971 /* Cannot load it directly, generate a load with clobber so that it can be
6972 loaded via GPR with MOV / MOVT. */
6973 if (arm_disable_literal_pool
6974 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6975 && CONST_DOUBLE_P (operands[1])
6976 && TARGET_HARD_FLOAT
6977 && !vfp3_const_double_rtx (operands[1]))
6979 rtx clobreg = gen_reg_rtx (SFmode);
6980 emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
6987 ;; Transform a floating-point move of a constant into a core register into
6988 ;; an SImode operation.
6990 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6991 (match_operand:SF 1 "immediate_operand" ""))]
6994 && CONST_DOUBLE_P (operands[1])"
6995 [(set (match_dup 2) (match_dup 3))]
6997 operands[2] = gen_lowpart (SImode, operands[0]);
6998 operands[3] = gen_lowpart (SImode, operands[1]);
6999 if (operands[2] == 0 || operands[3] == 0)
7004 (define_insn "*arm_movsf_soft_insn"
7005 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7006 (match_operand:SF 1 "general_operand" "r,mE,r"))]
7008 && TARGET_SOFT_FLOAT
7009 && (!MEM_P (operands[0])
7010 || register_operand (operands[1], SFmode))"
7012 switch (which_alternative)
7014 case 0: return \"mov%?\\t%0, %1\";
7016 /* Cannot load it directly, split to load it via MOV / MOVT. */
7017 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7019 return \"ldr%?\\t%0, %1\\t%@ float\";
7020 case 2: return \"str%?\\t%1, %0\\t%@ float\";
7021 default: gcc_unreachable ();
7024 [(set_attr "predicable" "yes")
7025 (set_attr "type" "mov_reg,load_4,store_4")
7026 (set_attr "arm_pool_range" "*,4096,*")
7027 (set_attr "thumb2_pool_range" "*,4094,*")
7028 (set_attr "arm_neg_pool_range" "*,4084,*")
7029 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7032 ;; Splitter for the above.
7034 [(set (match_operand:SF 0 "s_register_operand")
7035 (match_operand:SF 1 "const_double_operand"))]
7036 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7040 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
7041 rtx cst = gen_int_mode (buf, SImode);
7042 emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
7047 (define_expand "movdf"
7048 [(set (match_operand:DF 0 "general_operand" "")
7049 (match_operand:DF 1 "general_operand" ""))]
7054 if (MEM_P (operands[0]))
7055 operands[1] = force_reg (DFmode, operands[1]);
7057 else /* TARGET_THUMB */
7059 if (can_create_pseudo_p ())
7061 if (!REG_P (operands[0]))
7062 operands[1] = force_reg (DFmode, operands[1]);
7066 /* Cannot load it directly, generate a load with clobber so that it can be
7067 loaded via GPR with MOV / MOVT. */
7068 if (arm_disable_literal_pool
7069 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
7070 && CONSTANT_P (operands[1])
7071 && TARGET_HARD_FLOAT
7072 && !arm_const_double_rtx (operands[1])
7073 && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
7075 rtx clobreg = gen_reg_rtx (DFmode);
7076 emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
7083 ;; Reloading a df mode value stored in integer regs to memory can require a
7085 (define_expand "reload_outdf"
7086 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7087 (match_operand:DF 1 "s_register_operand" "r")
7088 (match_operand:SI 2 "s_register_operand" "=&r")]
7092 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7095 operands[2] = XEXP (operands[0], 0);
7096 else if (code == POST_INC || code == PRE_DEC)
7098 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7099 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7100 emit_insn (gen_movdi (operands[0], operands[1]));
7103 else if (code == PRE_INC)
7105 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7107 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7110 else if (code == POST_DEC)
7111 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7113 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7114 XEXP (XEXP (operands[0], 0), 1)));
7116 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7119 if (code == POST_DEC)
7120 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7126 (define_insn "*movdf_soft_insn"
7127 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
7128 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
7129 "TARGET_32BIT && TARGET_SOFT_FLOAT
7130 && ( register_operand (operands[0], DFmode)
7131 || register_operand (operands[1], DFmode))"
7133 switch (which_alternative)
7140 /* Cannot load it directly, split to load it via MOV / MOVT. */
7141 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7145 return output_move_double (operands, true, NULL);
7148 [(set_attr "length" "8,12,16,8,8")
7149 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7150 (set_attr "arm_pool_range" "*,*,*,1020,*")
7151 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7152 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7153 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7156 ;; Splitter for the above.
7158 [(set (match_operand:DF 0 "s_register_operand")
7159 (match_operand:DF 1 "const_double_operand"))]
7160 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7164 int order = BYTES_BIG_ENDIAN ? 1 : 0;
7165 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
7166 unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
7167 ival |= (zext_hwi (buf[1 - order], 32) << 32);
7168 rtx cst = gen_int_mode (ival, DImode);
7169 emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
7175 ;; load- and store-multiple insns
7176 ;; The arm can load/store any set of registers, provided that they are in
7177 ;; ascending order, but these expanders assume a contiguous set.
7179 (define_expand "load_multiple"
7180 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7181 (match_operand:SI 1 "" ""))
7182 (use (match_operand:SI 2 "" ""))])]
7185 HOST_WIDE_INT offset = 0;
7187 /* Support only fixed point registers. */
7188 if (!CONST_INT_P (operands[2])
7189 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7190 || INTVAL (operands[2]) < 2
7191 || !MEM_P (operands[1])
7192 || !REG_P (operands[0])
7193 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7194 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7198 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7199 INTVAL (operands[2]),
7200 force_reg (SImode, XEXP (operands[1], 0)),
7201 FALSE, operands[1], &offset);
7204 (define_expand "store_multiple"
7205 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7206 (match_operand:SI 1 "" ""))
7207 (use (match_operand:SI 2 "" ""))])]
7210 HOST_WIDE_INT offset = 0;
7212 /* Support only fixed point registers. */
7213 if (!CONST_INT_P (operands[2])
7214 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7215 || INTVAL (operands[2]) < 2
7216 || !REG_P (operands[1])
7217 || !MEM_P (operands[0])
7218 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7219 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7223 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7224 INTVAL (operands[2]),
7225 force_reg (SImode, XEXP (operands[0], 0)),
7226 FALSE, operands[0], &offset);
7230 (define_expand "setmemsi"
7231 [(match_operand:BLK 0 "general_operand" "")
7232 (match_operand:SI 1 "const_int_operand" "")
7233 (match_operand:SI 2 "const_int_operand" "")
7234 (match_operand:SI 3 "const_int_operand" "")]
7237 if (arm_gen_setmem (operands))
7244 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7245 ;; We could let this apply for blocks of less than this, but it clobbers so
7246 ;; many registers that there is then probably a better way.
7248 (define_expand "movmemqi"
7249 [(match_operand:BLK 0 "general_operand" "")
7250 (match_operand:BLK 1 "general_operand" "")
7251 (match_operand:SI 2 "const_int_operand" "")
7252 (match_operand:SI 3 "const_int_operand" "")]
7257 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7258 && !optimize_function_for_size_p (cfun))
7260 if (gen_movmem_ldrd_strd (operands))
7265 if (arm_gen_movmemqi (operands))
7269 else /* TARGET_THUMB1 */
7271 if ( INTVAL (operands[3]) != 4
7272 || INTVAL (operands[2]) > 48)
7275 thumb_expand_movmemqi (operands);
7282 ;; Compare & branch insns
7283 ;; The range calculations are based as follows:
7284 ;; For forward branches, the address calculation returns the address of
7285 ;; the next instruction. This is 2 beyond the branch instruction.
7286 ;; For backward branches, the address calculation returns the address of
7287 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7288 ;; instruction for the shortest sequence, and 4 before the branch instruction
7289 ;; if we have to jump around an unconditional branch.
7290 ;; To the basic branch range the PC offset must be added (this is +4).
7291 ;; So for forward branches we have
7292 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7293 ;; And for backward branches we have
7294 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7296 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7297 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7299 (define_expand "cbranchsi4"
7300 [(set (pc) (if_then_else
7301 (match_operator 0 "expandable_comparison_operator"
7302 [(match_operand:SI 1 "s_register_operand" "")
7303 (match_operand:SI 2 "nonmemory_operand" "")])
7304 (label_ref (match_operand 3 "" ""))
7310 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7312 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7316 if (thumb1_cmpneg_operand (operands[2], SImode))
7318 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7319 operands[3], operands[0]));
7322 if (!thumb1_cmp_operand (operands[2], SImode))
7323 operands[2] = force_reg (SImode, operands[2]);
7326 (define_expand "cbranchsf4"
7327 [(set (pc) (if_then_else
7328 (match_operator 0 "expandable_comparison_operator"
7329 [(match_operand:SF 1 "s_register_operand" "")
7330 (match_operand:SF 2 "vfp_compare_operand" "")])
7331 (label_ref (match_operand 3 "" ""))
7333 "TARGET_32BIT && TARGET_HARD_FLOAT"
7334 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7335 operands[3])); DONE;"
7338 (define_expand "cbranchdf4"
7339 [(set (pc) (if_then_else
7340 (match_operator 0 "expandable_comparison_operator"
7341 [(match_operand:DF 1 "s_register_operand" "")
7342 (match_operand:DF 2 "vfp_compare_operand" "")])
7343 (label_ref (match_operand 3 "" ""))
7345 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7346 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7347 operands[3])); DONE;"
7350 (define_expand "cbranchdi4"
7351 [(set (pc) (if_then_else
7352 (match_operator 0 "expandable_comparison_operator"
7353 [(match_operand:DI 1 "s_register_operand" "")
7354 (match_operand:DI 2 "cmpdi_operand" "")])
7355 (label_ref (match_operand 3 "" ""))
7359 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7361 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7367 ;; Comparison and test insns
7369 (define_insn "*arm_cmpsi_insn"
7370 [(set (reg:CC CC_REGNUM)
7371 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7372 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7380 [(set_attr "conds" "set")
7381 (set_attr "arch" "t2,t2,any,any,any")
7382 (set_attr "length" "2,2,4,4,4")
7383 (set_attr "predicable" "yes")
7384 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7385 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7388 (define_insn "*cmpsi_shiftsi"
7389 [(set (reg:CC CC_REGNUM)
7390 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7391 (match_operator:SI 3 "shift_operator"
7392 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7393 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7396 [(set_attr "conds" "set")
7397 (set_attr "shift" "1")
7398 (set_attr "arch" "32,a,a")
7399 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7401 (define_insn "*cmpsi_shiftsi_swp"
7402 [(set (reg:CC_SWP CC_REGNUM)
7403 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7404 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7405 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7406 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7409 [(set_attr "conds" "set")
7410 (set_attr "shift" "1")
7411 (set_attr "arch" "32,a,a")
7412 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7414 (define_insn "*arm_cmpsi_negshiftsi_si"
7415 [(set (reg:CC_Z CC_REGNUM)
7417 (neg:SI (match_operator:SI 1 "shift_operator"
7418 [(match_operand:SI 2 "s_register_operand" "r")
7419 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7420 (match_operand:SI 0 "s_register_operand" "r")))]
7423 [(set_attr "conds" "set")
7424 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7425 (const_string "alus_shift_imm")
7426 (const_string "alus_shift_reg")))
7427 (set_attr "predicable" "yes")]
7430 ;; DImode comparisons. The generic code generates branches that
7431 ;; if-conversion cannot reduce to a conditional compare, so we do
7434 (define_insn_and_split "*arm_cmpdi_insn"
7435 [(set (reg:CC_NCV CC_REGNUM)
7436 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7437 (match_operand:DI 1 "arm_di_operand" "rDi")))
7438 (clobber (match_scratch:SI 2 "=r"))]
7440 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7441 "&& reload_completed"
7442 [(set (reg:CC CC_REGNUM)
7443 (compare:CC (match_dup 0) (match_dup 1)))
7444 (parallel [(set (reg:CC CC_REGNUM)
7445 (compare:CC (match_dup 3) (match_dup 4)))
7447 (minus:SI (match_dup 5)
7448 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7450 operands[3] = gen_highpart (SImode, operands[0]);
7451 operands[0] = gen_lowpart (SImode, operands[0]);
7452 if (CONST_INT_P (operands[1]))
7454 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);
7455 if (operands[4] == const0_rtx)
7456 operands[5] = operands[3];
7458 operands[5] = gen_rtx_PLUS (SImode, operands[3],
7459 gen_int_mode (-UINTVAL (operands[4]),
7464 operands[4] = gen_highpart (SImode, operands[1]);
7465 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7467 operands[1] = gen_lowpart (SImode, operands[1]);
7468 operands[2] = gen_lowpart (SImode, operands[2]);
7470 [(set_attr "conds" "set")
7471 (set_attr "length" "8")
7472 (set_attr "type" "multiple")]
7475 (define_insn_and_split "*arm_cmpdi_unsigned"
7476 [(set (reg:CC_CZ CC_REGNUM)
7477 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7478 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7481 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7482 "&& reload_completed"
7483 [(set (reg:CC CC_REGNUM)
7484 (compare:CC (match_dup 2) (match_dup 3)))
7485 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7486 (set (reg:CC CC_REGNUM)
7487 (compare:CC (match_dup 0) (match_dup 1))))]
7489 operands[2] = gen_highpart (SImode, operands[0]);
7490 operands[0] = gen_lowpart (SImode, operands[0]);
7491 if (CONST_INT_P (operands[1]))
7492 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7494 operands[3] = gen_highpart (SImode, operands[1]);
7495 operands[1] = gen_lowpart (SImode, operands[1]);
7497 [(set_attr "conds" "set")
7498 (set_attr "enabled_for_short_it" "yes,yes,no,*")
7499 (set_attr "arch" "t2,t2,t2,a")
7500 (set_attr "length" "6,6,10,8")
7501 (set_attr "type" "multiple")]
7504 (define_insn "*arm_cmpdi_zero"
7505 [(set (reg:CC_Z CC_REGNUM)
7506 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7508 (clobber (match_scratch:SI 1 "=r"))]
7510 "orrs%?\\t%1, %Q0, %R0"
7511 [(set_attr "conds" "set")
7512 (set_attr "type" "logics_reg")]
7515 ; This insn allows redundant compares to be removed by cse, nothing should
7516 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7517 ; is deleted later on. The match_dup will match the mode here, so that
7518 ; mode changes of the condition codes aren't lost by this even though we don't
7519 ; specify what they are.
7521 (define_insn "*deleted_compare"
7522 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7524 "\\t%@ deleted compare"
7525 [(set_attr "conds" "set")
7526 (set_attr "length" "0")
7527 (set_attr "type" "no_insn")]
7531 ;; Conditional branch insns
7533 (define_expand "cbranch_cc"
7535 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7536 (match_operand 2 "" "")])
7537 (label_ref (match_operand 3 "" ""))
7540 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7541 operands[1], operands[2], NULL_RTX);
7542 operands[2] = const0_rtx;"
7546 ;; Patterns to match conditional branch insns.
7549 (define_insn "arm_cond_branch"
7551 (if_then_else (match_operator 1 "arm_comparison_operator"
7552 [(match_operand 2 "cc_register" "") (const_int 0)])
7553 (label_ref (match_operand 0 "" ""))
7557 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7559 arm_ccfsm_state += 2;
7562 return \"b%d1\\t%l0\";
7564 [(set_attr "conds" "use")
7565 (set_attr "type" "branch")
7566 (set (attr "length")
7568 (and (match_test "TARGET_THUMB2")
7569 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7570 (le (minus (match_dup 0) (pc)) (const_int 256))))
7575 (define_insn "*arm_cond_branch_reversed"
7577 (if_then_else (match_operator 1 "arm_comparison_operator"
7578 [(match_operand 2 "cc_register" "") (const_int 0)])
7580 (label_ref (match_operand 0 "" ""))))]
7583 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7585 arm_ccfsm_state += 2;
7588 return \"b%D1\\t%l0\";
7590 [(set_attr "conds" "use")
7591 (set_attr "type" "branch")
7592 (set (attr "length")
7594 (and (match_test "TARGET_THUMB2")
7595 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7596 (le (minus (match_dup 0) (pc)) (const_int 256))))
7605 (define_expand "cstore_cc"
7606 [(set (match_operand:SI 0 "s_register_operand" "")
7607 (match_operator:SI 1 "" [(match_operand 2 "" "")
7608 (match_operand 3 "" "")]))]
7610 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7611 operands[2], operands[3], NULL_RTX);
7612 operands[3] = const0_rtx;"
7615 (define_insn_and_split "*mov_scc"
7616 [(set (match_operand:SI 0 "s_register_operand" "=r")
7617 (match_operator:SI 1 "arm_comparison_operator_mode"
7618 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7620 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7623 (if_then_else:SI (match_dup 1)
7627 [(set_attr "conds" "use")
7628 (set_attr "length" "8")
7629 (set_attr "type" "multiple")]
7632 (define_insn_and_split "*mov_negscc"
7633 [(set (match_operand:SI 0 "s_register_operand" "=r")
7634 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7635 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7637 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7640 (if_then_else:SI (match_dup 1)
7644 operands[3] = GEN_INT (~0);
7646 [(set_attr "conds" "use")
7647 (set_attr "length" "8")
7648 (set_attr "type" "multiple")]
7651 (define_insn_and_split "*mov_notscc"
7652 [(set (match_operand:SI 0 "s_register_operand" "=r")
7653 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7654 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7656 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7659 (if_then_else:SI (match_dup 1)
7663 operands[3] = GEN_INT (~1);
7664 operands[4] = GEN_INT (~0);
7666 [(set_attr "conds" "use")
7667 (set_attr "length" "8")
7668 (set_attr "type" "multiple")]
7671 (define_expand "cstoresi4"
7672 [(set (match_operand:SI 0 "s_register_operand" "")
7673 (match_operator:SI 1 "expandable_comparison_operator"
7674 [(match_operand:SI 2 "s_register_operand" "")
7675 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7676 "TARGET_32BIT || TARGET_THUMB1"
7678 rtx op3, scratch, scratch2;
7682 if (!arm_add_operand (operands[3], SImode))
7683 operands[3] = force_reg (SImode, operands[3]);
7684 emit_insn (gen_cstore_cc (operands[0], operands[1],
7685 operands[2], operands[3]));
7689 if (operands[3] == const0_rtx)
7691 switch (GET_CODE (operands[1]))
7694 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7698 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7702 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7703 NULL_RTX, 0, OPTAB_WIDEN);
7704 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7705 NULL_RTX, 0, OPTAB_WIDEN);
7706 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7707 operands[0], 1, OPTAB_WIDEN);
7711 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7713 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7714 NULL_RTX, 1, OPTAB_WIDEN);
7718 scratch = expand_binop (SImode, ashr_optab, operands[2],
7719 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7720 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7721 NULL_RTX, 0, OPTAB_WIDEN);
7722 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7726 /* LT is handled by generic code. No need for unsigned with 0. */
7733 switch (GET_CODE (operands[1]))
7736 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7737 NULL_RTX, 0, OPTAB_WIDEN);
7738 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7742 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7743 NULL_RTX, 0, OPTAB_WIDEN);
7744 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7748 op3 = force_reg (SImode, operands[3]);
7750 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7751 NULL_RTX, 1, OPTAB_WIDEN);
7752 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7753 NULL_RTX, 0, OPTAB_WIDEN);
7754 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7760 if (!thumb1_cmp_operand (op3, SImode))
7761 op3 = force_reg (SImode, op3);
7762 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7763 NULL_RTX, 0, OPTAB_WIDEN);
7764 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7765 NULL_RTX, 1, OPTAB_WIDEN);
7766 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7771 op3 = force_reg (SImode, operands[3]);
7772 scratch = force_reg (SImode, const0_rtx);
7773 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7779 if (!thumb1_cmp_operand (op3, SImode))
7780 op3 = force_reg (SImode, op3);
7781 scratch = force_reg (SImode, const0_rtx);
7782 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7788 if (!thumb1_cmp_operand (op3, SImode))
7789 op3 = force_reg (SImode, op3);
7790 scratch = gen_reg_rtx (SImode);
7791 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7795 op3 = force_reg (SImode, operands[3]);
7796 scratch = gen_reg_rtx (SImode);
7797 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7800 /* No good sequences for GT, LT. */
7807 (define_expand "cstorehf4"
7808 [(set (match_operand:SI 0 "s_register_operand")
7809 (match_operator:SI 1 "expandable_comparison_operator"
7810 [(match_operand:HF 2 "s_register_operand")
7811 (match_operand:HF 3 "vfp_compare_operand")]))]
7812 "TARGET_VFP_FP16INST"
7814 if (!arm_validize_comparison (&operands[1],
7819 emit_insn (gen_cstore_cc (operands[0], operands[1],
7820 operands[2], operands[3]));
7825 (define_expand "cstoresf4"
7826 [(set (match_operand:SI 0 "s_register_operand" "")
7827 (match_operator:SI 1 "expandable_comparison_operator"
7828 [(match_operand:SF 2 "s_register_operand" "")
7829 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7830 "TARGET_32BIT && TARGET_HARD_FLOAT"
7831 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7832 operands[2], operands[3])); DONE;"
7835 (define_expand "cstoredf4"
7836 [(set (match_operand:SI 0 "s_register_operand" "")
7837 (match_operator:SI 1 "expandable_comparison_operator"
7838 [(match_operand:DF 2 "s_register_operand" "")
7839 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7840 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7841 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7842 operands[2], operands[3])); DONE;"
7845 (define_expand "cstoredi4"
7846 [(set (match_operand:SI 0 "s_register_operand" "")
7847 (match_operator:SI 1 "expandable_comparison_operator"
7848 [(match_operand:DI 2 "s_register_operand" "")
7849 (match_operand:DI 3 "cmpdi_operand" "")]))]
7852 if (!arm_validize_comparison (&operands[1],
7856 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7863 ;; Conditional move insns
7865 (define_expand "movsicc"
7866 [(set (match_operand:SI 0 "s_register_operand" "")
7867 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7868 (match_operand:SI 2 "arm_not_operand" "")
7869 (match_operand:SI 3 "arm_not_operand" "")))]
7876 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7877 &XEXP (operands[1], 1)))
7880 code = GET_CODE (operands[1]);
7881 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7882 XEXP (operands[1], 1), NULL_RTX);
7883 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7887 (define_expand "movhfcc"
7888 [(set (match_operand:HF 0 "s_register_operand")
7889 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7890 (match_operand:HF 2 "s_register_operand")
7891 (match_operand:HF 3 "s_register_operand")))]
7892 "TARGET_VFP_FP16INST"
7895 enum rtx_code code = GET_CODE (operands[1]);
7898 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7899 &XEXP (operands[1], 1)))
7902 code = GET_CODE (operands[1]);
7903 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7904 XEXP (operands[1], 1), NULL_RTX);
7905 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7909 (define_expand "movsfcc"
7910 [(set (match_operand:SF 0 "s_register_operand" "")
7911 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7912 (match_operand:SF 2 "s_register_operand" "")
7913 (match_operand:SF 3 "s_register_operand" "")))]
7914 "TARGET_32BIT && TARGET_HARD_FLOAT"
7917 enum rtx_code code = GET_CODE (operands[1]);
7920 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7921 &XEXP (operands[1], 1)))
7924 code = GET_CODE (operands[1]);
7925 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7926 XEXP (operands[1], 1), NULL_RTX);
7927 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7931 (define_expand "movdfcc"
7932 [(set (match_operand:DF 0 "s_register_operand" "")
7933 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7934 (match_operand:DF 2 "s_register_operand" "")
7935 (match_operand:DF 3 "s_register_operand" "")))]
7936 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7939 enum rtx_code code = GET_CODE (operands[1]);
7942 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7943 &XEXP (operands[1], 1)))
7945 code = GET_CODE (operands[1]);
7946 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7947 XEXP (operands[1], 1), NULL_RTX);
7948 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7952 (define_insn "*cmov<mode>"
7953 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7954 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7955 [(match_operand 2 "cc_register" "") (const_int 0)])
7956 (match_operand:SDF 3 "s_register_operand"
7958 (match_operand:SDF 4 "s_register_operand"
7959 "<F_constraint>")))]
7960 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7963 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7970 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7975 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7981 [(set_attr "conds" "use")
7982 (set_attr "type" "fcsel")]
7985 (define_insn "*cmovhf"
7986 [(set (match_operand:HF 0 "s_register_operand" "=t")
7987 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7988 [(match_operand 2 "cc_register" "") (const_int 0)])
7989 (match_operand:HF 3 "s_register_operand" "t")
7990 (match_operand:HF 4 "s_register_operand" "t")))]
7991 "TARGET_VFP_FP16INST"
7994 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
8001 return \"vsel%d1.f16\\t%0, %3, %4\";
8006 return \"vsel%D1.f16\\t%0, %4, %3\";
8012 [(set_attr "conds" "use")
8013 (set_attr "type" "fcsel")]
8016 (define_insn_and_split "*movsicc_insn"
8017 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8019 (match_operator 3 "arm_comparison_operator"
8020 [(match_operand 4 "cc_register" "") (const_int 0)])
8021 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8022 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8033 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8034 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8035 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8036 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8037 "&& reload_completed"
8040 enum rtx_code rev_code;
8044 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8046 gen_rtx_SET (operands[0], operands[1])));
8048 rev_code = GET_CODE (operands[3]);
8049 mode = GET_MODE (operands[4]);
8050 if (mode == CCFPmode || mode == CCFPEmode)
8051 rev_code = reverse_condition_maybe_unordered (rev_code);
8053 rev_code = reverse_condition (rev_code);
8055 rev_cond = gen_rtx_fmt_ee (rev_code,
8059 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8061 gen_rtx_SET (operands[0], operands[2])));
8064 [(set_attr "length" "4,4,4,4,8,8,8,8")
8065 (set_attr "conds" "use")
8066 (set_attr_alternative "type"
8067 [(if_then_else (match_operand 2 "const_int_operand" "")
8068 (const_string "mov_imm")
8069 (const_string "mov_reg"))
8070 (const_string "mvn_imm")
8071 (if_then_else (match_operand 1 "const_int_operand" "")
8072 (const_string "mov_imm")
8073 (const_string "mov_reg"))
8074 (const_string "mvn_imm")
8075 (const_string "multiple")
8076 (const_string "multiple")
8077 (const_string "multiple")
8078 (const_string "multiple")])]
8081 (define_insn "*movsfcc_soft_insn"
8082 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8083 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8084 [(match_operand 4 "cc_register" "") (const_int 0)])
8085 (match_operand:SF 1 "s_register_operand" "0,r")
8086 (match_operand:SF 2 "s_register_operand" "r,0")))]
8087 "TARGET_ARM && TARGET_SOFT_FLOAT"
8091 [(set_attr "conds" "use")
8092 (set_attr "type" "mov_reg")]
8096 ;; Jump and linkage insns
8098 (define_expand "jump"
8100 (label_ref (match_operand 0 "" "")))]
8105 (define_insn "*arm_jump"
8107 (label_ref (match_operand 0 "" "")))]
8111 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8113 arm_ccfsm_state += 2;
8116 return \"b%?\\t%l0\";
8119 [(set_attr "predicable" "yes")
8120 (set (attr "length")
8122 (and (match_test "TARGET_THUMB2")
8123 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8124 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8127 (set_attr "type" "branch")]
8130 (define_expand "call"
8131 [(parallel [(call (match_operand 0 "memory_operand" "")
8132 (match_operand 1 "general_operand" ""))
8133 (use (match_operand 2 "" ""))
8134 (clobber (reg:SI LR_REGNUM))])]
8139 tree addr = MEM_EXPR (operands[0]);
8141 /* In an untyped call, we can get NULL for operand 2. */
8142 if (operands[2] == NULL_RTX)
8143 operands[2] = const0_rtx;
8145 /* Decide if we should generate indirect calls by loading the
8146 32-bit address of the callee into a register before performing the
8148 callee = XEXP (operands[0], 0);
8149 if (GET_CODE (callee) == SYMBOL_REF
8150 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8152 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8154 if (detect_cmse_nonsecure_call (addr))
8156 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8158 emit_call_insn (pat);
8162 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8163 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8169 (define_expand "call_internal"
8170 [(parallel [(call (match_operand 0 "memory_operand" "")
8171 (match_operand 1 "general_operand" ""))
8172 (use (match_operand 2 "" ""))
8173 (clobber (reg:SI LR_REGNUM))])])
8175 (define_expand "nonsecure_call_internal"
8176 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8177 UNSPEC_NONSECURE_MEM)
8178 (match_operand 1 "general_operand" ""))
8179 (use (match_operand 2 "" ""))
8180 (clobber (reg:SI LR_REGNUM))])]
8185 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8186 gen_rtx_REG (SImode, R4_REGNUM),
8189 operands[0] = replace_equiv_address (operands[0], tmp);
8192 (define_insn "*call_reg_armv5"
8193 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8194 (match_operand 1 "" ""))
8195 (use (match_operand 2 "" ""))
8196 (clobber (reg:SI LR_REGNUM))]
8197 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8199 [(set_attr "type" "call")]
8202 (define_insn "*call_reg_arm"
8203 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8204 (match_operand 1 "" ""))
8205 (use (match_operand 2 "" ""))
8206 (clobber (reg:SI LR_REGNUM))]
8207 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8209 return output_call (operands);
8211 ;; length is worst case, normally it is only two
8212 [(set_attr "length" "12")
8213 (set_attr "type" "call")]
8217 (define_expand "call_value"
8218 [(parallel [(set (match_operand 0 "" "")
8219 (call (match_operand 1 "memory_operand" "")
8220 (match_operand 2 "general_operand" "")))
8221 (use (match_operand 3 "" ""))
8222 (clobber (reg:SI LR_REGNUM))])]
8227 tree addr = MEM_EXPR (operands[1]);
8229 /* In an untyped call, we can get NULL for operand 2. */
8230 if (operands[3] == 0)
8231 operands[3] = const0_rtx;
8233 /* Decide if we should generate indirect calls by loading the
8234 32-bit address of the callee into a register before performing the
8236 callee = XEXP (operands[1], 0);
8237 if (GET_CODE (callee) == SYMBOL_REF
8238 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8240 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8242 if (detect_cmse_nonsecure_call (addr))
8244 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8245 operands[2], operands[3]);
8246 emit_call_insn (pat);
8250 pat = gen_call_value_internal (operands[0], operands[1],
8251 operands[2], operands[3]);
8252 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8258 (define_expand "call_value_internal"
8259 [(parallel [(set (match_operand 0 "" "")
8260 (call (match_operand 1 "memory_operand" "")
8261 (match_operand 2 "general_operand" "")))
8262 (use (match_operand 3 "" ""))
8263 (clobber (reg:SI LR_REGNUM))])])
8265 (define_expand "nonsecure_call_value_internal"
8266 [(parallel [(set (match_operand 0 "" "")
8267 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8268 UNSPEC_NONSECURE_MEM)
8269 (match_operand 2 "general_operand" "")))
8270 (use (match_operand 3 "" ""))
8271 (clobber (reg:SI LR_REGNUM))])]
8276 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8277 gen_rtx_REG (SImode, R4_REGNUM),
8280 operands[1] = replace_equiv_address (operands[1], tmp);
8283 (define_insn "*call_value_reg_armv5"
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 [(set_attr "type" "call")]
8294 (define_insn "*call_value_reg_arm"
8295 [(set (match_operand 0 "" "")
8296 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8297 (match_operand 2 "" "")))
8298 (use (match_operand 3 "" ""))
8299 (clobber (reg:SI LR_REGNUM))]
8300 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8302 return output_call (&operands[1]);
8304 [(set_attr "length" "12")
8305 (set_attr "type" "call")]
8308 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8309 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8311 (define_insn "*call_symbol"
8312 [(call (mem:SI (match_operand:SI 0 "" ""))
8313 (match_operand 1 "" ""))
8314 (use (match_operand 2 "" ""))
8315 (clobber (reg:SI LR_REGNUM))]
8317 && !SIBLING_CALL_P (insn)
8318 && (GET_CODE (operands[0]) == SYMBOL_REF)
8319 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8322 rtx op = operands[0];
8324 /* Switch mode now when possible. */
8325 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8326 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8327 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8329 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8331 [(set_attr "type" "call")]
8334 (define_insn "*call_value_symbol"
8335 [(set (match_operand 0 "" "")
8336 (call (mem:SI (match_operand:SI 1 "" ""))
8337 (match_operand:SI 2 "" "")))
8338 (use (match_operand 3 "" ""))
8339 (clobber (reg:SI LR_REGNUM))]
8341 && !SIBLING_CALL_P (insn)
8342 && (GET_CODE (operands[1]) == SYMBOL_REF)
8343 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8346 rtx op = operands[1];
8348 /* Switch mode now when possible. */
8349 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8350 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8351 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8353 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8355 [(set_attr "type" "call")]
8358 (define_expand "sibcall_internal"
8359 [(parallel [(call (match_operand 0 "memory_operand" "")
8360 (match_operand 1 "general_operand" ""))
8362 (use (match_operand 2 "" ""))])])
8364 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8365 (define_expand "sibcall"
8366 [(parallel [(call (match_operand 0 "memory_operand" "")
8367 (match_operand 1 "general_operand" ""))
8369 (use (match_operand 2 "" ""))])]
8375 if ((!REG_P (XEXP (operands[0], 0))
8376 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8377 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8378 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8379 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8381 if (operands[2] == NULL_RTX)
8382 operands[2] = const0_rtx;
8384 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8385 arm_emit_call_insn (pat, operands[0], true);
8390 (define_expand "sibcall_value_internal"
8391 [(parallel [(set (match_operand 0 "" "")
8392 (call (match_operand 1 "memory_operand" "")
8393 (match_operand 2 "general_operand" "")))
8395 (use (match_operand 3 "" ""))])])
8397 (define_expand "sibcall_value"
8398 [(parallel [(set (match_operand 0 "" "")
8399 (call (match_operand 1 "memory_operand" "")
8400 (match_operand 2 "general_operand" "")))
8402 (use (match_operand 3 "" ""))])]
8408 if ((!REG_P (XEXP (operands[1], 0))
8409 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8410 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8411 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8412 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8414 if (operands[3] == NULL_RTX)
8415 operands[3] = const0_rtx;
8417 pat = gen_sibcall_value_internal (operands[0], operands[1],
8418 operands[2], operands[3]);
8419 arm_emit_call_insn (pat, operands[1], true);
8424 (define_insn "*sibcall_insn"
8425 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8426 (match_operand 1 "" ""))
8428 (use (match_operand 2 "" ""))]
8429 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8431 if (which_alternative == 1)
8432 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8435 if (arm_arch5t || arm_arch4t)
8436 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8438 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8441 [(set_attr "type" "call")]
8444 (define_insn "*sibcall_value_insn"
8445 [(set (match_operand 0 "" "")
8446 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8447 (match_operand 2 "" "")))
8449 (use (match_operand 3 "" ""))]
8450 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8452 if (which_alternative == 1)
8453 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8456 if (arm_arch5t || arm_arch4t)
8457 return \"bx%?\\t%1\";
8459 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8462 [(set_attr "type" "call")]
8465 (define_expand "<return_str>return"
8467 "(TARGET_ARM || (TARGET_THUMB2
8468 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8469 && !IS_STACKALIGN (arm_current_func_type ())))
8470 <return_cond_false>"
8475 thumb2_expand_return (<return_simple_p>);
8482 ;; Often the return insn will be the same as loading from memory, so set attr
8483 (define_insn "*arm_return"
8485 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8488 if (arm_ccfsm_state == 2)
8490 arm_ccfsm_state += 2;
8493 return output_return_instruction (const_true_rtx, true, false, false);
8495 [(set_attr "type" "load_4")
8496 (set_attr "length" "12")
8497 (set_attr "predicable" "yes")]
8500 (define_insn "*cond_<return_str>return"
8502 (if_then_else (match_operator 0 "arm_comparison_operator"
8503 [(match_operand 1 "cc_register" "") (const_int 0)])
8506 "TARGET_ARM <return_cond_true>"
8509 if (arm_ccfsm_state == 2)
8511 arm_ccfsm_state += 2;
8514 return output_return_instruction (operands[0], true, false,
8517 [(set_attr "conds" "use")
8518 (set_attr "length" "12")
8519 (set_attr "type" "load_4")]
8522 (define_insn "*cond_<return_str>return_inverted"
8524 (if_then_else (match_operator 0 "arm_comparison_operator"
8525 [(match_operand 1 "cc_register" "") (const_int 0)])
8528 "TARGET_ARM <return_cond_true>"
8531 if (arm_ccfsm_state == 2)
8533 arm_ccfsm_state += 2;
8536 return output_return_instruction (operands[0], true, true,
8539 [(set_attr "conds" "use")
8540 (set_attr "length" "12")
8541 (set_attr "type" "load_4")]
8544 (define_insn "*arm_simple_return"
8549 if (arm_ccfsm_state == 2)
8551 arm_ccfsm_state += 2;
8554 return output_return_instruction (const_true_rtx, true, false, true);
8556 [(set_attr "type" "branch")
8557 (set_attr "length" "4")
8558 (set_attr "predicable" "yes")]
8561 ;; Generate a sequence of instructions to determine if the processor is
8562 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8565 (define_expand "return_addr_mask"
8567 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8569 (set (match_operand:SI 0 "s_register_operand" "")
8570 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8572 (const_int 67108860)))] ; 0x03fffffc
8575 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8578 (define_insn "*check_arch2"
8579 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8580 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8583 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8584 [(set_attr "length" "8")
8585 (set_attr "conds" "set")
8586 (set_attr "type" "multiple")]
8589 ;; Call subroutine returning any type.
8591 (define_expand "untyped_call"
8592 [(parallel [(call (match_operand 0 "" "")
8594 (match_operand 1 "" "")
8595 (match_operand 2 "" "")])]
8600 rtx par = gen_rtx_PARALLEL (VOIDmode,
8601 rtvec_alloc (XVECLEN (operands[2], 0)));
8602 rtx addr = gen_reg_rtx (Pmode);
8606 emit_move_insn (addr, XEXP (operands[1], 0));
8607 mem = change_address (operands[1], BLKmode, addr);
8609 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8611 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8613 /* Default code only uses r0 as a return value, but we could
8614 be using anything up to 4 registers. */
8615 if (REGNO (src) == R0_REGNUM)
8616 src = gen_rtx_REG (TImode, R0_REGNUM);
8618 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8620 size += GET_MODE_SIZE (GET_MODE (src));
8623 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8627 for (i = 0; i < XVECLEN (par, 0); i++)
8629 HOST_WIDE_INT offset = 0;
8630 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8633 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8635 mem = change_address (mem, GET_MODE (reg), NULL);
8636 if (REGNO (reg) == R0_REGNUM)
8638 /* On thumb we have to use a write-back instruction. */
8639 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8640 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8641 size = TARGET_ARM ? 16 : 0;
8645 emit_move_insn (mem, reg);
8646 size = GET_MODE_SIZE (GET_MODE (reg));
8650 /* The optimizer does not know that the call sets the function value
8651 registers we stored in the result block. We avoid problems by
8652 claiming that all hard registers are used and clobbered at this
8654 emit_insn (gen_blockage ());
8660 (define_expand "untyped_return"
8661 [(match_operand:BLK 0 "memory_operand" "")
8662 (match_operand 1 "" "")]
8667 rtx addr = gen_reg_rtx (Pmode);
8671 emit_move_insn (addr, XEXP (operands[0], 0));
8672 mem = change_address (operands[0], BLKmode, addr);
8674 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8676 HOST_WIDE_INT offset = 0;
8677 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8680 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8682 mem = change_address (mem, GET_MODE (reg), NULL);
8683 if (REGNO (reg) == R0_REGNUM)
8685 /* On thumb we have to use a write-back instruction. */
8686 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8687 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8688 size = TARGET_ARM ? 16 : 0;
8692 emit_move_insn (reg, mem);
8693 size = GET_MODE_SIZE (GET_MODE (reg));
8697 /* Emit USE insns before the return. */
8698 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8699 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8701 /* Construct the return. */
8702 expand_naked_return ();
8708 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8709 ;; all of memory. This blocks insns from being moved across this point.
8711 (define_insn "blockage"
8712 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8715 [(set_attr "length" "0")
8716 (set_attr "type" "block")]
8719 ;; Since we hard code r0 here use the 'o' constraint to prevent
8720 ;; provoking undefined behaviour in the hardware with putting out
8721 ;; auto-increment operations with potentially r0 as the base register.
8722 (define_insn "probe_stack"
8723 [(set (match_operand:SI 0 "memory_operand" "=o")
8724 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8727 [(set_attr "type" "store_4")
8728 (set_attr "predicable" "yes")]
8731 (define_insn "probe_stack_range"
8732 [(set (match_operand:SI 0 "register_operand" "=r")
8733 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8734 (match_operand:SI 2 "register_operand" "r")]
8735 VUNSPEC_PROBE_STACK_RANGE))]
8738 return output_probe_stack_range (operands[0], operands[2]);
8740 [(set_attr "type" "multiple")
8741 (set_attr "conds" "clob")]
8744 ;; Named patterns for stack smashing protection.
8745 (define_expand "stack_protect_combined_set"
8747 [(set (match_operand:SI 0 "memory_operand" "")
8748 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8750 (clobber (match_scratch:SI 2 ""))
8751 (clobber (match_scratch:SI 3 ""))])]
8756 ;; Use a separate insn from the above expand to be able to have the mem outside
8757 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8758 ;; try to reload the guard since we need to control how PIC access is done in
8759 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8760 ;; legitimize_pic_address ()).
8761 (define_insn_and_split "*stack_protect_combined_set_insn"
8762 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8763 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8765 (clobber (match_scratch:SI 2 "=&l,&r"))
8766 (clobber (match_scratch:SI 3 "=&l,&r"))]
8770 [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))]
8772 (clobber (match_dup 2))])]
8777 /* Forces recomputing of GOT base now. */
8778 legitimize_pic_address (operands[1], SImode, operands[2], operands[3],
8779 true /*compute_now*/);
8783 if (address_operand (operands[1], SImode))
8784 operands[2] = operands[1];
8787 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8788 emit_move_insn (operands[2], mem);
8792 [(set_attr "arch" "t1,32")]
8795 (define_insn "*stack_protect_set_insn"
8796 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8797 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))]
8799 (clobber (match_dup 1))]
8802 ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1,#0
8803 ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1,#0"
8804 [(set_attr "length" "8,12")
8805 (set_attr "conds" "clob,nocond")
8806 (set_attr "type" "multiple")
8807 (set_attr "arch" "t1,32")]
8810 (define_expand "stack_protect_combined_test"
8814 (eq (match_operand:SI 0 "memory_operand" "")
8815 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8817 (label_ref (match_operand 2))
8819 (clobber (match_scratch:SI 3 ""))
8820 (clobber (match_scratch:SI 4 ""))
8821 (clobber (reg:CC CC_REGNUM))])]
8826 ;; Use a separate insn from the above expand to be able to have the mem outside
8827 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8828 ;; try to reload the guard since we need to control how PIC access is done in
8829 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8830 ;; legitimize_pic_address ()).
8831 (define_insn_and_split "*stack_protect_combined_test_insn"
8834 (eq (match_operand:SI 0 "memory_operand" "m,m")
8835 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8837 (label_ref (match_operand 2))
8839 (clobber (match_scratch:SI 3 "=&l,&r"))
8840 (clobber (match_scratch:SI 4 "=&l,&r"))
8841 (clobber (reg:CC CC_REGNUM))]
8851 /* Forces recomputing of GOT base now. */
8852 legitimize_pic_address (operands[1], SImode, operands[3], operands[4],
8853 true /*compute_now*/);
8857 if (address_operand (operands[1], SImode))
8858 operands[3] = operands[1];
8861 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8862 emit_move_insn (operands[3], mem);
8867 emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0],
8869 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
8870 eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx);
8871 emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg));
8875 emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0],
8877 eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
8878 emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx,
8883 [(set_attr "arch" "t1,32")]
8886 (define_insn "arm_stack_protect_test_insn"
8887 [(set (reg:CC_Z CC_REGNUM)
8888 (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m")
8889 (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))]
8892 (clobber (match_operand:SI 0 "register_operand" "=&l,&r"))
8893 (clobber (match_dup 2))]
8895 "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0"
8896 [(set_attr "length" "8,12")
8897 (set_attr "conds" "set")
8898 (set_attr "type" "multiple")
8899 (set_attr "arch" "t,32")]
8902 (define_expand "casesi"
8903 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8904 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8905 (match_operand:SI 2 "const_int_operand" "") ; total range
8906 (match_operand:SI 3 "" "") ; table label
8907 (match_operand:SI 4 "" "")] ; Out of range label
8908 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8911 enum insn_code code;
8912 if (operands[1] != const0_rtx)
8914 rtx reg = gen_reg_rtx (SImode);
8916 emit_insn (gen_addsi3 (reg, operands[0],
8917 gen_int_mode (-INTVAL (operands[1]),
8923 code = CODE_FOR_arm_casesi_internal;
8924 else if (TARGET_THUMB1)
8925 code = CODE_FOR_thumb1_casesi_internal_pic;
8927 code = CODE_FOR_thumb2_casesi_internal_pic;
8929 code = CODE_FOR_thumb2_casesi_internal;
8931 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8932 operands[2] = force_reg (SImode, operands[2]);
8934 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8935 operands[3], operands[4]));
8940 ;; The USE in this pattern is needed to tell flow analysis that this is
8941 ;; a CASESI insn. It has no other purpose.
8942 (define_insn "arm_casesi_internal"
8943 [(parallel [(set (pc)
8945 (leu (match_operand:SI 0 "s_register_operand" "r")
8946 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8947 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8948 (label_ref (match_operand 2 "" ""))))
8949 (label_ref (match_operand 3 "" ""))))
8950 (clobber (reg:CC CC_REGNUM))
8951 (use (label_ref (match_dup 2)))])]
8955 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8956 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8958 [(set_attr "conds" "clob")
8959 (set_attr "length" "12")
8960 (set_attr "type" "multiple")]
8963 (define_expand "indirect_jump"
8965 (match_operand:SI 0 "s_register_operand" ""))]
8968 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8969 address and use bx. */
8973 tmp = gen_reg_rtx (SImode);
8974 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8980 ;; NB Never uses BX.
8981 (define_insn "*arm_indirect_jump"
8983 (match_operand:SI 0 "s_register_operand" "r"))]
8985 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8986 [(set_attr "predicable" "yes")
8987 (set_attr "type" "branch")]
8990 (define_insn "*load_indirect_jump"
8992 (match_operand:SI 0 "memory_operand" "m"))]
8994 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8995 [(set_attr "type" "load_4")
8996 (set_attr "pool_range" "4096")
8997 (set_attr "neg_pool_range" "4084")
8998 (set_attr "predicable" "yes")]
9008 [(set (attr "length")
9009 (if_then_else (eq_attr "is_thumb" "yes")
9012 (set_attr "type" "mov_reg")]
9016 [(trap_if (const_int 1) (const_int 0))]
9020 return \".inst\\t0xe7f000f0\";
9022 return \".inst\\t0xdeff\";
9024 [(set (attr "length")
9025 (if_then_else (eq_attr "is_thumb" "yes")
9028 (set_attr "type" "trap")
9029 (set_attr "conds" "unconditional")]
9033 ;; Patterns to allow combination of arithmetic, cond code and shifts
9035 (define_insn "*<arith_shift_insn>_multsi"
9036 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9038 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
9039 (match_operand:SI 3 "power_of_two_operand" ""))
9040 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
9042 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
9043 [(set_attr "predicable" "yes")
9044 (set_attr "shift" "2")
9045 (set_attr "arch" "a,t2")
9046 (set_attr "type" "alu_shift_imm")])
9048 (define_insn "*<arith_shift_insn>_shiftsi"
9049 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9051 (match_operator:SI 2 "shift_nomul_operator"
9052 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9053 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
9054 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
9055 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
9056 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
9057 [(set_attr "predicable" "yes")
9058 (set_attr "shift" "3")
9059 (set_attr "arch" "a,t2,a")
9060 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9063 [(set (match_operand:SI 0 "s_register_operand" "")
9064 (match_operator:SI 1 "shiftable_operator"
9065 [(match_operator:SI 2 "shiftable_operator"
9066 [(match_operator:SI 3 "shift_operator"
9067 [(match_operand:SI 4 "s_register_operand" "")
9068 (match_operand:SI 5 "reg_or_int_operand" "")])
9069 (match_operand:SI 6 "s_register_operand" "")])
9070 (match_operand:SI 7 "arm_rhs_operand" "")]))
9071 (clobber (match_operand:SI 8 "s_register_operand" ""))]
9074 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9077 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
9080 (define_insn "*arith_shiftsi_compare0"
9081 [(set (reg:CC_NOOV CC_REGNUM)
9083 (match_operator:SI 1 "shiftable_operator"
9084 [(match_operator:SI 3 "shift_operator"
9085 [(match_operand:SI 4 "s_register_operand" "r,r")
9086 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9087 (match_operand:SI 2 "s_register_operand" "r,r")])
9089 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9090 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9093 "%i1s%?\\t%0, %2, %4%S3"
9094 [(set_attr "conds" "set")
9095 (set_attr "shift" "4")
9096 (set_attr "arch" "32,a")
9097 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9099 (define_insn "*arith_shiftsi_compare0_scratch"
9100 [(set (reg:CC_NOOV CC_REGNUM)
9102 (match_operator:SI 1 "shiftable_operator"
9103 [(match_operator:SI 3 "shift_operator"
9104 [(match_operand:SI 4 "s_register_operand" "r,r")
9105 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9106 (match_operand:SI 2 "s_register_operand" "r,r")])
9108 (clobber (match_scratch:SI 0 "=r,r"))]
9110 "%i1s%?\\t%0, %2, %4%S3"
9111 [(set_attr "conds" "set")
9112 (set_attr "shift" "4")
9113 (set_attr "arch" "32,a")
9114 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9116 (define_insn "*sub_shiftsi"
9117 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9118 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9119 (match_operator:SI 2 "shift_operator"
9120 [(match_operand:SI 3 "s_register_operand" "r,r")
9121 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
9123 "sub%?\\t%0, %1, %3%S2"
9124 [(set_attr "predicable" "yes")
9125 (set_attr "predicable_short_it" "no")
9126 (set_attr "shift" "3")
9127 (set_attr "arch" "32,a")
9128 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9130 (define_insn "*sub_shiftsi_compare0"
9131 [(set (reg:CC_NOOV CC_REGNUM)
9133 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9134 (match_operator:SI 2 "shift_operator"
9135 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9136 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9138 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9139 (minus:SI (match_dup 1)
9140 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
9142 "subs%?\\t%0, %1, %3%S2"
9143 [(set_attr "conds" "set")
9144 (set_attr "shift" "3")
9145 (set_attr "arch" "32,a,a")
9146 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9148 (define_insn "*sub_shiftsi_compare0_scratch"
9149 [(set (reg:CC_NOOV CC_REGNUM)
9151 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9152 (match_operator:SI 2 "shift_operator"
9153 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9154 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9156 (clobber (match_scratch:SI 0 "=r,r,r"))]
9158 "subs%?\\t%0, %1, %3%S2"
9159 [(set_attr "conds" "set")
9160 (set_attr "shift" "3")
9161 (set_attr "arch" "32,a,a")
9162 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9165 (define_insn_and_split "*and_scc"
9166 [(set (match_operand:SI 0 "s_register_operand" "=r")
9167 (and:SI (match_operator:SI 1 "arm_comparison_operator"
9168 [(match_operand 2 "cc_register" "") (const_int 0)])
9169 (match_operand:SI 3 "s_register_operand" "r")))]
9171 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
9172 "&& reload_completed"
9173 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
9174 (cond_exec (match_dup 4) (set (match_dup 0)
9175 (and:SI (match_dup 3) (const_int 1))))]
9177 machine_mode mode = GET_MODE (operands[2]);
9178 enum rtx_code rc = GET_CODE (operands[1]);
9180 /* Note that operands[4] is the same as operands[1],
9181 but with VOIDmode as the result. */
9182 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9183 if (mode == CCFPmode || mode == CCFPEmode)
9184 rc = reverse_condition_maybe_unordered (rc);
9186 rc = reverse_condition (rc);
9187 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9189 [(set_attr "conds" "use")
9190 (set_attr "type" "multiple")
9191 (set_attr "length" "8")]
9194 (define_insn_and_split "*ior_scc"
9195 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9196 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
9197 [(match_operand 2 "cc_register" "") (const_int 0)])
9198 (match_operand:SI 3 "s_register_operand" "0,?r")))]
9203 "&& reload_completed
9204 && REGNO (operands [0]) != REGNO (operands[3])"
9205 ;; && which_alternative == 1
9206 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
9207 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
9208 (cond_exec (match_dup 4) (set (match_dup 0)
9209 (ior:SI (match_dup 3) (const_int 1))))]
9211 machine_mode mode = GET_MODE (operands[2]);
9212 enum rtx_code rc = GET_CODE (operands[1]);
9214 /* Note that operands[4] is the same as operands[1],
9215 but with VOIDmode as the result. */
9216 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9217 if (mode == CCFPmode || mode == CCFPEmode)
9218 rc = reverse_condition_maybe_unordered (rc);
9220 rc = reverse_condition (rc);
9221 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9223 [(set_attr "conds" "use")
9224 (set_attr "length" "4,8")
9225 (set_attr "type" "logic_imm,multiple")]
9228 ; A series of splitters for the compare_scc pattern below. Note that
9229 ; order is important.
9231 [(set (match_operand:SI 0 "s_register_operand" "")
9232 (lt:SI (match_operand:SI 1 "s_register_operand" "")
9234 (clobber (reg:CC CC_REGNUM))]
9235 "TARGET_32BIT && reload_completed"
9236 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9239 [(set (match_operand:SI 0 "s_register_operand" "")
9240 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9242 (clobber (reg:CC CC_REGNUM))]
9243 "TARGET_32BIT && reload_completed"
9244 [(set (match_dup 0) (not:SI (match_dup 1)))
9245 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9248 [(set (match_operand:SI 0 "s_register_operand" "")
9249 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9251 (clobber (reg:CC CC_REGNUM))]
9252 "arm_arch5t && TARGET_32BIT"
9253 [(set (match_dup 0) (clz:SI (match_dup 1)))
9254 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9258 [(set (match_operand:SI 0 "s_register_operand" "")
9259 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9261 (clobber (reg:CC CC_REGNUM))]
9262 "TARGET_32BIT && reload_completed"
9264 [(set (reg:CC CC_REGNUM)
9265 (compare:CC (const_int 1) (match_dup 1)))
9267 (minus:SI (const_int 1) (match_dup 1)))])
9268 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9269 (set (match_dup 0) (const_int 0)))])
9272 [(set (match_operand:SI 0 "s_register_operand" "")
9273 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9274 (match_operand:SI 2 "const_int_operand" "")))
9275 (clobber (reg:CC CC_REGNUM))]
9276 "TARGET_32BIT && reload_completed"
9278 [(set (reg:CC CC_REGNUM)
9279 (compare:CC (match_dup 1) (match_dup 2)))
9280 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9281 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9282 (set (match_dup 0) (const_int 1)))]
9284 operands[3] = GEN_INT (-INTVAL (operands[2]));
9288 [(set (match_operand:SI 0 "s_register_operand" "")
9289 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9290 (match_operand:SI 2 "arm_add_operand" "")))
9291 (clobber (reg:CC CC_REGNUM))]
9292 "TARGET_32BIT && reload_completed"
9294 [(set (reg:CC_NOOV CC_REGNUM)
9295 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9297 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9298 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9299 (set (match_dup 0) (const_int 1)))])
9301 (define_insn_and_split "*compare_scc"
9302 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9303 (match_operator:SI 1 "arm_comparison_operator"
9304 [(match_operand:SI 2 "s_register_operand" "r,r")
9305 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9306 (clobber (reg:CC CC_REGNUM))]
9309 "&& reload_completed"
9310 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9311 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9312 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9315 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9316 operands[2], operands[3]);
9317 enum rtx_code rc = GET_CODE (operands[1]);
9319 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9321 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9322 if (mode == CCFPmode || mode == CCFPEmode)
9323 rc = reverse_condition_maybe_unordered (rc);
9325 rc = reverse_condition (rc);
9326 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9328 [(set_attr "type" "multiple")]
9331 ;; Attempt to improve the sequence generated by the compare_scc splitters
9332 ;; not to use conditional execution.
9334 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9338 [(set (reg:CC CC_REGNUM)
9339 (compare:CC (match_operand:SI 1 "register_operand" "")
9341 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9342 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9343 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9344 (set (match_dup 0) (const_int 1)))]
9345 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9346 [(set (match_dup 0) (clz:SI (match_dup 1)))
9347 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9350 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9354 [(set (reg:CC CC_REGNUM)
9355 (compare:CC (match_operand:SI 1 "register_operand" "")
9357 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9358 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9359 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9360 (set (match_dup 0) (const_int 1)))
9361 (match_scratch:SI 2 "r")]
9362 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9364 [(set (reg:CC CC_REGNUM)
9365 (compare:CC (const_int 0) (match_dup 1)))
9366 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9368 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9369 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9372 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9373 ;; sub Rd, Reg1, reg2
9377 [(set (reg:CC CC_REGNUM)
9378 (compare:CC (match_operand:SI 1 "register_operand" "")
9379 (match_operand:SI 2 "arm_rhs_operand" "")))
9380 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9381 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9382 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9383 (set (match_dup 0) (const_int 1)))]
9384 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9385 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9386 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9387 (set (match_dup 0) (clz:SI (match_dup 0)))
9388 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9392 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9393 ;; sub T1, Reg1, reg2
9397 [(set (reg:CC CC_REGNUM)
9398 (compare:CC (match_operand:SI 1 "register_operand" "")
9399 (match_operand:SI 2 "arm_rhs_operand" "")))
9400 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9401 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9402 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9403 (set (match_dup 0) (const_int 1)))
9404 (match_scratch:SI 3 "r")]
9405 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9406 [(set (match_dup 3) (match_dup 4))
9408 [(set (reg:CC CC_REGNUM)
9409 (compare:CC (const_int 0) (match_dup 3)))
9410 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9412 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9413 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9415 if (CONST_INT_P (operands[2]))
9416 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9418 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9421 (define_insn "*cond_move"
9422 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9423 (if_then_else:SI (match_operator 3 "equality_operator"
9424 [(match_operator 4 "arm_comparison_operator"
9425 [(match_operand 5 "cc_register" "") (const_int 0)])
9427 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9428 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9431 if (GET_CODE (operands[3]) == NE)
9433 if (which_alternative != 1)
9434 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9435 if (which_alternative != 0)
9436 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9439 if (which_alternative != 0)
9440 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9441 if (which_alternative != 1)
9442 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9445 [(set_attr "conds" "use")
9446 (set_attr_alternative "type"
9447 [(if_then_else (match_operand 2 "const_int_operand" "")
9448 (const_string "mov_imm")
9449 (const_string "mov_reg"))
9450 (if_then_else (match_operand 1 "const_int_operand" "")
9451 (const_string "mov_imm")
9452 (const_string "mov_reg"))
9453 (const_string "multiple")])
9454 (set_attr "length" "4,4,8")]
9457 (define_insn "*cond_arith"
9458 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9459 (match_operator:SI 5 "shiftable_operator"
9460 [(match_operator:SI 4 "arm_comparison_operator"
9461 [(match_operand:SI 2 "s_register_operand" "r,r")
9462 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9463 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9464 (clobber (reg:CC CC_REGNUM))]
9467 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9468 return \"%i5\\t%0, %1, %2, lsr #31\";
9470 output_asm_insn (\"cmp\\t%2, %3\", operands);
9471 if (GET_CODE (operands[5]) == AND)
9472 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9473 else if (GET_CODE (operands[5]) == MINUS)
9474 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9475 else if (which_alternative != 0)
9476 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9477 return \"%i5%d4\\t%0, %1, #1\";
9479 [(set_attr "conds" "clob")
9480 (set_attr "length" "12")
9481 (set_attr "type" "multiple")]
9484 (define_insn "*cond_sub"
9485 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9486 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9487 (match_operator:SI 4 "arm_comparison_operator"
9488 [(match_operand:SI 2 "s_register_operand" "r,r")
9489 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9490 (clobber (reg:CC CC_REGNUM))]
9493 output_asm_insn (\"cmp\\t%2, %3\", operands);
9494 if (which_alternative != 0)
9495 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9496 return \"sub%d4\\t%0, %1, #1\";
9498 [(set_attr "conds" "clob")
9499 (set_attr "length" "8,12")
9500 (set_attr "type" "multiple")]
9503 (define_insn "*cmp_ite0"
9504 [(set (match_operand 6 "dominant_cc_register" "")
9507 (match_operator 4 "arm_comparison_operator"
9508 [(match_operand:SI 0 "s_register_operand"
9509 "l,l,l,r,r,r,r,r,r")
9510 (match_operand:SI 1 "arm_add_operand"
9511 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9512 (match_operator:SI 5 "arm_comparison_operator"
9513 [(match_operand:SI 2 "s_register_operand"
9514 "l,r,r,l,l,r,r,r,r")
9515 (match_operand:SI 3 "arm_add_operand"
9516 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9522 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9524 {\"cmp%d5\\t%0, %1\",
9525 \"cmp%d4\\t%2, %3\"},
9526 {\"cmn%d5\\t%0, #%n1\",
9527 \"cmp%d4\\t%2, %3\"},
9528 {\"cmp%d5\\t%0, %1\",
9529 \"cmn%d4\\t%2, #%n3\"},
9530 {\"cmn%d5\\t%0, #%n1\",
9531 \"cmn%d4\\t%2, #%n3\"}
9533 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9538 \"cmn\\t%0, #%n1\"},
9539 {\"cmn\\t%2, #%n3\",
9541 {\"cmn\\t%2, #%n3\",
9544 static const char * const ite[2] =
9549 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9550 CMP_CMP, CMN_CMP, CMP_CMP,
9551 CMN_CMP, CMP_CMN, CMN_CMN};
9553 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9555 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9556 if (TARGET_THUMB2) {
9557 output_asm_insn (ite[swap], operands);
9559 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9562 [(set_attr "conds" "set")
9563 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9564 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9565 (set_attr "type" "multiple")
9566 (set_attr_alternative "length"
9572 (if_then_else (eq_attr "is_thumb" "no")
9575 (if_then_else (eq_attr "is_thumb" "no")
9578 (if_then_else (eq_attr "is_thumb" "no")
9581 (if_then_else (eq_attr "is_thumb" "no")
9586 (define_insn "*cmp_ite1"
9587 [(set (match_operand 6 "dominant_cc_register" "")
9590 (match_operator 4 "arm_comparison_operator"
9591 [(match_operand:SI 0 "s_register_operand"
9592 "l,l,l,r,r,r,r,r,r")
9593 (match_operand:SI 1 "arm_add_operand"
9594 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9595 (match_operator:SI 5 "arm_comparison_operator"
9596 [(match_operand:SI 2 "s_register_operand"
9597 "l,r,r,l,l,r,r,r,r")
9598 (match_operand:SI 3 "arm_add_operand"
9599 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9605 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9609 {\"cmn\\t%0, #%n1\",
9612 \"cmn\\t%2, #%n3\"},
9613 {\"cmn\\t%0, #%n1\",
9616 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9618 {\"cmp%d4\\t%2, %3\",
9619 \"cmp%D5\\t%0, %1\"},
9620 {\"cmp%d4\\t%2, %3\",
9621 \"cmn%D5\\t%0, #%n1\"},
9622 {\"cmn%d4\\t%2, #%n3\",
9623 \"cmp%D5\\t%0, %1\"},
9624 {\"cmn%d4\\t%2, #%n3\",
9625 \"cmn%D5\\t%0, #%n1\"}
9627 static const char * const ite[2] =
9632 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9633 CMP_CMP, CMN_CMP, CMP_CMP,
9634 CMN_CMP, CMP_CMN, CMN_CMN};
9636 comparison_dominates_p (GET_CODE (operands[5]),
9637 reverse_condition (GET_CODE (operands[4])));
9639 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9640 if (TARGET_THUMB2) {
9641 output_asm_insn (ite[swap], operands);
9643 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9646 [(set_attr "conds" "set")
9647 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9648 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9649 (set_attr_alternative "length"
9655 (if_then_else (eq_attr "is_thumb" "no")
9658 (if_then_else (eq_attr "is_thumb" "no")
9661 (if_then_else (eq_attr "is_thumb" "no")
9664 (if_then_else (eq_attr "is_thumb" "no")
9667 (set_attr "type" "multiple")]
9670 (define_insn "*cmp_and"
9671 [(set (match_operand 6 "dominant_cc_register" "")
9674 (match_operator 4 "arm_comparison_operator"
9675 [(match_operand:SI 0 "s_register_operand"
9676 "l,l,l,r,r,r,r,r,r")
9677 (match_operand:SI 1 "arm_add_operand"
9678 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9679 (match_operator:SI 5 "arm_comparison_operator"
9680 [(match_operand:SI 2 "s_register_operand"
9681 "l,r,r,l,l,r,r,r,r")
9682 (match_operand:SI 3 "arm_add_operand"
9683 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9688 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9690 {\"cmp%d5\\t%0, %1\",
9691 \"cmp%d4\\t%2, %3\"},
9692 {\"cmn%d5\\t%0, #%n1\",
9693 \"cmp%d4\\t%2, %3\"},
9694 {\"cmp%d5\\t%0, %1\",
9695 \"cmn%d4\\t%2, #%n3\"},
9696 {\"cmn%d5\\t%0, #%n1\",
9697 \"cmn%d4\\t%2, #%n3\"}
9699 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9704 \"cmn\\t%0, #%n1\"},
9705 {\"cmn\\t%2, #%n3\",
9707 {\"cmn\\t%2, #%n3\",
9710 static const char *const ite[2] =
9715 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9716 CMP_CMP, CMN_CMP, CMP_CMP,
9717 CMN_CMP, CMP_CMN, CMN_CMN};
9719 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9721 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9722 if (TARGET_THUMB2) {
9723 output_asm_insn (ite[swap], operands);
9725 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9728 [(set_attr "conds" "set")
9729 (set_attr "predicable" "no")
9730 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9731 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9732 (set_attr_alternative "length"
9738 (if_then_else (eq_attr "is_thumb" "no")
9741 (if_then_else (eq_attr "is_thumb" "no")
9744 (if_then_else (eq_attr "is_thumb" "no")
9747 (if_then_else (eq_attr "is_thumb" "no")
9750 (set_attr "type" "multiple")]
9753 (define_insn "*cmp_ior"
9754 [(set (match_operand 6 "dominant_cc_register" "")
9757 (match_operator 4 "arm_comparison_operator"
9758 [(match_operand:SI 0 "s_register_operand"
9759 "l,l,l,r,r,r,r,r,r")
9760 (match_operand:SI 1 "arm_add_operand"
9761 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9762 (match_operator:SI 5 "arm_comparison_operator"
9763 [(match_operand:SI 2 "s_register_operand"
9764 "l,r,r,l,l,r,r,r,r")
9765 (match_operand:SI 3 "arm_add_operand"
9766 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9771 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9775 {\"cmn\\t%0, #%n1\",
9778 \"cmn\\t%2, #%n3\"},
9779 {\"cmn\\t%0, #%n1\",
9782 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9784 {\"cmp%D4\\t%2, %3\",
9785 \"cmp%D5\\t%0, %1\"},
9786 {\"cmp%D4\\t%2, %3\",
9787 \"cmn%D5\\t%0, #%n1\"},
9788 {\"cmn%D4\\t%2, #%n3\",
9789 \"cmp%D5\\t%0, %1\"},
9790 {\"cmn%D4\\t%2, #%n3\",
9791 \"cmn%D5\\t%0, #%n1\"}
9793 static const char *const ite[2] =
9798 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9799 CMP_CMP, CMN_CMP, CMP_CMP,
9800 CMN_CMP, CMP_CMN, CMN_CMN};
9802 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9804 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9805 if (TARGET_THUMB2) {
9806 output_asm_insn (ite[swap], operands);
9808 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9812 [(set_attr "conds" "set")
9813 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9814 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9815 (set_attr_alternative "length"
9821 (if_then_else (eq_attr "is_thumb" "no")
9824 (if_then_else (eq_attr "is_thumb" "no")
9827 (if_then_else (eq_attr "is_thumb" "no")
9830 (if_then_else (eq_attr "is_thumb" "no")
9833 (set_attr "type" "multiple")]
9836 (define_insn_and_split "*ior_scc_scc"
9837 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9838 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9839 [(match_operand:SI 1 "s_register_operand" "l,r")
9840 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9841 (match_operator:SI 6 "arm_comparison_operator"
9842 [(match_operand:SI 4 "s_register_operand" "l,r")
9843 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9844 (clobber (reg:CC CC_REGNUM))]
9846 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9849 "TARGET_32BIT && reload_completed"
9853 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9854 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9856 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9858 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9861 [(set_attr "conds" "clob")
9862 (set_attr "enabled_for_short_it" "yes,no")
9863 (set_attr "length" "16")
9864 (set_attr "type" "multiple")]
9867 ; If the above pattern is followed by a CMP insn, then the compare is
9868 ; redundant, since we can rework the conditional instruction that follows.
9869 (define_insn_and_split "*ior_scc_scc_cmp"
9870 [(set (match_operand 0 "dominant_cc_register" "")
9871 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9872 [(match_operand:SI 1 "s_register_operand" "l,r")
9873 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9874 (match_operator:SI 6 "arm_comparison_operator"
9875 [(match_operand:SI 4 "s_register_operand" "l,r")
9876 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9878 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9879 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9880 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9883 "TARGET_32BIT && reload_completed"
9887 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9888 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9890 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9892 [(set_attr "conds" "set")
9893 (set_attr "enabled_for_short_it" "yes,no")
9894 (set_attr "length" "16")
9895 (set_attr "type" "multiple")]
9898 (define_insn_and_split "*and_scc_scc"
9899 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9900 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9901 [(match_operand:SI 1 "s_register_operand" "l,r")
9902 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9903 (match_operator:SI 6 "arm_comparison_operator"
9904 [(match_operand:SI 4 "s_register_operand" "l,r")
9905 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9906 (clobber (reg:CC CC_REGNUM))]
9908 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9911 "TARGET_32BIT && reload_completed
9912 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9917 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9918 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9920 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9922 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9925 [(set_attr "conds" "clob")
9926 (set_attr "enabled_for_short_it" "yes,no")
9927 (set_attr "length" "16")
9928 (set_attr "type" "multiple")]
9931 ; If the above pattern is followed by a CMP insn, then the compare is
9932 ; redundant, since we can rework the conditional instruction that follows.
9933 (define_insn_and_split "*and_scc_scc_cmp"
9934 [(set (match_operand 0 "dominant_cc_register" "")
9935 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9936 [(match_operand:SI 1 "s_register_operand" "l,r")
9937 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9938 (match_operator:SI 6 "arm_comparison_operator"
9939 [(match_operand:SI 4 "s_register_operand" "l,r")
9940 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9942 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9943 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9944 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9947 "TARGET_32BIT && reload_completed"
9951 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9952 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9954 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9956 [(set_attr "conds" "set")
9957 (set_attr "enabled_for_short_it" "yes,no")
9958 (set_attr "length" "16")
9959 (set_attr "type" "multiple")]
9962 ;; If there is no dominance in the comparison, then we can still save an
9963 ;; instruction in the AND case, since we can know that the second compare
9964 ;; need only zero the value if false (if true, then the value is already
9966 (define_insn_and_split "*and_scc_scc_nodom"
9967 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9968 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9969 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9970 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9971 (match_operator:SI 6 "arm_comparison_operator"
9972 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9973 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9974 (clobber (reg:CC CC_REGNUM))]
9976 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9979 "TARGET_32BIT && reload_completed"
9980 [(parallel [(set (match_dup 0)
9981 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9982 (clobber (reg:CC CC_REGNUM))])
9983 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9985 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9988 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9989 operands[4], operands[5]),
9991 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9993 [(set_attr "conds" "clob")
9994 (set_attr "length" "20")
9995 (set_attr "type" "multiple")]
9999 [(set (reg:CC_NOOV CC_REGNUM)
10000 (compare:CC_NOOV (ior:SI
10001 (and:SI (match_operand:SI 0 "s_register_operand" "")
10003 (match_operator:SI 1 "arm_comparison_operator"
10004 [(match_operand:SI 2 "s_register_operand" "")
10005 (match_operand:SI 3 "arm_add_operand" "")]))
10007 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10009 [(set (match_dup 4)
10010 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10012 (set (reg:CC_NOOV CC_REGNUM)
10013 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10018 [(set (reg:CC_NOOV CC_REGNUM)
10019 (compare:CC_NOOV (ior:SI
10020 (match_operator:SI 1 "arm_comparison_operator"
10021 [(match_operand:SI 2 "s_register_operand" "")
10022 (match_operand:SI 3 "arm_add_operand" "")])
10023 (and:SI (match_operand:SI 0 "s_register_operand" "")
10026 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10028 [(set (match_dup 4)
10029 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10031 (set (reg:CC_NOOV CC_REGNUM)
10032 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10035 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10037 (define_insn_and_split "*negscc"
10038 [(set (match_operand:SI 0 "s_register_operand" "=r")
10039 (neg:SI (match_operator 3 "arm_comparison_operator"
10040 [(match_operand:SI 1 "s_register_operand" "r")
10041 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10042 (clobber (reg:CC CC_REGNUM))]
10045 "&& reload_completed"
10048 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10050 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10052 /* Emit mov\\t%0, %1, asr #31 */
10053 emit_insn (gen_rtx_SET (operands[0],
10054 gen_rtx_ASHIFTRT (SImode,
10059 else if (GET_CODE (operands[3]) == NE)
10061 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10062 if (CONST_INT_P (operands[2]))
10063 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10064 GEN_INT (- INTVAL (operands[2]))));
10066 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10068 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10069 gen_rtx_NE (SImode,
10072 gen_rtx_SET (operands[0],
10078 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10079 emit_insn (gen_rtx_SET (cc_reg,
10080 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10081 enum rtx_code rc = GET_CODE (operands[3]);
10083 rc = reverse_condition (rc);
10084 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10085 gen_rtx_fmt_ee (rc,
10089 gen_rtx_SET (operands[0], const0_rtx)));
10090 rc = GET_CODE (operands[3]);
10091 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10092 gen_rtx_fmt_ee (rc,
10096 gen_rtx_SET (operands[0],
10102 [(set_attr "conds" "clob")
10103 (set_attr "length" "12")
10104 (set_attr "type" "multiple")]
10107 (define_insn_and_split "movcond_addsi"
10108 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
10110 (match_operator 5 "comparison_operator"
10111 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
10112 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
10114 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
10115 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
10116 (clobber (reg:CC CC_REGNUM))]
10119 "&& reload_completed"
10120 [(set (reg:CC_NOOV CC_REGNUM)
10122 (plus:SI (match_dup 3)
10125 (set (match_dup 0) (match_dup 1))
10126 (cond_exec (match_dup 6)
10127 (set (match_dup 0) (match_dup 2)))]
10130 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
10131 operands[3], operands[4]);
10132 enum rtx_code rc = GET_CODE (operands[5]);
10133 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10134 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
10135 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
10136 rc = reverse_condition (rc);
10138 std::swap (operands[1], operands[2]);
10140 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10143 [(set_attr "conds" "clob")
10144 (set_attr "enabled_for_short_it" "no,yes,yes")
10145 (set_attr "type" "multiple")]
10148 (define_insn "movcond"
10149 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10151 (match_operator 5 "arm_comparison_operator"
10152 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10153 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
10154 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10155 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
10156 (clobber (reg:CC CC_REGNUM))]
10159 if (GET_CODE (operands[5]) == LT
10160 && (operands[4] == const0_rtx))
10162 if (which_alternative != 1 && REG_P (operands[1]))
10164 if (operands[2] == const0_rtx)
10165 return \"and\\t%0, %1, %3, asr #31\";
10166 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
10168 else if (which_alternative != 0 && REG_P (operands[2]))
10170 if (operands[1] == const0_rtx)
10171 return \"bic\\t%0, %2, %3, asr #31\";
10172 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
10174 /* The only case that falls through to here is when both ops 1 & 2
10178 if (GET_CODE (operands[5]) == GE
10179 && (operands[4] == const0_rtx))
10181 if (which_alternative != 1 && REG_P (operands[1]))
10183 if (operands[2] == const0_rtx)
10184 return \"bic\\t%0, %1, %3, asr #31\";
10185 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
10187 else if (which_alternative != 0 && REG_P (operands[2]))
10189 if (operands[1] == const0_rtx)
10190 return \"and\\t%0, %2, %3, asr #31\";
10191 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
10193 /* The only case that falls through to here is when both ops 1 & 2
10196 if (CONST_INT_P (operands[4])
10197 && !const_ok_for_arm (INTVAL (operands[4])))
10198 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
10200 output_asm_insn (\"cmp\\t%3, %4\", operands);
10201 if (which_alternative != 0)
10202 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
10203 if (which_alternative != 1)
10204 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
10207 [(set_attr "conds" "clob")
10208 (set_attr "length" "8,8,12")
10209 (set_attr "type" "multiple")]
10212 ;; ??? The patterns below need checking for Thumb-2 usefulness.
10214 (define_insn "*ifcompare_plus_move"
10215 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10216 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10217 [(match_operand:SI 4 "s_register_operand" "r,r")
10218 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10220 (match_operand:SI 2 "s_register_operand" "r,r")
10221 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10222 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10223 (clobber (reg:CC CC_REGNUM))]
10226 [(set_attr "conds" "clob")
10227 (set_attr "length" "8,12")
10228 (set_attr "type" "multiple")]
10231 (define_insn "*if_plus_move"
10232 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10234 (match_operator 4 "arm_comparison_operator"
10235 [(match_operand 5 "cc_register" "") (const_int 0)])
10237 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10238 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10239 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10242 add%d4\\t%0, %2, %3
10243 sub%d4\\t%0, %2, #%n3
10244 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10245 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10246 [(set_attr "conds" "use")
10247 (set_attr "length" "4,4,8,8")
10248 (set_attr_alternative "type"
10249 [(if_then_else (match_operand 3 "const_int_operand" "")
10250 (const_string "alu_imm" )
10251 (const_string "alu_sreg"))
10252 (const_string "alu_imm")
10253 (const_string "multiple")
10254 (const_string "multiple")])]
10257 (define_insn "*ifcompare_move_plus"
10258 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10259 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10260 [(match_operand:SI 4 "s_register_operand" "r,r")
10261 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10262 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10264 (match_operand:SI 2 "s_register_operand" "r,r")
10265 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10266 (clobber (reg:CC CC_REGNUM))]
10269 [(set_attr "conds" "clob")
10270 (set_attr "length" "8,12")
10271 (set_attr "type" "multiple")]
10274 (define_insn "*if_move_plus"
10275 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10277 (match_operator 4 "arm_comparison_operator"
10278 [(match_operand 5 "cc_register" "") (const_int 0)])
10279 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10281 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10282 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10285 add%D4\\t%0, %2, %3
10286 sub%D4\\t%0, %2, #%n3
10287 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10288 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10289 [(set_attr "conds" "use")
10290 (set_attr "length" "4,4,8,8")
10291 (set_attr_alternative "type"
10292 [(if_then_else (match_operand 3 "const_int_operand" "")
10293 (const_string "alu_imm" )
10294 (const_string "alu_sreg"))
10295 (const_string "alu_imm")
10296 (const_string "multiple")
10297 (const_string "multiple")])]
10300 (define_insn "*ifcompare_arith_arith"
10301 [(set (match_operand:SI 0 "s_register_operand" "=r")
10302 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10303 [(match_operand:SI 5 "s_register_operand" "r")
10304 (match_operand:SI 6 "arm_add_operand" "rIL")])
10305 (match_operator:SI 8 "shiftable_operator"
10306 [(match_operand:SI 1 "s_register_operand" "r")
10307 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10308 (match_operator:SI 7 "shiftable_operator"
10309 [(match_operand:SI 3 "s_register_operand" "r")
10310 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10311 (clobber (reg:CC CC_REGNUM))]
10314 [(set_attr "conds" "clob")
10315 (set_attr "length" "12")
10316 (set_attr "type" "multiple")]
10319 (define_insn "*if_arith_arith"
10320 [(set (match_operand:SI 0 "s_register_operand" "=r")
10321 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10322 [(match_operand 8 "cc_register" "") (const_int 0)])
10323 (match_operator:SI 6 "shiftable_operator"
10324 [(match_operand:SI 1 "s_register_operand" "r")
10325 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10326 (match_operator:SI 7 "shiftable_operator"
10327 [(match_operand:SI 3 "s_register_operand" "r")
10328 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10330 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10331 [(set_attr "conds" "use")
10332 (set_attr "length" "8")
10333 (set_attr "type" "multiple")]
10336 (define_insn "*ifcompare_arith_move"
10337 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10338 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10339 [(match_operand:SI 2 "s_register_operand" "r,r")
10340 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10341 (match_operator:SI 7 "shiftable_operator"
10342 [(match_operand:SI 4 "s_register_operand" "r,r")
10343 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10344 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10345 (clobber (reg:CC CC_REGNUM))]
10348 /* If we have an operation where (op x 0) is the identity operation and
10349 the conditional operator is LT or GE and we are comparing against zero and
10350 everything is in registers then we can do this in two instructions. */
10351 if (operands[3] == const0_rtx
10352 && GET_CODE (operands[7]) != AND
10353 && REG_P (operands[5])
10354 && REG_P (operands[1])
10355 && REGNO (operands[1]) == REGNO (operands[4])
10356 && REGNO (operands[4]) != REGNO (operands[0]))
10358 if (GET_CODE (operands[6]) == LT)
10359 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10360 else if (GET_CODE (operands[6]) == GE)
10361 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10363 if (CONST_INT_P (operands[3])
10364 && !const_ok_for_arm (INTVAL (operands[3])))
10365 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10367 output_asm_insn (\"cmp\\t%2, %3\", operands);
10368 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10369 if (which_alternative != 0)
10370 return \"mov%D6\\t%0, %1\";
10373 [(set_attr "conds" "clob")
10374 (set_attr "length" "8,12")
10375 (set_attr "type" "multiple")]
10378 (define_insn "*if_arith_move"
10379 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10380 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10381 [(match_operand 6 "cc_register" "") (const_int 0)])
10382 (match_operator:SI 5 "shiftable_operator"
10383 [(match_operand:SI 2 "s_register_operand" "r,r")
10384 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10385 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10388 %I5%d4\\t%0, %2, %3
10389 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10390 [(set_attr "conds" "use")
10391 (set_attr "length" "4,8")
10392 (set_attr_alternative "type"
10393 [(if_then_else (match_operand 3 "const_int_operand" "")
10394 (const_string "alu_shift_imm" )
10395 (const_string "alu_shift_reg"))
10396 (const_string "multiple")])]
10399 (define_insn "*ifcompare_move_arith"
10400 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10401 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10402 [(match_operand:SI 4 "s_register_operand" "r,r")
10403 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10404 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10405 (match_operator:SI 7 "shiftable_operator"
10406 [(match_operand:SI 2 "s_register_operand" "r,r")
10407 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10408 (clobber (reg:CC CC_REGNUM))]
10411 /* If we have an operation where (op x 0) is the identity operation and
10412 the conditional operator is LT or GE and we are comparing against zero and
10413 everything is in registers then we can do this in two instructions */
10414 if (operands[5] == const0_rtx
10415 && GET_CODE (operands[7]) != AND
10416 && REG_P (operands[3])
10417 && REG_P (operands[1])
10418 && REGNO (operands[1]) == REGNO (operands[2])
10419 && REGNO (operands[2]) != REGNO (operands[0]))
10421 if (GET_CODE (operands[6]) == GE)
10422 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10423 else if (GET_CODE (operands[6]) == LT)
10424 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10427 if (CONST_INT_P (operands[5])
10428 && !const_ok_for_arm (INTVAL (operands[5])))
10429 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10431 output_asm_insn (\"cmp\\t%4, %5\", operands);
10433 if (which_alternative != 0)
10434 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10435 return \"%I7%D6\\t%0, %2, %3\";
10437 [(set_attr "conds" "clob")
10438 (set_attr "length" "8,12")
10439 (set_attr "type" "multiple")]
10442 (define_insn "*if_move_arith"
10443 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10445 (match_operator 4 "arm_comparison_operator"
10446 [(match_operand 6 "cc_register" "") (const_int 0)])
10447 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10448 (match_operator:SI 5 "shiftable_operator"
10449 [(match_operand:SI 2 "s_register_operand" "r,r")
10450 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10453 %I5%D4\\t%0, %2, %3
10454 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10455 [(set_attr "conds" "use")
10456 (set_attr "length" "4,8")
10457 (set_attr_alternative "type"
10458 [(if_then_else (match_operand 3 "const_int_operand" "")
10459 (const_string "alu_shift_imm" )
10460 (const_string "alu_shift_reg"))
10461 (const_string "multiple")])]
10464 (define_insn "*ifcompare_move_not"
10465 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10467 (match_operator 5 "arm_comparison_operator"
10468 [(match_operand:SI 3 "s_register_operand" "r,r")
10469 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10470 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10472 (match_operand:SI 2 "s_register_operand" "r,r"))))
10473 (clobber (reg:CC CC_REGNUM))]
10476 [(set_attr "conds" "clob")
10477 (set_attr "length" "8,12")
10478 (set_attr "type" "multiple")]
10481 (define_insn "*if_move_not"
10482 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10484 (match_operator 4 "arm_comparison_operator"
10485 [(match_operand 3 "cc_register" "") (const_int 0)])
10486 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10487 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10491 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10492 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10493 [(set_attr "conds" "use")
10494 (set_attr "type" "mvn_reg")
10495 (set_attr "length" "4,8,8")
10496 (set_attr "type" "mvn_reg,multiple,multiple")]
10499 (define_insn "*ifcompare_not_move"
10500 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10502 (match_operator 5 "arm_comparison_operator"
10503 [(match_operand:SI 3 "s_register_operand" "r,r")
10504 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10506 (match_operand:SI 2 "s_register_operand" "r,r"))
10507 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10508 (clobber (reg:CC CC_REGNUM))]
10511 [(set_attr "conds" "clob")
10512 (set_attr "length" "8,12")
10513 (set_attr "type" "multiple")]
10516 (define_insn "*if_not_move"
10517 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10519 (match_operator 4 "arm_comparison_operator"
10520 [(match_operand 3 "cc_register" "") (const_int 0)])
10521 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10522 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10526 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10527 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10528 [(set_attr "conds" "use")
10529 (set_attr "type" "mvn_reg,multiple,multiple")
10530 (set_attr "length" "4,8,8")]
10533 (define_insn "*ifcompare_shift_move"
10534 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10536 (match_operator 6 "arm_comparison_operator"
10537 [(match_operand:SI 4 "s_register_operand" "r,r")
10538 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10539 (match_operator:SI 7 "shift_operator"
10540 [(match_operand:SI 2 "s_register_operand" "r,r")
10541 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10542 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10543 (clobber (reg:CC CC_REGNUM))]
10546 [(set_attr "conds" "clob")
10547 (set_attr "length" "8,12")
10548 (set_attr "type" "multiple")]
10551 (define_insn "*if_shift_move"
10552 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10554 (match_operator 5 "arm_comparison_operator"
10555 [(match_operand 6 "cc_register" "") (const_int 0)])
10556 (match_operator:SI 4 "shift_operator"
10557 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10558 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10559 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10563 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10564 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10565 [(set_attr "conds" "use")
10566 (set_attr "shift" "2")
10567 (set_attr "length" "4,8,8")
10568 (set_attr_alternative "type"
10569 [(if_then_else (match_operand 3 "const_int_operand" "")
10570 (const_string "mov_shift" )
10571 (const_string "mov_shift_reg"))
10572 (const_string "multiple")
10573 (const_string "multiple")])]
10576 (define_insn "*ifcompare_move_shift"
10577 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10579 (match_operator 6 "arm_comparison_operator"
10580 [(match_operand:SI 4 "s_register_operand" "r,r")
10581 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10582 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10583 (match_operator:SI 7 "shift_operator"
10584 [(match_operand:SI 2 "s_register_operand" "r,r")
10585 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10586 (clobber (reg:CC CC_REGNUM))]
10589 [(set_attr "conds" "clob")
10590 (set_attr "length" "8,12")
10591 (set_attr "type" "multiple")]
10594 (define_insn "*if_move_shift"
10595 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10597 (match_operator 5 "arm_comparison_operator"
10598 [(match_operand 6 "cc_register" "") (const_int 0)])
10599 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10600 (match_operator:SI 4 "shift_operator"
10601 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10602 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10606 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10607 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10608 [(set_attr "conds" "use")
10609 (set_attr "shift" "2")
10610 (set_attr "length" "4,8,8")
10611 (set_attr_alternative "type"
10612 [(if_then_else (match_operand 3 "const_int_operand" "")
10613 (const_string "mov_shift" )
10614 (const_string "mov_shift_reg"))
10615 (const_string "multiple")
10616 (const_string "multiple")])]
10619 (define_insn "*ifcompare_shift_shift"
10620 [(set (match_operand:SI 0 "s_register_operand" "=r")
10622 (match_operator 7 "arm_comparison_operator"
10623 [(match_operand:SI 5 "s_register_operand" "r")
10624 (match_operand:SI 6 "arm_add_operand" "rIL")])
10625 (match_operator:SI 8 "shift_operator"
10626 [(match_operand:SI 1 "s_register_operand" "r")
10627 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10628 (match_operator:SI 9 "shift_operator"
10629 [(match_operand:SI 3 "s_register_operand" "r")
10630 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10631 (clobber (reg:CC CC_REGNUM))]
10634 [(set_attr "conds" "clob")
10635 (set_attr "length" "12")
10636 (set_attr "type" "multiple")]
10639 (define_insn "*if_shift_shift"
10640 [(set (match_operand:SI 0 "s_register_operand" "=r")
10642 (match_operator 5 "arm_comparison_operator"
10643 [(match_operand 8 "cc_register" "") (const_int 0)])
10644 (match_operator:SI 6 "shift_operator"
10645 [(match_operand:SI 1 "s_register_operand" "r")
10646 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10647 (match_operator:SI 7 "shift_operator"
10648 [(match_operand:SI 3 "s_register_operand" "r")
10649 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10651 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10652 [(set_attr "conds" "use")
10653 (set_attr "shift" "1")
10654 (set_attr "length" "8")
10655 (set (attr "type") (if_then_else
10656 (and (match_operand 2 "const_int_operand" "")
10657 (match_operand 4 "const_int_operand" ""))
10658 (const_string "mov_shift")
10659 (const_string "mov_shift_reg")))]
10662 (define_insn "*ifcompare_not_arith"
10663 [(set (match_operand:SI 0 "s_register_operand" "=r")
10665 (match_operator 6 "arm_comparison_operator"
10666 [(match_operand:SI 4 "s_register_operand" "r")
10667 (match_operand:SI 5 "arm_add_operand" "rIL")])
10668 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10669 (match_operator:SI 7 "shiftable_operator"
10670 [(match_operand:SI 2 "s_register_operand" "r")
10671 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10672 (clobber (reg:CC CC_REGNUM))]
10675 [(set_attr "conds" "clob")
10676 (set_attr "length" "12")
10677 (set_attr "type" "multiple")]
10680 (define_insn "*if_not_arith"
10681 [(set (match_operand:SI 0 "s_register_operand" "=r")
10683 (match_operator 5 "arm_comparison_operator"
10684 [(match_operand 4 "cc_register" "") (const_int 0)])
10685 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10686 (match_operator:SI 6 "shiftable_operator"
10687 [(match_operand:SI 2 "s_register_operand" "r")
10688 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10690 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10691 [(set_attr "conds" "use")
10692 (set_attr "type" "mvn_reg")
10693 (set_attr "length" "8")]
10696 (define_insn "*ifcompare_arith_not"
10697 [(set (match_operand:SI 0 "s_register_operand" "=r")
10699 (match_operator 6 "arm_comparison_operator"
10700 [(match_operand:SI 4 "s_register_operand" "r")
10701 (match_operand:SI 5 "arm_add_operand" "rIL")])
10702 (match_operator:SI 7 "shiftable_operator"
10703 [(match_operand:SI 2 "s_register_operand" "r")
10704 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10705 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10706 (clobber (reg:CC CC_REGNUM))]
10709 [(set_attr "conds" "clob")
10710 (set_attr "length" "12")
10711 (set_attr "type" "multiple")]
10714 (define_insn "*if_arith_not"
10715 [(set (match_operand:SI 0 "s_register_operand" "=r")
10717 (match_operator 5 "arm_comparison_operator"
10718 [(match_operand 4 "cc_register" "") (const_int 0)])
10719 (match_operator:SI 6 "shiftable_operator"
10720 [(match_operand:SI 2 "s_register_operand" "r")
10721 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10722 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10724 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10725 [(set_attr "conds" "use")
10726 (set_attr "type" "multiple")
10727 (set_attr "length" "8")]
10730 (define_insn "*ifcompare_neg_move"
10731 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10733 (match_operator 5 "arm_comparison_operator"
10734 [(match_operand:SI 3 "s_register_operand" "r,r")
10735 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10736 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10737 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10738 (clobber (reg:CC CC_REGNUM))]
10741 [(set_attr "conds" "clob")
10742 (set_attr "length" "8,12")
10743 (set_attr "type" "multiple")]
10746 (define_insn_and_split "*if_neg_move"
10747 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10749 (match_operator 4 "arm_comparison_operator"
10750 [(match_operand 3 "cc_register" "") (const_int 0)])
10751 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10752 (match_operand:SI 1 "s_register_operand" "0,0")))]
10755 "&& reload_completed"
10756 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10757 (set (match_dup 0) (neg:SI (match_dup 2))))]
10759 [(set_attr "conds" "use")
10760 (set_attr "length" "4")
10761 (set_attr "arch" "t2,32")
10762 (set_attr "enabled_for_short_it" "yes,no")
10763 (set_attr "type" "logic_shift_imm")]
10766 (define_insn "*ifcompare_move_neg"
10767 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10769 (match_operator 5 "arm_comparison_operator"
10770 [(match_operand:SI 3 "s_register_operand" "r,r")
10771 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10772 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10773 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10774 (clobber (reg:CC CC_REGNUM))]
10777 [(set_attr "conds" "clob")
10778 (set_attr "length" "8,12")
10779 (set_attr "type" "multiple")]
10782 (define_insn_and_split "*if_move_neg"
10783 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10785 (match_operator 4 "arm_comparison_operator"
10786 [(match_operand 3 "cc_register" "") (const_int 0)])
10787 (match_operand:SI 1 "s_register_operand" "0,0")
10788 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10791 "&& reload_completed"
10792 [(cond_exec (match_dup 5)
10793 (set (match_dup 0) (neg:SI (match_dup 2))))]
10795 machine_mode mode = GET_MODE (operands[3]);
10796 rtx_code rc = GET_CODE (operands[4]);
10798 if (mode == CCFPmode || mode == CCFPEmode)
10799 rc = reverse_condition_maybe_unordered (rc);
10801 rc = reverse_condition (rc);
10803 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10805 [(set_attr "conds" "use")
10806 (set_attr "length" "4")
10807 (set_attr "arch" "t2,32")
10808 (set_attr "enabled_for_short_it" "yes,no")
10809 (set_attr "type" "logic_shift_imm")]
10812 (define_insn "*arith_adjacentmem"
10813 [(set (match_operand:SI 0 "s_register_operand" "=r")
10814 (match_operator:SI 1 "shiftable_operator"
10815 [(match_operand:SI 2 "memory_operand" "m")
10816 (match_operand:SI 3 "memory_operand" "m")]))
10817 (clobber (match_scratch:SI 4 "=r"))]
10818 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10824 HOST_WIDE_INT val1 = 0, val2 = 0;
10826 if (REGNO (operands[0]) > REGNO (operands[4]))
10828 ldm[1] = operands[4];
10829 ldm[2] = operands[0];
10833 ldm[1] = operands[0];
10834 ldm[2] = operands[4];
10837 base_reg = XEXP (operands[2], 0);
10839 if (!REG_P (base_reg))
10841 val1 = INTVAL (XEXP (base_reg, 1));
10842 base_reg = XEXP (base_reg, 0);
10845 if (!REG_P (XEXP (operands[3], 0)))
10846 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10848 arith[0] = operands[0];
10849 arith[3] = operands[1];
10863 if (val1 !=0 && val2 != 0)
10867 if (val1 == 4 || val2 == 4)
10868 /* Other val must be 8, since we know they are adjacent and neither
10870 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10871 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10873 ldm[0] = ops[0] = operands[4];
10875 ops[2] = GEN_INT (val1);
10876 output_add_immediate (ops);
10878 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10880 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10884 /* Offset is out of range for a single add, so use two ldr. */
10887 ops[2] = GEN_INT (val1);
10888 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10890 ops[2] = GEN_INT (val2);
10891 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10894 else if (val1 != 0)
10897 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10899 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10904 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10906 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10908 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10911 [(set_attr "length" "12")
10912 (set_attr "predicable" "yes")
10913 (set_attr "type" "load_4")]
10916 ; This pattern is never tried by combine, so do it as a peephole
10919 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10920 (match_operand:SI 1 "arm_general_register_operand" ""))
10921 (set (reg:CC CC_REGNUM)
10922 (compare:CC (match_dup 1) (const_int 0)))]
10924 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10925 (set (match_dup 0) (match_dup 1))])]
10930 [(set (match_operand:SI 0 "s_register_operand" "")
10931 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10933 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10934 [(match_operand:SI 3 "s_register_operand" "")
10935 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10936 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10938 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10939 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10944 ;; This split can be used because CC_Z mode implies that the following
10945 ;; branch will be an equality, or an unsigned inequality, so the sign
10946 ;; extension is not needed.
10949 [(set (reg:CC_Z CC_REGNUM)
10951 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10953 (match_operand 1 "const_int_operand" "")))
10954 (clobber (match_scratch:SI 2 ""))]
10956 && ((UINTVAL (operands[1]))
10957 == ((UINTVAL (operands[1])) >> 24) << 24)"
10958 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10959 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10961 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10964 ;; ??? Check the patterns above for Thumb-2 usefulness
10966 (define_expand "prologue"
10967 [(clobber (const_int 0))]
10970 arm_expand_prologue ();
10972 thumb1_expand_prologue ();
10977 (define_expand "epilogue"
10978 [(clobber (const_int 0))]
10981 if (crtl->calls_eh_return)
10982 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10985 thumb1_expand_epilogue ();
10986 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10987 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10989 else if (HAVE_return)
10991 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10992 no need for explicit testing again. */
10993 emit_jump_insn (gen_return ());
10995 else if (TARGET_32BIT)
10997 arm_expand_epilogue (true);
11003 ;; Note - although unspec_volatile's USE all hard registers,
11004 ;; USEs are ignored after relaod has completed. Thus we need
11005 ;; to add an unspec of the link register to ensure that flow
11006 ;; does not think that it is unused by the sibcall branch that
11007 ;; will replace the standard function epilogue.
11008 (define_expand "sibcall_epilogue"
11009 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
11010 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
11013 arm_expand_epilogue (false);
11018 (define_expand "eh_epilogue"
11019 [(use (match_operand:SI 0 "register_operand" ""))
11020 (use (match_operand:SI 1 "register_operand" ""))
11021 (use (match_operand:SI 2 "register_operand" ""))]
11025 cfun->machine->eh_epilogue_sp_ofs = operands[1];
11026 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11028 rtx ra = gen_rtx_REG (Pmode, 2);
11030 emit_move_insn (ra, operands[2]);
11033 /* This is a hack -- we may have crystalized the function type too
11035 cfun->machine->func_type = 0;
11039 ;; This split is only used during output to reduce the number of patterns
11040 ;; that need assembler instructions adding to them. We allowed the setting
11041 ;; of the conditions to be implicit during rtl generation so that
11042 ;; the conditional compare patterns would work. However this conflicts to
11043 ;; some extent with the conditional data operations, so we have to split them
11046 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
11047 ;; conditional execution sufficient?
11050 [(set (match_operand:SI 0 "s_register_operand" "")
11051 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11052 [(match_operand 2 "" "") (match_operand 3 "" "")])
11054 (match_operand 4 "" "")))
11055 (clobber (reg:CC CC_REGNUM))]
11056 "TARGET_ARM && reload_completed"
11057 [(set (match_dup 5) (match_dup 6))
11058 (cond_exec (match_dup 7)
11059 (set (match_dup 0) (match_dup 4)))]
11062 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11063 operands[2], operands[3]);
11064 enum rtx_code rc = GET_CODE (operands[1]);
11066 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11067 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11068 if (mode == CCFPmode || mode == CCFPEmode)
11069 rc = reverse_condition_maybe_unordered (rc);
11071 rc = reverse_condition (rc);
11073 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11078 [(set (match_operand:SI 0 "s_register_operand" "")
11079 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11080 [(match_operand 2 "" "") (match_operand 3 "" "")])
11081 (match_operand 4 "" "")
11083 (clobber (reg:CC CC_REGNUM))]
11084 "TARGET_ARM && reload_completed"
11085 [(set (match_dup 5) (match_dup 6))
11086 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11087 (set (match_dup 0) (match_dup 4)))]
11090 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11091 operands[2], operands[3]);
11093 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11094 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11099 [(set (match_operand:SI 0 "s_register_operand" "")
11100 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11101 [(match_operand 2 "" "") (match_operand 3 "" "")])
11102 (match_operand 4 "" "")
11103 (match_operand 5 "" "")))
11104 (clobber (reg:CC CC_REGNUM))]
11105 "TARGET_ARM && reload_completed"
11106 [(set (match_dup 6) (match_dup 7))
11107 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11108 (set (match_dup 0) (match_dup 4)))
11109 (cond_exec (match_dup 8)
11110 (set (match_dup 0) (match_dup 5)))]
11113 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11114 operands[2], operands[3]);
11115 enum rtx_code rc = GET_CODE (operands[1]);
11117 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11118 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11119 if (mode == CCFPmode || mode == CCFPEmode)
11120 rc = reverse_condition_maybe_unordered (rc);
11122 rc = reverse_condition (rc);
11124 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11129 [(set (match_operand:SI 0 "s_register_operand" "")
11130 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11131 [(match_operand:SI 2 "s_register_operand" "")
11132 (match_operand:SI 3 "arm_add_operand" "")])
11133 (match_operand:SI 4 "arm_rhs_operand" "")
11135 (match_operand:SI 5 "s_register_operand" ""))))
11136 (clobber (reg:CC CC_REGNUM))]
11137 "TARGET_ARM && reload_completed"
11138 [(set (match_dup 6) (match_dup 7))
11139 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11140 (set (match_dup 0) (match_dup 4)))
11141 (cond_exec (match_dup 8)
11142 (set (match_dup 0) (not:SI (match_dup 5))))]
11145 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11146 operands[2], operands[3]);
11147 enum rtx_code rc = GET_CODE (operands[1]);
11149 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11150 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11151 if (mode == CCFPmode || mode == CCFPEmode)
11152 rc = reverse_condition_maybe_unordered (rc);
11154 rc = reverse_condition (rc);
11156 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11160 (define_insn "*cond_move_not"
11161 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11162 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11163 [(match_operand 3 "cc_register" "") (const_int 0)])
11164 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11166 (match_operand:SI 2 "s_register_operand" "r,r"))))]
11170 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11171 [(set_attr "conds" "use")
11172 (set_attr "type" "mvn_reg,multiple")
11173 (set_attr "length" "4,8")]
11176 ;; The next two patterns occur when an AND operation is followed by a
11177 ;; scc insn sequence
11179 (define_insn "*sign_extract_onebit"
11180 [(set (match_operand:SI 0 "s_register_operand" "=r")
11181 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11183 (match_operand:SI 2 "const_int_operand" "n")))
11184 (clobber (reg:CC CC_REGNUM))]
11187 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11188 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
11189 return \"mvnne\\t%0, #0\";
11191 [(set_attr "conds" "clob")
11192 (set_attr "length" "8")
11193 (set_attr "type" "multiple")]
11196 (define_insn "*not_signextract_onebit"
11197 [(set (match_operand:SI 0 "s_register_operand" "=r")
11199 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11201 (match_operand:SI 2 "const_int_operand" "n"))))
11202 (clobber (reg:CC CC_REGNUM))]
11205 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11206 output_asm_insn (\"tst\\t%1, %2\", operands);
11207 output_asm_insn (\"mvneq\\t%0, #0\", operands);
11208 return \"movne\\t%0, #0\";
11210 [(set_attr "conds" "clob")
11211 (set_attr "length" "12")
11212 (set_attr "type" "multiple")]
11214 ;; ??? The above patterns need auditing for Thumb-2
11216 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
11217 ;; expressions. For simplicity, the first register is also in the unspec
11219 ;; To avoid the usage of GNU extension, the length attribute is computed
11220 ;; in a C function arm_attr_length_push_multi.
11221 (define_insn "*push_multi"
11222 [(match_parallel 2 "multi_register_push"
11223 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11224 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11225 UNSPEC_PUSH_MULT))])]
11229 int num_saves = XVECLEN (operands[2], 0);
11231 /* For the StrongARM at least it is faster to
11232 use STR to store only a single register.
11233 In Thumb mode always use push, and the assembler will pick
11234 something appropriate. */
11235 if (num_saves == 1 && TARGET_ARM)
11236 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11243 strcpy (pattern, \"push%?\\t{%1\");
11245 strcpy (pattern, \"push\\t{%1\");
11247 for (i = 1; i < num_saves; i++)
11249 strcat (pattern, \", %|\");
11251 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11254 strcat (pattern, \"}\");
11255 output_asm_insn (pattern, operands);
11260 [(set_attr "type" "store_16")
11261 (set (attr "length")
11262 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11265 (define_insn "stack_tie"
11266 [(set (mem:BLK (scratch))
11267 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11268 (match_operand:SI 1 "s_register_operand" "rk")]
11272 [(set_attr "length" "0")
11273 (set_attr "type" "block")]
11276 ;; Pop (as used in epilogue RTL)
11278 (define_insn "*load_multiple_with_writeback"
11279 [(match_parallel 0 "load_multiple_operation"
11280 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11281 (plus:SI (match_dup 1)
11282 (match_operand:SI 2 "const_int_I_operand" "I")))
11283 (set (match_operand:SI 3 "s_register_operand" "=rk")
11284 (mem:SI (match_dup 1)))
11286 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11289 arm_output_multireg_pop (operands, /*return_pc=*/false,
11290 /*cond=*/const_true_rtx,
11296 [(set_attr "type" "load_16")
11297 (set_attr "predicable" "yes")
11298 (set (attr "length")
11299 (symbol_ref "arm_attr_length_pop_multi (operands,
11300 /*return_pc=*/false,
11301 /*write_back_p=*/true)"))]
11304 ;; Pop with return (as used in epilogue RTL)
11306 ;; This instruction is generated when the registers are popped at the end of
11307 ;; epilogue. Here, instead of popping the value into LR and then generating
11308 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11310 (define_insn "*pop_multiple_with_writeback_and_return"
11311 [(match_parallel 0 "pop_multiple_return"
11313 (set (match_operand:SI 1 "s_register_operand" "+rk")
11314 (plus:SI (match_dup 1)
11315 (match_operand:SI 2 "const_int_I_operand" "I")))
11316 (set (match_operand:SI 3 "s_register_operand" "=rk")
11317 (mem:SI (match_dup 1)))
11319 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11322 arm_output_multireg_pop (operands, /*return_pc=*/true,
11323 /*cond=*/const_true_rtx,
11329 [(set_attr "type" "load_16")
11330 (set_attr "predicable" "yes")
11331 (set (attr "length")
11332 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11333 /*write_back_p=*/true)"))]
11336 (define_insn "*pop_multiple_with_return"
11337 [(match_parallel 0 "pop_multiple_return"
11339 (set (match_operand:SI 2 "s_register_operand" "=rk")
11340 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11342 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11345 arm_output_multireg_pop (operands, /*return_pc=*/true,
11346 /*cond=*/const_true_rtx,
11352 [(set_attr "type" "load_16")
11353 (set_attr "predicable" "yes")
11354 (set (attr "length")
11355 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11356 /*write_back_p=*/false)"))]
11359 ;; Load into PC and return
11360 (define_insn "*ldr_with_return"
11362 (set (reg:SI PC_REGNUM)
11363 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11364 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11365 "ldr%?\t%|pc, [%0], #4"
11366 [(set_attr "type" "load_4")
11367 (set_attr "predicable" "yes")]
11369 ;; Pop for floating point registers (as used in epilogue RTL)
11370 (define_insn "*vfp_pop_multiple_with_writeback"
11371 [(match_parallel 0 "pop_multiple_fp"
11372 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11373 (plus:SI (match_dup 1)
11374 (match_operand:SI 2 "const_int_I_operand" "I")))
11375 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11376 (mem:DF (match_dup 1)))])]
11377 "TARGET_32BIT && TARGET_HARD_FLOAT"
11380 int num_regs = XVECLEN (operands[0], 0);
11383 strcpy (pattern, \"vldm\\t\");
11384 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11385 strcat (pattern, \"!, {\");
11386 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11387 strcat (pattern, \"%P0\");
11388 if ((num_regs - 1) > 1)
11390 strcat (pattern, \"-%P1\");
11391 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11394 strcat (pattern, \"}\");
11395 output_asm_insn (pattern, op_list);
11399 [(set_attr "type" "load_16")
11400 (set_attr "conds" "unconditional")
11401 (set_attr "predicable" "no")]
11404 ;; Special patterns for dealing with the constant pool
11406 (define_insn "align_4"
11407 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11410 assemble_align (32);
11413 [(set_attr "type" "no_insn")]
11416 (define_insn "align_8"
11417 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11420 assemble_align (64);
11423 [(set_attr "type" "no_insn")]
11426 (define_insn "consttable_end"
11427 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11430 making_const_table = FALSE;
11433 [(set_attr "type" "no_insn")]
11436 (define_insn "consttable_1"
11437 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11440 making_const_table = TRUE;
11441 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11442 assemble_zeros (3);
11445 [(set_attr "length" "4")
11446 (set_attr "type" "no_insn")]
11449 (define_insn "consttable_2"
11450 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11454 rtx x = operands[0];
11455 making_const_table = TRUE;
11456 switch (GET_MODE_CLASS (GET_MODE (x)))
11459 arm_emit_fp16_const (x);
11462 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11463 assemble_zeros (2);
11468 [(set_attr "length" "4")
11469 (set_attr "type" "no_insn")]
11472 (define_insn "consttable_4"
11473 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11477 rtx x = operands[0];
11478 making_const_table = TRUE;
11479 scalar_float_mode float_mode;
11480 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11481 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11484 /* XXX: Sometimes gcc does something really dumb and ends up with
11485 a HIGH in a constant pool entry, usually because it's trying to
11486 load into a VFP register. We know this will always be used in
11487 combination with a LO_SUM which ignores the high bits, so just
11488 strip off the HIGH. */
11489 if (GET_CODE (x) == HIGH)
11491 assemble_integer (x, 4, BITS_PER_WORD, 1);
11492 mark_symbol_refs_as_used (x);
11496 [(set_attr "length" "4")
11497 (set_attr "type" "no_insn")]
11500 (define_insn "consttable_8"
11501 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11505 making_const_table = TRUE;
11506 scalar_float_mode float_mode;
11507 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11508 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11509 float_mode, BITS_PER_WORD);
11511 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11514 [(set_attr "length" "8")
11515 (set_attr "type" "no_insn")]
11518 (define_insn "consttable_16"
11519 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11523 making_const_table = TRUE;
11524 scalar_float_mode float_mode;
11525 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11526 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11527 float_mode, BITS_PER_WORD);
11529 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11532 [(set_attr "length" "16")
11533 (set_attr "type" "no_insn")]
11536 ;; V5 Instructions,
11538 (define_insn "clzsi2"
11539 [(set (match_operand:SI 0 "s_register_operand" "=r")
11540 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11541 "TARGET_32BIT && arm_arch5t"
11543 [(set_attr "predicable" "yes")
11544 (set_attr "type" "clz")])
11546 (define_insn "rbitsi2"
11547 [(set (match_operand:SI 0 "s_register_operand" "=r")
11548 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11549 "TARGET_32BIT && arm_arch_thumb2"
11551 [(set_attr "predicable" "yes")
11552 (set_attr "type" "clz")])
11554 ;; Keep this as a CTZ expression until after reload and then split
11555 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11556 ;; to fold with any other expression.
11558 (define_insn_and_split "ctzsi2"
11559 [(set (match_operand:SI 0 "s_register_operand" "=r")
11560 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11561 "TARGET_32BIT && arm_arch_thumb2"
11563 "&& reload_completed"
11566 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11567 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11571 ;; V5E instructions.
11573 (define_insn "prefetch"
11574 [(prefetch (match_operand:SI 0 "address_operand" "p")
11575 (match_operand:SI 1 "" "")
11576 (match_operand:SI 2 "" ""))]
11577 "TARGET_32BIT && arm_arch5te"
11579 [(set_attr "type" "load_4")]
11582 ;; General predication pattern
11585 [(match_operator 0 "arm_comparison_operator"
11586 [(match_operand 1 "cc_register" "")
11589 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11591 [(set_attr "predicated" "yes")]
11594 (define_insn "force_register_use"
11595 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11598 [(set_attr "length" "0")
11599 (set_attr "type" "no_insn")]
11603 ;; Patterns for exception handling
11605 (define_expand "eh_return"
11606 [(use (match_operand 0 "general_operand" ""))]
11611 emit_insn (gen_arm_eh_return (operands[0]));
11613 emit_insn (gen_thumb_eh_return (operands[0]));
11618 ;; We can't expand this before we know where the link register is stored.
11619 (define_insn_and_split "arm_eh_return"
11620 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11622 (clobber (match_scratch:SI 1 "=&r"))]
11625 "&& reload_completed"
11629 arm_set_return_address (operands[0], operands[1]);
11637 (define_insn "load_tp_hard"
11638 [(set (match_operand:SI 0 "register_operand" "=r")
11639 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11641 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11642 [(set_attr "predicable" "yes")
11643 (set_attr "type" "mrs")]
11646 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11647 (define_insn "load_tp_soft"
11648 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11649 (clobber (reg:SI LR_REGNUM))
11650 (clobber (reg:SI IP_REGNUM))
11651 (clobber (reg:CC CC_REGNUM))]
11653 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11654 [(set_attr "conds" "clob")
11655 (set_attr "type" "branch")]
11658 ;; tls descriptor call
11659 (define_insn "tlscall"
11660 [(set (reg:SI R0_REGNUM)
11661 (unspec:SI [(reg:SI R0_REGNUM)
11662 (match_operand:SI 0 "" "X")
11663 (match_operand 1 "" "")] UNSPEC_TLS))
11664 (clobber (reg:SI R1_REGNUM))
11665 (clobber (reg:SI LR_REGNUM))
11666 (clobber (reg:SI CC_REGNUM))]
11669 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11670 INTVAL (operands[1]));
11671 return "bl\\t%c0(tlscall)";
11673 [(set_attr "conds" "clob")
11674 (set_attr "length" "4")
11675 (set_attr "type" "branch")]
11678 ;; For thread pointer builtin
11679 (define_expand "get_thread_pointersi"
11680 [(match_operand:SI 0 "s_register_operand" "=r")]
11684 arm_load_tp (operands[0]);
11690 ;; We only care about the lower 16 bits of the constant
11691 ;; being inserted into the upper 16 bits of the register.
11692 (define_insn "*arm_movtas_ze"
11693 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11696 (match_operand:SI 1 "const_int_operand" ""))]
11701 [(set_attr "arch" "32,v8mb")
11702 (set_attr "predicable" "yes")
11703 (set_attr "length" "4")
11704 (set_attr "type" "alu_sreg")]
11707 (define_insn "*arm_rev"
11708 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11709 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11715 [(set_attr "arch" "t1,t2,32")
11716 (set_attr "length" "2,2,4")
11717 (set_attr "predicable" "no,yes,yes")
11718 (set_attr "type" "rev")]
11721 (define_expand "arm_legacy_rev"
11722 [(set (match_operand:SI 2 "s_register_operand" "")
11723 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11727 (lshiftrt:SI (match_dup 2)
11729 (set (match_operand:SI 3 "s_register_operand" "")
11730 (rotatert:SI (match_dup 1)
11733 (and:SI (match_dup 2)
11734 (const_int -65281)))
11735 (set (match_operand:SI 0 "s_register_operand" "")
11736 (xor:SI (match_dup 3)
11742 ;; Reuse temporaries to keep register pressure down.
11743 (define_expand "thumb_legacy_rev"
11744 [(set (match_operand:SI 2 "s_register_operand" "")
11745 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11747 (set (match_operand:SI 3 "s_register_operand" "")
11748 (lshiftrt:SI (match_dup 1)
11751 (ior:SI (match_dup 3)
11753 (set (match_operand:SI 4 "s_register_operand" "")
11755 (set (match_operand:SI 5 "s_register_operand" "")
11756 (rotatert:SI (match_dup 1)
11759 (ashift:SI (match_dup 5)
11762 (lshiftrt:SI (match_dup 5)
11765 (ior:SI (match_dup 5)
11768 (rotatert:SI (match_dup 5)
11770 (set (match_operand:SI 0 "s_register_operand" "")
11771 (ior:SI (match_dup 5)
11777 ;; ARM-specific expansion of signed mod by power of 2
11778 ;; using conditional negate.
11779 ;; For r0 % n where n is a power of 2 produce:
11781 ;; and r0, r0, #(n - 1)
11782 ;; and r1, r1, #(n - 1)
11783 ;; rsbpl r0, r1, #0
11785 (define_expand "modsi3"
11786 [(match_operand:SI 0 "register_operand" "")
11787 (match_operand:SI 1 "register_operand" "")
11788 (match_operand:SI 2 "const_int_operand" "")]
11791 HOST_WIDE_INT val = INTVAL (operands[2]);
11794 || exact_log2 (val) <= 0)
11797 rtx mask = GEN_INT (val - 1);
11799 /* In the special case of x0 % 2 we can do the even shorter:
11802 rsblt r0, r0, #0. */
11806 rtx cc_reg = arm_gen_compare_reg (LT,
11807 operands[1], const0_rtx, NULL_RTX);
11808 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11809 rtx masked = gen_reg_rtx (SImode);
11811 emit_insn (gen_andsi3 (masked, operands[1], mask));
11812 emit_move_insn (operands[0],
11813 gen_rtx_IF_THEN_ELSE (SImode, cond,
11814 gen_rtx_NEG (SImode,
11820 rtx neg_op = gen_reg_rtx (SImode);
11821 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11824 /* Extract the condition register and mode. */
11825 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11826 rtx cc_reg = SET_DEST (cmp);
11827 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11829 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11831 rtx masked_neg = gen_reg_rtx (SImode);
11832 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11834 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11835 during expand does not always work. Do an IF_THEN_ELSE instead. */
11836 emit_move_insn (operands[0],
11837 gen_rtx_IF_THEN_ELSE (SImode, cond,
11838 gen_rtx_NEG (SImode, masked_neg),
11846 (define_expand "bswapsi2"
11847 [(set (match_operand:SI 0 "s_register_operand" "=r")
11848 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11849 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11853 rtx op2 = gen_reg_rtx (SImode);
11854 rtx op3 = gen_reg_rtx (SImode);
11858 rtx op4 = gen_reg_rtx (SImode);
11859 rtx op5 = gen_reg_rtx (SImode);
11861 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11862 op2, op3, op4, op5));
11866 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11875 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11876 ;; and unsigned variants, respectively. For rev16, expose
11877 ;; byte-swapping in the lower 16 bits only.
11878 (define_insn "*arm_revsh"
11879 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11880 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11886 [(set_attr "arch" "t1,t2,32")
11887 (set_attr "length" "2,2,4")
11888 (set_attr "type" "rev")]
11891 (define_insn "*arm_rev16"
11892 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11893 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11899 [(set_attr "arch" "t1,t2,32")
11900 (set_attr "length" "2,2,4")
11901 (set_attr "type" "rev")]
11904 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11905 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11906 ;; each valid permutation.
11908 (define_insn "arm_rev16si2"
11909 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11910 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11912 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11913 (and:SI (lshiftrt:SI (match_dup 1)
11915 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11917 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11918 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11920 [(set_attr "arch" "t1,t2,32")
11921 (set_attr "length" "2,2,4")
11922 (set_attr "type" "rev")]
11925 (define_insn "arm_rev16si2_alt"
11926 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11927 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11929 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11930 (and:SI (ashift:SI (match_dup 1)
11932 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11934 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11935 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11937 [(set_attr "arch" "t1,t2,32")
11938 (set_attr "length" "2,2,4")
11939 (set_attr "type" "rev")]
11942 (define_expand "bswaphi2"
11943 [(set (match_operand:HI 0 "s_register_operand" "=r")
11944 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11949 ;; Patterns for LDRD/STRD in Thumb2 mode
11951 (define_insn "*thumb2_ldrd"
11952 [(set (match_operand:SI 0 "s_register_operand" "=r")
11953 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11954 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11955 (set (match_operand:SI 3 "s_register_operand" "=r")
11956 (mem:SI (plus:SI (match_dup 1)
11957 (match_operand:SI 4 "const_int_operand" ""))))]
11958 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11959 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11960 && (operands_ok_ldrd_strd (operands[0], operands[3],
11961 operands[1], INTVAL (operands[2]),
11963 "ldrd%?\t%0, %3, [%1, %2]"
11964 [(set_attr "type" "load_8")
11965 (set_attr "predicable" "yes")])
11967 (define_insn "*thumb2_ldrd_base"
11968 [(set (match_operand:SI 0 "s_register_operand" "=r")
11969 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11970 (set (match_operand:SI 2 "s_register_operand" "=r")
11971 (mem:SI (plus:SI (match_dup 1)
11973 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11974 && (operands_ok_ldrd_strd (operands[0], operands[2],
11975 operands[1], 0, false, true))"
11976 "ldrd%?\t%0, %2, [%1]"
11977 [(set_attr "type" "load_8")
11978 (set_attr "predicable" "yes")])
11980 (define_insn "*thumb2_ldrd_base_neg"
11981 [(set (match_operand:SI 0 "s_register_operand" "=r")
11982 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11984 (set (match_operand:SI 2 "s_register_operand" "=r")
11985 (mem:SI (match_dup 1)))]
11986 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11987 && (operands_ok_ldrd_strd (operands[0], operands[2],
11988 operands[1], -4, false, true))"
11989 "ldrd%?\t%0, %2, [%1, #-4]"
11990 [(set_attr "type" "load_8")
11991 (set_attr "predicable" "yes")])
11993 (define_insn "*thumb2_strd"
11994 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11995 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11996 (match_operand:SI 2 "s_register_operand" "r"))
11997 (set (mem:SI (plus:SI (match_dup 0)
11998 (match_operand:SI 3 "const_int_operand" "")))
11999 (match_operand:SI 4 "s_register_operand" "r"))]
12000 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12001 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
12002 && (operands_ok_ldrd_strd (operands[2], operands[4],
12003 operands[0], INTVAL (operands[1]),
12005 "strd%?\t%2, %4, [%0, %1]"
12006 [(set_attr "type" "store_8")
12007 (set_attr "predicable" "yes")])
12009 (define_insn "*thumb2_strd_base"
12010 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
12011 (match_operand:SI 1 "s_register_operand" "r"))
12012 (set (mem:SI (plus:SI (match_dup 0)
12014 (match_operand:SI 2 "s_register_operand" "r"))]
12015 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12016 && (operands_ok_ldrd_strd (operands[1], operands[2],
12017 operands[0], 0, false, false))"
12018 "strd%?\t%1, %2, [%0]"
12019 [(set_attr "type" "store_8")
12020 (set_attr "predicable" "yes")])
12022 (define_insn "*thumb2_strd_base_neg"
12023 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12025 (match_operand:SI 1 "s_register_operand" "r"))
12026 (set (mem:SI (match_dup 0))
12027 (match_operand:SI 2 "s_register_operand" "r"))]
12028 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12029 && (operands_ok_ldrd_strd (operands[1], operands[2],
12030 operands[0], -4, false, false))"
12031 "strd%?\t%1, %2, [%0, #-4]"
12032 [(set_attr "type" "store_8")
12033 (set_attr "predicable" "yes")])
12035 ;; ARMv8 CRC32 instructions.
12036 (define_insn "<crc_variant>"
12037 [(set (match_operand:SI 0 "s_register_operand" "=r")
12038 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
12039 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
12042 "<crc_variant>\\t%0, %1, %2"
12043 [(set_attr "type" "crc")
12044 (set_attr "conds" "unconditional")]
12047 ;; Load the load/store double peephole optimizations.
12048 (include "ldrdstrd.md")
12050 ;; Load the load/store multiple patterns
12051 (include "ldmstm.md")
12053 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12054 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12055 ;; The operands are validated through the load_multiple_operation
12056 ;; match_parallel predicate rather than through constraints so enable it only
12058 (define_insn "*load_multiple"
12059 [(match_parallel 0 "load_multiple_operation"
12060 [(set (match_operand:SI 2 "s_register_operand" "=rk")
12061 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12063 "TARGET_32BIT && reload_completed"
12066 arm_output_multireg_pop (operands, /*return_pc=*/false,
12067 /*cond=*/const_true_rtx,
12073 [(set_attr "predicable" "yes")]
12076 (define_expand "copysignsf3"
12077 [(match_operand:SF 0 "register_operand")
12078 (match_operand:SF 1 "register_operand")
12079 (match_operand:SF 2 "register_operand")]
12080 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12082 emit_move_insn (operands[0], operands[2]);
12083 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
12084 GEN_INT (31), GEN_INT (0),
12085 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
12090 (define_expand "copysigndf3"
12091 [(match_operand:DF 0 "register_operand")
12092 (match_operand:DF 1 "register_operand")
12093 (match_operand:DF 2 "register_operand")]
12094 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12096 rtx op0_low = gen_lowpart (SImode, operands[0]);
12097 rtx op0_high = gen_highpart (SImode, operands[0]);
12098 rtx op1_low = gen_lowpart (SImode, operands[1]);
12099 rtx op1_high = gen_highpart (SImode, operands[1]);
12100 rtx op2_high = gen_highpart (SImode, operands[2]);
12102 rtx scratch1 = gen_reg_rtx (SImode);
12103 rtx scratch2 = gen_reg_rtx (SImode);
12104 emit_move_insn (scratch1, op2_high);
12105 emit_move_insn (scratch2, op1_high);
12107 emit_insn(gen_rtx_SET(scratch1,
12108 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
12109 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
12110 emit_move_insn (op0_low, op1_low);
12111 emit_move_insn (op0_high, scratch2);
12117 ;; movmisalign patterns for HImode and SImode.
12118 (define_expand "movmisalign<mode>"
12119 [(match_operand:HSI 0 "general_operand")
12120 (match_operand:HSI 1 "general_operand")]
12123 /* This pattern is not permitted to fail during expansion: if both arguments
12124 are non-registers (e.g. memory := constant), force operand 1 into a
12126 rtx (* gen_unaligned_load)(rtx, rtx);
12127 rtx tmp_dest = operands[0];
12128 if (!s_register_operand (operands[0], <MODE>mode)
12129 && !s_register_operand (operands[1], <MODE>mode))
12130 operands[1] = force_reg (<MODE>mode, operands[1]);
12132 if (<MODE>mode == HImode)
12134 gen_unaligned_load = gen_unaligned_loadhiu;
12135 tmp_dest = gen_reg_rtx (SImode);
12138 gen_unaligned_load = gen_unaligned_loadsi;
12140 if (MEM_P (operands[1]))
12142 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
12143 if (<MODE>mode == HImode)
12144 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
12147 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
12152 (define_insn "<cdp>"
12153 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12154 (match_operand:SI 1 "immediate_operand" "n")
12155 (match_operand:SI 2 "immediate_operand" "n")
12156 (match_operand:SI 3 "immediate_operand" "n")
12157 (match_operand:SI 4 "immediate_operand" "n")
12158 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
12159 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
12161 arm_const_bounds (operands[0], 0, 16);
12162 arm_const_bounds (operands[1], 0, 16);
12163 arm_const_bounds (operands[2], 0, (1 << 5));
12164 arm_const_bounds (operands[3], 0, (1 << 5));
12165 arm_const_bounds (operands[4], 0, (1 << 5));
12166 arm_const_bounds (operands[5], 0, 8);
12167 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
12169 [(set_attr "length" "4")
12170 (set_attr "type" "coproc")])
12172 (define_insn "*ldc"
12173 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12174 (match_operand:SI 1 "immediate_operand" "n")
12175 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
12176 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
12178 arm_const_bounds (operands[0], 0, 16);
12179 arm_const_bounds (operands[1], 0, (1 << 5));
12180 return "<ldc>\\tp%c0, CR%c1, %2";
12182 [(set_attr "length" "4")
12183 (set_attr "type" "coproc")])
12185 (define_insn "*stc"
12186 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12187 (match_operand:SI 1 "immediate_operand" "n")
12188 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
12189 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
12191 arm_const_bounds (operands[0], 0, 16);
12192 arm_const_bounds (operands[1], 0, (1 << 5));
12193 return "<stc>\\tp%c0, CR%c1, %2";
12195 [(set_attr "length" "4")
12196 (set_attr "type" "coproc")])
12198 (define_expand "<ldc>"
12199 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12200 (match_operand:SI 1 "immediate_operand")
12201 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
12202 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
12204 (define_expand "<stc>"
12205 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12206 (match_operand:SI 1 "immediate_operand")
12207 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12208 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12210 (define_insn "<mcr>"
12211 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12212 (match_operand:SI 1 "immediate_operand" "n")
12213 (match_operand:SI 2 "s_register_operand" "r")
12214 (match_operand:SI 3 "immediate_operand" "n")
12215 (match_operand:SI 4 "immediate_operand" "n")
12216 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12217 (use (match_dup 2))]
12218 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12220 arm_const_bounds (operands[0], 0, 16);
12221 arm_const_bounds (operands[1], 0, 8);
12222 arm_const_bounds (operands[3], 0, (1 << 5));
12223 arm_const_bounds (operands[4], 0, (1 << 5));
12224 arm_const_bounds (operands[5], 0, 8);
12225 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12227 [(set_attr "length" "4")
12228 (set_attr "type" "coproc")])
12230 (define_insn "<mrc>"
12231 [(set (match_operand:SI 0 "s_register_operand" "=r")
12232 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12233 (match_operand:SI 2 "immediate_operand" "n")
12234 (match_operand:SI 3 "immediate_operand" "n")
12235 (match_operand:SI 4 "immediate_operand" "n")
12236 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12237 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12239 arm_const_bounds (operands[1], 0, 16);
12240 arm_const_bounds (operands[2], 0, 8);
12241 arm_const_bounds (operands[3], 0, (1 << 5));
12242 arm_const_bounds (operands[4], 0, (1 << 5));
12243 arm_const_bounds (operands[5], 0, 8);
12244 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12246 [(set_attr "length" "4")
12247 (set_attr "type" "coproc")])
12249 (define_insn "<mcrr>"
12250 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12251 (match_operand:SI 1 "immediate_operand" "n")
12252 (match_operand:DI 2 "s_register_operand" "r")
12253 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12254 (use (match_dup 2))]
12255 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12257 arm_const_bounds (operands[0], 0, 16);
12258 arm_const_bounds (operands[1], 0, 8);
12259 arm_const_bounds (operands[3], 0, (1 << 5));
12260 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12262 [(set_attr "length" "4")
12263 (set_attr "type" "coproc")])
12265 (define_insn "<mrrc>"
12266 [(set (match_operand:DI 0 "s_register_operand" "=r")
12267 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12268 (match_operand:SI 2 "immediate_operand" "n")
12269 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12270 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12272 arm_const_bounds (operands[1], 0, 16);
12273 arm_const_bounds (operands[2], 0, 8);
12274 arm_const_bounds (operands[3], 0, (1 << 5));
12275 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12277 [(set_attr "length" "4")
12278 (set_attr "type" "coproc")])
12280 (define_expand "speculation_barrier"
12281 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12284 /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
12285 have a usable barrier (and probably don't need one in practice).
12286 But to be safe if such code is run on later architectures, call a
12287 helper function in libgcc that will do the thing for the active
12289 if (!(arm_arch7 || arm_arch8))
12291 arm_emit_speculation_barrier_function ();
12297 ;; Generate a hard speculation barrier when we have not enabled speculation
12299 (define_insn "*speculation_barrier_insn"
12300 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12301 "arm_arch7 || arm_arch8"
12303 [(set_attr "type" "block")
12304 (set_attr "length" "8")]
12307 ;; Vector bits common to IWMMXT and Neon
12308 (include "vec-common.md")
12309 ;; Load the Intel Wireless Multimedia Extension patterns
12310 (include "iwmmxt.md")
12311 ;; Load the VFP co-processor patterns
12313 ;; Thumb-1 patterns
12314 (include "thumb1.md")
12315 ;; Thumb-2 patterns
12316 (include "thumb2.md")
12318 (include "neon.md")
12320 (include "crypto.md")
12321 ;; Synchronization Primitives
12322 (include "sync.md")
12323 ;; Fixed-point patterns
12324 (include "arm-fixed.md")