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 subsi3_compare 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" "I,L")))
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" "L,I")))]
871 && (INTVAL (operands[2])
872 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
874 /* For 0 and INT_MIN it is essential that we use subs, as adds will result
875 in different condition codes (like cmn rather than like cmp), so that
876 alternative comes first. Both alternatives can match for any 0x??000000
877 where except for 0 and INT_MIN it doesn't matter what we choose, and also
878 for -1 and 1 with TARGET_THUMB2, in that case prefer instruction with #1
880 if (which_alternative == 0 && operands[3] != const1_rtx)
881 return "subs%?\\t%0, %1, #%n3";
883 return "adds%?\\t%0, %1, %3";
885 [(set_attr "conds" "set")
886 (set_attr "type" "alus_sreg")]
889 ;; Convert the sequence
891 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
895 ;; bcs dest ((unsigned)rn >= 1)
896 ;; similarly for the beq variant using bcc.
897 ;; This is a common looping idiom (while (n--))
899 [(set (match_operand:SI 0 "arm_general_register_operand" "")
900 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
902 (set (match_operand 2 "cc_register" "")
903 (compare (match_dup 0) (const_int -1)))
905 (if_then_else (match_operator 3 "equality_operator"
906 [(match_dup 2) (const_int 0)])
907 (match_operand 4 "" "")
908 (match_operand 5 "" "")))]
909 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
913 (match_dup 1) (const_int 1)))
914 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
916 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
919 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
920 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
923 operands[2], const0_rtx);"
926 ;; The next four insns work because they compare the result with one of
927 ;; the operands, and we know that the use of the condition code is
928 ;; either GEU or LTU, so we can use the carry flag from the addition
929 ;; instead of doing the compare a second time.
930 (define_insn "*addsi3_compare_op1"
931 [(set (reg:CC_C CC_REGNUM)
933 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
934 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
936 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
937 (plus:SI (match_dup 1) (match_dup 2)))]
941 subs%?\\t%0, %1, #%n2
943 [(set_attr "conds" "set")
944 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
947 (define_insn "*addsi3_compare_op2"
948 [(set (reg:CC_C CC_REGNUM)
950 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
951 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
953 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
954 (plus:SI (match_dup 1) (match_dup 2)))]
958 subs%?\\t%0, %1, #%n2
960 [(set_attr "conds" "set")
961 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
964 (define_insn "*compare_addsi2_op0"
965 [(set (reg:CC_C CC_REGNUM)
967 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
968 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
977 [(set_attr "conds" "set")
978 (set_attr "predicable" "yes")
979 (set_attr "arch" "t2,t2,*,*,*")
980 (set_attr "predicable_short_it" "yes,yes,no,no,no")
981 (set_attr "length" "2,2,4,4,4")
982 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
985 (define_insn "*compare_addsi2_op1"
986 [(set (reg:CC_C CC_REGNUM)
988 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
989 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
998 [(set_attr "conds" "set")
999 (set_attr "predicable" "yes")
1000 (set_attr "arch" "t2,t2,*,*,*")
1001 (set_attr "predicable_short_it" "yes,yes,no,no,no")
1002 (set_attr "length" "2,2,4,4,4")
1003 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
1006 (define_insn "*addsi3_carryin_<optab>"
1007 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1008 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
1009 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
1010 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1015 sbc%?\\t%0, %1, #%B2"
1016 [(set_attr "conds" "use")
1017 (set_attr "predicable" "yes")
1018 (set_attr "arch" "t2,*,*")
1019 (set_attr "length" "4")
1020 (set_attr "predicable_short_it" "yes,no,no")
1021 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1024 (define_insn "*addsi3_carryin_alt2_<optab>"
1025 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1026 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1027 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1028 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1033 sbc%?\\t%0, %1, #%B2"
1034 [(set_attr "conds" "use")
1035 (set_attr "predicable" "yes")
1036 (set_attr "arch" "t2,*,*")
1037 (set_attr "length" "4")
1038 (set_attr "predicable_short_it" "yes,no,no")
1039 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1042 (define_insn "*addsi3_carryin_shift_<optab>"
1043 [(set (match_operand:SI 0 "s_register_operand" "=r")
1045 (match_operator:SI 2 "shift_operator"
1046 [(match_operand:SI 3 "s_register_operand" "r")
1047 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1048 (match_operand:SI 1 "s_register_operand" "r"))
1049 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1051 "adc%?\\t%0, %1, %3%S2"
1052 [(set_attr "conds" "use")
1053 (set_attr "predicable" "yes")
1054 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1055 (const_string "alu_shift_imm")
1056 (const_string "alu_shift_reg")))]
1059 (define_insn "*addsi3_carryin_clobercc_<optab>"
1060 [(set (match_operand:SI 0 "s_register_operand" "=r")
1061 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1062 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1063 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1064 (clobber (reg:CC CC_REGNUM))]
1066 "adcs%?\\t%0, %1, %2"
1067 [(set_attr "conds" "set")
1068 (set_attr "type" "adcs_reg")]
1071 (define_expand "subv<mode>4"
1072 [(match_operand:SIDI 0 "register_operand")
1073 (match_operand:SIDI 1 "register_operand")
1074 (match_operand:SIDI 2 "register_operand")
1075 (match_operand 3 "")]
1078 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1079 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1084 (define_expand "usubv<mode>4"
1085 [(match_operand:SIDI 0 "register_operand")
1086 (match_operand:SIDI 1 "register_operand")
1087 (match_operand:SIDI 2 "register_operand")
1088 (match_operand 3 "")]
1091 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1092 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1097 (define_insn_and_split "subdi3_compare1"
1098 [(set (reg:CC CC_REGNUM)
1100 (match_operand:DI 1 "register_operand" "r")
1101 (match_operand:DI 2 "register_operand" "r")))
1102 (set (match_operand:DI 0 "register_operand" "=&r")
1103 (minus:DI (match_dup 1) (match_dup 2)))]
1106 "&& reload_completed"
1107 [(parallel [(set (reg:CC CC_REGNUM)
1108 (compare:CC (match_dup 1) (match_dup 2)))
1109 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1110 (parallel [(set (reg:CC CC_REGNUM)
1111 (compare:CC (match_dup 4) (match_dup 5)))
1112 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1113 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1115 operands[3] = gen_highpart (SImode, operands[0]);
1116 operands[0] = gen_lowpart (SImode, operands[0]);
1117 operands[4] = gen_highpart (SImode, operands[1]);
1118 operands[1] = gen_lowpart (SImode, operands[1]);
1119 operands[5] = gen_highpart (SImode, operands[2]);
1120 operands[2] = gen_lowpart (SImode, operands[2]);
1122 [(set_attr "conds" "set")
1123 (set_attr "length" "8")
1124 (set_attr "type" "multiple")]
1127 (define_insn "subsi3_compare1"
1128 [(set (reg:CC CC_REGNUM)
1130 (match_operand:SI 1 "register_operand" "r")
1131 (match_operand:SI 2 "register_operand" "r")))
1132 (set (match_operand:SI 0 "register_operand" "=r")
1133 (minus:SI (match_dup 1) (match_dup 2)))]
1135 "subs%?\\t%0, %1, %2"
1136 [(set_attr "conds" "set")
1137 (set_attr "type" "alus_sreg")]
1140 (define_insn "*subsi3_carryin"
1141 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1142 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1143 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1144 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1149 sbc%?\\t%0, %2, %2, lsl #1"
1150 [(set_attr "conds" "use")
1151 (set_attr "arch" "*,a,t2")
1152 (set_attr "predicable" "yes")
1153 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1156 (define_insn "*subsi3_carryin_const"
1157 [(set (match_operand:SI 0 "s_register_operand" "=r")
1158 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1159 (match_operand:SI 2 "arm_neg_immediate_operand" "L"))
1160 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1162 "sbc\\t%0, %1, #%n2"
1163 [(set_attr "conds" "use")
1164 (set_attr "type" "adc_imm")]
1167 (define_insn "*subsi3_carryin_const0"
1168 [(set (match_operand:SI 0 "s_register_operand" "=r")
1169 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
1170 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1173 [(set_attr "conds" "use")
1174 (set_attr "type" "adc_imm")]
1177 (define_insn "*subsi3_carryin_compare"
1178 [(set (reg:CC CC_REGNUM)
1179 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1180 (match_operand:SI 2 "s_register_operand" "r")))
1181 (set (match_operand:SI 0 "s_register_operand" "=r")
1182 (minus:SI (minus:SI (match_dup 1)
1184 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1187 [(set_attr "conds" "set")
1188 (set_attr "type" "adcs_reg")]
1191 (define_insn "*subsi3_carryin_compare_const"
1192 [(set (reg:CC CC_REGNUM)
1193 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1194 (match_operand:SI 2 "const_int_I_operand" "I")))
1195 (set (match_operand:SI 0 "s_register_operand" "=r")
1196 (minus:SI (plus:SI (match_dup 1)
1197 (match_operand:SI 3 "arm_neg_immediate_operand" "L"))
1198 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1200 && (INTVAL (operands[2])
1201 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
1202 "sbcs\\t%0, %1, #%n3"
1203 [(set_attr "conds" "set")
1204 (set_attr "type" "adcs_imm")]
1207 (define_insn "*subsi3_carryin_compare_const0"
1208 [(set (reg:CC CC_REGNUM)
1209 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1211 (set (match_operand:SI 0 "s_register_operand" "=r")
1212 (minus:SI (match_dup 1)
1213 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1216 [(set_attr "conds" "set")
1217 (set_attr "type" "adcs_imm")]
1220 (define_insn "*subsi3_carryin_shift"
1221 [(set (match_operand:SI 0 "s_register_operand" "=r")
1223 (match_operand:SI 1 "s_register_operand" "r")
1224 (match_operator:SI 2 "shift_operator"
1225 [(match_operand:SI 3 "s_register_operand" "r")
1226 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1227 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1229 "sbc%?\\t%0, %1, %3%S2"
1230 [(set_attr "conds" "use")
1231 (set_attr "predicable" "yes")
1232 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1233 (const_string "alu_shift_imm")
1234 (const_string "alu_shift_reg")))]
1237 (define_insn "*rsbsi3_carryin_shift"
1238 [(set (match_operand:SI 0 "s_register_operand" "=r")
1240 (match_operator:SI 2 "shift_operator"
1241 [(match_operand:SI 3 "s_register_operand" "r")
1242 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1243 (match_operand:SI 1 "s_register_operand" "r"))
1244 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1246 "rsc%?\\t%0, %1, %3%S2"
1247 [(set_attr "conds" "use")
1248 (set_attr "predicable" "yes")
1249 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1250 (const_string "alu_shift_imm")
1251 (const_string "alu_shift_reg")))]
1254 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1256 [(set (match_operand:SI 0 "s_register_operand" "")
1257 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1258 (match_operand:SI 2 "s_register_operand" ""))
1260 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1262 [(set (match_dup 3) (match_dup 1))
1263 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1265 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1268 (define_expand "addsf3"
1269 [(set (match_operand:SF 0 "s_register_operand")
1270 (plus:SF (match_operand:SF 1 "s_register_operand")
1271 (match_operand:SF 2 "s_register_operand")))]
1272 "TARGET_32BIT && TARGET_HARD_FLOAT"
1276 (define_expand "adddf3"
1277 [(set (match_operand:DF 0 "s_register_operand")
1278 (plus:DF (match_operand:DF 1 "s_register_operand")
1279 (match_operand:DF 2 "s_register_operand")))]
1280 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1284 (define_expand "subdi3"
1286 [(set (match_operand:DI 0 "s_register_operand")
1287 (minus:DI (match_operand:DI 1 "s_register_operand")
1288 (match_operand:DI 2 "s_register_operand")))
1289 (clobber (reg:CC CC_REGNUM))])]
1294 if (!REG_P (operands[1]))
1295 operands[1] = force_reg (DImode, operands[1]);
1296 if (!REG_P (operands[2]))
1297 operands[2] = force_reg (DImode, operands[2]);
1302 (define_insn_and_split "*arm_subdi3"
1303 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
1304 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1305 (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1306 (clobber (reg:CC CC_REGNUM))]
1307 "TARGET_32BIT && !TARGET_NEON"
1308 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1309 "&& (!TARGET_IWMMXT || reload_completed)"
1310 [(parallel [(set (reg:CC CC_REGNUM)
1311 (compare:CC (match_dup 1) (match_dup 2)))
1312 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1313 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1314 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1316 operands[3] = gen_highpart (SImode, operands[0]);
1317 operands[0] = gen_lowpart (SImode, operands[0]);
1318 operands[4] = gen_highpart (SImode, operands[1]);
1319 operands[1] = gen_lowpart (SImode, operands[1]);
1320 operands[5] = gen_highpart (SImode, operands[2]);
1321 operands[2] = gen_lowpart (SImode, operands[2]);
1323 [(set_attr "conds" "clob")
1324 (set_attr "length" "8")
1325 (set_attr "type" "multiple")]
1328 (define_insn_and_split "*subdi_di_zesidi"
1329 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1330 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1332 (match_operand:SI 2 "s_register_operand" "r,r"))))
1333 (clobber (reg:CC CC_REGNUM))]
1335 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1336 "&& reload_completed"
1337 [(parallel [(set (reg:CC CC_REGNUM)
1338 (compare:CC (match_dup 1) (match_dup 2)))
1339 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1340 (set (match_dup 3) (minus:SI (match_dup 4)
1341 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1343 operands[3] = gen_highpart (SImode, operands[0]);
1344 operands[0] = gen_lowpart (SImode, operands[0]);
1345 operands[4] = gen_highpart (SImode, operands[1]);
1346 operands[1] = gen_lowpart (SImode, operands[1]);
1348 [(set_attr "conds" "clob")
1349 (set_attr "length" "8")
1350 (set_attr "type" "multiple")]
1353 (define_insn_and_split "*subdi_di_sesidi"
1354 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1355 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1357 (match_operand:SI 2 "s_register_operand" "r,r"))))
1358 (clobber (reg:CC CC_REGNUM))]
1360 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1361 "&& reload_completed"
1362 [(parallel [(set (reg:CC CC_REGNUM)
1363 (compare:CC (match_dup 1) (match_dup 2)))
1364 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1365 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1366 (ashiftrt:SI (match_dup 2)
1368 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1370 operands[3] = gen_highpart (SImode, operands[0]);
1371 operands[0] = gen_lowpart (SImode, operands[0]);
1372 operands[4] = gen_highpart (SImode, operands[1]);
1373 operands[1] = gen_lowpart (SImode, operands[1]);
1375 [(set_attr "conds" "clob")
1376 (set_attr "length" "8")
1377 (set_attr "type" "multiple")]
1380 (define_insn_and_split "*subdi_zesidi_di"
1381 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1382 (minus:DI (zero_extend:DI
1383 (match_operand:SI 2 "s_register_operand" "r,r"))
1384 (match_operand:DI 1 "s_register_operand" "0,r")))
1385 (clobber (reg:CC CC_REGNUM))]
1387 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1389 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1390 "&& reload_completed"
1391 [(parallel [(set (reg:CC CC_REGNUM)
1392 (compare:CC (match_dup 2) (match_dup 1)))
1393 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1394 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1395 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1397 operands[3] = gen_highpart (SImode, operands[0]);
1398 operands[0] = gen_lowpart (SImode, operands[0]);
1399 operands[4] = gen_highpart (SImode, operands[1]);
1400 operands[1] = gen_lowpart (SImode, operands[1]);
1402 [(set_attr "conds" "clob")
1403 (set_attr "length" "8")
1404 (set_attr "type" "multiple")]
1407 (define_insn_and_split "*subdi_sesidi_di"
1408 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1409 (minus:DI (sign_extend:DI
1410 (match_operand:SI 2 "s_register_operand" "r,r"))
1411 (match_operand:DI 1 "s_register_operand" "0,r")))
1412 (clobber (reg:CC CC_REGNUM))]
1414 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1416 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1417 "&& reload_completed"
1418 [(parallel [(set (reg:CC CC_REGNUM)
1419 (compare:CC (match_dup 2) (match_dup 1)))
1420 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1421 (set (match_dup 3) (minus:SI (minus:SI
1422 (ashiftrt:SI (match_dup 2)
1425 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1427 operands[3] = gen_highpart (SImode, operands[0]);
1428 operands[0] = gen_lowpart (SImode, operands[0]);
1429 operands[4] = gen_highpart (SImode, operands[1]);
1430 operands[1] = gen_lowpart (SImode, operands[1]);
1432 [(set_attr "conds" "clob")
1433 (set_attr "length" "8")
1434 (set_attr "type" "multiple")]
1437 (define_insn_and_split "*subdi_zesidi_zesidi"
1438 [(set (match_operand:DI 0 "s_register_operand" "=r")
1439 (minus:DI (zero_extend:DI
1440 (match_operand:SI 1 "s_register_operand" "r"))
1442 (match_operand:SI 2 "s_register_operand" "r"))))
1443 (clobber (reg:CC CC_REGNUM))]
1445 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1446 "&& reload_completed"
1447 [(parallel [(set (reg:CC CC_REGNUM)
1448 (compare:CC (match_dup 1) (match_dup 2)))
1449 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1450 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1451 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1453 operands[3] = gen_highpart (SImode, operands[0]);
1454 operands[0] = gen_lowpart (SImode, operands[0]);
1456 [(set_attr "conds" "clob")
1457 (set_attr "length" "8")
1458 (set_attr "type" "multiple")]
1461 (define_expand "subsi3"
1462 [(set (match_operand:SI 0 "s_register_operand")
1463 (minus:SI (match_operand:SI 1 "reg_or_int_operand")
1464 (match_operand:SI 2 "s_register_operand")))]
1467 if (CONST_INT_P (operands[1]))
1471 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1472 operands[1] = force_reg (SImode, operands[1]);
1475 arm_split_constant (MINUS, SImode, NULL_RTX,
1476 INTVAL (operands[1]), operands[0],
1478 optimize && can_create_pseudo_p ());
1482 else /* TARGET_THUMB1 */
1483 operands[1] = force_reg (SImode, operands[1]);
1488 ; ??? Check Thumb-2 split length
1489 (define_insn_and_split "*arm_subsi3_insn"
1490 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1491 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1492 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1504 "&& (CONST_INT_P (operands[1])
1505 && !const_ok_for_arm (INTVAL (operands[1])))"
1506 [(clobber (const_int 0))]
1508 arm_split_constant (MINUS, SImode, curr_insn,
1509 INTVAL (operands[1]), operands[0], operands[2], 0);
1512 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1513 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1514 (set_attr "predicable" "yes")
1515 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1516 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1520 [(match_scratch:SI 3 "r")
1521 (set (match_operand:SI 0 "arm_general_register_operand" "")
1522 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1523 (match_operand:SI 2 "arm_general_register_operand" "")))]
1525 && !const_ok_for_arm (INTVAL (operands[1]))
1526 && const_ok_for_arm (~INTVAL (operands[1]))"
1527 [(set (match_dup 3) (match_dup 1))
1528 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1532 (define_insn "subsi3_compare0"
1533 [(set (reg:CC_NOOV CC_REGNUM)
1535 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1536 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1538 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1539 (minus:SI (match_dup 1) (match_dup 2)))]
1544 rsbs%?\\t%0, %2, %1"
1545 [(set_attr "conds" "set")
1546 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1549 (define_insn "subsi3_compare"
1550 [(set (reg:CC CC_REGNUM)
1551 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1552 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1553 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1554 (minus:SI (match_dup 1) (match_dup 2)))]
1559 rsbs%?\\t%0, %2, %1"
1560 [(set_attr "conds" "set")
1561 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1564 (define_expand "subsf3"
1565 [(set (match_operand:SF 0 "s_register_operand")
1566 (minus:SF (match_operand:SF 1 "s_register_operand")
1567 (match_operand:SF 2 "s_register_operand")))]
1568 "TARGET_32BIT && TARGET_HARD_FLOAT"
1572 (define_expand "subdf3"
1573 [(set (match_operand:DF 0 "s_register_operand")
1574 (minus:DF (match_operand:DF 1 "s_register_operand")
1575 (match_operand:DF 2 "s_register_operand")))]
1576 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1581 ;; Multiplication insns
1583 (define_expand "mulhi3"
1584 [(set (match_operand:HI 0 "s_register_operand")
1585 (mult:HI (match_operand:HI 1 "s_register_operand")
1586 (match_operand:HI 2 "s_register_operand")))]
1587 "TARGET_DSP_MULTIPLY"
1590 rtx result = gen_reg_rtx (SImode);
1591 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1592 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1597 (define_expand "mulsi3"
1598 [(set (match_operand:SI 0 "s_register_operand")
1599 (mult:SI (match_operand:SI 2 "s_register_operand")
1600 (match_operand:SI 1 "s_register_operand")))]
1605 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1606 (define_insn "*arm_mulsi3"
1607 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1608 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1609 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1610 "TARGET_32BIT && !arm_arch6"
1611 "mul%?\\t%0, %2, %1"
1612 [(set_attr "type" "mul")
1613 (set_attr "predicable" "yes")]
1616 (define_insn "*arm_mulsi3_v6"
1617 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1618 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1619 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1620 "TARGET_32BIT && arm_arch6"
1621 "mul%?\\t%0, %1, %2"
1622 [(set_attr "type" "mul")
1623 (set_attr "predicable" "yes")
1624 (set_attr "arch" "t2,t2,*")
1625 (set_attr "length" "4")
1626 (set_attr "predicable_short_it" "yes,yes,no")]
1629 (define_insn "*mulsi3_compare0"
1630 [(set (reg:CC_NOOV CC_REGNUM)
1631 (compare:CC_NOOV (mult:SI
1632 (match_operand:SI 2 "s_register_operand" "r,r")
1633 (match_operand:SI 1 "s_register_operand" "%0,r"))
1635 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1636 (mult:SI (match_dup 2) (match_dup 1)))]
1637 "TARGET_ARM && !arm_arch6"
1638 "muls%?\\t%0, %2, %1"
1639 [(set_attr "conds" "set")
1640 (set_attr "type" "muls")]
1643 (define_insn "*mulsi3_compare0_v6"
1644 [(set (reg:CC_NOOV CC_REGNUM)
1645 (compare:CC_NOOV (mult:SI
1646 (match_operand:SI 2 "s_register_operand" "r")
1647 (match_operand:SI 1 "s_register_operand" "r"))
1649 (set (match_operand:SI 0 "s_register_operand" "=r")
1650 (mult:SI (match_dup 2) (match_dup 1)))]
1651 "TARGET_ARM && arm_arch6 && optimize_size"
1652 "muls%?\\t%0, %2, %1"
1653 [(set_attr "conds" "set")
1654 (set_attr "type" "muls")]
1657 (define_insn "*mulsi_compare0_scratch"
1658 [(set (reg:CC_NOOV CC_REGNUM)
1659 (compare:CC_NOOV (mult:SI
1660 (match_operand:SI 2 "s_register_operand" "r,r")
1661 (match_operand:SI 1 "s_register_operand" "%0,r"))
1663 (clobber (match_scratch:SI 0 "=&r,&r"))]
1664 "TARGET_ARM && !arm_arch6"
1665 "muls%?\\t%0, %2, %1"
1666 [(set_attr "conds" "set")
1667 (set_attr "type" "muls")]
1670 (define_insn "*mulsi_compare0_scratch_v6"
1671 [(set (reg:CC_NOOV CC_REGNUM)
1672 (compare:CC_NOOV (mult:SI
1673 (match_operand:SI 2 "s_register_operand" "r")
1674 (match_operand:SI 1 "s_register_operand" "r"))
1676 (clobber (match_scratch:SI 0 "=r"))]
1677 "TARGET_ARM && arm_arch6 && optimize_size"
1678 "muls%?\\t%0, %2, %1"
1679 [(set_attr "conds" "set")
1680 (set_attr "type" "muls")]
1683 ;; Unnamed templates to match MLA instruction.
1685 (define_insn "*mulsi3addsi"
1686 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1688 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1689 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1690 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1691 "TARGET_32BIT && !arm_arch6"
1692 "mla%?\\t%0, %2, %1, %3"
1693 [(set_attr "type" "mla")
1694 (set_attr "predicable" "yes")]
1697 (define_insn "*mulsi3addsi_v6"
1698 [(set (match_operand:SI 0 "s_register_operand" "=r")
1700 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1701 (match_operand:SI 1 "s_register_operand" "r"))
1702 (match_operand:SI 3 "s_register_operand" "r")))]
1703 "TARGET_32BIT && arm_arch6"
1704 "mla%?\\t%0, %2, %1, %3"
1705 [(set_attr "type" "mla")
1706 (set_attr "predicable" "yes")]
1709 (define_insn "*mulsi3addsi_compare0"
1710 [(set (reg:CC_NOOV CC_REGNUM)
1713 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1714 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1715 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1717 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1718 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1720 "TARGET_ARM && arm_arch6"
1721 "mlas%?\\t%0, %2, %1, %3"
1722 [(set_attr "conds" "set")
1723 (set_attr "type" "mlas")]
1726 (define_insn "*mulsi3addsi_compare0_v6"
1727 [(set (reg:CC_NOOV CC_REGNUM)
1730 (match_operand:SI 2 "s_register_operand" "r")
1731 (match_operand:SI 1 "s_register_operand" "r"))
1732 (match_operand:SI 3 "s_register_operand" "r"))
1734 (set (match_operand:SI 0 "s_register_operand" "=r")
1735 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1737 "TARGET_ARM && arm_arch6 && optimize_size"
1738 "mlas%?\\t%0, %2, %1, %3"
1739 [(set_attr "conds" "set")
1740 (set_attr "type" "mlas")]
1743 (define_insn "*mulsi3addsi_compare0_scratch"
1744 [(set (reg:CC_NOOV CC_REGNUM)
1747 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1748 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1749 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1751 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1752 "TARGET_ARM && !arm_arch6"
1753 "mlas%?\\t%0, %2, %1, %3"
1754 [(set_attr "conds" "set")
1755 (set_attr "type" "mlas")]
1758 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1759 [(set (reg:CC_NOOV CC_REGNUM)
1762 (match_operand:SI 2 "s_register_operand" "r")
1763 (match_operand:SI 1 "s_register_operand" "r"))
1764 (match_operand:SI 3 "s_register_operand" "r"))
1766 (clobber (match_scratch:SI 0 "=r"))]
1767 "TARGET_ARM && arm_arch6 && optimize_size"
1768 "mlas%?\\t%0, %2, %1, %3"
1769 [(set_attr "conds" "set")
1770 (set_attr "type" "mlas")]
1773 (define_insn "*mulsi3subsi"
1774 [(set (match_operand:SI 0 "s_register_operand" "=r")
1776 (match_operand:SI 3 "s_register_operand" "r")
1777 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1778 (match_operand:SI 1 "s_register_operand" "r"))))]
1779 "TARGET_32BIT && arm_arch_thumb2"
1780 "mls%?\\t%0, %2, %1, %3"
1781 [(set_attr "type" "mla")
1782 (set_attr "predicable" "yes")]
1785 (define_expand "maddsidi4"
1786 [(set (match_operand:DI 0 "s_register_operand")
1789 (sign_extend:DI (match_operand:SI 1 "s_register_operand"))
1790 (sign_extend:DI (match_operand:SI 2 "s_register_operand")))
1791 (match_operand:DI 3 "s_register_operand")))]
1795 (define_insn "*mulsidi3adddi"
1796 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1799 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1800 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1801 (match_operand:DI 1 "s_register_operand" "0")))]
1802 "TARGET_32BIT && !arm_arch6"
1803 "smlal%?\\t%Q0, %R0, %3, %2"
1804 [(set_attr "type" "smlal")
1805 (set_attr "predicable" "yes")]
1808 (define_insn "*mulsidi3adddi_v6"
1809 [(set (match_operand:DI 0 "s_register_operand" "=r")
1812 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1813 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1814 (match_operand:DI 1 "s_register_operand" "0")))]
1815 "TARGET_32BIT && arm_arch6"
1816 "smlal%?\\t%Q0, %R0, %3, %2"
1817 [(set_attr "type" "smlal")
1818 (set_attr "predicable" "yes")]
1821 ;; 32x32->64 widening multiply.
1822 ;; As with mulsi3, the only difference between the v3-5 and v6+
1823 ;; versions of these patterns is the requirement that the output not
1824 ;; overlap the inputs, but that still means we have to have a named
1825 ;; expander and two different starred insns.
1827 (define_expand "mulsidi3"
1828 [(set (match_operand:DI 0 "s_register_operand")
1830 (sign_extend:DI (match_operand:SI 1 "s_register_operand"))
1831 (sign_extend:DI (match_operand:SI 2 "s_register_operand"))))]
1836 (define_insn "*mulsidi3_nov6"
1837 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1839 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1840 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1841 "TARGET_32BIT && !arm_arch6"
1842 "smull%?\\t%Q0, %R0, %1, %2"
1843 [(set_attr "type" "smull")
1844 (set_attr "predicable" "yes")]
1847 (define_insn "*mulsidi3_v6"
1848 [(set (match_operand:DI 0 "s_register_operand" "=r")
1850 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1851 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1852 "TARGET_32BIT && arm_arch6"
1853 "smull%?\\t%Q0, %R0, %1, %2"
1854 [(set_attr "type" "smull")
1855 (set_attr "predicable" "yes")]
1858 (define_expand "umulsidi3"
1859 [(set (match_operand:DI 0 "s_register_operand")
1861 (zero_extend:DI (match_operand:SI 1 "s_register_operand"))
1862 (zero_extend:DI (match_operand:SI 2 "s_register_operand"))))]
1867 (define_insn "*umulsidi3_nov6"
1868 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1870 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1871 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1872 "TARGET_32BIT && !arm_arch6"
1873 "umull%?\\t%Q0, %R0, %1, %2"
1874 [(set_attr "type" "umull")
1875 (set_attr "predicable" "yes")]
1878 (define_insn "*umulsidi3_v6"
1879 [(set (match_operand:DI 0 "s_register_operand" "=r")
1881 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1882 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1883 "TARGET_32BIT && arm_arch6"
1884 "umull%?\\t%Q0, %R0, %1, %2"
1885 [(set_attr "type" "umull")
1886 (set_attr "predicable" "yes")]
1889 (define_expand "umaddsidi4"
1890 [(set (match_operand:DI 0 "s_register_operand")
1893 (zero_extend:DI (match_operand:SI 1 "s_register_operand"))
1894 (zero_extend:DI (match_operand:SI 2 "s_register_operand")))
1895 (match_operand:DI 3 "s_register_operand")))]
1899 (define_insn "*umulsidi3adddi"
1900 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1903 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1904 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1905 (match_operand:DI 1 "s_register_operand" "0")))]
1906 "TARGET_32BIT && !arm_arch6"
1907 "umlal%?\\t%Q0, %R0, %3, %2"
1908 [(set_attr "type" "umlal")
1909 (set_attr "predicable" "yes")]
1912 (define_insn "*umulsidi3adddi_v6"
1913 [(set (match_operand:DI 0 "s_register_operand" "=r")
1916 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1917 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1918 (match_operand:DI 1 "s_register_operand" "0")))]
1919 "TARGET_32BIT && arm_arch6"
1920 "umlal%?\\t%Q0, %R0, %3, %2"
1921 [(set_attr "type" "umlal")
1922 (set_attr "predicable" "yes")]
1925 (define_expand "smulsi3_highpart"
1927 [(set (match_operand:SI 0 "s_register_operand")
1931 (sign_extend:DI (match_operand:SI 1 "s_register_operand"))
1932 (sign_extend:DI (match_operand:SI 2 "s_register_operand")))
1934 (clobber (match_scratch:SI 3 ""))])]
1939 (define_insn "*smulsi3_highpart_nov6"
1940 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1944 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1945 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1947 (clobber (match_scratch:SI 3 "=&r,&r"))]
1948 "TARGET_32BIT && !arm_arch6"
1949 "smull%?\\t%3, %0, %2, %1"
1950 [(set_attr "type" "smull")
1951 (set_attr "predicable" "yes")]
1954 (define_insn "*smulsi3_highpart_v6"
1955 [(set (match_operand:SI 0 "s_register_operand" "=r")
1959 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1960 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1962 (clobber (match_scratch:SI 3 "=r"))]
1963 "TARGET_32BIT && arm_arch6"
1964 "smull%?\\t%3, %0, %2, %1"
1965 [(set_attr "type" "smull")
1966 (set_attr "predicable" "yes")]
1969 (define_expand "umulsi3_highpart"
1971 [(set (match_operand:SI 0 "s_register_operand")
1975 (zero_extend:DI (match_operand:SI 1 "s_register_operand"))
1976 (zero_extend:DI (match_operand:SI 2 "s_register_operand")))
1978 (clobber (match_scratch:SI 3 ""))])]
1983 (define_insn "*umulsi3_highpart_nov6"
1984 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1988 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1989 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1991 (clobber (match_scratch:SI 3 "=&r,&r"))]
1992 "TARGET_32BIT && !arm_arch6"
1993 "umull%?\\t%3, %0, %2, %1"
1994 [(set_attr "type" "umull")
1995 (set_attr "predicable" "yes")]
1998 (define_insn "*umulsi3_highpart_v6"
1999 [(set (match_operand:SI 0 "s_register_operand" "=r")
2003 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
2004 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
2006 (clobber (match_scratch:SI 3 "=r"))]
2007 "TARGET_32BIT && arm_arch6"
2008 "umull%?\\t%3, %0, %2, %1"
2009 [(set_attr "type" "umull")
2010 (set_attr "predicable" "yes")]
2013 (define_insn "mulhisi3"
2014 [(set (match_operand:SI 0 "s_register_operand" "=r")
2015 (mult:SI (sign_extend:SI
2016 (match_operand:HI 1 "s_register_operand" "%r"))
2018 (match_operand:HI 2 "s_register_operand" "r"))))]
2019 "TARGET_DSP_MULTIPLY"
2020 "smulbb%?\\t%0, %1, %2"
2021 [(set_attr "type" "smulxy")
2022 (set_attr "predicable" "yes")]
2025 (define_insn "*mulhisi3tb"
2026 [(set (match_operand:SI 0 "s_register_operand" "=r")
2027 (mult:SI (ashiftrt:SI
2028 (match_operand:SI 1 "s_register_operand" "r")
2031 (match_operand:HI 2 "s_register_operand" "r"))))]
2032 "TARGET_DSP_MULTIPLY"
2033 "smultb%?\\t%0, %1, %2"
2034 [(set_attr "type" "smulxy")
2035 (set_attr "predicable" "yes")]
2038 (define_insn "*mulhisi3bt"
2039 [(set (match_operand:SI 0 "s_register_operand" "=r")
2040 (mult:SI (sign_extend:SI
2041 (match_operand:HI 1 "s_register_operand" "r"))
2043 (match_operand:SI 2 "s_register_operand" "r")
2045 "TARGET_DSP_MULTIPLY"
2046 "smulbt%?\\t%0, %1, %2"
2047 [(set_attr "type" "smulxy")
2048 (set_attr "predicable" "yes")]
2051 (define_insn "*mulhisi3tt"
2052 [(set (match_operand:SI 0 "s_register_operand" "=r")
2053 (mult:SI (ashiftrt:SI
2054 (match_operand:SI 1 "s_register_operand" "r")
2057 (match_operand:SI 2 "s_register_operand" "r")
2059 "TARGET_DSP_MULTIPLY"
2060 "smultt%?\\t%0, %1, %2"
2061 [(set_attr "type" "smulxy")
2062 (set_attr "predicable" "yes")]
2065 (define_insn "maddhisi4"
2066 [(set (match_operand:SI 0 "s_register_operand" "=r")
2067 (plus:SI (mult:SI (sign_extend:SI
2068 (match_operand:HI 1 "s_register_operand" "r"))
2070 (match_operand:HI 2 "s_register_operand" "r")))
2071 (match_operand:SI 3 "s_register_operand" "r")))]
2072 "TARGET_DSP_MULTIPLY"
2073 "smlabb%?\\t%0, %1, %2, %3"
2074 [(set_attr "type" "smlaxy")
2075 (set_attr "predicable" "yes")]
2078 ;; Note: there is no maddhisi4ibt because this one is canonical form
2079 (define_insn "*maddhisi4tb"
2080 [(set (match_operand:SI 0 "s_register_operand" "=r")
2081 (plus:SI (mult:SI (ashiftrt:SI
2082 (match_operand:SI 1 "s_register_operand" "r")
2085 (match_operand:HI 2 "s_register_operand" "r")))
2086 (match_operand:SI 3 "s_register_operand" "r")))]
2087 "TARGET_DSP_MULTIPLY"
2088 "smlatb%?\\t%0, %1, %2, %3"
2089 [(set_attr "type" "smlaxy")
2090 (set_attr "predicable" "yes")]
2093 (define_insn "*maddhisi4tt"
2094 [(set (match_operand:SI 0 "s_register_operand" "=r")
2095 (plus:SI (mult:SI (ashiftrt:SI
2096 (match_operand:SI 1 "s_register_operand" "r")
2099 (match_operand:SI 2 "s_register_operand" "r")
2101 (match_operand:SI 3 "s_register_operand" "r")))]
2102 "TARGET_DSP_MULTIPLY"
2103 "smlatt%?\\t%0, %1, %2, %3"
2104 [(set_attr "type" "smlaxy")
2105 (set_attr "predicable" "yes")]
2108 (define_insn "maddhidi4"
2109 [(set (match_operand:DI 0 "s_register_operand" "=r")
2111 (mult:DI (sign_extend:DI
2112 (match_operand:HI 1 "s_register_operand" "r"))
2114 (match_operand:HI 2 "s_register_operand" "r")))
2115 (match_operand:DI 3 "s_register_operand" "0")))]
2116 "TARGET_DSP_MULTIPLY"
2117 "smlalbb%?\\t%Q0, %R0, %1, %2"
2118 [(set_attr "type" "smlalxy")
2119 (set_attr "predicable" "yes")])
2121 ;; Note: there is no maddhidi4ibt because this one is canonical form
2122 (define_insn "*maddhidi4tb"
2123 [(set (match_operand:DI 0 "s_register_operand" "=r")
2125 (mult:DI (sign_extend:DI
2127 (match_operand:SI 1 "s_register_operand" "r")
2130 (match_operand:HI 2 "s_register_operand" "r")))
2131 (match_operand:DI 3 "s_register_operand" "0")))]
2132 "TARGET_DSP_MULTIPLY"
2133 "smlaltb%?\\t%Q0, %R0, %1, %2"
2134 [(set_attr "type" "smlalxy")
2135 (set_attr "predicable" "yes")])
2137 (define_insn "*maddhidi4tt"
2138 [(set (match_operand:DI 0 "s_register_operand" "=r")
2140 (mult:DI (sign_extend:DI
2142 (match_operand:SI 1 "s_register_operand" "r")
2146 (match_operand:SI 2 "s_register_operand" "r")
2148 (match_operand:DI 3 "s_register_operand" "0")))]
2149 "TARGET_DSP_MULTIPLY"
2150 "smlaltt%?\\t%Q0, %R0, %1, %2"
2151 [(set_attr "type" "smlalxy")
2152 (set_attr "predicable" "yes")])
2154 (define_expand "mulsf3"
2155 [(set (match_operand:SF 0 "s_register_operand")
2156 (mult:SF (match_operand:SF 1 "s_register_operand")
2157 (match_operand:SF 2 "s_register_operand")))]
2158 "TARGET_32BIT && TARGET_HARD_FLOAT"
2162 (define_expand "muldf3"
2163 [(set (match_operand:DF 0 "s_register_operand")
2164 (mult:DF (match_operand:DF 1 "s_register_operand")
2165 (match_operand:DF 2 "s_register_operand")))]
2166 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2172 (define_expand "divsf3"
2173 [(set (match_operand:SF 0 "s_register_operand")
2174 (div:SF (match_operand:SF 1 "s_register_operand")
2175 (match_operand:SF 2 "s_register_operand")))]
2176 "TARGET_32BIT && TARGET_HARD_FLOAT"
2179 (define_expand "divdf3"
2180 [(set (match_operand:DF 0 "s_register_operand")
2181 (div:DF (match_operand:DF 1 "s_register_operand")
2182 (match_operand:DF 2 "s_register_operand")))]
2183 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2186 ;; Boolean and,ior,xor insns
2188 ;; Split up double word logical operations
2190 ;; Split up simple DImode logical operations. Simply perform the logical
2191 ;; operation on the upper and lower halves of the registers.
2193 [(set (match_operand:DI 0 "s_register_operand" "")
2194 (match_operator:DI 6 "logical_binary_operator"
2195 [(match_operand:DI 1 "s_register_operand" "")
2196 (match_operand:DI 2 "s_register_operand" "")]))]
2197 "TARGET_32BIT && reload_completed
2198 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2199 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2200 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2201 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2204 operands[3] = gen_highpart (SImode, operands[0]);
2205 operands[0] = gen_lowpart (SImode, operands[0]);
2206 operands[4] = gen_highpart (SImode, operands[1]);
2207 operands[1] = gen_lowpart (SImode, operands[1]);
2208 operands[5] = gen_highpart (SImode, operands[2]);
2209 operands[2] = gen_lowpart (SImode, operands[2]);
2214 [(set (match_operand:DI 0 "s_register_operand" "")
2215 (match_operator:DI 6 "logical_binary_operator"
2216 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2217 (match_operand:DI 1 "s_register_operand" "")]))]
2218 "TARGET_32BIT && reload_completed"
2219 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2220 (set (match_dup 3) (match_op_dup:SI 6
2221 [(ashiftrt:SI (match_dup 2) (const_int 31))
2225 operands[3] = gen_highpart (SImode, operands[0]);
2226 operands[0] = gen_lowpart (SImode, operands[0]);
2227 operands[4] = gen_highpart (SImode, operands[1]);
2228 operands[1] = gen_lowpart (SImode, operands[1]);
2229 operands[5] = gen_highpart (SImode, operands[2]);
2230 operands[2] = gen_lowpart (SImode, operands[2]);
2234 ;; The zero extend of operand 2 means we can just copy the high part of
2235 ;; operand1 into operand0.
2237 [(set (match_operand:DI 0 "s_register_operand" "")
2239 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2240 (match_operand:DI 1 "s_register_operand" "")))]
2241 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2242 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2243 (set (match_dup 3) (match_dup 4))]
2246 operands[4] = gen_highpart (SImode, operands[1]);
2247 operands[3] = gen_highpart (SImode, operands[0]);
2248 operands[0] = gen_lowpart (SImode, operands[0]);
2249 operands[1] = gen_lowpart (SImode, operands[1]);
2253 ;; The zero extend of operand 2 means we can just copy the high part of
2254 ;; operand1 into operand0.
2256 [(set (match_operand:DI 0 "s_register_operand" "")
2258 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2259 (match_operand:DI 1 "s_register_operand" "")))]
2260 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2261 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2262 (set (match_dup 3) (match_dup 4))]
2265 operands[4] = gen_highpart (SImode, operands[1]);
2266 operands[3] = gen_highpart (SImode, operands[0]);
2267 operands[0] = gen_lowpart (SImode, operands[0]);
2268 operands[1] = gen_lowpart (SImode, operands[1]);
2272 (define_expand "anddi3"
2273 [(set (match_operand:DI 0 "s_register_operand")
2274 (and:DI (match_operand:DI 1 "s_register_operand")
2275 (match_operand:DI 2 "neon_inv_logic_op2")))]
2278 if (!TARGET_NEON && !TARGET_IWMMXT)
2280 rtx low = simplify_gen_binary (AND, SImode,
2281 gen_lowpart (SImode, operands[1]),
2282 gen_lowpart (SImode, operands[2]));
2283 rtx high = simplify_gen_binary (AND, SImode,
2284 gen_highpart (SImode, operands[1]),
2285 gen_highpart_mode (SImode, DImode,
2288 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2289 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2293 /* Otherwise expand pattern as above. */
2297 (define_insn_and_split "*anddi3_insn"
2298 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2299 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2300 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2301 "TARGET_32BIT && !TARGET_IWMMXT"
2303 switch (which_alternative)
2305 case 0: /* fall through */
2306 case 6: return "vand\t%P0, %P1, %P2";
2307 case 1: /* fall through */
2308 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2309 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2313 case 5: /* fall through */
2315 default: gcc_unreachable ();
2318 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2319 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2320 [(set (match_dup 3) (match_dup 4))
2321 (set (match_dup 5) (match_dup 6))]
2324 operands[3] = gen_lowpart (SImode, operands[0]);
2325 operands[5] = gen_highpart (SImode, operands[0]);
2327 operands[4] = simplify_gen_binary (AND, SImode,
2328 gen_lowpart (SImode, operands[1]),
2329 gen_lowpart (SImode, operands[2]));
2330 operands[6] = simplify_gen_binary (AND, SImode,
2331 gen_highpart (SImode, operands[1]),
2332 gen_highpart_mode (SImode, DImode, operands[2]));
2335 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2336 multiple,multiple,neon_logic,neon_logic")
2337 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2338 avoid_neon_for_64bits,avoid_neon_for_64bits")
2339 (set_attr "length" "*,*,8,8,8,8,*,*")
2343 (define_insn_and_split "*anddi_zesidi_di"
2344 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2345 (and:DI (zero_extend:DI
2346 (match_operand:SI 2 "s_register_operand" "r,r"))
2347 (match_operand:DI 1 "s_register_operand" "0,r")))]
2350 "TARGET_32BIT && reload_completed"
2351 ; The zero extend of operand 2 clears the high word of the output
2353 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2354 (set (match_dup 3) (const_int 0))]
2357 operands[3] = gen_highpart (SImode, operands[0]);
2358 operands[0] = gen_lowpart (SImode, operands[0]);
2359 operands[1] = gen_lowpart (SImode, operands[1]);
2361 [(set_attr "length" "8")
2362 (set_attr "type" "multiple")]
2365 (define_insn "*anddi_sesdi_di"
2366 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2367 (and:DI (sign_extend:DI
2368 (match_operand:SI 2 "s_register_operand" "r,r"))
2369 (match_operand:DI 1 "s_register_operand" "0,r")))]
2372 [(set_attr "length" "8")
2373 (set_attr "type" "multiple")]
2376 (define_expand "andsi3"
2377 [(set (match_operand:SI 0 "s_register_operand")
2378 (and:SI (match_operand:SI 1 "s_register_operand")
2379 (match_operand:SI 2 "reg_or_int_operand")))]
2384 if (CONST_INT_P (operands[2]))
2386 if (INTVAL (operands[2]) == 255 && arm_arch6)
2388 operands[1] = convert_to_mode (QImode, operands[1], 1);
2389 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2393 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2394 operands[2] = force_reg (SImode, operands[2]);
2397 arm_split_constant (AND, SImode, NULL_RTX,
2398 INTVAL (operands[2]), operands[0],
2400 optimize && can_create_pseudo_p ());
2406 else /* TARGET_THUMB1 */
2408 if (!CONST_INT_P (operands[2]))
2410 rtx tmp = force_reg (SImode, operands[2]);
2411 if (rtx_equal_p (operands[0], operands[1]))
2415 operands[2] = operands[1];
2423 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2425 operands[2] = force_reg (SImode,
2426 GEN_INT (~INTVAL (operands[2])));
2428 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2433 for (i = 9; i <= 31; i++)
2435 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2437 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2441 else if ((HOST_WIDE_INT_1 << i) - 1
2442 == ~INTVAL (operands[2]))
2444 rtx shift = GEN_INT (i);
2445 rtx reg = gen_reg_rtx (SImode);
2447 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2448 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2454 operands[2] = force_reg (SImode, operands[2]);
2460 ; ??? Check split length for Thumb-2
2461 (define_insn_and_split "*arm_andsi3_insn"
2462 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2463 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2464 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2469 bic%?\\t%0, %1, #%B2
2473 && CONST_INT_P (operands[2])
2474 && !(const_ok_for_arm (INTVAL (operands[2]))
2475 || const_ok_for_arm (~INTVAL (operands[2])))"
2476 [(clobber (const_int 0))]
2478 arm_split_constant (AND, SImode, curr_insn,
2479 INTVAL (operands[2]), operands[0], operands[1], 0);
2482 [(set_attr "length" "4,4,4,4,16")
2483 (set_attr "predicable" "yes")
2484 (set_attr "predicable_short_it" "no,yes,no,no,no")
2485 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2488 (define_insn "*andsi3_compare0"
2489 [(set (reg:CC_NOOV CC_REGNUM)
2491 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2492 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2494 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2495 (and:SI (match_dup 1) (match_dup 2)))]
2499 bics%?\\t%0, %1, #%B2
2500 ands%?\\t%0, %1, %2"
2501 [(set_attr "conds" "set")
2502 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2505 (define_insn "*andsi3_compare0_scratch"
2506 [(set (reg:CC_NOOV CC_REGNUM)
2508 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2509 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2511 (clobber (match_scratch:SI 2 "=X,r,X"))]
2515 bics%?\\t%2, %0, #%B1
2517 [(set_attr "conds" "set")
2518 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2521 (define_insn "*zeroextractsi_compare0_scratch"
2522 [(set (reg:CC_NOOV CC_REGNUM)
2523 (compare:CC_NOOV (zero_extract:SI
2524 (match_operand:SI 0 "s_register_operand" "r")
2525 (match_operand 1 "const_int_operand" "n")
2526 (match_operand 2 "const_int_operand" "n"))
2529 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2530 && INTVAL (operands[1]) > 0
2531 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2532 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2534 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2535 << INTVAL (operands[2]));
2536 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2539 [(set_attr "conds" "set")
2540 (set_attr "predicable" "yes")
2541 (set_attr "type" "logics_imm")]
2544 (define_insn_and_split "*ne_zeroextractsi"
2545 [(set (match_operand:SI 0 "s_register_operand" "=r")
2546 (ne:SI (zero_extract:SI
2547 (match_operand:SI 1 "s_register_operand" "r")
2548 (match_operand:SI 2 "const_int_operand" "n")
2549 (match_operand:SI 3 "const_int_operand" "n"))
2551 (clobber (reg:CC CC_REGNUM))]
2553 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2554 && INTVAL (operands[2]) > 0
2555 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2556 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2559 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2560 && INTVAL (operands[2]) > 0
2561 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2562 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2563 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2564 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2566 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2568 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2569 (match_dup 0) (const_int 1)))]
2571 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2572 << INTVAL (operands[3]));
2574 [(set_attr "conds" "clob")
2575 (set (attr "length")
2576 (if_then_else (eq_attr "is_thumb" "yes")
2579 (set_attr "type" "multiple")]
2582 (define_insn_and_split "*ne_zeroextractsi_shifted"
2583 [(set (match_operand:SI 0 "s_register_operand" "=r")
2584 (ne:SI (zero_extract:SI
2585 (match_operand:SI 1 "s_register_operand" "r")
2586 (match_operand:SI 2 "const_int_operand" "n")
2589 (clobber (reg:CC CC_REGNUM))]
2593 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2594 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2596 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2598 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2599 (match_dup 0) (const_int 1)))]
2601 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2603 [(set_attr "conds" "clob")
2604 (set_attr "length" "8")
2605 (set_attr "type" "multiple")]
2608 (define_insn_and_split "*ite_ne_zeroextractsi"
2609 [(set (match_operand:SI 0 "s_register_operand" "=r")
2610 (if_then_else:SI (ne (zero_extract:SI
2611 (match_operand:SI 1 "s_register_operand" "r")
2612 (match_operand:SI 2 "const_int_operand" "n")
2613 (match_operand:SI 3 "const_int_operand" "n"))
2615 (match_operand:SI 4 "arm_not_operand" "rIK")
2617 (clobber (reg:CC CC_REGNUM))]
2619 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2620 && INTVAL (operands[2]) > 0
2621 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2622 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2623 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2626 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2627 && INTVAL (operands[2]) > 0
2628 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2629 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2630 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2631 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2632 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2634 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2636 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2637 (match_dup 0) (match_dup 4)))]
2639 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2640 << INTVAL (operands[3]));
2642 [(set_attr "conds" "clob")
2643 (set_attr "length" "8")
2644 (set_attr "type" "multiple")]
2647 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2648 [(set (match_operand:SI 0 "s_register_operand" "=r")
2649 (if_then_else:SI (ne (zero_extract:SI
2650 (match_operand:SI 1 "s_register_operand" "r")
2651 (match_operand:SI 2 "const_int_operand" "n")
2654 (match_operand:SI 3 "arm_not_operand" "rIK")
2656 (clobber (reg:CC CC_REGNUM))]
2657 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2659 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2660 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2661 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2663 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2665 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2666 (match_dup 0) (match_dup 3)))]
2668 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2670 [(set_attr "conds" "clob")
2671 (set_attr "length" "8")
2672 (set_attr "type" "multiple")]
2675 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2677 [(set (match_operand:SI 0 "s_register_operand" "")
2678 (match_operator:SI 1 "shiftable_operator"
2679 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2680 (match_operand:SI 3 "const_int_operand" "")
2681 (match_operand:SI 4 "const_int_operand" ""))
2682 (match_operand:SI 5 "s_register_operand" "")]))
2683 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2685 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2688 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2691 HOST_WIDE_INT temp = INTVAL (operands[3]);
2693 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2694 operands[4] = GEN_INT (32 - temp);
2699 [(set (match_operand:SI 0 "s_register_operand" "")
2700 (match_operator:SI 1 "shiftable_operator"
2701 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2702 (match_operand:SI 3 "const_int_operand" "")
2703 (match_operand:SI 4 "const_int_operand" ""))
2704 (match_operand:SI 5 "s_register_operand" "")]))
2705 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2707 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2710 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2713 HOST_WIDE_INT temp = INTVAL (operands[3]);
2715 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2716 operands[4] = GEN_INT (32 - temp);
2720 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2721 ;;; represented by the bitfield, then this will produce incorrect results.
2722 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2723 ;;; which have a real bit-field insert instruction, the truncation happens
2724 ;;; in the bit-field insert instruction itself. Since arm does not have a
2725 ;;; bit-field insert instruction, we would have to emit code here to truncate
2726 ;;; the value before we insert. This loses some of the advantage of having
2727 ;;; this insv pattern, so this pattern needs to be reevalutated.
2729 (define_expand "insv"
2730 [(set (zero_extract (match_operand 0 "nonimmediate_operand")
2731 (match_operand 1 "general_operand")
2732 (match_operand 2 "general_operand"))
2733 (match_operand 3 "reg_or_int_operand"))]
2734 "TARGET_ARM || arm_arch_thumb2"
2737 int start_bit = INTVAL (operands[2]);
2738 int width = INTVAL (operands[1]);
2739 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2740 rtx target, subtarget;
2742 if (arm_arch_thumb2)
2744 if (unaligned_access && MEM_P (operands[0])
2745 && s_register_operand (operands[3], GET_MODE (operands[3]))
2746 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2750 if (BYTES_BIG_ENDIAN)
2751 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2756 base_addr = adjust_address (operands[0], SImode,
2757 start_bit / BITS_PER_UNIT);
2758 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2762 rtx tmp = gen_reg_rtx (HImode);
2764 base_addr = adjust_address (operands[0], HImode,
2765 start_bit / BITS_PER_UNIT);
2766 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2767 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2771 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2773 bool use_bfi = TRUE;
2775 if (CONST_INT_P (operands[3]))
2777 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2781 emit_insn (gen_insv_zero (operands[0], operands[1],
2786 /* See if the set can be done with a single orr instruction. */
2787 if (val == mask && const_ok_for_arm (val << start_bit))
2793 if (!REG_P (operands[3]))
2794 operands[3] = force_reg (SImode, operands[3]);
2796 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2805 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2808 target = copy_rtx (operands[0]);
2809 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2810 subreg as the final target. */
2811 if (GET_CODE (target) == SUBREG)
2813 subtarget = gen_reg_rtx (SImode);
2814 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2815 < GET_MODE_SIZE (SImode))
2816 target = SUBREG_REG (target);
2821 if (CONST_INT_P (operands[3]))
2823 /* Since we are inserting a known constant, we may be able to
2824 reduce the number of bits that we have to clear so that
2825 the mask becomes simple. */
2826 /* ??? This code does not check to see if the new mask is actually
2827 simpler. It may not be. */
2828 rtx op1 = gen_reg_rtx (SImode);
2829 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2830 start of this pattern. */
2831 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2832 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2834 emit_insn (gen_andsi3 (op1, operands[0],
2835 gen_int_mode (~mask2, SImode)));
2836 emit_insn (gen_iorsi3 (subtarget, op1,
2837 gen_int_mode (op3_value << start_bit, SImode)));
2839 else if (start_bit == 0
2840 && !(const_ok_for_arm (mask)
2841 || const_ok_for_arm (~mask)))
2843 /* A Trick, since we are setting the bottom bits in the word,
2844 we can shift operand[3] up, operand[0] down, OR them together
2845 and rotate the result back again. This takes 3 insns, and
2846 the third might be mergeable into another op. */
2847 /* The shift up copes with the possibility that operand[3] is
2848 wider than the bitfield. */
2849 rtx op0 = gen_reg_rtx (SImode);
2850 rtx op1 = gen_reg_rtx (SImode);
2852 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2853 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2854 emit_insn (gen_iorsi3 (op1, op1, op0));
2855 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2857 else if ((width + start_bit == 32)
2858 && !(const_ok_for_arm (mask)
2859 || const_ok_for_arm (~mask)))
2861 /* Similar trick, but slightly less efficient. */
2863 rtx op0 = gen_reg_rtx (SImode);
2864 rtx op1 = gen_reg_rtx (SImode);
2866 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2867 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2868 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2869 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2873 rtx op0 = gen_int_mode (mask, SImode);
2874 rtx op1 = gen_reg_rtx (SImode);
2875 rtx op2 = gen_reg_rtx (SImode);
2877 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2879 rtx tmp = gen_reg_rtx (SImode);
2881 emit_insn (gen_movsi (tmp, op0));
2885 /* Mask out any bits in operand[3] that are not needed. */
2886 emit_insn (gen_andsi3 (op1, operands[3], op0));
2888 if (CONST_INT_P (op0)
2889 && (const_ok_for_arm (mask << start_bit)
2890 || const_ok_for_arm (~(mask << start_bit))))
2892 op0 = gen_int_mode (~(mask << start_bit), SImode);
2893 emit_insn (gen_andsi3 (op2, operands[0], op0));
2897 if (CONST_INT_P (op0))
2899 rtx tmp = gen_reg_rtx (SImode);
2901 emit_insn (gen_movsi (tmp, op0));
2906 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2908 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2912 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2914 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2917 if (subtarget != target)
2919 /* If TARGET is still a SUBREG, then it must be wider than a word,
2920 so we must be careful only to set the subword we were asked to. */
2921 if (GET_CODE (target) == SUBREG)
2922 emit_move_insn (target, subtarget);
2924 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2931 (define_insn "insv_zero"
2932 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2933 (match_operand:SI 1 "const_int_M_operand" "M")
2934 (match_operand:SI 2 "const_int_M_operand" "M"))
2938 [(set_attr "length" "4")
2939 (set_attr "predicable" "yes")
2940 (set_attr "type" "bfm")]
2943 (define_insn "insv_t2"
2944 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2945 (match_operand:SI 1 "const_int_M_operand" "M")
2946 (match_operand:SI 2 "const_int_M_operand" "M"))
2947 (match_operand:SI 3 "s_register_operand" "r"))]
2949 "bfi%?\t%0, %3, %2, %1"
2950 [(set_attr "length" "4")
2951 (set_attr "predicable" "yes")
2952 (set_attr "type" "bfm")]
2955 ; constants for op 2 will never be given to these patterns.
2956 (define_insn_and_split "*anddi_notdi_di"
2957 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2958 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2959 (match_operand:DI 2 "s_register_operand" "r,0")))]
2962 "TARGET_32BIT && reload_completed
2963 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2964 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2965 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2966 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2969 operands[3] = gen_highpart (SImode, operands[0]);
2970 operands[0] = gen_lowpart (SImode, operands[0]);
2971 operands[4] = gen_highpart (SImode, operands[1]);
2972 operands[1] = gen_lowpart (SImode, operands[1]);
2973 operands[5] = gen_highpart (SImode, operands[2]);
2974 operands[2] = gen_lowpart (SImode, operands[2]);
2976 [(set_attr "length" "8")
2977 (set_attr "predicable" "yes")
2978 (set_attr "type" "multiple")]
2981 (define_insn_and_split "*anddi_notzesidi_di"
2982 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2983 (and:DI (not:DI (zero_extend:DI
2984 (match_operand:SI 2 "s_register_operand" "r,r")))
2985 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2988 bic%?\\t%Q0, %Q1, %2
2990 ; (not (zero_extend ...)) allows us to just copy the high word from
2991 ; operand1 to operand0.
2994 && operands[0] != operands[1]"
2995 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2996 (set (match_dup 3) (match_dup 4))]
2999 operands[3] = gen_highpart (SImode, operands[0]);
3000 operands[0] = gen_lowpart (SImode, operands[0]);
3001 operands[4] = gen_highpart (SImode, operands[1]);
3002 operands[1] = gen_lowpart (SImode, operands[1]);
3004 [(set_attr "length" "4,8")
3005 (set_attr "predicable" "yes")
3006 (set_attr "type" "multiple")]
3009 (define_insn_and_split "*anddi_notdi_zesidi"
3010 [(set (match_operand:DI 0 "s_register_operand" "=r")
3011 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
3013 (match_operand:SI 1 "s_register_operand" "r"))))]
3016 "TARGET_32BIT && reload_completed"
3017 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3018 (set (match_dup 3) (const_int 0))]
3021 operands[3] = gen_highpart (SImode, operands[0]);
3022 operands[0] = gen_lowpart (SImode, operands[0]);
3023 operands[2] = gen_lowpart (SImode, operands[2]);
3025 [(set_attr "length" "8")
3026 (set_attr "predicable" "yes")
3027 (set_attr "type" "multiple")]
3030 (define_insn_and_split "*anddi_notsesidi_di"
3031 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3032 (and:DI (not:DI (sign_extend:DI
3033 (match_operand:SI 2 "s_register_operand" "r,r")))
3034 (match_operand:DI 1 "s_register_operand" "0,r")))]
3037 "TARGET_32BIT && reload_completed"
3038 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3039 (set (match_dup 3) (and:SI (not:SI
3040 (ashiftrt:SI (match_dup 2) (const_int 31)))
3044 operands[3] = gen_highpart (SImode, operands[0]);
3045 operands[0] = gen_lowpart (SImode, operands[0]);
3046 operands[4] = gen_highpart (SImode, operands[1]);
3047 operands[1] = gen_lowpart (SImode, operands[1]);
3049 [(set_attr "length" "8")
3050 (set_attr "predicable" "yes")
3051 (set_attr "type" "multiple")]
3054 (define_insn "andsi_notsi_si"
3055 [(set (match_operand:SI 0 "s_register_operand" "=r")
3056 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3057 (match_operand:SI 1 "s_register_operand" "r")))]
3059 "bic%?\\t%0, %1, %2"
3060 [(set_attr "predicable" "yes")
3061 (set_attr "type" "logic_reg")]
3064 (define_insn "andsi_not_shiftsi_si"
3065 [(set (match_operand:SI 0 "s_register_operand" "=r")
3066 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3067 [(match_operand:SI 2 "s_register_operand" "r")
3068 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3069 (match_operand:SI 1 "s_register_operand" "r")))]
3071 "bic%?\\t%0, %1, %2%S4"
3072 [(set_attr "predicable" "yes")
3073 (set_attr "shift" "2")
3074 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3075 (const_string "logic_shift_imm")
3076 (const_string "logic_shift_reg")))]
3079 ;; Shifted bics pattern used to set up CC status register and not reusing
3080 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3081 ;; does not support shift by register.
3082 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3083 [(set (reg:CC_NOOV CC_REGNUM)
3085 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3086 [(match_operand:SI 1 "s_register_operand" "r")
3087 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3088 (match_operand:SI 3 "s_register_operand" "r"))
3090 (clobber (match_scratch:SI 4 "=r"))]
3091 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3092 "bics%?\\t%4, %3, %1%S0"
3093 [(set_attr "predicable" "yes")
3094 (set_attr "conds" "set")
3095 (set_attr "shift" "1")
3096 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3097 (const_string "logic_shift_imm")
3098 (const_string "logic_shift_reg")))]
3101 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3102 ;; getting reused later.
3103 (define_insn "andsi_not_shiftsi_si_scc"
3104 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3106 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3107 [(match_operand:SI 1 "s_register_operand" "r")
3108 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3109 (match_operand:SI 3 "s_register_operand" "r"))
3111 (set (match_operand:SI 4 "s_register_operand" "=r")
3112 (and:SI (not:SI (match_op_dup 0
3116 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3117 "bics%?\\t%4, %3, %1%S0"
3118 [(set_attr "predicable" "yes")
3119 (set_attr "conds" "set")
3120 (set_attr "shift" "1")
3121 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3122 (const_string "logic_shift_imm")
3123 (const_string "logic_shift_reg")))]
3126 (define_insn "*andsi_notsi_si_compare0"
3127 [(set (reg:CC_NOOV CC_REGNUM)
3129 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3130 (match_operand:SI 1 "s_register_operand" "r"))
3132 (set (match_operand:SI 0 "s_register_operand" "=r")
3133 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3136 [(set_attr "conds" "set")
3137 (set_attr "type" "logics_shift_reg")]
3140 (define_insn "*andsi_notsi_si_compare0_scratch"
3141 [(set (reg:CC_NOOV CC_REGNUM)
3143 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3144 (match_operand:SI 1 "s_register_operand" "r"))
3146 (clobber (match_scratch:SI 0 "=r"))]
3149 [(set_attr "conds" "set")
3150 (set_attr "type" "logics_shift_reg")]
3153 (define_expand "iordi3"
3154 [(set (match_operand:DI 0 "s_register_operand")
3155 (ior:DI (match_operand:DI 1 "s_register_operand")
3156 (match_operand:DI 2 "neon_logic_op2")))]
3159 if (!TARGET_NEON && !TARGET_IWMMXT)
3161 rtx low = simplify_gen_binary (IOR, SImode,
3162 gen_lowpart (SImode, operands[1]),
3163 gen_lowpart (SImode, operands[2]));
3164 rtx high = simplify_gen_binary (IOR, SImode,
3165 gen_highpart (SImode, operands[1]),
3166 gen_highpart_mode (SImode, DImode,
3169 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3170 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3174 /* Otherwise expand pattern as above. */
3178 (define_insn_and_split "*iordi3_insn"
3179 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3180 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3181 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3182 "TARGET_32BIT && !TARGET_IWMMXT"
3184 switch (which_alternative)
3186 case 0: /* fall through */
3187 case 6: return "vorr\t%P0, %P1, %P2";
3188 case 1: /* fall through */
3189 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3190 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3196 default: gcc_unreachable ();
3199 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3200 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3201 [(set (match_dup 3) (match_dup 4))
3202 (set (match_dup 5) (match_dup 6))]
3205 operands[3] = gen_lowpart (SImode, operands[0]);
3206 operands[5] = gen_highpart (SImode, operands[0]);
3208 operands[4] = simplify_gen_binary (IOR, SImode,
3209 gen_lowpart (SImode, operands[1]),
3210 gen_lowpart (SImode, operands[2]));
3211 operands[6] = simplify_gen_binary (IOR, SImode,
3212 gen_highpart (SImode, operands[1]),
3213 gen_highpart_mode (SImode, DImode, operands[2]));
3216 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3217 multiple,neon_logic,neon_logic")
3218 (set_attr "length" "*,*,8,8,8,8,*,*")
3219 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3222 (define_insn "*iordi_zesidi_di"
3223 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3224 (ior:DI (zero_extend:DI
3225 (match_operand:SI 2 "s_register_operand" "r,r"))
3226 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3229 orr%?\\t%Q0, %Q1, %2
3231 [(set_attr "length" "4,8")
3232 (set_attr "predicable" "yes")
3233 (set_attr "type" "logic_reg,multiple")]
3236 (define_insn "*iordi_sesidi_di"
3237 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3238 (ior:DI (sign_extend:DI
3239 (match_operand:SI 2 "s_register_operand" "r,r"))
3240 (match_operand:DI 1 "s_register_operand" "0,r")))]
3243 [(set_attr "length" "8")
3244 (set_attr "predicable" "yes")
3245 (set_attr "type" "multiple")]
3248 (define_expand "iorsi3"
3249 [(set (match_operand:SI 0 "s_register_operand")
3250 (ior:SI (match_operand:SI 1 "s_register_operand")
3251 (match_operand:SI 2 "reg_or_int_operand")))]
3254 if (CONST_INT_P (operands[2]))
3258 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3259 operands[2] = force_reg (SImode, operands[2]);
3262 arm_split_constant (IOR, SImode, NULL_RTX,
3263 INTVAL (operands[2]), operands[0],
3265 optimize && can_create_pseudo_p ());
3269 else /* TARGET_THUMB1 */
3271 rtx tmp = force_reg (SImode, operands[2]);
3272 if (rtx_equal_p (operands[0], operands[1]))
3276 operands[2] = operands[1];
3284 (define_insn_and_split "*iorsi3_insn"
3285 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3286 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3287 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3292 orn%?\\t%0, %1, #%B2
3296 && CONST_INT_P (operands[2])
3297 && !(const_ok_for_arm (INTVAL (operands[2]))
3298 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3299 [(clobber (const_int 0))]
3301 arm_split_constant (IOR, SImode, curr_insn,
3302 INTVAL (operands[2]), operands[0], operands[1], 0);
3305 [(set_attr "length" "4,4,4,4,16")
3306 (set_attr "arch" "32,t2,t2,32,32")
3307 (set_attr "predicable" "yes")
3308 (set_attr "predicable_short_it" "no,yes,no,no,no")
3309 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3313 [(match_scratch:SI 3 "r")
3314 (set (match_operand:SI 0 "arm_general_register_operand" "")
3315 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3316 (match_operand:SI 2 "const_int_operand" "")))]
3318 && !const_ok_for_arm (INTVAL (operands[2]))
3319 && const_ok_for_arm (~INTVAL (operands[2]))"
3320 [(set (match_dup 3) (match_dup 2))
3321 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3325 (define_insn "*iorsi3_compare0"
3326 [(set (reg:CC_NOOV CC_REGNUM)
3327 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3328 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3330 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3331 (ior:SI (match_dup 1) (match_dup 2)))]
3333 "orrs%?\\t%0, %1, %2"
3334 [(set_attr "conds" "set")
3335 (set_attr "type" "logics_imm,logics_reg")]
3338 (define_insn "*iorsi3_compare0_scratch"
3339 [(set (reg:CC_NOOV CC_REGNUM)
3340 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3341 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3343 (clobber (match_scratch:SI 0 "=r,r"))]
3345 "orrs%?\\t%0, %1, %2"
3346 [(set_attr "conds" "set")
3347 (set_attr "type" "logics_imm,logics_reg")]
3350 (define_expand "xordi3"
3351 [(set (match_operand:DI 0 "s_register_operand")
3352 (xor:DI (match_operand:DI 1 "s_register_operand")
3353 (match_operand:DI 2 "arm_xordi_operand")))]
3356 /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3357 to reuse this expander for all TARGET_32BIT targets so just force the
3358 constants into a register. Unlike for the anddi3 and iordi3 there are
3359 no NEON instructions that take an immediate. */
3360 if (TARGET_IWMMXT && !REG_P (operands[2]))
3361 operands[2] = force_reg (DImode, operands[2]);
3362 if (!TARGET_NEON && !TARGET_IWMMXT)
3364 rtx low = simplify_gen_binary (XOR, SImode,
3365 gen_lowpart (SImode, operands[1]),
3366 gen_lowpart (SImode, operands[2]));
3367 rtx high = simplify_gen_binary (XOR, SImode,
3368 gen_highpart (SImode, operands[1]),
3369 gen_highpart_mode (SImode, DImode,
3372 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3373 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3377 /* Otherwise expand pattern as above. */
3381 (define_insn_and_split "*xordi3_insn"
3382 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3383 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3384 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3385 "TARGET_32BIT && !TARGET_IWMMXT"
3387 switch (which_alternative)
3392 case 4: /* fall through */
3394 case 0: /* fall through */
3395 case 5: return "veor\t%P0, %P1, %P2";
3396 default: gcc_unreachable ();
3399 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3400 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3401 [(set (match_dup 3) (match_dup 4))
3402 (set (match_dup 5) (match_dup 6))]
3405 operands[3] = gen_lowpart (SImode, operands[0]);
3406 operands[5] = gen_highpart (SImode, operands[0]);
3408 operands[4] = simplify_gen_binary (XOR, SImode,
3409 gen_lowpart (SImode, operands[1]),
3410 gen_lowpart (SImode, operands[2]));
3411 operands[6] = simplify_gen_binary (XOR, SImode,
3412 gen_highpart (SImode, operands[1]),
3413 gen_highpart_mode (SImode, DImode, operands[2]));
3416 [(set_attr "length" "*,8,8,8,8,*")
3417 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3418 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3421 (define_insn "*xordi_zesidi_di"
3422 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3423 (xor:DI (zero_extend:DI
3424 (match_operand:SI 2 "s_register_operand" "r,r"))
3425 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3428 eor%?\\t%Q0, %Q1, %2
3430 [(set_attr "length" "4,8")
3431 (set_attr "predicable" "yes")
3432 (set_attr "type" "logic_reg")]
3435 (define_insn "*xordi_sesidi_di"
3436 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3437 (xor:DI (sign_extend:DI
3438 (match_operand:SI 2 "s_register_operand" "r,r"))
3439 (match_operand:DI 1 "s_register_operand" "0,r")))]
3442 [(set_attr "length" "8")
3443 (set_attr "predicable" "yes")
3444 (set_attr "type" "multiple")]
3447 (define_expand "xorsi3"
3448 [(set (match_operand:SI 0 "s_register_operand")
3449 (xor:SI (match_operand:SI 1 "s_register_operand")
3450 (match_operand:SI 2 "reg_or_int_operand")))]
3452 "if (CONST_INT_P (operands[2]))
3456 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3457 operands[2] = force_reg (SImode, operands[2]);
3460 arm_split_constant (XOR, SImode, NULL_RTX,
3461 INTVAL (operands[2]), operands[0],
3463 optimize && can_create_pseudo_p ());
3467 else /* TARGET_THUMB1 */
3469 rtx tmp = force_reg (SImode, operands[2]);
3470 if (rtx_equal_p (operands[0], operands[1]))
3474 operands[2] = operands[1];
3481 (define_insn_and_split "*arm_xorsi3"
3482 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3483 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3484 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3492 && CONST_INT_P (operands[2])
3493 && !const_ok_for_arm (INTVAL (operands[2]))"
3494 [(clobber (const_int 0))]
3496 arm_split_constant (XOR, SImode, curr_insn,
3497 INTVAL (operands[2]), operands[0], operands[1], 0);
3500 [(set_attr "length" "4,4,4,16")
3501 (set_attr "predicable" "yes")
3502 (set_attr "predicable_short_it" "no,yes,no,no")
3503 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3506 (define_insn "*xorsi3_compare0"
3507 [(set (reg:CC_NOOV CC_REGNUM)
3508 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3509 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3511 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3512 (xor:SI (match_dup 1) (match_dup 2)))]
3514 "eors%?\\t%0, %1, %2"
3515 [(set_attr "conds" "set")
3516 (set_attr "type" "logics_imm,logics_reg")]
3519 (define_insn "*xorsi3_compare0_scratch"
3520 [(set (reg:CC_NOOV CC_REGNUM)
3521 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3522 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3526 [(set_attr "conds" "set")
3527 (set_attr "type" "logics_imm,logics_reg")]
3530 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3531 ; (NOT D) we can sometimes merge the final NOT into one of the following
3535 [(set (match_operand:SI 0 "s_register_operand" "")
3536 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3537 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3538 (match_operand:SI 3 "arm_rhs_operand" "")))
3539 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3541 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3542 (not:SI (match_dup 3))))
3543 (set (match_dup 0) (not:SI (match_dup 4)))]
3547 (define_insn_and_split "*andsi_iorsi3_notsi"
3548 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3549 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3550 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3551 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3553 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3554 "&& reload_completed"
3555 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3556 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3558 /* If operands[3] is a constant make sure to fold the NOT into it
3559 to avoid creating a NOT of a CONST_INT. */
3560 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3561 if (CONST_INT_P (not_rtx))
3563 operands[4] = operands[0];
3564 operands[5] = not_rtx;
3568 operands[5] = operands[0];
3569 operands[4] = not_rtx;
3572 [(set_attr "length" "8")
3573 (set_attr "ce_count" "2")
3574 (set_attr "predicable" "yes")
3575 (set_attr "type" "multiple")]
3578 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3579 ; insns are available?
3581 [(set (match_operand:SI 0 "s_register_operand" "")
3582 (match_operator:SI 1 "logical_binary_operator"
3583 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3584 (match_operand:SI 3 "const_int_operand" "")
3585 (match_operand:SI 4 "const_int_operand" ""))
3586 (match_operator:SI 9 "logical_binary_operator"
3587 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3588 (match_operand:SI 6 "const_int_operand" ""))
3589 (match_operand:SI 7 "s_register_operand" "")])]))
3590 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3592 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3593 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3596 [(ashift:SI (match_dup 2) (match_dup 4))
3600 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3603 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3607 [(set (match_operand:SI 0 "s_register_operand" "")
3608 (match_operator:SI 1 "logical_binary_operator"
3609 [(match_operator:SI 9 "logical_binary_operator"
3610 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3611 (match_operand:SI 6 "const_int_operand" ""))
3612 (match_operand:SI 7 "s_register_operand" "")])
3613 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3614 (match_operand:SI 3 "const_int_operand" "")
3615 (match_operand:SI 4 "const_int_operand" ""))]))
3616 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3618 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3619 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3622 [(ashift:SI (match_dup 2) (match_dup 4))
3626 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3629 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3633 [(set (match_operand:SI 0 "s_register_operand" "")
3634 (match_operator:SI 1 "logical_binary_operator"
3635 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3636 (match_operand:SI 3 "const_int_operand" "")
3637 (match_operand:SI 4 "const_int_operand" ""))
3638 (match_operator:SI 9 "logical_binary_operator"
3639 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3640 (match_operand:SI 6 "const_int_operand" ""))
3641 (match_operand:SI 7 "s_register_operand" "")])]))
3642 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3644 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3645 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3648 [(ashift:SI (match_dup 2) (match_dup 4))
3652 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3655 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3659 [(set (match_operand:SI 0 "s_register_operand" "")
3660 (match_operator:SI 1 "logical_binary_operator"
3661 [(match_operator:SI 9 "logical_binary_operator"
3662 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3663 (match_operand:SI 6 "const_int_operand" ""))
3664 (match_operand:SI 7 "s_register_operand" "")])
3665 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3666 (match_operand:SI 3 "const_int_operand" "")
3667 (match_operand:SI 4 "const_int_operand" ""))]))
3668 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3670 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3671 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3674 [(ashift:SI (match_dup 2) (match_dup 4))
3678 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3681 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3685 ;; Minimum and maximum insns
3687 (define_expand "smaxsi3"
3689 (set (match_operand:SI 0 "s_register_operand")
3690 (smax:SI (match_operand:SI 1 "s_register_operand")
3691 (match_operand:SI 2 "arm_rhs_operand")))
3692 (clobber (reg:CC CC_REGNUM))])]
3695 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3697 /* No need for a clobber of the condition code register here. */
3698 emit_insn (gen_rtx_SET (operands[0],
3699 gen_rtx_SMAX (SImode, operands[1],
3705 (define_insn "*smax_0"
3706 [(set (match_operand:SI 0 "s_register_operand" "=r")
3707 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3710 "bic%?\\t%0, %1, %1, asr #31"
3711 [(set_attr "predicable" "yes")
3712 (set_attr "type" "logic_shift_reg")]
3715 (define_insn "*smax_m1"
3716 [(set (match_operand:SI 0 "s_register_operand" "=r")
3717 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3720 "orr%?\\t%0, %1, %1, asr #31"
3721 [(set_attr "predicable" "yes")
3722 (set_attr "type" "logic_shift_reg")]
3725 (define_insn_and_split "*arm_smax_insn"
3726 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3727 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3728 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3729 (clobber (reg:CC CC_REGNUM))]
3732 ; cmp\\t%1, %2\;movlt\\t%0, %2
3733 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3735 [(set (reg:CC CC_REGNUM)
3736 (compare:CC (match_dup 1) (match_dup 2)))
3738 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3742 [(set_attr "conds" "clob")
3743 (set_attr "length" "8,12")
3744 (set_attr "type" "multiple")]
3747 (define_expand "sminsi3"
3749 (set (match_operand:SI 0 "s_register_operand")
3750 (smin:SI (match_operand:SI 1 "s_register_operand")
3751 (match_operand:SI 2 "arm_rhs_operand")))
3752 (clobber (reg:CC CC_REGNUM))])]
3755 if (operands[2] == const0_rtx)
3757 /* No need for a clobber of the condition code register here. */
3758 emit_insn (gen_rtx_SET (operands[0],
3759 gen_rtx_SMIN (SImode, operands[1],
3765 (define_insn "*smin_0"
3766 [(set (match_operand:SI 0 "s_register_operand" "=r")
3767 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3770 "and%?\\t%0, %1, %1, asr #31"
3771 [(set_attr "predicable" "yes")
3772 (set_attr "type" "logic_shift_reg")]
3775 (define_insn_and_split "*arm_smin_insn"
3776 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3777 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3778 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3779 (clobber (reg:CC CC_REGNUM))]
3782 ; cmp\\t%1, %2\;movge\\t%0, %2
3783 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3785 [(set (reg:CC CC_REGNUM)
3786 (compare:CC (match_dup 1) (match_dup 2)))
3788 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3792 [(set_attr "conds" "clob")
3793 (set_attr "length" "8,12")
3794 (set_attr "type" "multiple,multiple")]
3797 (define_expand "umaxsi3"
3799 (set (match_operand:SI 0 "s_register_operand")
3800 (umax:SI (match_operand:SI 1 "s_register_operand")
3801 (match_operand:SI 2 "arm_rhs_operand")))
3802 (clobber (reg:CC CC_REGNUM))])]
3807 (define_insn_and_split "*arm_umaxsi3"
3808 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3809 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3810 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3811 (clobber (reg:CC CC_REGNUM))]
3814 ; cmp\\t%1, %2\;movcc\\t%0, %2
3815 ; cmp\\t%1, %2\;movcs\\t%0, %1
3816 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3818 [(set (reg:CC CC_REGNUM)
3819 (compare:CC (match_dup 1) (match_dup 2)))
3821 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3825 [(set_attr "conds" "clob")
3826 (set_attr "length" "8,8,12")
3827 (set_attr "type" "store_4")]
3830 (define_expand "uminsi3"
3832 (set (match_operand:SI 0 "s_register_operand")
3833 (umin:SI (match_operand:SI 1 "s_register_operand")
3834 (match_operand:SI 2 "arm_rhs_operand")))
3835 (clobber (reg:CC CC_REGNUM))])]
3840 (define_insn_and_split "*arm_uminsi3"
3841 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3842 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3843 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3844 (clobber (reg:CC CC_REGNUM))]
3847 ; cmp\\t%1, %2\;movcs\\t%0, %2
3848 ; cmp\\t%1, %2\;movcc\\t%0, %1
3849 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3851 [(set (reg:CC CC_REGNUM)
3852 (compare:CC (match_dup 1) (match_dup 2)))
3854 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3858 [(set_attr "conds" "clob")
3859 (set_attr "length" "8,8,12")
3860 (set_attr "type" "store_4")]
3863 (define_insn "*store_minmaxsi"
3864 [(set (match_operand:SI 0 "memory_operand" "=m")
3865 (match_operator:SI 3 "minmax_operator"
3866 [(match_operand:SI 1 "s_register_operand" "r")
3867 (match_operand:SI 2 "s_register_operand" "r")]))
3868 (clobber (reg:CC CC_REGNUM))]
3869 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3871 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3872 operands[1], operands[2]);
3873 output_asm_insn (\"cmp\\t%1, %2\", operands);
3875 output_asm_insn (\"ite\t%d3\", operands);
3876 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3877 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3880 [(set_attr "conds" "clob")
3881 (set (attr "length")
3882 (if_then_else (eq_attr "is_thumb" "yes")
3885 (set_attr "type" "store_4")]
3888 ; Reject the frame pointer in operand[1], since reloading this after
3889 ; it has been eliminated can cause carnage.
3890 (define_insn "*minmax_arithsi"
3891 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3892 (match_operator:SI 4 "shiftable_operator"
3893 [(match_operator:SI 5 "minmax_operator"
3894 [(match_operand:SI 2 "s_register_operand" "r,r")
3895 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3896 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3897 (clobber (reg:CC CC_REGNUM))]
3898 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3901 enum rtx_code code = GET_CODE (operands[4]);
3904 if (which_alternative != 0 || operands[3] != const0_rtx
3905 || (code != PLUS && code != IOR && code != XOR))
3910 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3911 operands[2], operands[3]);
3912 output_asm_insn (\"cmp\\t%2, %3\", operands);
3916 output_asm_insn (\"ite\\t%d5\", operands);
3918 output_asm_insn (\"it\\t%d5\", operands);
3920 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3922 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3925 [(set_attr "conds" "clob")
3926 (set (attr "length")
3927 (if_then_else (eq_attr "is_thumb" "yes")
3930 (set_attr "type" "multiple")]
3933 ; Reject the frame pointer in operand[1], since reloading this after
3934 ; it has been eliminated can cause carnage.
3935 (define_insn_and_split "*minmax_arithsi_non_canon"
3936 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3938 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3939 (match_operator:SI 4 "minmax_operator"
3940 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3941 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3942 (clobber (reg:CC CC_REGNUM))]
3943 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3944 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3946 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3947 [(set (reg:CC CC_REGNUM)
3948 (compare:CC (match_dup 2) (match_dup 3)))
3950 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3952 (minus:SI (match_dup 1)
3954 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3958 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3959 operands[2], operands[3]);
3960 enum rtx_code rc = minmax_code (operands[4]);
3961 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3962 operands[2], operands[3]);
3964 if (mode == CCFPmode || mode == CCFPEmode)
3965 rc = reverse_condition_maybe_unordered (rc);
3967 rc = reverse_condition (rc);
3968 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3969 if (CONST_INT_P (operands[3]))
3970 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3972 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3974 [(set_attr "conds" "clob")
3975 (set (attr "length")
3976 (if_then_else (eq_attr "is_thumb" "yes")
3979 (set_attr "type" "multiple")]
3982 (define_code_iterator SAT [smin smax])
3983 (define_code_iterator SATrev [smin smax])
3984 (define_code_attr SATlo [(smin "1") (smax "2")])
3985 (define_code_attr SAThi [(smin "2") (smax "1")])
3987 (define_insn "*satsi_<SAT:code>"
3988 [(set (match_operand:SI 0 "s_register_operand" "=r")
3989 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3990 (match_operand:SI 1 "const_int_operand" "i"))
3991 (match_operand:SI 2 "const_int_operand" "i")))]
3992 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3993 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3997 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3998 &mask, &signed_sat))
4001 operands[1] = GEN_INT (mask);
4003 return "ssat%?\t%0, %1, %3";
4005 return "usat%?\t%0, %1, %3";
4007 [(set_attr "predicable" "yes")
4008 (set_attr "type" "alus_imm")]
4011 (define_insn "*satsi_<SAT:code>_shift"
4012 [(set (match_operand:SI 0 "s_register_operand" "=r")
4013 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
4014 [(match_operand:SI 4 "s_register_operand" "r")
4015 (match_operand:SI 5 "const_int_operand" "i")])
4016 (match_operand:SI 1 "const_int_operand" "i"))
4017 (match_operand:SI 2 "const_int_operand" "i")))]
4018 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
4019 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
4023 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
4024 &mask, &signed_sat))
4027 operands[1] = GEN_INT (mask);
4029 return "ssat%?\t%0, %1, %4%S3";
4031 return "usat%?\t%0, %1, %4%S3";
4033 [(set_attr "predicable" "yes")
4034 (set_attr "shift" "3")
4035 (set_attr "type" "logic_shift_reg")])
4037 ;; Shift and rotation insns
4039 (define_expand "ashldi3"
4040 [(set (match_operand:DI 0 "s_register_operand")
4041 (ashift:DI (match_operand:DI 1 "s_register_operand")
4042 (match_operand:SI 2 "general_operand")))]
4047 /* Delay the decision whether to use NEON or core-regs until
4048 register allocation. */
4049 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4054 /* Only the NEON case can handle in-memory shift counts. */
4055 if (!reg_or_int_operand (operands[2], SImode))
4056 operands[2] = force_reg (SImode, operands[2]);
4059 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4060 ; /* No special preparation statements; expand pattern as above. */
4063 rtx scratch1, scratch2;
4065 /* Ideally we should use iwmmxt here if we could know that operands[1]
4066 ends up already living in an iwmmxt register. Otherwise it's
4067 cheaper to have the alternate code being generated than moving
4068 values to iwmmxt regs and back. */
4070 /* Expand operation using core-registers.
4071 'FAIL' would achieve the same thing, but this is a bit smarter. */
4072 scratch1 = gen_reg_rtx (SImode);
4073 scratch2 = gen_reg_rtx (SImode);
4074 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4075 operands[2], scratch1, scratch2);
4081 (define_expand "ashlsi3"
4082 [(set (match_operand:SI 0 "s_register_operand")
4083 (ashift:SI (match_operand:SI 1 "s_register_operand")
4084 (match_operand:SI 2 "arm_rhs_operand")))]
4087 if (CONST_INT_P (operands[2])
4088 && (UINTVAL (operands[2])) > 31)
4090 emit_insn (gen_movsi (operands[0], const0_rtx));
4096 (define_expand "ashrdi3"
4097 [(set (match_operand:DI 0 "s_register_operand")
4098 (ashiftrt:DI (match_operand:DI 1 "s_register_operand")
4099 (match_operand:SI 2 "reg_or_int_operand")))]
4104 /* Delay the decision whether to use NEON or core-regs until
4105 register allocation. */
4106 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4110 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4111 ; /* No special preparation statements; expand pattern as above. */
4114 rtx scratch1, scratch2;
4116 /* Ideally we should use iwmmxt here if we could know that operands[1]
4117 ends up already living in an iwmmxt register. Otherwise it's
4118 cheaper to have the alternate code being generated than moving
4119 values to iwmmxt regs and back. */
4121 /* Expand operation using core-registers.
4122 'FAIL' would achieve the same thing, but this is a bit smarter. */
4123 scratch1 = gen_reg_rtx (SImode);
4124 scratch2 = gen_reg_rtx (SImode);
4125 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4126 operands[2], scratch1, scratch2);
4132 (define_expand "ashrsi3"
4133 [(set (match_operand:SI 0 "s_register_operand")
4134 (ashiftrt:SI (match_operand:SI 1 "s_register_operand")
4135 (match_operand:SI 2 "arm_rhs_operand")))]
4138 if (CONST_INT_P (operands[2])
4139 && UINTVAL (operands[2]) > 31)
4140 operands[2] = GEN_INT (31);
4144 (define_expand "lshrdi3"
4145 [(set (match_operand:DI 0 "s_register_operand")
4146 (lshiftrt:DI (match_operand:DI 1 "s_register_operand")
4147 (match_operand:SI 2 "reg_or_int_operand")))]
4152 /* Delay the decision whether to use NEON or core-regs until
4153 register allocation. */
4154 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4158 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4159 ; /* No special preparation statements; expand pattern as above. */
4162 rtx scratch1, scratch2;
4164 /* Ideally we should use iwmmxt here if we could know that operands[1]
4165 ends up already living in an iwmmxt register. Otherwise it's
4166 cheaper to have the alternate code being generated than moving
4167 values to iwmmxt regs and back. */
4169 /* Expand operation using core-registers.
4170 'FAIL' would achieve the same thing, but this is a bit smarter. */
4171 scratch1 = gen_reg_rtx (SImode);
4172 scratch2 = gen_reg_rtx (SImode);
4173 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4174 operands[2], scratch1, scratch2);
4180 (define_expand "lshrsi3"
4181 [(set (match_operand:SI 0 "s_register_operand")
4182 (lshiftrt:SI (match_operand:SI 1 "s_register_operand")
4183 (match_operand:SI 2 "arm_rhs_operand")))]
4186 if (CONST_INT_P (operands[2])
4187 && (UINTVAL (operands[2])) > 31)
4189 emit_insn (gen_movsi (operands[0], const0_rtx));
4195 (define_expand "rotlsi3"
4196 [(set (match_operand:SI 0 "s_register_operand")
4197 (rotatert:SI (match_operand:SI 1 "s_register_operand")
4198 (match_operand:SI 2 "reg_or_int_operand")))]
4201 if (CONST_INT_P (operands[2]))
4202 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4205 rtx reg = gen_reg_rtx (SImode);
4206 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4212 (define_expand "rotrsi3"
4213 [(set (match_operand:SI 0 "s_register_operand")
4214 (rotatert:SI (match_operand:SI 1 "s_register_operand")
4215 (match_operand:SI 2 "arm_rhs_operand")))]
4220 if (CONST_INT_P (operands[2])
4221 && UINTVAL (operands[2]) > 31)
4222 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4224 else /* TARGET_THUMB1 */
4226 if (CONST_INT_P (operands [2]))
4227 operands [2] = force_reg (SImode, operands[2]);
4232 (define_insn "*arm_shiftsi3"
4233 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4234 (match_operator:SI 3 "shift_operator"
4235 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4236 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4238 "* return arm_output_shift(operands, 0);"
4239 [(set_attr "predicable" "yes")
4240 (set_attr "arch" "t2,t2,*,*")
4241 (set_attr "predicable_short_it" "yes,yes,no,no")
4242 (set_attr "length" "4")
4243 (set_attr "shift" "1")
4244 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4247 (define_insn "*shiftsi3_compare0"
4248 [(set (reg:CC_NOOV CC_REGNUM)
4249 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4250 [(match_operand:SI 1 "s_register_operand" "r,r")
4251 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4253 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4254 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4256 "* return arm_output_shift(operands, 1);"
4257 [(set_attr "conds" "set")
4258 (set_attr "shift" "1")
4259 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4262 (define_insn "*shiftsi3_compare0_scratch"
4263 [(set (reg:CC_NOOV CC_REGNUM)
4264 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4265 [(match_operand:SI 1 "s_register_operand" "r,r")
4266 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4268 (clobber (match_scratch:SI 0 "=r,r"))]
4270 "* return arm_output_shift(operands, 1);"
4271 [(set_attr "conds" "set")
4272 (set_attr "shift" "1")
4273 (set_attr "type" "shift_imm,shift_reg")]
4276 (define_insn "*not_shiftsi"
4277 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4278 (not:SI (match_operator:SI 3 "shift_operator"
4279 [(match_operand:SI 1 "s_register_operand" "r,r")
4280 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4283 [(set_attr "predicable" "yes")
4284 (set_attr "shift" "1")
4285 (set_attr "arch" "32,a")
4286 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4288 (define_insn "*not_shiftsi_compare0"
4289 [(set (reg:CC_NOOV CC_REGNUM)
4291 (not:SI (match_operator:SI 3 "shift_operator"
4292 [(match_operand:SI 1 "s_register_operand" "r,r")
4293 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4295 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4296 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4298 "mvns%?\\t%0, %1%S3"
4299 [(set_attr "conds" "set")
4300 (set_attr "shift" "1")
4301 (set_attr "arch" "32,a")
4302 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4304 (define_insn "*not_shiftsi_compare0_scratch"
4305 [(set (reg:CC_NOOV CC_REGNUM)
4307 (not:SI (match_operator:SI 3 "shift_operator"
4308 [(match_operand:SI 1 "s_register_operand" "r,r")
4309 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4311 (clobber (match_scratch:SI 0 "=r,r"))]
4313 "mvns%?\\t%0, %1%S3"
4314 [(set_attr "conds" "set")
4315 (set_attr "shift" "1")
4316 (set_attr "arch" "32,a")
4317 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4319 ;; We don't really have extzv, but defining this using shifts helps
4320 ;; to reduce register pressure later on.
4322 (define_expand "extzv"
4323 [(set (match_operand 0 "s_register_operand")
4324 (zero_extract (match_operand 1 "nonimmediate_operand")
4325 (match_operand 2 "const_int_operand")
4326 (match_operand 3 "const_int_operand")))]
4327 "TARGET_THUMB1 || arm_arch_thumb2"
4330 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4331 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4333 if (arm_arch_thumb2)
4335 HOST_WIDE_INT width = INTVAL (operands[2]);
4336 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4338 if (unaligned_access && MEM_P (operands[1])
4339 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4343 if (BYTES_BIG_ENDIAN)
4344 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4349 base_addr = adjust_address (operands[1], SImode,
4350 bitpos / BITS_PER_UNIT);
4351 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4355 rtx dest = operands[0];
4356 rtx tmp = gen_reg_rtx (SImode);
4358 /* We may get a paradoxical subreg here. Strip it off. */
4359 if (GET_CODE (dest) == SUBREG
4360 && GET_MODE (dest) == SImode
4361 && GET_MODE (SUBREG_REG (dest)) == HImode)
4362 dest = SUBREG_REG (dest);
4364 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4367 base_addr = adjust_address (operands[1], HImode,
4368 bitpos / BITS_PER_UNIT);
4369 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4370 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4374 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4376 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4384 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4387 operands[3] = GEN_INT (rshift);
4391 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4395 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4396 operands[3], gen_reg_rtx (SImode)));
4401 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4403 (define_expand "extzv_t1"
4404 [(set (match_operand:SI 4 "s_register_operand")
4405 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
4406 (match_operand:SI 2 "const_int_operand")))
4407 (set (match_operand:SI 0 "s_register_operand")
4408 (lshiftrt:SI (match_dup 4)
4409 (match_operand:SI 3 "const_int_operand")))]
4413 (define_expand "extv"
4414 [(set (match_operand 0 "s_register_operand")
4415 (sign_extract (match_operand 1 "nonimmediate_operand")
4416 (match_operand 2 "const_int_operand")
4417 (match_operand 3 "const_int_operand")))]
4420 HOST_WIDE_INT width = INTVAL (operands[2]);
4421 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4423 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4424 && (bitpos % BITS_PER_UNIT) == 0)
4428 if (BYTES_BIG_ENDIAN)
4429 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4433 base_addr = adjust_address (operands[1], SImode,
4434 bitpos / BITS_PER_UNIT);
4435 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4439 rtx dest = operands[0];
4440 rtx tmp = gen_reg_rtx (SImode);
4442 /* We may get a paradoxical subreg here. Strip it off. */
4443 if (GET_CODE (dest) == SUBREG
4444 && GET_MODE (dest) == SImode
4445 && GET_MODE (SUBREG_REG (dest)) == HImode)
4446 dest = SUBREG_REG (dest);
4448 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4451 base_addr = adjust_address (operands[1], HImode,
4452 bitpos / BITS_PER_UNIT);
4453 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4454 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4459 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4461 else if (GET_MODE (operands[0]) == SImode
4462 && GET_MODE (operands[1]) == SImode)
4464 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4472 ; Helper to expand register forms of extv with the proper modes.
4474 (define_expand "extv_regsi"
4475 [(set (match_operand:SI 0 "s_register_operand")
4476 (sign_extract:SI (match_operand:SI 1 "s_register_operand")
4477 (match_operand 2 "const_int_operand")
4478 (match_operand 3 "const_int_operand")))]
4483 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4485 (define_insn "unaligned_loadsi"
4486 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
4487 (unspec:SI [(match_operand:SI 1 "memory_operand" "m,Uw,m")]
4488 UNSPEC_UNALIGNED_LOAD))]
4491 ldr\t%0, %1\t@ unaligned
4492 ldr%?\t%0, %1\t@ unaligned
4493 ldr%?\t%0, %1\t@ unaligned"
4494 [(set_attr "arch" "t1,t2,32")
4495 (set_attr "length" "2,2,4")
4496 (set_attr "predicable" "no,yes,yes")
4497 (set_attr "predicable_short_it" "no,yes,no")
4498 (set_attr "type" "load_4")])
4500 ;; The 16-bit Thumb1 variant of ldrsh requires two registers in the
4501 ;; address (there's no immediate format). That's tricky to support
4502 ;; here and we don't really need this pattern for that case, so only
4503 ;; enable for 32-bit ISAs.
4504 (define_insn "unaligned_loadhis"
4505 [(set (match_operand:SI 0 "s_register_operand" "=r")
4507 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
4508 UNSPEC_UNALIGNED_LOAD)))]
4509 "unaligned_access && TARGET_32BIT"
4510 "ldrsh%?\t%0, %1\t@ unaligned"
4511 [(set_attr "predicable" "yes")
4512 (set_attr "type" "load_byte")])
4514 (define_insn "unaligned_loadhiu"
4515 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
4517 (unspec:HI [(match_operand:HI 1 "memory_operand" "m,Uw,m")]
4518 UNSPEC_UNALIGNED_LOAD)))]
4521 ldrh\t%0, %1\t@ unaligned
4522 ldrh%?\t%0, %1\t@ unaligned
4523 ldrh%?\t%0, %1\t@ unaligned"
4524 [(set_attr "arch" "t1,t2,32")
4525 (set_attr "length" "2,2,4")
4526 (set_attr "predicable" "no,yes,yes")
4527 (set_attr "predicable_short_it" "no,yes,no")
4528 (set_attr "type" "load_byte")])
4530 (define_insn "unaligned_storesi"
4531 [(set (match_operand:SI 0 "memory_operand" "=m,Uw,m")
4532 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,l,r")]
4533 UNSPEC_UNALIGNED_STORE))]
4536 str\t%1, %0\t@ unaligned
4537 str%?\t%1, %0\t@ unaligned
4538 str%?\t%1, %0\t@ unaligned"
4539 [(set_attr "arch" "t1,t2,32")
4540 (set_attr "length" "2,2,4")
4541 (set_attr "predicable" "no,yes,yes")
4542 (set_attr "predicable_short_it" "no,yes,no")
4543 (set_attr "type" "store_4")])
4545 (define_insn "unaligned_storehi"
4546 [(set (match_operand:HI 0 "memory_operand" "=m,Uw,m")
4547 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,l,r")]
4548 UNSPEC_UNALIGNED_STORE))]
4551 strh\t%1, %0\t@ unaligned
4552 strh%?\t%1, %0\t@ unaligned
4553 strh%?\t%1, %0\t@ unaligned"
4554 [(set_attr "arch" "t1,t2,32")
4555 (set_attr "length" "2,2,4")
4556 (set_attr "predicable" "no,yes,yes")
4557 (set_attr "predicable_short_it" "no,yes,no")
4558 (set_attr "type" "store_4")])
4561 (define_insn "*extv_reg"
4562 [(set (match_operand:SI 0 "s_register_operand" "=r")
4563 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4564 (match_operand:SI 2 "const_int_operand" "n")
4565 (match_operand:SI 3 "const_int_operand" "n")))]
4567 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4568 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4569 "sbfx%?\t%0, %1, %3, %2"
4570 [(set_attr "length" "4")
4571 (set_attr "predicable" "yes")
4572 (set_attr "type" "bfm")]
4575 (define_insn "extzv_t2"
4576 [(set (match_operand:SI 0 "s_register_operand" "=r")
4577 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4578 (match_operand:SI 2 "const_int_operand" "n")
4579 (match_operand:SI 3 "const_int_operand" "n")))]
4581 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4582 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4583 "ubfx%?\t%0, %1, %3, %2"
4584 [(set_attr "length" "4")
4585 (set_attr "predicable" "yes")
4586 (set_attr "type" "bfm")]
4590 ;; Division instructions
4591 (define_insn "divsi3"
4592 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4593 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4594 (match_operand:SI 2 "s_register_operand" "r,r")))]
4599 [(set_attr "arch" "32,v8mb")
4600 (set_attr "predicable" "yes")
4601 (set_attr "type" "sdiv")]
4604 (define_insn "udivsi3"
4605 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4606 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4607 (match_operand:SI 2 "s_register_operand" "r,r")))]
4612 [(set_attr "arch" "32,v8mb")
4613 (set_attr "predicable" "yes")
4614 (set_attr "type" "udiv")]
4618 ;; Unary arithmetic insns
4620 (define_expand "negvsi3"
4621 [(match_operand:SI 0 "register_operand")
4622 (match_operand:SI 1 "register_operand")
4623 (match_operand 2 "")]
4626 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4627 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4632 (define_expand "negvdi3"
4633 [(match_operand:DI 0 "register_operand")
4634 (match_operand:DI 1 "register_operand")
4635 (match_operand 2 "")]
4638 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4639 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4645 (define_insn_and_split "negdi2_compare"
4646 [(set (reg:CC CC_REGNUM)
4649 (match_operand:DI 1 "register_operand" "0,r")))
4650 (set (match_operand:DI 0 "register_operand" "=r,&r")
4651 (minus:DI (const_int 0) (match_dup 1)))]
4654 "&& reload_completed"
4655 [(parallel [(set (reg:CC CC_REGNUM)
4656 (compare:CC (const_int 0) (match_dup 1)))
4657 (set (match_dup 0) (minus:SI (const_int 0)
4659 (parallel [(set (reg:CC CC_REGNUM)
4660 (compare:CC (const_int 0) (match_dup 3)))
4663 (minus:SI (const_int 0) (match_dup 3))
4664 (ltu:SI (reg:CC_C CC_REGNUM)
4667 operands[2] = gen_highpart (SImode, operands[0]);
4668 operands[0] = gen_lowpart (SImode, operands[0]);
4669 operands[3] = gen_highpart (SImode, operands[1]);
4670 operands[1] = gen_lowpart (SImode, operands[1]);
4672 [(set_attr "conds" "set")
4673 (set_attr "length" "8")
4674 (set_attr "type" "multiple")]
4677 (define_expand "negdi2"
4679 [(set (match_operand:DI 0 "s_register_operand")
4680 (neg:DI (match_operand:DI 1 "s_register_operand")))
4681 (clobber (reg:CC CC_REGNUM))])]
4686 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4692 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4693 ;; The first alternative allows the common case of a *full* overlap.
4694 (define_insn_and_split "*negdi2_insn"
4695 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4696 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4697 (clobber (reg:CC CC_REGNUM))]
4699 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4700 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4701 "&& reload_completed"
4702 [(parallel [(set (reg:CC CC_REGNUM)
4703 (compare:CC (const_int 0) (match_dup 1)))
4704 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4705 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4706 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4708 operands[2] = gen_highpart (SImode, operands[0]);
4709 operands[0] = gen_lowpart (SImode, operands[0]);
4710 operands[3] = gen_highpart (SImode, operands[1]);
4711 operands[1] = gen_lowpart (SImode, operands[1]);
4713 [(set_attr "conds" "clob")
4714 (set_attr "length" "8")
4715 (set_attr "type" "multiple")]
4718 (define_insn "*negsi2_carryin_compare"
4719 [(set (reg:CC CC_REGNUM)
4720 (compare:CC (const_int 0)
4721 (match_operand:SI 1 "s_register_operand" "r")))
4722 (set (match_operand:SI 0 "s_register_operand" "=r")
4723 (minus:SI (minus:SI (const_int 0)
4725 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4728 [(set_attr "conds" "set")
4729 (set_attr "type" "alus_imm")]
4732 (define_expand "negsi2"
4733 [(set (match_operand:SI 0 "s_register_operand")
4734 (neg:SI (match_operand:SI 1 "s_register_operand")))]
4739 (define_insn "*arm_negsi2"
4740 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4741 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4743 "rsb%?\\t%0, %1, #0"
4744 [(set_attr "predicable" "yes")
4745 (set_attr "predicable_short_it" "yes,no")
4746 (set_attr "arch" "t2,*")
4747 (set_attr "length" "4")
4748 (set_attr "type" "alu_sreg")]
4751 (define_expand "negsf2"
4752 [(set (match_operand:SF 0 "s_register_operand")
4753 (neg:SF (match_operand:SF 1 "s_register_operand")))]
4754 "TARGET_32BIT && TARGET_HARD_FLOAT"
4758 (define_expand "negdf2"
4759 [(set (match_operand:DF 0 "s_register_operand")
4760 (neg:DF (match_operand:DF 1 "s_register_operand")))]
4761 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4764 (define_insn_and_split "*zextendsidi_negsi"
4765 [(set (match_operand:DI 0 "s_register_operand" "=r")
4766 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4771 (neg:SI (match_dup 1)))
4775 operands[2] = gen_lowpart (SImode, operands[0]);
4776 operands[3] = gen_highpart (SImode, operands[0]);
4778 [(set_attr "length" "8")
4779 (set_attr "type" "multiple")]
4782 ;; Negate an extended 32-bit value.
4783 (define_insn_and_split "*negdi_extendsidi"
4784 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4785 (neg:DI (sign_extend:DI
4786 (match_operand:SI 1 "s_register_operand" "l,r"))))
4787 (clobber (reg:CC CC_REGNUM))]
4790 "&& reload_completed"
4793 rtx low = gen_lowpart (SImode, operands[0]);
4794 rtx high = gen_highpart (SImode, operands[0]);
4796 if (reg_overlap_mentioned_p (low, operands[1]))
4798 /* Input overlaps the low word of the output. Use:
4801 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4802 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4804 emit_insn (gen_rtx_SET (high,
4805 gen_rtx_ASHIFTRT (SImode, operands[1],
4808 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4810 emit_insn (gen_rtx_SET (high,
4811 gen_rtx_MINUS (SImode,
4812 gen_rtx_MINUS (SImode,
4815 gen_rtx_LTU (SImode,
4820 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4821 emit_insn (gen_rtx_SET (high,
4822 gen_rtx_MINUS (SImode,
4823 gen_rtx_MINUS (SImode,
4826 gen_rtx_LTU (SImode,
4833 /* No overlap, or overlap on high word. Use:
4837 Flags not needed for this sequence. */
4838 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4839 emit_insn (gen_rtx_SET (high,
4840 gen_rtx_AND (SImode,
4841 gen_rtx_NOT (SImode, operands[1]),
4843 emit_insn (gen_rtx_SET (high,
4844 gen_rtx_ASHIFTRT (SImode, high,
4849 [(set_attr "length" "12")
4850 (set_attr "arch" "t2,*")
4851 (set_attr "type" "multiple")]
4854 (define_insn_and_split "*negdi_zero_extendsidi"
4855 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4856 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4857 (clobber (reg:CC CC_REGNUM))]
4859 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4860 ;; Don't care what register is input to sbc,
4861 ;; since we just need to propagate the carry.
4862 "&& reload_completed"
4863 [(parallel [(set (reg:CC CC_REGNUM)
4864 (compare:CC (const_int 0) (match_dup 1)))
4865 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4866 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4867 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4869 operands[2] = gen_highpart (SImode, operands[0]);
4870 operands[0] = gen_lowpart (SImode, operands[0]);
4872 [(set_attr "conds" "clob")
4873 (set_attr "length" "8")
4874 (set_attr "type" "multiple")] ;; length in thumb is 4
4877 ;; abssi2 doesn't really clobber the condition codes if a different register
4878 ;; is being set. To keep things simple, assume during rtl manipulations that
4879 ;; it does, but tell the final scan operator the truth. Similarly for
4882 (define_expand "abssi2"
4884 [(set (match_operand:SI 0 "s_register_operand")
4885 (abs:SI (match_operand:SI 1 "s_register_operand")))
4886 (clobber (match_dup 2))])]
4890 operands[2] = gen_rtx_SCRATCH (SImode);
4892 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4895 (define_insn_and_split "*arm_abssi2"
4896 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4897 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4898 (clobber (reg:CC CC_REGNUM))]
4901 "&& reload_completed"
4904 /* if (which_alternative == 0) */
4905 if (REGNO(operands[0]) == REGNO(operands[1]))
4907 /* Emit the pattern:
4908 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4909 [(set (reg:CC CC_REGNUM)
4910 (compare:CC (match_dup 0) (const_int 0)))
4911 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4912 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4914 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4915 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4916 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4917 (gen_rtx_LT (SImode,
4918 gen_rtx_REG (CCmode, CC_REGNUM),
4920 (gen_rtx_SET (operands[0],
4921 (gen_rtx_MINUS (SImode,
4928 /* Emit the pattern:
4929 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4931 (xor:SI (match_dup 1)
4932 (ashiftrt:SI (match_dup 1) (const_int 31))))
4934 (minus:SI (match_dup 0)
4935 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4937 emit_insn (gen_rtx_SET (operands[0],
4938 gen_rtx_XOR (SImode,
4939 gen_rtx_ASHIFTRT (SImode,
4943 emit_insn (gen_rtx_SET (operands[0],
4944 gen_rtx_MINUS (SImode,
4946 gen_rtx_ASHIFTRT (SImode,
4952 [(set_attr "conds" "clob,*")
4953 (set_attr "shift" "1")
4954 (set_attr "predicable" "no, yes")
4955 (set_attr "length" "8")
4956 (set_attr "type" "multiple")]
4959 (define_insn_and_split "*arm_neg_abssi2"
4960 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4961 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4962 (clobber (reg:CC CC_REGNUM))]
4965 "&& reload_completed"
4968 /* if (which_alternative == 0) */
4969 if (REGNO (operands[0]) == REGNO (operands[1]))
4971 /* Emit the pattern:
4972 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4974 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4975 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4976 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4978 gen_rtx_REG (CCmode, CC_REGNUM),
4980 gen_rtx_SET (operands[0],
4981 (gen_rtx_MINUS (SImode,
4987 /* Emit the pattern:
4988 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4990 emit_insn (gen_rtx_SET (operands[0],
4991 gen_rtx_XOR (SImode,
4992 gen_rtx_ASHIFTRT (SImode,
4996 emit_insn (gen_rtx_SET (operands[0],
4997 gen_rtx_MINUS (SImode,
4998 gen_rtx_ASHIFTRT (SImode,
5005 [(set_attr "conds" "clob,*")
5006 (set_attr "shift" "1")
5007 (set_attr "predicable" "no, yes")
5008 (set_attr "length" "8")
5009 (set_attr "type" "multiple")]
5012 (define_expand "abssf2"
5013 [(set (match_operand:SF 0 "s_register_operand")
5014 (abs:SF (match_operand:SF 1 "s_register_operand")))]
5015 "TARGET_32BIT && TARGET_HARD_FLOAT"
5018 (define_expand "absdf2"
5019 [(set (match_operand:DF 0 "s_register_operand")
5020 (abs:DF (match_operand:DF 1 "s_register_operand")))]
5021 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5024 (define_expand "sqrtsf2"
5025 [(set (match_operand:SF 0 "s_register_operand")
5026 (sqrt:SF (match_operand:SF 1 "s_register_operand")))]
5027 "TARGET_32BIT && TARGET_HARD_FLOAT"
5030 (define_expand "sqrtdf2"
5031 [(set (match_operand:DF 0 "s_register_operand")
5032 (sqrt:DF (match_operand:DF 1 "s_register_operand")))]
5033 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5036 (define_expand "one_cmpldi2"
5037 [(set (match_operand:DI 0 "s_register_operand")
5038 (not:DI (match_operand:DI 1 "s_register_operand")))]
5041 if (!TARGET_NEON && !TARGET_IWMMXT)
5043 rtx low = simplify_gen_unary (NOT, SImode,
5044 gen_lowpart (SImode, operands[1]),
5046 rtx high = simplify_gen_unary (NOT, SImode,
5047 gen_highpart_mode (SImode, DImode,
5051 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5052 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5056 /* Otherwise expand pattern as above. */
5060 (define_insn_and_split "*one_cmpldi2_insn"
5061 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5062 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5069 "TARGET_32BIT && reload_completed
5070 && arm_general_register_operand (operands[0], DImode)"
5071 [(set (match_dup 0) (not:SI (match_dup 1)))
5072 (set (match_dup 2) (not:SI (match_dup 3)))]
5075 operands[2] = gen_highpart (SImode, operands[0]);
5076 operands[0] = gen_lowpart (SImode, operands[0]);
5077 operands[3] = gen_highpart (SImode, operands[1]);
5078 operands[1] = gen_lowpart (SImode, operands[1]);
5080 [(set_attr "length" "*,8,8,*")
5081 (set_attr "predicable" "no,yes,yes,no")
5082 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5083 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5086 (define_expand "one_cmplsi2"
5087 [(set (match_operand:SI 0 "s_register_operand")
5088 (not:SI (match_operand:SI 1 "s_register_operand")))]
5093 (define_insn "*arm_one_cmplsi2"
5094 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5095 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5098 [(set_attr "predicable" "yes")
5099 (set_attr "predicable_short_it" "yes,no")
5100 (set_attr "arch" "t2,*")
5101 (set_attr "length" "4")
5102 (set_attr "type" "mvn_reg")]
5105 (define_insn "*notsi_compare0"
5106 [(set (reg:CC_NOOV CC_REGNUM)
5107 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5109 (set (match_operand:SI 0 "s_register_operand" "=r")
5110 (not:SI (match_dup 1)))]
5113 [(set_attr "conds" "set")
5114 (set_attr "type" "mvn_reg")]
5117 (define_insn "*notsi_compare0_scratch"
5118 [(set (reg:CC_NOOV CC_REGNUM)
5119 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5121 (clobber (match_scratch:SI 0 "=r"))]
5124 [(set_attr "conds" "set")
5125 (set_attr "type" "mvn_reg")]
5128 ;; Fixed <--> Floating conversion insns
5130 (define_expand "floatsihf2"
5131 [(set (match_operand:HF 0 "general_operand")
5132 (float:HF (match_operand:SI 1 "general_operand")))]
5136 rtx op1 = gen_reg_rtx (SFmode);
5137 expand_float (op1, operands[1], 0);
5138 op1 = convert_to_mode (HFmode, op1, 0);
5139 emit_move_insn (operands[0], op1);
5144 (define_expand "floatdihf2"
5145 [(set (match_operand:HF 0 "general_operand")
5146 (float:HF (match_operand:DI 1 "general_operand")))]
5150 rtx op1 = gen_reg_rtx (SFmode);
5151 expand_float (op1, operands[1], 0);
5152 op1 = convert_to_mode (HFmode, op1, 0);
5153 emit_move_insn (operands[0], op1);
5158 (define_expand "floatsisf2"
5159 [(set (match_operand:SF 0 "s_register_operand")
5160 (float:SF (match_operand:SI 1 "s_register_operand")))]
5161 "TARGET_32BIT && TARGET_HARD_FLOAT"
5165 (define_expand "floatsidf2"
5166 [(set (match_operand:DF 0 "s_register_operand")
5167 (float:DF (match_operand:SI 1 "s_register_operand")))]
5168 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5172 (define_expand "fix_trunchfsi2"
5173 [(set (match_operand:SI 0 "general_operand")
5174 (fix:SI (fix:HF (match_operand:HF 1 "general_operand"))))]
5178 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5179 expand_fix (operands[0], op1, 0);
5184 (define_expand "fix_trunchfdi2"
5185 [(set (match_operand:DI 0 "general_operand")
5186 (fix:DI (fix:HF (match_operand:HF 1 "general_operand"))))]
5190 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5191 expand_fix (operands[0], op1, 0);
5196 (define_expand "fix_truncsfsi2"
5197 [(set (match_operand:SI 0 "s_register_operand")
5198 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"))))]
5199 "TARGET_32BIT && TARGET_HARD_FLOAT"
5203 (define_expand "fix_truncdfsi2"
5204 [(set (match_operand:SI 0 "s_register_operand")
5205 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"))))]
5206 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5212 (define_expand "truncdfsf2"
5213 [(set (match_operand:SF 0 "s_register_operand")
5215 (match_operand:DF 1 "s_register_operand")))]
5216 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5220 ;; DFmode to HFmode conversions on targets without a single-step hardware
5221 ;; instruction for it would have to go through SFmode. This is dangerous
5222 ;; as it introduces double rounding.
5224 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5225 ;; a single-step instruction.
5227 (define_expand "truncdfhf2"
5228 [(set (match_operand:HF 0 "s_register_operand")
5230 (match_operand:DF 1 "s_register_operand")))]
5231 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5232 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5234 /* We don't have a direct instruction for this, so we must be in
5235 an unsafe math mode, and going via SFmode. */
5237 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5240 op1 = convert_to_mode (SFmode, operands[1], 0);
5241 op1 = convert_to_mode (HFmode, op1, 0);
5242 emit_move_insn (operands[0], op1);
5245 /* Otherwise, we will pick this up as a single instruction with
5246 no intermediary rounding. */
5250 ;; Zero and sign extension instructions.
5252 (define_insn "zero_extend<mode>di2"
5253 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5254 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5255 "<qhs_zextenddi_cstr>")))]
5256 "TARGET_32BIT <qhs_zextenddi_cond>"
5258 [(set_attr "length" "8,4,8,8")
5259 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5260 (set_attr "ce_count" "2")
5261 (set_attr "predicable" "yes")
5262 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5265 (define_insn "extend<mode>di2"
5266 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5267 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5268 "<qhs_extenddi_cstr>")))]
5269 "TARGET_32BIT <qhs_sextenddi_cond>"
5271 [(set_attr "length" "8,4,8,8,8")
5272 (set_attr "ce_count" "2")
5273 (set_attr "shift" "1")
5274 (set_attr "predicable" "yes")
5275 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5276 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5279 ;; Splits for all extensions to DImode
5281 [(set (match_operand:DI 0 "s_register_operand" "")
5282 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5283 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5284 [(set (match_dup 0) (match_dup 1))]
5286 rtx lo_part = gen_lowpart (SImode, operands[0]);
5287 machine_mode src_mode = GET_MODE (operands[1]);
5289 if (REG_P (operands[0])
5290 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5291 emit_clobber (operands[0]);
5292 if (!REG_P (lo_part) || src_mode != SImode
5293 || !rtx_equal_p (lo_part, operands[1]))
5295 if (src_mode == SImode)
5296 emit_move_insn (lo_part, operands[1]);
5298 emit_insn (gen_rtx_SET (lo_part,
5299 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5300 operands[1] = lo_part;
5302 operands[0] = gen_highpart (SImode, operands[0]);
5303 operands[1] = const0_rtx;
5307 [(set (match_operand:DI 0 "s_register_operand" "")
5308 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5309 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5310 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5312 rtx lo_part = gen_lowpart (SImode, operands[0]);
5313 machine_mode src_mode = GET_MODE (operands[1]);
5315 if (REG_P (operands[0])
5316 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5317 emit_clobber (operands[0]);
5319 if (!REG_P (lo_part) || src_mode != SImode
5320 || !rtx_equal_p (lo_part, operands[1]))
5322 if (src_mode == SImode)
5323 emit_move_insn (lo_part, operands[1]);
5325 emit_insn (gen_rtx_SET (lo_part,
5326 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5327 operands[1] = lo_part;
5329 operands[0] = gen_highpart (SImode, operands[0]);
5332 (define_expand "zero_extendhisi2"
5333 [(set (match_operand:SI 0 "s_register_operand")
5334 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
5337 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5339 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5342 if (!arm_arch6 && !MEM_P (operands[1]))
5344 rtx t = gen_lowpart (SImode, operands[1]);
5345 rtx tmp = gen_reg_rtx (SImode);
5346 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5347 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5353 [(set (match_operand:SI 0 "s_register_operand" "")
5354 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5355 "!TARGET_THUMB2 && !arm_arch6"
5356 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5357 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5359 operands[2] = gen_lowpart (SImode, operands[1]);
5362 (define_insn "*arm_zero_extendhisi2"
5363 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5364 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5365 "TARGET_ARM && arm_arch4 && !arm_arch6"
5369 [(set_attr "type" "alu_shift_reg,load_byte")
5370 (set_attr "predicable" "yes")]
5373 (define_insn "*arm_zero_extendhisi2_v6"
5374 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5375 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5376 "TARGET_ARM && arm_arch6"
5380 [(set_attr "predicable" "yes")
5381 (set_attr "type" "extend,load_byte")]
5384 (define_insn "*arm_zero_extendhisi2addsi"
5385 [(set (match_operand:SI 0 "s_register_operand" "=r")
5386 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5387 (match_operand:SI 2 "s_register_operand" "r")))]
5389 "uxtah%?\\t%0, %2, %1"
5390 [(set_attr "type" "alu_shift_reg")
5391 (set_attr "predicable" "yes")]
5394 (define_expand "zero_extendqisi2"
5395 [(set (match_operand:SI 0 "s_register_operand")
5396 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
5399 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5401 emit_insn (gen_andsi3 (operands[0],
5402 gen_lowpart (SImode, operands[1]),
5406 if (!arm_arch6 && !MEM_P (operands[1]))
5408 rtx t = gen_lowpart (SImode, operands[1]);
5409 rtx tmp = gen_reg_rtx (SImode);
5410 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5411 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5417 [(set (match_operand:SI 0 "s_register_operand" "")
5418 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5420 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5421 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5423 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5426 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5431 (define_insn "*arm_zero_extendqisi2"
5432 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5433 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5434 "TARGET_ARM && !arm_arch6"
5437 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5438 [(set_attr "length" "8,4")
5439 (set_attr "type" "alu_shift_reg,load_byte")
5440 (set_attr "predicable" "yes")]
5443 (define_insn "*arm_zero_extendqisi2_v6"
5444 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5445 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5446 "TARGET_ARM && arm_arch6"
5449 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5450 [(set_attr "type" "extend,load_byte")
5451 (set_attr "predicable" "yes")]
5454 (define_insn "*arm_zero_extendqisi2addsi"
5455 [(set (match_operand:SI 0 "s_register_operand" "=r")
5456 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5457 (match_operand:SI 2 "s_register_operand" "r")))]
5459 "uxtab%?\\t%0, %2, %1"
5460 [(set_attr "predicable" "yes")
5461 (set_attr "type" "alu_shift_reg")]
5465 [(set (match_operand:SI 0 "s_register_operand" "")
5466 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5467 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5468 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5469 [(set (match_dup 2) (match_dup 1))
5470 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5475 [(set (match_operand:SI 0 "s_register_operand" "")
5476 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5477 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5478 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5479 [(set (match_dup 2) (match_dup 1))
5480 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5486 [(set (match_operand:SI 0 "s_register_operand" "")
5487 (IOR_XOR:SI (and:SI (ashift:SI
5488 (match_operand:SI 1 "s_register_operand" "")
5489 (match_operand:SI 2 "const_int_operand" ""))
5490 (match_operand:SI 3 "const_int_operand" ""))
5492 (match_operator 5 "subreg_lowpart_operator"
5493 [(match_operand:SI 4 "s_register_operand" "")]))))]
5495 && (UINTVAL (operands[3])
5496 == (GET_MODE_MASK (GET_MODE (operands[5]))
5497 & (GET_MODE_MASK (GET_MODE (operands[5]))
5498 << (INTVAL (operands[2])))))"
5499 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5501 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5502 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5505 (define_insn "*compareqi_eq0"
5506 [(set (reg:CC_Z CC_REGNUM)
5507 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5511 [(set_attr "conds" "set")
5512 (set_attr "predicable" "yes")
5513 (set_attr "type" "logic_imm")]
5516 (define_expand "extendhisi2"
5517 [(set (match_operand:SI 0 "s_register_operand")
5518 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
5523 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5526 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5528 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5532 if (!arm_arch6 && !MEM_P (operands[1]))
5534 rtx t = gen_lowpart (SImode, operands[1]);
5535 rtx tmp = gen_reg_rtx (SImode);
5536 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5537 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5544 [(set (match_operand:SI 0 "register_operand" "")
5545 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5546 (clobber (match_scratch:SI 2 ""))])]
5548 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5549 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5551 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5554 ;; This pattern will only be used when ldsh is not available
5555 (define_expand "extendhisi2_mem"
5556 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5558 (zero_extend:SI (match_dup 7)))
5559 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5560 (set (match_operand:SI 0 "" "")
5561 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5566 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5568 mem1 = change_address (operands[1], QImode, addr);
5569 mem2 = change_address (operands[1], QImode,
5570 plus_constant (Pmode, addr, 1));
5571 operands[0] = gen_lowpart (SImode, operands[0]);
5573 operands[2] = gen_reg_rtx (SImode);
5574 operands[3] = gen_reg_rtx (SImode);
5575 operands[6] = gen_reg_rtx (SImode);
5578 if (BYTES_BIG_ENDIAN)
5580 operands[4] = operands[2];
5581 operands[5] = operands[3];
5585 operands[4] = operands[3];
5586 operands[5] = operands[2];
5592 [(set (match_operand:SI 0 "register_operand" "")
5593 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5595 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5596 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5598 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5601 (define_insn "*arm_extendhisi2"
5602 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5603 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5604 "TARGET_ARM && arm_arch4 && !arm_arch6"
5608 [(set_attr "length" "8,4")
5609 (set_attr "type" "alu_shift_reg,load_byte")
5610 (set_attr "predicable" "yes")]
5613 ;; ??? Check Thumb-2 pool range
5614 (define_insn "*arm_extendhisi2_v6"
5615 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5616 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5617 "TARGET_32BIT && arm_arch6"
5621 [(set_attr "type" "extend,load_byte")
5622 (set_attr "predicable" "yes")]
5625 (define_insn "*arm_extendhisi2addsi"
5626 [(set (match_operand:SI 0 "s_register_operand" "=r")
5627 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5628 (match_operand:SI 2 "s_register_operand" "r")))]
5630 "sxtah%?\\t%0, %2, %1"
5631 [(set_attr "type" "alu_shift_reg")]
5634 (define_expand "extendqihi2"
5636 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op")
5638 (set (match_operand:HI 0 "s_register_operand")
5639 (ashiftrt:SI (match_dup 2)
5644 if (arm_arch4 && MEM_P (operands[1]))
5646 emit_insn (gen_rtx_SET (operands[0],
5647 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5650 if (!s_register_operand (operands[1], QImode))
5651 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5652 operands[0] = gen_lowpart (SImode, operands[0]);
5653 operands[1] = gen_lowpart (SImode, operands[1]);
5654 operands[2] = gen_reg_rtx (SImode);
5658 (define_insn "*arm_extendqihi_insn"
5659 [(set (match_operand:HI 0 "s_register_operand" "=r")
5660 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5661 "TARGET_ARM && arm_arch4"
5663 [(set_attr "type" "load_byte")
5664 (set_attr "predicable" "yes")]
5667 (define_expand "extendqisi2"
5668 [(set (match_operand:SI 0 "s_register_operand")
5669 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op")))]
5672 if (!arm_arch4 && MEM_P (operands[1]))
5673 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5675 if (!arm_arch6 && !MEM_P (operands[1]))
5677 rtx t = gen_lowpart (SImode, operands[1]);
5678 rtx tmp = gen_reg_rtx (SImode);
5679 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5680 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5686 [(set (match_operand:SI 0 "register_operand" "")
5687 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5689 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5690 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5692 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5695 (define_insn "*arm_extendqisi"
5696 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5697 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5698 "TARGET_ARM && arm_arch4 && !arm_arch6"
5702 [(set_attr "length" "8,4")
5703 (set_attr "type" "alu_shift_reg,load_byte")
5704 (set_attr "predicable" "yes")]
5707 (define_insn "*arm_extendqisi_v6"
5708 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5710 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5711 "TARGET_ARM && arm_arch6"
5715 [(set_attr "type" "extend,load_byte")
5716 (set_attr "predicable" "yes")]
5719 (define_insn "*arm_extendqisi2addsi"
5720 [(set (match_operand:SI 0 "s_register_operand" "=r")
5721 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5722 (match_operand:SI 2 "s_register_operand" "r")))]
5724 "sxtab%?\\t%0, %2, %1"
5725 [(set_attr "type" "alu_shift_reg")
5726 (set_attr "predicable" "yes")]
5729 (define_expand "extendsfdf2"
5730 [(set (match_operand:DF 0 "s_register_operand")
5731 (float_extend:DF (match_operand:SF 1 "s_register_operand")))]
5732 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5736 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5737 ;; must go through SFmode.
5739 ;; This is always safe for an extend.
5741 (define_expand "extendhfdf2"
5742 [(set (match_operand:DF 0 "s_register_operand")
5743 (float_extend:DF (match_operand:HF 1 "s_register_operand")))]
5746 /* We don't have a direct instruction for this, so go via SFmode. */
5747 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5750 op1 = convert_to_mode (SFmode, operands[1], 0);
5751 op1 = convert_to_mode (DFmode, op1, 0);
5752 emit_insn (gen_movdf (operands[0], op1));
5755 /* Otherwise, we're done producing RTL and will pick up the correct
5756 pattern to do this with one rounding-step in a single instruction. */
5760 ;; Move insns (including loads and stores)
5762 ;; XXX Just some ideas about movti.
5763 ;; I don't think these are a good idea on the arm, there just aren't enough
5765 ;;(define_expand "loadti"
5766 ;; [(set (match_operand:TI 0 "s_register_operand")
5767 ;; (mem:TI (match_operand:SI 1 "address_operand")))]
5770 ;;(define_expand "storeti"
5771 ;; [(set (mem:TI (match_operand:TI 0 "address_operand"))
5772 ;; (match_operand:TI 1 "s_register_operand"))]
5775 ;;(define_expand "movti"
5776 ;; [(set (match_operand:TI 0 "general_operand")
5777 ;; (match_operand:TI 1 "general_operand"))]
5783 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5784 ;; operands[1] = copy_to_reg (operands[1]);
5785 ;; if (MEM_P (operands[0]))
5786 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5787 ;; else if (MEM_P (operands[1]))
5788 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5792 ;; emit_insn (insn);
5796 ;; Recognize garbage generated above.
5799 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5800 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5804 ;; register mem = (which_alternative < 3);
5805 ;; register const char *template;
5807 ;; operands[mem] = XEXP (operands[mem], 0);
5808 ;; switch (which_alternative)
5810 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5811 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5812 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5813 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5814 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5815 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5817 ;; output_asm_insn (template, operands);
5821 (define_expand "movdi"
5822 [(set (match_operand:DI 0 "general_operand")
5823 (match_operand:DI 1 "general_operand"))]
5826 if (can_create_pseudo_p ())
5828 if (!REG_P (operands[0]))
5829 operands[1] = force_reg (DImode, operands[1]);
5831 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5832 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5834 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5835 when expanding function calls. */
5836 gcc_assert (can_create_pseudo_p ());
5837 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5839 /* Perform load into legal reg pair first, then move. */
5840 rtx reg = gen_reg_rtx (DImode);
5841 emit_insn (gen_movdi (reg, operands[1]));
5844 emit_move_insn (gen_lowpart (SImode, operands[0]),
5845 gen_lowpart (SImode, operands[1]));
5846 emit_move_insn (gen_highpart (SImode, operands[0]),
5847 gen_highpart (SImode, operands[1]));
5850 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5851 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5853 /* Avoid STRD's from an odd-numbered register pair in ARM state
5854 when expanding function prologue. */
5855 gcc_assert (can_create_pseudo_p ());
5856 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5857 ? gen_reg_rtx (DImode)
5859 emit_move_insn (gen_lowpart (SImode, split_dest),
5860 gen_lowpart (SImode, operands[1]));
5861 emit_move_insn (gen_highpart (SImode, split_dest),
5862 gen_highpart (SImode, operands[1]));
5863 if (split_dest != operands[0])
5864 emit_insn (gen_movdi (operands[0], split_dest));
5870 (define_insn "*arm_movdi"
5871 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
5872 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
5874 && !(TARGET_HARD_FLOAT)
5876 && ( register_operand (operands[0], DImode)
5877 || register_operand (operands[1], DImode))"
5879 switch (which_alternative)
5886 /* Cannot load it directly, split to load it via MOV / MOVT. */
5887 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
5891 return output_move_double (operands, true, NULL);
5894 [(set_attr "length" "8,12,16,8,8")
5895 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5896 (set_attr "arm_pool_range" "*,*,*,1020,*")
5897 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5898 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5899 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5903 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5904 (match_operand:ANY64 1 "immediate_operand" ""))]
5907 && (arm_disable_literal_pool
5908 || (arm_const_double_inline_cost (operands[1])
5909 <= arm_max_const_double_inline_cost ()))"
5912 arm_split_constant (SET, SImode, curr_insn,
5913 INTVAL (gen_lowpart (SImode, operands[1])),
5914 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5915 arm_split_constant (SET, SImode, curr_insn,
5916 INTVAL (gen_highpart_mode (SImode,
5917 GET_MODE (operands[0]),
5919 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5924 ; If optimizing for size, or if we have load delay slots, then
5925 ; we want to split the constant into two separate operations.
5926 ; In both cases this may split a trivial part into a single data op
5927 ; leaving a single complex constant to load. We can also get longer
5928 ; offsets in a LDR which means we get better chances of sharing the pool
5929 ; entries. Finally, we can normally do a better job of scheduling
5930 ; LDR instructions than we can with LDM.
5931 ; This pattern will only match if the one above did not.
5933 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5934 (match_operand:ANY64 1 "const_double_operand" ""))]
5935 "TARGET_ARM && reload_completed
5936 && arm_const_double_by_parts (operands[1])"
5937 [(set (match_dup 0) (match_dup 1))
5938 (set (match_dup 2) (match_dup 3))]
5940 operands[2] = gen_highpart (SImode, operands[0]);
5941 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5943 operands[0] = gen_lowpart (SImode, operands[0]);
5944 operands[1] = gen_lowpart (SImode, operands[1]);
5949 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5950 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5951 "TARGET_EITHER && reload_completed"
5952 [(set (match_dup 0) (match_dup 1))
5953 (set (match_dup 2) (match_dup 3))]
5955 operands[2] = gen_highpart (SImode, operands[0]);
5956 operands[3] = gen_highpart (SImode, operands[1]);
5957 operands[0] = gen_lowpart (SImode, operands[0]);
5958 operands[1] = gen_lowpart (SImode, operands[1]);
5960 /* Handle a partial overlap. */
5961 if (rtx_equal_p (operands[0], operands[3]))
5963 rtx tmp0 = operands[0];
5964 rtx tmp1 = operands[1];
5966 operands[0] = operands[2];
5967 operands[1] = operands[3];
5974 ;; We can't actually do base+index doubleword loads if the index and
5975 ;; destination overlap. Split here so that we at least have chance to
5978 [(set (match_operand:DI 0 "s_register_operand" "")
5979 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5980 (match_operand:SI 2 "s_register_operand" ""))))]
5982 && reg_overlap_mentioned_p (operands[0], operands[1])
5983 && reg_overlap_mentioned_p (operands[0], operands[2])"
5985 (plus:SI (match_dup 1)
5988 (mem:DI (match_dup 4)))]
5990 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5994 (define_expand "movsi"
5995 [(set (match_operand:SI 0 "general_operand")
5996 (match_operand:SI 1 "general_operand"))]
6000 rtx base, offset, tmp;
6002 if (TARGET_32BIT || TARGET_HAVE_MOVT)
6004 /* Everything except mem = const or mem = mem can be done easily. */
6005 if (MEM_P (operands[0]))
6006 operands[1] = force_reg (SImode, operands[1]);
6007 if (arm_general_register_operand (operands[0], SImode)
6008 && CONST_INT_P (operands[1])
6009 && !(const_ok_for_arm (INTVAL (operands[1]))
6010 || const_ok_for_arm (~INTVAL (operands[1]))))
6012 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
6014 emit_insn (gen_rtx_SET (operands[0], operands[1]));
6019 arm_split_constant (SET, SImode, NULL_RTX,
6020 INTVAL (operands[1]), operands[0], NULL_RTX,
6021 optimize && can_create_pseudo_p ());
6026 else /* Target doesn't have MOVT... */
6028 if (can_create_pseudo_p ())
6030 if (!REG_P (operands[0]))
6031 operands[1] = force_reg (SImode, operands[1]);
6035 split_const (operands[1], &base, &offset);
6036 if (INTVAL (offset) != 0
6037 && targetm.cannot_force_const_mem (SImode, operands[1]))
6039 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6040 emit_move_insn (tmp, base);
6041 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6045 tmp = can_create_pseudo_p () ? NULL_RTX : operands[0];
6047 /* Recognize the case where operand[1] is a reference to thread-local
6048 data and load its address to a register. Offsets have been split off
6050 if (arm_tls_referenced_p (operands[1]))
6051 operands[1] = legitimize_tls_address (operands[1], tmp);
6053 && (CONSTANT_P (operands[1])
6054 || symbol_mentioned_p (operands[1])
6055 || label_mentioned_p (operands[1])))
6057 legitimize_pic_address (operands[1], SImode, tmp, NULL_RTX, false);
6062 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6063 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6064 ;; so this does not matter.
6065 (define_insn "*arm_movt"
6066 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6067 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6068 (match_operand:SI 2 "general_operand" "i,i")))]
6069 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6071 movt%?\t%0, #:upper16:%c2
6072 movt\t%0, #:upper16:%c2"
6073 [(set_attr "arch" "32,v8mb")
6074 (set_attr "predicable" "yes")
6075 (set_attr "length" "4")
6076 (set_attr "type" "alu_sreg")]
6079 (define_insn "*arm_movsi_insn"
6080 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6081 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6082 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6083 && ( register_operand (operands[0], SImode)
6084 || register_operand (operands[1], SImode))"
6092 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6093 (set_attr "predicable" "yes")
6094 (set_attr "arch" "*,*,*,v6t2,*,*")
6095 (set_attr "pool_range" "*,*,*,*,4096,*")
6096 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6100 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6101 (match_operand:SI 1 "const_int_operand" ""))]
6102 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6103 && (!(const_ok_for_arm (INTVAL (operands[1]))
6104 || const_ok_for_arm (~INTVAL (operands[1]))))"
6105 [(clobber (const_int 0))]
6107 arm_split_constant (SET, SImode, NULL_RTX,
6108 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6113 ;; A normal way to do (symbol + offset) requires three instructions at least
6114 ;; (depends on how big the offset is) as below:
6115 ;; movw r0, #:lower16:g
6116 ;; movw r0, #:upper16:g
6119 ;; A better way would be:
6120 ;; movw r0, #:lower16:g+4
6121 ;; movw r0, #:upper16:g+4
6123 ;; The limitation of this way is that the length of offset should be a 16-bit
6124 ;; signed value, because current assembler only supports REL type relocation for
6125 ;; such case. If the more powerful RELA type is supported in future, we should
6126 ;; update this pattern to go with better way.
6128 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6129 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6130 (match_operand:SI 2 "const_int_operand" ""))))]
6133 && arm_disable_literal_pool
6135 && GET_CODE (operands[1]) == SYMBOL_REF"
6136 [(clobber (const_int 0))]
6138 int offset = INTVAL (operands[2]);
6140 if (offset < -0x8000 || offset > 0x7fff)
6142 arm_emit_movpair (operands[0], operands[1]);
6143 emit_insn (gen_rtx_SET (operands[0],
6144 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6148 rtx op = gen_rtx_CONST (SImode,
6149 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6150 arm_emit_movpair (operands[0], op);
6155 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6156 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6157 ;; and lo_sum would be merged back into memory load at cprop. However,
6158 ;; if the default is to prefer movt/movw rather than a load from the constant
6159 ;; pool, the performance is better.
6161 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6162 (match_operand:SI 1 "general_operand" ""))]
6163 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6164 && !target_word_relocations
6165 && !arm_tls_referenced_p (operands[1])"
6166 [(clobber (const_int 0))]
6168 arm_emit_movpair (operands[0], operands[1]);
6172 ;; When generating pic, we need to load the symbol offset into a register.
6173 ;; So that the optimizer does not confuse this with a normal symbol load
6174 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6175 ;; since that is the only type of relocation we can use.
6177 ;; Wrap calculation of the whole PIC address in a single pattern for the
6178 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6179 ;; a PIC address involves two loads from memory, so we want to CSE it
6180 ;; as often as possible.
6181 ;; This pattern will be split into one of the pic_load_addr_* patterns
6182 ;; and a move after GCSE optimizations.
6184 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6185 (define_expand "calculate_pic_address"
6186 [(set (match_operand:SI 0 "register_operand")
6187 (mem:SI (plus:SI (match_operand:SI 1 "register_operand")
6188 (unspec:SI [(match_operand:SI 2 "" "")]
6193 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6195 [(set (match_operand:SI 0 "register_operand" "")
6196 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6197 (unspec:SI [(match_operand:SI 2 "" "")]
6200 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6201 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6202 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6205 ;; operand1 is the memory address to go into
6206 ;; pic_load_addr_32bit.
6207 ;; operand2 is the PIC label to be emitted
6208 ;; from pic_add_dot_plus_eight.
6209 ;; We do this to allow hoisting of the entire insn.
6210 (define_insn_and_split "pic_load_addr_unified"
6211 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6212 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6213 (match_operand:SI 2 "" "")]
6214 UNSPEC_PIC_UNIFIED))]
6217 "&& reload_completed"
6218 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6219 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6220 (match_dup 2)] UNSPEC_PIC_BASE))]
6221 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6222 [(set_attr "type" "load_4,load_4,load_4")
6223 (set_attr "pool_range" "4096,4094,1022")
6224 (set_attr "neg_pool_range" "4084,0,0")
6225 (set_attr "arch" "a,t2,t1")
6226 (set_attr "length" "8,6,4")]
6229 ;; The rather odd constraints on the following are to force reload to leave
6230 ;; the insn alone, and to force the minipool generation pass to then move
6231 ;; the GOT symbol to memory.
6233 (define_insn "pic_load_addr_32bit"
6234 [(set (match_operand:SI 0 "s_register_operand" "=r")
6235 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6236 "TARGET_32BIT && flag_pic"
6238 [(set_attr "type" "load_4")
6239 (set (attr "pool_range")
6240 (if_then_else (eq_attr "is_thumb" "no")
6243 (set (attr "neg_pool_range")
6244 (if_then_else (eq_attr "is_thumb" "no")
6249 (define_insn "pic_load_addr_thumb1"
6250 [(set (match_operand:SI 0 "s_register_operand" "=l")
6251 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6252 "TARGET_THUMB1 && flag_pic"
6254 [(set_attr "type" "load_4")
6255 (set (attr "pool_range") (const_int 1018))]
6258 (define_insn "pic_add_dot_plus_four"
6259 [(set (match_operand:SI 0 "register_operand" "=r")
6260 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6262 (match_operand 2 "" "")]
6266 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6267 INTVAL (operands[2]));
6268 return \"add\\t%0, %|pc\";
6270 [(set_attr "length" "2")
6271 (set_attr "type" "alu_sreg")]
6274 (define_insn "pic_add_dot_plus_eight"
6275 [(set (match_operand:SI 0 "register_operand" "=r")
6276 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6278 (match_operand 2 "" "")]
6282 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6283 INTVAL (operands[2]));
6284 return \"add%?\\t%0, %|pc, %1\";
6286 [(set_attr "predicable" "yes")
6287 (set_attr "type" "alu_sreg")]
6290 (define_insn "tls_load_dot_plus_eight"
6291 [(set (match_operand:SI 0 "register_operand" "=r")
6292 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6294 (match_operand 2 "" "")]
6298 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6299 INTVAL (operands[2]));
6300 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6302 [(set_attr "predicable" "yes")
6303 (set_attr "type" "load_4")]
6306 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6307 ;; followed by a load. These sequences can be crunched down to
6308 ;; tls_load_dot_plus_eight by a peephole.
6311 [(set (match_operand:SI 0 "register_operand" "")
6312 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6314 (match_operand 1 "" "")]
6316 (set (match_operand:SI 2 "arm_general_register_operand" "")
6317 (mem:SI (match_dup 0)))]
6318 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6320 (mem:SI (unspec:SI [(match_dup 3)
6327 (define_insn "pic_offset_arm"
6328 [(set (match_operand:SI 0 "register_operand" "=r")
6329 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6330 (unspec:SI [(match_operand:SI 2 "" "X")]
6331 UNSPEC_PIC_OFFSET))))]
6332 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6333 "ldr%?\\t%0, [%1,%2]"
6334 [(set_attr "type" "load_4")]
6337 (define_expand "builtin_setjmp_receiver"
6338 [(label_ref (match_operand 0 "" ""))]
6342 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6344 if (arm_pic_register != INVALID_REGNUM)
6345 arm_load_pic_register (1UL << 3, NULL_RTX);
6349 ;; If copying one reg to another we can set the condition codes according to
6350 ;; its value. Such a move is common after a return from subroutine and the
6351 ;; result is being tested against zero.
6353 (define_insn "*movsi_compare0"
6354 [(set (reg:CC CC_REGNUM)
6355 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6357 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6362 subs%?\\t%0, %1, #0"
6363 [(set_attr "conds" "set")
6364 (set_attr "type" "alus_imm,alus_imm")]
6367 ;; Subroutine to store a half word from a register into memory.
6368 ;; Operand 0 is the source register (HImode)
6369 ;; Operand 1 is the destination address in a register (SImode)
6371 ;; In both this routine and the next, we must be careful not to spill
6372 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6373 ;; can generate unrecognizable rtl.
6375 (define_expand "storehi"
6376 [;; store the low byte
6377 (set (match_operand 1 "" "") (match_dup 3))
6378 ;; extract the high byte
6380 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6381 ;; store the high byte
6382 (set (match_dup 4) (match_dup 5))]
6386 rtx op1 = operands[1];
6387 rtx addr = XEXP (op1, 0);
6388 enum rtx_code code = GET_CODE (addr);
6390 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6392 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6394 operands[4] = adjust_address (op1, QImode, 1);
6395 operands[1] = adjust_address (operands[1], QImode, 0);
6396 operands[3] = gen_lowpart (QImode, operands[0]);
6397 operands[0] = gen_lowpart (SImode, operands[0]);
6398 operands[2] = gen_reg_rtx (SImode);
6399 operands[5] = gen_lowpart (QImode, operands[2]);
6403 (define_expand "storehi_bigend"
6404 [(set (match_dup 4) (match_dup 3))
6406 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6407 (set (match_operand 1 "" "") (match_dup 5))]
6411 rtx op1 = operands[1];
6412 rtx addr = XEXP (op1, 0);
6413 enum rtx_code code = GET_CODE (addr);
6415 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6417 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6419 operands[4] = adjust_address (op1, QImode, 1);
6420 operands[1] = adjust_address (operands[1], QImode, 0);
6421 operands[3] = gen_lowpart (QImode, operands[0]);
6422 operands[0] = gen_lowpart (SImode, operands[0]);
6423 operands[2] = gen_reg_rtx (SImode);
6424 operands[5] = gen_lowpart (QImode, operands[2]);
6428 ;; Subroutine to store a half word integer constant into memory.
6429 (define_expand "storeinthi"
6430 [(set (match_operand 0 "" "")
6431 (match_operand 1 "" ""))
6432 (set (match_dup 3) (match_dup 2))]
6436 HOST_WIDE_INT value = INTVAL (operands[1]);
6437 rtx addr = XEXP (operands[0], 0);
6438 rtx op0 = operands[0];
6439 enum rtx_code code = GET_CODE (addr);
6441 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6443 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6445 operands[1] = gen_reg_rtx (SImode);
6446 if (BYTES_BIG_ENDIAN)
6448 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6449 if ((value & 255) == ((value >> 8) & 255))
6450 operands[2] = operands[1];
6453 operands[2] = gen_reg_rtx (SImode);
6454 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6459 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6460 if ((value & 255) == ((value >> 8) & 255))
6461 operands[2] = operands[1];
6464 operands[2] = gen_reg_rtx (SImode);
6465 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6469 operands[3] = adjust_address (op0, QImode, 1);
6470 operands[0] = adjust_address (operands[0], QImode, 0);
6471 operands[2] = gen_lowpart (QImode, operands[2]);
6472 operands[1] = gen_lowpart (QImode, operands[1]);
6476 (define_expand "storehi_single_op"
6477 [(set (match_operand:HI 0 "memory_operand")
6478 (match_operand:HI 1 "general_operand"))]
6479 "TARGET_32BIT && arm_arch4"
6481 if (!s_register_operand (operands[1], HImode))
6482 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6486 (define_expand "movhi"
6487 [(set (match_operand:HI 0 "general_operand")
6488 (match_operand:HI 1 "general_operand"))]
6493 if (can_create_pseudo_p ())
6495 if (MEM_P (operands[0]))
6499 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6502 if (CONST_INT_P (operands[1]))
6503 emit_insn (gen_storeinthi (operands[0], operands[1]));
6506 if (MEM_P (operands[1]))
6507 operands[1] = force_reg (HImode, operands[1]);
6508 if (BYTES_BIG_ENDIAN)
6509 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6511 emit_insn (gen_storehi (operands[1], operands[0]));
6515 /* Sign extend a constant, and keep it in an SImode reg. */
6516 else if (CONST_INT_P (operands[1]))
6518 rtx reg = gen_reg_rtx (SImode);
6519 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6521 /* If the constant is already valid, leave it alone. */
6522 if (!const_ok_for_arm (val))
6524 /* If setting all the top bits will make the constant
6525 loadable in a single instruction, then set them.
6526 Otherwise, sign extend the number. */
6528 if (const_ok_for_arm (~(val | ~0xffff)))
6530 else if (val & 0x8000)
6534 emit_insn (gen_movsi (reg, GEN_INT (val)));
6535 operands[1] = gen_lowpart (HImode, reg);
6537 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6538 && MEM_P (operands[1]))
6540 rtx reg = gen_reg_rtx (SImode);
6542 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6543 operands[1] = gen_lowpart (HImode, reg);
6545 else if (!arm_arch4)
6547 if (MEM_P (operands[1]))
6550 rtx offset = const0_rtx;
6551 rtx reg = gen_reg_rtx (SImode);
6553 if ((REG_P (base = XEXP (operands[1], 0))
6554 || (GET_CODE (base) == PLUS
6555 && (CONST_INT_P (offset = XEXP (base, 1)))
6556 && ((INTVAL(offset) & 1) != 1)
6557 && REG_P (base = XEXP (base, 0))))
6558 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6562 new_rtx = widen_memory_access (operands[1], SImode,
6563 ((INTVAL (offset) & ~3)
6564 - INTVAL (offset)));
6565 emit_insn (gen_movsi (reg, new_rtx));
6566 if (((INTVAL (offset) & 2) != 0)
6567 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6569 rtx reg2 = gen_reg_rtx (SImode);
6571 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6576 emit_insn (gen_movhi_bytes (reg, operands[1]));
6578 operands[1] = gen_lowpart (HImode, reg);
6582 /* Handle loading a large integer during reload. */
6583 else if (CONST_INT_P (operands[1])
6584 && !const_ok_for_arm (INTVAL (operands[1]))
6585 && !const_ok_for_arm (~INTVAL (operands[1])))
6587 /* Writing a constant to memory needs a scratch, which should
6588 be handled with SECONDARY_RELOADs. */
6589 gcc_assert (REG_P (operands[0]));
6591 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6592 emit_insn (gen_movsi (operands[0], operands[1]));
6596 else if (TARGET_THUMB2)
6598 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6599 if (can_create_pseudo_p ())
6601 if (!REG_P (operands[0]))
6602 operands[1] = force_reg (HImode, operands[1]);
6603 /* Zero extend a constant, and keep it in an SImode reg. */
6604 else if (CONST_INT_P (operands[1]))
6606 rtx reg = gen_reg_rtx (SImode);
6607 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6609 emit_insn (gen_movsi (reg, GEN_INT (val)));
6610 operands[1] = gen_lowpart (HImode, reg);
6614 else /* TARGET_THUMB1 */
6616 if (can_create_pseudo_p ())
6618 if (CONST_INT_P (operands[1]))
6620 rtx reg = gen_reg_rtx (SImode);
6622 emit_insn (gen_movsi (reg, operands[1]));
6623 operands[1] = gen_lowpart (HImode, reg);
6626 /* ??? We shouldn't really get invalid addresses here, but this can
6627 happen if we are passed a SP (never OK for HImode/QImode) or
6628 virtual register (also rejected as illegitimate for HImode/QImode)
6629 relative address. */
6630 /* ??? This should perhaps be fixed elsewhere, for instance, in
6631 fixup_stack_1, by checking for other kinds of invalid addresses,
6632 e.g. a bare reference to a virtual register. This may confuse the
6633 alpha though, which must handle this case differently. */
6634 if (MEM_P (operands[0])
6635 && !memory_address_p (GET_MODE (operands[0]),
6636 XEXP (operands[0], 0)))
6638 = replace_equiv_address (operands[0],
6639 copy_to_reg (XEXP (operands[0], 0)));
6641 if (MEM_P (operands[1])
6642 && !memory_address_p (GET_MODE (operands[1]),
6643 XEXP (operands[1], 0)))
6645 = replace_equiv_address (operands[1],
6646 copy_to_reg (XEXP (operands[1], 0)));
6648 if (MEM_P (operands[1]) && optimize > 0)
6650 rtx reg = gen_reg_rtx (SImode);
6652 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6653 operands[1] = gen_lowpart (HImode, reg);
6656 if (MEM_P (operands[0]))
6657 operands[1] = force_reg (HImode, operands[1]);
6659 else if (CONST_INT_P (operands[1])
6660 && !satisfies_constraint_I (operands[1]))
6662 /* Handle loading a large integer during reload. */
6664 /* Writing a constant to memory needs a scratch, which should
6665 be handled with SECONDARY_RELOADs. */
6666 gcc_assert (REG_P (operands[0]));
6668 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6669 emit_insn (gen_movsi (operands[0], operands[1]));
6676 (define_expand "movhi_bytes"
6677 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6679 (zero_extend:SI (match_dup 6)))
6680 (set (match_operand:SI 0 "" "")
6681 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6686 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6688 mem1 = change_address (operands[1], QImode, addr);
6689 mem2 = change_address (operands[1], QImode,
6690 plus_constant (Pmode, addr, 1));
6691 operands[0] = gen_lowpart (SImode, operands[0]);
6693 operands[2] = gen_reg_rtx (SImode);
6694 operands[3] = gen_reg_rtx (SImode);
6697 if (BYTES_BIG_ENDIAN)
6699 operands[4] = operands[2];
6700 operands[5] = operands[3];
6704 operands[4] = operands[3];
6705 operands[5] = operands[2];
6710 (define_expand "movhi_bigend"
6712 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand") 0)
6715 (ashiftrt:SI (match_dup 2) (const_int 16)))
6716 (set (match_operand:HI 0 "s_register_operand")
6720 operands[2] = gen_reg_rtx (SImode);
6721 operands[3] = gen_reg_rtx (SImode);
6722 operands[4] = gen_lowpart (HImode, operands[3]);
6726 ;; Pattern to recognize insn generated default case above
6727 (define_insn "*movhi_insn_arch4"
6728 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6729 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6731 && arm_arch4 && !TARGET_HARD_FLOAT
6732 && (register_operand (operands[0], HImode)
6733 || register_operand (operands[1], HImode))"
6735 mov%?\\t%0, %1\\t%@ movhi
6736 mvn%?\\t%0, #%B1\\t%@ movhi
6737 movw%?\\t%0, %L1\\t%@ movhi
6738 strh%?\\t%1, %0\\t%@ movhi
6739 ldrh%?\\t%0, %1\\t%@ movhi"
6740 [(set_attr "predicable" "yes")
6741 (set_attr "pool_range" "*,*,*,*,256")
6742 (set_attr "neg_pool_range" "*,*,*,*,244")
6743 (set_attr "arch" "*,*,v6t2,*,*")
6744 (set_attr_alternative "type"
6745 [(if_then_else (match_operand 1 "const_int_operand" "")
6746 (const_string "mov_imm" )
6747 (const_string "mov_reg"))
6748 (const_string "mvn_imm")
6749 (const_string "mov_imm")
6750 (const_string "store_4")
6751 (const_string "load_4")])]
6754 (define_insn "*movhi_bytes"
6755 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6756 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6757 "TARGET_ARM && !TARGET_HARD_FLOAT"
6759 mov%?\\t%0, %1\\t%@ movhi
6760 mov%?\\t%0, %1\\t%@ movhi
6761 mvn%?\\t%0, #%B1\\t%@ movhi"
6762 [(set_attr "predicable" "yes")
6763 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6766 ;; We use a DImode scratch because we may occasionally need an additional
6767 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6768 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6769 ;; The reload_in<m> and reload_out<m> patterns require special constraints
6770 ;; to be correctly handled in default_secondary_reload function.
6771 (define_expand "reload_outhi"
6772 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6773 (match_operand:HI 1 "s_register_operand" "r")
6774 (match_operand:DI 2 "s_register_operand" "=&l")])]
6777 arm_reload_out_hi (operands);
6779 thumb_reload_out_hi (operands);
6784 (define_expand "reload_inhi"
6785 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6786 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6787 (match_operand:DI 2 "s_register_operand" "=&r")])]
6791 arm_reload_in_hi (operands);
6793 thumb_reload_out_hi (operands);
6797 (define_expand "movqi"
6798 [(set (match_operand:QI 0 "general_operand")
6799 (match_operand:QI 1 "general_operand"))]
6802 /* Everything except mem = const or mem = mem can be done easily */
6804 if (can_create_pseudo_p ())
6806 if (CONST_INT_P (operands[1]))
6808 rtx reg = gen_reg_rtx (SImode);
6810 /* For thumb we want an unsigned immediate, then we are more likely
6811 to be able to use a movs insn. */
6813 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6815 emit_insn (gen_movsi (reg, operands[1]));
6816 operands[1] = gen_lowpart (QImode, reg);
6821 /* ??? We shouldn't really get invalid addresses here, but this can
6822 happen if we are passed a SP (never OK for HImode/QImode) or
6823 virtual register (also rejected as illegitimate for HImode/QImode)
6824 relative address. */
6825 /* ??? This should perhaps be fixed elsewhere, for instance, in
6826 fixup_stack_1, by checking for other kinds of invalid addresses,
6827 e.g. a bare reference to a virtual register. This may confuse the
6828 alpha though, which must handle this case differently. */
6829 if (MEM_P (operands[0])
6830 && !memory_address_p (GET_MODE (operands[0]),
6831 XEXP (operands[0], 0)))
6833 = replace_equiv_address (operands[0],
6834 copy_to_reg (XEXP (operands[0], 0)));
6835 if (MEM_P (operands[1])
6836 && !memory_address_p (GET_MODE (operands[1]),
6837 XEXP (operands[1], 0)))
6839 = replace_equiv_address (operands[1],
6840 copy_to_reg (XEXP (operands[1], 0)));
6843 if (MEM_P (operands[1]) && optimize > 0)
6845 rtx reg = gen_reg_rtx (SImode);
6847 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6848 operands[1] = gen_lowpart (QImode, reg);
6851 if (MEM_P (operands[0]))
6852 operands[1] = force_reg (QImode, operands[1]);
6854 else if (TARGET_THUMB
6855 && CONST_INT_P (operands[1])
6856 && !satisfies_constraint_I (operands[1]))
6858 /* Handle loading a large integer during reload. */
6860 /* Writing a constant to memory needs a scratch, which should
6861 be handled with SECONDARY_RELOADs. */
6862 gcc_assert (REG_P (operands[0]));
6864 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6865 emit_insn (gen_movsi (operands[0], operands[1]));
6871 (define_insn "*arm_movqi_insn"
6872 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6873 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6875 && ( register_operand (operands[0], QImode)
6876 || register_operand (operands[1], QImode))"
6887 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6888 (set_attr "predicable" "yes")
6889 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6890 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6891 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6895 (define_expand "movhf"
6896 [(set (match_operand:HF 0 "general_operand")
6897 (match_operand:HF 1 "general_operand"))]
6902 if (MEM_P (operands[0]))
6903 operands[1] = force_reg (HFmode, operands[1]);
6905 else /* TARGET_THUMB1 */
6907 if (can_create_pseudo_p ())
6909 if (!REG_P (operands[0]))
6910 operands[1] = force_reg (HFmode, operands[1]);
6916 (define_insn "*arm32_movhf"
6917 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6918 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6919 "TARGET_32BIT && !TARGET_HARD_FLOAT
6920 && ( s_register_operand (operands[0], HFmode)
6921 || s_register_operand (operands[1], HFmode))"
6923 switch (which_alternative)
6925 case 0: /* ARM register from memory */
6926 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6927 case 1: /* memory from ARM register */
6928 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6929 case 2: /* ARM register from ARM register */
6930 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6931 case 3: /* ARM register from constant */
6936 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6938 ops[0] = operands[0];
6939 ops[1] = GEN_INT (bits);
6940 ops[2] = GEN_INT (bits & 0xff00);
6941 ops[3] = GEN_INT (bits & 0x00ff);
6943 if (arm_arch_thumb2)
6944 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6946 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6953 [(set_attr "conds" "unconditional")
6954 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6955 (set_attr "length" "4,4,4,8")
6956 (set_attr "predicable" "yes")]
6959 (define_expand "movsf"
6960 [(set (match_operand:SF 0 "general_operand")
6961 (match_operand:SF 1 "general_operand"))]
6966 if (MEM_P (operands[0]))
6967 operands[1] = force_reg (SFmode, operands[1]);
6969 else /* TARGET_THUMB1 */
6971 if (can_create_pseudo_p ())
6973 if (!REG_P (operands[0]))
6974 operands[1] = force_reg (SFmode, operands[1]);
6978 /* Cannot load it directly, generate a load with clobber so that it can be
6979 loaded via GPR with MOV / MOVT. */
6980 if (arm_disable_literal_pool
6981 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6982 && CONST_DOUBLE_P (operands[1])
6983 && TARGET_HARD_FLOAT
6984 && !vfp3_const_double_rtx (operands[1]))
6986 rtx clobreg = gen_reg_rtx (SFmode);
6987 emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
6994 ;; Transform a floating-point move of a constant into a core register into
6995 ;; an SImode operation.
6997 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6998 (match_operand:SF 1 "immediate_operand" ""))]
7001 && CONST_DOUBLE_P (operands[1])"
7002 [(set (match_dup 2) (match_dup 3))]
7004 operands[2] = gen_lowpart (SImode, operands[0]);
7005 operands[3] = gen_lowpart (SImode, operands[1]);
7006 if (operands[2] == 0 || operands[3] == 0)
7011 (define_insn "*arm_movsf_soft_insn"
7012 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7013 (match_operand:SF 1 "general_operand" "r,mE,r"))]
7015 && TARGET_SOFT_FLOAT
7016 && (!MEM_P (operands[0])
7017 || register_operand (operands[1], SFmode))"
7019 switch (which_alternative)
7021 case 0: return \"mov%?\\t%0, %1\";
7023 /* Cannot load it directly, split to load it via MOV / MOVT. */
7024 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7026 return \"ldr%?\\t%0, %1\\t%@ float\";
7027 case 2: return \"str%?\\t%1, %0\\t%@ float\";
7028 default: gcc_unreachable ();
7031 [(set_attr "predicable" "yes")
7032 (set_attr "type" "mov_reg,load_4,store_4")
7033 (set_attr "arm_pool_range" "*,4096,*")
7034 (set_attr "thumb2_pool_range" "*,4094,*")
7035 (set_attr "arm_neg_pool_range" "*,4084,*")
7036 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7039 ;; Splitter for the above.
7041 [(set (match_operand:SF 0 "s_register_operand")
7042 (match_operand:SF 1 "const_double_operand"))]
7043 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7047 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
7048 rtx cst = gen_int_mode (buf, SImode);
7049 emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
7054 (define_expand "movdf"
7055 [(set (match_operand:DF 0 "general_operand")
7056 (match_operand:DF 1 "general_operand"))]
7061 if (MEM_P (operands[0]))
7062 operands[1] = force_reg (DFmode, operands[1]);
7064 else /* TARGET_THUMB */
7066 if (can_create_pseudo_p ())
7068 if (!REG_P (operands[0]))
7069 operands[1] = force_reg (DFmode, operands[1]);
7073 /* Cannot load it directly, generate a load with clobber so that it can be
7074 loaded via GPR with MOV / MOVT. */
7075 if (arm_disable_literal_pool
7076 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
7077 && CONSTANT_P (operands[1])
7078 && TARGET_HARD_FLOAT
7079 && !arm_const_double_rtx (operands[1])
7080 && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
7082 rtx clobreg = gen_reg_rtx (DFmode);
7083 emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
7090 ;; Reloading a df mode value stored in integer regs to memory can require a
7092 ;; Another reload_out<m> pattern that requires special constraints.
7093 (define_expand "reload_outdf"
7094 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7095 (match_operand:DF 1 "s_register_operand" "r")
7096 (match_operand:SI 2 "s_register_operand" "=&r")]
7100 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7103 operands[2] = XEXP (operands[0], 0);
7104 else if (code == POST_INC || code == PRE_DEC)
7106 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7107 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7108 emit_insn (gen_movdi (operands[0], operands[1]));
7111 else if (code == PRE_INC)
7113 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7115 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7118 else if (code == POST_DEC)
7119 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7121 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7122 XEXP (XEXP (operands[0], 0), 1)));
7124 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7127 if (code == POST_DEC)
7128 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7134 (define_insn "*movdf_soft_insn"
7135 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
7136 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
7137 "TARGET_32BIT && TARGET_SOFT_FLOAT
7138 && ( register_operand (operands[0], DFmode)
7139 || register_operand (operands[1], DFmode))"
7141 switch (which_alternative)
7148 /* Cannot load it directly, split to load it via MOV / MOVT. */
7149 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7153 return output_move_double (operands, true, NULL);
7156 [(set_attr "length" "8,12,16,8,8")
7157 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7158 (set_attr "arm_pool_range" "*,*,*,1020,*")
7159 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7160 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7161 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7164 ;; Splitter for the above.
7166 [(set (match_operand:DF 0 "s_register_operand")
7167 (match_operand:DF 1 "const_double_operand"))]
7168 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7172 int order = BYTES_BIG_ENDIAN ? 1 : 0;
7173 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
7174 unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
7175 ival |= (zext_hwi (buf[1 - order], 32) << 32);
7176 rtx cst = gen_int_mode (ival, DImode);
7177 emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
7183 ;; load- and store-multiple insns
7184 ;; The arm can load/store any set of registers, provided that they are in
7185 ;; ascending order, but these expanders assume a contiguous set.
7187 (define_expand "load_multiple"
7188 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7189 (match_operand:SI 1 "" ""))
7190 (use (match_operand:SI 2 "" ""))])]
7193 HOST_WIDE_INT offset = 0;
7195 /* Support only fixed point registers. */
7196 if (!CONST_INT_P (operands[2])
7197 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7198 || INTVAL (operands[2]) < 2
7199 || !MEM_P (operands[1])
7200 || !REG_P (operands[0])
7201 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7202 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7206 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7207 INTVAL (operands[2]),
7208 force_reg (SImode, XEXP (operands[1], 0)),
7209 FALSE, operands[1], &offset);
7212 (define_expand "store_multiple"
7213 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7214 (match_operand:SI 1 "" ""))
7215 (use (match_operand:SI 2 "" ""))])]
7218 HOST_WIDE_INT offset = 0;
7220 /* Support only fixed point registers. */
7221 if (!CONST_INT_P (operands[2])
7222 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7223 || INTVAL (operands[2]) < 2
7224 || !REG_P (operands[1])
7225 || !MEM_P (operands[0])
7226 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7227 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7231 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7232 INTVAL (operands[2]),
7233 force_reg (SImode, XEXP (operands[0], 0)),
7234 FALSE, operands[0], &offset);
7238 (define_expand "setmemsi"
7239 [(match_operand:BLK 0 "general_operand")
7240 (match_operand:SI 1 "const_int_operand")
7241 (match_operand:SI 2 "const_int_operand")
7242 (match_operand:SI 3 "const_int_operand")]
7245 if (arm_gen_setmem (operands))
7252 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7253 ;; We could let this apply for blocks of less than this, but it clobbers so
7254 ;; many registers that there is then probably a better way.
7256 (define_expand "cpymemqi"
7257 [(match_operand:BLK 0 "general_operand")
7258 (match_operand:BLK 1 "general_operand")
7259 (match_operand:SI 2 "const_int_operand")
7260 (match_operand:SI 3 "const_int_operand")]
7265 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7266 && !optimize_function_for_size_p (cfun))
7268 if (gen_cpymem_ldrd_strd (operands))
7273 if (arm_gen_cpymemqi (operands))
7277 else /* TARGET_THUMB1 */
7279 if ( INTVAL (operands[3]) != 4
7280 || INTVAL (operands[2]) > 48)
7283 thumb_expand_cpymemqi (operands);
7290 ;; Compare & branch insns
7291 ;; The range calculations are based as follows:
7292 ;; For forward branches, the address calculation returns the address of
7293 ;; the next instruction. This is 2 beyond the branch instruction.
7294 ;; For backward branches, the address calculation returns the address of
7295 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7296 ;; instruction for the shortest sequence, and 4 before the branch instruction
7297 ;; if we have to jump around an unconditional branch.
7298 ;; To the basic branch range the PC offset must be added (this is +4).
7299 ;; So for forward branches we have
7300 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7301 ;; And for backward branches we have
7302 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7304 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7305 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7307 (define_expand "cbranchsi4"
7308 [(set (pc) (if_then_else
7309 (match_operator 0 "expandable_comparison_operator"
7310 [(match_operand:SI 1 "s_register_operand")
7311 (match_operand:SI 2 "nonmemory_operand")])
7312 (label_ref (match_operand 3 "" ""))
7318 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7320 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7324 if (thumb1_cmpneg_operand (operands[2], SImode))
7326 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7327 operands[3], operands[0]));
7330 if (!thumb1_cmp_operand (operands[2], SImode))
7331 operands[2] = force_reg (SImode, operands[2]);
7334 (define_expand "cbranchsf4"
7335 [(set (pc) (if_then_else
7336 (match_operator 0 "expandable_comparison_operator"
7337 [(match_operand:SF 1 "s_register_operand")
7338 (match_operand:SF 2 "vfp_compare_operand")])
7339 (label_ref (match_operand 3 "" ""))
7341 "TARGET_32BIT && TARGET_HARD_FLOAT"
7342 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7343 operands[3])); DONE;"
7346 (define_expand "cbranchdf4"
7347 [(set (pc) (if_then_else
7348 (match_operator 0 "expandable_comparison_operator"
7349 [(match_operand:DF 1 "s_register_operand")
7350 (match_operand:DF 2 "vfp_compare_operand")])
7351 (label_ref (match_operand 3 "" ""))
7353 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7354 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7355 operands[3])); DONE;"
7358 (define_expand "cbranchdi4"
7359 [(set (pc) (if_then_else
7360 (match_operator 0 "expandable_comparison_operator"
7361 [(match_operand:DI 1 "s_register_operand")
7362 (match_operand:DI 2 "cmpdi_operand")])
7363 (label_ref (match_operand 3 "" ""))
7367 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7369 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7375 ;; Comparison and test insns
7377 (define_insn "*arm_cmpsi_insn"
7378 [(set (reg:CC CC_REGNUM)
7379 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7380 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7388 [(set_attr "conds" "set")
7389 (set_attr "arch" "t2,t2,any,any,any")
7390 (set_attr "length" "2,2,4,4,4")
7391 (set_attr "predicable" "yes")
7392 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7393 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7396 (define_insn "*cmpsi_shiftsi"
7397 [(set (reg:CC CC_REGNUM)
7398 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7399 (match_operator:SI 3 "shift_operator"
7400 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7401 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7404 [(set_attr "conds" "set")
7405 (set_attr "shift" "1")
7406 (set_attr "arch" "32,a,a")
7407 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7409 (define_insn "*cmpsi_shiftsi_swp"
7410 [(set (reg:CC_SWP CC_REGNUM)
7411 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7412 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7413 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7414 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7417 [(set_attr "conds" "set")
7418 (set_attr "shift" "1")
7419 (set_attr "arch" "32,a,a")
7420 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7422 (define_insn "*arm_cmpsi_negshiftsi_si"
7423 [(set (reg:CC_Z CC_REGNUM)
7425 (neg:SI (match_operator:SI 1 "shift_operator"
7426 [(match_operand:SI 2 "s_register_operand" "r")
7427 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7428 (match_operand:SI 0 "s_register_operand" "r")))]
7431 [(set_attr "conds" "set")
7432 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7433 (const_string "alus_shift_imm")
7434 (const_string "alus_shift_reg")))
7435 (set_attr "predicable" "yes")]
7438 ;; DImode comparisons. The generic code generates branches that
7439 ;; if-conversion cannot reduce to a conditional compare, so we do
7442 (define_insn_and_split "*arm_cmpdi_insn"
7443 [(set (reg:CC_NCV CC_REGNUM)
7444 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7445 (match_operand:DI 1 "arm_di_operand" "rDi")))
7446 (clobber (match_scratch:SI 2 "=r"))]
7448 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7449 "&& reload_completed"
7450 [(set (reg:CC CC_REGNUM)
7451 (compare:CC (match_dup 0) (match_dup 1)))
7452 (parallel [(set (reg:CC CC_REGNUM)
7453 (compare:CC (match_dup 3) (match_dup 4)))
7455 (minus:SI (match_dup 5)
7456 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7458 operands[3] = gen_highpart (SImode, operands[0]);
7459 operands[0] = gen_lowpart (SImode, operands[0]);
7460 if (CONST_INT_P (operands[1]))
7462 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);
7463 if (operands[4] == const0_rtx)
7464 operands[5] = operands[3];
7466 operands[5] = gen_rtx_PLUS (SImode, operands[3],
7467 gen_int_mode (-UINTVAL (operands[4]),
7472 operands[4] = gen_highpart (SImode, operands[1]);
7473 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7475 operands[1] = gen_lowpart (SImode, operands[1]);
7476 operands[2] = gen_lowpart (SImode, operands[2]);
7478 [(set_attr "conds" "set")
7479 (set_attr "length" "8")
7480 (set_attr "type" "multiple")]
7483 (define_insn_and_split "*arm_cmpdi_unsigned"
7484 [(set (reg:CC_CZ CC_REGNUM)
7485 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7486 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7489 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7490 "&& reload_completed"
7491 [(set (reg:CC CC_REGNUM)
7492 (compare:CC (match_dup 2) (match_dup 3)))
7493 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7494 (set (reg:CC CC_REGNUM)
7495 (compare:CC (match_dup 0) (match_dup 1))))]
7497 operands[2] = gen_highpart (SImode, operands[0]);
7498 operands[0] = gen_lowpart (SImode, operands[0]);
7499 if (CONST_INT_P (operands[1]))
7500 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7502 operands[3] = gen_highpart (SImode, operands[1]);
7503 operands[1] = gen_lowpart (SImode, operands[1]);
7505 [(set_attr "conds" "set")
7506 (set_attr "enabled_for_short_it" "yes,yes,no,*")
7507 (set_attr "arch" "t2,t2,t2,a")
7508 (set_attr "length" "6,6,10,8")
7509 (set_attr "type" "multiple")]
7512 (define_insn "*arm_cmpdi_zero"
7513 [(set (reg:CC_Z CC_REGNUM)
7514 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7516 (clobber (match_scratch:SI 1 "=r"))]
7518 "orrs%?\\t%1, %Q0, %R0"
7519 [(set_attr "conds" "set")
7520 (set_attr "type" "logics_reg")]
7523 ; This insn allows redundant compares to be removed by cse, nothing should
7524 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7525 ; is deleted later on. The match_dup will match the mode here, so that
7526 ; mode changes of the condition codes aren't lost by this even though we don't
7527 ; specify what they are.
7529 (define_insn "*deleted_compare"
7530 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7532 "\\t%@ deleted compare"
7533 [(set_attr "conds" "set")
7534 (set_attr "length" "0")
7535 (set_attr "type" "no_insn")]
7539 ;; Conditional branch insns
7541 (define_expand "cbranch_cc"
7543 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7544 (match_operand 2 "" "")])
7545 (label_ref (match_operand 3 "" ""))
7548 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7549 operands[1], operands[2], NULL_RTX);
7550 operands[2] = const0_rtx;"
7554 ;; Patterns to match conditional branch insns.
7557 (define_insn "arm_cond_branch"
7559 (if_then_else (match_operator 1 "arm_comparison_operator"
7560 [(match_operand 2 "cc_register" "") (const_int 0)])
7561 (label_ref (match_operand 0 "" ""))
7565 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7567 arm_ccfsm_state += 2;
7570 return \"b%d1\\t%l0\";
7572 [(set_attr "conds" "use")
7573 (set_attr "type" "branch")
7574 (set (attr "length")
7576 (and (match_test "TARGET_THUMB2")
7577 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7578 (le (minus (match_dup 0) (pc)) (const_int 256))))
7583 (define_insn "*arm_cond_branch_reversed"
7585 (if_then_else (match_operator 1 "arm_comparison_operator"
7586 [(match_operand 2 "cc_register" "") (const_int 0)])
7588 (label_ref (match_operand 0 "" ""))))]
7591 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7593 arm_ccfsm_state += 2;
7596 return \"b%D1\\t%l0\";
7598 [(set_attr "conds" "use")
7599 (set_attr "type" "branch")
7600 (set (attr "length")
7602 (and (match_test "TARGET_THUMB2")
7603 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7604 (le (minus (match_dup 0) (pc)) (const_int 256))))
7613 (define_expand "cstore_cc"
7614 [(set (match_operand:SI 0 "s_register_operand")
7615 (match_operator:SI 1 "" [(match_operand 2 "" "")
7616 (match_operand 3 "" "")]))]
7618 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7619 operands[2], operands[3], NULL_RTX);
7620 operands[3] = const0_rtx;"
7623 (define_insn_and_split "*mov_scc"
7624 [(set (match_operand:SI 0 "s_register_operand" "=r")
7625 (match_operator:SI 1 "arm_comparison_operator_mode"
7626 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7628 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7631 (if_then_else:SI (match_dup 1)
7635 [(set_attr "conds" "use")
7636 (set_attr "length" "8")
7637 (set_attr "type" "multiple")]
7640 (define_insn_and_split "*mov_negscc"
7641 [(set (match_operand:SI 0 "s_register_operand" "=r")
7642 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7643 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7645 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7648 (if_then_else:SI (match_dup 1)
7652 operands[3] = GEN_INT (~0);
7654 [(set_attr "conds" "use")
7655 (set_attr "length" "8")
7656 (set_attr "type" "multiple")]
7659 (define_insn_and_split "*mov_notscc"
7660 [(set (match_operand:SI 0 "s_register_operand" "=r")
7661 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7662 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7664 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7667 (if_then_else:SI (match_dup 1)
7671 operands[3] = GEN_INT (~1);
7672 operands[4] = GEN_INT (~0);
7674 [(set_attr "conds" "use")
7675 (set_attr "length" "8")
7676 (set_attr "type" "multiple")]
7679 (define_expand "cstoresi4"
7680 [(set (match_operand:SI 0 "s_register_operand")
7681 (match_operator:SI 1 "expandable_comparison_operator"
7682 [(match_operand:SI 2 "s_register_operand")
7683 (match_operand:SI 3 "reg_or_int_operand")]))]
7684 "TARGET_32BIT || TARGET_THUMB1"
7686 rtx op3, scratch, scratch2;
7690 if (!arm_add_operand (operands[3], SImode))
7691 operands[3] = force_reg (SImode, operands[3]);
7692 emit_insn (gen_cstore_cc (operands[0], operands[1],
7693 operands[2], operands[3]));
7697 if (operands[3] == const0_rtx)
7699 switch (GET_CODE (operands[1]))
7702 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7706 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7710 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7711 NULL_RTX, 0, OPTAB_WIDEN);
7712 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7713 NULL_RTX, 0, OPTAB_WIDEN);
7714 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7715 operands[0], 1, OPTAB_WIDEN);
7719 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7721 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7722 NULL_RTX, 1, OPTAB_WIDEN);
7726 scratch = expand_binop (SImode, ashr_optab, operands[2],
7727 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7728 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7729 NULL_RTX, 0, OPTAB_WIDEN);
7730 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7734 /* LT is handled by generic code. No need for unsigned with 0. */
7741 switch (GET_CODE (operands[1]))
7744 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7745 NULL_RTX, 0, OPTAB_WIDEN);
7746 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7750 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7751 NULL_RTX, 0, OPTAB_WIDEN);
7752 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7756 op3 = force_reg (SImode, operands[3]);
7758 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7759 NULL_RTX, 1, OPTAB_WIDEN);
7760 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7761 NULL_RTX, 0, OPTAB_WIDEN);
7762 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7768 if (!thumb1_cmp_operand (op3, SImode))
7769 op3 = force_reg (SImode, op3);
7770 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7771 NULL_RTX, 0, OPTAB_WIDEN);
7772 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7773 NULL_RTX, 1, OPTAB_WIDEN);
7774 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7779 op3 = force_reg (SImode, operands[3]);
7780 scratch = force_reg (SImode, const0_rtx);
7781 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7787 if (!thumb1_cmp_operand (op3, SImode))
7788 op3 = force_reg (SImode, op3);
7789 scratch = force_reg (SImode, const0_rtx);
7790 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7796 if (!thumb1_cmp_operand (op3, SImode))
7797 op3 = force_reg (SImode, op3);
7798 scratch = gen_reg_rtx (SImode);
7799 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7803 op3 = force_reg (SImode, operands[3]);
7804 scratch = gen_reg_rtx (SImode);
7805 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7808 /* No good sequences for GT, LT. */
7815 (define_expand "cstorehf4"
7816 [(set (match_operand:SI 0 "s_register_operand")
7817 (match_operator:SI 1 "expandable_comparison_operator"
7818 [(match_operand:HF 2 "s_register_operand")
7819 (match_operand:HF 3 "vfp_compare_operand")]))]
7820 "TARGET_VFP_FP16INST"
7822 if (!arm_validize_comparison (&operands[1],
7827 emit_insn (gen_cstore_cc (operands[0], operands[1],
7828 operands[2], operands[3]));
7833 (define_expand "cstoresf4"
7834 [(set (match_operand:SI 0 "s_register_operand")
7835 (match_operator:SI 1 "expandable_comparison_operator"
7836 [(match_operand:SF 2 "s_register_operand")
7837 (match_operand:SF 3 "vfp_compare_operand")]))]
7838 "TARGET_32BIT && TARGET_HARD_FLOAT"
7839 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7840 operands[2], operands[3])); DONE;"
7843 (define_expand "cstoredf4"
7844 [(set (match_operand:SI 0 "s_register_operand")
7845 (match_operator:SI 1 "expandable_comparison_operator"
7846 [(match_operand:DF 2 "s_register_operand")
7847 (match_operand:DF 3 "vfp_compare_operand")]))]
7848 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7849 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7850 operands[2], operands[3])); DONE;"
7853 (define_expand "cstoredi4"
7854 [(set (match_operand:SI 0 "s_register_operand")
7855 (match_operator:SI 1 "expandable_comparison_operator"
7856 [(match_operand:DI 2 "s_register_operand")
7857 (match_operand:DI 3 "cmpdi_operand")]))]
7860 if (!arm_validize_comparison (&operands[1],
7864 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7871 ;; Conditional move insns
7873 (define_expand "movsicc"
7874 [(set (match_operand:SI 0 "s_register_operand")
7875 (if_then_else:SI (match_operand 1 "expandable_comparison_operator")
7876 (match_operand:SI 2 "arm_not_operand")
7877 (match_operand:SI 3 "arm_not_operand")))]
7884 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7885 &XEXP (operands[1], 1)))
7888 code = GET_CODE (operands[1]);
7889 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7890 XEXP (operands[1], 1), NULL_RTX);
7891 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7895 (define_expand "movhfcc"
7896 [(set (match_operand:HF 0 "s_register_operand")
7897 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7898 (match_operand:HF 2 "s_register_operand")
7899 (match_operand:HF 3 "s_register_operand")))]
7900 "TARGET_VFP_FP16INST"
7903 enum rtx_code code = GET_CODE (operands[1]);
7906 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7907 &XEXP (operands[1], 1)))
7910 code = GET_CODE (operands[1]);
7911 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7912 XEXP (operands[1], 1), NULL_RTX);
7913 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7917 (define_expand "movsfcc"
7918 [(set (match_operand:SF 0 "s_register_operand")
7919 (if_then_else:SF (match_operand 1 "arm_cond_move_operator")
7920 (match_operand:SF 2 "s_register_operand")
7921 (match_operand:SF 3 "s_register_operand")))]
7922 "TARGET_32BIT && TARGET_HARD_FLOAT"
7925 enum rtx_code code = GET_CODE (operands[1]);
7928 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7929 &XEXP (operands[1], 1)))
7932 code = GET_CODE (operands[1]);
7933 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7934 XEXP (operands[1], 1), NULL_RTX);
7935 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7939 (define_expand "movdfcc"
7940 [(set (match_operand:DF 0 "s_register_operand")
7941 (if_then_else:DF (match_operand 1 "arm_cond_move_operator")
7942 (match_operand:DF 2 "s_register_operand")
7943 (match_operand:DF 3 "s_register_operand")))]
7944 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7947 enum rtx_code code = GET_CODE (operands[1]);
7950 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7951 &XEXP (operands[1], 1)))
7953 code = GET_CODE (operands[1]);
7954 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7955 XEXP (operands[1], 1), NULL_RTX);
7956 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7960 (define_insn "*cmov<mode>"
7961 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7962 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7963 [(match_operand 2 "cc_register" "") (const_int 0)])
7964 (match_operand:SDF 3 "s_register_operand"
7966 (match_operand:SDF 4 "s_register_operand"
7967 "<F_constraint>")))]
7968 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7971 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7978 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7983 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7989 [(set_attr "conds" "use")
7990 (set_attr "type" "fcsel")]
7993 (define_insn "*cmovhf"
7994 [(set (match_operand:HF 0 "s_register_operand" "=t")
7995 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7996 [(match_operand 2 "cc_register" "") (const_int 0)])
7997 (match_operand:HF 3 "s_register_operand" "t")
7998 (match_operand:HF 4 "s_register_operand" "t")))]
7999 "TARGET_VFP_FP16INST"
8002 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
8009 return \"vsel%d1.f16\\t%0, %3, %4\";
8014 return \"vsel%D1.f16\\t%0, %4, %3\";
8020 [(set_attr "conds" "use")
8021 (set_attr "type" "fcsel")]
8024 (define_insn_and_split "*movsicc_insn"
8025 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8027 (match_operator 3 "arm_comparison_operator"
8028 [(match_operand 4 "cc_register" "") (const_int 0)])
8029 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8030 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8041 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8042 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8043 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8044 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8045 "&& reload_completed"
8048 enum rtx_code rev_code;
8052 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8054 gen_rtx_SET (operands[0], operands[1])));
8056 rev_code = GET_CODE (operands[3]);
8057 mode = GET_MODE (operands[4]);
8058 if (mode == CCFPmode || mode == CCFPEmode)
8059 rev_code = reverse_condition_maybe_unordered (rev_code);
8061 rev_code = reverse_condition (rev_code);
8063 rev_cond = gen_rtx_fmt_ee (rev_code,
8067 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8069 gen_rtx_SET (operands[0], operands[2])));
8072 [(set_attr "length" "4,4,4,4,8,8,8,8")
8073 (set_attr "conds" "use")
8074 (set_attr_alternative "type"
8075 [(if_then_else (match_operand 2 "const_int_operand" "")
8076 (const_string "mov_imm")
8077 (const_string "mov_reg"))
8078 (const_string "mvn_imm")
8079 (if_then_else (match_operand 1 "const_int_operand" "")
8080 (const_string "mov_imm")
8081 (const_string "mov_reg"))
8082 (const_string "mvn_imm")
8083 (const_string "multiple")
8084 (const_string "multiple")
8085 (const_string "multiple")
8086 (const_string "multiple")])]
8089 (define_insn "*movsfcc_soft_insn"
8090 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8091 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8092 [(match_operand 4 "cc_register" "") (const_int 0)])
8093 (match_operand:SF 1 "s_register_operand" "0,r")
8094 (match_operand:SF 2 "s_register_operand" "r,0")))]
8095 "TARGET_ARM && TARGET_SOFT_FLOAT"
8099 [(set_attr "conds" "use")
8100 (set_attr "type" "mov_reg")]
8104 ;; Jump and linkage insns
8106 (define_expand "jump"
8108 (label_ref (match_operand 0 "" "")))]
8113 (define_insn "*arm_jump"
8115 (label_ref (match_operand 0 "" "")))]
8119 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8121 arm_ccfsm_state += 2;
8124 return \"b%?\\t%l0\";
8127 [(set_attr "predicable" "yes")
8128 (set (attr "length")
8130 (and (match_test "TARGET_THUMB2")
8131 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8132 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8135 (set_attr "type" "branch")]
8138 (define_expand "call"
8139 [(parallel [(call (match_operand 0 "memory_operand")
8140 (match_operand 1 "general_operand"))
8141 (use (match_operand 2 "" ""))
8142 (clobber (reg:SI LR_REGNUM))])]
8147 tree addr = MEM_EXPR (operands[0]);
8149 /* In an untyped call, we can get NULL for operand 2. */
8150 if (operands[2] == NULL_RTX)
8151 operands[2] = const0_rtx;
8153 /* Decide if we should generate indirect calls by loading the
8154 32-bit address of the callee into a register before performing the
8156 callee = XEXP (operands[0], 0);
8157 if (GET_CODE (callee) == SYMBOL_REF
8158 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8160 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8162 if (detect_cmse_nonsecure_call (addr))
8164 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8166 emit_call_insn (pat);
8170 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8171 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8177 (define_expand "call_internal"
8178 [(parallel [(call (match_operand 0 "memory_operand")
8179 (match_operand 1 "general_operand"))
8180 (use (match_operand 2 "" ""))
8181 (clobber (reg:SI LR_REGNUM))])])
8183 (define_expand "nonsecure_call_internal"
8184 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand")]
8185 UNSPEC_NONSECURE_MEM)
8186 (match_operand 1 "general_operand"))
8187 (use (match_operand 2 "" ""))
8188 (clobber (reg:SI LR_REGNUM))])]
8193 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8194 gen_rtx_REG (SImode, R4_REGNUM),
8197 operands[0] = replace_equiv_address (operands[0], tmp);
8200 (define_insn "*call_reg_armv5"
8201 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8202 (match_operand 1 "" ""))
8203 (use (match_operand 2 "" ""))
8204 (clobber (reg:SI LR_REGNUM))]
8205 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8207 [(set_attr "type" "call")]
8210 (define_insn "*call_reg_arm"
8211 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8212 (match_operand 1 "" ""))
8213 (use (match_operand 2 "" ""))
8214 (clobber (reg:SI LR_REGNUM))]
8215 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8217 return output_call (operands);
8219 ;; length is worst case, normally it is only two
8220 [(set_attr "length" "12")
8221 (set_attr "type" "call")]
8225 (define_expand "call_value"
8226 [(parallel [(set (match_operand 0 "" "")
8227 (call (match_operand 1 "memory_operand")
8228 (match_operand 2 "general_operand")))
8229 (use (match_operand 3 "" ""))
8230 (clobber (reg:SI LR_REGNUM))])]
8235 tree addr = MEM_EXPR (operands[1]);
8237 /* In an untyped call, we can get NULL for operand 2. */
8238 if (operands[3] == 0)
8239 operands[3] = const0_rtx;
8241 /* Decide if we should generate indirect calls by loading the
8242 32-bit address of the callee into a register before performing the
8244 callee = XEXP (operands[1], 0);
8245 if (GET_CODE (callee) == SYMBOL_REF
8246 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8248 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8250 if (detect_cmse_nonsecure_call (addr))
8252 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8253 operands[2], operands[3]);
8254 emit_call_insn (pat);
8258 pat = gen_call_value_internal (operands[0], operands[1],
8259 operands[2], operands[3]);
8260 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8266 (define_expand "call_value_internal"
8267 [(parallel [(set (match_operand 0 "" "")
8268 (call (match_operand 1 "memory_operand")
8269 (match_operand 2 "general_operand")))
8270 (use (match_operand 3 "" ""))
8271 (clobber (reg:SI LR_REGNUM))])])
8273 (define_expand "nonsecure_call_value_internal"
8274 [(parallel [(set (match_operand 0 "" "")
8275 (call (unspec:SI [(match_operand 1 "memory_operand")]
8276 UNSPEC_NONSECURE_MEM)
8277 (match_operand 2 "general_operand")))
8278 (use (match_operand 3 "" ""))
8279 (clobber (reg:SI LR_REGNUM))])]
8284 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8285 gen_rtx_REG (SImode, R4_REGNUM),
8288 operands[1] = replace_equiv_address (operands[1], tmp);
8291 (define_insn "*call_value_reg_armv5"
8292 [(set (match_operand 0 "" "")
8293 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8294 (match_operand 2 "" "")))
8295 (use (match_operand 3 "" ""))
8296 (clobber (reg:SI LR_REGNUM))]
8297 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8299 [(set_attr "type" "call")]
8302 (define_insn "*call_value_reg_arm"
8303 [(set (match_operand 0 "" "")
8304 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8305 (match_operand 2 "" "")))
8306 (use (match_operand 3 "" ""))
8307 (clobber (reg:SI LR_REGNUM))]
8308 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8310 return output_call (&operands[1]);
8312 [(set_attr "length" "12")
8313 (set_attr "type" "call")]
8316 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8317 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8319 (define_insn "*call_symbol"
8320 [(call (mem:SI (match_operand:SI 0 "" ""))
8321 (match_operand 1 "" ""))
8322 (use (match_operand 2 "" ""))
8323 (clobber (reg:SI LR_REGNUM))]
8325 && !SIBLING_CALL_P (insn)
8326 && (GET_CODE (operands[0]) == SYMBOL_REF)
8327 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8330 rtx op = operands[0];
8332 /* Switch mode now when possible. */
8333 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8334 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8335 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8337 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8339 [(set_attr "type" "call")]
8342 (define_insn "*call_value_symbol"
8343 [(set (match_operand 0 "" "")
8344 (call (mem:SI (match_operand:SI 1 "" ""))
8345 (match_operand:SI 2 "" "")))
8346 (use (match_operand 3 "" ""))
8347 (clobber (reg:SI LR_REGNUM))]
8349 && !SIBLING_CALL_P (insn)
8350 && (GET_CODE (operands[1]) == SYMBOL_REF)
8351 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8354 rtx op = operands[1];
8356 /* Switch mode now when possible. */
8357 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8358 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8359 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8361 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8363 [(set_attr "type" "call")]
8366 (define_expand "sibcall_internal"
8367 [(parallel [(call (match_operand 0 "memory_operand")
8368 (match_operand 1 "general_operand"))
8370 (use (match_operand 2 "" ""))])])
8372 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8373 (define_expand "sibcall"
8374 [(parallel [(call (match_operand 0 "memory_operand")
8375 (match_operand 1 "general_operand"))
8377 (use (match_operand 2 "" ""))])]
8383 if ((!REG_P (XEXP (operands[0], 0))
8384 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8385 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8386 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8387 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8389 if (operands[2] == NULL_RTX)
8390 operands[2] = const0_rtx;
8392 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8393 arm_emit_call_insn (pat, operands[0], true);
8398 (define_expand "sibcall_value_internal"
8399 [(parallel [(set (match_operand 0 "" "")
8400 (call (match_operand 1 "memory_operand")
8401 (match_operand 2 "general_operand")))
8403 (use (match_operand 3 "" ""))])])
8405 (define_expand "sibcall_value"
8406 [(parallel [(set (match_operand 0 "" "")
8407 (call (match_operand 1 "memory_operand")
8408 (match_operand 2 "general_operand")))
8410 (use (match_operand 3 "" ""))])]
8416 if ((!REG_P (XEXP (operands[1], 0))
8417 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8418 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8419 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8420 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8422 if (operands[3] == NULL_RTX)
8423 operands[3] = const0_rtx;
8425 pat = gen_sibcall_value_internal (operands[0], operands[1],
8426 operands[2], operands[3]);
8427 arm_emit_call_insn (pat, operands[1], true);
8432 (define_insn "*sibcall_insn"
8433 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8434 (match_operand 1 "" ""))
8436 (use (match_operand 2 "" ""))]
8437 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8439 if (which_alternative == 1)
8440 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8443 if (arm_arch5t || arm_arch4t)
8444 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8446 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8449 [(set_attr "type" "call")]
8452 (define_insn "*sibcall_value_insn"
8453 [(set (match_operand 0 "" "")
8454 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8455 (match_operand 2 "" "")))
8457 (use (match_operand 3 "" ""))]
8458 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8460 if (which_alternative == 1)
8461 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8464 if (arm_arch5t || arm_arch4t)
8465 return \"bx%?\\t%1\";
8467 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8470 [(set_attr "type" "call")]
8473 (define_expand "<return_str>return"
8475 "(TARGET_ARM || (TARGET_THUMB2
8476 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8477 && !IS_STACKALIGN (arm_current_func_type ())))
8478 <return_cond_false>"
8483 thumb2_expand_return (<return_simple_p>);
8490 ;; Often the return insn will be the same as loading from memory, so set attr
8491 (define_insn "*arm_return"
8493 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8496 if (arm_ccfsm_state == 2)
8498 arm_ccfsm_state += 2;
8501 return output_return_instruction (const_true_rtx, true, false, false);
8503 [(set_attr "type" "load_4")
8504 (set_attr "length" "12")
8505 (set_attr "predicable" "yes")]
8508 (define_insn "*cond_<return_str>return"
8510 (if_then_else (match_operator 0 "arm_comparison_operator"
8511 [(match_operand 1 "cc_register" "") (const_int 0)])
8514 "TARGET_ARM <return_cond_true>"
8517 if (arm_ccfsm_state == 2)
8519 arm_ccfsm_state += 2;
8522 return output_return_instruction (operands[0], true, false,
8525 [(set_attr "conds" "use")
8526 (set_attr "length" "12")
8527 (set_attr "type" "load_4")]
8530 (define_insn "*cond_<return_str>return_inverted"
8532 (if_then_else (match_operator 0 "arm_comparison_operator"
8533 [(match_operand 1 "cc_register" "") (const_int 0)])
8536 "TARGET_ARM <return_cond_true>"
8539 if (arm_ccfsm_state == 2)
8541 arm_ccfsm_state += 2;
8544 return output_return_instruction (operands[0], true, true,
8547 [(set_attr "conds" "use")
8548 (set_attr "length" "12")
8549 (set_attr "type" "load_4")]
8552 (define_insn "*arm_simple_return"
8557 if (arm_ccfsm_state == 2)
8559 arm_ccfsm_state += 2;
8562 return output_return_instruction (const_true_rtx, true, false, true);
8564 [(set_attr "type" "branch")
8565 (set_attr "length" "4")
8566 (set_attr "predicable" "yes")]
8569 ;; Generate a sequence of instructions to determine if the processor is
8570 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8573 (define_expand "return_addr_mask"
8575 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8577 (set (match_operand:SI 0 "s_register_operand")
8578 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8580 (const_int 67108860)))] ; 0x03fffffc
8583 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8586 (define_insn "*check_arch2"
8587 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8588 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8591 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8592 [(set_attr "length" "8")
8593 (set_attr "conds" "set")
8594 (set_attr "type" "multiple")]
8597 ;; Call subroutine returning any type.
8599 (define_expand "untyped_call"
8600 [(parallel [(call (match_operand 0 "" "")
8602 (match_operand 1 "" "")
8603 (match_operand 2 "" "")])]
8608 rtx par = gen_rtx_PARALLEL (VOIDmode,
8609 rtvec_alloc (XVECLEN (operands[2], 0)));
8610 rtx addr = gen_reg_rtx (Pmode);
8614 emit_move_insn (addr, XEXP (operands[1], 0));
8615 mem = change_address (operands[1], BLKmode, addr);
8617 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8619 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8621 /* Default code only uses r0 as a return value, but we could
8622 be using anything up to 4 registers. */
8623 if (REGNO (src) == R0_REGNUM)
8624 src = gen_rtx_REG (TImode, R0_REGNUM);
8626 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8628 size += GET_MODE_SIZE (GET_MODE (src));
8631 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8635 for (i = 0; i < XVECLEN (par, 0); i++)
8637 HOST_WIDE_INT offset = 0;
8638 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8641 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8643 mem = change_address (mem, GET_MODE (reg), NULL);
8644 if (REGNO (reg) == R0_REGNUM)
8646 /* On thumb we have to use a write-back instruction. */
8647 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8648 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8649 size = TARGET_ARM ? 16 : 0;
8653 emit_move_insn (mem, reg);
8654 size = GET_MODE_SIZE (GET_MODE (reg));
8658 /* The optimizer does not know that the call sets the function value
8659 registers we stored in the result block. We avoid problems by
8660 claiming that all hard registers are used and clobbered at this
8662 emit_insn (gen_blockage ());
8668 (define_expand "untyped_return"
8669 [(match_operand:BLK 0 "memory_operand")
8670 (match_operand 1 "" "")]
8675 rtx addr = gen_reg_rtx (Pmode);
8679 emit_move_insn (addr, XEXP (operands[0], 0));
8680 mem = change_address (operands[0], BLKmode, addr);
8682 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8684 HOST_WIDE_INT offset = 0;
8685 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8688 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8690 mem = change_address (mem, GET_MODE (reg), NULL);
8691 if (REGNO (reg) == R0_REGNUM)
8693 /* On thumb we have to use a write-back instruction. */
8694 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8695 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8696 size = TARGET_ARM ? 16 : 0;
8700 emit_move_insn (reg, mem);
8701 size = GET_MODE_SIZE (GET_MODE (reg));
8705 /* Emit USE insns before the return. */
8706 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8707 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8709 /* Construct the return. */
8710 expand_naked_return ();
8716 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8717 ;; all of memory. This blocks insns from being moved across this point.
8719 (define_insn "blockage"
8720 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8723 [(set_attr "length" "0")
8724 (set_attr "type" "block")]
8727 ;; Since we hard code r0 here use the 'o' constraint to prevent
8728 ;; provoking undefined behaviour in the hardware with putting out
8729 ;; auto-increment operations with potentially r0 as the base register.
8730 (define_insn "probe_stack"
8731 [(set (match_operand:SI 0 "memory_operand" "=o")
8732 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8735 [(set_attr "type" "store_4")
8736 (set_attr "predicable" "yes")]
8739 (define_insn "probe_stack_range"
8740 [(set (match_operand:SI 0 "register_operand" "=r")
8741 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8742 (match_operand:SI 2 "register_operand" "r")]
8743 VUNSPEC_PROBE_STACK_RANGE))]
8746 return output_probe_stack_range (operands[0], operands[2]);
8748 [(set_attr "type" "multiple")
8749 (set_attr "conds" "clob")]
8752 ;; Named patterns for stack smashing protection.
8753 (define_expand "stack_protect_combined_set"
8755 [(set (match_operand:SI 0 "memory_operand")
8756 (unspec:SI [(match_operand:SI 1 "guard_operand")]
8758 (clobber (match_scratch:SI 2 ""))
8759 (clobber (match_scratch:SI 3 ""))])]
8764 ;; Use a separate insn from the above expand to be able to have the mem outside
8765 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8766 ;; try to reload the guard since we need to control how PIC access is done in
8767 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8768 ;; legitimize_pic_address ()).
8769 (define_insn_and_split "*stack_protect_combined_set_insn"
8770 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8771 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8773 (clobber (match_scratch:SI 2 "=&l,&r"))
8774 (clobber (match_scratch:SI 3 "=&l,&r"))]
8778 [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))]
8780 (clobber (match_dup 2))])]
8785 /* Forces recomputing of GOT base now. */
8786 legitimize_pic_address (operands[1], SImode, operands[2], operands[3],
8787 true /*compute_now*/);
8791 if (address_operand (operands[1], SImode))
8792 operands[2] = operands[1];
8795 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8796 emit_move_insn (operands[2], mem);
8800 [(set_attr "arch" "t1,32")]
8803 (define_insn "*stack_protect_set_insn"
8804 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8805 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))]
8807 (clobber (match_dup 1))]
8810 ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1,#0
8811 ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1,#0"
8812 [(set_attr "length" "8,12")
8813 (set_attr "conds" "clob,nocond")
8814 (set_attr "type" "multiple")
8815 (set_attr "arch" "t1,32")]
8818 (define_expand "stack_protect_combined_test"
8822 (eq (match_operand:SI 0 "memory_operand")
8823 (unspec:SI [(match_operand:SI 1 "guard_operand")]
8825 (label_ref (match_operand 2))
8827 (clobber (match_scratch:SI 3 ""))
8828 (clobber (match_scratch:SI 4 ""))
8829 (clobber (reg:CC CC_REGNUM))])]
8834 ;; Use a separate insn from the above expand to be able to have the mem outside
8835 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8836 ;; try to reload the guard since we need to control how PIC access is done in
8837 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8838 ;; legitimize_pic_address ()).
8839 (define_insn_and_split "*stack_protect_combined_test_insn"
8842 (eq (match_operand:SI 0 "memory_operand" "m,m")
8843 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8845 (label_ref (match_operand 2))
8847 (clobber (match_scratch:SI 3 "=&l,&r"))
8848 (clobber (match_scratch:SI 4 "=&l,&r"))
8849 (clobber (reg:CC CC_REGNUM))]
8859 /* Forces recomputing of GOT base now. */
8860 legitimize_pic_address (operands[1], SImode, operands[3], operands[4],
8861 true /*compute_now*/);
8865 if (address_operand (operands[1], SImode))
8866 operands[3] = operands[1];
8869 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8870 emit_move_insn (operands[3], mem);
8875 emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0],
8877 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
8878 eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx);
8879 emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg));
8883 emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0],
8885 eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
8886 emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx,
8891 [(set_attr "arch" "t1,32")]
8894 (define_insn "arm_stack_protect_test_insn"
8895 [(set (reg:CC_Z CC_REGNUM)
8896 (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m")
8897 (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))]
8900 (clobber (match_operand:SI 0 "register_operand" "=&l,&r"))
8901 (clobber (match_dup 2))]
8903 "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0"
8904 [(set_attr "length" "8,12")
8905 (set_attr "conds" "set")
8906 (set_attr "type" "multiple")
8907 (set_attr "arch" "t,32")]
8910 (define_expand "casesi"
8911 [(match_operand:SI 0 "s_register_operand") ; index to jump on
8912 (match_operand:SI 1 "const_int_operand") ; lower bound
8913 (match_operand:SI 2 "const_int_operand") ; total range
8914 (match_operand:SI 3 "" "") ; table label
8915 (match_operand:SI 4 "" "")] ; Out of range label
8916 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8919 enum insn_code code;
8920 if (operands[1] != const0_rtx)
8922 rtx reg = gen_reg_rtx (SImode);
8924 emit_insn (gen_addsi3 (reg, operands[0],
8925 gen_int_mode (-INTVAL (operands[1]),
8931 code = CODE_FOR_arm_casesi_internal;
8932 else if (TARGET_THUMB1)
8933 code = CODE_FOR_thumb1_casesi_internal_pic;
8935 code = CODE_FOR_thumb2_casesi_internal_pic;
8937 code = CODE_FOR_thumb2_casesi_internal;
8939 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8940 operands[2] = force_reg (SImode, operands[2]);
8942 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8943 operands[3], operands[4]));
8948 ;; The USE in this pattern is needed to tell flow analysis that this is
8949 ;; a CASESI insn. It has no other purpose.
8950 (define_expand "arm_casesi_internal"
8951 [(parallel [(set (pc)
8953 (leu (match_operand:SI 0 "s_register_operand")
8954 (match_operand:SI 1 "arm_rhs_operand"))
8956 (label_ref:SI (match_operand 3 ""))))
8957 (clobber (reg:CC CC_REGNUM))
8958 (use (label_ref:SI (match_operand 2 "")))])]
8961 operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
8962 operands[4] = gen_rtx_PLUS (SImode, operands[4],
8963 gen_rtx_LABEL_REF (SImode, operands[2]));
8964 operands[4] = gen_rtx_MEM (SImode, operands[4]);
8965 MEM_READONLY_P (operands[4]) = 1;
8966 MEM_NOTRAP_P (operands[4]) = 1;
8969 (define_insn "*arm_casesi_internal"
8970 [(parallel [(set (pc)
8972 (leu (match_operand:SI 0 "s_register_operand" "r")
8973 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8974 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8975 (label_ref:SI (match_operand 2 "" ""))))
8976 (label_ref:SI (match_operand 3 "" ""))))
8977 (clobber (reg:CC CC_REGNUM))
8978 (use (label_ref:SI (match_dup 2)))])]
8982 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8983 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8985 [(set_attr "conds" "clob")
8986 (set_attr "length" "12")
8987 (set_attr "type" "multiple")]
8990 (define_expand "indirect_jump"
8992 (match_operand:SI 0 "s_register_operand"))]
8995 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8996 address and use bx. */
9000 tmp = gen_reg_rtx (SImode);
9001 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
9007 ;; NB Never uses BX.
9008 (define_insn "*arm_indirect_jump"
9010 (match_operand:SI 0 "s_register_operand" "r"))]
9012 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
9013 [(set_attr "predicable" "yes")
9014 (set_attr "type" "branch")]
9017 (define_insn "*load_indirect_jump"
9019 (match_operand:SI 0 "memory_operand" "m"))]
9021 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
9022 [(set_attr "type" "load_4")
9023 (set_attr "pool_range" "4096")
9024 (set_attr "neg_pool_range" "4084")
9025 (set_attr "predicable" "yes")]
9035 [(set (attr "length")
9036 (if_then_else (eq_attr "is_thumb" "yes")
9039 (set_attr "type" "mov_reg")]
9043 [(trap_if (const_int 1) (const_int 0))]
9047 return \".inst\\t0xe7f000f0\";
9049 return \".inst\\t0xdeff\";
9051 [(set (attr "length")
9052 (if_then_else (eq_attr "is_thumb" "yes")
9055 (set_attr "type" "trap")
9056 (set_attr "conds" "unconditional")]
9060 ;; Patterns to allow combination of arithmetic, cond code and shifts
9062 (define_insn "*<arith_shift_insn>_multsi"
9063 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9065 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
9066 (match_operand:SI 3 "power_of_two_operand" ""))
9067 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
9069 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
9070 [(set_attr "predicable" "yes")
9071 (set_attr "shift" "2")
9072 (set_attr "arch" "a,t2")
9073 (set_attr "type" "alu_shift_imm")])
9075 (define_insn "*<arith_shift_insn>_shiftsi"
9076 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9078 (match_operator:SI 2 "shift_nomul_operator"
9079 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9080 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
9081 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
9082 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
9083 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
9084 [(set_attr "predicable" "yes")
9085 (set_attr "shift" "3")
9086 (set_attr "arch" "a,t2,a")
9087 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9090 [(set (match_operand:SI 0 "s_register_operand" "")
9091 (match_operator:SI 1 "shiftable_operator"
9092 [(match_operator:SI 2 "shiftable_operator"
9093 [(match_operator:SI 3 "shift_operator"
9094 [(match_operand:SI 4 "s_register_operand" "")
9095 (match_operand:SI 5 "reg_or_int_operand" "")])
9096 (match_operand:SI 6 "s_register_operand" "")])
9097 (match_operand:SI 7 "arm_rhs_operand" "")]))
9098 (clobber (match_operand:SI 8 "s_register_operand" ""))]
9101 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9104 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
9107 (define_insn "*arith_shiftsi_compare0"
9108 [(set (reg:CC_NOOV CC_REGNUM)
9110 (match_operator:SI 1 "shiftable_operator"
9111 [(match_operator:SI 3 "shift_operator"
9112 [(match_operand:SI 4 "s_register_operand" "r,r")
9113 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9114 (match_operand:SI 2 "s_register_operand" "r,r")])
9116 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9117 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9120 "%i1s%?\\t%0, %2, %4%S3"
9121 [(set_attr "conds" "set")
9122 (set_attr "shift" "4")
9123 (set_attr "arch" "32,a")
9124 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9126 (define_insn "*arith_shiftsi_compare0_scratch"
9127 [(set (reg:CC_NOOV CC_REGNUM)
9129 (match_operator:SI 1 "shiftable_operator"
9130 [(match_operator:SI 3 "shift_operator"
9131 [(match_operand:SI 4 "s_register_operand" "r,r")
9132 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9133 (match_operand:SI 2 "s_register_operand" "r,r")])
9135 (clobber (match_scratch:SI 0 "=r,r"))]
9137 "%i1s%?\\t%0, %2, %4%S3"
9138 [(set_attr "conds" "set")
9139 (set_attr "shift" "4")
9140 (set_attr "arch" "32,a")
9141 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9143 (define_insn "*sub_shiftsi"
9144 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9145 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9146 (match_operator:SI 2 "shift_operator"
9147 [(match_operand:SI 3 "s_register_operand" "r,r")
9148 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
9150 "sub%?\\t%0, %1, %3%S2"
9151 [(set_attr "predicable" "yes")
9152 (set_attr "predicable_short_it" "no")
9153 (set_attr "shift" "3")
9154 (set_attr "arch" "32,a")
9155 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9157 (define_insn "*sub_shiftsi_compare0"
9158 [(set (reg:CC_NOOV CC_REGNUM)
9160 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9161 (match_operator:SI 2 "shift_operator"
9162 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9163 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9165 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9166 (minus:SI (match_dup 1)
9167 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
9169 "subs%?\\t%0, %1, %3%S2"
9170 [(set_attr "conds" "set")
9171 (set_attr "shift" "3")
9172 (set_attr "arch" "32,a,a")
9173 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9175 (define_insn "*sub_shiftsi_compare0_scratch"
9176 [(set (reg:CC_NOOV CC_REGNUM)
9178 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9179 (match_operator:SI 2 "shift_operator"
9180 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9181 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9183 (clobber (match_scratch:SI 0 "=r,r,r"))]
9185 "subs%?\\t%0, %1, %3%S2"
9186 [(set_attr "conds" "set")
9187 (set_attr "shift" "3")
9188 (set_attr "arch" "32,a,a")
9189 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9192 (define_insn_and_split "*and_scc"
9193 [(set (match_operand:SI 0 "s_register_operand" "=r")
9194 (and:SI (match_operator:SI 1 "arm_comparison_operator"
9195 [(match_operand 2 "cc_register" "") (const_int 0)])
9196 (match_operand:SI 3 "s_register_operand" "r")))]
9198 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
9199 "&& reload_completed"
9200 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
9201 (cond_exec (match_dup 4) (set (match_dup 0)
9202 (and:SI (match_dup 3) (const_int 1))))]
9204 machine_mode mode = GET_MODE (operands[2]);
9205 enum rtx_code rc = GET_CODE (operands[1]);
9207 /* Note that operands[4] is the same as operands[1],
9208 but with VOIDmode as the result. */
9209 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9210 if (mode == CCFPmode || mode == CCFPEmode)
9211 rc = reverse_condition_maybe_unordered (rc);
9213 rc = reverse_condition (rc);
9214 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9216 [(set_attr "conds" "use")
9217 (set_attr "type" "multiple")
9218 (set_attr "length" "8")]
9221 (define_insn_and_split "*ior_scc"
9222 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9223 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
9224 [(match_operand 2 "cc_register" "") (const_int 0)])
9225 (match_operand:SI 3 "s_register_operand" "0,?r")))]
9230 "&& reload_completed
9231 && REGNO (operands [0]) != REGNO (operands[3])"
9232 ;; && which_alternative == 1
9233 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
9234 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
9235 (cond_exec (match_dup 4) (set (match_dup 0)
9236 (ior:SI (match_dup 3) (const_int 1))))]
9238 machine_mode mode = GET_MODE (operands[2]);
9239 enum rtx_code rc = GET_CODE (operands[1]);
9241 /* Note that operands[4] is the same as operands[1],
9242 but with VOIDmode as the result. */
9243 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9244 if (mode == CCFPmode || mode == CCFPEmode)
9245 rc = reverse_condition_maybe_unordered (rc);
9247 rc = reverse_condition (rc);
9248 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9250 [(set_attr "conds" "use")
9251 (set_attr "length" "4,8")
9252 (set_attr "type" "logic_imm,multiple")]
9255 ; A series of splitters for the compare_scc pattern below. Note that
9256 ; order is important.
9258 [(set (match_operand:SI 0 "s_register_operand" "")
9259 (lt:SI (match_operand:SI 1 "s_register_operand" "")
9261 (clobber (reg:CC CC_REGNUM))]
9262 "TARGET_32BIT && reload_completed"
9263 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9266 [(set (match_operand:SI 0 "s_register_operand" "")
9267 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9269 (clobber (reg:CC CC_REGNUM))]
9270 "TARGET_32BIT && reload_completed"
9271 [(set (match_dup 0) (not:SI (match_dup 1)))
9272 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9275 [(set (match_operand:SI 0 "s_register_operand" "")
9276 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9278 (clobber (reg:CC CC_REGNUM))]
9279 "arm_arch5t && TARGET_32BIT"
9280 [(set (match_dup 0) (clz:SI (match_dup 1)))
9281 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9285 [(set (match_operand:SI 0 "s_register_operand" "")
9286 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9288 (clobber (reg:CC CC_REGNUM))]
9289 "TARGET_32BIT && reload_completed"
9291 [(set (reg:CC CC_REGNUM)
9292 (compare:CC (const_int 1) (match_dup 1)))
9294 (minus:SI (const_int 1) (match_dup 1)))])
9295 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9296 (set (match_dup 0) (const_int 0)))])
9299 [(set (match_operand:SI 0 "s_register_operand" "")
9300 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9301 (match_operand:SI 2 "const_int_operand" "")))
9302 (clobber (reg:CC CC_REGNUM))]
9303 "TARGET_32BIT && reload_completed"
9305 [(set (reg:CC CC_REGNUM)
9306 (compare:CC (match_dup 1) (match_dup 2)))
9307 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9308 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9309 (set (match_dup 0) (const_int 1)))]
9311 operands[3] = gen_int_mode (-INTVAL (operands[2]), SImode);
9315 [(set (match_operand:SI 0 "s_register_operand" "")
9316 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9317 (match_operand:SI 2 "arm_add_operand" "")))
9318 (clobber (reg:CC CC_REGNUM))]
9319 "TARGET_32BIT && reload_completed"
9321 [(set (reg:CC_NOOV CC_REGNUM)
9322 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9324 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9325 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9326 (set (match_dup 0) (const_int 1)))])
9328 (define_insn_and_split "*compare_scc"
9329 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9330 (match_operator:SI 1 "arm_comparison_operator"
9331 [(match_operand:SI 2 "s_register_operand" "r,r")
9332 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9333 (clobber (reg:CC CC_REGNUM))]
9336 "&& reload_completed"
9337 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9338 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9339 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9342 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9343 operands[2], operands[3]);
9344 enum rtx_code rc = GET_CODE (operands[1]);
9346 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9348 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9349 if (mode == CCFPmode || mode == CCFPEmode)
9350 rc = reverse_condition_maybe_unordered (rc);
9352 rc = reverse_condition (rc);
9353 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9355 [(set_attr "type" "multiple")]
9358 ;; Attempt to improve the sequence generated by the compare_scc splitters
9359 ;; not to use conditional execution.
9361 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9365 [(set (reg:CC CC_REGNUM)
9366 (compare:CC (match_operand:SI 1 "register_operand" "")
9368 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9369 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9370 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9371 (set (match_dup 0) (const_int 1)))]
9372 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9373 [(set (match_dup 0) (clz:SI (match_dup 1)))
9374 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9377 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9381 [(set (reg:CC CC_REGNUM)
9382 (compare:CC (match_operand:SI 1 "register_operand" "")
9384 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9385 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9386 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9387 (set (match_dup 0) (const_int 1)))
9388 (match_scratch:SI 2 "r")]
9389 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9391 [(set (reg:CC CC_REGNUM)
9392 (compare:CC (const_int 0) (match_dup 1)))
9393 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9395 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9396 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9399 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9400 ;; sub Rd, Reg1, reg2
9404 [(set (reg:CC CC_REGNUM)
9405 (compare:CC (match_operand:SI 1 "register_operand" "")
9406 (match_operand:SI 2 "arm_rhs_operand" "")))
9407 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9408 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9409 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9410 (set (match_dup 0) (const_int 1)))]
9411 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9412 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9413 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9414 (set (match_dup 0) (clz:SI (match_dup 0)))
9415 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9419 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9420 ;; sub T1, Reg1, reg2
9424 [(set (reg:CC CC_REGNUM)
9425 (compare:CC (match_operand:SI 1 "register_operand" "")
9426 (match_operand:SI 2 "arm_rhs_operand" "")))
9427 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9428 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9429 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9430 (set (match_dup 0) (const_int 1)))
9431 (match_scratch:SI 3 "r")]
9432 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9433 [(set (match_dup 3) (match_dup 4))
9435 [(set (reg:CC CC_REGNUM)
9436 (compare:CC (const_int 0) (match_dup 3)))
9437 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9439 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9440 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9442 if (CONST_INT_P (operands[2]))
9443 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9445 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9448 (define_insn "*cond_move"
9449 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9450 (if_then_else:SI (match_operator 3 "equality_operator"
9451 [(match_operator 4 "arm_comparison_operator"
9452 [(match_operand 5 "cc_register" "") (const_int 0)])
9454 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9455 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9458 if (GET_CODE (operands[3]) == NE)
9460 if (which_alternative != 1)
9461 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9462 if (which_alternative != 0)
9463 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9466 if (which_alternative != 0)
9467 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9468 if (which_alternative != 1)
9469 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9472 [(set_attr "conds" "use")
9473 (set_attr_alternative "type"
9474 [(if_then_else (match_operand 2 "const_int_operand" "")
9475 (const_string "mov_imm")
9476 (const_string "mov_reg"))
9477 (if_then_else (match_operand 1 "const_int_operand" "")
9478 (const_string "mov_imm")
9479 (const_string "mov_reg"))
9480 (const_string "multiple")])
9481 (set_attr "length" "4,4,8")]
9484 (define_insn "*cond_arith"
9485 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9486 (match_operator:SI 5 "shiftable_operator"
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 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9491 (clobber (reg:CC CC_REGNUM))]
9494 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9495 return \"%i5\\t%0, %1, %2, lsr #31\";
9497 output_asm_insn (\"cmp\\t%2, %3\", operands);
9498 if (GET_CODE (operands[5]) == AND)
9499 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9500 else if (GET_CODE (operands[5]) == MINUS)
9501 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9502 else if (which_alternative != 0)
9503 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9504 return \"%i5%d4\\t%0, %1, #1\";
9506 [(set_attr "conds" "clob")
9507 (set_attr "length" "12")
9508 (set_attr "type" "multiple")]
9511 (define_insn "*cond_sub"
9512 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9513 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9514 (match_operator:SI 4 "arm_comparison_operator"
9515 [(match_operand:SI 2 "s_register_operand" "r,r")
9516 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9517 (clobber (reg:CC CC_REGNUM))]
9520 output_asm_insn (\"cmp\\t%2, %3\", operands);
9521 if (which_alternative != 0)
9522 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9523 return \"sub%d4\\t%0, %1, #1\";
9525 [(set_attr "conds" "clob")
9526 (set_attr "length" "8,12")
9527 (set_attr "type" "multiple")]
9530 (define_insn "*cmp_ite0"
9531 [(set (match_operand 6 "dominant_cc_register" "")
9534 (match_operator 4 "arm_comparison_operator"
9535 [(match_operand:SI 0 "s_register_operand"
9536 "l,l,l,r,r,r,r,r,r")
9537 (match_operand:SI 1 "arm_add_operand"
9538 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9539 (match_operator:SI 5 "arm_comparison_operator"
9540 [(match_operand:SI 2 "s_register_operand"
9541 "l,r,r,l,l,r,r,r,r")
9542 (match_operand:SI 3 "arm_add_operand"
9543 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9549 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9551 {\"cmp%d5\\t%0, %1\",
9552 \"cmp%d4\\t%2, %3\"},
9553 {\"cmn%d5\\t%0, #%n1\",
9554 \"cmp%d4\\t%2, %3\"},
9555 {\"cmp%d5\\t%0, %1\",
9556 \"cmn%d4\\t%2, #%n3\"},
9557 {\"cmn%d5\\t%0, #%n1\",
9558 \"cmn%d4\\t%2, #%n3\"}
9560 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9565 \"cmn\\t%0, #%n1\"},
9566 {\"cmn\\t%2, #%n3\",
9568 {\"cmn\\t%2, #%n3\",
9571 static const char * const ite[2] =
9576 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9577 CMP_CMP, CMN_CMP, CMP_CMP,
9578 CMN_CMP, CMP_CMN, CMN_CMN};
9580 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9582 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9583 if (TARGET_THUMB2) {
9584 output_asm_insn (ite[swap], operands);
9586 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9589 [(set_attr "conds" "set")
9590 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9591 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9592 (set_attr "type" "multiple")
9593 (set_attr_alternative "length"
9599 (if_then_else (eq_attr "is_thumb" "no")
9602 (if_then_else (eq_attr "is_thumb" "no")
9605 (if_then_else (eq_attr "is_thumb" "no")
9608 (if_then_else (eq_attr "is_thumb" "no")
9613 (define_insn "*cmp_ite1"
9614 [(set (match_operand 6 "dominant_cc_register" "")
9617 (match_operator 4 "arm_comparison_operator"
9618 [(match_operand:SI 0 "s_register_operand"
9619 "l,l,l,r,r,r,r,r,r")
9620 (match_operand:SI 1 "arm_add_operand"
9621 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9622 (match_operator:SI 5 "arm_comparison_operator"
9623 [(match_operand:SI 2 "s_register_operand"
9624 "l,r,r,l,l,r,r,r,r")
9625 (match_operand:SI 3 "arm_add_operand"
9626 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9632 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9636 {\"cmn\\t%0, #%n1\",
9639 \"cmn\\t%2, #%n3\"},
9640 {\"cmn\\t%0, #%n1\",
9643 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9645 {\"cmp%d4\\t%2, %3\",
9646 \"cmp%D5\\t%0, %1\"},
9647 {\"cmp%d4\\t%2, %3\",
9648 \"cmn%D5\\t%0, #%n1\"},
9649 {\"cmn%d4\\t%2, #%n3\",
9650 \"cmp%D5\\t%0, %1\"},
9651 {\"cmn%d4\\t%2, #%n3\",
9652 \"cmn%D5\\t%0, #%n1\"}
9654 static const char * const ite[2] =
9659 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9660 CMP_CMP, CMN_CMP, CMP_CMP,
9661 CMN_CMP, CMP_CMN, CMN_CMN};
9663 comparison_dominates_p (GET_CODE (operands[5]),
9664 reverse_condition (GET_CODE (operands[4])));
9666 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9667 if (TARGET_THUMB2) {
9668 output_asm_insn (ite[swap], operands);
9670 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9673 [(set_attr "conds" "set")
9674 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9675 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9676 (set_attr_alternative "length"
9682 (if_then_else (eq_attr "is_thumb" "no")
9685 (if_then_else (eq_attr "is_thumb" "no")
9688 (if_then_else (eq_attr "is_thumb" "no")
9691 (if_then_else (eq_attr "is_thumb" "no")
9694 (set_attr "type" "multiple")]
9697 (define_insn "*cmp_and"
9698 [(set (match_operand 6 "dominant_cc_register" "")
9701 (match_operator 4 "arm_comparison_operator"
9702 [(match_operand:SI 0 "s_register_operand"
9703 "l,l,l,r,r,r,r,r,r")
9704 (match_operand:SI 1 "arm_add_operand"
9705 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9706 (match_operator:SI 5 "arm_comparison_operator"
9707 [(match_operand:SI 2 "s_register_operand"
9708 "l,r,r,l,l,r,r,r,r")
9709 (match_operand:SI 3 "arm_add_operand"
9710 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9715 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9717 {\"cmp%d5\\t%0, %1\",
9718 \"cmp%d4\\t%2, %3\"},
9719 {\"cmn%d5\\t%0, #%n1\",
9720 \"cmp%d4\\t%2, %3\"},
9721 {\"cmp%d5\\t%0, %1\",
9722 \"cmn%d4\\t%2, #%n3\"},
9723 {\"cmn%d5\\t%0, #%n1\",
9724 \"cmn%d4\\t%2, #%n3\"}
9726 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9731 \"cmn\\t%0, #%n1\"},
9732 {\"cmn\\t%2, #%n3\",
9734 {\"cmn\\t%2, #%n3\",
9737 static const char *const ite[2] =
9742 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9743 CMP_CMP, CMN_CMP, CMP_CMP,
9744 CMN_CMP, CMP_CMN, CMN_CMN};
9746 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9748 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9749 if (TARGET_THUMB2) {
9750 output_asm_insn (ite[swap], operands);
9752 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9755 [(set_attr "conds" "set")
9756 (set_attr "predicable" "no")
9757 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9758 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9759 (set_attr_alternative "length"
9765 (if_then_else (eq_attr "is_thumb" "no")
9768 (if_then_else (eq_attr "is_thumb" "no")
9771 (if_then_else (eq_attr "is_thumb" "no")
9774 (if_then_else (eq_attr "is_thumb" "no")
9777 (set_attr "type" "multiple")]
9780 (define_insn "*cmp_ior"
9781 [(set (match_operand 6 "dominant_cc_register" "")
9784 (match_operator 4 "arm_comparison_operator"
9785 [(match_operand:SI 0 "s_register_operand"
9786 "l,l,l,r,r,r,r,r,r")
9787 (match_operand:SI 1 "arm_add_operand"
9788 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9789 (match_operator:SI 5 "arm_comparison_operator"
9790 [(match_operand:SI 2 "s_register_operand"
9791 "l,r,r,l,l,r,r,r,r")
9792 (match_operand:SI 3 "arm_add_operand"
9793 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9798 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9802 {\"cmn\\t%0, #%n1\",
9805 \"cmn\\t%2, #%n3\"},
9806 {\"cmn\\t%0, #%n1\",
9809 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9811 {\"cmp%D4\\t%2, %3\",
9812 \"cmp%D5\\t%0, %1\"},
9813 {\"cmp%D4\\t%2, %3\",
9814 \"cmn%D5\\t%0, #%n1\"},
9815 {\"cmn%D4\\t%2, #%n3\",
9816 \"cmp%D5\\t%0, %1\"},
9817 {\"cmn%D4\\t%2, #%n3\",
9818 \"cmn%D5\\t%0, #%n1\"}
9820 static const char *const ite[2] =
9825 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9826 CMP_CMP, CMN_CMP, CMP_CMP,
9827 CMN_CMP, CMP_CMN, CMN_CMN};
9829 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9831 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9832 if (TARGET_THUMB2) {
9833 output_asm_insn (ite[swap], operands);
9835 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9839 [(set_attr "conds" "set")
9840 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9841 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9842 (set_attr_alternative "length"
9848 (if_then_else (eq_attr "is_thumb" "no")
9851 (if_then_else (eq_attr "is_thumb" "no")
9854 (if_then_else (eq_attr "is_thumb" "no")
9857 (if_then_else (eq_attr "is_thumb" "no")
9860 (set_attr "type" "multiple")]
9863 (define_insn_and_split "*ior_scc_scc"
9864 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9865 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9866 [(match_operand:SI 1 "s_register_operand" "l,r")
9867 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9868 (match_operator:SI 6 "arm_comparison_operator"
9869 [(match_operand:SI 4 "s_register_operand" "l,r")
9870 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9871 (clobber (reg:CC CC_REGNUM))]
9873 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9876 "TARGET_32BIT && reload_completed"
9880 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9881 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9883 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9885 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9888 [(set_attr "conds" "clob")
9889 (set_attr "enabled_for_short_it" "yes,no")
9890 (set_attr "length" "16")
9891 (set_attr "type" "multiple")]
9894 ; If the above pattern is followed by a CMP insn, then the compare is
9895 ; redundant, since we can rework the conditional instruction that follows.
9896 (define_insn_and_split "*ior_scc_scc_cmp"
9897 [(set (match_operand 0 "dominant_cc_register" "")
9898 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9899 [(match_operand:SI 1 "s_register_operand" "l,r")
9900 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9901 (match_operator:SI 6 "arm_comparison_operator"
9902 [(match_operand:SI 4 "s_register_operand" "l,r")
9903 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9905 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9906 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9907 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9910 "TARGET_32BIT && reload_completed"
9914 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9915 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9917 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9919 [(set_attr "conds" "set")
9920 (set_attr "enabled_for_short_it" "yes,no")
9921 (set_attr "length" "16")
9922 (set_attr "type" "multiple")]
9925 (define_insn_and_split "*and_scc_scc"
9926 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9927 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9928 [(match_operand:SI 1 "s_register_operand" "l,r")
9929 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9930 (match_operator:SI 6 "arm_comparison_operator"
9931 [(match_operand:SI 4 "s_register_operand" "l,r")
9932 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9933 (clobber (reg:CC CC_REGNUM))]
9935 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9938 "TARGET_32BIT && reload_completed
9939 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9944 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9945 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9947 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9949 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9952 [(set_attr "conds" "clob")
9953 (set_attr "enabled_for_short_it" "yes,no")
9954 (set_attr "length" "16")
9955 (set_attr "type" "multiple")]
9958 ; If the above pattern is followed by a CMP insn, then the compare is
9959 ; redundant, since we can rework the conditional instruction that follows.
9960 (define_insn_and_split "*and_scc_scc_cmp"
9961 [(set (match_operand 0 "dominant_cc_register" "")
9962 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9963 [(match_operand:SI 1 "s_register_operand" "l,r")
9964 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9965 (match_operator:SI 6 "arm_comparison_operator"
9966 [(match_operand:SI 4 "s_register_operand" "l,r")
9967 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9969 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9970 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9971 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9974 "TARGET_32BIT && reload_completed"
9978 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9979 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9981 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9983 [(set_attr "conds" "set")
9984 (set_attr "enabled_for_short_it" "yes,no")
9985 (set_attr "length" "16")
9986 (set_attr "type" "multiple")]
9989 ;; If there is no dominance in the comparison, then we can still save an
9990 ;; instruction in the AND case, since we can know that the second compare
9991 ;; need only zero the value if false (if true, then the value is already
9993 (define_insn_and_split "*and_scc_scc_nodom"
9994 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9995 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9996 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9997 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9998 (match_operator:SI 6 "arm_comparison_operator"
9999 [(match_operand:SI 4 "s_register_operand" "r,r,r")
10000 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
10001 (clobber (reg:CC CC_REGNUM))]
10003 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
10006 "TARGET_32BIT && reload_completed"
10007 [(parallel [(set (match_dup 0)
10008 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
10009 (clobber (reg:CC CC_REGNUM))])
10010 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
10012 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
10015 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
10016 operands[4], operands[5]),
10018 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
10020 [(set_attr "conds" "clob")
10021 (set_attr "length" "20")
10022 (set_attr "type" "multiple")]
10026 [(set (reg:CC_NOOV CC_REGNUM)
10027 (compare:CC_NOOV (ior:SI
10028 (and:SI (match_operand:SI 0 "s_register_operand" "")
10030 (match_operator:SI 1 "arm_comparison_operator"
10031 [(match_operand:SI 2 "s_register_operand" "")
10032 (match_operand:SI 3 "arm_add_operand" "")]))
10034 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10036 [(set (match_dup 4)
10037 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10039 (set (reg:CC_NOOV CC_REGNUM)
10040 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10045 [(set (reg:CC_NOOV CC_REGNUM)
10046 (compare:CC_NOOV (ior:SI
10047 (match_operator:SI 1 "arm_comparison_operator"
10048 [(match_operand:SI 2 "s_register_operand" "")
10049 (match_operand:SI 3 "arm_add_operand" "")])
10050 (and:SI (match_operand:SI 0 "s_register_operand" "")
10053 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10055 [(set (match_dup 4)
10056 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10058 (set (reg:CC_NOOV CC_REGNUM)
10059 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10062 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10064 (define_insn_and_split "*negscc"
10065 [(set (match_operand:SI 0 "s_register_operand" "=r")
10066 (neg:SI (match_operator 3 "arm_comparison_operator"
10067 [(match_operand:SI 1 "s_register_operand" "r")
10068 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10069 (clobber (reg:CC CC_REGNUM))]
10072 "&& reload_completed"
10075 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10077 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10079 /* Emit mov\\t%0, %1, asr #31 */
10080 emit_insn (gen_rtx_SET (operands[0],
10081 gen_rtx_ASHIFTRT (SImode,
10086 else if (GET_CODE (operands[3]) == NE)
10088 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10089 if (CONST_INT_P (operands[2]))
10090 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10091 gen_int_mode (-INTVAL (operands[2]),
10094 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10096 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10097 gen_rtx_NE (SImode,
10100 gen_rtx_SET (operands[0],
10106 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10107 emit_insn (gen_rtx_SET (cc_reg,
10108 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10109 enum rtx_code rc = GET_CODE (operands[3]);
10111 rc = reverse_condition (rc);
10112 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10113 gen_rtx_fmt_ee (rc,
10117 gen_rtx_SET (operands[0], const0_rtx)));
10118 rc = GET_CODE (operands[3]);
10119 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10120 gen_rtx_fmt_ee (rc,
10124 gen_rtx_SET (operands[0],
10130 [(set_attr "conds" "clob")
10131 (set_attr "length" "12")
10132 (set_attr "type" "multiple")]
10135 (define_insn_and_split "movcond_addsi"
10136 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
10138 (match_operator 5 "comparison_operator"
10139 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
10140 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
10142 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
10143 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
10144 (clobber (reg:CC CC_REGNUM))]
10147 "&& reload_completed"
10148 [(set (reg:CC_NOOV CC_REGNUM)
10150 (plus:SI (match_dup 3)
10153 (set (match_dup 0) (match_dup 1))
10154 (cond_exec (match_dup 6)
10155 (set (match_dup 0) (match_dup 2)))]
10158 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
10159 operands[3], operands[4]);
10160 enum rtx_code rc = GET_CODE (operands[5]);
10161 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10162 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
10163 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
10164 rc = reverse_condition (rc);
10166 std::swap (operands[1], operands[2]);
10168 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10171 [(set_attr "conds" "clob")
10172 (set_attr "enabled_for_short_it" "no,yes,yes")
10173 (set_attr "type" "multiple")]
10176 (define_insn "movcond"
10177 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10179 (match_operator 5 "arm_comparison_operator"
10180 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10181 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
10182 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10183 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
10184 (clobber (reg:CC CC_REGNUM))]
10187 if (GET_CODE (operands[5]) == LT
10188 && (operands[4] == const0_rtx))
10190 if (which_alternative != 1 && REG_P (operands[1]))
10192 if (operands[2] == const0_rtx)
10193 return \"and\\t%0, %1, %3, asr #31\";
10194 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
10196 else if (which_alternative != 0 && REG_P (operands[2]))
10198 if (operands[1] == const0_rtx)
10199 return \"bic\\t%0, %2, %3, asr #31\";
10200 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
10202 /* The only case that falls through to here is when both ops 1 & 2
10206 if (GET_CODE (operands[5]) == GE
10207 && (operands[4] == const0_rtx))
10209 if (which_alternative != 1 && REG_P (operands[1]))
10211 if (operands[2] == const0_rtx)
10212 return \"bic\\t%0, %1, %3, asr #31\";
10213 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
10215 else if (which_alternative != 0 && REG_P (operands[2]))
10217 if (operands[1] == const0_rtx)
10218 return \"and\\t%0, %2, %3, asr #31\";
10219 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
10221 /* The only case that falls through to here is when both ops 1 & 2
10224 if (CONST_INT_P (operands[4])
10225 && !const_ok_for_arm (INTVAL (operands[4])))
10226 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
10228 output_asm_insn (\"cmp\\t%3, %4\", operands);
10229 if (which_alternative != 0)
10230 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
10231 if (which_alternative != 1)
10232 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
10235 [(set_attr "conds" "clob")
10236 (set_attr "length" "8,8,12")
10237 (set_attr "type" "multiple")]
10240 ;; ??? The patterns below need checking for Thumb-2 usefulness.
10242 (define_insn "*ifcompare_plus_move"
10243 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10244 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10245 [(match_operand:SI 4 "s_register_operand" "r,r")
10246 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10248 (match_operand:SI 2 "s_register_operand" "r,r")
10249 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10250 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10251 (clobber (reg:CC CC_REGNUM))]
10254 [(set_attr "conds" "clob")
10255 (set_attr "length" "8,12")
10256 (set_attr "type" "multiple")]
10259 (define_insn "*if_plus_move"
10260 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10262 (match_operator 4 "arm_comparison_operator"
10263 [(match_operand 5 "cc_register" "") (const_int 0)])
10265 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10266 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10267 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10270 add%d4\\t%0, %2, %3
10271 sub%d4\\t%0, %2, #%n3
10272 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10273 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10274 [(set_attr "conds" "use")
10275 (set_attr "length" "4,4,8,8")
10276 (set_attr_alternative "type"
10277 [(if_then_else (match_operand 3 "const_int_operand" "")
10278 (const_string "alu_imm" )
10279 (const_string "alu_sreg"))
10280 (const_string "alu_imm")
10281 (const_string "multiple")
10282 (const_string "multiple")])]
10285 (define_insn "*ifcompare_move_plus"
10286 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10287 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10288 [(match_operand:SI 4 "s_register_operand" "r,r")
10289 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10290 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10292 (match_operand:SI 2 "s_register_operand" "r,r")
10293 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10294 (clobber (reg:CC CC_REGNUM))]
10297 [(set_attr "conds" "clob")
10298 (set_attr "length" "8,12")
10299 (set_attr "type" "multiple")]
10302 (define_insn "*if_move_plus"
10303 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10305 (match_operator 4 "arm_comparison_operator"
10306 [(match_operand 5 "cc_register" "") (const_int 0)])
10307 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10309 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10310 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10313 add%D4\\t%0, %2, %3
10314 sub%D4\\t%0, %2, #%n3
10315 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10316 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10317 [(set_attr "conds" "use")
10318 (set_attr "length" "4,4,8,8")
10319 (set_attr_alternative "type"
10320 [(if_then_else (match_operand 3 "const_int_operand" "")
10321 (const_string "alu_imm" )
10322 (const_string "alu_sreg"))
10323 (const_string "alu_imm")
10324 (const_string "multiple")
10325 (const_string "multiple")])]
10328 (define_insn "*ifcompare_arith_arith"
10329 [(set (match_operand:SI 0 "s_register_operand" "=r")
10330 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10331 [(match_operand:SI 5 "s_register_operand" "r")
10332 (match_operand:SI 6 "arm_add_operand" "rIL")])
10333 (match_operator:SI 8 "shiftable_operator"
10334 [(match_operand:SI 1 "s_register_operand" "r")
10335 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10336 (match_operator:SI 7 "shiftable_operator"
10337 [(match_operand:SI 3 "s_register_operand" "r")
10338 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10339 (clobber (reg:CC CC_REGNUM))]
10342 [(set_attr "conds" "clob")
10343 (set_attr "length" "12")
10344 (set_attr "type" "multiple")]
10347 (define_insn "*if_arith_arith"
10348 [(set (match_operand:SI 0 "s_register_operand" "=r")
10349 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10350 [(match_operand 8 "cc_register" "") (const_int 0)])
10351 (match_operator:SI 6 "shiftable_operator"
10352 [(match_operand:SI 1 "s_register_operand" "r")
10353 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10354 (match_operator:SI 7 "shiftable_operator"
10355 [(match_operand:SI 3 "s_register_operand" "r")
10356 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10358 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10359 [(set_attr "conds" "use")
10360 (set_attr "length" "8")
10361 (set_attr "type" "multiple")]
10364 (define_insn "*ifcompare_arith_move"
10365 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10366 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10367 [(match_operand:SI 2 "s_register_operand" "r,r")
10368 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10369 (match_operator:SI 7 "shiftable_operator"
10370 [(match_operand:SI 4 "s_register_operand" "r,r")
10371 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10372 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10373 (clobber (reg:CC CC_REGNUM))]
10376 /* If we have an operation where (op x 0) is the identity operation and
10377 the conditional operator is LT or GE and we are comparing against zero and
10378 everything is in registers then we can do this in two instructions. */
10379 if (operands[3] == const0_rtx
10380 && GET_CODE (operands[7]) != AND
10381 && REG_P (operands[5])
10382 && REG_P (operands[1])
10383 && REGNO (operands[1]) == REGNO (operands[4])
10384 && REGNO (operands[4]) != REGNO (operands[0]))
10386 if (GET_CODE (operands[6]) == LT)
10387 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10388 else if (GET_CODE (operands[6]) == GE)
10389 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10391 if (CONST_INT_P (operands[3])
10392 && !const_ok_for_arm (INTVAL (operands[3])))
10393 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10395 output_asm_insn (\"cmp\\t%2, %3\", operands);
10396 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10397 if (which_alternative != 0)
10398 return \"mov%D6\\t%0, %1\";
10401 [(set_attr "conds" "clob")
10402 (set_attr "length" "8,12")
10403 (set_attr "type" "multiple")]
10406 (define_insn "*if_arith_move"
10407 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10408 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10409 [(match_operand 6 "cc_register" "") (const_int 0)])
10410 (match_operator:SI 5 "shiftable_operator"
10411 [(match_operand:SI 2 "s_register_operand" "r,r")
10412 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10413 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10416 %I5%d4\\t%0, %2, %3
10417 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10418 [(set_attr "conds" "use")
10419 (set_attr "length" "4,8")
10420 (set_attr_alternative "type"
10421 [(if_then_else (match_operand 3 "const_int_operand" "")
10422 (const_string "alu_shift_imm" )
10423 (const_string "alu_shift_reg"))
10424 (const_string "multiple")])]
10427 (define_insn "*ifcompare_move_arith"
10428 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10429 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10430 [(match_operand:SI 4 "s_register_operand" "r,r")
10431 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10432 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10433 (match_operator:SI 7 "shiftable_operator"
10434 [(match_operand:SI 2 "s_register_operand" "r,r")
10435 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10436 (clobber (reg:CC CC_REGNUM))]
10439 /* If we have an operation where (op x 0) is the identity operation and
10440 the conditional operator is LT or GE and we are comparing against zero and
10441 everything is in registers then we can do this in two instructions */
10442 if (operands[5] == const0_rtx
10443 && GET_CODE (operands[7]) != AND
10444 && REG_P (operands[3])
10445 && REG_P (operands[1])
10446 && REGNO (operands[1]) == REGNO (operands[2])
10447 && REGNO (operands[2]) != REGNO (operands[0]))
10449 if (GET_CODE (operands[6]) == GE)
10450 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10451 else if (GET_CODE (operands[6]) == LT)
10452 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10455 if (CONST_INT_P (operands[5])
10456 && !const_ok_for_arm (INTVAL (operands[5])))
10457 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10459 output_asm_insn (\"cmp\\t%4, %5\", operands);
10461 if (which_alternative != 0)
10462 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10463 return \"%I7%D6\\t%0, %2, %3\";
10465 [(set_attr "conds" "clob")
10466 (set_attr "length" "8,12")
10467 (set_attr "type" "multiple")]
10470 (define_insn "*if_move_arith"
10471 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10473 (match_operator 4 "arm_comparison_operator"
10474 [(match_operand 6 "cc_register" "") (const_int 0)])
10475 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10476 (match_operator:SI 5 "shiftable_operator"
10477 [(match_operand:SI 2 "s_register_operand" "r,r")
10478 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10481 %I5%D4\\t%0, %2, %3
10482 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10483 [(set_attr "conds" "use")
10484 (set_attr "length" "4,8")
10485 (set_attr_alternative "type"
10486 [(if_then_else (match_operand 3 "const_int_operand" "")
10487 (const_string "alu_shift_imm" )
10488 (const_string "alu_shift_reg"))
10489 (const_string "multiple")])]
10492 (define_insn "*ifcompare_move_not"
10493 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10495 (match_operator 5 "arm_comparison_operator"
10496 [(match_operand:SI 3 "s_register_operand" "r,r")
10497 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10498 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10500 (match_operand:SI 2 "s_register_operand" "r,r"))))
10501 (clobber (reg:CC CC_REGNUM))]
10504 [(set_attr "conds" "clob")
10505 (set_attr "length" "8,12")
10506 (set_attr "type" "multiple")]
10509 (define_insn "*if_move_not"
10510 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10512 (match_operator 4 "arm_comparison_operator"
10513 [(match_operand 3 "cc_register" "") (const_int 0)])
10514 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10515 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10519 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10520 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10521 [(set_attr "conds" "use")
10522 (set_attr "type" "mvn_reg")
10523 (set_attr "length" "4,8,8")
10524 (set_attr "type" "mvn_reg,multiple,multiple")]
10527 (define_insn "*ifcompare_not_move"
10528 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10530 (match_operator 5 "arm_comparison_operator"
10531 [(match_operand:SI 3 "s_register_operand" "r,r")
10532 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10534 (match_operand:SI 2 "s_register_operand" "r,r"))
10535 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10536 (clobber (reg:CC CC_REGNUM))]
10539 [(set_attr "conds" "clob")
10540 (set_attr "length" "8,12")
10541 (set_attr "type" "multiple")]
10544 (define_insn "*if_not_move"
10545 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10547 (match_operator 4 "arm_comparison_operator"
10548 [(match_operand 3 "cc_register" "") (const_int 0)])
10549 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10550 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10554 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10555 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10556 [(set_attr "conds" "use")
10557 (set_attr "type" "mvn_reg,multiple,multiple")
10558 (set_attr "length" "4,8,8")]
10561 (define_insn "*ifcompare_shift_move"
10562 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10564 (match_operator 6 "arm_comparison_operator"
10565 [(match_operand:SI 4 "s_register_operand" "r,r")
10566 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10567 (match_operator:SI 7 "shift_operator"
10568 [(match_operand:SI 2 "s_register_operand" "r,r")
10569 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10570 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10571 (clobber (reg:CC CC_REGNUM))]
10574 [(set_attr "conds" "clob")
10575 (set_attr "length" "8,12")
10576 (set_attr "type" "multiple")]
10579 (define_insn "*if_shift_move"
10580 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10582 (match_operator 5 "arm_comparison_operator"
10583 [(match_operand 6 "cc_register" "") (const_int 0)])
10584 (match_operator:SI 4 "shift_operator"
10585 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10586 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10587 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10591 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10592 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10593 [(set_attr "conds" "use")
10594 (set_attr "shift" "2")
10595 (set_attr "length" "4,8,8")
10596 (set_attr_alternative "type"
10597 [(if_then_else (match_operand 3 "const_int_operand" "")
10598 (const_string "mov_shift" )
10599 (const_string "mov_shift_reg"))
10600 (const_string "multiple")
10601 (const_string "multiple")])]
10604 (define_insn "*ifcompare_move_shift"
10605 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10607 (match_operator 6 "arm_comparison_operator"
10608 [(match_operand:SI 4 "s_register_operand" "r,r")
10609 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10610 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10611 (match_operator:SI 7 "shift_operator"
10612 [(match_operand:SI 2 "s_register_operand" "r,r")
10613 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10614 (clobber (reg:CC CC_REGNUM))]
10617 [(set_attr "conds" "clob")
10618 (set_attr "length" "8,12")
10619 (set_attr "type" "multiple")]
10622 (define_insn "*if_move_shift"
10623 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10625 (match_operator 5 "arm_comparison_operator"
10626 [(match_operand 6 "cc_register" "") (const_int 0)])
10627 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10628 (match_operator:SI 4 "shift_operator"
10629 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10630 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10634 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10635 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10636 [(set_attr "conds" "use")
10637 (set_attr "shift" "2")
10638 (set_attr "length" "4,8,8")
10639 (set_attr_alternative "type"
10640 [(if_then_else (match_operand 3 "const_int_operand" "")
10641 (const_string "mov_shift" )
10642 (const_string "mov_shift_reg"))
10643 (const_string "multiple")
10644 (const_string "multiple")])]
10647 (define_insn "*ifcompare_shift_shift"
10648 [(set (match_operand:SI 0 "s_register_operand" "=r")
10650 (match_operator 7 "arm_comparison_operator"
10651 [(match_operand:SI 5 "s_register_operand" "r")
10652 (match_operand:SI 6 "arm_add_operand" "rIL")])
10653 (match_operator:SI 8 "shift_operator"
10654 [(match_operand:SI 1 "s_register_operand" "r")
10655 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10656 (match_operator:SI 9 "shift_operator"
10657 [(match_operand:SI 3 "s_register_operand" "r")
10658 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10659 (clobber (reg:CC CC_REGNUM))]
10662 [(set_attr "conds" "clob")
10663 (set_attr "length" "12")
10664 (set_attr "type" "multiple")]
10667 (define_insn "*if_shift_shift"
10668 [(set (match_operand:SI 0 "s_register_operand" "=r")
10670 (match_operator 5 "arm_comparison_operator"
10671 [(match_operand 8 "cc_register" "") (const_int 0)])
10672 (match_operator:SI 6 "shift_operator"
10673 [(match_operand:SI 1 "s_register_operand" "r")
10674 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10675 (match_operator:SI 7 "shift_operator"
10676 [(match_operand:SI 3 "s_register_operand" "r")
10677 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10679 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10680 [(set_attr "conds" "use")
10681 (set_attr "shift" "1")
10682 (set_attr "length" "8")
10683 (set (attr "type") (if_then_else
10684 (and (match_operand 2 "const_int_operand" "")
10685 (match_operand 4 "const_int_operand" ""))
10686 (const_string "mov_shift")
10687 (const_string "mov_shift_reg")))]
10690 (define_insn "*ifcompare_not_arith"
10691 [(set (match_operand:SI 0 "s_register_operand" "=r")
10693 (match_operator 6 "arm_comparison_operator"
10694 [(match_operand:SI 4 "s_register_operand" "r")
10695 (match_operand:SI 5 "arm_add_operand" "rIL")])
10696 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10697 (match_operator:SI 7 "shiftable_operator"
10698 [(match_operand:SI 2 "s_register_operand" "r")
10699 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10700 (clobber (reg:CC CC_REGNUM))]
10703 [(set_attr "conds" "clob")
10704 (set_attr "length" "12")
10705 (set_attr "type" "multiple")]
10708 (define_insn "*if_not_arith"
10709 [(set (match_operand:SI 0 "s_register_operand" "=r")
10711 (match_operator 5 "arm_comparison_operator"
10712 [(match_operand 4 "cc_register" "") (const_int 0)])
10713 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10714 (match_operator:SI 6 "shiftable_operator"
10715 [(match_operand:SI 2 "s_register_operand" "r")
10716 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10718 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10719 [(set_attr "conds" "use")
10720 (set_attr "type" "mvn_reg")
10721 (set_attr "length" "8")]
10724 (define_insn "*ifcompare_arith_not"
10725 [(set (match_operand:SI 0 "s_register_operand" "=r")
10727 (match_operator 6 "arm_comparison_operator"
10728 [(match_operand:SI 4 "s_register_operand" "r")
10729 (match_operand:SI 5 "arm_add_operand" "rIL")])
10730 (match_operator:SI 7 "shiftable_operator"
10731 [(match_operand:SI 2 "s_register_operand" "r")
10732 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10733 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10734 (clobber (reg:CC CC_REGNUM))]
10737 [(set_attr "conds" "clob")
10738 (set_attr "length" "12")
10739 (set_attr "type" "multiple")]
10742 (define_insn "*if_arith_not"
10743 [(set (match_operand:SI 0 "s_register_operand" "=r")
10745 (match_operator 5 "arm_comparison_operator"
10746 [(match_operand 4 "cc_register" "") (const_int 0)])
10747 (match_operator:SI 6 "shiftable_operator"
10748 [(match_operand:SI 2 "s_register_operand" "r")
10749 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10750 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10752 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10753 [(set_attr "conds" "use")
10754 (set_attr "type" "multiple")
10755 (set_attr "length" "8")]
10758 (define_insn "*ifcompare_neg_move"
10759 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10761 (match_operator 5 "arm_comparison_operator"
10762 [(match_operand:SI 3 "s_register_operand" "r,r")
10763 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10764 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10765 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10766 (clobber (reg:CC CC_REGNUM))]
10769 [(set_attr "conds" "clob")
10770 (set_attr "length" "8,12")
10771 (set_attr "type" "multiple")]
10774 (define_insn_and_split "*if_neg_move"
10775 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10777 (match_operator 4 "arm_comparison_operator"
10778 [(match_operand 3 "cc_register" "") (const_int 0)])
10779 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10780 (match_operand:SI 1 "s_register_operand" "0,0")))]
10783 "&& reload_completed"
10784 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10785 (set (match_dup 0) (neg:SI (match_dup 2))))]
10787 [(set_attr "conds" "use")
10788 (set_attr "length" "4")
10789 (set_attr "arch" "t2,32")
10790 (set_attr "enabled_for_short_it" "yes,no")
10791 (set_attr "type" "logic_shift_imm")]
10794 (define_insn "*ifcompare_move_neg"
10795 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10797 (match_operator 5 "arm_comparison_operator"
10798 [(match_operand:SI 3 "s_register_operand" "r,r")
10799 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10800 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10801 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10802 (clobber (reg:CC CC_REGNUM))]
10805 [(set_attr "conds" "clob")
10806 (set_attr "length" "8,12")
10807 (set_attr "type" "multiple")]
10810 (define_insn_and_split "*if_move_neg"
10811 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10813 (match_operator 4 "arm_comparison_operator"
10814 [(match_operand 3 "cc_register" "") (const_int 0)])
10815 (match_operand:SI 1 "s_register_operand" "0,0")
10816 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10819 "&& reload_completed"
10820 [(cond_exec (match_dup 5)
10821 (set (match_dup 0) (neg:SI (match_dup 2))))]
10823 machine_mode mode = GET_MODE (operands[3]);
10824 rtx_code rc = GET_CODE (operands[4]);
10826 if (mode == CCFPmode || mode == CCFPEmode)
10827 rc = reverse_condition_maybe_unordered (rc);
10829 rc = reverse_condition (rc);
10831 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10833 [(set_attr "conds" "use")
10834 (set_attr "length" "4")
10835 (set_attr "arch" "t2,32")
10836 (set_attr "enabled_for_short_it" "yes,no")
10837 (set_attr "type" "logic_shift_imm")]
10840 (define_insn "*arith_adjacentmem"
10841 [(set (match_operand:SI 0 "s_register_operand" "=r")
10842 (match_operator:SI 1 "shiftable_operator"
10843 [(match_operand:SI 2 "memory_operand" "m")
10844 (match_operand:SI 3 "memory_operand" "m")]))
10845 (clobber (match_scratch:SI 4 "=r"))]
10846 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10852 HOST_WIDE_INT val1 = 0, val2 = 0;
10854 if (REGNO (operands[0]) > REGNO (operands[4]))
10856 ldm[1] = operands[4];
10857 ldm[2] = operands[0];
10861 ldm[1] = operands[0];
10862 ldm[2] = operands[4];
10865 base_reg = XEXP (operands[2], 0);
10867 if (!REG_P (base_reg))
10869 val1 = INTVAL (XEXP (base_reg, 1));
10870 base_reg = XEXP (base_reg, 0);
10873 if (!REG_P (XEXP (operands[3], 0)))
10874 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10876 arith[0] = operands[0];
10877 arith[3] = operands[1];
10891 if (val1 !=0 && val2 != 0)
10895 if (val1 == 4 || val2 == 4)
10896 /* Other val must be 8, since we know they are adjacent and neither
10898 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10899 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10901 ldm[0] = ops[0] = operands[4];
10903 ops[2] = GEN_INT (val1);
10904 output_add_immediate (ops);
10906 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10908 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10912 /* Offset is out of range for a single add, so use two ldr. */
10915 ops[2] = GEN_INT (val1);
10916 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10918 ops[2] = GEN_INT (val2);
10919 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10922 else if (val1 != 0)
10925 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10927 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10932 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10934 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10936 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10939 [(set_attr "length" "12")
10940 (set_attr "predicable" "yes")
10941 (set_attr "type" "load_4")]
10944 ; This pattern is never tried by combine, so do it as a peephole
10947 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10948 (match_operand:SI 1 "arm_general_register_operand" ""))
10949 (set (reg:CC CC_REGNUM)
10950 (compare:CC (match_dup 1) (const_int 0)))]
10952 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10953 (set (match_dup 0) (match_dup 1))])]
10958 [(set (match_operand:SI 0 "s_register_operand" "")
10959 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10961 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10962 [(match_operand:SI 3 "s_register_operand" "")
10963 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10964 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10966 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10967 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10972 ;; This split can be used because CC_Z mode implies that the following
10973 ;; branch will be an equality, or an unsigned inequality, so the sign
10974 ;; extension is not needed.
10977 [(set (reg:CC_Z CC_REGNUM)
10979 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10981 (match_operand 1 "const_int_operand" "")))
10982 (clobber (match_scratch:SI 2 ""))]
10984 && ((UINTVAL (operands[1]))
10985 == ((UINTVAL (operands[1])) >> 24) << 24)"
10986 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10987 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10989 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10992 ;; ??? Check the patterns above for Thumb-2 usefulness
10994 (define_expand "prologue"
10995 [(clobber (const_int 0))]
10998 arm_expand_prologue ();
11000 thumb1_expand_prologue ();
11005 (define_expand "epilogue"
11006 [(clobber (const_int 0))]
11009 if (crtl->calls_eh_return)
11010 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
11013 thumb1_expand_epilogue ();
11014 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
11015 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
11017 else if (HAVE_return)
11019 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
11020 no need for explicit testing again. */
11021 emit_jump_insn (gen_return ());
11023 else if (TARGET_32BIT)
11025 arm_expand_epilogue (true);
11031 ;; Note - although unspec_volatile's USE all hard registers,
11032 ;; USEs are ignored after relaod has completed. Thus we need
11033 ;; to add an unspec of the link register to ensure that flow
11034 ;; does not think that it is unused by the sibcall branch that
11035 ;; will replace the standard function epilogue.
11036 (define_expand "sibcall_epilogue"
11037 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
11038 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
11041 arm_expand_epilogue (false);
11046 (define_expand "eh_epilogue"
11047 [(use (match_operand:SI 0 "register_operand"))
11048 (use (match_operand:SI 1 "register_operand"))
11049 (use (match_operand:SI 2 "register_operand"))]
11053 cfun->machine->eh_epilogue_sp_ofs = operands[1];
11054 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11056 rtx ra = gen_rtx_REG (Pmode, 2);
11058 emit_move_insn (ra, operands[2]);
11061 /* This is a hack -- we may have crystalized the function type too
11063 cfun->machine->func_type = 0;
11067 ;; This split is only used during output to reduce the number of patterns
11068 ;; that need assembler instructions adding to them. We allowed the setting
11069 ;; of the conditions to be implicit during rtl generation so that
11070 ;; the conditional compare patterns would work. However this conflicts to
11071 ;; some extent with the conditional data operations, so we have to split them
11074 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
11075 ;; conditional execution sufficient?
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 "" "")])
11082 (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_dup 7)
11087 (set (match_dup 0) (match_dup 4)))]
11090 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11091 operands[2], operands[3]);
11092 enum rtx_code rc = GET_CODE (operands[1]);
11094 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11095 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11096 if (mode == CCFPmode || mode == CCFPEmode)
11097 rc = reverse_condition_maybe_unordered (rc);
11099 rc = reverse_condition (rc);
11101 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11106 [(set (match_operand:SI 0 "s_register_operand" "")
11107 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11108 [(match_operand 2 "" "") (match_operand 3 "" "")])
11109 (match_operand 4 "" "")
11111 (clobber (reg:CC CC_REGNUM))]
11112 "TARGET_ARM && reload_completed"
11113 [(set (match_dup 5) (match_dup 6))
11114 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11115 (set (match_dup 0) (match_dup 4)))]
11118 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11119 operands[2], operands[3]);
11121 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11122 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11127 [(set (match_operand:SI 0 "s_register_operand" "")
11128 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11129 [(match_operand 2 "" "") (match_operand 3 "" "")])
11130 (match_operand 4 "" "")
11131 (match_operand 5 "" "")))
11132 (clobber (reg:CC CC_REGNUM))]
11133 "TARGET_ARM && reload_completed"
11134 [(set (match_dup 6) (match_dup 7))
11135 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11136 (set (match_dup 0) (match_dup 4)))
11137 (cond_exec (match_dup 8)
11138 (set (match_dup 0) (match_dup 5)))]
11141 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11142 operands[2], operands[3]);
11143 enum rtx_code rc = GET_CODE (operands[1]);
11145 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11146 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11147 if (mode == CCFPmode || mode == CCFPEmode)
11148 rc = reverse_condition_maybe_unordered (rc);
11150 rc = reverse_condition (rc);
11152 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11157 [(set (match_operand:SI 0 "s_register_operand" "")
11158 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11159 [(match_operand:SI 2 "s_register_operand" "")
11160 (match_operand:SI 3 "arm_add_operand" "")])
11161 (match_operand:SI 4 "arm_rhs_operand" "")
11163 (match_operand:SI 5 "s_register_operand" ""))))
11164 (clobber (reg:CC CC_REGNUM))]
11165 "TARGET_ARM && reload_completed"
11166 [(set (match_dup 6) (match_dup 7))
11167 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11168 (set (match_dup 0) (match_dup 4)))
11169 (cond_exec (match_dup 8)
11170 (set (match_dup 0) (not:SI (match_dup 5))))]
11173 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11174 operands[2], operands[3]);
11175 enum rtx_code rc = GET_CODE (operands[1]);
11177 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11178 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11179 if (mode == CCFPmode || mode == CCFPEmode)
11180 rc = reverse_condition_maybe_unordered (rc);
11182 rc = reverse_condition (rc);
11184 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11188 (define_insn "*cond_move_not"
11189 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11190 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11191 [(match_operand 3 "cc_register" "") (const_int 0)])
11192 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11194 (match_operand:SI 2 "s_register_operand" "r,r"))))]
11198 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11199 [(set_attr "conds" "use")
11200 (set_attr "type" "mvn_reg,multiple")
11201 (set_attr "length" "4,8")]
11204 ;; The next two patterns occur when an AND operation is followed by a
11205 ;; scc insn sequence
11207 (define_insn "*sign_extract_onebit"
11208 [(set (match_operand:SI 0 "s_register_operand" "=r")
11209 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11211 (match_operand:SI 2 "const_int_operand" "n")))
11212 (clobber (reg:CC CC_REGNUM))]
11215 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11216 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
11217 return \"mvnne\\t%0, #0\";
11219 [(set_attr "conds" "clob")
11220 (set_attr "length" "8")
11221 (set_attr "type" "multiple")]
11224 (define_insn "*not_signextract_onebit"
11225 [(set (match_operand:SI 0 "s_register_operand" "=r")
11227 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11229 (match_operand:SI 2 "const_int_operand" "n"))))
11230 (clobber (reg:CC CC_REGNUM))]
11233 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11234 output_asm_insn (\"tst\\t%1, %2\", operands);
11235 output_asm_insn (\"mvneq\\t%0, #0\", operands);
11236 return \"movne\\t%0, #0\";
11238 [(set_attr "conds" "clob")
11239 (set_attr "length" "12")
11240 (set_attr "type" "multiple")]
11242 ;; ??? The above patterns need auditing for Thumb-2
11244 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
11245 ;; expressions. For simplicity, the first register is also in the unspec
11247 ;; To avoid the usage of GNU extension, the length attribute is computed
11248 ;; in a C function arm_attr_length_push_multi.
11249 (define_insn "*push_multi"
11250 [(match_parallel 2 "multi_register_push"
11251 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11252 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11253 UNSPEC_PUSH_MULT))])]
11257 int num_saves = XVECLEN (operands[2], 0);
11259 /* For the StrongARM at least it is faster to
11260 use STR to store only a single register.
11261 In Thumb mode always use push, and the assembler will pick
11262 something appropriate. */
11263 if (num_saves == 1 && TARGET_ARM)
11264 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11271 strcpy (pattern, \"push%?\\t{%1\");
11273 strcpy (pattern, \"push\\t{%1\");
11275 for (i = 1; i < num_saves; i++)
11277 strcat (pattern, \", %|\");
11279 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11282 strcat (pattern, \"}\");
11283 output_asm_insn (pattern, operands);
11288 [(set_attr "type" "store_16")
11289 (set (attr "length")
11290 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11293 (define_insn "stack_tie"
11294 [(set (mem:BLK (scratch))
11295 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11296 (match_operand:SI 1 "s_register_operand" "rk")]
11300 [(set_attr "length" "0")
11301 (set_attr "type" "block")]
11304 ;; Pop (as used in epilogue RTL)
11306 (define_insn "*load_multiple_with_writeback"
11307 [(match_parallel 0 "load_multiple_operation"
11308 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11309 (plus:SI (match_dup 1)
11310 (match_operand:SI 2 "const_int_I_operand" "I")))
11311 (set (match_operand:SI 3 "s_register_operand" "=rk")
11312 (mem:SI (match_dup 1)))
11314 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11317 arm_output_multireg_pop (operands, /*return_pc=*/false,
11318 /*cond=*/const_true_rtx,
11324 [(set_attr "type" "load_16")
11325 (set_attr "predicable" "yes")
11326 (set (attr "length")
11327 (symbol_ref "arm_attr_length_pop_multi (operands,
11328 /*return_pc=*/false,
11329 /*write_back_p=*/true)"))]
11332 ;; Pop with return (as used in epilogue RTL)
11334 ;; This instruction is generated when the registers are popped at the end of
11335 ;; epilogue. Here, instead of popping the value into LR and then generating
11336 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11338 (define_insn "*pop_multiple_with_writeback_and_return"
11339 [(match_parallel 0 "pop_multiple_return"
11341 (set (match_operand:SI 1 "s_register_operand" "+rk")
11342 (plus:SI (match_dup 1)
11343 (match_operand:SI 2 "const_int_I_operand" "I")))
11344 (set (match_operand:SI 3 "s_register_operand" "=rk")
11345 (mem:SI (match_dup 1)))
11347 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11350 arm_output_multireg_pop (operands, /*return_pc=*/true,
11351 /*cond=*/const_true_rtx,
11357 [(set_attr "type" "load_16")
11358 (set_attr "predicable" "yes")
11359 (set (attr "length")
11360 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11361 /*write_back_p=*/true)"))]
11364 (define_insn "*pop_multiple_with_return"
11365 [(match_parallel 0 "pop_multiple_return"
11367 (set (match_operand:SI 2 "s_register_operand" "=rk")
11368 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11370 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11373 arm_output_multireg_pop (operands, /*return_pc=*/true,
11374 /*cond=*/const_true_rtx,
11380 [(set_attr "type" "load_16")
11381 (set_attr "predicable" "yes")
11382 (set (attr "length")
11383 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11384 /*write_back_p=*/false)"))]
11387 ;; Load into PC and return
11388 (define_insn "*ldr_with_return"
11390 (set (reg:SI PC_REGNUM)
11391 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11392 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11393 "ldr%?\t%|pc, [%0], #4"
11394 [(set_attr "type" "load_4")
11395 (set_attr "predicable" "yes")]
11397 ;; Pop for floating point registers (as used in epilogue RTL)
11398 (define_insn "*vfp_pop_multiple_with_writeback"
11399 [(match_parallel 0 "pop_multiple_fp"
11400 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11401 (plus:SI (match_dup 1)
11402 (match_operand:SI 2 "const_int_I_operand" "I")))
11403 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11404 (mem:DF (match_dup 1)))])]
11405 "TARGET_32BIT && TARGET_HARD_FLOAT"
11408 int num_regs = XVECLEN (operands[0], 0);
11411 strcpy (pattern, \"vldm\\t\");
11412 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11413 strcat (pattern, \"!, {\");
11414 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11415 strcat (pattern, \"%P0\");
11416 if ((num_regs - 1) > 1)
11418 strcat (pattern, \"-%P1\");
11419 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11422 strcat (pattern, \"}\");
11423 output_asm_insn (pattern, op_list);
11427 [(set_attr "type" "load_16")
11428 (set_attr "conds" "unconditional")
11429 (set_attr "predicable" "no")]
11432 ;; Special patterns for dealing with the constant pool
11434 (define_insn "align_4"
11435 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11438 assemble_align (32);
11441 [(set_attr "type" "no_insn")]
11444 (define_insn "align_8"
11445 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11448 assemble_align (64);
11451 [(set_attr "type" "no_insn")]
11454 (define_insn "consttable_end"
11455 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11458 making_const_table = FALSE;
11461 [(set_attr "type" "no_insn")]
11464 (define_insn "consttable_1"
11465 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11468 making_const_table = TRUE;
11469 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11470 assemble_zeros (3);
11473 [(set_attr "length" "4")
11474 (set_attr "type" "no_insn")]
11477 (define_insn "consttable_2"
11478 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11482 rtx x = operands[0];
11483 making_const_table = TRUE;
11484 switch (GET_MODE_CLASS (GET_MODE (x)))
11487 arm_emit_fp16_const (x);
11490 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11491 assemble_zeros (2);
11496 [(set_attr "length" "4")
11497 (set_attr "type" "no_insn")]
11500 (define_insn "consttable_4"
11501 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11505 rtx x = operands[0];
11506 making_const_table = TRUE;
11507 scalar_float_mode float_mode;
11508 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11509 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11512 /* XXX: Sometimes gcc does something really dumb and ends up with
11513 a HIGH in a constant pool entry, usually because it's trying to
11514 load into a VFP register. We know this will always be used in
11515 combination with a LO_SUM which ignores the high bits, so just
11516 strip off the HIGH. */
11517 if (GET_CODE (x) == HIGH)
11519 assemble_integer (x, 4, BITS_PER_WORD, 1);
11520 mark_symbol_refs_as_used (x);
11524 [(set_attr "length" "4")
11525 (set_attr "type" "no_insn")]
11528 (define_insn "consttable_8"
11529 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11533 making_const_table = TRUE;
11534 scalar_float_mode float_mode;
11535 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11536 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11537 float_mode, BITS_PER_WORD);
11539 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11542 [(set_attr "length" "8")
11543 (set_attr "type" "no_insn")]
11546 (define_insn "consttable_16"
11547 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11551 making_const_table = TRUE;
11552 scalar_float_mode float_mode;
11553 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11554 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11555 float_mode, BITS_PER_WORD);
11557 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11560 [(set_attr "length" "16")
11561 (set_attr "type" "no_insn")]
11564 ;; V5 Instructions,
11566 (define_insn "clzsi2"
11567 [(set (match_operand:SI 0 "s_register_operand" "=r")
11568 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11569 "TARGET_32BIT && arm_arch5t"
11571 [(set_attr "predicable" "yes")
11572 (set_attr "type" "clz")])
11574 (define_insn "rbitsi2"
11575 [(set (match_operand:SI 0 "s_register_operand" "=r")
11576 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11577 "TARGET_32BIT && arm_arch_thumb2"
11579 [(set_attr "predicable" "yes")
11580 (set_attr "type" "clz")])
11582 ;; Keep this as a CTZ expression until after reload and then split
11583 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11584 ;; to fold with any other expression.
11586 (define_insn_and_split "ctzsi2"
11587 [(set (match_operand:SI 0 "s_register_operand" "=r")
11588 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11589 "TARGET_32BIT && arm_arch_thumb2"
11591 "&& reload_completed"
11594 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11595 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11599 ;; V5E instructions.
11601 (define_insn "prefetch"
11602 [(prefetch (match_operand:SI 0 "address_operand" "p")
11603 (match_operand:SI 1 "" "")
11604 (match_operand:SI 2 "" ""))]
11605 "TARGET_32BIT && arm_arch5te"
11607 [(set_attr "type" "load_4")]
11610 ;; General predication pattern
11613 [(match_operator 0 "arm_comparison_operator"
11614 [(match_operand 1 "cc_register" "")
11617 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11619 [(set_attr "predicated" "yes")]
11622 (define_insn "force_register_use"
11623 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11626 [(set_attr "length" "0")
11627 (set_attr "type" "no_insn")]
11631 ;; Patterns for exception handling
11633 (define_expand "eh_return"
11634 [(use (match_operand 0 "general_operand"))]
11639 emit_insn (gen_arm_eh_return (operands[0]));
11641 emit_insn (gen_thumb_eh_return (operands[0]));
11646 ;; We can't expand this before we know where the link register is stored.
11647 (define_insn_and_split "arm_eh_return"
11648 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11650 (clobber (match_scratch:SI 1 "=&r"))]
11653 "&& reload_completed"
11657 arm_set_return_address (operands[0], operands[1]);
11665 (define_insn "load_tp_hard"
11666 [(set (match_operand:SI 0 "register_operand" "=r")
11667 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11669 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11670 [(set_attr "predicable" "yes")
11671 (set_attr "type" "mrs")]
11674 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11675 (define_insn "load_tp_soft"
11676 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11677 (clobber (reg:SI LR_REGNUM))
11678 (clobber (reg:SI IP_REGNUM))
11679 (clobber (reg:CC CC_REGNUM))]
11681 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11682 [(set_attr "conds" "clob")
11683 (set_attr "type" "branch")]
11686 ;; tls descriptor call
11687 (define_insn "tlscall"
11688 [(set (reg:SI R0_REGNUM)
11689 (unspec:SI [(reg:SI R0_REGNUM)
11690 (match_operand:SI 0 "" "X")
11691 (match_operand 1 "" "")] UNSPEC_TLS))
11692 (clobber (reg:SI R1_REGNUM))
11693 (clobber (reg:SI LR_REGNUM))
11694 (clobber (reg:SI CC_REGNUM))]
11697 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11698 INTVAL (operands[1]));
11699 return "bl\\t%c0(tlscall)";
11701 [(set_attr "conds" "clob")
11702 (set_attr "length" "4")
11703 (set_attr "type" "branch")]
11706 ;; For thread pointer builtin
11707 (define_expand "get_thread_pointersi"
11708 [(match_operand:SI 0 "s_register_operand")]
11712 arm_load_tp (operands[0]);
11718 ;; We only care about the lower 16 bits of the constant
11719 ;; being inserted into the upper 16 bits of the register.
11720 (define_insn "*arm_movtas_ze"
11721 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11724 (match_operand:SI 1 "const_int_operand" ""))]
11729 [(set_attr "arch" "32,v8mb")
11730 (set_attr "predicable" "yes")
11731 (set_attr "length" "4")
11732 (set_attr "type" "alu_sreg")]
11735 (define_insn "*arm_rev"
11736 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11737 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11743 [(set_attr "arch" "t1,t2,32")
11744 (set_attr "length" "2,2,4")
11745 (set_attr "predicable" "no,yes,yes")
11746 (set_attr "type" "rev")]
11749 (define_expand "arm_legacy_rev"
11750 [(set (match_operand:SI 2 "s_register_operand")
11751 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand")
11755 (lshiftrt:SI (match_dup 2)
11757 (set (match_operand:SI 3 "s_register_operand")
11758 (rotatert:SI (match_dup 1)
11761 (and:SI (match_dup 2)
11762 (const_int -65281)))
11763 (set (match_operand:SI 0 "s_register_operand")
11764 (xor:SI (match_dup 3)
11770 ;; Reuse temporaries to keep register pressure down.
11771 (define_expand "thumb_legacy_rev"
11772 [(set (match_operand:SI 2 "s_register_operand")
11773 (ashift:SI (match_operand:SI 1 "s_register_operand")
11775 (set (match_operand:SI 3 "s_register_operand")
11776 (lshiftrt:SI (match_dup 1)
11779 (ior:SI (match_dup 3)
11781 (set (match_operand:SI 4 "s_register_operand")
11783 (set (match_operand:SI 5 "s_register_operand")
11784 (rotatert:SI (match_dup 1)
11787 (ashift:SI (match_dup 5)
11790 (lshiftrt:SI (match_dup 5)
11793 (ior:SI (match_dup 5)
11796 (rotatert:SI (match_dup 5)
11798 (set (match_operand:SI 0 "s_register_operand")
11799 (ior:SI (match_dup 5)
11805 ;; ARM-specific expansion of signed mod by power of 2
11806 ;; using conditional negate.
11807 ;; For r0 % n where n is a power of 2 produce:
11809 ;; and r0, r0, #(n - 1)
11810 ;; and r1, r1, #(n - 1)
11811 ;; rsbpl r0, r1, #0
11813 (define_expand "modsi3"
11814 [(match_operand:SI 0 "register_operand")
11815 (match_operand:SI 1 "register_operand")
11816 (match_operand:SI 2 "const_int_operand")]
11819 HOST_WIDE_INT val = INTVAL (operands[2]);
11822 || exact_log2 (val) <= 0)
11825 rtx mask = GEN_INT (val - 1);
11827 /* In the special case of x0 % 2 we can do the even shorter:
11830 rsblt r0, r0, #0. */
11834 rtx cc_reg = arm_gen_compare_reg (LT,
11835 operands[1], const0_rtx, NULL_RTX);
11836 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11837 rtx masked = gen_reg_rtx (SImode);
11839 emit_insn (gen_andsi3 (masked, operands[1], mask));
11840 emit_move_insn (operands[0],
11841 gen_rtx_IF_THEN_ELSE (SImode, cond,
11842 gen_rtx_NEG (SImode,
11848 rtx neg_op = gen_reg_rtx (SImode);
11849 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11852 /* Extract the condition register and mode. */
11853 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11854 rtx cc_reg = SET_DEST (cmp);
11855 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11857 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11859 rtx masked_neg = gen_reg_rtx (SImode);
11860 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11862 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11863 during expand does not always work. Do an IF_THEN_ELSE instead. */
11864 emit_move_insn (operands[0],
11865 gen_rtx_IF_THEN_ELSE (SImode, cond,
11866 gen_rtx_NEG (SImode, masked_neg),
11874 (define_expand "bswapsi2"
11875 [(set (match_operand:SI 0 "s_register_operand")
11876 (bswap:SI (match_operand:SI 1 "s_register_operand")))]
11877 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11881 rtx op2 = gen_reg_rtx (SImode);
11882 rtx op3 = gen_reg_rtx (SImode);
11886 rtx op4 = gen_reg_rtx (SImode);
11887 rtx op5 = gen_reg_rtx (SImode);
11889 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11890 op2, op3, op4, op5));
11894 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11903 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11904 ;; and unsigned variants, respectively. For rev16, expose
11905 ;; byte-swapping in the lower 16 bits only.
11906 (define_insn "*arm_revsh"
11907 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11908 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11914 [(set_attr "arch" "t1,t2,32")
11915 (set_attr "length" "2,2,4")
11916 (set_attr "type" "rev")]
11919 (define_insn "*arm_rev16"
11920 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11921 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11927 [(set_attr "arch" "t1,t2,32")
11928 (set_attr "length" "2,2,4")
11929 (set_attr "type" "rev")]
11932 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11933 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11934 ;; each valid permutation.
11936 (define_insn "arm_rev16si2"
11937 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11938 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11940 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11941 (and:SI (lshiftrt:SI (match_dup 1)
11943 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11945 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11946 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11948 [(set_attr "arch" "t1,t2,32")
11949 (set_attr "length" "2,2,4")
11950 (set_attr "type" "rev")]
11953 (define_insn "arm_rev16si2_alt"
11954 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11955 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11957 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11958 (and:SI (ashift:SI (match_dup 1)
11960 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11962 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11963 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11965 [(set_attr "arch" "t1,t2,32")
11966 (set_attr "length" "2,2,4")
11967 (set_attr "type" "rev")]
11970 (define_expand "bswaphi2"
11971 [(set (match_operand:HI 0 "s_register_operand")
11972 (bswap:HI (match_operand:HI 1 "s_register_operand")))]
11977 ;; Patterns for LDRD/STRD in Thumb2 mode
11979 (define_insn "*thumb2_ldrd"
11980 [(set (match_operand:SI 0 "s_register_operand" "=r")
11981 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11982 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11983 (set (match_operand:SI 3 "s_register_operand" "=r")
11984 (mem:SI (plus:SI (match_dup 1)
11985 (match_operand:SI 4 "const_int_operand" ""))))]
11986 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11987 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11988 && (operands_ok_ldrd_strd (operands[0], operands[3],
11989 operands[1], INTVAL (operands[2]),
11991 "ldrd%?\t%0, %3, [%1, %2]"
11992 [(set_attr "type" "load_8")
11993 (set_attr "predicable" "yes")])
11995 (define_insn "*thumb2_ldrd_base"
11996 [(set (match_operand:SI 0 "s_register_operand" "=r")
11997 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11998 (set (match_operand:SI 2 "s_register_operand" "=r")
11999 (mem:SI (plus:SI (match_dup 1)
12001 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12002 && (operands_ok_ldrd_strd (operands[0], operands[2],
12003 operands[1], 0, false, true))"
12004 "ldrd%?\t%0, %2, [%1]"
12005 [(set_attr "type" "load_8")
12006 (set_attr "predicable" "yes")])
12008 (define_insn "*thumb2_ldrd_base_neg"
12009 [(set (match_operand:SI 0 "s_register_operand" "=r")
12010 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
12012 (set (match_operand:SI 2 "s_register_operand" "=r")
12013 (mem:SI (match_dup 1)))]
12014 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12015 && (operands_ok_ldrd_strd (operands[0], operands[2],
12016 operands[1], -4, false, true))"
12017 "ldrd%?\t%0, %2, [%1, #-4]"
12018 [(set_attr "type" "load_8")
12019 (set_attr "predicable" "yes")])
12021 (define_insn "*thumb2_strd"
12022 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12023 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
12024 (match_operand:SI 2 "s_register_operand" "r"))
12025 (set (mem:SI (plus:SI (match_dup 0)
12026 (match_operand:SI 3 "const_int_operand" "")))
12027 (match_operand:SI 4 "s_register_operand" "r"))]
12028 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12029 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
12030 && (operands_ok_ldrd_strd (operands[2], operands[4],
12031 operands[0], INTVAL (operands[1]),
12033 "strd%?\t%2, %4, [%0, %1]"
12034 [(set_attr "type" "store_8")
12035 (set_attr "predicable" "yes")])
12037 (define_insn "*thumb2_strd_base"
12038 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
12039 (match_operand:SI 1 "s_register_operand" "r"))
12040 (set (mem:SI (plus:SI (match_dup 0)
12042 (match_operand:SI 2 "s_register_operand" "r"))]
12043 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12044 && (operands_ok_ldrd_strd (operands[1], operands[2],
12045 operands[0], 0, false, false))"
12046 "strd%?\t%1, %2, [%0]"
12047 [(set_attr "type" "store_8")
12048 (set_attr "predicable" "yes")])
12050 (define_insn "*thumb2_strd_base_neg"
12051 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12053 (match_operand:SI 1 "s_register_operand" "r"))
12054 (set (mem:SI (match_dup 0))
12055 (match_operand:SI 2 "s_register_operand" "r"))]
12056 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12057 && (operands_ok_ldrd_strd (operands[1], operands[2],
12058 operands[0], -4, false, false))"
12059 "strd%?\t%1, %2, [%0, #-4]"
12060 [(set_attr "type" "store_8")
12061 (set_attr "predicable" "yes")])
12063 ;; ARMv8 CRC32 instructions.
12064 (define_insn "<crc_variant>"
12065 [(set (match_operand:SI 0 "s_register_operand" "=r")
12066 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
12067 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
12070 "<crc_variant>\\t%0, %1, %2"
12071 [(set_attr "type" "crc")
12072 (set_attr "conds" "unconditional")]
12075 ;; Load the load/store double peephole optimizations.
12076 (include "ldrdstrd.md")
12078 ;; Load the load/store multiple patterns
12079 (include "ldmstm.md")
12081 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12082 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12083 ;; The operands are validated through the load_multiple_operation
12084 ;; match_parallel predicate rather than through constraints so enable it only
12086 (define_insn "*load_multiple"
12087 [(match_parallel 0 "load_multiple_operation"
12088 [(set (match_operand:SI 2 "s_register_operand" "=rk")
12089 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12091 "TARGET_32BIT && reload_completed"
12094 arm_output_multireg_pop (operands, /*return_pc=*/false,
12095 /*cond=*/const_true_rtx,
12101 [(set_attr "predicable" "yes")]
12104 (define_expand "copysignsf3"
12105 [(match_operand:SF 0 "register_operand")
12106 (match_operand:SF 1 "register_operand")
12107 (match_operand:SF 2 "register_operand")]
12108 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12110 emit_move_insn (operands[0], operands[2]);
12111 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
12112 GEN_INT (31), GEN_INT (0),
12113 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
12118 (define_expand "copysigndf3"
12119 [(match_operand:DF 0 "register_operand")
12120 (match_operand:DF 1 "register_operand")
12121 (match_operand:DF 2 "register_operand")]
12122 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12124 rtx op0_low = gen_lowpart (SImode, operands[0]);
12125 rtx op0_high = gen_highpart (SImode, operands[0]);
12126 rtx op1_low = gen_lowpart (SImode, operands[1]);
12127 rtx op1_high = gen_highpart (SImode, operands[1]);
12128 rtx op2_high = gen_highpart (SImode, operands[2]);
12130 rtx scratch1 = gen_reg_rtx (SImode);
12131 rtx scratch2 = gen_reg_rtx (SImode);
12132 emit_move_insn (scratch1, op2_high);
12133 emit_move_insn (scratch2, op1_high);
12135 emit_insn(gen_rtx_SET(scratch1,
12136 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
12137 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
12138 emit_move_insn (op0_low, op1_low);
12139 emit_move_insn (op0_high, scratch2);
12145 ;; movmisalign patterns for HImode and SImode.
12146 (define_expand "movmisalign<mode>"
12147 [(match_operand:HSI 0 "general_operand")
12148 (match_operand:HSI 1 "general_operand")]
12151 /* This pattern is not permitted to fail during expansion: if both arguments
12152 are non-registers (e.g. memory := constant), force operand 1 into a
12154 rtx (* gen_unaligned_load)(rtx, rtx);
12155 rtx tmp_dest = operands[0];
12156 if (!s_register_operand (operands[0], <MODE>mode)
12157 && !s_register_operand (operands[1], <MODE>mode))
12158 operands[1] = force_reg (<MODE>mode, operands[1]);
12160 if (<MODE>mode == HImode)
12162 gen_unaligned_load = gen_unaligned_loadhiu;
12163 tmp_dest = gen_reg_rtx (SImode);
12166 gen_unaligned_load = gen_unaligned_loadsi;
12168 if (MEM_P (operands[1]))
12170 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
12171 if (<MODE>mode == HImode)
12172 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
12175 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
12180 (define_insn "<cdp>"
12181 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12182 (match_operand:SI 1 "immediate_operand" "n")
12183 (match_operand:SI 2 "immediate_operand" "n")
12184 (match_operand:SI 3 "immediate_operand" "n")
12185 (match_operand:SI 4 "immediate_operand" "n")
12186 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
12187 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
12189 arm_const_bounds (operands[0], 0, 16);
12190 arm_const_bounds (operands[1], 0, 16);
12191 arm_const_bounds (operands[2], 0, (1 << 5));
12192 arm_const_bounds (operands[3], 0, (1 << 5));
12193 arm_const_bounds (operands[4], 0, (1 << 5));
12194 arm_const_bounds (operands[5], 0, 8);
12195 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
12197 [(set_attr "length" "4")
12198 (set_attr "type" "coproc")])
12200 (define_insn "*ldc"
12201 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12202 (match_operand:SI 1 "immediate_operand" "n")
12203 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
12204 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
12206 arm_const_bounds (operands[0], 0, 16);
12207 arm_const_bounds (operands[1], 0, (1 << 5));
12208 return "<ldc>\\tp%c0, CR%c1, %2";
12210 [(set_attr "length" "4")
12211 (set_attr "type" "coproc")])
12213 (define_insn "*stc"
12214 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12215 (match_operand:SI 1 "immediate_operand" "n")
12216 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
12217 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
12219 arm_const_bounds (operands[0], 0, 16);
12220 arm_const_bounds (operands[1], 0, (1 << 5));
12221 return "<stc>\\tp%c0, CR%c1, %2";
12223 [(set_attr "length" "4")
12224 (set_attr "type" "coproc")])
12226 (define_expand "<ldc>"
12227 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12228 (match_operand:SI 1 "immediate_operand")
12229 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
12230 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
12232 (define_expand "<stc>"
12233 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12234 (match_operand:SI 1 "immediate_operand")
12235 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12236 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12238 (define_insn "<mcr>"
12239 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12240 (match_operand:SI 1 "immediate_operand" "n")
12241 (match_operand:SI 2 "s_register_operand" "r")
12242 (match_operand:SI 3 "immediate_operand" "n")
12243 (match_operand:SI 4 "immediate_operand" "n")
12244 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12245 (use (match_dup 2))]
12246 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12248 arm_const_bounds (operands[0], 0, 16);
12249 arm_const_bounds (operands[1], 0, 8);
12250 arm_const_bounds (operands[3], 0, (1 << 5));
12251 arm_const_bounds (operands[4], 0, (1 << 5));
12252 arm_const_bounds (operands[5], 0, 8);
12253 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12255 [(set_attr "length" "4")
12256 (set_attr "type" "coproc")])
12258 (define_insn "<mrc>"
12259 [(set (match_operand:SI 0 "s_register_operand" "=r")
12260 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12261 (match_operand:SI 2 "immediate_operand" "n")
12262 (match_operand:SI 3 "immediate_operand" "n")
12263 (match_operand:SI 4 "immediate_operand" "n")
12264 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12265 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12267 arm_const_bounds (operands[1], 0, 16);
12268 arm_const_bounds (operands[2], 0, 8);
12269 arm_const_bounds (operands[3], 0, (1 << 5));
12270 arm_const_bounds (operands[4], 0, (1 << 5));
12271 arm_const_bounds (operands[5], 0, 8);
12272 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12274 [(set_attr "length" "4")
12275 (set_attr "type" "coproc")])
12277 (define_insn "<mcrr>"
12278 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12279 (match_operand:SI 1 "immediate_operand" "n")
12280 (match_operand:DI 2 "s_register_operand" "r")
12281 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12282 (use (match_dup 2))]
12283 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12285 arm_const_bounds (operands[0], 0, 16);
12286 arm_const_bounds (operands[1], 0, 8);
12287 arm_const_bounds (operands[3], 0, (1 << 5));
12288 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12290 [(set_attr "length" "4")
12291 (set_attr "type" "coproc")])
12293 (define_insn "<mrrc>"
12294 [(set (match_operand:DI 0 "s_register_operand" "=r")
12295 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12296 (match_operand:SI 2 "immediate_operand" "n")
12297 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12298 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12300 arm_const_bounds (operands[1], 0, 16);
12301 arm_const_bounds (operands[2], 0, 8);
12302 arm_const_bounds (operands[3], 0, (1 << 5));
12303 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12305 [(set_attr "length" "4")
12306 (set_attr "type" "coproc")])
12308 (define_expand "speculation_barrier"
12309 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12312 /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
12313 have a usable barrier (and probably don't need one in practice).
12314 But to be safe if such code is run on later architectures, call a
12315 helper function in libgcc that will do the thing for the active
12317 if (!(arm_arch7 || arm_arch8))
12319 arm_emit_speculation_barrier_function ();
12325 ;; Generate a hard speculation barrier when we have not enabled speculation
12327 (define_insn "*speculation_barrier_insn"
12328 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12329 "arm_arch7 || arm_arch8"
12331 [(set_attr "type" "block")
12332 (set_attr "length" "8")]
12335 ;; Vector bits common to IWMMXT and Neon
12336 (include "vec-common.md")
12337 ;; Load the Intel Wireless Multimedia Extension patterns
12338 (include "iwmmxt.md")
12339 ;; Load the VFP co-processor patterns
12341 ;; Thumb-1 patterns
12342 (include "thumb1.md")
12343 ;; Thumb-2 patterns
12344 (include "thumb2.md")
12346 (include "neon.md")
12348 (include "crypto.md")
12349 ;; Synchronization Primitives
12350 (include "sync.md")
12351 ;; Fixed-point patterns
12352 (include "arm-fixed.md")