1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2019 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;---------------------------------------------------------------------------
29 ;; Register numbers -- All machine registers should be defined here
31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (R4_REGNUM 4) ; Fifth CORE register
34 (IP_REGNUM 12) ; Scratch register
35 (SP_REGNUM 13) ; Stack pointer
36 (LR_REGNUM 14) ; Return address register
37 (PC_REGNUM 15) ; Program counter
38 (LAST_ARM_REGNUM 15) ;
39 (CC_REGNUM 100) ; Condition code pseudo register
40 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
43 ;; 3rd operand to select_dominance_cc_mode
50 ;; conditional compare combination
61 ;;---------------------------------------------------------------------------
64 ;; Processor type. This is created automatically from arm-cores.def.
65 (include "arm-tune.md")
67 ;; Instruction classification types
70 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
71 ; generating ARM code. This is used to control the length of some insn
72 ; patterns that share the same RTL in both ARM and Thumb code.
73 (define_attr "is_thumb" "yes,no"
74 (const (if_then_else (symbol_ref "TARGET_THUMB")
75 (const_string "yes") (const_string "no"))))
77 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
78 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
80 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
81 (define_attr "is_thumb1" "yes,no"
82 (const (if_then_else (symbol_ref "TARGET_THUMB1")
83 (const_string "yes") (const_string "no"))))
85 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
86 ; The arm_restrict_it flag enables the "short IT" feature which
87 ; restricts IT blocks to a single 16-bit instruction.
88 ; This attribute should only be used on 16-bit Thumb-2 instructions
89 ; which may be predicated (the "predicable" attribute must be set).
90 (define_attr "predicable_short_it" "no,yes" (const_string "no"))
92 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
93 ; This attribute should only be used on instructions which may emit
94 ; an IT block in their expansion which is not a short IT.
95 (define_attr "enabled_for_short_it" "no,yes" (const_string "yes"))
97 ;; Operand number of an input operand that is shifted. Zero if the
98 ;; given instruction does not shift one of its input operands.
99 (define_attr "shift" "" (const_int 0))
101 ;; [For compatibility with AArch64 in pipeline models]
102 ;; Attribute that specifies whether or not the instruction touches fp
104 (define_attr "fp" "no,yes" (const_string "no"))
106 ; Floating Point Unit. If we only have floating point emulation, then there
107 ; is no point in scheduling the floating point insns. (Well, for best
108 ; performance we should try and group them together).
109 (define_attr "fpu" "none,vfp"
110 (const (symbol_ref "arm_fpu_attr")))
112 ; Predicated means that the insn form is conditionally executed based on a
113 ; predicate. We default to 'no' because no Thumb patterns match this rule
114 ; and not all ARM insns do.
115 (define_attr "predicated" "yes,no" (const_string "no"))
117 ; LENGTH of an instruction (in bytes)
118 (define_attr "length" ""
121 ; The architecture which supports the instruction (or alternative).
122 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
123 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
124 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
125 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
126 ; Baseline. This attribute is used to compute attribute "enabled",
127 ; use type "any" to enable an alternative in all cases.
128 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
129 (const_string "any"))
131 (define_attr "arch_enabled" "no,yes"
132 (cond [(eq_attr "arch" "any")
135 (and (eq_attr "arch" "a")
136 (match_test "TARGET_ARM"))
139 (and (eq_attr "arch" "t")
140 (match_test "TARGET_THUMB"))
143 (and (eq_attr "arch" "t1")
144 (match_test "TARGET_THUMB1"))
147 (and (eq_attr "arch" "t2")
148 (match_test "TARGET_THUMB2"))
151 (and (eq_attr "arch" "32")
152 (match_test "TARGET_32BIT"))
155 (and (eq_attr "arch" "v6")
156 (match_test "TARGET_32BIT && arm_arch6"))
159 (and (eq_attr "arch" "nov6")
160 (match_test "TARGET_32BIT && !arm_arch6"))
163 (and (eq_attr "arch" "v6t2")
164 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
167 (and (eq_attr "arch" "v8mb")
168 (match_test "TARGET_THUMB1 && arm_arch8"))
171 (and (eq_attr "arch" "avoid_neon_for_64bits")
172 (match_test "TARGET_NEON")
173 (not (match_test "TARGET_PREFER_NEON_64BITS")))
176 (and (eq_attr "arch" "neon_for_64bits")
177 (match_test "TARGET_NEON")
178 (match_test "TARGET_PREFER_NEON_64BITS"))
181 (and (eq_attr "arch" "iwmmxt2")
182 (match_test "TARGET_REALLY_IWMMXT2"))
185 (and (eq_attr "arch" "armv6_or_vfpv3")
186 (match_test "arm_arch6 || TARGET_VFP3"))
189 (and (eq_attr "arch" "neon")
190 (match_test "TARGET_NEON"))
194 (const_string "no")))
196 (define_attr "opt" "any,speed,size"
197 (const_string "any"))
199 (define_attr "opt_enabled" "no,yes"
200 (cond [(eq_attr "opt" "any")
203 (and (eq_attr "opt" "speed")
204 (match_test "optimize_function_for_speed_p (cfun)"))
207 (and (eq_attr "opt" "size")
208 (match_test "optimize_function_for_size_p (cfun)"))
209 (const_string "yes")]
210 (const_string "no")))
212 (define_attr "use_literal_pool" "no,yes"
213 (cond [(and (eq_attr "type" "f_loads,f_loadd")
214 (match_test "CONSTANT_P (operands[1])"))
215 (const_string "yes")]
216 (const_string "no")))
218 ; Enable all alternatives that are both arch_enabled and insn_enabled.
219 ; FIXME:: opt_enabled has been temporarily removed till the time we have
220 ; an attribute that allows the use of such alternatives.
221 ; This depends on caching of speed_p, size_p on a per
222 ; alternative basis. The problem is that the enabled attribute
223 ; cannot depend on any state that is not cached or is not constant
224 ; for a compilation unit. We probably need a generic "hot/cold"
225 ; alternative which if implemented can help with this. We disable this
226 ; until such a time as this is implemented and / or the improvements or
227 ; regressions with removing this attribute are double checked.
228 ; See ashldi3_neon and <shift>di3_neon in neon.md.
230 (define_attr "enabled" "no,yes"
231 (cond [(and (eq_attr "predicable_short_it" "no")
232 (and (eq_attr "predicated" "yes")
233 (match_test "arm_restrict_it")))
236 (and (eq_attr "enabled_for_short_it" "no")
237 (match_test "arm_restrict_it"))
240 (eq_attr "arch_enabled" "no")
242 (const_string "yes")))
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed. If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address. It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
257 (define_attr "pool_range" ""
258 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259 (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262 (attr "arm_neg_pool_range")))
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268 [(set_attr "conds" "clob")
269 (set_attr "length" "4")
270 (set_attr "pool_range" "250")])
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions. It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
280 ; USE means that the condition codes are used by the insn in the process of
281 ; outputting code, this means (at present) that we can't use the insn in
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ; well defined manner.
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ; they are altered at all
290 ; UNCONDITIONAL means the instruction cannot be conditionally executed and
291 ; that the instruction does not use or alter the condition codes.
293 ; NOCOND means that the instruction does not use or alter the condition
294 ; codes but can be converted into a conditionally exectuted instruction.
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
298 (ior (eq_attr "is_thumb1" "yes")
299 (eq_attr "type" "call"))
300 (const_string "clob")
301 (if_then_else (eq_attr "is_neon_type" "no")
302 (const_string "nocond")
303 (const_string "unconditional"))))
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by
307 ; gen...). We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
311 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
312 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor. Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320 (if_then_else (eq_attr "type"
323 (const_string "no")))
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328 (if_then_else (eq_attr "type"
329 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345 (const_string "single")
346 (const_string "multi")))
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label. Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
357 ;;---------------------------------------------------------------------------
360 (include "unspecs.md")
362 ;;---------------------------------------------------------------------------
365 (include "iterators.md")
367 ;;---------------------------------------------------------------------------
370 (include "predicates.md")
371 (include "constraints.md")
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
376 (define_attr "tune_cortexr4" "yes,no"
378 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
380 (const_string "no"))))
382 ;; True if the generic scheduling description should be used.
384 (define_attr "generic_sched" "yes,no"
386 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387 arm926ejs,arm10e,arm1026ejs,arm1136js,\
388 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389 cortexa9,cortexa12,cortexa15,cortexa17,\
390 cortexa53,cortexa57,cortexm4,cortexm7,\
391 exynosm1,marvell_pj4,xgene1")
392 (eq_attr "tune_cortexr4" "yes"))
394 (const_string "yes"))))
396 (define_attr "generic_vfp" "yes,no"
398 (and (eq_attr "fpu" "vfp")
399 (eq_attr "tune" "!arm10e,cortexa5,cortexa7,\
400 cortexa8,cortexa9,cortexa53,cortexm4,\
401 cortexm7,marvell_pj4,xgene1")
402 (eq_attr "tune_cortexr4" "no"))
404 (const_string "no"))))
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
436 ;;---------------------------------------------------------------------------
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
445 (define_expand "adddi3"
447 [(set (match_operand:DI 0 "s_register_operand" "")
448 (plus:DI (match_operand:DI 1 "s_register_operand" "")
449 (match_operand:DI 2 "arm_adddi_operand" "")))
450 (clobber (reg:CC CC_REGNUM))])]
455 if (!REG_P (operands[1]))
456 operands[1] = force_reg (DImode, operands[1]);
457 if (!REG_P (operands[2]))
458 operands[2] = force_reg (DImode, operands[2]);
463 (define_insn_and_split "*arm_adddi3"
464 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r,&r,&r")
465 (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r")
466 (match_operand:DI 2 "arm_general_adddi_operand" "r, 0, r, Dd, Dd")))
467 (clobber (reg:CC CC_REGNUM))]
468 "TARGET_32BIT && !TARGET_NEON"
470 "TARGET_32BIT && ((!TARGET_NEON && !TARGET_IWMMXT) || reload_completed)"
471 [(parallel [(set (reg:CC_C CC_REGNUM)
472 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
474 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
475 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
476 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
479 operands[3] = gen_highpart (SImode, operands[0]);
480 operands[0] = gen_lowpart (SImode, operands[0]);
481 operands[4] = gen_highpart (SImode, operands[1]);
482 operands[1] = gen_lowpart (SImode, operands[1]);
483 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
484 operands[2] = gen_lowpart (SImode, operands[2]);
486 [(set_attr "conds" "clob")
487 (set_attr "length" "8")
488 (set_attr "type" "multiple")]
491 (define_insn_and_split "*adddi_sesidi_di"
492 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
493 (plus:DI (sign_extend:DI
494 (match_operand:SI 2 "s_register_operand" "r,r"))
495 (match_operand:DI 1 "s_register_operand" "0,r")))
496 (clobber (reg:CC CC_REGNUM))]
499 "TARGET_32BIT && reload_completed"
500 [(parallel [(set (reg:CC_C CC_REGNUM)
501 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
503 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
504 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
507 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
510 operands[3] = gen_highpart (SImode, operands[0]);
511 operands[0] = gen_lowpart (SImode, operands[0]);
512 operands[4] = gen_highpart (SImode, operands[1]);
513 operands[1] = gen_lowpart (SImode, operands[1]);
514 operands[2] = gen_lowpart (SImode, operands[2]);
516 [(set_attr "conds" "clob")
517 (set_attr "length" "8")
518 (set_attr "type" "multiple")]
521 (define_insn_and_split "*adddi_zesidi_di"
522 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
523 (plus:DI (zero_extend:DI
524 (match_operand:SI 2 "s_register_operand" "r,r"))
525 (match_operand:DI 1 "s_register_operand" "0,r")))
526 (clobber (reg:CC CC_REGNUM))]
529 "TARGET_32BIT && reload_completed"
530 [(parallel [(set (reg:CC_C CC_REGNUM)
531 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
533 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
534 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
535 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
538 operands[3] = gen_highpart (SImode, operands[0]);
539 operands[0] = gen_lowpart (SImode, operands[0]);
540 operands[4] = gen_highpart (SImode, operands[1]);
541 operands[1] = gen_lowpart (SImode, operands[1]);
542 operands[2] = gen_lowpart (SImode, operands[2]);
544 [(set_attr "conds" "clob")
545 (set_attr "length" "8")
546 (set_attr "type" "multiple")]
549 (define_expand "addv<mode>4"
550 [(match_operand:SIDI 0 "register_operand")
551 (match_operand:SIDI 1 "register_operand")
552 (match_operand:SIDI 2 "register_operand")
553 (match_operand 3 "")]
556 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
557 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
562 (define_expand "uaddv<mode>4"
563 [(match_operand:SIDI 0 "register_operand")
564 (match_operand:SIDI 1 "register_operand")
565 (match_operand:SIDI 2 "register_operand")
566 (match_operand 3 "")]
569 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
570 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
575 (define_expand "addsi3"
576 [(set (match_operand:SI 0 "s_register_operand" "")
577 (plus:SI (match_operand:SI 1 "s_register_operand" "")
578 (match_operand:SI 2 "reg_or_int_operand" "")))]
581 if (TARGET_32BIT && CONST_INT_P (operands[2]))
583 arm_split_constant (PLUS, SImode, NULL_RTX,
584 INTVAL (operands[2]), operands[0], operands[1],
585 optimize && can_create_pseudo_p ());
591 ; If there is a scratch available, this will be faster than synthesizing the
594 [(match_scratch:SI 3 "r")
595 (set (match_operand:SI 0 "arm_general_register_operand" "")
596 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
597 (match_operand:SI 2 "const_int_operand" "")))]
599 !(const_ok_for_arm (INTVAL (operands[2]))
600 || const_ok_for_arm (-INTVAL (operands[2])))
601 && const_ok_for_arm (~INTVAL (operands[2]))"
602 [(set (match_dup 3) (match_dup 2))
603 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
607 ;; The r/r/k alternative is required when reloading the address
608 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
609 ;; put the duplicated register first, and not try the commutative version.
610 (define_insn_and_split "*arm_addsi3"
611 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
612 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,r ,rk,k ,rk,k,r,rk,k ,rk")
613 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
629 subw%?\\t%0, %1, #%n2
630 subw%?\\t%0, %1, #%n2
633 && CONST_INT_P (operands[2])
634 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
635 && (reload_completed || !arm_eliminable_register (operands[1]))"
636 [(clobber (const_int 0))]
638 arm_split_constant (PLUS, SImode, curr_insn,
639 INTVAL (operands[2]), operands[0],
643 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
644 (set_attr "predicable" "yes")
645 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
646 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
647 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
648 (const_string "alu_imm")
649 (const_string "alu_sreg")))
653 (define_insn_and_split "adddi3_compareV"
654 [(set (reg:CC_V CC_REGNUM)
657 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
658 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
659 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
660 (set (match_operand:DI 0 "register_operand" "=&r")
661 (plus:DI (match_dup 1) (match_dup 2)))]
664 "&& reload_completed"
665 [(parallel [(set (reg:CC_C CC_REGNUM)
666 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
668 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
669 (parallel [(set (reg:CC_V CC_REGNUM)
672 (sign_extend:DI (match_dup 4))
673 (sign_extend:DI (match_dup 5)))
674 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
675 (plus:DI (sign_extend:DI
676 (plus:SI (match_dup 4) (match_dup 5)))
677 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
678 (set (match_dup 3) (plus:SI (plus:SI
679 (match_dup 4) (match_dup 5))
680 (ltu:SI (reg:CC_C CC_REGNUM)
684 operands[3] = gen_highpart (SImode, operands[0]);
685 operands[0] = gen_lowpart (SImode, operands[0]);
686 operands[4] = gen_highpart (SImode, operands[1]);
687 operands[1] = gen_lowpart (SImode, operands[1]);
688 operands[5] = gen_highpart (SImode, operands[2]);
689 operands[2] = gen_lowpart (SImode, operands[2]);
691 [(set_attr "conds" "set")
692 (set_attr "length" "8")
693 (set_attr "type" "multiple")]
696 (define_insn "addsi3_compareV"
697 [(set (reg:CC_V CC_REGNUM)
700 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
701 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
702 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
703 (set (match_operand:SI 0 "register_operand" "=r")
704 (plus:SI (match_dup 1) (match_dup 2)))]
706 "adds%?\\t%0, %1, %2"
707 [(set_attr "conds" "set")
708 (set_attr "type" "alus_sreg")]
711 (define_insn "*addsi3_compareV_upper"
712 [(set (reg:CC_V CC_REGNUM)
716 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
717 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
718 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
719 (plus:DI (sign_extend:DI
720 (plus:SI (match_dup 1) (match_dup 2)))
721 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
722 (set (match_operand:SI 0 "register_operand" "=r")
724 (plus:SI (match_dup 1) (match_dup 2))
725 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
727 "adcs%?\\t%0, %1, %2"
728 [(set_attr "conds" "set")
729 (set_attr "type" "adcs_reg")]
732 (define_insn_and_split "adddi3_compareC"
733 [(set (reg:CC_C CC_REGNUM)
736 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
737 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
738 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
739 (set (match_operand:DI 0 "register_operand" "=&r")
740 (plus:DI (match_dup 1) (match_dup 2)))]
743 "&& reload_completed"
744 [(parallel [(set (reg:CC_C CC_REGNUM)
745 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
747 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
748 (parallel [(set (reg:CC_C CC_REGNUM)
751 (zero_extend:DI (match_dup 4))
752 (zero_extend:DI (match_dup 5)))
753 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
754 (plus:DI (zero_extend:DI
755 (plus:SI (match_dup 4) (match_dup 5)))
756 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
757 (set (match_dup 3) (plus:SI
758 (plus:SI (match_dup 4) (match_dup 5))
759 (ltu:SI (reg:CC_C CC_REGNUM)
763 operands[3] = gen_highpart (SImode, operands[0]);
764 operands[0] = gen_lowpart (SImode, operands[0]);
765 operands[4] = gen_highpart (SImode, operands[1]);
766 operands[5] = gen_highpart (SImode, operands[2]);
767 operands[1] = gen_lowpart (SImode, operands[1]);
768 operands[2] = gen_lowpart (SImode, operands[2]);
770 [(set_attr "conds" "set")
771 (set_attr "length" "8")
772 (set_attr "type" "multiple")]
775 (define_insn "*addsi3_compareC_upper"
776 [(set (reg:CC_C CC_REGNUM)
780 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
781 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
782 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
783 (plus:DI (zero_extend:DI
784 (plus:SI (match_dup 1) (match_dup 2)))
785 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
786 (set (match_operand:SI 0 "register_operand" "=r")
788 (plus:SI (match_dup 1) (match_dup 2))
789 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
791 "adcs%?\\t%0, %1, %2"
792 [(set_attr "conds" "set")
793 (set_attr "type" "adcs_reg")]
796 (define_insn "addsi3_compareC"
797 [(set (reg:CC_C CC_REGNUM)
800 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
801 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
803 (plus:SI (match_dup 1) (match_dup 2)))))
804 (set (match_operand:SI 0 "register_operand" "=r")
805 (plus:SI (match_dup 1) (match_dup 2)))]
807 "adds%?\\t%0, %1, %2"
808 [(set_attr "conds" "set")
809 (set_attr "type" "alus_sreg")]
812 (define_insn "addsi3_compare0"
813 [(set (reg:CC_NOOV CC_REGNUM)
815 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
816 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
818 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
819 (plus:SI (match_dup 1) (match_dup 2)))]
823 subs%?\\t%0, %1, #%n2
825 [(set_attr "conds" "set")
826 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
829 (define_insn "*addsi3_compare0_scratch"
830 [(set (reg:CC_NOOV CC_REGNUM)
832 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
833 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
840 [(set_attr "conds" "set")
841 (set_attr "predicable" "yes")
842 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
845 (define_insn "*compare_negsi_si"
846 [(set (reg:CC_Z CC_REGNUM)
848 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
849 (match_operand:SI 1 "s_register_operand" "l,r")))]
852 [(set_attr "conds" "set")
853 (set_attr "predicable" "yes")
854 (set_attr "arch" "t2,*")
855 (set_attr "length" "2,4")
856 (set_attr "predicable_short_it" "yes,no")
857 (set_attr "type" "alus_sreg")]
860 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
861 ;; addend is a constant.
862 (define_insn "cmpsi2_addneg"
863 [(set (reg:CC CC_REGNUM)
865 (match_operand:SI 1 "s_register_operand" "r,r")
866 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
867 (set (match_operand:SI 0 "s_register_operand" "=r,r")
868 (plus:SI (match_dup 1)
869 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
870 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
873 subs%?\\t%0, %1, #%n3"
874 [(set_attr "conds" "set")
875 (set_attr "type" "alus_sreg")]
878 ;; Convert the sequence
880 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
884 ;; bcs dest ((unsigned)rn >= 1)
885 ;; similarly for the beq variant using bcc.
886 ;; This is a common looping idiom (while (n--))
888 [(set (match_operand:SI 0 "arm_general_register_operand" "")
889 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
891 (set (match_operand 2 "cc_register" "")
892 (compare (match_dup 0) (const_int -1)))
894 (if_then_else (match_operator 3 "equality_operator"
895 [(match_dup 2) (const_int 0)])
896 (match_operand 4 "" "")
897 (match_operand 5 "" "")))]
898 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
902 (match_dup 1) (const_int 1)))
903 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
905 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
908 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
909 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
912 operands[2], const0_rtx);"
915 ;; The next four insns work because they compare the result with one of
916 ;; the operands, and we know that the use of the condition code is
917 ;; either GEU or LTU, so we can use the carry flag from the addition
918 ;; instead of doing the compare a second time.
919 (define_insn "*addsi3_compare_op1"
920 [(set (reg:CC_C CC_REGNUM)
922 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
923 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
925 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
926 (plus:SI (match_dup 1) (match_dup 2)))]
930 subs%?\\t%0, %1, #%n2
932 [(set_attr "conds" "set")
933 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
936 (define_insn "*addsi3_compare_op2"
937 [(set (reg:CC_C CC_REGNUM)
939 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
940 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
942 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
943 (plus:SI (match_dup 1) (match_dup 2)))]
947 subs%?\\t%0, %1, #%n2
949 [(set_attr "conds" "set")
950 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
953 (define_insn "*compare_addsi2_op0"
954 [(set (reg:CC_C CC_REGNUM)
956 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
957 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
966 [(set_attr "conds" "set")
967 (set_attr "predicable" "yes")
968 (set_attr "arch" "t2,t2,*,*,*")
969 (set_attr "predicable_short_it" "yes,yes,no,no,no")
970 (set_attr "length" "2,2,4,4,4")
971 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
974 (define_insn "*compare_addsi2_op1"
975 [(set (reg:CC_C CC_REGNUM)
977 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
978 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
987 [(set_attr "conds" "set")
988 (set_attr "predicable" "yes")
989 (set_attr "arch" "t2,t2,*,*,*")
990 (set_attr "predicable_short_it" "yes,yes,no,no,no")
991 (set_attr "length" "2,2,4,4,4")
992 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
995 (define_insn "*addsi3_carryin_<optab>"
996 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
997 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
998 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
999 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1004 sbc%?\\t%0, %1, #%B2"
1005 [(set_attr "conds" "use")
1006 (set_attr "predicable" "yes")
1007 (set_attr "arch" "t2,*,*")
1008 (set_attr "length" "4")
1009 (set_attr "predicable_short_it" "yes,no,no")
1010 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1013 (define_insn "*addsi3_carryin_alt2_<optab>"
1014 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1015 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1016 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1017 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1022 sbc%?\\t%0, %1, #%B2"
1023 [(set_attr "conds" "use")
1024 (set_attr "predicable" "yes")
1025 (set_attr "arch" "t2,*,*")
1026 (set_attr "length" "4")
1027 (set_attr "predicable_short_it" "yes,no,no")
1028 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1031 (define_insn "*addsi3_carryin_shift_<optab>"
1032 [(set (match_operand:SI 0 "s_register_operand" "=r")
1034 (match_operator:SI 2 "shift_operator"
1035 [(match_operand:SI 3 "s_register_operand" "r")
1036 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1037 (match_operand:SI 1 "s_register_operand" "r"))
1038 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1040 "adc%?\\t%0, %1, %3%S2"
1041 [(set_attr "conds" "use")
1042 (set_attr "predicable" "yes")
1043 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1044 (const_string "alu_shift_imm")
1045 (const_string "alu_shift_reg")))]
1048 (define_insn "*addsi3_carryin_clobercc_<optab>"
1049 [(set (match_operand:SI 0 "s_register_operand" "=r")
1050 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1051 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1052 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1053 (clobber (reg:CC CC_REGNUM))]
1055 "adcs%?\\t%0, %1, %2"
1056 [(set_attr "conds" "set")
1057 (set_attr "type" "adcs_reg")]
1060 (define_expand "subv<mode>4"
1061 [(match_operand:SIDI 0 "register_operand")
1062 (match_operand:SIDI 1 "register_operand")
1063 (match_operand:SIDI 2 "register_operand")
1064 (match_operand 3 "")]
1067 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1068 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1073 (define_expand "usubv<mode>4"
1074 [(match_operand:SIDI 0 "register_operand")
1075 (match_operand:SIDI 1 "register_operand")
1076 (match_operand:SIDI 2 "register_operand")
1077 (match_operand 3 "")]
1080 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1081 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1086 (define_insn_and_split "subdi3_compare1"
1087 [(set (reg:CC CC_REGNUM)
1089 (match_operand:DI 1 "register_operand" "r")
1090 (match_operand:DI 2 "register_operand" "r")))
1091 (set (match_operand:DI 0 "register_operand" "=&r")
1092 (minus:DI (match_dup 1) (match_dup 2)))]
1095 "&& reload_completed"
1096 [(parallel [(set (reg:CC CC_REGNUM)
1097 (compare:CC (match_dup 1) (match_dup 2)))
1098 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1099 (parallel [(set (reg:CC CC_REGNUM)
1100 (compare:CC (match_dup 4) (match_dup 5)))
1101 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1102 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1104 operands[3] = gen_highpart (SImode, operands[0]);
1105 operands[0] = gen_lowpart (SImode, operands[0]);
1106 operands[4] = gen_highpart (SImode, operands[1]);
1107 operands[1] = gen_lowpart (SImode, operands[1]);
1108 operands[5] = gen_highpart (SImode, operands[2]);
1109 operands[2] = gen_lowpart (SImode, operands[2]);
1111 [(set_attr "conds" "set")
1112 (set_attr "length" "8")
1113 (set_attr "type" "multiple")]
1116 (define_insn "subsi3_compare1"
1117 [(set (reg:CC CC_REGNUM)
1119 (match_operand:SI 1 "register_operand" "r")
1120 (match_operand:SI 2 "register_operand" "r")))
1121 (set (match_operand:SI 0 "register_operand" "=r")
1122 (minus:SI (match_dup 1) (match_dup 2)))]
1124 "subs%?\\t%0, %1, %2"
1125 [(set_attr "conds" "set")
1126 (set_attr "type" "alus_sreg")]
1129 (define_insn "*subsi3_carryin"
1130 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1131 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1132 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1133 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1138 sbc%?\\t%0, %2, %2, lsl #1"
1139 [(set_attr "conds" "use")
1140 (set_attr "arch" "*,a,t2")
1141 (set_attr "predicable" "yes")
1142 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1145 (define_insn "*subsi3_carryin_const"
1146 [(set (match_operand:SI 0 "s_register_operand" "=r")
1147 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1148 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1149 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1151 "sbc\\t%0, %1, #%B2"
1152 [(set_attr "conds" "use")
1153 (set_attr "type" "adc_imm")]
1156 (define_insn "*subsi3_carryin_compare"
1157 [(set (reg:CC CC_REGNUM)
1158 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1159 (match_operand:SI 2 "s_register_operand" "r")))
1160 (set (match_operand:SI 0 "s_register_operand" "=r")
1161 (minus:SI (minus:SI (match_dup 1)
1163 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1166 [(set_attr "conds" "set")
1167 (set_attr "type" "adcs_reg")]
1170 (define_insn "*subsi3_carryin_compare_const"
1171 [(set (reg:CC CC_REGNUM)
1172 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1173 (match_operand:SI 2 "arm_not_operand" "K")))
1174 (set (match_operand:SI 0 "s_register_operand" "=r")
1175 (minus:SI (plus:SI (match_dup 1)
1177 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1179 "sbcs\\t%0, %1, #%B2"
1180 [(set_attr "conds" "set")
1181 (set_attr "type" "adcs_imm")]
1184 (define_insn "*subsi3_carryin_shift"
1185 [(set (match_operand:SI 0 "s_register_operand" "=r")
1187 (match_operand:SI 1 "s_register_operand" "r")
1188 (match_operator:SI 2 "shift_operator"
1189 [(match_operand:SI 3 "s_register_operand" "r")
1190 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1191 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1193 "sbc%?\\t%0, %1, %3%S2"
1194 [(set_attr "conds" "use")
1195 (set_attr "predicable" "yes")
1196 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1197 (const_string "alu_shift_imm")
1198 (const_string "alu_shift_reg")))]
1201 (define_insn "*rsbsi3_carryin_shift"
1202 [(set (match_operand:SI 0 "s_register_operand" "=r")
1204 (match_operator:SI 2 "shift_operator"
1205 [(match_operand:SI 3 "s_register_operand" "r")
1206 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1207 (match_operand:SI 1 "s_register_operand" "r"))
1208 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1210 "rsc%?\\t%0, %1, %3%S2"
1211 [(set_attr "conds" "use")
1212 (set_attr "predicable" "yes")
1213 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1214 (const_string "alu_shift_imm")
1215 (const_string "alu_shift_reg")))]
1218 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1220 [(set (match_operand:SI 0 "s_register_operand" "")
1221 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1222 (match_operand:SI 2 "s_register_operand" ""))
1224 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1226 [(set (match_dup 3) (match_dup 1))
1227 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1229 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1232 (define_expand "addsf3"
1233 [(set (match_operand:SF 0 "s_register_operand" "")
1234 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1235 (match_operand:SF 2 "s_register_operand" "")))]
1236 "TARGET_32BIT && TARGET_HARD_FLOAT"
1240 (define_expand "adddf3"
1241 [(set (match_operand:DF 0 "s_register_operand" "")
1242 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1243 (match_operand:DF 2 "s_register_operand" "")))]
1244 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1248 (define_expand "subdi3"
1250 [(set (match_operand:DI 0 "s_register_operand" "")
1251 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1252 (match_operand:DI 2 "s_register_operand" "")))
1253 (clobber (reg:CC CC_REGNUM))])]
1258 if (!REG_P (operands[1]))
1259 operands[1] = force_reg (DImode, operands[1]);
1260 if (!REG_P (operands[2]))
1261 operands[2] = force_reg (DImode, operands[2]);
1266 (define_insn_and_split "*arm_subdi3"
1267 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
1268 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1269 (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1270 (clobber (reg:CC CC_REGNUM))]
1271 "TARGET_32BIT && !TARGET_NEON"
1272 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1273 "&& (!TARGET_IWMMXT || reload_completed)"
1274 [(parallel [(set (reg:CC CC_REGNUM)
1275 (compare:CC (match_dup 1) (match_dup 2)))
1276 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1277 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1278 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1280 operands[3] = gen_highpart (SImode, operands[0]);
1281 operands[0] = gen_lowpart (SImode, operands[0]);
1282 operands[4] = gen_highpart (SImode, operands[1]);
1283 operands[1] = gen_lowpart (SImode, operands[1]);
1284 operands[5] = gen_highpart (SImode, operands[2]);
1285 operands[2] = gen_lowpart (SImode, operands[2]);
1287 [(set_attr "conds" "clob")
1288 (set_attr "length" "8")
1289 (set_attr "type" "multiple")]
1292 (define_insn_and_split "*subdi_di_zesidi"
1293 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1294 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1296 (match_operand:SI 2 "s_register_operand" "r,r"))))
1297 (clobber (reg:CC CC_REGNUM))]
1299 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1300 "&& reload_completed"
1301 [(parallel [(set (reg:CC CC_REGNUM)
1302 (compare:CC (match_dup 1) (match_dup 2)))
1303 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1304 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1305 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1307 operands[3] = gen_highpart (SImode, operands[0]);
1308 operands[0] = gen_lowpart (SImode, operands[0]);
1309 operands[4] = gen_highpart (SImode, operands[1]);
1310 operands[1] = gen_lowpart (SImode, operands[1]);
1311 operands[5] = GEN_INT (~0);
1313 [(set_attr "conds" "clob")
1314 (set_attr "length" "8")
1315 (set_attr "type" "multiple")]
1318 (define_insn_and_split "*subdi_di_sesidi"
1319 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1320 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1322 (match_operand:SI 2 "s_register_operand" "r,r"))))
1323 (clobber (reg:CC CC_REGNUM))]
1325 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1326 "&& reload_completed"
1327 [(parallel [(set (reg:CC CC_REGNUM)
1328 (compare:CC (match_dup 1) (match_dup 2)))
1329 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1330 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1331 (ashiftrt:SI (match_dup 2)
1333 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1335 operands[3] = gen_highpart (SImode, operands[0]);
1336 operands[0] = gen_lowpart (SImode, operands[0]);
1337 operands[4] = gen_highpart (SImode, operands[1]);
1338 operands[1] = gen_lowpart (SImode, operands[1]);
1340 [(set_attr "conds" "clob")
1341 (set_attr "length" "8")
1342 (set_attr "type" "multiple")]
1345 (define_insn_and_split "*subdi_zesidi_di"
1346 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1347 (minus:DI (zero_extend:DI
1348 (match_operand:SI 2 "s_register_operand" "r,r"))
1349 (match_operand:DI 1 "s_register_operand" "0,r")))
1350 (clobber (reg:CC CC_REGNUM))]
1352 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1354 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1355 "&& reload_completed"
1356 [(parallel [(set (reg:CC CC_REGNUM)
1357 (compare:CC (match_dup 2) (match_dup 1)))
1358 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1359 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1360 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1362 operands[3] = gen_highpart (SImode, operands[0]);
1363 operands[0] = gen_lowpart (SImode, operands[0]);
1364 operands[4] = gen_highpart (SImode, operands[1]);
1365 operands[1] = gen_lowpart (SImode, operands[1]);
1367 [(set_attr "conds" "clob")
1368 (set_attr "length" "8")
1369 (set_attr "type" "multiple")]
1372 (define_insn_and_split "*subdi_sesidi_di"
1373 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1374 (minus:DI (sign_extend:DI
1375 (match_operand:SI 2 "s_register_operand" "r,r"))
1376 (match_operand:DI 1 "s_register_operand" "0,r")))
1377 (clobber (reg:CC CC_REGNUM))]
1379 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1381 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1382 "&& reload_completed"
1383 [(parallel [(set (reg:CC CC_REGNUM)
1384 (compare:CC (match_dup 2) (match_dup 1)))
1385 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1386 (set (match_dup 3) (minus:SI (minus:SI
1387 (ashiftrt:SI (match_dup 2)
1390 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1392 operands[3] = gen_highpart (SImode, operands[0]);
1393 operands[0] = gen_lowpart (SImode, operands[0]);
1394 operands[4] = gen_highpart (SImode, operands[1]);
1395 operands[1] = gen_lowpart (SImode, operands[1]);
1397 [(set_attr "conds" "clob")
1398 (set_attr "length" "8")
1399 (set_attr "type" "multiple")]
1402 (define_insn_and_split "*subdi_zesidi_zesidi"
1403 [(set (match_operand:DI 0 "s_register_operand" "=r")
1404 (minus:DI (zero_extend:DI
1405 (match_operand:SI 1 "s_register_operand" "r"))
1407 (match_operand:SI 2 "s_register_operand" "r"))))
1408 (clobber (reg:CC CC_REGNUM))]
1410 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1411 "&& reload_completed"
1412 [(parallel [(set (reg:CC CC_REGNUM)
1413 (compare:CC (match_dup 1) (match_dup 2)))
1414 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1415 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1416 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1418 operands[3] = gen_highpart (SImode, operands[0]);
1419 operands[0] = gen_lowpart (SImode, operands[0]);
1421 [(set_attr "conds" "clob")
1422 (set_attr "length" "8")
1423 (set_attr "type" "multiple")]
1426 (define_expand "subsi3"
1427 [(set (match_operand:SI 0 "s_register_operand" "")
1428 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1429 (match_operand:SI 2 "s_register_operand" "")))]
1432 if (CONST_INT_P (operands[1]))
1436 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1437 operands[1] = force_reg (SImode, operands[1]);
1440 arm_split_constant (MINUS, SImode, NULL_RTX,
1441 INTVAL (operands[1]), operands[0],
1443 optimize && can_create_pseudo_p ());
1447 else /* TARGET_THUMB1 */
1448 operands[1] = force_reg (SImode, operands[1]);
1453 ; ??? Check Thumb-2 split length
1454 (define_insn_and_split "*arm_subsi3_insn"
1455 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1456 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1457 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1469 "&& (CONST_INT_P (operands[1])
1470 && !const_ok_for_arm (INTVAL (operands[1])))"
1471 [(clobber (const_int 0))]
1473 arm_split_constant (MINUS, SImode, curr_insn,
1474 INTVAL (operands[1]), operands[0], operands[2], 0);
1477 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1478 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1479 (set_attr "predicable" "yes")
1480 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1481 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1485 [(match_scratch:SI 3 "r")
1486 (set (match_operand:SI 0 "arm_general_register_operand" "")
1487 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1488 (match_operand:SI 2 "arm_general_register_operand" "")))]
1490 && !const_ok_for_arm (INTVAL (operands[1]))
1491 && const_ok_for_arm (~INTVAL (operands[1]))"
1492 [(set (match_dup 3) (match_dup 1))
1493 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1497 (define_insn "subsi3_compare0"
1498 [(set (reg:CC_NOOV CC_REGNUM)
1500 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1501 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1503 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1504 (minus:SI (match_dup 1) (match_dup 2)))]
1509 rsbs%?\\t%0, %2, %1"
1510 [(set_attr "conds" "set")
1511 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1514 (define_insn "subsi3_compare"
1515 [(set (reg:CC CC_REGNUM)
1516 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1517 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1518 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1519 (minus:SI (match_dup 1) (match_dup 2)))]
1524 rsbs%?\\t%0, %2, %1"
1525 [(set_attr "conds" "set")
1526 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1529 (define_expand "subsf3"
1530 [(set (match_operand:SF 0 "s_register_operand" "")
1531 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1532 (match_operand:SF 2 "s_register_operand" "")))]
1533 "TARGET_32BIT && TARGET_HARD_FLOAT"
1537 (define_expand "subdf3"
1538 [(set (match_operand:DF 0 "s_register_operand" "")
1539 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1540 (match_operand:DF 2 "s_register_operand" "")))]
1541 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1546 ;; Multiplication insns
1548 (define_expand "mulhi3"
1549 [(set (match_operand:HI 0 "s_register_operand" "")
1550 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1551 (match_operand:HI 2 "s_register_operand" "")))]
1552 "TARGET_DSP_MULTIPLY"
1555 rtx result = gen_reg_rtx (SImode);
1556 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1557 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1562 (define_expand "mulsi3"
1563 [(set (match_operand:SI 0 "s_register_operand" "")
1564 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1565 (match_operand:SI 1 "s_register_operand" "")))]
1570 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1571 (define_insn "*arm_mulsi3"
1572 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1573 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1574 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1575 "TARGET_32BIT && !arm_arch6"
1576 "mul%?\\t%0, %2, %1"
1577 [(set_attr "type" "mul")
1578 (set_attr "predicable" "yes")]
1581 (define_insn "*arm_mulsi3_v6"
1582 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1583 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1584 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1585 "TARGET_32BIT && arm_arch6"
1586 "mul%?\\t%0, %1, %2"
1587 [(set_attr "type" "mul")
1588 (set_attr "predicable" "yes")
1589 (set_attr "arch" "t2,t2,*")
1590 (set_attr "length" "4")
1591 (set_attr "predicable_short_it" "yes,yes,no")]
1594 (define_insn "*mulsi3_compare0"
1595 [(set (reg:CC_NOOV CC_REGNUM)
1596 (compare:CC_NOOV (mult:SI
1597 (match_operand:SI 2 "s_register_operand" "r,r")
1598 (match_operand:SI 1 "s_register_operand" "%0,r"))
1600 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1601 (mult:SI (match_dup 2) (match_dup 1)))]
1602 "TARGET_ARM && !arm_arch6"
1603 "muls%?\\t%0, %2, %1"
1604 [(set_attr "conds" "set")
1605 (set_attr "type" "muls")]
1608 (define_insn "*mulsi3_compare0_v6"
1609 [(set (reg:CC_NOOV CC_REGNUM)
1610 (compare:CC_NOOV (mult:SI
1611 (match_operand:SI 2 "s_register_operand" "r")
1612 (match_operand:SI 1 "s_register_operand" "r"))
1614 (set (match_operand:SI 0 "s_register_operand" "=r")
1615 (mult:SI (match_dup 2) (match_dup 1)))]
1616 "TARGET_ARM && arm_arch6 && optimize_size"
1617 "muls%?\\t%0, %2, %1"
1618 [(set_attr "conds" "set")
1619 (set_attr "type" "muls")]
1622 (define_insn "*mulsi_compare0_scratch"
1623 [(set (reg:CC_NOOV CC_REGNUM)
1624 (compare:CC_NOOV (mult:SI
1625 (match_operand:SI 2 "s_register_operand" "r,r")
1626 (match_operand:SI 1 "s_register_operand" "%0,r"))
1628 (clobber (match_scratch:SI 0 "=&r,&r"))]
1629 "TARGET_ARM && !arm_arch6"
1630 "muls%?\\t%0, %2, %1"
1631 [(set_attr "conds" "set")
1632 (set_attr "type" "muls")]
1635 (define_insn "*mulsi_compare0_scratch_v6"
1636 [(set (reg:CC_NOOV CC_REGNUM)
1637 (compare:CC_NOOV (mult:SI
1638 (match_operand:SI 2 "s_register_operand" "r")
1639 (match_operand:SI 1 "s_register_operand" "r"))
1641 (clobber (match_scratch:SI 0 "=r"))]
1642 "TARGET_ARM && arm_arch6 && optimize_size"
1643 "muls%?\\t%0, %2, %1"
1644 [(set_attr "conds" "set")
1645 (set_attr "type" "muls")]
1648 ;; Unnamed templates to match MLA instruction.
1650 (define_insn "*mulsi3addsi"
1651 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1653 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1654 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1655 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1656 "TARGET_32BIT && !arm_arch6"
1657 "mla%?\\t%0, %2, %1, %3"
1658 [(set_attr "type" "mla")
1659 (set_attr "predicable" "yes")]
1662 (define_insn "*mulsi3addsi_v6"
1663 [(set (match_operand:SI 0 "s_register_operand" "=r")
1665 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1666 (match_operand:SI 1 "s_register_operand" "r"))
1667 (match_operand:SI 3 "s_register_operand" "r")))]
1668 "TARGET_32BIT && arm_arch6"
1669 "mla%?\\t%0, %2, %1, %3"
1670 [(set_attr "type" "mla")
1671 (set_attr "predicable" "yes")]
1674 (define_insn "*mulsi3addsi_compare0"
1675 [(set (reg:CC_NOOV CC_REGNUM)
1678 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1679 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1680 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1682 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1683 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1685 "TARGET_ARM && arm_arch6"
1686 "mlas%?\\t%0, %2, %1, %3"
1687 [(set_attr "conds" "set")
1688 (set_attr "type" "mlas")]
1691 (define_insn "*mulsi3addsi_compare0_v6"
1692 [(set (reg:CC_NOOV CC_REGNUM)
1695 (match_operand:SI 2 "s_register_operand" "r")
1696 (match_operand:SI 1 "s_register_operand" "r"))
1697 (match_operand:SI 3 "s_register_operand" "r"))
1699 (set (match_operand:SI 0 "s_register_operand" "=r")
1700 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1702 "TARGET_ARM && arm_arch6 && optimize_size"
1703 "mlas%?\\t%0, %2, %1, %3"
1704 [(set_attr "conds" "set")
1705 (set_attr "type" "mlas")]
1708 (define_insn "*mulsi3addsi_compare0_scratch"
1709 [(set (reg:CC_NOOV CC_REGNUM)
1712 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1713 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1714 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1716 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1717 "TARGET_ARM && !arm_arch6"
1718 "mlas%?\\t%0, %2, %1, %3"
1719 [(set_attr "conds" "set")
1720 (set_attr "type" "mlas")]
1723 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1724 [(set (reg:CC_NOOV CC_REGNUM)
1727 (match_operand:SI 2 "s_register_operand" "r")
1728 (match_operand:SI 1 "s_register_operand" "r"))
1729 (match_operand:SI 3 "s_register_operand" "r"))
1731 (clobber (match_scratch:SI 0 "=r"))]
1732 "TARGET_ARM && arm_arch6 && optimize_size"
1733 "mlas%?\\t%0, %2, %1, %3"
1734 [(set_attr "conds" "set")
1735 (set_attr "type" "mlas")]
1738 (define_insn "*mulsi3subsi"
1739 [(set (match_operand:SI 0 "s_register_operand" "=r")
1741 (match_operand:SI 3 "s_register_operand" "r")
1742 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1743 (match_operand:SI 1 "s_register_operand" "r"))))]
1744 "TARGET_32BIT && arm_arch_thumb2"
1745 "mls%?\\t%0, %2, %1, %3"
1746 [(set_attr "type" "mla")
1747 (set_attr "predicable" "yes")]
1750 (define_expand "maddsidi4"
1751 [(set (match_operand:DI 0 "s_register_operand" "")
1754 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1755 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1756 (match_operand:DI 3 "s_register_operand" "")))]
1760 (define_insn "*mulsidi3adddi"
1761 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1764 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1765 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1766 (match_operand:DI 1 "s_register_operand" "0")))]
1767 "TARGET_32BIT && !arm_arch6"
1768 "smlal%?\\t%Q0, %R0, %3, %2"
1769 [(set_attr "type" "smlal")
1770 (set_attr "predicable" "yes")]
1773 (define_insn "*mulsidi3adddi_v6"
1774 [(set (match_operand:DI 0 "s_register_operand" "=r")
1777 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1778 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1779 (match_operand:DI 1 "s_register_operand" "0")))]
1780 "TARGET_32BIT && arm_arch6"
1781 "smlal%?\\t%Q0, %R0, %3, %2"
1782 [(set_attr "type" "smlal")
1783 (set_attr "predicable" "yes")]
1786 ;; 32x32->64 widening multiply.
1787 ;; As with mulsi3, the only difference between the v3-5 and v6+
1788 ;; versions of these patterns is the requirement that the output not
1789 ;; overlap the inputs, but that still means we have to have a named
1790 ;; expander and two different starred insns.
1792 (define_expand "mulsidi3"
1793 [(set (match_operand:DI 0 "s_register_operand" "")
1795 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1796 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1801 (define_insn "*mulsidi3_nov6"
1802 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1804 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1805 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1806 "TARGET_32BIT && !arm_arch6"
1807 "smull%?\\t%Q0, %R0, %1, %2"
1808 [(set_attr "type" "smull")
1809 (set_attr "predicable" "yes")]
1812 (define_insn "*mulsidi3_v6"
1813 [(set (match_operand:DI 0 "s_register_operand" "=r")
1815 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1816 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1817 "TARGET_32BIT && arm_arch6"
1818 "smull%?\\t%Q0, %R0, %1, %2"
1819 [(set_attr "type" "smull")
1820 (set_attr "predicable" "yes")]
1823 (define_expand "umulsidi3"
1824 [(set (match_operand:DI 0 "s_register_operand" "")
1826 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1827 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1832 (define_insn "*umulsidi3_nov6"
1833 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1835 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1836 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1837 "TARGET_32BIT && !arm_arch6"
1838 "umull%?\\t%Q0, %R0, %1, %2"
1839 [(set_attr "type" "umull")
1840 (set_attr "predicable" "yes")]
1843 (define_insn "*umulsidi3_v6"
1844 [(set (match_operand:DI 0 "s_register_operand" "=r")
1846 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1847 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1848 "TARGET_32BIT && arm_arch6"
1849 "umull%?\\t%Q0, %R0, %1, %2"
1850 [(set_attr "type" "umull")
1851 (set_attr "predicable" "yes")]
1854 (define_expand "umaddsidi4"
1855 [(set (match_operand:DI 0 "s_register_operand" "")
1858 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1859 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1860 (match_operand:DI 3 "s_register_operand" "")))]
1864 (define_insn "*umulsidi3adddi"
1865 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1868 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1869 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1870 (match_operand:DI 1 "s_register_operand" "0")))]
1871 "TARGET_32BIT && !arm_arch6"
1872 "umlal%?\\t%Q0, %R0, %3, %2"
1873 [(set_attr "type" "umlal")
1874 (set_attr "predicable" "yes")]
1877 (define_insn "*umulsidi3adddi_v6"
1878 [(set (match_operand:DI 0 "s_register_operand" "=r")
1881 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1882 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1883 (match_operand:DI 1 "s_register_operand" "0")))]
1884 "TARGET_32BIT && arm_arch6"
1885 "umlal%?\\t%Q0, %R0, %3, %2"
1886 [(set_attr "type" "umlal")
1887 (set_attr "predicable" "yes")]
1890 (define_expand "smulsi3_highpart"
1892 [(set (match_operand:SI 0 "s_register_operand" "")
1896 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1897 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1899 (clobber (match_scratch:SI 3 ""))])]
1904 (define_insn "*smulsi3_highpart_nov6"
1905 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1909 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1910 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1912 (clobber (match_scratch:SI 3 "=&r,&r"))]
1913 "TARGET_32BIT && !arm_arch6"
1914 "smull%?\\t%3, %0, %2, %1"
1915 [(set_attr "type" "smull")
1916 (set_attr "predicable" "yes")]
1919 (define_insn "*smulsi3_highpart_v6"
1920 [(set (match_operand:SI 0 "s_register_operand" "=r")
1924 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1925 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1927 (clobber (match_scratch:SI 3 "=r"))]
1928 "TARGET_32BIT && arm_arch6"
1929 "smull%?\\t%3, %0, %2, %1"
1930 [(set_attr "type" "smull")
1931 (set_attr "predicable" "yes")]
1934 (define_expand "umulsi3_highpart"
1936 [(set (match_operand:SI 0 "s_register_operand" "")
1940 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1941 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1943 (clobber (match_scratch:SI 3 ""))])]
1948 (define_insn "*umulsi3_highpart_nov6"
1949 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1953 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1954 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1956 (clobber (match_scratch:SI 3 "=&r,&r"))]
1957 "TARGET_32BIT && !arm_arch6"
1958 "umull%?\\t%3, %0, %2, %1"
1959 [(set_attr "type" "umull")
1960 (set_attr "predicable" "yes")]
1963 (define_insn "*umulsi3_highpart_v6"
1964 [(set (match_operand:SI 0 "s_register_operand" "=r")
1968 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1969 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1971 (clobber (match_scratch:SI 3 "=r"))]
1972 "TARGET_32BIT && arm_arch6"
1973 "umull%?\\t%3, %0, %2, %1"
1974 [(set_attr "type" "umull")
1975 (set_attr "predicable" "yes")]
1978 (define_insn "mulhisi3"
1979 [(set (match_operand:SI 0 "s_register_operand" "=r")
1980 (mult:SI (sign_extend:SI
1981 (match_operand:HI 1 "s_register_operand" "%r"))
1983 (match_operand:HI 2 "s_register_operand" "r"))))]
1984 "TARGET_DSP_MULTIPLY"
1985 "smulbb%?\\t%0, %1, %2"
1986 [(set_attr "type" "smulxy")
1987 (set_attr "predicable" "yes")]
1990 (define_insn "*mulhisi3tb"
1991 [(set (match_operand:SI 0 "s_register_operand" "=r")
1992 (mult:SI (ashiftrt:SI
1993 (match_operand:SI 1 "s_register_operand" "r")
1996 (match_operand:HI 2 "s_register_operand" "r"))))]
1997 "TARGET_DSP_MULTIPLY"
1998 "smultb%?\\t%0, %1, %2"
1999 [(set_attr "type" "smulxy")
2000 (set_attr "predicable" "yes")]
2003 (define_insn "*mulhisi3bt"
2004 [(set (match_operand:SI 0 "s_register_operand" "=r")
2005 (mult:SI (sign_extend:SI
2006 (match_operand:HI 1 "s_register_operand" "r"))
2008 (match_operand:SI 2 "s_register_operand" "r")
2010 "TARGET_DSP_MULTIPLY"
2011 "smulbt%?\\t%0, %1, %2"
2012 [(set_attr "type" "smulxy")
2013 (set_attr "predicable" "yes")]
2016 (define_insn "*mulhisi3tt"
2017 [(set (match_operand:SI 0 "s_register_operand" "=r")
2018 (mult:SI (ashiftrt:SI
2019 (match_operand:SI 1 "s_register_operand" "r")
2022 (match_operand:SI 2 "s_register_operand" "r")
2024 "TARGET_DSP_MULTIPLY"
2025 "smultt%?\\t%0, %1, %2"
2026 [(set_attr "type" "smulxy")
2027 (set_attr "predicable" "yes")]
2030 (define_insn "maddhisi4"
2031 [(set (match_operand:SI 0 "s_register_operand" "=r")
2032 (plus:SI (mult:SI (sign_extend:SI
2033 (match_operand:HI 1 "s_register_operand" "r"))
2035 (match_operand:HI 2 "s_register_operand" "r")))
2036 (match_operand:SI 3 "s_register_operand" "r")))]
2037 "TARGET_DSP_MULTIPLY"
2038 "smlabb%?\\t%0, %1, %2, %3"
2039 [(set_attr "type" "smlaxy")
2040 (set_attr "predicable" "yes")]
2043 ;; Note: there is no maddhisi4ibt because this one is canonical form
2044 (define_insn "*maddhisi4tb"
2045 [(set (match_operand:SI 0 "s_register_operand" "=r")
2046 (plus:SI (mult:SI (ashiftrt:SI
2047 (match_operand:SI 1 "s_register_operand" "r")
2050 (match_operand:HI 2 "s_register_operand" "r")))
2051 (match_operand:SI 3 "s_register_operand" "r")))]
2052 "TARGET_DSP_MULTIPLY"
2053 "smlatb%?\\t%0, %1, %2, %3"
2054 [(set_attr "type" "smlaxy")
2055 (set_attr "predicable" "yes")]
2058 (define_insn "*maddhisi4tt"
2059 [(set (match_operand:SI 0 "s_register_operand" "=r")
2060 (plus:SI (mult:SI (ashiftrt:SI
2061 (match_operand:SI 1 "s_register_operand" "r")
2064 (match_operand:SI 2 "s_register_operand" "r")
2066 (match_operand:SI 3 "s_register_operand" "r")))]
2067 "TARGET_DSP_MULTIPLY"
2068 "smlatt%?\\t%0, %1, %2, %3"
2069 [(set_attr "type" "smlaxy")
2070 (set_attr "predicable" "yes")]
2073 (define_insn "maddhidi4"
2074 [(set (match_operand:DI 0 "s_register_operand" "=r")
2076 (mult:DI (sign_extend:DI
2077 (match_operand:HI 1 "s_register_operand" "r"))
2079 (match_operand:HI 2 "s_register_operand" "r")))
2080 (match_operand:DI 3 "s_register_operand" "0")))]
2081 "TARGET_DSP_MULTIPLY"
2082 "smlalbb%?\\t%Q0, %R0, %1, %2"
2083 [(set_attr "type" "smlalxy")
2084 (set_attr "predicable" "yes")])
2086 ;; Note: there is no maddhidi4ibt because this one is canonical form
2087 (define_insn "*maddhidi4tb"
2088 [(set (match_operand:DI 0 "s_register_operand" "=r")
2090 (mult:DI (sign_extend:DI
2092 (match_operand:SI 1 "s_register_operand" "r")
2095 (match_operand:HI 2 "s_register_operand" "r")))
2096 (match_operand:DI 3 "s_register_operand" "0")))]
2097 "TARGET_DSP_MULTIPLY"
2098 "smlaltb%?\\t%Q0, %R0, %1, %2"
2099 [(set_attr "type" "smlalxy")
2100 (set_attr "predicable" "yes")])
2102 (define_insn "*maddhidi4tt"
2103 [(set (match_operand:DI 0 "s_register_operand" "=r")
2105 (mult:DI (sign_extend:DI
2107 (match_operand:SI 1 "s_register_operand" "r")
2111 (match_operand:SI 2 "s_register_operand" "r")
2113 (match_operand:DI 3 "s_register_operand" "0")))]
2114 "TARGET_DSP_MULTIPLY"
2115 "smlaltt%?\\t%Q0, %R0, %1, %2"
2116 [(set_attr "type" "smlalxy")
2117 (set_attr "predicable" "yes")])
2119 (define_expand "mulsf3"
2120 [(set (match_operand:SF 0 "s_register_operand" "")
2121 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2122 (match_operand:SF 2 "s_register_operand" "")))]
2123 "TARGET_32BIT && TARGET_HARD_FLOAT"
2127 (define_expand "muldf3"
2128 [(set (match_operand:DF 0 "s_register_operand" "")
2129 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2130 (match_operand:DF 2 "s_register_operand" "")))]
2131 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2137 (define_expand "divsf3"
2138 [(set (match_operand:SF 0 "s_register_operand" "")
2139 (div:SF (match_operand:SF 1 "s_register_operand" "")
2140 (match_operand:SF 2 "s_register_operand" "")))]
2141 "TARGET_32BIT && TARGET_HARD_FLOAT"
2144 (define_expand "divdf3"
2145 [(set (match_operand:DF 0 "s_register_operand" "")
2146 (div:DF (match_operand:DF 1 "s_register_operand" "")
2147 (match_operand:DF 2 "s_register_operand" "")))]
2148 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2151 ;; Boolean and,ior,xor insns
2153 ;; Split up double word logical operations
2155 ;; Split up simple DImode logical operations. Simply perform the logical
2156 ;; operation on the upper and lower halves of the registers.
2158 [(set (match_operand:DI 0 "s_register_operand" "")
2159 (match_operator:DI 6 "logical_binary_operator"
2160 [(match_operand:DI 1 "s_register_operand" "")
2161 (match_operand:DI 2 "s_register_operand" "")]))]
2162 "TARGET_32BIT && reload_completed
2163 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2164 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2165 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2166 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2169 operands[3] = gen_highpart (SImode, operands[0]);
2170 operands[0] = gen_lowpart (SImode, operands[0]);
2171 operands[4] = gen_highpart (SImode, operands[1]);
2172 operands[1] = gen_lowpart (SImode, operands[1]);
2173 operands[5] = gen_highpart (SImode, operands[2]);
2174 operands[2] = gen_lowpart (SImode, operands[2]);
2179 [(set (match_operand:DI 0 "s_register_operand" "")
2180 (match_operator:DI 6 "logical_binary_operator"
2181 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2182 (match_operand:DI 1 "s_register_operand" "")]))]
2183 "TARGET_32BIT && reload_completed"
2184 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2185 (set (match_dup 3) (match_op_dup:SI 6
2186 [(ashiftrt:SI (match_dup 2) (const_int 31))
2190 operands[3] = gen_highpart (SImode, operands[0]);
2191 operands[0] = gen_lowpart (SImode, operands[0]);
2192 operands[4] = gen_highpart (SImode, operands[1]);
2193 operands[1] = gen_lowpart (SImode, operands[1]);
2194 operands[5] = gen_highpart (SImode, operands[2]);
2195 operands[2] = gen_lowpart (SImode, operands[2]);
2199 ;; The zero extend of operand 2 means we can just copy the high part of
2200 ;; operand1 into operand0.
2202 [(set (match_operand:DI 0 "s_register_operand" "")
2204 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2205 (match_operand:DI 1 "s_register_operand" "")))]
2206 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2207 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2208 (set (match_dup 3) (match_dup 4))]
2211 operands[4] = gen_highpart (SImode, operands[1]);
2212 operands[3] = gen_highpart (SImode, operands[0]);
2213 operands[0] = gen_lowpart (SImode, operands[0]);
2214 operands[1] = gen_lowpart (SImode, operands[1]);
2218 ;; The zero extend of operand 2 means we can just copy the high part of
2219 ;; operand1 into operand0.
2221 [(set (match_operand:DI 0 "s_register_operand" "")
2223 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2224 (match_operand:DI 1 "s_register_operand" "")))]
2225 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2226 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2227 (set (match_dup 3) (match_dup 4))]
2230 operands[4] = gen_highpart (SImode, operands[1]);
2231 operands[3] = gen_highpart (SImode, operands[0]);
2232 operands[0] = gen_lowpart (SImode, operands[0]);
2233 operands[1] = gen_lowpart (SImode, operands[1]);
2237 (define_expand "anddi3"
2238 [(set (match_operand:DI 0 "s_register_operand" "")
2239 (and:DI (match_operand:DI 1 "s_register_operand" "")
2240 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2243 if (!TARGET_NEON && !TARGET_IWMMXT)
2245 rtx low = simplify_gen_binary (AND, SImode,
2246 gen_lowpart (SImode, operands[1]),
2247 gen_lowpart (SImode, operands[2]));
2248 rtx high = simplify_gen_binary (AND, SImode,
2249 gen_highpart (SImode, operands[1]),
2250 gen_highpart_mode (SImode, DImode,
2253 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2254 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2258 /* Otherwise expand pattern as above. */
2262 (define_insn_and_split "*anddi3_insn"
2263 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2264 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2265 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2266 "TARGET_32BIT && !TARGET_IWMMXT"
2268 switch (which_alternative)
2270 case 0: /* fall through */
2271 case 6: return "vand\t%P0, %P1, %P2";
2272 case 1: /* fall through */
2273 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2274 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2278 case 5: /* fall through */
2280 default: gcc_unreachable ();
2283 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2284 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2285 [(set (match_dup 3) (match_dup 4))
2286 (set (match_dup 5) (match_dup 6))]
2289 operands[3] = gen_lowpart (SImode, operands[0]);
2290 operands[5] = gen_highpart (SImode, operands[0]);
2292 operands[4] = simplify_gen_binary (AND, SImode,
2293 gen_lowpart (SImode, operands[1]),
2294 gen_lowpart (SImode, operands[2]));
2295 operands[6] = simplify_gen_binary (AND, SImode,
2296 gen_highpart (SImode, operands[1]),
2297 gen_highpart_mode (SImode, DImode, operands[2]));
2300 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2301 multiple,multiple,neon_logic,neon_logic")
2302 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2303 avoid_neon_for_64bits,avoid_neon_for_64bits")
2304 (set_attr "length" "*,*,8,8,8,8,*,*")
2308 (define_insn_and_split "*anddi_zesidi_di"
2309 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2310 (and:DI (zero_extend:DI
2311 (match_operand:SI 2 "s_register_operand" "r,r"))
2312 (match_operand:DI 1 "s_register_operand" "0,r")))]
2315 "TARGET_32BIT && reload_completed"
2316 ; The zero extend of operand 2 clears the high word of the output
2318 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2319 (set (match_dup 3) (const_int 0))]
2322 operands[3] = gen_highpart (SImode, operands[0]);
2323 operands[0] = gen_lowpart (SImode, operands[0]);
2324 operands[1] = gen_lowpart (SImode, operands[1]);
2326 [(set_attr "length" "8")
2327 (set_attr "type" "multiple")]
2330 (define_insn "*anddi_sesdi_di"
2331 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2332 (and:DI (sign_extend:DI
2333 (match_operand:SI 2 "s_register_operand" "r,r"))
2334 (match_operand:DI 1 "s_register_operand" "0,r")))]
2337 [(set_attr "length" "8")
2338 (set_attr "type" "multiple")]
2341 (define_expand "andsi3"
2342 [(set (match_operand:SI 0 "s_register_operand" "")
2343 (and:SI (match_operand:SI 1 "s_register_operand" "")
2344 (match_operand:SI 2 "reg_or_int_operand" "")))]
2349 if (CONST_INT_P (operands[2]))
2351 if (INTVAL (operands[2]) == 255 && arm_arch6)
2353 operands[1] = convert_to_mode (QImode, operands[1], 1);
2354 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2358 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2359 operands[2] = force_reg (SImode, operands[2]);
2362 arm_split_constant (AND, SImode, NULL_RTX,
2363 INTVAL (operands[2]), operands[0],
2365 optimize && can_create_pseudo_p ());
2371 else /* TARGET_THUMB1 */
2373 if (!CONST_INT_P (operands[2]))
2375 rtx tmp = force_reg (SImode, operands[2]);
2376 if (rtx_equal_p (operands[0], operands[1]))
2380 operands[2] = operands[1];
2388 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2390 operands[2] = force_reg (SImode,
2391 GEN_INT (~INTVAL (operands[2])));
2393 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2398 for (i = 9; i <= 31; i++)
2400 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2402 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2406 else if ((HOST_WIDE_INT_1 << i) - 1
2407 == ~INTVAL (operands[2]))
2409 rtx shift = GEN_INT (i);
2410 rtx reg = gen_reg_rtx (SImode);
2412 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2413 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2419 operands[2] = force_reg (SImode, operands[2]);
2425 ; ??? Check split length for Thumb-2
2426 (define_insn_and_split "*arm_andsi3_insn"
2427 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2428 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2429 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2434 bic%?\\t%0, %1, #%B2
2438 && CONST_INT_P (operands[2])
2439 && !(const_ok_for_arm (INTVAL (operands[2]))
2440 || const_ok_for_arm (~INTVAL (operands[2])))"
2441 [(clobber (const_int 0))]
2443 arm_split_constant (AND, SImode, curr_insn,
2444 INTVAL (operands[2]), operands[0], operands[1], 0);
2447 [(set_attr "length" "4,4,4,4,16")
2448 (set_attr "predicable" "yes")
2449 (set_attr "predicable_short_it" "no,yes,no,no,no")
2450 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2453 (define_insn "*andsi3_compare0"
2454 [(set (reg:CC_NOOV CC_REGNUM)
2456 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2457 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2459 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2460 (and:SI (match_dup 1) (match_dup 2)))]
2464 bics%?\\t%0, %1, #%B2
2465 ands%?\\t%0, %1, %2"
2466 [(set_attr "conds" "set")
2467 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2470 (define_insn "*andsi3_compare0_scratch"
2471 [(set (reg:CC_NOOV CC_REGNUM)
2473 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2474 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2476 (clobber (match_scratch:SI 2 "=X,r,X"))]
2480 bics%?\\t%2, %0, #%B1
2482 [(set_attr "conds" "set")
2483 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2486 (define_insn "*zeroextractsi_compare0_scratch"
2487 [(set (reg:CC_NOOV CC_REGNUM)
2488 (compare:CC_NOOV (zero_extract:SI
2489 (match_operand:SI 0 "s_register_operand" "r")
2490 (match_operand 1 "const_int_operand" "n")
2491 (match_operand 2 "const_int_operand" "n"))
2494 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2495 && INTVAL (operands[1]) > 0
2496 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2497 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2499 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2500 << INTVAL (operands[2]));
2501 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2504 [(set_attr "conds" "set")
2505 (set_attr "predicable" "yes")
2506 (set_attr "type" "logics_imm")]
2509 (define_insn_and_split "*ne_zeroextractsi"
2510 [(set (match_operand:SI 0 "s_register_operand" "=r")
2511 (ne:SI (zero_extract:SI
2512 (match_operand:SI 1 "s_register_operand" "r")
2513 (match_operand:SI 2 "const_int_operand" "n")
2514 (match_operand:SI 3 "const_int_operand" "n"))
2516 (clobber (reg:CC CC_REGNUM))]
2518 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2519 && INTVAL (operands[2]) > 0
2520 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2521 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2524 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2525 && INTVAL (operands[2]) > 0
2526 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2527 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2528 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2529 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2531 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2533 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2534 (match_dup 0) (const_int 1)))]
2536 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2537 << INTVAL (operands[3]));
2539 [(set_attr "conds" "clob")
2540 (set (attr "length")
2541 (if_then_else (eq_attr "is_thumb" "yes")
2544 (set_attr "type" "multiple")]
2547 (define_insn_and_split "*ne_zeroextractsi_shifted"
2548 [(set (match_operand:SI 0 "s_register_operand" "=r")
2549 (ne:SI (zero_extract:SI
2550 (match_operand:SI 1 "s_register_operand" "r")
2551 (match_operand:SI 2 "const_int_operand" "n")
2554 (clobber (reg:CC CC_REGNUM))]
2558 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2559 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2561 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2563 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2564 (match_dup 0) (const_int 1)))]
2566 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2568 [(set_attr "conds" "clob")
2569 (set_attr "length" "8")
2570 (set_attr "type" "multiple")]
2573 (define_insn_and_split "*ite_ne_zeroextractsi"
2574 [(set (match_operand:SI 0 "s_register_operand" "=r")
2575 (if_then_else:SI (ne (zero_extract:SI
2576 (match_operand:SI 1 "s_register_operand" "r")
2577 (match_operand:SI 2 "const_int_operand" "n")
2578 (match_operand:SI 3 "const_int_operand" "n"))
2580 (match_operand:SI 4 "arm_not_operand" "rIK")
2582 (clobber (reg:CC CC_REGNUM))]
2584 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2585 && INTVAL (operands[2]) > 0
2586 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2587 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2588 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2591 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2592 && INTVAL (operands[2]) > 0
2593 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2594 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2595 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2596 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2597 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2599 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2601 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2602 (match_dup 0) (match_dup 4)))]
2604 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2605 << INTVAL (operands[3]));
2607 [(set_attr "conds" "clob")
2608 (set_attr "length" "8")
2609 (set_attr "type" "multiple")]
2612 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2613 [(set (match_operand:SI 0 "s_register_operand" "=r")
2614 (if_then_else:SI (ne (zero_extract:SI
2615 (match_operand:SI 1 "s_register_operand" "r")
2616 (match_operand:SI 2 "const_int_operand" "n")
2619 (match_operand:SI 3 "arm_not_operand" "rIK")
2621 (clobber (reg:CC CC_REGNUM))]
2622 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2624 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2625 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2626 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2628 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2630 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2631 (match_dup 0) (match_dup 3)))]
2633 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2635 [(set_attr "conds" "clob")
2636 (set_attr "length" "8")
2637 (set_attr "type" "multiple")]
2640 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2642 [(set (match_operand:SI 0 "s_register_operand" "")
2643 (match_operator:SI 1 "shiftable_operator"
2644 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2645 (match_operand:SI 3 "const_int_operand" "")
2646 (match_operand:SI 4 "const_int_operand" ""))
2647 (match_operand:SI 5 "s_register_operand" "")]))
2648 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2650 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2653 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2656 HOST_WIDE_INT temp = INTVAL (operands[3]);
2658 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2659 operands[4] = GEN_INT (32 - temp);
2664 [(set (match_operand:SI 0 "s_register_operand" "")
2665 (match_operator:SI 1 "shiftable_operator"
2666 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2667 (match_operand:SI 3 "const_int_operand" "")
2668 (match_operand:SI 4 "const_int_operand" ""))
2669 (match_operand:SI 5 "s_register_operand" "")]))
2670 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2672 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2675 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2678 HOST_WIDE_INT temp = INTVAL (operands[3]);
2680 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2681 operands[4] = GEN_INT (32 - temp);
2685 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2686 ;;; represented by the bitfield, then this will produce incorrect results.
2687 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2688 ;;; which have a real bit-field insert instruction, the truncation happens
2689 ;;; in the bit-field insert instruction itself. Since arm does not have a
2690 ;;; bit-field insert instruction, we would have to emit code here to truncate
2691 ;;; the value before we insert. This loses some of the advantage of having
2692 ;;; this insv pattern, so this pattern needs to be reevalutated.
2694 (define_expand "insv"
2695 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2696 (match_operand 1 "general_operand" "")
2697 (match_operand 2 "general_operand" ""))
2698 (match_operand 3 "reg_or_int_operand" ""))]
2699 "TARGET_ARM || arm_arch_thumb2"
2702 int start_bit = INTVAL (operands[2]);
2703 int width = INTVAL (operands[1]);
2704 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2705 rtx target, subtarget;
2707 if (arm_arch_thumb2)
2709 if (unaligned_access && MEM_P (operands[0])
2710 && s_register_operand (operands[3], GET_MODE (operands[3]))
2711 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2715 if (BYTES_BIG_ENDIAN)
2716 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2721 base_addr = adjust_address (operands[0], SImode,
2722 start_bit / BITS_PER_UNIT);
2723 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2727 rtx tmp = gen_reg_rtx (HImode);
2729 base_addr = adjust_address (operands[0], HImode,
2730 start_bit / BITS_PER_UNIT);
2731 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2732 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2736 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2738 bool use_bfi = TRUE;
2740 if (CONST_INT_P (operands[3]))
2742 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2746 emit_insn (gen_insv_zero (operands[0], operands[1],
2751 /* See if the set can be done with a single orr instruction. */
2752 if (val == mask && const_ok_for_arm (val << start_bit))
2758 if (!REG_P (operands[3]))
2759 operands[3] = force_reg (SImode, operands[3]);
2761 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2770 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2773 target = copy_rtx (operands[0]);
2774 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2775 subreg as the final target. */
2776 if (GET_CODE (target) == SUBREG)
2778 subtarget = gen_reg_rtx (SImode);
2779 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2780 < GET_MODE_SIZE (SImode))
2781 target = SUBREG_REG (target);
2786 if (CONST_INT_P (operands[3]))
2788 /* Since we are inserting a known constant, we may be able to
2789 reduce the number of bits that we have to clear so that
2790 the mask becomes simple. */
2791 /* ??? This code does not check to see if the new mask is actually
2792 simpler. It may not be. */
2793 rtx op1 = gen_reg_rtx (SImode);
2794 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2795 start of this pattern. */
2796 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2797 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2799 emit_insn (gen_andsi3 (op1, operands[0],
2800 gen_int_mode (~mask2, SImode)));
2801 emit_insn (gen_iorsi3 (subtarget, op1,
2802 gen_int_mode (op3_value << start_bit, SImode)));
2804 else if (start_bit == 0
2805 && !(const_ok_for_arm (mask)
2806 || const_ok_for_arm (~mask)))
2808 /* A Trick, since we are setting the bottom bits in the word,
2809 we can shift operand[3] up, operand[0] down, OR them together
2810 and rotate the result back again. This takes 3 insns, and
2811 the third might be mergeable into another op. */
2812 /* The shift up copes with the possibility that operand[3] is
2813 wider than the bitfield. */
2814 rtx op0 = gen_reg_rtx (SImode);
2815 rtx op1 = gen_reg_rtx (SImode);
2817 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2818 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2819 emit_insn (gen_iorsi3 (op1, op1, op0));
2820 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2822 else if ((width + start_bit == 32)
2823 && !(const_ok_for_arm (mask)
2824 || const_ok_for_arm (~mask)))
2826 /* Similar trick, but slightly less efficient. */
2828 rtx op0 = gen_reg_rtx (SImode);
2829 rtx op1 = gen_reg_rtx (SImode);
2831 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2832 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2833 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2834 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2838 rtx op0 = gen_int_mode (mask, SImode);
2839 rtx op1 = gen_reg_rtx (SImode);
2840 rtx op2 = gen_reg_rtx (SImode);
2842 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2844 rtx tmp = gen_reg_rtx (SImode);
2846 emit_insn (gen_movsi (tmp, op0));
2850 /* Mask out any bits in operand[3] that are not needed. */
2851 emit_insn (gen_andsi3 (op1, operands[3], op0));
2853 if (CONST_INT_P (op0)
2854 && (const_ok_for_arm (mask << start_bit)
2855 || const_ok_for_arm (~(mask << start_bit))))
2857 op0 = gen_int_mode (~(mask << start_bit), SImode);
2858 emit_insn (gen_andsi3 (op2, operands[0], op0));
2862 if (CONST_INT_P (op0))
2864 rtx tmp = gen_reg_rtx (SImode);
2866 emit_insn (gen_movsi (tmp, op0));
2871 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2873 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2877 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2879 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2882 if (subtarget != target)
2884 /* If TARGET is still a SUBREG, then it must be wider than a word,
2885 so we must be careful only to set the subword we were asked to. */
2886 if (GET_CODE (target) == SUBREG)
2887 emit_move_insn (target, subtarget);
2889 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2896 (define_insn "insv_zero"
2897 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2898 (match_operand:SI 1 "const_int_M_operand" "M")
2899 (match_operand:SI 2 "const_int_M_operand" "M"))
2903 [(set_attr "length" "4")
2904 (set_attr "predicable" "yes")
2905 (set_attr "type" "bfm")]
2908 (define_insn "insv_t2"
2909 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2910 (match_operand:SI 1 "const_int_M_operand" "M")
2911 (match_operand:SI 2 "const_int_M_operand" "M"))
2912 (match_operand:SI 3 "s_register_operand" "r"))]
2914 "bfi%?\t%0, %3, %2, %1"
2915 [(set_attr "length" "4")
2916 (set_attr "predicable" "yes")
2917 (set_attr "type" "bfm")]
2920 ; constants for op 2 will never be given to these patterns.
2921 (define_insn_and_split "*anddi_notdi_di"
2922 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2923 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2924 (match_operand:DI 2 "s_register_operand" "r,0")))]
2927 "TARGET_32BIT && reload_completed
2928 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2929 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2930 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2931 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2934 operands[3] = gen_highpart (SImode, operands[0]);
2935 operands[0] = gen_lowpart (SImode, operands[0]);
2936 operands[4] = gen_highpart (SImode, operands[1]);
2937 operands[1] = gen_lowpart (SImode, operands[1]);
2938 operands[5] = gen_highpart (SImode, operands[2]);
2939 operands[2] = gen_lowpart (SImode, operands[2]);
2941 [(set_attr "length" "8")
2942 (set_attr "predicable" "yes")
2943 (set_attr "type" "multiple")]
2946 (define_insn_and_split "*anddi_notzesidi_di"
2947 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2948 (and:DI (not:DI (zero_extend:DI
2949 (match_operand:SI 2 "s_register_operand" "r,r")))
2950 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2953 bic%?\\t%Q0, %Q1, %2
2955 ; (not (zero_extend ...)) allows us to just copy the high word from
2956 ; operand1 to operand0.
2959 && operands[0] != operands[1]"
2960 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2961 (set (match_dup 3) (match_dup 4))]
2964 operands[3] = gen_highpart (SImode, operands[0]);
2965 operands[0] = gen_lowpart (SImode, operands[0]);
2966 operands[4] = gen_highpart (SImode, operands[1]);
2967 operands[1] = gen_lowpart (SImode, operands[1]);
2969 [(set_attr "length" "4,8")
2970 (set_attr "predicable" "yes")
2971 (set_attr "type" "multiple")]
2974 (define_insn_and_split "*anddi_notdi_zesidi"
2975 [(set (match_operand:DI 0 "s_register_operand" "=r")
2976 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2978 (match_operand:SI 1 "s_register_operand" "r"))))]
2981 "TARGET_32BIT && reload_completed"
2982 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2983 (set (match_dup 3) (const_int 0))]
2986 operands[3] = gen_highpart (SImode, operands[0]);
2987 operands[0] = gen_lowpart (SImode, operands[0]);
2988 operands[2] = gen_lowpart (SImode, operands[2]);
2990 [(set_attr "length" "8")
2991 (set_attr "predicable" "yes")
2992 (set_attr "type" "multiple")]
2995 (define_insn_and_split "*anddi_notsesidi_di"
2996 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2997 (and:DI (not:DI (sign_extend:DI
2998 (match_operand:SI 2 "s_register_operand" "r,r")))
2999 (match_operand:DI 1 "s_register_operand" "0,r")))]
3002 "TARGET_32BIT && reload_completed"
3003 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3004 (set (match_dup 3) (and:SI (not:SI
3005 (ashiftrt:SI (match_dup 2) (const_int 31)))
3009 operands[3] = gen_highpart (SImode, operands[0]);
3010 operands[0] = gen_lowpart (SImode, operands[0]);
3011 operands[4] = gen_highpart (SImode, operands[1]);
3012 operands[1] = gen_lowpart (SImode, operands[1]);
3014 [(set_attr "length" "8")
3015 (set_attr "predicable" "yes")
3016 (set_attr "type" "multiple")]
3019 (define_insn "andsi_notsi_si"
3020 [(set (match_operand:SI 0 "s_register_operand" "=r")
3021 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3022 (match_operand:SI 1 "s_register_operand" "r")))]
3024 "bic%?\\t%0, %1, %2"
3025 [(set_attr "predicable" "yes")
3026 (set_attr "type" "logic_reg")]
3029 (define_insn "andsi_not_shiftsi_si"
3030 [(set (match_operand:SI 0 "s_register_operand" "=r")
3031 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3032 [(match_operand:SI 2 "s_register_operand" "r")
3033 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3034 (match_operand:SI 1 "s_register_operand" "r")))]
3036 "bic%?\\t%0, %1, %2%S4"
3037 [(set_attr "predicable" "yes")
3038 (set_attr "shift" "2")
3039 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3040 (const_string "logic_shift_imm")
3041 (const_string "logic_shift_reg")))]
3044 ;; Shifted bics pattern used to set up CC status register and not reusing
3045 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3046 ;; does not support shift by register.
3047 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3048 [(set (reg:CC_NOOV CC_REGNUM)
3050 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3051 [(match_operand:SI 1 "s_register_operand" "r")
3052 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3053 (match_operand:SI 3 "s_register_operand" "r"))
3055 (clobber (match_scratch:SI 4 "=r"))]
3056 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3057 "bics%?\\t%4, %3, %1%S0"
3058 [(set_attr "predicable" "yes")
3059 (set_attr "conds" "set")
3060 (set_attr "shift" "1")
3061 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3062 (const_string "logic_shift_imm")
3063 (const_string "logic_shift_reg")))]
3066 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3067 ;; getting reused later.
3068 (define_insn "andsi_not_shiftsi_si_scc"
3069 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3071 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3072 [(match_operand:SI 1 "s_register_operand" "r")
3073 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3074 (match_operand:SI 3 "s_register_operand" "r"))
3076 (set (match_operand:SI 4 "s_register_operand" "=r")
3077 (and:SI (not:SI (match_op_dup 0
3081 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3082 "bics%?\\t%4, %3, %1%S0"
3083 [(set_attr "predicable" "yes")
3084 (set_attr "conds" "set")
3085 (set_attr "shift" "1")
3086 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3087 (const_string "logic_shift_imm")
3088 (const_string "logic_shift_reg")))]
3091 (define_insn "*andsi_notsi_si_compare0"
3092 [(set (reg:CC_NOOV CC_REGNUM)
3094 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3095 (match_operand:SI 1 "s_register_operand" "r"))
3097 (set (match_operand:SI 0 "s_register_operand" "=r")
3098 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3101 [(set_attr "conds" "set")
3102 (set_attr "type" "logics_shift_reg")]
3105 (define_insn "*andsi_notsi_si_compare0_scratch"
3106 [(set (reg:CC_NOOV CC_REGNUM)
3108 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3109 (match_operand:SI 1 "s_register_operand" "r"))
3111 (clobber (match_scratch:SI 0 "=r"))]
3114 [(set_attr "conds" "set")
3115 (set_attr "type" "logics_shift_reg")]
3118 (define_expand "iordi3"
3119 [(set (match_operand:DI 0 "s_register_operand" "")
3120 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3121 (match_operand:DI 2 "neon_logic_op2" "")))]
3124 if (!TARGET_NEON && !TARGET_IWMMXT)
3126 rtx low = simplify_gen_binary (IOR, SImode,
3127 gen_lowpart (SImode, operands[1]),
3128 gen_lowpart (SImode, operands[2]));
3129 rtx high = simplify_gen_binary (IOR, SImode,
3130 gen_highpart (SImode, operands[1]),
3131 gen_highpart_mode (SImode, DImode,
3134 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3135 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3139 /* Otherwise expand pattern as above. */
3143 (define_insn_and_split "*iordi3_insn"
3144 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3145 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3146 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3147 "TARGET_32BIT && !TARGET_IWMMXT"
3149 switch (which_alternative)
3151 case 0: /* fall through */
3152 case 6: return "vorr\t%P0, %P1, %P2";
3153 case 1: /* fall through */
3154 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3155 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3161 default: gcc_unreachable ();
3164 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3165 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3166 [(set (match_dup 3) (match_dup 4))
3167 (set (match_dup 5) (match_dup 6))]
3170 operands[3] = gen_lowpart (SImode, operands[0]);
3171 operands[5] = gen_highpart (SImode, operands[0]);
3173 operands[4] = simplify_gen_binary (IOR, SImode,
3174 gen_lowpart (SImode, operands[1]),
3175 gen_lowpart (SImode, operands[2]));
3176 operands[6] = simplify_gen_binary (IOR, SImode,
3177 gen_highpart (SImode, operands[1]),
3178 gen_highpart_mode (SImode, DImode, operands[2]));
3181 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3182 multiple,neon_logic,neon_logic")
3183 (set_attr "length" "*,*,8,8,8,8,*,*")
3184 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3187 (define_insn "*iordi_zesidi_di"
3188 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3189 (ior:DI (zero_extend:DI
3190 (match_operand:SI 2 "s_register_operand" "r,r"))
3191 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3194 orr%?\\t%Q0, %Q1, %2
3196 [(set_attr "length" "4,8")
3197 (set_attr "predicable" "yes")
3198 (set_attr "type" "logic_reg,multiple")]
3201 (define_insn "*iordi_sesidi_di"
3202 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3203 (ior:DI (sign_extend:DI
3204 (match_operand:SI 2 "s_register_operand" "r,r"))
3205 (match_operand:DI 1 "s_register_operand" "0,r")))]
3208 [(set_attr "length" "8")
3209 (set_attr "predicable" "yes")
3210 (set_attr "type" "multiple")]
3213 (define_expand "iorsi3"
3214 [(set (match_operand:SI 0 "s_register_operand" "")
3215 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3216 (match_operand:SI 2 "reg_or_int_operand" "")))]
3219 if (CONST_INT_P (operands[2]))
3223 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3224 operands[2] = force_reg (SImode, operands[2]);
3227 arm_split_constant (IOR, SImode, NULL_RTX,
3228 INTVAL (operands[2]), operands[0],
3230 optimize && can_create_pseudo_p ());
3234 else /* TARGET_THUMB1 */
3236 rtx tmp = force_reg (SImode, operands[2]);
3237 if (rtx_equal_p (operands[0], operands[1]))
3241 operands[2] = operands[1];
3249 (define_insn_and_split "*iorsi3_insn"
3250 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3251 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3252 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3257 orn%?\\t%0, %1, #%B2
3261 && CONST_INT_P (operands[2])
3262 && !(const_ok_for_arm (INTVAL (operands[2]))
3263 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3264 [(clobber (const_int 0))]
3266 arm_split_constant (IOR, SImode, curr_insn,
3267 INTVAL (operands[2]), operands[0], operands[1], 0);
3270 [(set_attr "length" "4,4,4,4,16")
3271 (set_attr "arch" "32,t2,t2,32,32")
3272 (set_attr "predicable" "yes")
3273 (set_attr "predicable_short_it" "no,yes,no,no,no")
3274 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3278 [(match_scratch:SI 3 "r")
3279 (set (match_operand:SI 0 "arm_general_register_operand" "")
3280 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3281 (match_operand:SI 2 "const_int_operand" "")))]
3283 && !const_ok_for_arm (INTVAL (operands[2]))
3284 && const_ok_for_arm (~INTVAL (operands[2]))"
3285 [(set (match_dup 3) (match_dup 2))
3286 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3290 (define_insn "*iorsi3_compare0"
3291 [(set (reg:CC_NOOV CC_REGNUM)
3292 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3293 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3295 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3296 (ior:SI (match_dup 1) (match_dup 2)))]
3298 "orrs%?\\t%0, %1, %2"
3299 [(set_attr "conds" "set")
3300 (set_attr "type" "logics_imm,logics_reg")]
3303 (define_insn "*iorsi3_compare0_scratch"
3304 [(set (reg:CC_NOOV CC_REGNUM)
3305 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3306 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3308 (clobber (match_scratch:SI 0 "=r,r"))]
3310 "orrs%?\\t%0, %1, %2"
3311 [(set_attr "conds" "set")
3312 (set_attr "type" "logics_imm,logics_reg")]
3315 (define_expand "xordi3"
3316 [(set (match_operand:DI 0 "s_register_operand" "")
3317 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3318 (match_operand:DI 2 "arm_xordi_operand" "")))]
3321 /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3322 to reuse this expander for all TARGET_32BIT targets so just force the
3323 constants into a register. Unlike for the anddi3 and iordi3 there are
3324 no NEON instructions that take an immediate. */
3325 if (TARGET_IWMMXT && !REG_P (operands[2]))
3326 operands[2] = force_reg (DImode, operands[2]);
3327 if (!TARGET_NEON && !TARGET_IWMMXT)
3329 rtx low = simplify_gen_binary (XOR, SImode,
3330 gen_lowpart (SImode, operands[1]),
3331 gen_lowpart (SImode, operands[2]));
3332 rtx high = simplify_gen_binary (XOR, SImode,
3333 gen_highpart (SImode, operands[1]),
3334 gen_highpart_mode (SImode, DImode,
3337 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3338 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3342 /* Otherwise expand pattern as above. */
3346 (define_insn_and_split "*xordi3_insn"
3347 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3348 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3349 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3350 "TARGET_32BIT && !TARGET_IWMMXT"
3352 switch (which_alternative)
3357 case 4: /* fall through */
3359 case 0: /* fall through */
3360 case 5: return "veor\t%P0, %P1, %P2";
3361 default: gcc_unreachable ();
3364 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3365 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3366 [(set (match_dup 3) (match_dup 4))
3367 (set (match_dup 5) (match_dup 6))]
3370 operands[3] = gen_lowpart (SImode, operands[0]);
3371 operands[5] = gen_highpart (SImode, operands[0]);
3373 operands[4] = simplify_gen_binary (XOR, SImode,
3374 gen_lowpart (SImode, operands[1]),
3375 gen_lowpart (SImode, operands[2]));
3376 operands[6] = simplify_gen_binary (XOR, SImode,
3377 gen_highpart (SImode, operands[1]),
3378 gen_highpart_mode (SImode, DImode, operands[2]));
3381 [(set_attr "length" "*,8,8,8,8,*")
3382 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3383 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3386 (define_insn "*xordi_zesidi_di"
3387 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3388 (xor:DI (zero_extend:DI
3389 (match_operand:SI 2 "s_register_operand" "r,r"))
3390 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3393 eor%?\\t%Q0, %Q1, %2
3395 [(set_attr "length" "4,8")
3396 (set_attr "predicable" "yes")
3397 (set_attr "type" "logic_reg")]
3400 (define_insn "*xordi_sesidi_di"
3401 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3402 (xor:DI (sign_extend:DI
3403 (match_operand:SI 2 "s_register_operand" "r,r"))
3404 (match_operand:DI 1 "s_register_operand" "0,r")))]
3407 [(set_attr "length" "8")
3408 (set_attr "predicable" "yes")
3409 (set_attr "type" "multiple")]
3412 (define_expand "xorsi3"
3413 [(set (match_operand:SI 0 "s_register_operand" "")
3414 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3415 (match_operand:SI 2 "reg_or_int_operand" "")))]
3417 "if (CONST_INT_P (operands[2]))
3421 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3422 operands[2] = force_reg (SImode, operands[2]);
3425 arm_split_constant (XOR, SImode, NULL_RTX,
3426 INTVAL (operands[2]), operands[0],
3428 optimize && can_create_pseudo_p ());
3432 else /* TARGET_THUMB1 */
3434 rtx tmp = force_reg (SImode, operands[2]);
3435 if (rtx_equal_p (operands[0], operands[1]))
3439 operands[2] = operands[1];
3446 (define_insn_and_split "*arm_xorsi3"
3447 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3448 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3449 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3457 && CONST_INT_P (operands[2])
3458 && !const_ok_for_arm (INTVAL (operands[2]))"
3459 [(clobber (const_int 0))]
3461 arm_split_constant (XOR, SImode, curr_insn,
3462 INTVAL (operands[2]), operands[0], operands[1], 0);
3465 [(set_attr "length" "4,4,4,16")
3466 (set_attr "predicable" "yes")
3467 (set_attr "predicable_short_it" "no,yes,no,no")
3468 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3471 (define_insn "*xorsi3_compare0"
3472 [(set (reg:CC_NOOV CC_REGNUM)
3473 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3474 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3476 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3477 (xor:SI (match_dup 1) (match_dup 2)))]
3479 "eors%?\\t%0, %1, %2"
3480 [(set_attr "conds" "set")
3481 (set_attr "type" "logics_imm,logics_reg")]
3484 (define_insn "*xorsi3_compare0_scratch"
3485 [(set (reg:CC_NOOV CC_REGNUM)
3486 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3487 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3491 [(set_attr "conds" "set")
3492 (set_attr "type" "logics_imm,logics_reg")]
3495 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3496 ; (NOT D) we can sometimes merge the final NOT into one of the following
3500 [(set (match_operand:SI 0 "s_register_operand" "")
3501 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3502 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3503 (match_operand:SI 3 "arm_rhs_operand" "")))
3504 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3506 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3507 (not:SI (match_dup 3))))
3508 (set (match_dup 0) (not:SI (match_dup 4)))]
3512 (define_insn_and_split "*andsi_iorsi3_notsi"
3513 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3514 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3515 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3516 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3518 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3519 "&& reload_completed"
3520 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3521 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3523 /* If operands[3] is a constant make sure to fold the NOT into it
3524 to avoid creating a NOT of a CONST_INT. */
3525 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3526 if (CONST_INT_P (not_rtx))
3528 operands[4] = operands[0];
3529 operands[5] = not_rtx;
3533 operands[5] = operands[0];
3534 operands[4] = not_rtx;
3537 [(set_attr "length" "8")
3538 (set_attr "ce_count" "2")
3539 (set_attr "predicable" "yes")
3540 (set_attr "type" "multiple")]
3543 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3544 ; insns are available?
3546 [(set (match_operand:SI 0 "s_register_operand" "")
3547 (match_operator:SI 1 "logical_binary_operator"
3548 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3549 (match_operand:SI 3 "const_int_operand" "")
3550 (match_operand:SI 4 "const_int_operand" ""))
3551 (match_operator:SI 9 "logical_binary_operator"
3552 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3553 (match_operand:SI 6 "const_int_operand" ""))
3554 (match_operand:SI 7 "s_register_operand" "")])]))
3555 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3557 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3558 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3561 [(ashift:SI (match_dup 2) (match_dup 4))
3565 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3568 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3572 [(set (match_operand:SI 0 "s_register_operand" "")
3573 (match_operator:SI 1 "logical_binary_operator"
3574 [(match_operator:SI 9 "logical_binary_operator"
3575 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3576 (match_operand:SI 6 "const_int_operand" ""))
3577 (match_operand:SI 7 "s_register_operand" "")])
3578 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3579 (match_operand:SI 3 "const_int_operand" "")
3580 (match_operand:SI 4 "const_int_operand" ""))]))
3581 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3583 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3584 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3587 [(ashift:SI (match_dup 2) (match_dup 4))
3591 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3594 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3598 [(set (match_operand:SI 0 "s_register_operand" "")
3599 (match_operator:SI 1 "logical_binary_operator"
3600 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3601 (match_operand:SI 3 "const_int_operand" "")
3602 (match_operand:SI 4 "const_int_operand" ""))
3603 (match_operator:SI 9 "logical_binary_operator"
3604 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3605 (match_operand:SI 6 "const_int_operand" ""))
3606 (match_operand:SI 7 "s_register_operand" "")])]))
3607 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3609 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3610 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3613 [(ashift:SI (match_dup 2) (match_dup 4))
3617 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3620 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3624 [(set (match_operand:SI 0 "s_register_operand" "")
3625 (match_operator:SI 1 "logical_binary_operator"
3626 [(match_operator:SI 9 "logical_binary_operator"
3627 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3628 (match_operand:SI 6 "const_int_operand" ""))
3629 (match_operand:SI 7 "s_register_operand" "")])
3630 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3631 (match_operand:SI 3 "const_int_operand" "")
3632 (match_operand:SI 4 "const_int_operand" ""))]))
3633 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3635 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3636 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3639 [(ashift:SI (match_dup 2) (match_dup 4))
3643 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3646 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3650 ;; Minimum and maximum insns
3652 (define_expand "smaxsi3"
3654 (set (match_operand:SI 0 "s_register_operand" "")
3655 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3656 (match_operand:SI 2 "arm_rhs_operand" "")))
3657 (clobber (reg:CC CC_REGNUM))])]
3660 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3662 /* No need for a clobber of the condition code register here. */
3663 emit_insn (gen_rtx_SET (operands[0],
3664 gen_rtx_SMAX (SImode, operands[1],
3670 (define_insn "*smax_0"
3671 [(set (match_operand:SI 0 "s_register_operand" "=r")
3672 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3675 "bic%?\\t%0, %1, %1, asr #31"
3676 [(set_attr "predicable" "yes")
3677 (set_attr "type" "logic_shift_reg")]
3680 (define_insn "*smax_m1"
3681 [(set (match_operand:SI 0 "s_register_operand" "=r")
3682 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3685 "orr%?\\t%0, %1, %1, asr #31"
3686 [(set_attr "predicable" "yes")
3687 (set_attr "type" "logic_shift_reg")]
3690 (define_insn_and_split "*arm_smax_insn"
3691 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3692 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3693 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3694 (clobber (reg:CC CC_REGNUM))]
3697 ; cmp\\t%1, %2\;movlt\\t%0, %2
3698 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3700 [(set (reg:CC CC_REGNUM)
3701 (compare:CC (match_dup 1) (match_dup 2)))
3703 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3707 [(set_attr "conds" "clob")
3708 (set_attr "length" "8,12")
3709 (set_attr "type" "multiple")]
3712 (define_expand "sminsi3"
3714 (set (match_operand:SI 0 "s_register_operand" "")
3715 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3716 (match_operand:SI 2 "arm_rhs_operand" "")))
3717 (clobber (reg:CC CC_REGNUM))])]
3720 if (operands[2] == const0_rtx)
3722 /* No need for a clobber of the condition code register here. */
3723 emit_insn (gen_rtx_SET (operands[0],
3724 gen_rtx_SMIN (SImode, operands[1],
3730 (define_insn "*smin_0"
3731 [(set (match_operand:SI 0 "s_register_operand" "=r")
3732 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3735 "and%?\\t%0, %1, %1, asr #31"
3736 [(set_attr "predicable" "yes")
3737 (set_attr "type" "logic_shift_reg")]
3740 (define_insn_and_split "*arm_smin_insn"
3741 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3742 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3743 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3744 (clobber (reg:CC CC_REGNUM))]
3747 ; cmp\\t%1, %2\;movge\\t%0, %2
3748 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3750 [(set (reg:CC CC_REGNUM)
3751 (compare:CC (match_dup 1) (match_dup 2)))
3753 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3757 [(set_attr "conds" "clob")
3758 (set_attr "length" "8,12")
3759 (set_attr "type" "multiple,multiple")]
3762 (define_expand "umaxsi3"
3764 (set (match_operand:SI 0 "s_register_operand" "")
3765 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3766 (match_operand:SI 2 "arm_rhs_operand" "")))
3767 (clobber (reg:CC CC_REGNUM))])]
3772 (define_insn_and_split "*arm_umaxsi3"
3773 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3774 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3775 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3776 (clobber (reg:CC CC_REGNUM))]
3779 ; cmp\\t%1, %2\;movcc\\t%0, %2
3780 ; cmp\\t%1, %2\;movcs\\t%0, %1
3781 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3783 [(set (reg:CC CC_REGNUM)
3784 (compare:CC (match_dup 1) (match_dup 2)))
3786 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3790 [(set_attr "conds" "clob")
3791 (set_attr "length" "8,8,12")
3792 (set_attr "type" "store_4")]
3795 (define_expand "uminsi3"
3797 (set (match_operand:SI 0 "s_register_operand" "")
3798 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3799 (match_operand:SI 2 "arm_rhs_operand" "")))
3800 (clobber (reg:CC CC_REGNUM))])]
3805 (define_insn_and_split "*arm_uminsi3"
3806 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3807 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3808 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3809 (clobber (reg:CC CC_REGNUM))]
3812 ; cmp\\t%1, %2\;movcs\\t%0, %2
3813 ; cmp\\t%1, %2\;movcc\\t%0, %1
3814 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3816 [(set (reg:CC CC_REGNUM)
3817 (compare:CC (match_dup 1) (match_dup 2)))
3819 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3823 [(set_attr "conds" "clob")
3824 (set_attr "length" "8,8,12")
3825 (set_attr "type" "store_4")]
3828 (define_insn "*store_minmaxsi"
3829 [(set (match_operand:SI 0 "memory_operand" "=m")
3830 (match_operator:SI 3 "minmax_operator"
3831 [(match_operand:SI 1 "s_register_operand" "r")
3832 (match_operand:SI 2 "s_register_operand" "r")]))
3833 (clobber (reg:CC CC_REGNUM))]
3834 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3836 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3837 operands[1], operands[2]);
3838 output_asm_insn (\"cmp\\t%1, %2\", operands);
3840 output_asm_insn (\"ite\t%d3\", operands);
3841 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3842 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3845 [(set_attr "conds" "clob")
3846 (set (attr "length")
3847 (if_then_else (eq_attr "is_thumb" "yes")
3850 (set_attr "type" "store_4")]
3853 ; Reject the frame pointer in operand[1], since reloading this after
3854 ; it has been eliminated can cause carnage.
3855 (define_insn "*minmax_arithsi"
3856 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3857 (match_operator:SI 4 "shiftable_operator"
3858 [(match_operator:SI 5 "minmax_operator"
3859 [(match_operand:SI 2 "s_register_operand" "r,r")
3860 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3861 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3862 (clobber (reg:CC CC_REGNUM))]
3863 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3866 enum rtx_code code = GET_CODE (operands[4]);
3869 if (which_alternative != 0 || operands[3] != const0_rtx
3870 || (code != PLUS && code != IOR && code != XOR))
3875 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3876 operands[2], operands[3]);
3877 output_asm_insn (\"cmp\\t%2, %3\", operands);
3881 output_asm_insn (\"ite\\t%d5\", operands);
3883 output_asm_insn (\"it\\t%d5\", operands);
3885 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3887 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3890 [(set_attr "conds" "clob")
3891 (set (attr "length")
3892 (if_then_else (eq_attr "is_thumb" "yes")
3895 (set_attr "type" "multiple")]
3898 ; Reject the frame pointer in operand[1], since reloading this after
3899 ; it has been eliminated can cause carnage.
3900 (define_insn_and_split "*minmax_arithsi_non_canon"
3901 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3903 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3904 (match_operator:SI 4 "minmax_operator"
3905 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3906 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3907 (clobber (reg:CC CC_REGNUM))]
3908 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3909 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3911 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3912 [(set (reg:CC CC_REGNUM)
3913 (compare:CC (match_dup 2) (match_dup 3)))
3915 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3917 (minus:SI (match_dup 1)
3919 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3923 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3924 operands[2], operands[3]);
3925 enum rtx_code rc = minmax_code (operands[4]);
3926 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3927 operands[2], operands[3]);
3929 if (mode == CCFPmode || mode == CCFPEmode)
3930 rc = reverse_condition_maybe_unordered (rc);
3932 rc = reverse_condition (rc);
3933 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3934 if (CONST_INT_P (operands[3]))
3935 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3937 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3939 [(set_attr "conds" "clob")
3940 (set (attr "length")
3941 (if_then_else (eq_attr "is_thumb" "yes")
3944 (set_attr "type" "multiple")]
3947 (define_code_iterator SAT [smin smax])
3948 (define_code_iterator SATrev [smin smax])
3949 (define_code_attr SATlo [(smin "1") (smax "2")])
3950 (define_code_attr SAThi [(smin "2") (smax "1")])
3952 (define_insn "*satsi_<SAT:code>"
3953 [(set (match_operand:SI 0 "s_register_operand" "=r")
3954 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3955 (match_operand:SI 1 "const_int_operand" "i"))
3956 (match_operand:SI 2 "const_int_operand" "i")))]
3957 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3958 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3962 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3963 &mask, &signed_sat))
3966 operands[1] = GEN_INT (mask);
3968 return "ssat%?\t%0, %1, %3";
3970 return "usat%?\t%0, %1, %3";
3972 [(set_attr "predicable" "yes")
3973 (set_attr "type" "alus_imm")]
3976 (define_insn "*satsi_<SAT:code>_shift"
3977 [(set (match_operand:SI 0 "s_register_operand" "=r")
3978 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3979 [(match_operand:SI 4 "s_register_operand" "r")
3980 (match_operand:SI 5 "const_int_operand" "i")])
3981 (match_operand:SI 1 "const_int_operand" "i"))
3982 (match_operand:SI 2 "const_int_operand" "i")))]
3983 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3984 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3988 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3989 &mask, &signed_sat))
3992 operands[1] = GEN_INT (mask);
3994 return "ssat%?\t%0, %1, %4%S3";
3996 return "usat%?\t%0, %1, %4%S3";
3998 [(set_attr "predicable" "yes")
3999 (set_attr "shift" "3")
4000 (set_attr "type" "logic_shift_reg")])
4002 ;; Shift and rotation insns
4004 (define_expand "ashldi3"
4005 [(set (match_operand:DI 0 "s_register_operand" "")
4006 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
4007 (match_operand:SI 2 "general_operand" "")))]
4012 /* Delay the decision whether to use NEON or core-regs until
4013 register allocation. */
4014 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4019 /* Only the NEON case can handle in-memory shift counts. */
4020 if (!reg_or_int_operand (operands[2], SImode))
4021 operands[2] = force_reg (SImode, operands[2]);
4024 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4025 ; /* No special preparation statements; expand pattern as above. */
4028 rtx scratch1, scratch2;
4030 /* Ideally we should use iwmmxt here if we could know that operands[1]
4031 ends up already living in an iwmmxt register. Otherwise it's
4032 cheaper to have the alternate code being generated than moving
4033 values to iwmmxt regs and back. */
4035 /* Expand operation using core-registers.
4036 'FAIL' would achieve the same thing, but this is a bit smarter. */
4037 scratch1 = gen_reg_rtx (SImode);
4038 scratch2 = gen_reg_rtx (SImode);
4039 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4040 operands[2], scratch1, scratch2);
4046 (define_expand "ashlsi3"
4047 [(set (match_operand:SI 0 "s_register_operand" "")
4048 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4049 (match_operand:SI 2 "arm_rhs_operand" "")))]
4052 if (CONST_INT_P (operands[2])
4053 && (UINTVAL (operands[2])) > 31)
4055 emit_insn (gen_movsi (operands[0], const0_rtx));
4061 (define_expand "ashrdi3"
4062 [(set (match_operand:DI 0 "s_register_operand" "")
4063 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4064 (match_operand:SI 2 "reg_or_int_operand" "")))]
4069 /* Delay the decision whether to use NEON or core-regs until
4070 register allocation. */
4071 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4075 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4076 ; /* No special preparation statements; expand pattern as above. */
4079 rtx scratch1, scratch2;
4081 /* Ideally we should use iwmmxt here if we could know that operands[1]
4082 ends up already living in an iwmmxt register. Otherwise it's
4083 cheaper to have the alternate code being generated than moving
4084 values to iwmmxt regs and back. */
4086 /* Expand operation using core-registers.
4087 'FAIL' would achieve the same thing, but this is a bit smarter. */
4088 scratch1 = gen_reg_rtx (SImode);
4089 scratch2 = gen_reg_rtx (SImode);
4090 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4091 operands[2], scratch1, scratch2);
4097 (define_expand "ashrsi3"
4098 [(set (match_operand:SI 0 "s_register_operand" "")
4099 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4100 (match_operand:SI 2 "arm_rhs_operand" "")))]
4103 if (CONST_INT_P (operands[2])
4104 && UINTVAL (operands[2]) > 31)
4105 operands[2] = GEN_INT (31);
4109 (define_expand "lshrdi3"
4110 [(set (match_operand:DI 0 "s_register_operand" "")
4111 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4112 (match_operand:SI 2 "reg_or_int_operand" "")))]
4117 /* Delay the decision whether to use NEON or core-regs until
4118 register allocation. */
4119 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4123 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4124 ; /* No special preparation statements; expand pattern as above. */
4127 rtx scratch1, scratch2;
4129 /* Ideally we should use iwmmxt here if we could know that operands[1]
4130 ends up already living in an iwmmxt register. Otherwise it's
4131 cheaper to have the alternate code being generated than moving
4132 values to iwmmxt regs and back. */
4134 /* Expand operation using core-registers.
4135 'FAIL' would achieve the same thing, but this is a bit smarter. */
4136 scratch1 = gen_reg_rtx (SImode);
4137 scratch2 = gen_reg_rtx (SImode);
4138 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4139 operands[2], scratch1, scratch2);
4145 (define_expand "lshrsi3"
4146 [(set (match_operand:SI 0 "s_register_operand" "")
4147 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4148 (match_operand:SI 2 "arm_rhs_operand" "")))]
4151 if (CONST_INT_P (operands[2])
4152 && (UINTVAL (operands[2])) > 31)
4154 emit_insn (gen_movsi (operands[0], const0_rtx));
4160 (define_expand "rotlsi3"
4161 [(set (match_operand:SI 0 "s_register_operand" "")
4162 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4163 (match_operand:SI 2 "reg_or_int_operand" "")))]
4166 if (CONST_INT_P (operands[2]))
4167 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4170 rtx reg = gen_reg_rtx (SImode);
4171 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4177 (define_expand "rotrsi3"
4178 [(set (match_operand:SI 0 "s_register_operand" "")
4179 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4180 (match_operand:SI 2 "arm_rhs_operand" "")))]
4185 if (CONST_INT_P (operands[2])
4186 && UINTVAL (operands[2]) > 31)
4187 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4189 else /* TARGET_THUMB1 */
4191 if (CONST_INT_P (operands [2]))
4192 operands [2] = force_reg (SImode, operands[2]);
4197 (define_insn "*arm_shiftsi3"
4198 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4199 (match_operator:SI 3 "shift_operator"
4200 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4201 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4203 "* return arm_output_shift(operands, 0);"
4204 [(set_attr "predicable" "yes")
4205 (set_attr "arch" "t2,t2,*,*")
4206 (set_attr "predicable_short_it" "yes,yes,no,no")
4207 (set_attr "length" "4")
4208 (set_attr "shift" "1")
4209 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4212 (define_insn "*shiftsi3_compare0"
4213 [(set (reg:CC_NOOV CC_REGNUM)
4214 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4215 [(match_operand:SI 1 "s_register_operand" "r,r")
4216 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4218 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4219 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4221 "* return arm_output_shift(operands, 1);"
4222 [(set_attr "conds" "set")
4223 (set_attr "shift" "1")
4224 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4227 (define_insn "*shiftsi3_compare0_scratch"
4228 [(set (reg:CC_NOOV CC_REGNUM)
4229 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4230 [(match_operand:SI 1 "s_register_operand" "r,r")
4231 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4233 (clobber (match_scratch:SI 0 "=r,r"))]
4235 "* return arm_output_shift(operands, 1);"
4236 [(set_attr "conds" "set")
4237 (set_attr "shift" "1")
4238 (set_attr "type" "shift_imm,shift_reg")]
4241 (define_insn "*not_shiftsi"
4242 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4243 (not:SI (match_operator:SI 3 "shift_operator"
4244 [(match_operand:SI 1 "s_register_operand" "r,r")
4245 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4248 [(set_attr "predicable" "yes")
4249 (set_attr "shift" "1")
4250 (set_attr "arch" "32,a")
4251 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4253 (define_insn "*not_shiftsi_compare0"
4254 [(set (reg:CC_NOOV CC_REGNUM)
4256 (not:SI (match_operator:SI 3 "shift_operator"
4257 [(match_operand:SI 1 "s_register_operand" "r,r")
4258 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4260 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4261 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4263 "mvns%?\\t%0, %1%S3"
4264 [(set_attr "conds" "set")
4265 (set_attr "shift" "1")
4266 (set_attr "arch" "32,a")
4267 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4269 (define_insn "*not_shiftsi_compare0_scratch"
4270 [(set (reg:CC_NOOV CC_REGNUM)
4272 (not:SI (match_operator:SI 3 "shift_operator"
4273 [(match_operand:SI 1 "s_register_operand" "r,r")
4274 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4276 (clobber (match_scratch:SI 0 "=r,r"))]
4278 "mvns%?\\t%0, %1%S3"
4279 [(set_attr "conds" "set")
4280 (set_attr "shift" "1")
4281 (set_attr "arch" "32,a")
4282 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4284 ;; We don't really have extzv, but defining this using shifts helps
4285 ;; to reduce register pressure later on.
4287 (define_expand "extzv"
4288 [(set (match_operand 0 "s_register_operand" "")
4289 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4290 (match_operand 2 "const_int_operand" "")
4291 (match_operand 3 "const_int_operand" "")))]
4292 "TARGET_THUMB1 || arm_arch_thumb2"
4295 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4296 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4298 if (arm_arch_thumb2)
4300 HOST_WIDE_INT width = INTVAL (operands[2]);
4301 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4303 if (unaligned_access && MEM_P (operands[1])
4304 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4308 if (BYTES_BIG_ENDIAN)
4309 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4314 base_addr = adjust_address (operands[1], SImode,
4315 bitpos / BITS_PER_UNIT);
4316 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4320 rtx dest = operands[0];
4321 rtx tmp = gen_reg_rtx (SImode);
4323 /* We may get a paradoxical subreg here. Strip it off. */
4324 if (GET_CODE (dest) == SUBREG
4325 && GET_MODE (dest) == SImode
4326 && GET_MODE (SUBREG_REG (dest)) == HImode)
4327 dest = SUBREG_REG (dest);
4329 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4332 base_addr = adjust_address (operands[1], HImode,
4333 bitpos / BITS_PER_UNIT);
4334 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4335 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4339 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4341 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4349 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4352 operands[3] = GEN_INT (rshift);
4356 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4360 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4361 operands[3], gen_reg_rtx (SImode)));
4366 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4368 (define_expand "extzv_t1"
4369 [(set (match_operand:SI 4 "s_register_operand" "")
4370 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4371 (match_operand:SI 2 "const_int_operand" "")))
4372 (set (match_operand:SI 0 "s_register_operand" "")
4373 (lshiftrt:SI (match_dup 4)
4374 (match_operand:SI 3 "const_int_operand" "")))]
4378 (define_expand "extv"
4379 [(set (match_operand 0 "s_register_operand" "")
4380 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4381 (match_operand 2 "const_int_operand" "")
4382 (match_operand 3 "const_int_operand" "")))]
4385 HOST_WIDE_INT width = INTVAL (operands[2]);
4386 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4388 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4389 && (bitpos % BITS_PER_UNIT) == 0)
4393 if (BYTES_BIG_ENDIAN)
4394 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4398 base_addr = adjust_address (operands[1], SImode,
4399 bitpos / BITS_PER_UNIT);
4400 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4404 rtx dest = operands[0];
4405 rtx tmp = gen_reg_rtx (SImode);
4407 /* We may get a paradoxical subreg here. Strip it off. */
4408 if (GET_CODE (dest) == SUBREG
4409 && GET_MODE (dest) == SImode
4410 && GET_MODE (SUBREG_REG (dest)) == HImode)
4411 dest = SUBREG_REG (dest);
4413 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4416 base_addr = adjust_address (operands[1], HImode,
4417 bitpos / BITS_PER_UNIT);
4418 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4419 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4424 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4426 else if (GET_MODE (operands[0]) == SImode
4427 && GET_MODE (operands[1]) == SImode)
4429 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4437 ; Helper to expand register forms of extv with the proper modes.
4439 (define_expand "extv_regsi"
4440 [(set (match_operand:SI 0 "s_register_operand" "")
4441 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4442 (match_operand 2 "const_int_operand" "")
4443 (match_operand 3 "const_int_operand" "")))]
4448 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4450 (define_insn "unaligned_loadsi"
4451 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4452 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4453 UNSPEC_UNALIGNED_LOAD))]
4455 "ldr%?\t%0, %1\t@ unaligned"
4456 [(set_attr "arch" "t2,any")
4457 (set_attr "length" "2,4")
4458 (set_attr "predicable" "yes")
4459 (set_attr "predicable_short_it" "yes,no")
4460 (set_attr "type" "load_4")])
4462 (define_insn "unaligned_loadhis"
4463 [(set (match_operand:SI 0 "s_register_operand" "=r")
4465 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
4466 UNSPEC_UNALIGNED_LOAD)))]
4468 "ldrsh%?\t%0, %1\t@ unaligned"
4469 [(set_attr "predicable" "yes")
4470 (set_attr "type" "load_byte")])
4472 (define_insn "unaligned_loadhiu"
4473 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4475 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4476 UNSPEC_UNALIGNED_LOAD)))]
4478 "ldrh%?\t%0, %1\t@ unaligned"
4479 [(set_attr "arch" "t2,any")
4480 (set_attr "length" "2,4")
4481 (set_attr "predicable" "yes")
4482 (set_attr "predicable_short_it" "yes,no")
4483 (set_attr "type" "load_byte")])
4485 (define_insn "unaligned_storesi"
4486 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4487 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4488 UNSPEC_UNALIGNED_STORE))]
4490 "str%?\t%1, %0\t@ unaligned"
4491 [(set_attr "arch" "t2,any")
4492 (set_attr "length" "2,4")
4493 (set_attr "predicable" "yes")
4494 (set_attr "predicable_short_it" "yes,no")
4495 (set_attr "type" "store_4")])
4497 (define_insn "unaligned_storehi"
4498 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4499 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4500 UNSPEC_UNALIGNED_STORE))]
4502 "strh%?\t%1, %0\t@ unaligned"
4503 [(set_attr "arch" "t2,any")
4504 (set_attr "length" "2,4")
4505 (set_attr "predicable" "yes")
4506 (set_attr "predicable_short_it" "yes,no")
4507 (set_attr "type" "store_4")])
4510 (define_insn "*extv_reg"
4511 [(set (match_operand:SI 0 "s_register_operand" "=r")
4512 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4513 (match_operand:SI 2 "const_int_operand" "n")
4514 (match_operand:SI 3 "const_int_operand" "n")))]
4516 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4517 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4518 "sbfx%?\t%0, %1, %3, %2"
4519 [(set_attr "length" "4")
4520 (set_attr "predicable" "yes")
4521 (set_attr "type" "bfm")]
4524 (define_insn "extzv_t2"
4525 [(set (match_operand:SI 0 "s_register_operand" "=r")
4526 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4527 (match_operand:SI 2 "const_int_operand" "n")
4528 (match_operand:SI 3 "const_int_operand" "n")))]
4530 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4531 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4532 "ubfx%?\t%0, %1, %3, %2"
4533 [(set_attr "length" "4")
4534 (set_attr "predicable" "yes")
4535 (set_attr "type" "bfm")]
4539 ;; Division instructions
4540 (define_insn "divsi3"
4541 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4542 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4543 (match_operand:SI 2 "s_register_operand" "r,r")))]
4548 [(set_attr "arch" "32,v8mb")
4549 (set_attr "predicable" "yes")
4550 (set_attr "type" "sdiv")]
4553 (define_insn "udivsi3"
4554 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4555 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4556 (match_operand:SI 2 "s_register_operand" "r,r")))]
4561 [(set_attr "arch" "32,v8mb")
4562 (set_attr "predicable" "yes")
4563 (set_attr "type" "udiv")]
4567 ;; Unary arithmetic insns
4569 (define_expand "negvsi3"
4570 [(match_operand:SI 0 "register_operand")
4571 (match_operand:SI 1 "register_operand")
4572 (match_operand 2 "")]
4575 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4576 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4581 (define_expand "negvdi3"
4582 [(match_operand:DI 0 "register_operand")
4583 (match_operand:DI 1 "register_operand")
4584 (match_operand 2 "")]
4587 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4588 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4594 (define_insn_and_split "negdi2_compare"
4595 [(set (reg:CC CC_REGNUM)
4598 (match_operand:DI 1 "register_operand" "0,r")))
4599 (set (match_operand:DI 0 "register_operand" "=r,&r")
4600 (minus:DI (const_int 0) (match_dup 1)))]
4603 "&& reload_completed"
4604 [(parallel [(set (reg:CC CC_REGNUM)
4605 (compare:CC (const_int 0) (match_dup 1)))
4606 (set (match_dup 0) (minus:SI (const_int 0)
4608 (parallel [(set (reg:CC CC_REGNUM)
4609 (compare:CC (const_int 0) (match_dup 3)))
4612 (minus:SI (const_int 0) (match_dup 3))
4613 (ltu:SI (reg:CC_C CC_REGNUM)
4616 operands[2] = gen_highpart (SImode, operands[0]);
4617 operands[0] = gen_lowpart (SImode, operands[0]);
4618 operands[3] = gen_highpart (SImode, operands[1]);
4619 operands[1] = gen_lowpart (SImode, operands[1]);
4621 [(set_attr "conds" "set")
4622 (set_attr "length" "8")
4623 (set_attr "type" "multiple")]
4626 (define_expand "negdi2"
4628 [(set (match_operand:DI 0 "s_register_operand" "")
4629 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4630 (clobber (reg:CC CC_REGNUM))])]
4635 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4641 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4642 ;; The first alternative allows the common case of a *full* overlap.
4643 (define_insn_and_split "*negdi2_insn"
4644 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4645 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4646 (clobber (reg:CC CC_REGNUM))]
4648 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4649 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4650 "&& reload_completed"
4651 [(parallel [(set (reg:CC CC_REGNUM)
4652 (compare:CC (const_int 0) (match_dup 1)))
4653 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4654 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4655 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4657 operands[2] = gen_highpart (SImode, operands[0]);
4658 operands[0] = gen_lowpart (SImode, operands[0]);
4659 operands[3] = gen_highpart (SImode, operands[1]);
4660 operands[1] = gen_lowpart (SImode, operands[1]);
4662 [(set_attr "conds" "clob")
4663 (set_attr "length" "8")
4664 (set_attr "type" "multiple")]
4667 (define_insn "*negsi2_carryin_compare"
4668 [(set (reg:CC CC_REGNUM)
4669 (compare:CC (const_int 0)
4670 (match_operand:SI 1 "s_register_operand" "r")))
4671 (set (match_operand:SI 0 "s_register_operand" "=r")
4672 (minus:SI (minus:SI (const_int 0)
4674 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4677 [(set_attr "conds" "set")
4678 (set_attr "type" "alus_imm")]
4681 (define_expand "negsi2"
4682 [(set (match_operand:SI 0 "s_register_operand" "")
4683 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4688 (define_insn "*arm_negsi2"
4689 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4690 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4692 "rsb%?\\t%0, %1, #0"
4693 [(set_attr "predicable" "yes")
4694 (set_attr "predicable_short_it" "yes,no")
4695 (set_attr "arch" "t2,*")
4696 (set_attr "length" "4")
4697 (set_attr "type" "alu_sreg")]
4700 (define_expand "negsf2"
4701 [(set (match_operand:SF 0 "s_register_operand" "")
4702 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4703 "TARGET_32BIT && TARGET_HARD_FLOAT"
4707 (define_expand "negdf2"
4708 [(set (match_operand:DF 0 "s_register_operand" "")
4709 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4710 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4713 (define_insn_and_split "*zextendsidi_negsi"
4714 [(set (match_operand:DI 0 "s_register_operand" "=r")
4715 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4720 (neg:SI (match_dup 1)))
4724 operands[2] = gen_lowpart (SImode, operands[0]);
4725 operands[3] = gen_highpart (SImode, operands[0]);
4727 [(set_attr "length" "8")
4728 (set_attr "type" "multiple")]
4731 ;; Negate an extended 32-bit value.
4732 (define_insn_and_split "*negdi_extendsidi"
4733 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4734 (neg:DI (sign_extend:DI
4735 (match_operand:SI 1 "s_register_operand" "l,r"))))
4736 (clobber (reg:CC CC_REGNUM))]
4739 "&& reload_completed"
4742 rtx low = gen_lowpart (SImode, operands[0]);
4743 rtx high = gen_highpart (SImode, operands[0]);
4745 if (reg_overlap_mentioned_p (low, operands[1]))
4747 /* Input overlaps the low word of the output. Use:
4750 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4751 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4753 emit_insn (gen_rtx_SET (high,
4754 gen_rtx_ASHIFTRT (SImode, operands[1],
4757 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4759 emit_insn (gen_rtx_SET (high,
4760 gen_rtx_MINUS (SImode,
4761 gen_rtx_MINUS (SImode,
4764 gen_rtx_LTU (SImode,
4769 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4770 emit_insn (gen_rtx_SET (high,
4771 gen_rtx_MINUS (SImode,
4772 gen_rtx_MINUS (SImode,
4775 gen_rtx_LTU (SImode,
4782 /* No overlap, or overlap on high word. Use:
4786 Flags not needed for this sequence. */
4787 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4788 emit_insn (gen_rtx_SET (high,
4789 gen_rtx_AND (SImode,
4790 gen_rtx_NOT (SImode, operands[1]),
4792 emit_insn (gen_rtx_SET (high,
4793 gen_rtx_ASHIFTRT (SImode, high,
4798 [(set_attr "length" "12")
4799 (set_attr "arch" "t2,*")
4800 (set_attr "type" "multiple")]
4803 (define_insn_and_split "*negdi_zero_extendsidi"
4804 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4805 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4806 (clobber (reg:CC CC_REGNUM))]
4808 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4809 ;; Don't care what register is input to sbc,
4810 ;; since we just need to propagate the carry.
4811 "&& reload_completed"
4812 [(parallel [(set (reg:CC CC_REGNUM)
4813 (compare:CC (const_int 0) (match_dup 1)))
4814 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4815 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4816 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4818 operands[2] = gen_highpart (SImode, operands[0]);
4819 operands[0] = gen_lowpart (SImode, operands[0]);
4821 [(set_attr "conds" "clob")
4822 (set_attr "length" "8")
4823 (set_attr "type" "multiple")] ;; length in thumb is 4
4826 ;; abssi2 doesn't really clobber the condition codes if a different register
4827 ;; is being set. To keep things simple, assume during rtl manipulations that
4828 ;; it does, but tell the final scan operator the truth. Similarly for
4831 (define_expand "abssi2"
4833 [(set (match_operand:SI 0 "s_register_operand" "")
4834 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4835 (clobber (match_dup 2))])]
4839 operands[2] = gen_rtx_SCRATCH (SImode);
4841 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4844 (define_insn_and_split "*arm_abssi2"
4845 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4846 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4847 (clobber (reg:CC CC_REGNUM))]
4850 "&& reload_completed"
4853 /* if (which_alternative == 0) */
4854 if (REGNO(operands[0]) == REGNO(operands[1]))
4856 /* Emit the pattern:
4857 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4858 [(set (reg:CC CC_REGNUM)
4859 (compare:CC (match_dup 0) (const_int 0)))
4860 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4861 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4863 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4864 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4865 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4866 (gen_rtx_LT (SImode,
4867 gen_rtx_REG (CCmode, CC_REGNUM),
4869 (gen_rtx_SET (operands[0],
4870 (gen_rtx_MINUS (SImode,
4877 /* Emit the pattern:
4878 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4880 (xor:SI (match_dup 1)
4881 (ashiftrt:SI (match_dup 1) (const_int 31))))
4883 (minus:SI (match_dup 0)
4884 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4886 emit_insn (gen_rtx_SET (operands[0],
4887 gen_rtx_XOR (SImode,
4888 gen_rtx_ASHIFTRT (SImode,
4892 emit_insn (gen_rtx_SET (operands[0],
4893 gen_rtx_MINUS (SImode,
4895 gen_rtx_ASHIFTRT (SImode,
4901 [(set_attr "conds" "clob,*")
4902 (set_attr "shift" "1")
4903 (set_attr "predicable" "no, yes")
4904 (set_attr "length" "8")
4905 (set_attr "type" "multiple")]
4908 (define_insn_and_split "*arm_neg_abssi2"
4909 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4910 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4911 (clobber (reg:CC CC_REGNUM))]
4914 "&& reload_completed"
4917 /* if (which_alternative == 0) */
4918 if (REGNO (operands[0]) == REGNO (operands[1]))
4920 /* Emit the pattern:
4921 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4923 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4924 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4925 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4927 gen_rtx_REG (CCmode, CC_REGNUM),
4929 gen_rtx_SET (operands[0],
4930 (gen_rtx_MINUS (SImode,
4936 /* Emit the pattern:
4937 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4939 emit_insn (gen_rtx_SET (operands[0],
4940 gen_rtx_XOR (SImode,
4941 gen_rtx_ASHIFTRT (SImode,
4945 emit_insn (gen_rtx_SET (operands[0],
4946 gen_rtx_MINUS (SImode,
4947 gen_rtx_ASHIFTRT (SImode,
4954 [(set_attr "conds" "clob,*")
4955 (set_attr "shift" "1")
4956 (set_attr "predicable" "no, yes")
4957 (set_attr "length" "8")
4958 (set_attr "type" "multiple")]
4961 (define_expand "abssf2"
4962 [(set (match_operand:SF 0 "s_register_operand" "")
4963 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4964 "TARGET_32BIT && TARGET_HARD_FLOAT"
4967 (define_expand "absdf2"
4968 [(set (match_operand:DF 0 "s_register_operand" "")
4969 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4970 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4973 (define_expand "sqrtsf2"
4974 [(set (match_operand:SF 0 "s_register_operand" "")
4975 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4976 "TARGET_32BIT && TARGET_HARD_FLOAT"
4979 (define_expand "sqrtdf2"
4980 [(set (match_operand:DF 0 "s_register_operand" "")
4981 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4982 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4985 (define_expand "one_cmpldi2"
4986 [(set (match_operand:DI 0 "s_register_operand" "")
4987 (not:DI (match_operand:DI 1 "s_register_operand" "")))]
4990 if (!TARGET_NEON && !TARGET_IWMMXT)
4992 rtx low = simplify_gen_unary (NOT, SImode,
4993 gen_lowpart (SImode, operands[1]),
4995 rtx high = simplify_gen_unary (NOT, SImode,
4996 gen_highpart_mode (SImode, DImode,
5000 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5001 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5005 /* Otherwise expand pattern as above. */
5009 (define_insn_and_split "*one_cmpldi2_insn"
5010 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5011 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5018 "TARGET_32BIT && reload_completed
5019 && arm_general_register_operand (operands[0], DImode)"
5020 [(set (match_dup 0) (not:SI (match_dup 1)))
5021 (set (match_dup 2) (not:SI (match_dup 3)))]
5024 operands[2] = gen_highpart (SImode, operands[0]);
5025 operands[0] = gen_lowpart (SImode, operands[0]);
5026 operands[3] = gen_highpart (SImode, operands[1]);
5027 operands[1] = gen_lowpart (SImode, operands[1]);
5029 [(set_attr "length" "*,8,8,*")
5030 (set_attr "predicable" "no,yes,yes,no")
5031 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5032 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5035 (define_expand "one_cmplsi2"
5036 [(set (match_operand:SI 0 "s_register_operand" "")
5037 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5042 (define_insn "*arm_one_cmplsi2"
5043 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5044 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5047 [(set_attr "predicable" "yes")
5048 (set_attr "predicable_short_it" "yes,no")
5049 (set_attr "arch" "t2,*")
5050 (set_attr "length" "4")
5051 (set_attr "type" "mvn_reg")]
5054 (define_insn "*notsi_compare0"
5055 [(set (reg:CC_NOOV CC_REGNUM)
5056 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5058 (set (match_operand:SI 0 "s_register_operand" "=r")
5059 (not:SI (match_dup 1)))]
5062 [(set_attr "conds" "set")
5063 (set_attr "type" "mvn_reg")]
5066 (define_insn "*notsi_compare0_scratch"
5067 [(set (reg:CC_NOOV CC_REGNUM)
5068 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5070 (clobber (match_scratch:SI 0 "=r"))]
5073 [(set_attr "conds" "set")
5074 (set_attr "type" "mvn_reg")]
5077 ;; Fixed <--> Floating conversion insns
5079 (define_expand "floatsihf2"
5080 [(set (match_operand:HF 0 "general_operand" "")
5081 (float:HF (match_operand:SI 1 "general_operand" "")))]
5085 rtx op1 = gen_reg_rtx (SFmode);
5086 expand_float (op1, operands[1], 0);
5087 op1 = convert_to_mode (HFmode, op1, 0);
5088 emit_move_insn (operands[0], op1);
5093 (define_expand "floatdihf2"
5094 [(set (match_operand:HF 0 "general_operand" "")
5095 (float:HF (match_operand:DI 1 "general_operand" "")))]
5099 rtx op1 = gen_reg_rtx (SFmode);
5100 expand_float (op1, operands[1], 0);
5101 op1 = convert_to_mode (HFmode, op1, 0);
5102 emit_move_insn (operands[0], op1);
5107 (define_expand "floatsisf2"
5108 [(set (match_operand:SF 0 "s_register_operand" "")
5109 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5110 "TARGET_32BIT && TARGET_HARD_FLOAT"
5114 (define_expand "floatsidf2"
5115 [(set (match_operand:DF 0 "s_register_operand" "")
5116 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5117 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5121 (define_expand "fix_trunchfsi2"
5122 [(set (match_operand:SI 0 "general_operand" "")
5123 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5127 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5128 expand_fix (operands[0], op1, 0);
5133 (define_expand "fix_trunchfdi2"
5134 [(set (match_operand:DI 0 "general_operand" "")
5135 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5139 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5140 expand_fix (operands[0], op1, 0);
5145 (define_expand "fix_truncsfsi2"
5146 [(set (match_operand:SI 0 "s_register_operand" "")
5147 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5148 "TARGET_32BIT && TARGET_HARD_FLOAT"
5152 (define_expand "fix_truncdfsi2"
5153 [(set (match_operand:SI 0 "s_register_operand" "")
5154 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5155 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5161 (define_expand "truncdfsf2"
5162 [(set (match_operand:SF 0 "s_register_operand" "")
5164 (match_operand:DF 1 "s_register_operand" "")))]
5165 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5169 ;; DFmode to HFmode conversions on targets without a single-step hardware
5170 ;; instruction for it would have to go through SFmode. This is dangerous
5171 ;; as it introduces double rounding.
5173 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5174 ;; a single-step instruction.
5176 (define_expand "truncdfhf2"
5177 [(set (match_operand:HF 0 "s_register_operand" "")
5179 (match_operand:DF 1 "s_register_operand" "")))]
5180 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5181 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5183 /* We don't have a direct instruction for this, so we must be in
5184 an unsafe math mode, and going via SFmode. */
5186 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5189 op1 = convert_to_mode (SFmode, operands[1], 0);
5190 op1 = convert_to_mode (HFmode, op1, 0);
5191 emit_move_insn (operands[0], op1);
5194 /* Otherwise, we will pick this up as a single instruction with
5195 no intermediary rounding. */
5199 ;; Zero and sign extension instructions.
5201 (define_insn "zero_extend<mode>di2"
5202 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5203 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5204 "<qhs_zextenddi_cstr>")))]
5205 "TARGET_32BIT <qhs_zextenddi_cond>"
5207 [(set_attr "length" "8,4,8,8")
5208 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5209 (set_attr "ce_count" "2")
5210 (set_attr "predicable" "yes")
5211 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5214 (define_insn "extend<mode>di2"
5215 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5216 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5217 "<qhs_extenddi_cstr>")))]
5218 "TARGET_32BIT <qhs_sextenddi_cond>"
5220 [(set_attr "length" "8,4,8,8,8")
5221 (set_attr "ce_count" "2")
5222 (set_attr "shift" "1")
5223 (set_attr "predicable" "yes")
5224 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5225 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5228 ;; Splits for all extensions to DImode
5230 [(set (match_operand:DI 0 "s_register_operand" "")
5231 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5232 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5233 [(set (match_dup 0) (match_dup 1))]
5235 rtx lo_part = gen_lowpart (SImode, operands[0]);
5236 machine_mode src_mode = GET_MODE (operands[1]);
5238 if (REG_P (operands[0])
5239 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5240 emit_clobber (operands[0]);
5241 if (!REG_P (lo_part) || src_mode != SImode
5242 || !rtx_equal_p (lo_part, operands[1]))
5244 if (src_mode == SImode)
5245 emit_move_insn (lo_part, operands[1]);
5247 emit_insn (gen_rtx_SET (lo_part,
5248 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5249 operands[1] = lo_part;
5251 operands[0] = gen_highpart (SImode, operands[0]);
5252 operands[1] = const0_rtx;
5256 [(set (match_operand:DI 0 "s_register_operand" "")
5257 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5258 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5259 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5261 rtx lo_part = gen_lowpart (SImode, operands[0]);
5262 machine_mode src_mode = GET_MODE (operands[1]);
5264 if (REG_P (operands[0])
5265 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5266 emit_clobber (operands[0]);
5268 if (!REG_P (lo_part) || src_mode != SImode
5269 || !rtx_equal_p (lo_part, operands[1]))
5271 if (src_mode == SImode)
5272 emit_move_insn (lo_part, operands[1]);
5274 emit_insn (gen_rtx_SET (lo_part,
5275 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5276 operands[1] = lo_part;
5278 operands[0] = gen_highpart (SImode, operands[0]);
5281 (define_expand "zero_extendhisi2"
5282 [(set (match_operand:SI 0 "s_register_operand" "")
5283 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5286 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5288 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5291 if (!arm_arch6 && !MEM_P (operands[1]))
5293 rtx t = gen_lowpart (SImode, operands[1]);
5294 rtx tmp = gen_reg_rtx (SImode);
5295 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5296 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5302 [(set (match_operand:SI 0 "s_register_operand" "")
5303 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5304 "!TARGET_THUMB2 && !arm_arch6"
5305 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5306 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5308 operands[2] = gen_lowpart (SImode, operands[1]);
5311 (define_insn "*arm_zero_extendhisi2"
5312 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5313 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5314 "TARGET_ARM && arm_arch4 && !arm_arch6"
5318 [(set_attr "type" "alu_shift_reg,load_byte")
5319 (set_attr "predicable" "yes")]
5322 (define_insn "*arm_zero_extendhisi2_v6"
5323 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5324 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5325 "TARGET_ARM && arm_arch6"
5329 [(set_attr "predicable" "yes")
5330 (set_attr "type" "extend,load_byte")]
5333 (define_insn "*arm_zero_extendhisi2addsi"
5334 [(set (match_operand:SI 0 "s_register_operand" "=r")
5335 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5336 (match_operand:SI 2 "s_register_operand" "r")))]
5338 "uxtah%?\\t%0, %2, %1"
5339 [(set_attr "type" "alu_shift_reg")
5340 (set_attr "predicable" "yes")]
5343 (define_expand "zero_extendqisi2"
5344 [(set (match_operand:SI 0 "s_register_operand" "")
5345 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5348 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5350 emit_insn (gen_andsi3 (operands[0],
5351 gen_lowpart (SImode, operands[1]),
5355 if (!arm_arch6 && !MEM_P (operands[1]))
5357 rtx t = gen_lowpart (SImode, operands[1]);
5358 rtx tmp = gen_reg_rtx (SImode);
5359 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5360 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5366 [(set (match_operand:SI 0 "s_register_operand" "")
5367 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5369 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5370 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5372 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5375 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5380 (define_insn "*arm_zero_extendqisi2"
5381 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5382 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5383 "TARGET_ARM && !arm_arch6"
5386 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5387 [(set_attr "length" "8,4")
5388 (set_attr "type" "alu_shift_reg,load_byte")
5389 (set_attr "predicable" "yes")]
5392 (define_insn "*arm_zero_extendqisi2_v6"
5393 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5394 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5395 "TARGET_ARM && arm_arch6"
5398 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5399 [(set_attr "type" "extend,load_byte")
5400 (set_attr "predicable" "yes")]
5403 (define_insn "*arm_zero_extendqisi2addsi"
5404 [(set (match_operand:SI 0 "s_register_operand" "=r")
5405 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5406 (match_operand:SI 2 "s_register_operand" "r")))]
5408 "uxtab%?\\t%0, %2, %1"
5409 [(set_attr "predicable" "yes")
5410 (set_attr "type" "alu_shift_reg")]
5414 [(set (match_operand:SI 0 "s_register_operand" "")
5415 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5416 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5417 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5418 [(set (match_dup 2) (match_dup 1))
5419 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5424 [(set (match_operand:SI 0 "s_register_operand" "")
5425 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5426 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5427 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5428 [(set (match_dup 2) (match_dup 1))
5429 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5435 [(set (match_operand:SI 0 "s_register_operand" "")
5436 (IOR_XOR:SI (and:SI (ashift:SI
5437 (match_operand:SI 1 "s_register_operand" "")
5438 (match_operand:SI 2 "const_int_operand" ""))
5439 (match_operand:SI 3 "const_int_operand" ""))
5441 (match_operator 5 "subreg_lowpart_operator"
5442 [(match_operand:SI 4 "s_register_operand" "")]))))]
5444 && (UINTVAL (operands[3])
5445 == (GET_MODE_MASK (GET_MODE (operands[5]))
5446 & (GET_MODE_MASK (GET_MODE (operands[5]))
5447 << (INTVAL (operands[2])))))"
5448 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5450 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5451 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5454 (define_insn "*compareqi_eq0"
5455 [(set (reg:CC_Z CC_REGNUM)
5456 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5460 [(set_attr "conds" "set")
5461 (set_attr "predicable" "yes")
5462 (set_attr "type" "logic_imm")]
5465 (define_expand "extendhisi2"
5466 [(set (match_operand:SI 0 "s_register_operand" "")
5467 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5472 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5475 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5477 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5481 if (!arm_arch6 && !MEM_P (operands[1]))
5483 rtx t = gen_lowpart (SImode, operands[1]);
5484 rtx tmp = gen_reg_rtx (SImode);
5485 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5486 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5493 [(set (match_operand:SI 0 "register_operand" "")
5494 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5495 (clobber (match_scratch:SI 2 ""))])]
5497 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5498 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5500 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5503 ;; This pattern will only be used when ldsh is not available
5504 (define_expand "extendhisi2_mem"
5505 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5507 (zero_extend:SI (match_dup 7)))
5508 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5509 (set (match_operand:SI 0 "" "")
5510 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5515 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5517 mem1 = change_address (operands[1], QImode, addr);
5518 mem2 = change_address (operands[1], QImode,
5519 plus_constant (Pmode, addr, 1));
5520 operands[0] = gen_lowpart (SImode, operands[0]);
5522 operands[2] = gen_reg_rtx (SImode);
5523 operands[3] = gen_reg_rtx (SImode);
5524 operands[6] = gen_reg_rtx (SImode);
5527 if (BYTES_BIG_ENDIAN)
5529 operands[4] = operands[2];
5530 operands[5] = operands[3];
5534 operands[4] = operands[3];
5535 operands[5] = operands[2];
5541 [(set (match_operand:SI 0 "register_operand" "")
5542 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5544 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5545 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5547 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5550 (define_insn "*arm_extendhisi2"
5551 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5552 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5553 "TARGET_ARM && arm_arch4 && !arm_arch6"
5557 [(set_attr "length" "8,4")
5558 (set_attr "type" "alu_shift_reg,load_byte")
5559 (set_attr "predicable" "yes")]
5562 ;; ??? Check Thumb-2 pool range
5563 (define_insn "*arm_extendhisi2_v6"
5564 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5566 "TARGET_32BIT && arm_arch6"
5570 [(set_attr "type" "extend,load_byte")
5571 (set_attr "predicable" "yes")]
5574 (define_insn "*arm_extendhisi2addsi"
5575 [(set (match_operand:SI 0 "s_register_operand" "=r")
5576 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5577 (match_operand:SI 2 "s_register_operand" "r")))]
5579 "sxtah%?\\t%0, %2, %1"
5580 [(set_attr "type" "alu_shift_reg")]
5583 (define_expand "extendqihi2"
5585 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5587 (set (match_operand:HI 0 "s_register_operand" "")
5588 (ashiftrt:SI (match_dup 2)
5593 if (arm_arch4 && MEM_P (operands[1]))
5595 emit_insn (gen_rtx_SET (operands[0],
5596 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5599 if (!s_register_operand (operands[1], QImode))
5600 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5601 operands[0] = gen_lowpart (SImode, operands[0]);
5602 operands[1] = gen_lowpart (SImode, operands[1]);
5603 operands[2] = gen_reg_rtx (SImode);
5607 (define_insn "*arm_extendqihi_insn"
5608 [(set (match_operand:HI 0 "s_register_operand" "=r")
5609 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5610 "TARGET_ARM && arm_arch4"
5612 [(set_attr "type" "load_byte")
5613 (set_attr "predicable" "yes")]
5616 (define_expand "extendqisi2"
5617 [(set (match_operand:SI 0 "s_register_operand" "")
5618 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5621 if (!arm_arch4 && MEM_P (operands[1]))
5622 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5624 if (!arm_arch6 && !MEM_P (operands[1]))
5626 rtx t = gen_lowpart (SImode, operands[1]);
5627 rtx tmp = gen_reg_rtx (SImode);
5628 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5629 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5635 [(set (match_operand:SI 0 "register_operand" "")
5636 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5638 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5639 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5641 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5644 (define_insn "*arm_extendqisi"
5645 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5646 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5647 "TARGET_ARM && arm_arch4 && !arm_arch6"
5651 [(set_attr "length" "8,4")
5652 (set_attr "type" "alu_shift_reg,load_byte")
5653 (set_attr "predicable" "yes")]
5656 (define_insn "*arm_extendqisi_v6"
5657 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5659 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5660 "TARGET_ARM && arm_arch6"
5664 [(set_attr "type" "extend,load_byte")
5665 (set_attr "predicable" "yes")]
5668 (define_insn "*arm_extendqisi2addsi"
5669 [(set (match_operand:SI 0 "s_register_operand" "=r")
5670 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5671 (match_operand:SI 2 "s_register_operand" "r")))]
5673 "sxtab%?\\t%0, %2, %1"
5674 [(set_attr "type" "alu_shift_reg")
5675 (set_attr "predicable" "yes")]
5678 (define_expand "extendsfdf2"
5679 [(set (match_operand:DF 0 "s_register_operand" "")
5680 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5681 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5685 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5686 ;; must go through SFmode.
5688 ;; This is always safe for an extend.
5690 (define_expand "extendhfdf2"
5691 [(set (match_operand:DF 0 "s_register_operand" "")
5692 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5695 /* We don't have a direct instruction for this, so go via SFmode. */
5696 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5699 op1 = convert_to_mode (SFmode, operands[1], 0);
5700 op1 = convert_to_mode (DFmode, op1, 0);
5701 emit_insn (gen_movdf (operands[0], op1));
5704 /* Otherwise, we're done producing RTL and will pick up the correct
5705 pattern to do this with one rounding-step in a single instruction. */
5709 ;; Move insns (including loads and stores)
5711 ;; XXX Just some ideas about movti.
5712 ;; I don't think these are a good idea on the arm, there just aren't enough
5714 ;;(define_expand "loadti"
5715 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5716 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5719 ;;(define_expand "storeti"
5720 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5721 ;; (match_operand:TI 1 "s_register_operand" ""))]
5724 ;;(define_expand "movti"
5725 ;; [(set (match_operand:TI 0 "general_operand" "")
5726 ;; (match_operand:TI 1 "general_operand" ""))]
5732 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5733 ;; operands[1] = copy_to_reg (operands[1]);
5734 ;; if (MEM_P (operands[0]))
5735 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5736 ;; else if (MEM_P (operands[1]))
5737 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5741 ;; emit_insn (insn);
5745 ;; Recognize garbage generated above.
5748 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5749 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5753 ;; register mem = (which_alternative < 3);
5754 ;; register const char *template;
5756 ;; operands[mem] = XEXP (operands[mem], 0);
5757 ;; switch (which_alternative)
5759 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5760 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5761 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5762 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5763 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5764 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5766 ;; output_asm_insn (template, operands);
5770 (define_expand "movdi"
5771 [(set (match_operand:DI 0 "general_operand" "")
5772 (match_operand:DI 1 "general_operand" ""))]
5775 if (can_create_pseudo_p ())
5777 if (!REG_P (operands[0]))
5778 operands[1] = force_reg (DImode, operands[1]);
5780 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5781 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5783 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5784 when expanding function calls. */
5785 gcc_assert (can_create_pseudo_p ());
5786 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5788 /* Perform load into legal reg pair first, then move. */
5789 rtx reg = gen_reg_rtx (DImode);
5790 emit_insn (gen_movdi (reg, operands[1]));
5793 emit_move_insn (gen_lowpart (SImode, operands[0]),
5794 gen_lowpart (SImode, operands[1]));
5795 emit_move_insn (gen_highpart (SImode, operands[0]),
5796 gen_highpart (SImode, operands[1]));
5799 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5800 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5802 /* Avoid STRD's from an odd-numbered register pair in ARM state
5803 when expanding function prologue. */
5804 gcc_assert (can_create_pseudo_p ());
5805 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5806 ? gen_reg_rtx (DImode)
5808 emit_move_insn (gen_lowpart (SImode, split_dest),
5809 gen_lowpart (SImode, operands[1]));
5810 emit_move_insn (gen_highpart (SImode, split_dest),
5811 gen_highpart (SImode, operands[1]));
5812 if (split_dest != operands[0])
5813 emit_insn (gen_movdi (operands[0], split_dest));
5819 (define_insn "*arm_movdi"
5820 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
5821 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
5823 && !(TARGET_HARD_FLOAT)
5825 && ( register_operand (operands[0], DImode)
5826 || register_operand (operands[1], DImode))"
5828 switch (which_alternative)
5835 /* Cannot load it directly, split to load it via MOV / MOVT. */
5836 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
5840 return output_move_double (operands, true, NULL);
5843 [(set_attr "length" "8,12,16,8,8")
5844 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5845 (set_attr "arm_pool_range" "*,*,*,1020,*")
5846 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5847 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5848 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5852 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5853 (match_operand:ANY64 1 "immediate_operand" ""))]
5856 && (arm_disable_literal_pool
5857 || (arm_const_double_inline_cost (operands[1])
5858 <= arm_max_const_double_inline_cost ()))"
5861 arm_split_constant (SET, SImode, curr_insn,
5862 INTVAL (gen_lowpart (SImode, operands[1])),
5863 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5864 arm_split_constant (SET, SImode, curr_insn,
5865 INTVAL (gen_highpart_mode (SImode,
5866 GET_MODE (operands[0]),
5868 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5873 ; If optimizing for size, or if we have load delay slots, then
5874 ; we want to split the constant into two separate operations.
5875 ; In both cases this may split a trivial part into a single data op
5876 ; leaving a single complex constant to load. We can also get longer
5877 ; offsets in a LDR which means we get better chances of sharing the pool
5878 ; entries. Finally, we can normally do a better job of scheduling
5879 ; LDR instructions than we can with LDM.
5880 ; This pattern will only match if the one above did not.
5882 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5883 (match_operand:ANY64 1 "const_double_operand" ""))]
5884 "TARGET_ARM && reload_completed
5885 && arm_const_double_by_parts (operands[1])"
5886 [(set (match_dup 0) (match_dup 1))
5887 (set (match_dup 2) (match_dup 3))]
5889 operands[2] = gen_highpart (SImode, operands[0]);
5890 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5892 operands[0] = gen_lowpart (SImode, operands[0]);
5893 operands[1] = gen_lowpart (SImode, operands[1]);
5898 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5899 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5900 "TARGET_EITHER && reload_completed"
5901 [(set (match_dup 0) (match_dup 1))
5902 (set (match_dup 2) (match_dup 3))]
5904 operands[2] = gen_highpart (SImode, operands[0]);
5905 operands[3] = gen_highpart (SImode, operands[1]);
5906 operands[0] = gen_lowpart (SImode, operands[0]);
5907 operands[1] = gen_lowpart (SImode, operands[1]);
5909 /* Handle a partial overlap. */
5910 if (rtx_equal_p (operands[0], operands[3]))
5912 rtx tmp0 = operands[0];
5913 rtx tmp1 = operands[1];
5915 operands[0] = operands[2];
5916 operands[1] = operands[3];
5923 ;; We can't actually do base+index doubleword loads if the index and
5924 ;; destination overlap. Split here so that we at least have chance to
5927 [(set (match_operand:DI 0 "s_register_operand" "")
5928 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5929 (match_operand:SI 2 "s_register_operand" ""))))]
5931 && reg_overlap_mentioned_p (operands[0], operands[1])
5932 && reg_overlap_mentioned_p (operands[0], operands[2])"
5934 (plus:SI (match_dup 1)
5937 (mem:DI (match_dup 4)))]
5939 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5943 (define_expand "movsi"
5944 [(set (match_operand:SI 0 "general_operand" "")
5945 (match_operand:SI 1 "general_operand" ""))]
5949 rtx base, offset, tmp;
5951 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5953 /* Everything except mem = const or mem = mem can be done easily. */
5954 if (MEM_P (operands[0]))
5955 operands[1] = force_reg (SImode, operands[1]);
5956 if (arm_general_register_operand (operands[0], SImode)
5957 && CONST_INT_P (operands[1])
5958 && !(const_ok_for_arm (INTVAL (operands[1]))
5959 || const_ok_for_arm (~INTVAL (operands[1]))))
5961 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5963 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5968 arm_split_constant (SET, SImode, NULL_RTX,
5969 INTVAL (operands[1]), operands[0], NULL_RTX,
5970 optimize && can_create_pseudo_p ());
5975 else /* Target doesn't have MOVT... */
5977 if (can_create_pseudo_p ())
5979 if (!REG_P (operands[0]))
5980 operands[1] = force_reg (SImode, operands[1]);
5984 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5986 split_const (operands[1], &base, &offset);
5987 if (GET_CODE (base) == SYMBOL_REF
5988 && !offset_within_block_p (base, INTVAL (offset)))
5990 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5991 emit_move_insn (tmp, base);
5992 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5997 /* Recognize the case where operand[1] is a reference to thread-local
5998 data and load its address to a register. */
5999 if (arm_tls_referenced_p (operands[1]))
6001 rtx tmp = operands[1];
6004 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6006 addend = XEXP (XEXP (tmp, 0), 1);
6007 tmp = XEXP (XEXP (tmp, 0), 0);
6010 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6011 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6013 tmp = legitimize_tls_address (tmp,
6014 !can_create_pseudo_p () ? operands[0] : 0);
6017 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6018 tmp = force_operand (tmp, operands[0]);
6023 && (CONSTANT_P (operands[1])
6024 || symbol_mentioned_p (operands[1])
6025 || label_mentioned_p (operands[1])))
6026 operands[1] = legitimize_pic_address (operands[1], SImode,
6027 (!can_create_pseudo_p ()
6029 : NULL_RTX), NULL_RTX,
6030 false /*compute_now*/);
6035 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6036 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6037 ;; so this does not matter.
6038 (define_insn "*arm_movt"
6039 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6040 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6041 (match_operand:SI 2 "general_operand" "i,i")))]
6042 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6044 movt%?\t%0, #:upper16:%c2
6045 movt\t%0, #:upper16:%c2"
6046 [(set_attr "arch" "32,v8mb")
6047 (set_attr "predicable" "yes")
6048 (set_attr "length" "4")
6049 (set_attr "type" "alu_sreg")]
6052 (define_insn "*arm_movsi_insn"
6053 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6054 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6055 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6056 && ( register_operand (operands[0], SImode)
6057 || register_operand (operands[1], SImode))"
6065 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6066 (set_attr "predicable" "yes")
6067 (set_attr "arch" "*,*,*,v6t2,*,*")
6068 (set_attr "pool_range" "*,*,*,*,4096,*")
6069 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6073 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6074 (match_operand:SI 1 "const_int_operand" ""))]
6075 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6076 && (!(const_ok_for_arm (INTVAL (operands[1]))
6077 || const_ok_for_arm (~INTVAL (operands[1]))))"
6078 [(clobber (const_int 0))]
6080 arm_split_constant (SET, SImode, NULL_RTX,
6081 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6086 ;; A normal way to do (symbol + offset) requires three instructions at least
6087 ;; (depends on how big the offset is) as below:
6088 ;; movw r0, #:lower16:g
6089 ;; movw r0, #:upper16:g
6092 ;; A better way would be:
6093 ;; movw r0, #:lower16:g+4
6094 ;; movw r0, #:upper16:g+4
6096 ;; The limitation of this way is that the length of offset should be a 16-bit
6097 ;; signed value, because current assembler only supports REL type relocation for
6098 ;; such case. If the more powerful RELA type is supported in future, we should
6099 ;; update this pattern to go with better way.
6101 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6102 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6103 (match_operand:SI 2 "const_int_operand" ""))))]
6106 && arm_disable_literal_pool
6108 && GET_CODE (operands[1]) == SYMBOL_REF"
6109 [(clobber (const_int 0))]
6111 int offset = INTVAL (operands[2]);
6113 if (offset < -0x8000 || offset > 0x7fff)
6115 arm_emit_movpair (operands[0], operands[1]);
6116 emit_insn (gen_rtx_SET (operands[0],
6117 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6121 rtx op = gen_rtx_CONST (SImode,
6122 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6123 arm_emit_movpair (operands[0], op);
6128 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6129 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6130 ;; and lo_sum would be merged back into memory load at cprop. However,
6131 ;; if the default is to prefer movt/movw rather than a load from the constant
6132 ;; pool, the performance is better.
6134 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6135 (match_operand:SI 1 "general_operand" ""))]
6136 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6137 && !target_word_relocations
6138 && !arm_tls_referenced_p (operands[1])"
6139 [(clobber (const_int 0))]
6141 arm_emit_movpair (operands[0], operands[1]);
6145 ;; When generating pic, we need to load the symbol offset into a register.
6146 ;; So that the optimizer does not confuse this with a normal symbol load
6147 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6148 ;; since that is the only type of relocation we can use.
6150 ;; Wrap calculation of the whole PIC address in a single pattern for the
6151 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6152 ;; a PIC address involves two loads from memory, so we want to CSE it
6153 ;; as often as possible.
6154 ;; This pattern will be split into one of the pic_load_addr_* patterns
6155 ;; and a move after GCSE optimizations.
6157 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6158 (define_expand "calculate_pic_address"
6159 [(set (match_operand:SI 0 "register_operand" "")
6160 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6161 (unspec:SI [(match_operand:SI 2 "" "")]
6166 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6168 [(set (match_operand:SI 0 "register_operand" "")
6169 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6170 (unspec:SI [(match_operand:SI 2 "" "")]
6173 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6174 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6175 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6178 ;; operand1 is the memory address to go into
6179 ;; pic_load_addr_32bit.
6180 ;; operand2 is the PIC label to be emitted
6181 ;; from pic_add_dot_plus_eight.
6182 ;; We do this to allow hoisting of the entire insn.
6183 (define_insn_and_split "pic_load_addr_unified"
6184 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6185 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6186 (match_operand:SI 2 "" "")]
6187 UNSPEC_PIC_UNIFIED))]
6190 "&& reload_completed"
6191 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6192 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6193 (match_dup 2)] UNSPEC_PIC_BASE))]
6194 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6195 [(set_attr "type" "load_4,load_4,load_4")
6196 (set_attr "pool_range" "4096,4094,1022")
6197 (set_attr "neg_pool_range" "4084,0,0")
6198 (set_attr "arch" "a,t2,t1")
6199 (set_attr "length" "8,6,4")]
6202 ;; The rather odd constraints on the following are to force reload to leave
6203 ;; the insn alone, and to force the minipool generation pass to then move
6204 ;; the GOT symbol to memory.
6206 (define_insn "pic_load_addr_32bit"
6207 [(set (match_operand:SI 0 "s_register_operand" "=r")
6208 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6209 "TARGET_32BIT && flag_pic"
6211 [(set_attr "type" "load_4")
6212 (set (attr "pool_range")
6213 (if_then_else (eq_attr "is_thumb" "no")
6216 (set (attr "neg_pool_range")
6217 (if_then_else (eq_attr "is_thumb" "no")
6222 (define_insn "pic_load_addr_thumb1"
6223 [(set (match_operand:SI 0 "s_register_operand" "=l")
6224 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6225 "TARGET_THUMB1 && flag_pic"
6227 [(set_attr "type" "load_4")
6228 (set (attr "pool_range") (const_int 1018))]
6231 (define_insn "pic_add_dot_plus_four"
6232 [(set (match_operand:SI 0 "register_operand" "=r")
6233 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6235 (match_operand 2 "" "")]
6239 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6240 INTVAL (operands[2]));
6241 return \"add\\t%0, %|pc\";
6243 [(set_attr "length" "2")
6244 (set_attr "type" "alu_sreg")]
6247 (define_insn "pic_add_dot_plus_eight"
6248 [(set (match_operand:SI 0 "register_operand" "=r")
6249 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6251 (match_operand 2 "" "")]
6255 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6256 INTVAL (operands[2]));
6257 return \"add%?\\t%0, %|pc, %1\";
6259 [(set_attr "predicable" "yes")
6260 (set_attr "type" "alu_sreg")]
6263 (define_insn "tls_load_dot_plus_eight"
6264 [(set (match_operand:SI 0 "register_operand" "=r")
6265 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6267 (match_operand 2 "" "")]
6271 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6272 INTVAL (operands[2]));
6273 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6275 [(set_attr "predicable" "yes")
6276 (set_attr "type" "load_4")]
6279 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6280 ;; followed by a load. These sequences can be crunched down to
6281 ;; tls_load_dot_plus_eight by a peephole.
6284 [(set (match_operand:SI 0 "register_operand" "")
6285 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6287 (match_operand 1 "" "")]
6289 (set (match_operand:SI 2 "arm_general_register_operand" "")
6290 (mem:SI (match_dup 0)))]
6291 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6293 (mem:SI (unspec:SI [(match_dup 3)
6300 (define_insn "pic_offset_arm"
6301 [(set (match_operand:SI 0 "register_operand" "=r")
6302 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6303 (unspec:SI [(match_operand:SI 2 "" "X")]
6304 UNSPEC_PIC_OFFSET))))]
6305 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6306 "ldr%?\\t%0, [%1,%2]"
6307 [(set_attr "type" "load_4")]
6310 (define_expand "builtin_setjmp_receiver"
6311 [(label_ref (match_operand 0 "" ""))]
6315 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6317 if (arm_pic_register != INVALID_REGNUM)
6318 arm_load_pic_register (1UL << 3, NULL_RTX);
6322 ;; If copying one reg to another we can set the condition codes according to
6323 ;; its value. Such a move is common after a return from subroutine and the
6324 ;; result is being tested against zero.
6326 (define_insn "*movsi_compare0"
6327 [(set (reg:CC CC_REGNUM)
6328 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6330 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6335 subs%?\\t%0, %1, #0"
6336 [(set_attr "conds" "set")
6337 (set_attr "type" "alus_imm,alus_imm")]
6340 ;; Subroutine to store a half word from a register into memory.
6341 ;; Operand 0 is the source register (HImode)
6342 ;; Operand 1 is the destination address in a register (SImode)
6344 ;; In both this routine and the next, we must be careful not to spill
6345 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6346 ;; can generate unrecognizable rtl.
6348 (define_expand "storehi"
6349 [;; store the low byte
6350 (set (match_operand 1 "" "") (match_dup 3))
6351 ;; extract the high byte
6353 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6354 ;; store the high byte
6355 (set (match_dup 4) (match_dup 5))]
6359 rtx op1 = operands[1];
6360 rtx addr = XEXP (op1, 0);
6361 enum rtx_code code = GET_CODE (addr);
6363 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6365 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6367 operands[4] = adjust_address (op1, QImode, 1);
6368 operands[1] = adjust_address (operands[1], QImode, 0);
6369 operands[3] = gen_lowpart (QImode, operands[0]);
6370 operands[0] = gen_lowpart (SImode, operands[0]);
6371 operands[2] = gen_reg_rtx (SImode);
6372 operands[5] = gen_lowpart (QImode, operands[2]);
6376 (define_expand "storehi_bigend"
6377 [(set (match_dup 4) (match_dup 3))
6379 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6380 (set (match_operand 1 "" "") (match_dup 5))]
6384 rtx op1 = operands[1];
6385 rtx addr = XEXP (op1, 0);
6386 enum rtx_code code = GET_CODE (addr);
6388 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6390 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6392 operands[4] = adjust_address (op1, QImode, 1);
6393 operands[1] = adjust_address (operands[1], QImode, 0);
6394 operands[3] = gen_lowpart (QImode, operands[0]);
6395 operands[0] = gen_lowpart (SImode, operands[0]);
6396 operands[2] = gen_reg_rtx (SImode);
6397 operands[5] = gen_lowpart (QImode, operands[2]);
6401 ;; Subroutine to store a half word integer constant into memory.
6402 (define_expand "storeinthi"
6403 [(set (match_operand 0 "" "")
6404 (match_operand 1 "" ""))
6405 (set (match_dup 3) (match_dup 2))]
6409 HOST_WIDE_INT value = INTVAL (operands[1]);
6410 rtx addr = XEXP (operands[0], 0);
6411 rtx op0 = operands[0];
6412 enum rtx_code code = GET_CODE (addr);
6414 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6416 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6418 operands[1] = gen_reg_rtx (SImode);
6419 if (BYTES_BIG_ENDIAN)
6421 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6422 if ((value & 255) == ((value >> 8) & 255))
6423 operands[2] = operands[1];
6426 operands[2] = gen_reg_rtx (SImode);
6427 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6432 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6433 if ((value & 255) == ((value >> 8) & 255))
6434 operands[2] = operands[1];
6437 operands[2] = gen_reg_rtx (SImode);
6438 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6442 operands[3] = adjust_address (op0, QImode, 1);
6443 operands[0] = adjust_address (operands[0], QImode, 0);
6444 operands[2] = gen_lowpart (QImode, operands[2]);
6445 operands[1] = gen_lowpart (QImode, operands[1]);
6449 (define_expand "storehi_single_op"
6450 [(set (match_operand:HI 0 "memory_operand" "")
6451 (match_operand:HI 1 "general_operand" ""))]
6452 "TARGET_32BIT && arm_arch4"
6454 if (!s_register_operand (operands[1], HImode))
6455 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6459 (define_expand "movhi"
6460 [(set (match_operand:HI 0 "general_operand" "")
6461 (match_operand:HI 1 "general_operand" ""))]
6466 if (can_create_pseudo_p ())
6468 if (MEM_P (operands[0]))
6472 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6475 if (CONST_INT_P (operands[1]))
6476 emit_insn (gen_storeinthi (operands[0], operands[1]));
6479 if (MEM_P (operands[1]))
6480 operands[1] = force_reg (HImode, operands[1]);
6481 if (BYTES_BIG_ENDIAN)
6482 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6484 emit_insn (gen_storehi (operands[1], operands[0]));
6488 /* Sign extend a constant, and keep it in an SImode reg. */
6489 else if (CONST_INT_P (operands[1]))
6491 rtx reg = gen_reg_rtx (SImode);
6492 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6494 /* If the constant is already valid, leave it alone. */
6495 if (!const_ok_for_arm (val))
6497 /* If setting all the top bits will make the constant
6498 loadable in a single instruction, then set them.
6499 Otherwise, sign extend the number. */
6501 if (const_ok_for_arm (~(val | ~0xffff)))
6503 else if (val & 0x8000)
6507 emit_insn (gen_movsi (reg, GEN_INT (val)));
6508 operands[1] = gen_lowpart (HImode, reg);
6510 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6511 && MEM_P (operands[1]))
6513 rtx reg = gen_reg_rtx (SImode);
6515 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6516 operands[1] = gen_lowpart (HImode, reg);
6518 else if (!arm_arch4)
6520 if (MEM_P (operands[1]))
6523 rtx offset = const0_rtx;
6524 rtx reg = gen_reg_rtx (SImode);
6526 if ((REG_P (base = XEXP (operands[1], 0))
6527 || (GET_CODE (base) == PLUS
6528 && (CONST_INT_P (offset = XEXP (base, 1)))
6529 && ((INTVAL(offset) & 1) != 1)
6530 && REG_P (base = XEXP (base, 0))))
6531 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6535 new_rtx = widen_memory_access (operands[1], SImode,
6536 ((INTVAL (offset) & ~3)
6537 - INTVAL (offset)));
6538 emit_insn (gen_movsi (reg, new_rtx));
6539 if (((INTVAL (offset) & 2) != 0)
6540 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6542 rtx reg2 = gen_reg_rtx (SImode);
6544 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6549 emit_insn (gen_movhi_bytes (reg, operands[1]));
6551 operands[1] = gen_lowpart (HImode, reg);
6555 /* Handle loading a large integer during reload. */
6556 else if (CONST_INT_P (operands[1])
6557 && !const_ok_for_arm (INTVAL (operands[1]))
6558 && !const_ok_for_arm (~INTVAL (operands[1])))
6560 /* Writing a constant to memory needs a scratch, which should
6561 be handled with SECONDARY_RELOADs. */
6562 gcc_assert (REG_P (operands[0]));
6564 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6565 emit_insn (gen_movsi (operands[0], operands[1]));
6569 else if (TARGET_THUMB2)
6571 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6572 if (can_create_pseudo_p ())
6574 if (!REG_P (operands[0]))
6575 operands[1] = force_reg (HImode, operands[1]);
6576 /* Zero extend a constant, and keep it in an SImode reg. */
6577 else if (CONST_INT_P (operands[1]))
6579 rtx reg = gen_reg_rtx (SImode);
6580 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6582 emit_insn (gen_movsi (reg, GEN_INT (val)));
6583 operands[1] = gen_lowpart (HImode, reg);
6587 else /* TARGET_THUMB1 */
6589 if (can_create_pseudo_p ())
6591 if (CONST_INT_P (operands[1]))
6593 rtx reg = gen_reg_rtx (SImode);
6595 emit_insn (gen_movsi (reg, operands[1]));
6596 operands[1] = gen_lowpart (HImode, reg);
6599 /* ??? We shouldn't really get invalid addresses here, but this can
6600 happen if we are passed a SP (never OK for HImode/QImode) or
6601 virtual register (also rejected as illegitimate for HImode/QImode)
6602 relative address. */
6603 /* ??? This should perhaps be fixed elsewhere, for instance, in
6604 fixup_stack_1, by checking for other kinds of invalid addresses,
6605 e.g. a bare reference to a virtual register. This may confuse the
6606 alpha though, which must handle this case differently. */
6607 if (MEM_P (operands[0])
6608 && !memory_address_p (GET_MODE (operands[0]),
6609 XEXP (operands[0], 0)))
6611 = replace_equiv_address (operands[0],
6612 copy_to_reg (XEXP (operands[0], 0)));
6614 if (MEM_P (operands[1])
6615 && !memory_address_p (GET_MODE (operands[1]),
6616 XEXP (operands[1], 0)))
6618 = replace_equiv_address (operands[1],
6619 copy_to_reg (XEXP (operands[1], 0)));
6621 if (MEM_P (operands[1]) && optimize > 0)
6623 rtx reg = gen_reg_rtx (SImode);
6625 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6626 operands[1] = gen_lowpart (HImode, reg);
6629 if (MEM_P (operands[0]))
6630 operands[1] = force_reg (HImode, operands[1]);
6632 else if (CONST_INT_P (operands[1])
6633 && !satisfies_constraint_I (operands[1]))
6635 /* Handle loading a large integer during reload. */
6637 /* Writing a constant to memory needs a scratch, which should
6638 be handled with SECONDARY_RELOADs. */
6639 gcc_assert (REG_P (operands[0]));
6641 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6642 emit_insn (gen_movsi (operands[0], operands[1]));
6649 (define_expand "movhi_bytes"
6650 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6652 (zero_extend:SI (match_dup 6)))
6653 (set (match_operand:SI 0 "" "")
6654 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6659 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6661 mem1 = change_address (operands[1], QImode, addr);
6662 mem2 = change_address (operands[1], QImode,
6663 plus_constant (Pmode, addr, 1));
6664 operands[0] = gen_lowpart (SImode, operands[0]);
6666 operands[2] = gen_reg_rtx (SImode);
6667 operands[3] = gen_reg_rtx (SImode);
6670 if (BYTES_BIG_ENDIAN)
6672 operands[4] = operands[2];
6673 operands[5] = operands[3];
6677 operands[4] = operands[3];
6678 operands[5] = operands[2];
6683 (define_expand "movhi_bigend"
6685 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6688 (ashiftrt:SI (match_dup 2) (const_int 16)))
6689 (set (match_operand:HI 0 "s_register_operand" "")
6693 operands[2] = gen_reg_rtx (SImode);
6694 operands[3] = gen_reg_rtx (SImode);
6695 operands[4] = gen_lowpart (HImode, operands[3]);
6699 ;; Pattern to recognize insn generated default case above
6700 (define_insn "*movhi_insn_arch4"
6701 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6702 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6704 && arm_arch4 && !TARGET_HARD_FLOAT
6705 && (register_operand (operands[0], HImode)
6706 || register_operand (operands[1], HImode))"
6708 mov%?\\t%0, %1\\t%@ movhi
6709 mvn%?\\t%0, #%B1\\t%@ movhi
6710 movw%?\\t%0, %L1\\t%@ movhi
6711 strh%?\\t%1, %0\\t%@ movhi
6712 ldrh%?\\t%0, %1\\t%@ movhi"
6713 [(set_attr "predicable" "yes")
6714 (set_attr "pool_range" "*,*,*,*,256")
6715 (set_attr "neg_pool_range" "*,*,*,*,244")
6716 (set_attr "arch" "*,*,v6t2,*,*")
6717 (set_attr_alternative "type"
6718 [(if_then_else (match_operand 1 "const_int_operand" "")
6719 (const_string "mov_imm" )
6720 (const_string "mov_reg"))
6721 (const_string "mvn_imm")
6722 (const_string "mov_imm")
6723 (const_string "store_4")
6724 (const_string "load_4")])]
6727 (define_insn "*movhi_bytes"
6728 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6729 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6730 "TARGET_ARM && !TARGET_HARD_FLOAT"
6732 mov%?\\t%0, %1\\t%@ movhi
6733 mov%?\\t%0, %1\\t%@ movhi
6734 mvn%?\\t%0, #%B1\\t%@ movhi"
6735 [(set_attr "predicable" "yes")
6736 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6739 ;; We use a DImode scratch because we may occasionally need an additional
6740 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6741 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6742 (define_expand "reload_outhi"
6743 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6744 (match_operand:HI 1 "s_register_operand" "r")
6745 (match_operand:DI 2 "s_register_operand" "=&l")])]
6748 arm_reload_out_hi (operands);
6750 thumb_reload_out_hi (operands);
6755 (define_expand "reload_inhi"
6756 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6757 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6758 (match_operand:DI 2 "s_register_operand" "=&r")])]
6762 arm_reload_in_hi (operands);
6764 thumb_reload_out_hi (operands);
6768 (define_expand "movqi"
6769 [(set (match_operand:QI 0 "general_operand" "")
6770 (match_operand:QI 1 "general_operand" ""))]
6773 /* Everything except mem = const or mem = mem can be done easily */
6775 if (can_create_pseudo_p ())
6777 if (CONST_INT_P (operands[1]))
6779 rtx reg = gen_reg_rtx (SImode);
6781 /* For thumb we want an unsigned immediate, then we are more likely
6782 to be able to use a movs insn. */
6784 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6786 emit_insn (gen_movsi (reg, operands[1]));
6787 operands[1] = gen_lowpart (QImode, reg);
6792 /* ??? We shouldn't really get invalid addresses here, but this can
6793 happen if we are passed a SP (never OK for HImode/QImode) or
6794 virtual register (also rejected as illegitimate for HImode/QImode)
6795 relative address. */
6796 /* ??? This should perhaps be fixed elsewhere, for instance, in
6797 fixup_stack_1, by checking for other kinds of invalid addresses,
6798 e.g. a bare reference to a virtual register. This may confuse the
6799 alpha though, which must handle this case differently. */
6800 if (MEM_P (operands[0])
6801 && !memory_address_p (GET_MODE (operands[0]),
6802 XEXP (operands[0], 0)))
6804 = replace_equiv_address (operands[0],
6805 copy_to_reg (XEXP (operands[0], 0)));
6806 if (MEM_P (operands[1])
6807 && !memory_address_p (GET_MODE (operands[1]),
6808 XEXP (operands[1], 0)))
6810 = replace_equiv_address (operands[1],
6811 copy_to_reg (XEXP (operands[1], 0)));
6814 if (MEM_P (operands[1]) && optimize > 0)
6816 rtx reg = gen_reg_rtx (SImode);
6818 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6819 operands[1] = gen_lowpart (QImode, reg);
6822 if (MEM_P (operands[0]))
6823 operands[1] = force_reg (QImode, operands[1]);
6825 else if (TARGET_THUMB
6826 && CONST_INT_P (operands[1])
6827 && !satisfies_constraint_I (operands[1]))
6829 /* Handle loading a large integer during reload. */
6831 /* Writing a constant to memory needs a scratch, which should
6832 be handled with SECONDARY_RELOADs. */
6833 gcc_assert (REG_P (operands[0]));
6835 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6836 emit_insn (gen_movsi (operands[0], operands[1]));
6842 (define_insn "*arm_movqi_insn"
6843 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6844 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6846 && ( register_operand (operands[0], QImode)
6847 || register_operand (operands[1], QImode))"
6858 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6859 (set_attr "predicable" "yes")
6860 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6861 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6862 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6866 (define_expand "movhf"
6867 [(set (match_operand:HF 0 "general_operand" "")
6868 (match_operand:HF 1 "general_operand" ""))]
6873 if (MEM_P (operands[0]))
6874 operands[1] = force_reg (HFmode, operands[1]);
6876 else /* TARGET_THUMB1 */
6878 if (can_create_pseudo_p ())
6880 if (!REG_P (operands[0]))
6881 operands[1] = force_reg (HFmode, operands[1]);
6887 (define_insn "*arm32_movhf"
6888 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6889 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6890 "TARGET_32BIT && !TARGET_HARD_FLOAT
6891 && ( s_register_operand (operands[0], HFmode)
6892 || s_register_operand (operands[1], HFmode))"
6894 switch (which_alternative)
6896 case 0: /* ARM register from memory */
6897 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6898 case 1: /* memory from ARM register */
6899 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6900 case 2: /* ARM register from ARM register */
6901 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6902 case 3: /* ARM register from constant */
6907 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6909 ops[0] = operands[0];
6910 ops[1] = GEN_INT (bits);
6911 ops[2] = GEN_INT (bits & 0xff00);
6912 ops[3] = GEN_INT (bits & 0x00ff);
6914 if (arm_arch_thumb2)
6915 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6917 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6924 [(set_attr "conds" "unconditional")
6925 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6926 (set_attr "length" "4,4,4,8")
6927 (set_attr "predicable" "yes")]
6930 (define_expand "movsf"
6931 [(set (match_operand:SF 0 "general_operand" "")
6932 (match_operand:SF 1 "general_operand" ""))]
6937 if (MEM_P (operands[0]))
6938 operands[1] = force_reg (SFmode, operands[1]);
6940 else /* TARGET_THUMB1 */
6942 if (can_create_pseudo_p ())
6944 if (!REG_P (operands[0]))
6945 operands[1] = force_reg (SFmode, operands[1]);
6949 /* Cannot load it directly, generate a load with clobber so that it can be
6950 loaded via GPR with MOV / MOVT. */
6951 if (arm_disable_literal_pool
6952 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6953 && CONST_DOUBLE_P (operands[1])
6954 && TARGET_HARD_FLOAT
6955 && !vfp3_const_double_rtx (operands[1]))
6957 rtx clobreg = gen_reg_rtx (SFmode);
6958 emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
6965 ;; Transform a floating-point move of a constant into a core register into
6966 ;; an SImode operation.
6968 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6969 (match_operand:SF 1 "immediate_operand" ""))]
6972 && CONST_DOUBLE_P (operands[1])"
6973 [(set (match_dup 2) (match_dup 3))]
6975 operands[2] = gen_lowpart (SImode, operands[0]);
6976 operands[3] = gen_lowpart (SImode, operands[1]);
6977 if (operands[2] == 0 || operands[3] == 0)
6982 (define_insn "*arm_movsf_soft_insn"
6983 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6984 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6986 && TARGET_SOFT_FLOAT
6987 && (!MEM_P (operands[0])
6988 || register_operand (operands[1], SFmode))"
6990 switch (which_alternative)
6992 case 0: return \"mov%?\\t%0, %1\";
6994 /* Cannot load it directly, split to load it via MOV / MOVT. */
6995 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
6997 return \"ldr%?\\t%0, %1\\t%@ float\";
6998 case 2: return \"str%?\\t%1, %0\\t%@ float\";
6999 default: gcc_unreachable ();
7002 [(set_attr "predicable" "yes")
7003 (set_attr "type" "mov_reg,load_4,store_4")
7004 (set_attr "arm_pool_range" "*,4096,*")
7005 (set_attr "thumb2_pool_range" "*,4094,*")
7006 (set_attr "arm_neg_pool_range" "*,4084,*")
7007 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7010 ;; Splitter for the above.
7012 [(set (match_operand:SF 0 "s_register_operand")
7013 (match_operand:SF 1 "const_double_operand"))]
7014 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7018 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
7019 rtx cst = gen_int_mode (buf, SImode);
7020 emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
7025 (define_expand "movdf"
7026 [(set (match_operand:DF 0 "general_operand" "")
7027 (match_operand:DF 1 "general_operand" ""))]
7032 if (MEM_P (operands[0]))
7033 operands[1] = force_reg (DFmode, operands[1]);
7035 else /* TARGET_THUMB */
7037 if (can_create_pseudo_p ())
7039 if (!REG_P (operands[0]))
7040 operands[1] = force_reg (DFmode, operands[1]);
7044 /* Cannot load it directly, generate a load with clobber so that it can be
7045 loaded via GPR with MOV / MOVT. */
7046 if (arm_disable_literal_pool
7047 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
7048 && CONSTANT_P (operands[1])
7049 && TARGET_HARD_FLOAT
7050 && !arm_const_double_rtx (operands[1])
7051 && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
7053 rtx clobreg = gen_reg_rtx (DFmode);
7054 emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
7061 ;; Reloading a df mode value stored in integer regs to memory can require a
7063 (define_expand "reload_outdf"
7064 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7065 (match_operand:DF 1 "s_register_operand" "r")
7066 (match_operand:SI 2 "s_register_operand" "=&r")]
7070 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7073 operands[2] = XEXP (operands[0], 0);
7074 else if (code == POST_INC || code == PRE_DEC)
7076 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7077 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7078 emit_insn (gen_movdi (operands[0], operands[1]));
7081 else if (code == PRE_INC)
7083 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7085 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7088 else if (code == POST_DEC)
7089 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7091 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7092 XEXP (XEXP (operands[0], 0), 1)));
7094 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7097 if (code == POST_DEC)
7098 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7104 (define_insn "*movdf_soft_insn"
7105 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
7106 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
7107 "TARGET_32BIT && TARGET_SOFT_FLOAT
7108 && ( register_operand (operands[0], DFmode)
7109 || register_operand (operands[1], DFmode))"
7111 switch (which_alternative)
7118 /* Cannot load it directly, split to load it via MOV / MOVT. */
7119 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7123 return output_move_double (operands, true, NULL);
7126 [(set_attr "length" "8,12,16,8,8")
7127 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7128 (set_attr "arm_pool_range" "*,*,*,1020,*")
7129 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7130 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7131 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7134 ;; Splitter for the above.
7136 [(set (match_operand:DF 0 "s_register_operand")
7137 (match_operand:DF 1 "const_double_operand"))]
7138 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7142 int order = BYTES_BIG_ENDIAN ? 1 : 0;
7143 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
7144 unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
7145 ival |= (zext_hwi (buf[1 - order], 32) << 32);
7146 rtx cst = gen_int_mode (ival, DImode);
7147 emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
7153 ;; load- and store-multiple insns
7154 ;; The arm can load/store any set of registers, provided that they are in
7155 ;; ascending order, but these expanders assume a contiguous set.
7157 (define_expand "load_multiple"
7158 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7159 (match_operand:SI 1 "" ""))
7160 (use (match_operand:SI 2 "" ""))])]
7163 HOST_WIDE_INT offset = 0;
7165 /* Support only fixed point registers. */
7166 if (!CONST_INT_P (operands[2])
7167 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7168 || INTVAL (operands[2]) < 2
7169 || !MEM_P (operands[1])
7170 || !REG_P (operands[0])
7171 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7172 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7176 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7177 INTVAL (operands[2]),
7178 force_reg (SImode, XEXP (operands[1], 0)),
7179 FALSE, operands[1], &offset);
7182 (define_expand "store_multiple"
7183 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7184 (match_operand:SI 1 "" ""))
7185 (use (match_operand:SI 2 "" ""))])]
7188 HOST_WIDE_INT offset = 0;
7190 /* Support only fixed point registers. */
7191 if (!CONST_INT_P (operands[2])
7192 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7193 || INTVAL (operands[2]) < 2
7194 || !REG_P (operands[1])
7195 || !MEM_P (operands[0])
7196 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7197 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7201 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7202 INTVAL (operands[2]),
7203 force_reg (SImode, XEXP (operands[0], 0)),
7204 FALSE, operands[0], &offset);
7208 (define_expand "setmemsi"
7209 [(match_operand:BLK 0 "general_operand" "")
7210 (match_operand:SI 1 "const_int_operand" "")
7211 (match_operand:SI 2 "const_int_operand" "")
7212 (match_operand:SI 3 "const_int_operand" "")]
7215 if (arm_gen_setmem (operands))
7222 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7223 ;; We could let this apply for blocks of less than this, but it clobbers so
7224 ;; many registers that there is then probably a better way.
7226 (define_expand "movmemqi"
7227 [(match_operand:BLK 0 "general_operand" "")
7228 (match_operand:BLK 1 "general_operand" "")
7229 (match_operand:SI 2 "const_int_operand" "")
7230 (match_operand:SI 3 "const_int_operand" "")]
7235 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7236 && !optimize_function_for_size_p (cfun))
7238 if (gen_movmem_ldrd_strd (operands))
7243 if (arm_gen_movmemqi (operands))
7247 else /* TARGET_THUMB1 */
7249 if ( INTVAL (operands[3]) != 4
7250 || INTVAL (operands[2]) > 48)
7253 thumb_expand_movmemqi (operands);
7260 ;; Compare & branch insns
7261 ;; The range calculations are based as follows:
7262 ;; For forward branches, the address calculation returns the address of
7263 ;; the next instruction. This is 2 beyond the branch instruction.
7264 ;; For backward branches, the address calculation returns the address of
7265 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7266 ;; instruction for the shortest sequence, and 4 before the branch instruction
7267 ;; if we have to jump around an unconditional branch.
7268 ;; To the basic branch range the PC offset must be added (this is +4).
7269 ;; So for forward branches we have
7270 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7271 ;; And for backward branches we have
7272 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7274 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7275 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7277 (define_expand "cbranchsi4"
7278 [(set (pc) (if_then_else
7279 (match_operator 0 "expandable_comparison_operator"
7280 [(match_operand:SI 1 "s_register_operand" "")
7281 (match_operand:SI 2 "nonmemory_operand" "")])
7282 (label_ref (match_operand 3 "" ""))
7288 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7290 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7294 if (thumb1_cmpneg_operand (operands[2], SImode))
7296 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7297 operands[3], operands[0]));
7300 if (!thumb1_cmp_operand (operands[2], SImode))
7301 operands[2] = force_reg (SImode, operands[2]);
7304 (define_expand "cbranchsf4"
7305 [(set (pc) (if_then_else
7306 (match_operator 0 "expandable_comparison_operator"
7307 [(match_operand:SF 1 "s_register_operand" "")
7308 (match_operand:SF 2 "vfp_compare_operand" "")])
7309 (label_ref (match_operand 3 "" ""))
7311 "TARGET_32BIT && TARGET_HARD_FLOAT"
7312 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7313 operands[3])); DONE;"
7316 (define_expand "cbranchdf4"
7317 [(set (pc) (if_then_else
7318 (match_operator 0 "expandable_comparison_operator"
7319 [(match_operand:DF 1 "s_register_operand" "")
7320 (match_operand:DF 2 "vfp_compare_operand" "")])
7321 (label_ref (match_operand 3 "" ""))
7323 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7324 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7325 operands[3])); DONE;"
7328 (define_expand "cbranchdi4"
7329 [(set (pc) (if_then_else
7330 (match_operator 0 "expandable_comparison_operator"
7331 [(match_operand:DI 1 "s_register_operand" "")
7332 (match_operand:DI 2 "cmpdi_operand" "")])
7333 (label_ref (match_operand 3 "" ""))
7337 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7339 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7345 ;; Comparison and test insns
7347 (define_insn "*arm_cmpsi_insn"
7348 [(set (reg:CC CC_REGNUM)
7349 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7350 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7358 [(set_attr "conds" "set")
7359 (set_attr "arch" "t2,t2,any,any,any")
7360 (set_attr "length" "2,2,4,4,4")
7361 (set_attr "predicable" "yes")
7362 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7363 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7366 (define_insn "*cmpsi_shiftsi"
7367 [(set (reg:CC CC_REGNUM)
7368 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7369 (match_operator:SI 3 "shift_operator"
7370 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7371 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7374 [(set_attr "conds" "set")
7375 (set_attr "shift" "1")
7376 (set_attr "arch" "32,a,a")
7377 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7379 (define_insn "*cmpsi_shiftsi_swp"
7380 [(set (reg:CC_SWP CC_REGNUM)
7381 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7382 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7383 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7384 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7387 [(set_attr "conds" "set")
7388 (set_attr "shift" "1")
7389 (set_attr "arch" "32,a,a")
7390 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7392 (define_insn "*arm_cmpsi_negshiftsi_si"
7393 [(set (reg:CC_Z CC_REGNUM)
7395 (neg:SI (match_operator:SI 1 "shift_operator"
7396 [(match_operand:SI 2 "s_register_operand" "r")
7397 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7398 (match_operand:SI 0 "s_register_operand" "r")))]
7401 [(set_attr "conds" "set")
7402 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7403 (const_string "alus_shift_imm")
7404 (const_string "alus_shift_reg")))
7405 (set_attr "predicable" "yes")]
7408 ;; DImode comparisons. The generic code generates branches that
7409 ;; if-conversion cannot reduce to a conditional compare, so we do
7412 (define_insn_and_split "*arm_cmpdi_insn"
7413 [(set (reg:CC_NCV CC_REGNUM)
7414 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7415 (match_operand:DI 1 "arm_di_operand" "rDi")))
7416 (clobber (match_scratch:SI 2 "=r"))]
7418 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7419 "&& reload_completed"
7420 [(set (reg:CC CC_REGNUM)
7421 (compare:CC (match_dup 0) (match_dup 1)))
7422 (parallel [(set (reg:CC CC_REGNUM)
7423 (compare:CC (match_dup 3) (match_dup 4)))
7425 (minus:SI (match_dup 5)
7426 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7428 operands[3] = gen_highpart (SImode, operands[0]);
7429 operands[0] = gen_lowpart (SImode, operands[0]);
7430 if (CONST_INT_P (operands[1]))
7432 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7435 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7439 operands[4] = gen_highpart (SImode, operands[1]);
7440 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7442 operands[1] = gen_lowpart (SImode, operands[1]);
7443 operands[2] = gen_lowpart (SImode, operands[2]);
7445 [(set_attr "conds" "set")
7446 (set_attr "length" "8")
7447 (set_attr "type" "multiple")]
7450 (define_insn_and_split "*arm_cmpdi_unsigned"
7451 [(set (reg:CC_CZ CC_REGNUM)
7452 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7453 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7456 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7457 "&& reload_completed"
7458 [(set (reg:CC CC_REGNUM)
7459 (compare:CC (match_dup 2) (match_dup 3)))
7460 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7461 (set (reg:CC CC_REGNUM)
7462 (compare:CC (match_dup 0) (match_dup 1))))]
7464 operands[2] = gen_highpart (SImode, operands[0]);
7465 operands[0] = gen_lowpart (SImode, operands[0]);
7466 if (CONST_INT_P (operands[1]))
7467 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7469 operands[3] = gen_highpart (SImode, operands[1]);
7470 operands[1] = gen_lowpart (SImode, operands[1]);
7472 [(set_attr "conds" "set")
7473 (set_attr "enabled_for_short_it" "yes,yes,no,*")
7474 (set_attr "arch" "t2,t2,t2,a")
7475 (set_attr "length" "6,6,10,8")
7476 (set_attr "type" "multiple")]
7479 (define_insn "*arm_cmpdi_zero"
7480 [(set (reg:CC_Z CC_REGNUM)
7481 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7483 (clobber (match_scratch:SI 1 "=r"))]
7485 "orrs%?\\t%1, %Q0, %R0"
7486 [(set_attr "conds" "set")
7487 (set_attr "type" "logics_reg")]
7490 ; This insn allows redundant compares to be removed by cse, nothing should
7491 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7492 ; is deleted later on. The match_dup will match the mode here, so that
7493 ; mode changes of the condition codes aren't lost by this even though we don't
7494 ; specify what they are.
7496 (define_insn "*deleted_compare"
7497 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7499 "\\t%@ deleted compare"
7500 [(set_attr "conds" "set")
7501 (set_attr "length" "0")
7502 (set_attr "type" "no_insn")]
7506 ;; Conditional branch insns
7508 (define_expand "cbranch_cc"
7510 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7511 (match_operand 2 "" "")])
7512 (label_ref (match_operand 3 "" ""))
7515 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7516 operands[1], operands[2], NULL_RTX);
7517 operands[2] = const0_rtx;"
7521 ;; Patterns to match conditional branch insns.
7524 (define_insn "arm_cond_branch"
7526 (if_then_else (match_operator 1 "arm_comparison_operator"
7527 [(match_operand 2 "cc_register" "") (const_int 0)])
7528 (label_ref (match_operand 0 "" ""))
7532 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7534 arm_ccfsm_state += 2;
7537 return \"b%d1\\t%l0\";
7539 [(set_attr "conds" "use")
7540 (set_attr "type" "branch")
7541 (set (attr "length")
7543 (and (match_test "TARGET_THUMB2")
7544 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7545 (le (minus (match_dup 0) (pc)) (const_int 256))))
7550 (define_insn "*arm_cond_branch_reversed"
7552 (if_then_else (match_operator 1 "arm_comparison_operator"
7553 [(match_operand 2 "cc_register" "") (const_int 0)])
7555 (label_ref (match_operand 0 "" ""))))]
7558 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7560 arm_ccfsm_state += 2;
7563 return \"b%D1\\t%l0\";
7565 [(set_attr "conds" "use")
7566 (set_attr "type" "branch")
7567 (set (attr "length")
7569 (and (match_test "TARGET_THUMB2")
7570 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7571 (le (minus (match_dup 0) (pc)) (const_int 256))))
7580 (define_expand "cstore_cc"
7581 [(set (match_operand:SI 0 "s_register_operand" "")
7582 (match_operator:SI 1 "" [(match_operand 2 "" "")
7583 (match_operand 3 "" "")]))]
7585 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7586 operands[2], operands[3], NULL_RTX);
7587 operands[3] = const0_rtx;"
7590 (define_insn_and_split "*mov_scc"
7591 [(set (match_operand:SI 0 "s_register_operand" "=r")
7592 (match_operator:SI 1 "arm_comparison_operator_mode"
7593 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7595 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7598 (if_then_else:SI (match_dup 1)
7602 [(set_attr "conds" "use")
7603 (set_attr "length" "8")
7604 (set_attr "type" "multiple")]
7607 (define_insn_and_split "*mov_negscc"
7608 [(set (match_operand:SI 0 "s_register_operand" "=r")
7609 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7610 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7612 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7615 (if_then_else:SI (match_dup 1)
7619 operands[3] = GEN_INT (~0);
7621 [(set_attr "conds" "use")
7622 (set_attr "length" "8")
7623 (set_attr "type" "multiple")]
7626 (define_insn_and_split "*mov_notscc"
7627 [(set (match_operand:SI 0 "s_register_operand" "=r")
7628 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7629 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7631 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7634 (if_then_else:SI (match_dup 1)
7638 operands[3] = GEN_INT (~1);
7639 operands[4] = GEN_INT (~0);
7641 [(set_attr "conds" "use")
7642 (set_attr "length" "8")
7643 (set_attr "type" "multiple")]
7646 (define_expand "cstoresi4"
7647 [(set (match_operand:SI 0 "s_register_operand" "")
7648 (match_operator:SI 1 "expandable_comparison_operator"
7649 [(match_operand:SI 2 "s_register_operand" "")
7650 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7651 "TARGET_32BIT || TARGET_THUMB1"
7653 rtx op3, scratch, scratch2;
7657 if (!arm_add_operand (operands[3], SImode))
7658 operands[3] = force_reg (SImode, operands[3]);
7659 emit_insn (gen_cstore_cc (operands[0], operands[1],
7660 operands[2], operands[3]));
7664 if (operands[3] == const0_rtx)
7666 switch (GET_CODE (operands[1]))
7669 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7673 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7677 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7678 NULL_RTX, 0, OPTAB_WIDEN);
7679 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7680 NULL_RTX, 0, OPTAB_WIDEN);
7681 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7682 operands[0], 1, OPTAB_WIDEN);
7686 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7688 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7689 NULL_RTX, 1, OPTAB_WIDEN);
7693 scratch = expand_binop (SImode, ashr_optab, operands[2],
7694 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7695 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7696 NULL_RTX, 0, OPTAB_WIDEN);
7697 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7701 /* LT is handled by generic code. No need for unsigned with 0. */
7708 switch (GET_CODE (operands[1]))
7711 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7712 NULL_RTX, 0, OPTAB_WIDEN);
7713 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7717 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7718 NULL_RTX, 0, OPTAB_WIDEN);
7719 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7723 op3 = force_reg (SImode, operands[3]);
7725 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7726 NULL_RTX, 1, OPTAB_WIDEN);
7727 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7728 NULL_RTX, 0, OPTAB_WIDEN);
7729 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7735 if (!thumb1_cmp_operand (op3, SImode))
7736 op3 = force_reg (SImode, op3);
7737 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7738 NULL_RTX, 0, OPTAB_WIDEN);
7739 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7740 NULL_RTX, 1, OPTAB_WIDEN);
7741 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7746 op3 = force_reg (SImode, operands[3]);
7747 scratch = force_reg (SImode, const0_rtx);
7748 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7754 if (!thumb1_cmp_operand (op3, SImode))
7755 op3 = force_reg (SImode, op3);
7756 scratch = force_reg (SImode, const0_rtx);
7757 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7763 if (!thumb1_cmp_operand (op3, SImode))
7764 op3 = force_reg (SImode, op3);
7765 scratch = gen_reg_rtx (SImode);
7766 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7770 op3 = force_reg (SImode, operands[3]);
7771 scratch = gen_reg_rtx (SImode);
7772 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7775 /* No good sequences for GT, LT. */
7782 (define_expand "cstorehf4"
7783 [(set (match_operand:SI 0 "s_register_operand")
7784 (match_operator:SI 1 "expandable_comparison_operator"
7785 [(match_operand:HF 2 "s_register_operand")
7786 (match_operand:HF 3 "vfp_compare_operand")]))]
7787 "TARGET_VFP_FP16INST"
7789 if (!arm_validize_comparison (&operands[1],
7794 emit_insn (gen_cstore_cc (operands[0], operands[1],
7795 operands[2], operands[3]));
7800 (define_expand "cstoresf4"
7801 [(set (match_operand:SI 0 "s_register_operand" "")
7802 (match_operator:SI 1 "expandable_comparison_operator"
7803 [(match_operand:SF 2 "s_register_operand" "")
7804 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7805 "TARGET_32BIT && TARGET_HARD_FLOAT"
7806 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7807 operands[2], operands[3])); DONE;"
7810 (define_expand "cstoredf4"
7811 [(set (match_operand:SI 0 "s_register_operand" "")
7812 (match_operator:SI 1 "expandable_comparison_operator"
7813 [(match_operand:DF 2 "s_register_operand" "")
7814 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7815 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7816 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7817 operands[2], operands[3])); DONE;"
7820 (define_expand "cstoredi4"
7821 [(set (match_operand:SI 0 "s_register_operand" "")
7822 (match_operator:SI 1 "expandable_comparison_operator"
7823 [(match_operand:DI 2 "s_register_operand" "")
7824 (match_operand:DI 3 "cmpdi_operand" "")]))]
7827 if (!arm_validize_comparison (&operands[1],
7831 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7838 ;; Conditional move insns
7840 (define_expand "movsicc"
7841 [(set (match_operand:SI 0 "s_register_operand" "")
7842 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7843 (match_operand:SI 2 "arm_not_operand" "")
7844 (match_operand:SI 3 "arm_not_operand" "")))]
7851 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7852 &XEXP (operands[1], 1)))
7855 code = GET_CODE (operands[1]);
7856 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7857 XEXP (operands[1], 1), NULL_RTX);
7858 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7862 (define_expand "movhfcc"
7863 [(set (match_operand:HF 0 "s_register_operand")
7864 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7865 (match_operand:HF 2 "s_register_operand")
7866 (match_operand:HF 3 "s_register_operand")))]
7867 "TARGET_VFP_FP16INST"
7870 enum rtx_code code = GET_CODE (operands[1]);
7873 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7874 &XEXP (operands[1], 1)))
7877 code = GET_CODE (operands[1]);
7878 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7879 XEXP (operands[1], 1), NULL_RTX);
7880 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7884 (define_expand "movsfcc"
7885 [(set (match_operand:SF 0 "s_register_operand" "")
7886 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7887 (match_operand:SF 2 "s_register_operand" "")
7888 (match_operand:SF 3 "s_register_operand" "")))]
7889 "TARGET_32BIT && TARGET_HARD_FLOAT"
7892 enum rtx_code code = GET_CODE (operands[1]);
7895 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7896 &XEXP (operands[1], 1)))
7899 code = GET_CODE (operands[1]);
7900 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7901 XEXP (operands[1], 1), NULL_RTX);
7902 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7906 (define_expand "movdfcc"
7907 [(set (match_operand:DF 0 "s_register_operand" "")
7908 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7909 (match_operand:DF 2 "s_register_operand" "")
7910 (match_operand:DF 3 "s_register_operand" "")))]
7911 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7914 enum rtx_code code = GET_CODE (operands[1]);
7917 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7918 &XEXP (operands[1], 1)))
7920 code = GET_CODE (operands[1]);
7921 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7922 XEXP (operands[1], 1), NULL_RTX);
7923 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7927 (define_insn "*cmov<mode>"
7928 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7929 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7930 [(match_operand 2 "cc_register" "") (const_int 0)])
7931 (match_operand:SDF 3 "s_register_operand"
7933 (match_operand:SDF 4 "s_register_operand"
7934 "<F_constraint>")))]
7935 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7938 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7945 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7950 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7956 [(set_attr "conds" "use")
7957 (set_attr "type" "fcsel")]
7960 (define_insn "*cmovhf"
7961 [(set (match_operand:HF 0 "s_register_operand" "=t")
7962 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7963 [(match_operand 2 "cc_register" "") (const_int 0)])
7964 (match_operand:HF 3 "s_register_operand" "t")
7965 (match_operand:HF 4 "s_register_operand" "t")))]
7966 "TARGET_VFP_FP16INST"
7969 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7976 return \"vsel%d1.f16\\t%0, %3, %4\";
7981 return \"vsel%D1.f16\\t%0, %4, %3\";
7987 [(set_attr "conds" "use")
7988 (set_attr "type" "fcsel")]
7991 (define_insn_and_split "*movsicc_insn"
7992 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7994 (match_operator 3 "arm_comparison_operator"
7995 [(match_operand 4 "cc_register" "") (const_int 0)])
7996 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7997 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8008 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8009 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8010 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8011 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8012 "&& reload_completed"
8015 enum rtx_code rev_code;
8019 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8021 gen_rtx_SET (operands[0], operands[1])));
8023 rev_code = GET_CODE (operands[3]);
8024 mode = GET_MODE (operands[4]);
8025 if (mode == CCFPmode || mode == CCFPEmode)
8026 rev_code = reverse_condition_maybe_unordered (rev_code);
8028 rev_code = reverse_condition (rev_code);
8030 rev_cond = gen_rtx_fmt_ee (rev_code,
8034 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8036 gen_rtx_SET (operands[0], operands[2])));
8039 [(set_attr "length" "4,4,4,4,8,8,8,8")
8040 (set_attr "conds" "use")
8041 (set_attr_alternative "type"
8042 [(if_then_else (match_operand 2 "const_int_operand" "")
8043 (const_string "mov_imm")
8044 (const_string "mov_reg"))
8045 (const_string "mvn_imm")
8046 (if_then_else (match_operand 1 "const_int_operand" "")
8047 (const_string "mov_imm")
8048 (const_string "mov_reg"))
8049 (const_string "mvn_imm")
8050 (const_string "multiple")
8051 (const_string "multiple")
8052 (const_string "multiple")
8053 (const_string "multiple")])]
8056 (define_insn "*movsfcc_soft_insn"
8057 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8058 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8059 [(match_operand 4 "cc_register" "") (const_int 0)])
8060 (match_operand:SF 1 "s_register_operand" "0,r")
8061 (match_operand:SF 2 "s_register_operand" "r,0")))]
8062 "TARGET_ARM && TARGET_SOFT_FLOAT"
8066 [(set_attr "conds" "use")
8067 (set_attr "type" "mov_reg")]
8071 ;; Jump and linkage insns
8073 (define_expand "jump"
8075 (label_ref (match_operand 0 "" "")))]
8080 (define_insn "*arm_jump"
8082 (label_ref (match_operand 0 "" "")))]
8086 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8088 arm_ccfsm_state += 2;
8091 return \"b%?\\t%l0\";
8094 [(set_attr "predicable" "yes")
8095 (set (attr "length")
8097 (and (match_test "TARGET_THUMB2")
8098 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8099 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8102 (set_attr "type" "branch")]
8105 (define_expand "call"
8106 [(parallel [(call (match_operand 0 "memory_operand" "")
8107 (match_operand 1 "general_operand" ""))
8108 (use (match_operand 2 "" ""))
8109 (clobber (reg:SI LR_REGNUM))])]
8114 tree addr = MEM_EXPR (operands[0]);
8116 /* In an untyped call, we can get NULL for operand 2. */
8117 if (operands[2] == NULL_RTX)
8118 operands[2] = const0_rtx;
8120 /* Decide if we should generate indirect calls by loading the
8121 32-bit address of the callee into a register before performing the
8123 callee = XEXP (operands[0], 0);
8124 if (GET_CODE (callee) == SYMBOL_REF
8125 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8127 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8129 if (detect_cmse_nonsecure_call (addr))
8131 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8133 emit_call_insn (pat);
8137 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8138 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8144 (define_expand "call_internal"
8145 [(parallel [(call (match_operand 0 "memory_operand" "")
8146 (match_operand 1 "general_operand" ""))
8147 (use (match_operand 2 "" ""))
8148 (clobber (reg:SI LR_REGNUM))])])
8150 (define_expand "nonsecure_call_internal"
8151 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8152 UNSPEC_NONSECURE_MEM)
8153 (match_operand 1 "general_operand" ""))
8154 (use (match_operand 2 "" ""))
8155 (clobber (reg:SI LR_REGNUM))])]
8160 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8161 gen_rtx_REG (SImode, R4_REGNUM),
8164 operands[0] = replace_equiv_address (operands[0], tmp);
8167 (define_insn "*call_reg_armv5"
8168 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8169 (match_operand 1 "" ""))
8170 (use (match_operand 2 "" ""))
8171 (clobber (reg:SI LR_REGNUM))]
8172 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8174 [(set_attr "type" "call")]
8177 (define_insn "*call_reg_arm"
8178 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8179 (match_operand 1 "" ""))
8180 (use (match_operand 2 "" ""))
8181 (clobber (reg:SI LR_REGNUM))]
8182 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8184 return output_call (operands);
8186 ;; length is worst case, normally it is only two
8187 [(set_attr "length" "12")
8188 (set_attr "type" "call")]
8192 (define_expand "call_value"
8193 [(parallel [(set (match_operand 0 "" "")
8194 (call (match_operand 1 "memory_operand" "")
8195 (match_operand 2 "general_operand" "")))
8196 (use (match_operand 3 "" ""))
8197 (clobber (reg:SI LR_REGNUM))])]
8202 tree addr = MEM_EXPR (operands[1]);
8204 /* In an untyped call, we can get NULL for operand 2. */
8205 if (operands[3] == 0)
8206 operands[3] = const0_rtx;
8208 /* Decide if we should generate indirect calls by loading the
8209 32-bit address of the callee into a register before performing the
8211 callee = XEXP (operands[1], 0);
8212 if (GET_CODE (callee) == SYMBOL_REF
8213 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8215 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8217 if (detect_cmse_nonsecure_call (addr))
8219 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8220 operands[2], operands[3]);
8221 emit_call_insn (pat);
8225 pat = gen_call_value_internal (operands[0], operands[1],
8226 operands[2], operands[3]);
8227 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8233 (define_expand "call_value_internal"
8234 [(parallel [(set (match_operand 0 "" "")
8235 (call (match_operand 1 "memory_operand" "")
8236 (match_operand 2 "general_operand" "")))
8237 (use (match_operand 3 "" ""))
8238 (clobber (reg:SI LR_REGNUM))])])
8240 (define_expand "nonsecure_call_value_internal"
8241 [(parallel [(set (match_operand 0 "" "")
8242 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8243 UNSPEC_NONSECURE_MEM)
8244 (match_operand 2 "general_operand" "")))
8245 (use (match_operand 3 "" ""))
8246 (clobber (reg:SI LR_REGNUM))])]
8251 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8252 gen_rtx_REG (SImode, R4_REGNUM),
8255 operands[1] = replace_equiv_address (operands[1], tmp);
8258 (define_insn "*call_value_reg_armv5"
8259 [(set (match_operand 0 "" "")
8260 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8261 (match_operand 2 "" "")))
8262 (use (match_operand 3 "" ""))
8263 (clobber (reg:SI LR_REGNUM))]
8264 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8266 [(set_attr "type" "call")]
8269 (define_insn "*call_value_reg_arm"
8270 [(set (match_operand 0 "" "")
8271 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8272 (match_operand 2 "" "")))
8273 (use (match_operand 3 "" ""))
8274 (clobber (reg:SI LR_REGNUM))]
8275 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8277 return output_call (&operands[1]);
8279 [(set_attr "length" "12")
8280 (set_attr "type" "call")]
8283 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8284 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8286 (define_insn "*call_symbol"
8287 [(call (mem:SI (match_operand:SI 0 "" ""))
8288 (match_operand 1 "" ""))
8289 (use (match_operand 2 "" ""))
8290 (clobber (reg:SI LR_REGNUM))]
8292 && !SIBLING_CALL_P (insn)
8293 && (GET_CODE (operands[0]) == SYMBOL_REF)
8294 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8297 rtx op = operands[0];
8299 /* Switch mode now when possible. */
8300 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8301 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8302 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8304 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8306 [(set_attr "type" "call")]
8309 (define_insn "*call_value_symbol"
8310 [(set (match_operand 0 "" "")
8311 (call (mem:SI (match_operand:SI 1 "" ""))
8312 (match_operand:SI 2 "" "")))
8313 (use (match_operand 3 "" ""))
8314 (clobber (reg:SI LR_REGNUM))]
8316 && !SIBLING_CALL_P (insn)
8317 && (GET_CODE (operands[1]) == SYMBOL_REF)
8318 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8321 rtx op = operands[1];
8323 /* Switch mode now when possible. */
8324 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8325 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8326 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8328 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8330 [(set_attr "type" "call")]
8333 (define_expand "sibcall_internal"
8334 [(parallel [(call (match_operand 0 "memory_operand" "")
8335 (match_operand 1 "general_operand" ""))
8337 (use (match_operand 2 "" ""))])])
8339 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8340 (define_expand "sibcall"
8341 [(parallel [(call (match_operand 0 "memory_operand" "")
8342 (match_operand 1 "general_operand" ""))
8344 (use (match_operand 2 "" ""))])]
8350 if ((!REG_P (XEXP (operands[0], 0))
8351 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8352 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8353 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8354 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8356 if (operands[2] == NULL_RTX)
8357 operands[2] = const0_rtx;
8359 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8360 arm_emit_call_insn (pat, operands[0], true);
8365 (define_expand "sibcall_value_internal"
8366 [(parallel [(set (match_operand 0 "" "")
8367 (call (match_operand 1 "memory_operand" "")
8368 (match_operand 2 "general_operand" "")))
8370 (use (match_operand 3 "" ""))])])
8372 (define_expand "sibcall_value"
8373 [(parallel [(set (match_operand 0 "" "")
8374 (call (match_operand 1 "memory_operand" "")
8375 (match_operand 2 "general_operand" "")))
8377 (use (match_operand 3 "" ""))])]
8383 if ((!REG_P (XEXP (operands[1], 0))
8384 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8385 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8386 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8387 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8389 if (operands[3] == NULL_RTX)
8390 operands[3] = const0_rtx;
8392 pat = gen_sibcall_value_internal (operands[0], operands[1],
8393 operands[2], operands[3]);
8394 arm_emit_call_insn (pat, operands[1], true);
8399 (define_insn "*sibcall_insn"
8400 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8401 (match_operand 1 "" ""))
8403 (use (match_operand 2 "" ""))]
8404 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8406 if (which_alternative == 1)
8407 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8410 if (arm_arch5t || arm_arch4t)
8411 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8413 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8416 [(set_attr "type" "call")]
8419 (define_insn "*sibcall_value_insn"
8420 [(set (match_operand 0 "" "")
8421 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8422 (match_operand 2 "" "")))
8424 (use (match_operand 3 "" ""))]
8425 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8427 if (which_alternative == 1)
8428 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8431 if (arm_arch5t || arm_arch4t)
8432 return \"bx%?\\t%1\";
8434 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8437 [(set_attr "type" "call")]
8440 (define_expand "<return_str>return"
8442 "(TARGET_ARM || (TARGET_THUMB2
8443 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8444 && !IS_STACKALIGN (arm_current_func_type ())))
8445 <return_cond_false>"
8450 thumb2_expand_return (<return_simple_p>);
8457 ;; Often the return insn will be the same as loading from memory, so set attr
8458 (define_insn "*arm_return"
8460 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8463 if (arm_ccfsm_state == 2)
8465 arm_ccfsm_state += 2;
8468 return output_return_instruction (const_true_rtx, true, false, false);
8470 [(set_attr "type" "load_4")
8471 (set_attr "length" "12")
8472 (set_attr "predicable" "yes")]
8475 (define_insn "*cond_<return_str>return"
8477 (if_then_else (match_operator 0 "arm_comparison_operator"
8478 [(match_operand 1 "cc_register" "") (const_int 0)])
8481 "TARGET_ARM <return_cond_true>"
8484 if (arm_ccfsm_state == 2)
8486 arm_ccfsm_state += 2;
8489 return output_return_instruction (operands[0], true, false,
8492 [(set_attr "conds" "use")
8493 (set_attr "length" "12")
8494 (set_attr "type" "load_4")]
8497 (define_insn "*cond_<return_str>return_inverted"
8499 (if_then_else (match_operator 0 "arm_comparison_operator"
8500 [(match_operand 1 "cc_register" "") (const_int 0)])
8503 "TARGET_ARM <return_cond_true>"
8506 if (arm_ccfsm_state == 2)
8508 arm_ccfsm_state += 2;
8511 return output_return_instruction (operands[0], true, true,
8514 [(set_attr "conds" "use")
8515 (set_attr "length" "12")
8516 (set_attr "type" "load_4")]
8519 (define_insn "*arm_simple_return"
8524 if (arm_ccfsm_state == 2)
8526 arm_ccfsm_state += 2;
8529 return output_return_instruction (const_true_rtx, true, false, true);
8531 [(set_attr "type" "branch")
8532 (set_attr "length" "4")
8533 (set_attr "predicable" "yes")]
8536 ;; Generate a sequence of instructions to determine if the processor is
8537 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8540 (define_expand "return_addr_mask"
8542 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8544 (set (match_operand:SI 0 "s_register_operand" "")
8545 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8547 (const_int 67108860)))] ; 0x03fffffc
8550 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8553 (define_insn "*check_arch2"
8554 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8555 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8558 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8559 [(set_attr "length" "8")
8560 (set_attr "conds" "set")
8561 (set_attr "type" "multiple")]
8564 ;; Call subroutine returning any type.
8566 (define_expand "untyped_call"
8567 [(parallel [(call (match_operand 0 "" "")
8569 (match_operand 1 "" "")
8570 (match_operand 2 "" "")])]
8575 rtx par = gen_rtx_PARALLEL (VOIDmode,
8576 rtvec_alloc (XVECLEN (operands[2], 0)));
8577 rtx addr = gen_reg_rtx (Pmode);
8581 emit_move_insn (addr, XEXP (operands[1], 0));
8582 mem = change_address (operands[1], BLKmode, addr);
8584 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8586 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8588 /* Default code only uses r0 as a return value, but we could
8589 be using anything up to 4 registers. */
8590 if (REGNO (src) == R0_REGNUM)
8591 src = gen_rtx_REG (TImode, R0_REGNUM);
8593 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8595 size += GET_MODE_SIZE (GET_MODE (src));
8598 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8602 for (i = 0; i < XVECLEN (par, 0); i++)
8604 HOST_WIDE_INT offset = 0;
8605 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8608 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8610 mem = change_address (mem, GET_MODE (reg), NULL);
8611 if (REGNO (reg) == R0_REGNUM)
8613 /* On thumb we have to use a write-back instruction. */
8614 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8615 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8616 size = TARGET_ARM ? 16 : 0;
8620 emit_move_insn (mem, reg);
8621 size = GET_MODE_SIZE (GET_MODE (reg));
8625 /* The optimizer does not know that the call sets the function value
8626 registers we stored in the result block. We avoid problems by
8627 claiming that all hard registers are used and clobbered at this
8629 emit_insn (gen_blockage ());
8635 (define_expand "untyped_return"
8636 [(match_operand:BLK 0 "memory_operand" "")
8637 (match_operand 1 "" "")]
8642 rtx addr = gen_reg_rtx (Pmode);
8646 emit_move_insn (addr, XEXP (operands[0], 0));
8647 mem = change_address (operands[0], BLKmode, addr);
8649 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8651 HOST_WIDE_INT offset = 0;
8652 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8655 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8657 mem = change_address (mem, GET_MODE (reg), NULL);
8658 if (REGNO (reg) == R0_REGNUM)
8660 /* On thumb we have to use a write-back instruction. */
8661 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8662 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8663 size = TARGET_ARM ? 16 : 0;
8667 emit_move_insn (reg, mem);
8668 size = GET_MODE_SIZE (GET_MODE (reg));
8672 /* Emit USE insns before the return. */
8673 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8674 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8676 /* Construct the return. */
8677 expand_naked_return ();
8683 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8684 ;; all of memory. This blocks insns from being moved across this point.
8686 (define_insn "blockage"
8687 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8690 [(set_attr "length" "0")
8691 (set_attr "type" "block")]
8694 ;; Since we hard code r0 here use the 'o' constraint to prevent
8695 ;; provoking undefined behaviour in the hardware with putting out
8696 ;; auto-increment operations with potentially r0 as the base register.
8697 (define_insn "probe_stack"
8698 [(set (match_operand:SI 0 "memory_operand" "=o")
8699 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8702 [(set_attr "type" "store_4")
8703 (set_attr "predicable" "yes")]
8706 (define_insn "probe_stack_range"
8707 [(set (match_operand:SI 0 "register_operand" "=r")
8708 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8709 (match_operand:SI 2 "register_operand" "r")]
8710 VUNSPEC_PROBE_STACK_RANGE))]
8713 return output_probe_stack_range (operands[0], operands[2]);
8715 [(set_attr "type" "multiple")
8716 (set_attr "conds" "clob")]
8719 ;; Named patterns for stack smashing protection.
8720 (define_expand "stack_protect_combined_set"
8722 [(set (match_operand:SI 0 "memory_operand" "")
8723 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8725 (clobber (match_scratch:SI 2 ""))
8726 (clobber (match_scratch:SI 3 ""))])]
8731 ;; Use a separate insn from the above expand to be able to have the mem outside
8732 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8733 ;; try to reload the guard since we need to control how PIC access is done in
8734 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8735 ;; legitimize_pic_address ()).
8736 (define_insn_and_split "*stack_protect_combined_set_insn"
8737 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8738 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8740 (clobber (match_scratch:SI 2 "=&l,&r"))
8741 (clobber (match_scratch:SI 3 "=&l,&r"))]
8745 [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))]
8747 (clobber (match_dup 2))])]
8752 /* Forces recomputing of GOT base now. */
8753 legitimize_pic_address (operands[1], SImode, operands[2], operands[3],
8754 true /*compute_now*/);
8758 if (address_operand (operands[1], SImode))
8759 operands[2] = operands[1];
8762 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8763 emit_move_insn (operands[2], mem);
8767 [(set_attr "arch" "t1,32")]
8770 (define_insn "*stack_protect_set_insn"
8771 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8772 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))]
8774 (clobber (match_dup 1))]
8777 ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1,#0
8778 ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1,#0"
8779 [(set_attr "length" "8,12")
8780 (set_attr "conds" "clob,nocond")
8781 (set_attr "type" "multiple")
8782 (set_attr "arch" "t1,32")]
8785 (define_expand "stack_protect_combined_test"
8789 (eq (match_operand:SI 0 "memory_operand" "")
8790 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8792 (label_ref (match_operand 2))
8794 (clobber (match_scratch:SI 3 ""))
8795 (clobber (match_scratch:SI 4 ""))
8796 (clobber (reg:CC CC_REGNUM))])]
8801 ;; Use a separate insn from the above expand to be able to have the mem outside
8802 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8803 ;; try to reload the guard since we need to control how PIC access is done in
8804 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8805 ;; legitimize_pic_address ()).
8806 (define_insn_and_split "*stack_protect_combined_test_insn"
8809 (eq (match_operand:SI 0 "memory_operand" "m,m")
8810 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8812 (label_ref (match_operand 2))
8814 (clobber (match_scratch:SI 3 "=&l,&r"))
8815 (clobber (match_scratch:SI 4 "=&l,&r"))
8816 (clobber (reg:CC CC_REGNUM))]
8826 /* Forces recomputing of GOT base now. */
8827 legitimize_pic_address (operands[1], SImode, operands[3], operands[4],
8828 true /*compute_now*/);
8832 if (address_operand (operands[1], SImode))
8833 operands[3] = operands[1];
8836 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8837 emit_move_insn (operands[3], mem);
8842 emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0],
8844 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
8845 eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx);
8846 emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg));
8850 emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0],
8852 eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
8853 emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx,
8858 [(set_attr "arch" "t1,32")]
8861 (define_insn "arm_stack_protect_test_insn"
8862 [(set (reg:CC_Z CC_REGNUM)
8863 (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m")
8864 (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))]
8867 (clobber (match_operand:SI 0 "register_operand" "=&l,&r"))
8868 (clobber (match_dup 2))]
8870 "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0"
8871 [(set_attr "length" "8,12")
8872 (set_attr "conds" "set")
8873 (set_attr "type" "multiple")
8874 (set_attr "arch" "t,32")]
8877 (define_expand "casesi"
8878 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8879 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8880 (match_operand:SI 2 "const_int_operand" "") ; total range
8881 (match_operand:SI 3 "" "") ; table label
8882 (match_operand:SI 4 "" "")] ; Out of range label
8883 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8886 enum insn_code code;
8887 if (operands[1] != const0_rtx)
8889 rtx reg = gen_reg_rtx (SImode);
8891 emit_insn (gen_addsi3 (reg, operands[0],
8892 gen_int_mode (-INTVAL (operands[1]),
8898 code = CODE_FOR_arm_casesi_internal;
8899 else if (TARGET_THUMB1)
8900 code = CODE_FOR_thumb1_casesi_internal_pic;
8902 code = CODE_FOR_thumb2_casesi_internal_pic;
8904 code = CODE_FOR_thumb2_casesi_internal;
8906 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8907 operands[2] = force_reg (SImode, operands[2]);
8909 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8910 operands[3], operands[4]));
8915 ;; The USE in this pattern is needed to tell flow analysis that this is
8916 ;; a CASESI insn. It has no other purpose.
8917 (define_insn "arm_casesi_internal"
8918 [(parallel [(set (pc)
8920 (leu (match_operand:SI 0 "s_register_operand" "r")
8921 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8922 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8923 (label_ref (match_operand 2 "" ""))))
8924 (label_ref (match_operand 3 "" ""))))
8925 (clobber (reg:CC CC_REGNUM))
8926 (use (label_ref (match_dup 2)))])]
8930 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8931 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8933 [(set_attr "conds" "clob")
8934 (set_attr "length" "12")
8935 (set_attr "type" "multiple")]
8938 (define_expand "indirect_jump"
8940 (match_operand:SI 0 "s_register_operand" ""))]
8943 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8944 address and use bx. */
8948 tmp = gen_reg_rtx (SImode);
8949 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8955 ;; NB Never uses BX.
8956 (define_insn "*arm_indirect_jump"
8958 (match_operand:SI 0 "s_register_operand" "r"))]
8960 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8961 [(set_attr "predicable" "yes")
8962 (set_attr "type" "branch")]
8965 (define_insn "*load_indirect_jump"
8967 (match_operand:SI 0 "memory_operand" "m"))]
8969 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8970 [(set_attr "type" "load_4")
8971 (set_attr "pool_range" "4096")
8972 (set_attr "neg_pool_range" "4084")
8973 (set_attr "predicable" "yes")]
8983 [(set (attr "length")
8984 (if_then_else (eq_attr "is_thumb" "yes")
8987 (set_attr "type" "mov_reg")]
8991 [(trap_if (const_int 1) (const_int 0))]
8995 return \".inst\\t0xe7f000f0\";
8997 return \".inst\\t0xdeff\";
8999 [(set (attr "length")
9000 (if_then_else (eq_attr "is_thumb" "yes")
9003 (set_attr "type" "trap")
9004 (set_attr "conds" "unconditional")]
9008 ;; Patterns to allow combination of arithmetic, cond code and shifts
9010 (define_insn "*<arith_shift_insn>_multsi"
9011 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9013 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
9014 (match_operand:SI 3 "power_of_two_operand" ""))
9015 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
9017 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
9018 [(set_attr "predicable" "yes")
9019 (set_attr "shift" "2")
9020 (set_attr "arch" "a,t2")
9021 (set_attr "type" "alu_shift_imm")])
9023 (define_insn "*<arith_shift_insn>_shiftsi"
9024 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9026 (match_operator:SI 2 "shift_nomul_operator"
9027 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9028 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
9029 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
9030 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
9031 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
9032 [(set_attr "predicable" "yes")
9033 (set_attr "shift" "3")
9034 (set_attr "arch" "a,t2,a")
9035 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9038 [(set (match_operand:SI 0 "s_register_operand" "")
9039 (match_operator:SI 1 "shiftable_operator"
9040 [(match_operator:SI 2 "shiftable_operator"
9041 [(match_operator:SI 3 "shift_operator"
9042 [(match_operand:SI 4 "s_register_operand" "")
9043 (match_operand:SI 5 "reg_or_int_operand" "")])
9044 (match_operand:SI 6 "s_register_operand" "")])
9045 (match_operand:SI 7 "arm_rhs_operand" "")]))
9046 (clobber (match_operand:SI 8 "s_register_operand" ""))]
9049 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9052 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
9055 (define_insn "*arith_shiftsi_compare0"
9056 [(set (reg:CC_NOOV CC_REGNUM)
9058 (match_operator:SI 1 "shiftable_operator"
9059 [(match_operator:SI 3 "shift_operator"
9060 [(match_operand:SI 4 "s_register_operand" "r,r")
9061 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9062 (match_operand:SI 2 "s_register_operand" "r,r")])
9064 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9065 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9068 "%i1s%?\\t%0, %2, %4%S3"
9069 [(set_attr "conds" "set")
9070 (set_attr "shift" "4")
9071 (set_attr "arch" "32,a")
9072 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9074 (define_insn "*arith_shiftsi_compare0_scratch"
9075 [(set (reg:CC_NOOV CC_REGNUM)
9077 (match_operator:SI 1 "shiftable_operator"
9078 [(match_operator:SI 3 "shift_operator"
9079 [(match_operand:SI 4 "s_register_operand" "r,r")
9080 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9081 (match_operand:SI 2 "s_register_operand" "r,r")])
9083 (clobber (match_scratch:SI 0 "=r,r"))]
9085 "%i1s%?\\t%0, %2, %4%S3"
9086 [(set_attr "conds" "set")
9087 (set_attr "shift" "4")
9088 (set_attr "arch" "32,a")
9089 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9091 (define_insn "*sub_shiftsi"
9092 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9093 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9094 (match_operator:SI 2 "shift_operator"
9095 [(match_operand:SI 3 "s_register_operand" "r,r")
9096 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
9098 "sub%?\\t%0, %1, %3%S2"
9099 [(set_attr "predicable" "yes")
9100 (set_attr "predicable_short_it" "no")
9101 (set_attr "shift" "3")
9102 (set_attr "arch" "32,a")
9103 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9105 (define_insn "*sub_shiftsi_compare0"
9106 [(set (reg:CC_NOOV CC_REGNUM)
9108 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9109 (match_operator:SI 2 "shift_operator"
9110 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9111 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9113 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9114 (minus:SI (match_dup 1)
9115 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
9117 "subs%?\\t%0, %1, %3%S2"
9118 [(set_attr "conds" "set")
9119 (set_attr "shift" "3")
9120 (set_attr "arch" "32,a,a")
9121 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9123 (define_insn "*sub_shiftsi_compare0_scratch"
9124 [(set (reg:CC_NOOV CC_REGNUM)
9126 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9127 (match_operator:SI 2 "shift_operator"
9128 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9129 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9131 (clobber (match_scratch:SI 0 "=r,r,r"))]
9133 "subs%?\\t%0, %1, %3%S2"
9134 [(set_attr "conds" "set")
9135 (set_attr "shift" "3")
9136 (set_attr "arch" "32,a,a")
9137 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9140 (define_insn_and_split "*and_scc"
9141 [(set (match_operand:SI 0 "s_register_operand" "=r")
9142 (and:SI (match_operator:SI 1 "arm_comparison_operator"
9143 [(match_operand 2 "cc_register" "") (const_int 0)])
9144 (match_operand:SI 3 "s_register_operand" "r")))]
9146 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
9147 "&& reload_completed"
9148 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
9149 (cond_exec (match_dup 4) (set (match_dup 0)
9150 (and:SI (match_dup 3) (const_int 1))))]
9152 machine_mode mode = GET_MODE (operands[2]);
9153 enum rtx_code rc = GET_CODE (operands[1]);
9155 /* Note that operands[4] is the same as operands[1],
9156 but with VOIDmode as the result. */
9157 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9158 if (mode == CCFPmode || mode == CCFPEmode)
9159 rc = reverse_condition_maybe_unordered (rc);
9161 rc = reverse_condition (rc);
9162 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9164 [(set_attr "conds" "use")
9165 (set_attr "type" "multiple")
9166 (set_attr "length" "8")]
9169 (define_insn_and_split "*ior_scc"
9170 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9171 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
9172 [(match_operand 2 "cc_register" "") (const_int 0)])
9173 (match_operand:SI 3 "s_register_operand" "0,?r")))]
9178 "&& reload_completed
9179 && REGNO (operands [0]) != REGNO (operands[3])"
9180 ;; && which_alternative == 1
9181 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
9182 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
9183 (cond_exec (match_dup 4) (set (match_dup 0)
9184 (ior:SI (match_dup 3) (const_int 1))))]
9186 machine_mode mode = GET_MODE (operands[2]);
9187 enum rtx_code rc = GET_CODE (operands[1]);
9189 /* Note that operands[4] is the same as operands[1],
9190 but with VOIDmode as the result. */
9191 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9192 if (mode == CCFPmode || mode == CCFPEmode)
9193 rc = reverse_condition_maybe_unordered (rc);
9195 rc = reverse_condition (rc);
9196 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9198 [(set_attr "conds" "use")
9199 (set_attr "length" "4,8")
9200 (set_attr "type" "logic_imm,multiple")]
9203 ; A series of splitters for the compare_scc pattern below. Note that
9204 ; order is important.
9206 [(set (match_operand:SI 0 "s_register_operand" "")
9207 (lt:SI (match_operand:SI 1 "s_register_operand" "")
9209 (clobber (reg:CC CC_REGNUM))]
9210 "TARGET_32BIT && reload_completed"
9211 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9214 [(set (match_operand:SI 0 "s_register_operand" "")
9215 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9217 (clobber (reg:CC CC_REGNUM))]
9218 "TARGET_32BIT && reload_completed"
9219 [(set (match_dup 0) (not:SI (match_dup 1)))
9220 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9223 [(set (match_operand:SI 0 "s_register_operand" "")
9224 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9226 (clobber (reg:CC CC_REGNUM))]
9227 "arm_arch5t && TARGET_32BIT"
9228 [(set (match_dup 0) (clz:SI (match_dup 1)))
9229 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9233 [(set (match_operand:SI 0 "s_register_operand" "")
9234 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9236 (clobber (reg:CC CC_REGNUM))]
9237 "TARGET_32BIT && reload_completed"
9239 [(set (reg:CC CC_REGNUM)
9240 (compare:CC (const_int 1) (match_dup 1)))
9242 (minus:SI (const_int 1) (match_dup 1)))])
9243 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9244 (set (match_dup 0) (const_int 0)))])
9247 [(set (match_operand:SI 0 "s_register_operand" "")
9248 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9249 (match_operand:SI 2 "const_int_operand" "")))
9250 (clobber (reg:CC CC_REGNUM))]
9251 "TARGET_32BIT && reload_completed"
9253 [(set (reg:CC CC_REGNUM)
9254 (compare:CC (match_dup 1) (match_dup 2)))
9255 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9256 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9257 (set (match_dup 0) (const_int 1)))]
9259 operands[3] = GEN_INT (-INTVAL (operands[2]));
9263 [(set (match_operand:SI 0 "s_register_operand" "")
9264 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9265 (match_operand:SI 2 "arm_add_operand" "")))
9266 (clobber (reg:CC CC_REGNUM))]
9267 "TARGET_32BIT && reload_completed"
9269 [(set (reg:CC_NOOV CC_REGNUM)
9270 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9272 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9273 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9274 (set (match_dup 0) (const_int 1)))])
9276 (define_insn_and_split "*compare_scc"
9277 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9278 (match_operator:SI 1 "arm_comparison_operator"
9279 [(match_operand:SI 2 "s_register_operand" "r,r")
9280 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9281 (clobber (reg:CC CC_REGNUM))]
9284 "&& reload_completed"
9285 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9286 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9287 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9290 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9291 operands[2], operands[3]);
9292 enum rtx_code rc = GET_CODE (operands[1]);
9294 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9296 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9297 if (mode == CCFPmode || mode == CCFPEmode)
9298 rc = reverse_condition_maybe_unordered (rc);
9300 rc = reverse_condition (rc);
9301 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9303 [(set_attr "type" "multiple")]
9306 ;; Attempt to improve the sequence generated by the compare_scc splitters
9307 ;; not to use conditional execution.
9309 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9313 [(set (reg:CC CC_REGNUM)
9314 (compare:CC (match_operand:SI 1 "register_operand" "")
9316 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9317 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9318 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9319 (set (match_dup 0) (const_int 1)))]
9320 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9321 [(set (match_dup 0) (clz:SI (match_dup 1)))
9322 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9325 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9329 [(set (reg:CC CC_REGNUM)
9330 (compare:CC (match_operand:SI 1 "register_operand" "")
9332 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9333 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9334 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9335 (set (match_dup 0) (const_int 1)))
9336 (match_scratch:SI 2 "r")]
9337 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9339 [(set (reg:CC CC_REGNUM)
9340 (compare:CC (const_int 0) (match_dup 1)))
9341 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9343 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9344 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9347 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9348 ;; sub Rd, Reg1, reg2
9352 [(set (reg:CC CC_REGNUM)
9353 (compare:CC (match_operand:SI 1 "register_operand" "")
9354 (match_operand:SI 2 "arm_rhs_operand" "")))
9355 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9356 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9357 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9358 (set (match_dup 0) (const_int 1)))]
9359 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9360 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9361 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9362 (set (match_dup 0) (clz:SI (match_dup 0)))
9363 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9367 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9368 ;; sub T1, Reg1, reg2
9372 [(set (reg:CC CC_REGNUM)
9373 (compare:CC (match_operand:SI 1 "register_operand" "")
9374 (match_operand:SI 2 "arm_rhs_operand" "")))
9375 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9376 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9377 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9378 (set (match_dup 0) (const_int 1)))
9379 (match_scratch:SI 3 "r")]
9380 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9381 [(set (match_dup 3) (match_dup 4))
9383 [(set (reg:CC CC_REGNUM)
9384 (compare:CC (const_int 0) (match_dup 3)))
9385 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9387 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9388 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9390 if (CONST_INT_P (operands[2]))
9391 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9393 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9396 (define_insn "*cond_move"
9397 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9398 (if_then_else:SI (match_operator 3 "equality_operator"
9399 [(match_operator 4 "arm_comparison_operator"
9400 [(match_operand 5 "cc_register" "") (const_int 0)])
9402 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9403 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9406 if (GET_CODE (operands[3]) == NE)
9408 if (which_alternative != 1)
9409 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9410 if (which_alternative != 0)
9411 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9414 if (which_alternative != 0)
9415 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9416 if (which_alternative != 1)
9417 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9420 [(set_attr "conds" "use")
9421 (set_attr_alternative "type"
9422 [(if_then_else (match_operand 2 "const_int_operand" "")
9423 (const_string "mov_imm")
9424 (const_string "mov_reg"))
9425 (if_then_else (match_operand 1 "const_int_operand" "")
9426 (const_string "mov_imm")
9427 (const_string "mov_reg"))
9428 (const_string "multiple")])
9429 (set_attr "length" "4,4,8")]
9432 (define_insn "*cond_arith"
9433 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9434 (match_operator:SI 5 "shiftable_operator"
9435 [(match_operator:SI 4 "arm_comparison_operator"
9436 [(match_operand:SI 2 "s_register_operand" "r,r")
9437 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9438 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9439 (clobber (reg:CC CC_REGNUM))]
9442 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9443 return \"%i5\\t%0, %1, %2, lsr #31\";
9445 output_asm_insn (\"cmp\\t%2, %3\", operands);
9446 if (GET_CODE (operands[5]) == AND)
9447 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9448 else if (GET_CODE (operands[5]) == MINUS)
9449 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9450 else if (which_alternative != 0)
9451 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9452 return \"%i5%d4\\t%0, %1, #1\";
9454 [(set_attr "conds" "clob")
9455 (set_attr "length" "12")
9456 (set_attr "type" "multiple")]
9459 (define_insn "*cond_sub"
9460 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9461 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9462 (match_operator:SI 4 "arm_comparison_operator"
9463 [(match_operand:SI 2 "s_register_operand" "r,r")
9464 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9465 (clobber (reg:CC CC_REGNUM))]
9468 output_asm_insn (\"cmp\\t%2, %3\", operands);
9469 if (which_alternative != 0)
9470 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9471 return \"sub%d4\\t%0, %1, #1\";
9473 [(set_attr "conds" "clob")
9474 (set_attr "length" "8,12")
9475 (set_attr "type" "multiple")]
9478 (define_insn "*cmp_ite0"
9479 [(set (match_operand 6 "dominant_cc_register" "")
9482 (match_operator 4 "arm_comparison_operator"
9483 [(match_operand:SI 0 "s_register_operand"
9484 "l,l,l,r,r,r,r,r,r")
9485 (match_operand:SI 1 "arm_add_operand"
9486 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9487 (match_operator:SI 5 "arm_comparison_operator"
9488 [(match_operand:SI 2 "s_register_operand"
9489 "l,r,r,l,l,r,r,r,r")
9490 (match_operand:SI 3 "arm_add_operand"
9491 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9497 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9499 {\"cmp%d5\\t%0, %1\",
9500 \"cmp%d4\\t%2, %3\"},
9501 {\"cmn%d5\\t%0, #%n1\",
9502 \"cmp%d4\\t%2, %3\"},
9503 {\"cmp%d5\\t%0, %1\",
9504 \"cmn%d4\\t%2, #%n3\"},
9505 {\"cmn%d5\\t%0, #%n1\",
9506 \"cmn%d4\\t%2, #%n3\"}
9508 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9513 \"cmn\\t%0, #%n1\"},
9514 {\"cmn\\t%2, #%n3\",
9516 {\"cmn\\t%2, #%n3\",
9519 static const char * const ite[2] =
9524 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9525 CMP_CMP, CMN_CMP, CMP_CMP,
9526 CMN_CMP, CMP_CMN, CMN_CMN};
9528 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9530 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9531 if (TARGET_THUMB2) {
9532 output_asm_insn (ite[swap], operands);
9534 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9537 [(set_attr "conds" "set")
9538 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9539 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9540 (set_attr "type" "multiple")
9541 (set_attr_alternative "length"
9547 (if_then_else (eq_attr "is_thumb" "no")
9550 (if_then_else (eq_attr "is_thumb" "no")
9553 (if_then_else (eq_attr "is_thumb" "no")
9556 (if_then_else (eq_attr "is_thumb" "no")
9561 (define_insn "*cmp_ite1"
9562 [(set (match_operand 6 "dominant_cc_register" "")
9565 (match_operator 4 "arm_comparison_operator"
9566 [(match_operand:SI 0 "s_register_operand"
9567 "l,l,l,r,r,r,r,r,r")
9568 (match_operand:SI 1 "arm_add_operand"
9569 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9570 (match_operator:SI 5 "arm_comparison_operator"
9571 [(match_operand:SI 2 "s_register_operand"
9572 "l,r,r,l,l,r,r,r,r")
9573 (match_operand:SI 3 "arm_add_operand"
9574 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9580 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9584 {\"cmn\\t%0, #%n1\",
9587 \"cmn\\t%2, #%n3\"},
9588 {\"cmn\\t%0, #%n1\",
9591 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9593 {\"cmp%d4\\t%2, %3\",
9594 \"cmp%D5\\t%0, %1\"},
9595 {\"cmp%d4\\t%2, %3\",
9596 \"cmn%D5\\t%0, #%n1\"},
9597 {\"cmn%d4\\t%2, #%n3\",
9598 \"cmp%D5\\t%0, %1\"},
9599 {\"cmn%d4\\t%2, #%n3\",
9600 \"cmn%D5\\t%0, #%n1\"}
9602 static const char * const ite[2] =
9607 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9608 CMP_CMP, CMN_CMP, CMP_CMP,
9609 CMN_CMP, CMP_CMN, CMN_CMN};
9611 comparison_dominates_p (GET_CODE (operands[5]),
9612 reverse_condition (GET_CODE (operands[4])));
9614 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9615 if (TARGET_THUMB2) {
9616 output_asm_insn (ite[swap], operands);
9618 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9621 [(set_attr "conds" "set")
9622 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9623 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9624 (set_attr_alternative "length"
9630 (if_then_else (eq_attr "is_thumb" "no")
9633 (if_then_else (eq_attr "is_thumb" "no")
9636 (if_then_else (eq_attr "is_thumb" "no")
9639 (if_then_else (eq_attr "is_thumb" "no")
9642 (set_attr "type" "multiple")]
9645 (define_insn "*cmp_and"
9646 [(set (match_operand 6 "dominant_cc_register" "")
9649 (match_operator 4 "arm_comparison_operator"
9650 [(match_operand:SI 0 "s_register_operand"
9651 "l,l,l,r,r,r,r,r,r")
9652 (match_operand:SI 1 "arm_add_operand"
9653 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9654 (match_operator:SI 5 "arm_comparison_operator"
9655 [(match_operand:SI 2 "s_register_operand"
9656 "l,r,r,l,l,r,r,r,r")
9657 (match_operand:SI 3 "arm_add_operand"
9658 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9663 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9665 {\"cmp%d5\\t%0, %1\",
9666 \"cmp%d4\\t%2, %3\"},
9667 {\"cmn%d5\\t%0, #%n1\",
9668 \"cmp%d4\\t%2, %3\"},
9669 {\"cmp%d5\\t%0, %1\",
9670 \"cmn%d4\\t%2, #%n3\"},
9671 {\"cmn%d5\\t%0, #%n1\",
9672 \"cmn%d4\\t%2, #%n3\"}
9674 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9679 \"cmn\\t%0, #%n1\"},
9680 {\"cmn\\t%2, #%n3\",
9682 {\"cmn\\t%2, #%n3\",
9685 static const char *const ite[2] =
9690 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9691 CMP_CMP, CMN_CMP, CMP_CMP,
9692 CMN_CMP, CMP_CMN, CMN_CMN};
9694 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9696 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9697 if (TARGET_THUMB2) {
9698 output_asm_insn (ite[swap], operands);
9700 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9703 [(set_attr "conds" "set")
9704 (set_attr "predicable" "no")
9705 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9706 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9707 (set_attr_alternative "length"
9713 (if_then_else (eq_attr "is_thumb" "no")
9716 (if_then_else (eq_attr "is_thumb" "no")
9719 (if_then_else (eq_attr "is_thumb" "no")
9722 (if_then_else (eq_attr "is_thumb" "no")
9725 (set_attr "type" "multiple")]
9728 (define_insn "*cmp_ior"
9729 [(set (match_operand 6 "dominant_cc_register" "")
9732 (match_operator 4 "arm_comparison_operator"
9733 [(match_operand:SI 0 "s_register_operand"
9734 "l,l,l,r,r,r,r,r,r")
9735 (match_operand:SI 1 "arm_add_operand"
9736 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9737 (match_operator:SI 5 "arm_comparison_operator"
9738 [(match_operand:SI 2 "s_register_operand"
9739 "l,r,r,l,l,r,r,r,r")
9740 (match_operand:SI 3 "arm_add_operand"
9741 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9746 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9750 {\"cmn\\t%0, #%n1\",
9753 \"cmn\\t%2, #%n3\"},
9754 {\"cmn\\t%0, #%n1\",
9757 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9759 {\"cmp%D4\\t%2, %3\",
9760 \"cmp%D5\\t%0, %1\"},
9761 {\"cmp%D4\\t%2, %3\",
9762 \"cmn%D5\\t%0, #%n1\"},
9763 {\"cmn%D4\\t%2, #%n3\",
9764 \"cmp%D5\\t%0, %1\"},
9765 {\"cmn%D4\\t%2, #%n3\",
9766 \"cmn%D5\\t%0, #%n1\"}
9768 static const char *const ite[2] =
9773 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9774 CMP_CMP, CMN_CMP, CMP_CMP,
9775 CMN_CMP, CMP_CMN, CMN_CMN};
9777 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9779 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9780 if (TARGET_THUMB2) {
9781 output_asm_insn (ite[swap], operands);
9783 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9787 [(set_attr "conds" "set")
9788 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9789 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9790 (set_attr_alternative "length"
9796 (if_then_else (eq_attr "is_thumb" "no")
9799 (if_then_else (eq_attr "is_thumb" "no")
9802 (if_then_else (eq_attr "is_thumb" "no")
9805 (if_then_else (eq_attr "is_thumb" "no")
9808 (set_attr "type" "multiple")]
9811 (define_insn_and_split "*ior_scc_scc"
9812 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9813 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9814 [(match_operand:SI 1 "s_register_operand" "l,r")
9815 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9816 (match_operator:SI 6 "arm_comparison_operator"
9817 [(match_operand:SI 4 "s_register_operand" "l,r")
9818 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9819 (clobber (reg:CC CC_REGNUM))]
9821 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9824 "TARGET_32BIT && reload_completed"
9828 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9829 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9831 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9833 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9836 [(set_attr "conds" "clob")
9837 (set_attr "enabled_for_short_it" "yes,no")
9838 (set_attr "length" "16")
9839 (set_attr "type" "multiple")]
9842 ; If the above pattern is followed by a CMP insn, then the compare is
9843 ; redundant, since we can rework the conditional instruction that follows.
9844 (define_insn_and_split "*ior_scc_scc_cmp"
9845 [(set (match_operand 0 "dominant_cc_register" "")
9846 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9847 [(match_operand:SI 1 "s_register_operand" "l,r")
9848 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9849 (match_operator:SI 6 "arm_comparison_operator"
9850 [(match_operand:SI 4 "s_register_operand" "l,r")
9851 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9853 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9854 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9855 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9858 "TARGET_32BIT && reload_completed"
9862 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9863 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9865 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9867 [(set_attr "conds" "set")
9868 (set_attr "enabled_for_short_it" "yes,no")
9869 (set_attr "length" "16")
9870 (set_attr "type" "multiple")]
9873 (define_insn_and_split "*and_scc_scc"
9874 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9875 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9876 [(match_operand:SI 1 "s_register_operand" "l,r")
9877 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9878 (match_operator:SI 6 "arm_comparison_operator"
9879 [(match_operand:SI 4 "s_register_operand" "l,r")
9880 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9881 (clobber (reg:CC CC_REGNUM))]
9883 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9886 "TARGET_32BIT && reload_completed
9887 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9892 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9893 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9895 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9897 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9900 [(set_attr "conds" "clob")
9901 (set_attr "enabled_for_short_it" "yes,no")
9902 (set_attr "length" "16")
9903 (set_attr "type" "multiple")]
9906 ; If the above pattern is followed by a CMP insn, then the compare is
9907 ; redundant, since we can rework the conditional instruction that follows.
9908 (define_insn_and_split "*and_scc_scc_cmp"
9909 [(set (match_operand 0 "dominant_cc_register" "")
9910 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9911 [(match_operand:SI 1 "s_register_operand" "l,r")
9912 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9913 (match_operator:SI 6 "arm_comparison_operator"
9914 [(match_operand:SI 4 "s_register_operand" "l,r")
9915 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9917 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9918 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9919 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9922 "TARGET_32BIT && reload_completed"
9926 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9927 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9929 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9931 [(set_attr "conds" "set")
9932 (set_attr "enabled_for_short_it" "yes,no")
9933 (set_attr "length" "16")
9934 (set_attr "type" "multiple")]
9937 ;; If there is no dominance in the comparison, then we can still save an
9938 ;; instruction in the AND case, since we can know that the second compare
9939 ;; need only zero the value if false (if true, then the value is already
9941 (define_insn_and_split "*and_scc_scc_nodom"
9942 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9943 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9944 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9945 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9946 (match_operator:SI 6 "arm_comparison_operator"
9947 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9948 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9949 (clobber (reg:CC CC_REGNUM))]
9951 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9954 "TARGET_32BIT && reload_completed"
9955 [(parallel [(set (match_dup 0)
9956 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9957 (clobber (reg:CC CC_REGNUM))])
9958 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9960 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9963 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9964 operands[4], operands[5]),
9966 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9968 [(set_attr "conds" "clob")
9969 (set_attr "length" "20")
9970 (set_attr "type" "multiple")]
9974 [(set (reg:CC_NOOV CC_REGNUM)
9975 (compare:CC_NOOV (ior:SI
9976 (and:SI (match_operand:SI 0 "s_register_operand" "")
9978 (match_operator:SI 1 "arm_comparison_operator"
9979 [(match_operand:SI 2 "s_register_operand" "")
9980 (match_operand:SI 3 "arm_add_operand" "")]))
9982 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9985 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9987 (set (reg:CC_NOOV CC_REGNUM)
9988 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9993 [(set (reg:CC_NOOV CC_REGNUM)
9994 (compare:CC_NOOV (ior:SI
9995 (match_operator:SI 1 "arm_comparison_operator"
9996 [(match_operand:SI 2 "s_register_operand" "")
9997 (match_operand:SI 3 "arm_add_operand" "")])
9998 (and:SI (match_operand:SI 0 "s_register_operand" "")
10001 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10003 [(set (match_dup 4)
10004 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10006 (set (reg:CC_NOOV CC_REGNUM)
10007 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10010 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10012 (define_insn_and_split "*negscc"
10013 [(set (match_operand:SI 0 "s_register_operand" "=r")
10014 (neg:SI (match_operator 3 "arm_comparison_operator"
10015 [(match_operand:SI 1 "s_register_operand" "r")
10016 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10017 (clobber (reg:CC CC_REGNUM))]
10020 "&& reload_completed"
10023 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10025 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10027 /* Emit mov\\t%0, %1, asr #31 */
10028 emit_insn (gen_rtx_SET (operands[0],
10029 gen_rtx_ASHIFTRT (SImode,
10034 else if (GET_CODE (operands[3]) == NE)
10036 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10037 if (CONST_INT_P (operands[2]))
10038 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10039 GEN_INT (- INTVAL (operands[2]))));
10041 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10043 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10044 gen_rtx_NE (SImode,
10047 gen_rtx_SET (operands[0],
10053 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10054 emit_insn (gen_rtx_SET (cc_reg,
10055 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10056 enum rtx_code rc = GET_CODE (operands[3]);
10058 rc = reverse_condition (rc);
10059 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10060 gen_rtx_fmt_ee (rc,
10064 gen_rtx_SET (operands[0], const0_rtx)));
10065 rc = GET_CODE (operands[3]);
10066 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10067 gen_rtx_fmt_ee (rc,
10071 gen_rtx_SET (operands[0],
10077 [(set_attr "conds" "clob")
10078 (set_attr "length" "12")
10079 (set_attr "type" "multiple")]
10082 (define_insn_and_split "movcond_addsi"
10083 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
10085 (match_operator 5 "comparison_operator"
10086 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
10087 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
10089 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
10090 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
10091 (clobber (reg:CC CC_REGNUM))]
10094 "&& reload_completed"
10095 [(set (reg:CC_NOOV CC_REGNUM)
10097 (plus:SI (match_dup 3)
10100 (set (match_dup 0) (match_dup 1))
10101 (cond_exec (match_dup 6)
10102 (set (match_dup 0) (match_dup 2)))]
10105 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
10106 operands[3], operands[4]);
10107 enum rtx_code rc = GET_CODE (operands[5]);
10108 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10109 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
10110 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
10111 rc = reverse_condition (rc);
10113 std::swap (operands[1], operands[2]);
10115 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10118 [(set_attr "conds" "clob")
10119 (set_attr "enabled_for_short_it" "no,yes,yes")
10120 (set_attr "type" "multiple")]
10123 (define_insn "movcond"
10124 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10126 (match_operator 5 "arm_comparison_operator"
10127 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10128 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
10129 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10130 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
10131 (clobber (reg:CC CC_REGNUM))]
10134 if (GET_CODE (operands[5]) == LT
10135 && (operands[4] == const0_rtx))
10137 if (which_alternative != 1 && REG_P (operands[1]))
10139 if (operands[2] == const0_rtx)
10140 return \"and\\t%0, %1, %3, asr #31\";
10141 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
10143 else if (which_alternative != 0 && REG_P (operands[2]))
10145 if (operands[1] == const0_rtx)
10146 return \"bic\\t%0, %2, %3, asr #31\";
10147 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
10149 /* The only case that falls through to here is when both ops 1 & 2
10153 if (GET_CODE (operands[5]) == GE
10154 && (operands[4] == const0_rtx))
10156 if (which_alternative != 1 && REG_P (operands[1]))
10158 if (operands[2] == const0_rtx)
10159 return \"bic\\t%0, %1, %3, asr #31\";
10160 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
10162 else if (which_alternative != 0 && REG_P (operands[2]))
10164 if (operands[1] == const0_rtx)
10165 return \"and\\t%0, %2, %3, asr #31\";
10166 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
10168 /* The only case that falls through to here is when both ops 1 & 2
10171 if (CONST_INT_P (operands[4])
10172 && !const_ok_for_arm (INTVAL (operands[4])))
10173 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
10175 output_asm_insn (\"cmp\\t%3, %4\", operands);
10176 if (which_alternative != 0)
10177 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
10178 if (which_alternative != 1)
10179 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
10182 [(set_attr "conds" "clob")
10183 (set_attr "length" "8,8,12")
10184 (set_attr "type" "multiple")]
10187 ;; ??? The patterns below need checking for Thumb-2 usefulness.
10189 (define_insn "*ifcompare_plus_move"
10190 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10191 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10192 [(match_operand:SI 4 "s_register_operand" "r,r")
10193 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10195 (match_operand:SI 2 "s_register_operand" "r,r")
10196 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10197 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10198 (clobber (reg:CC CC_REGNUM))]
10201 [(set_attr "conds" "clob")
10202 (set_attr "length" "8,12")
10203 (set_attr "type" "multiple")]
10206 (define_insn "*if_plus_move"
10207 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10209 (match_operator 4 "arm_comparison_operator"
10210 [(match_operand 5 "cc_register" "") (const_int 0)])
10212 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10213 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10214 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10217 add%d4\\t%0, %2, %3
10218 sub%d4\\t%0, %2, #%n3
10219 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10220 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10221 [(set_attr "conds" "use")
10222 (set_attr "length" "4,4,8,8")
10223 (set_attr_alternative "type"
10224 [(if_then_else (match_operand 3 "const_int_operand" "")
10225 (const_string "alu_imm" )
10226 (const_string "alu_sreg"))
10227 (const_string "alu_imm")
10228 (const_string "multiple")
10229 (const_string "multiple")])]
10232 (define_insn "*ifcompare_move_plus"
10233 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10234 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10235 [(match_operand:SI 4 "s_register_operand" "r,r")
10236 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10237 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10239 (match_operand:SI 2 "s_register_operand" "r,r")
10240 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10241 (clobber (reg:CC CC_REGNUM))]
10244 [(set_attr "conds" "clob")
10245 (set_attr "length" "8,12")
10246 (set_attr "type" "multiple")]
10249 (define_insn "*if_move_plus"
10250 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10252 (match_operator 4 "arm_comparison_operator"
10253 [(match_operand 5 "cc_register" "") (const_int 0)])
10254 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10256 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10257 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10260 add%D4\\t%0, %2, %3
10261 sub%D4\\t%0, %2, #%n3
10262 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10263 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10264 [(set_attr "conds" "use")
10265 (set_attr "length" "4,4,8,8")
10266 (set_attr_alternative "type"
10267 [(if_then_else (match_operand 3 "const_int_operand" "")
10268 (const_string "alu_imm" )
10269 (const_string "alu_sreg"))
10270 (const_string "alu_imm")
10271 (const_string "multiple")
10272 (const_string "multiple")])]
10275 (define_insn "*ifcompare_arith_arith"
10276 [(set (match_operand:SI 0 "s_register_operand" "=r")
10277 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10278 [(match_operand:SI 5 "s_register_operand" "r")
10279 (match_operand:SI 6 "arm_add_operand" "rIL")])
10280 (match_operator:SI 8 "shiftable_operator"
10281 [(match_operand:SI 1 "s_register_operand" "r")
10282 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10283 (match_operator:SI 7 "shiftable_operator"
10284 [(match_operand:SI 3 "s_register_operand" "r")
10285 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10286 (clobber (reg:CC CC_REGNUM))]
10289 [(set_attr "conds" "clob")
10290 (set_attr "length" "12")
10291 (set_attr "type" "multiple")]
10294 (define_insn "*if_arith_arith"
10295 [(set (match_operand:SI 0 "s_register_operand" "=r")
10296 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10297 [(match_operand 8 "cc_register" "") (const_int 0)])
10298 (match_operator:SI 6 "shiftable_operator"
10299 [(match_operand:SI 1 "s_register_operand" "r")
10300 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10301 (match_operator:SI 7 "shiftable_operator"
10302 [(match_operand:SI 3 "s_register_operand" "r")
10303 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10305 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10306 [(set_attr "conds" "use")
10307 (set_attr "length" "8")
10308 (set_attr "type" "multiple")]
10311 (define_insn "*ifcompare_arith_move"
10312 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10313 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10314 [(match_operand:SI 2 "s_register_operand" "r,r")
10315 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10316 (match_operator:SI 7 "shiftable_operator"
10317 [(match_operand:SI 4 "s_register_operand" "r,r")
10318 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10319 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10320 (clobber (reg:CC CC_REGNUM))]
10323 /* If we have an operation where (op x 0) is the identity operation and
10324 the conditional operator is LT or GE and we are comparing against zero and
10325 everything is in registers then we can do this in two instructions. */
10326 if (operands[3] == const0_rtx
10327 && GET_CODE (operands[7]) != AND
10328 && REG_P (operands[5])
10329 && REG_P (operands[1])
10330 && REGNO (operands[1]) == REGNO (operands[4])
10331 && REGNO (operands[4]) != REGNO (operands[0]))
10333 if (GET_CODE (operands[6]) == LT)
10334 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10335 else if (GET_CODE (operands[6]) == GE)
10336 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10338 if (CONST_INT_P (operands[3])
10339 && !const_ok_for_arm (INTVAL (operands[3])))
10340 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10342 output_asm_insn (\"cmp\\t%2, %3\", operands);
10343 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10344 if (which_alternative != 0)
10345 return \"mov%D6\\t%0, %1\";
10348 [(set_attr "conds" "clob")
10349 (set_attr "length" "8,12")
10350 (set_attr "type" "multiple")]
10353 (define_insn "*if_arith_move"
10354 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10355 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10356 [(match_operand 6 "cc_register" "") (const_int 0)])
10357 (match_operator:SI 5 "shiftable_operator"
10358 [(match_operand:SI 2 "s_register_operand" "r,r")
10359 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10360 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10363 %I5%d4\\t%0, %2, %3
10364 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10365 [(set_attr "conds" "use")
10366 (set_attr "length" "4,8")
10367 (set_attr_alternative "type"
10368 [(if_then_else (match_operand 3 "const_int_operand" "")
10369 (const_string "alu_shift_imm" )
10370 (const_string "alu_shift_reg"))
10371 (const_string "multiple")])]
10374 (define_insn "*ifcompare_move_arith"
10375 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10376 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10377 [(match_operand:SI 4 "s_register_operand" "r,r")
10378 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10379 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10380 (match_operator:SI 7 "shiftable_operator"
10381 [(match_operand:SI 2 "s_register_operand" "r,r")
10382 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10383 (clobber (reg:CC CC_REGNUM))]
10386 /* If we have an operation where (op x 0) is the identity operation and
10387 the conditional operator is LT or GE and we are comparing against zero and
10388 everything is in registers then we can do this in two instructions */
10389 if (operands[5] == const0_rtx
10390 && GET_CODE (operands[7]) != AND
10391 && REG_P (operands[3])
10392 && REG_P (operands[1])
10393 && REGNO (operands[1]) == REGNO (operands[2])
10394 && REGNO (operands[2]) != REGNO (operands[0]))
10396 if (GET_CODE (operands[6]) == GE)
10397 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10398 else if (GET_CODE (operands[6]) == LT)
10399 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10402 if (CONST_INT_P (operands[5])
10403 && !const_ok_for_arm (INTVAL (operands[5])))
10404 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10406 output_asm_insn (\"cmp\\t%4, %5\", operands);
10408 if (which_alternative != 0)
10409 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10410 return \"%I7%D6\\t%0, %2, %3\";
10412 [(set_attr "conds" "clob")
10413 (set_attr "length" "8,12")
10414 (set_attr "type" "multiple")]
10417 (define_insn "*if_move_arith"
10418 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10420 (match_operator 4 "arm_comparison_operator"
10421 [(match_operand 6 "cc_register" "") (const_int 0)])
10422 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10423 (match_operator:SI 5 "shiftable_operator"
10424 [(match_operand:SI 2 "s_register_operand" "r,r")
10425 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10428 %I5%D4\\t%0, %2, %3
10429 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10430 [(set_attr "conds" "use")
10431 (set_attr "length" "4,8")
10432 (set_attr_alternative "type"
10433 [(if_then_else (match_operand 3 "const_int_operand" "")
10434 (const_string "alu_shift_imm" )
10435 (const_string "alu_shift_reg"))
10436 (const_string "multiple")])]
10439 (define_insn "*ifcompare_move_not"
10440 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10442 (match_operator 5 "arm_comparison_operator"
10443 [(match_operand:SI 3 "s_register_operand" "r,r")
10444 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10445 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10447 (match_operand:SI 2 "s_register_operand" "r,r"))))
10448 (clobber (reg:CC CC_REGNUM))]
10451 [(set_attr "conds" "clob")
10452 (set_attr "length" "8,12")
10453 (set_attr "type" "multiple")]
10456 (define_insn "*if_move_not"
10457 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10459 (match_operator 4 "arm_comparison_operator"
10460 [(match_operand 3 "cc_register" "") (const_int 0)])
10461 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10462 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10466 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10467 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10468 [(set_attr "conds" "use")
10469 (set_attr "type" "mvn_reg")
10470 (set_attr "length" "4,8,8")
10471 (set_attr "type" "mvn_reg,multiple,multiple")]
10474 (define_insn "*ifcompare_not_move"
10475 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10477 (match_operator 5 "arm_comparison_operator"
10478 [(match_operand:SI 3 "s_register_operand" "r,r")
10479 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10481 (match_operand:SI 2 "s_register_operand" "r,r"))
10482 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10483 (clobber (reg:CC CC_REGNUM))]
10486 [(set_attr "conds" "clob")
10487 (set_attr "length" "8,12")
10488 (set_attr "type" "multiple")]
10491 (define_insn "*if_not_move"
10492 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10494 (match_operator 4 "arm_comparison_operator"
10495 [(match_operand 3 "cc_register" "") (const_int 0)])
10496 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10497 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10501 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10502 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10503 [(set_attr "conds" "use")
10504 (set_attr "type" "mvn_reg,multiple,multiple")
10505 (set_attr "length" "4,8,8")]
10508 (define_insn "*ifcompare_shift_move"
10509 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10511 (match_operator 6 "arm_comparison_operator"
10512 [(match_operand:SI 4 "s_register_operand" "r,r")
10513 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10514 (match_operator:SI 7 "shift_operator"
10515 [(match_operand:SI 2 "s_register_operand" "r,r")
10516 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10517 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10518 (clobber (reg:CC CC_REGNUM))]
10521 [(set_attr "conds" "clob")
10522 (set_attr "length" "8,12")
10523 (set_attr "type" "multiple")]
10526 (define_insn "*if_shift_move"
10527 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10529 (match_operator 5 "arm_comparison_operator"
10530 [(match_operand 6 "cc_register" "") (const_int 0)])
10531 (match_operator:SI 4 "shift_operator"
10532 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10533 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10534 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10538 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10539 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10540 [(set_attr "conds" "use")
10541 (set_attr "shift" "2")
10542 (set_attr "length" "4,8,8")
10543 (set_attr_alternative "type"
10544 [(if_then_else (match_operand 3 "const_int_operand" "")
10545 (const_string "mov_shift" )
10546 (const_string "mov_shift_reg"))
10547 (const_string "multiple")
10548 (const_string "multiple")])]
10551 (define_insn "*ifcompare_move_shift"
10552 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10554 (match_operator 6 "arm_comparison_operator"
10555 [(match_operand:SI 4 "s_register_operand" "r,r")
10556 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10557 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10558 (match_operator:SI 7 "shift_operator"
10559 [(match_operand:SI 2 "s_register_operand" "r,r")
10560 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10561 (clobber (reg:CC CC_REGNUM))]
10564 [(set_attr "conds" "clob")
10565 (set_attr "length" "8,12")
10566 (set_attr "type" "multiple")]
10569 (define_insn "*if_move_shift"
10570 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10572 (match_operator 5 "arm_comparison_operator"
10573 [(match_operand 6 "cc_register" "") (const_int 0)])
10574 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10575 (match_operator:SI 4 "shift_operator"
10576 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10577 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10581 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10582 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10583 [(set_attr "conds" "use")
10584 (set_attr "shift" "2")
10585 (set_attr "length" "4,8,8")
10586 (set_attr_alternative "type"
10587 [(if_then_else (match_operand 3 "const_int_operand" "")
10588 (const_string "mov_shift" )
10589 (const_string "mov_shift_reg"))
10590 (const_string "multiple")
10591 (const_string "multiple")])]
10594 (define_insn "*ifcompare_shift_shift"
10595 [(set (match_operand:SI 0 "s_register_operand" "=r")
10597 (match_operator 7 "arm_comparison_operator"
10598 [(match_operand:SI 5 "s_register_operand" "r")
10599 (match_operand:SI 6 "arm_add_operand" "rIL")])
10600 (match_operator:SI 8 "shift_operator"
10601 [(match_operand:SI 1 "s_register_operand" "r")
10602 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10603 (match_operator:SI 9 "shift_operator"
10604 [(match_operand:SI 3 "s_register_operand" "r")
10605 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10606 (clobber (reg:CC CC_REGNUM))]
10609 [(set_attr "conds" "clob")
10610 (set_attr "length" "12")
10611 (set_attr "type" "multiple")]
10614 (define_insn "*if_shift_shift"
10615 [(set (match_operand:SI 0 "s_register_operand" "=r")
10617 (match_operator 5 "arm_comparison_operator"
10618 [(match_operand 8 "cc_register" "") (const_int 0)])
10619 (match_operator:SI 6 "shift_operator"
10620 [(match_operand:SI 1 "s_register_operand" "r")
10621 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10622 (match_operator:SI 7 "shift_operator"
10623 [(match_operand:SI 3 "s_register_operand" "r")
10624 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10626 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10627 [(set_attr "conds" "use")
10628 (set_attr "shift" "1")
10629 (set_attr "length" "8")
10630 (set (attr "type") (if_then_else
10631 (and (match_operand 2 "const_int_operand" "")
10632 (match_operand 4 "const_int_operand" ""))
10633 (const_string "mov_shift")
10634 (const_string "mov_shift_reg")))]
10637 (define_insn "*ifcompare_not_arith"
10638 [(set (match_operand:SI 0 "s_register_operand" "=r")
10640 (match_operator 6 "arm_comparison_operator"
10641 [(match_operand:SI 4 "s_register_operand" "r")
10642 (match_operand:SI 5 "arm_add_operand" "rIL")])
10643 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10644 (match_operator:SI 7 "shiftable_operator"
10645 [(match_operand:SI 2 "s_register_operand" "r")
10646 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10647 (clobber (reg:CC CC_REGNUM))]
10650 [(set_attr "conds" "clob")
10651 (set_attr "length" "12")
10652 (set_attr "type" "multiple")]
10655 (define_insn "*if_not_arith"
10656 [(set (match_operand:SI 0 "s_register_operand" "=r")
10658 (match_operator 5 "arm_comparison_operator"
10659 [(match_operand 4 "cc_register" "") (const_int 0)])
10660 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10661 (match_operator:SI 6 "shiftable_operator"
10662 [(match_operand:SI 2 "s_register_operand" "r")
10663 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10665 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10666 [(set_attr "conds" "use")
10667 (set_attr "type" "mvn_reg")
10668 (set_attr "length" "8")]
10671 (define_insn "*ifcompare_arith_not"
10672 [(set (match_operand:SI 0 "s_register_operand" "=r")
10674 (match_operator 6 "arm_comparison_operator"
10675 [(match_operand:SI 4 "s_register_operand" "r")
10676 (match_operand:SI 5 "arm_add_operand" "rIL")])
10677 (match_operator:SI 7 "shiftable_operator"
10678 [(match_operand:SI 2 "s_register_operand" "r")
10679 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10680 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10681 (clobber (reg:CC CC_REGNUM))]
10684 [(set_attr "conds" "clob")
10685 (set_attr "length" "12")
10686 (set_attr "type" "multiple")]
10689 (define_insn "*if_arith_not"
10690 [(set (match_operand:SI 0 "s_register_operand" "=r")
10692 (match_operator 5 "arm_comparison_operator"
10693 [(match_operand 4 "cc_register" "") (const_int 0)])
10694 (match_operator:SI 6 "shiftable_operator"
10695 [(match_operand:SI 2 "s_register_operand" "r")
10696 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10697 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10699 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10700 [(set_attr "conds" "use")
10701 (set_attr "type" "multiple")
10702 (set_attr "length" "8")]
10705 (define_insn "*ifcompare_neg_move"
10706 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10708 (match_operator 5 "arm_comparison_operator"
10709 [(match_operand:SI 3 "s_register_operand" "r,r")
10710 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10711 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10712 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10713 (clobber (reg:CC CC_REGNUM))]
10716 [(set_attr "conds" "clob")
10717 (set_attr "length" "8,12")
10718 (set_attr "type" "multiple")]
10721 (define_insn_and_split "*if_neg_move"
10722 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10724 (match_operator 4 "arm_comparison_operator"
10725 [(match_operand 3 "cc_register" "") (const_int 0)])
10726 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10727 (match_operand:SI 1 "s_register_operand" "0,0")))]
10730 "&& reload_completed"
10731 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10732 (set (match_dup 0) (neg:SI (match_dup 2))))]
10734 [(set_attr "conds" "use")
10735 (set_attr "length" "4")
10736 (set_attr "arch" "t2,32")
10737 (set_attr "enabled_for_short_it" "yes,no")
10738 (set_attr "type" "logic_shift_imm")]
10741 (define_insn "*ifcompare_move_neg"
10742 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10744 (match_operator 5 "arm_comparison_operator"
10745 [(match_operand:SI 3 "s_register_operand" "r,r")
10746 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10747 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10748 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10749 (clobber (reg:CC CC_REGNUM))]
10752 [(set_attr "conds" "clob")
10753 (set_attr "length" "8,12")
10754 (set_attr "type" "multiple")]
10757 (define_insn_and_split "*if_move_neg"
10758 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10760 (match_operator 4 "arm_comparison_operator"
10761 [(match_operand 3 "cc_register" "") (const_int 0)])
10762 (match_operand:SI 1 "s_register_operand" "0,0")
10763 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10766 "&& reload_completed"
10767 [(cond_exec (match_dup 5)
10768 (set (match_dup 0) (neg:SI (match_dup 2))))]
10770 machine_mode mode = GET_MODE (operands[3]);
10771 rtx_code rc = GET_CODE (operands[4]);
10773 if (mode == CCFPmode || mode == CCFPEmode)
10774 rc = reverse_condition_maybe_unordered (rc);
10776 rc = reverse_condition (rc);
10778 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10780 [(set_attr "conds" "use")
10781 (set_attr "length" "4")
10782 (set_attr "arch" "t2,32")
10783 (set_attr "enabled_for_short_it" "yes,no")
10784 (set_attr "type" "logic_shift_imm")]
10787 (define_insn "*arith_adjacentmem"
10788 [(set (match_operand:SI 0 "s_register_operand" "=r")
10789 (match_operator:SI 1 "shiftable_operator"
10790 [(match_operand:SI 2 "memory_operand" "m")
10791 (match_operand:SI 3 "memory_operand" "m")]))
10792 (clobber (match_scratch:SI 4 "=r"))]
10793 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10799 HOST_WIDE_INT val1 = 0, val2 = 0;
10801 if (REGNO (operands[0]) > REGNO (operands[4]))
10803 ldm[1] = operands[4];
10804 ldm[2] = operands[0];
10808 ldm[1] = operands[0];
10809 ldm[2] = operands[4];
10812 base_reg = XEXP (operands[2], 0);
10814 if (!REG_P (base_reg))
10816 val1 = INTVAL (XEXP (base_reg, 1));
10817 base_reg = XEXP (base_reg, 0);
10820 if (!REG_P (XEXP (operands[3], 0)))
10821 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10823 arith[0] = operands[0];
10824 arith[3] = operands[1];
10838 if (val1 !=0 && val2 != 0)
10842 if (val1 == 4 || val2 == 4)
10843 /* Other val must be 8, since we know they are adjacent and neither
10845 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10846 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10848 ldm[0] = ops[0] = operands[4];
10850 ops[2] = GEN_INT (val1);
10851 output_add_immediate (ops);
10853 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10855 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10859 /* Offset is out of range for a single add, so use two ldr. */
10862 ops[2] = GEN_INT (val1);
10863 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10865 ops[2] = GEN_INT (val2);
10866 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10869 else if (val1 != 0)
10872 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10874 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10879 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10881 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10883 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10886 [(set_attr "length" "12")
10887 (set_attr "predicable" "yes")
10888 (set_attr "type" "load_4")]
10891 ; This pattern is never tried by combine, so do it as a peephole
10894 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10895 (match_operand:SI 1 "arm_general_register_operand" ""))
10896 (set (reg:CC CC_REGNUM)
10897 (compare:CC (match_dup 1) (const_int 0)))]
10899 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10900 (set (match_dup 0) (match_dup 1))])]
10905 [(set (match_operand:SI 0 "s_register_operand" "")
10906 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10908 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10909 [(match_operand:SI 3 "s_register_operand" "")
10910 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10911 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10913 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10914 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10919 ;; This split can be used because CC_Z mode implies that the following
10920 ;; branch will be an equality, or an unsigned inequality, so the sign
10921 ;; extension is not needed.
10924 [(set (reg:CC_Z CC_REGNUM)
10926 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10928 (match_operand 1 "const_int_operand" "")))
10929 (clobber (match_scratch:SI 2 ""))]
10931 && ((UINTVAL (operands[1]))
10932 == ((UINTVAL (operands[1])) >> 24) << 24)"
10933 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10934 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10936 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10939 ;; ??? Check the patterns above for Thumb-2 usefulness
10941 (define_expand "prologue"
10942 [(clobber (const_int 0))]
10945 arm_expand_prologue ();
10947 thumb1_expand_prologue ();
10952 (define_expand "epilogue"
10953 [(clobber (const_int 0))]
10956 if (crtl->calls_eh_return)
10957 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10960 thumb1_expand_epilogue ();
10961 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10962 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10964 else if (HAVE_return)
10966 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10967 no need for explicit testing again. */
10968 emit_jump_insn (gen_return ());
10970 else if (TARGET_32BIT)
10972 arm_expand_epilogue (true);
10978 ;; Note - although unspec_volatile's USE all hard registers,
10979 ;; USEs are ignored after relaod has completed. Thus we need
10980 ;; to add an unspec of the link register to ensure that flow
10981 ;; does not think that it is unused by the sibcall branch that
10982 ;; will replace the standard function epilogue.
10983 (define_expand "sibcall_epilogue"
10984 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10985 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10988 arm_expand_epilogue (false);
10993 (define_expand "eh_epilogue"
10994 [(use (match_operand:SI 0 "register_operand" ""))
10995 (use (match_operand:SI 1 "register_operand" ""))
10996 (use (match_operand:SI 2 "register_operand" ""))]
11000 cfun->machine->eh_epilogue_sp_ofs = operands[1];
11001 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11003 rtx ra = gen_rtx_REG (Pmode, 2);
11005 emit_move_insn (ra, operands[2]);
11008 /* This is a hack -- we may have crystalized the function type too
11010 cfun->machine->func_type = 0;
11014 ;; This split is only used during output to reduce the number of patterns
11015 ;; that need assembler instructions adding to them. We allowed the setting
11016 ;; of the conditions to be implicit during rtl generation so that
11017 ;; the conditional compare patterns would work. However this conflicts to
11018 ;; some extent with the conditional data operations, so we have to split them
11021 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
11022 ;; conditional execution sufficient?
11025 [(set (match_operand:SI 0 "s_register_operand" "")
11026 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11027 [(match_operand 2 "" "") (match_operand 3 "" "")])
11029 (match_operand 4 "" "")))
11030 (clobber (reg:CC CC_REGNUM))]
11031 "TARGET_ARM && reload_completed"
11032 [(set (match_dup 5) (match_dup 6))
11033 (cond_exec (match_dup 7)
11034 (set (match_dup 0) (match_dup 4)))]
11037 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11038 operands[2], operands[3]);
11039 enum rtx_code rc = GET_CODE (operands[1]);
11041 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11042 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11043 if (mode == CCFPmode || mode == CCFPEmode)
11044 rc = reverse_condition_maybe_unordered (rc);
11046 rc = reverse_condition (rc);
11048 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11053 [(set (match_operand:SI 0 "s_register_operand" "")
11054 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11055 [(match_operand 2 "" "") (match_operand 3 "" "")])
11056 (match_operand 4 "" "")
11058 (clobber (reg:CC CC_REGNUM))]
11059 "TARGET_ARM && reload_completed"
11060 [(set (match_dup 5) (match_dup 6))
11061 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11062 (set (match_dup 0) (match_dup 4)))]
11065 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11066 operands[2], operands[3]);
11068 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11069 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11074 [(set (match_operand:SI 0 "s_register_operand" "")
11075 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11076 [(match_operand 2 "" "") (match_operand 3 "" "")])
11077 (match_operand 4 "" "")
11078 (match_operand 5 "" "")))
11079 (clobber (reg:CC CC_REGNUM))]
11080 "TARGET_ARM && reload_completed"
11081 [(set (match_dup 6) (match_dup 7))
11082 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11083 (set (match_dup 0) (match_dup 4)))
11084 (cond_exec (match_dup 8)
11085 (set (match_dup 0) (match_dup 5)))]
11088 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11089 operands[2], operands[3]);
11090 enum rtx_code rc = GET_CODE (operands[1]);
11092 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11093 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11094 if (mode == CCFPmode || mode == CCFPEmode)
11095 rc = reverse_condition_maybe_unordered (rc);
11097 rc = reverse_condition (rc);
11099 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11104 [(set (match_operand:SI 0 "s_register_operand" "")
11105 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11106 [(match_operand:SI 2 "s_register_operand" "")
11107 (match_operand:SI 3 "arm_add_operand" "")])
11108 (match_operand:SI 4 "arm_rhs_operand" "")
11110 (match_operand:SI 5 "s_register_operand" ""))))
11111 (clobber (reg:CC CC_REGNUM))]
11112 "TARGET_ARM && reload_completed"
11113 [(set (match_dup 6) (match_dup 7))
11114 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11115 (set (match_dup 0) (match_dup 4)))
11116 (cond_exec (match_dup 8)
11117 (set (match_dup 0) (not:SI (match_dup 5))))]
11120 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11121 operands[2], operands[3]);
11122 enum rtx_code rc = GET_CODE (operands[1]);
11124 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11125 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11126 if (mode == CCFPmode || mode == CCFPEmode)
11127 rc = reverse_condition_maybe_unordered (rc);
11129 rc = reverse_condition (rc);
11131 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11135 (define_insn "*cond_move_not"
11136 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11137 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11138 [(match_operand 3 "cc_register" "") (const_int 0)])
11139 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11141 (match_operand:SI 2 "s_register_operand" "r,r"))))]
11145 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11146 [(set_attr "conds" "use")
11147 (set_attr "type" "mvn_reg,multiple")
11148 (set_attr "length" "4,8")]
11151 ;; The next two patterns occur when an AND operation is followed by a
11152 ;; scc insn sequence
11154 (define_insn "*sign_extract_onebit"
11155 [(set (match_operand:SI 0 "s_register_operand" "=r")
11156 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11158 (match_operand:SI 2 "const_int_operand" "n")))
11159 (clobber (reg:CC CC_REGNUM))]
11162 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11163 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
11164 return \"mvnne\\t%0, #0\";
11166 [(set_attr "conds" "clob")
11167 (set_attr "length" "8")
11168 (set_attr "type" "multiple")]
11171 (define_insn "*not_signextract_onebit"
11172 [(set (match_operand:SI 0 "s_register_operand" "=r")
11174 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11176 (match_operand:SI 2 "const_int_operand" "n"))))
11177 (clobber (reg:CC CC_REGNUM))]
11180 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11181 output_asm_insn (\"tst\\t%1, %2\", operands);
11182 output_asm_insn (\"mvneq\\t%0, #0\", operands);
11183 return \"movne\\t%0, #0\";
11185 [(set_attr "conds" "clob")
11186 (set_attr "length" "12")
11187 (set_attr "type" "multiple")]
11189 ;; ??? The above patterns need auditing for Thumb-2
11191 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
11192 ;; expressions. For simplicity, the first register is also in the unspec
11194 ;; To avoid the usage of GNU extension, the length attribute is computed
11195 ;; in a C function arm_attr_length_push_multi.
11196 (define_insn "*push_multi"
11197 [(match_parallel 2 "multi_register_push"
11198 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11199 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11200 UNSPEC_PUSH_MULT))])]
11204 int num_saves = XVECLEN (operands[2], 0);
11206 /* For the StrongARM at least it is faster to
11207 use STR to store only a single register.
11208 In Thumb mode always use push, and the assembler will pick
11209 something appropriate. */
11210 if (num_saves == 1 && TARGET_ARM)
11211 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11218 strcpy (pattern, \"push%?\\t{%1\");
11220 strcpy (pattern, \"push\\t{%1\");
11222 for (i = 1; i < num_saves; i++)
11224 strcat (pattern, \", %|\");
11226 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11229 strcat (pattern, \"}\");
11230 output_asm_insn (pattern, operands);
11235 [(set_attr "type" "store_16")
11236 (set (attr "length")
11237 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11240 (define_insn "stack_tie"
11241 [(set (mem:BLK (scratch))
11242 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11243 (match_operand:SI 1 "s_register_operand" "rk")]
11247 [(set_attr "length" "0")
11248 (set_attr "type" "block")]
11251 ;; Pop (as used in epilogue RTL)
11253 (define_insn "*load_multiple_with_writeback"
11254 [(match_parallel 0 "load_multiple_operation"
11255 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11256 (plus:SI (match_dup 1)
11257 (match_operand:SI 2 "const_int_I_operand" "I")))
11258 (set (match_operand:SI 3 "s_register_operand" "=rk")
11259 (mem:SI (match_dup 1)))
11261 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11264 arm_output_multireg_pop (operands, /*return_pc=*/false,
11265 /*cond=*/const_true_rtx,
11271 [(set_attr "type" "load_16")
11272 (set_attr "predicable" "yes")
11273 (set (attr "length")
11274 (symbol_ref "arm_attr_length_pop_multi (operands,
11275 /*return_pc=*/false,
11276 /*write_back_p=*/true)"))]
11279 ;; Pop with return (as used in epilogue RTL)
11281 ;; This instruction is generated when the registers are popped at the end of
11282 ;; epilogue. Here, instead of popping the value into LR and then generating
11283 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11285 (define_insn "*pop_multiple_with_writeback_and_return"
11286 [(match_parallel 0 "pop_multiple_return"
11288 (set (match_operand:SI 1 "s_register_operand" "+rk")
11289 (plus:SI (match_dup 1)
11290 (match_operand:SI 2 "const_int_I_operand" "I")))
11291 (set (match_operand:SI 3 "s_register_operand" "=rk")
11292 (mem:SI (match_dup 1)))
11294 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11297 arm_output_multireg_pop (operands, /*return_pc=*/true,
11298 /*cond=*/const_true_rtx,
11304 [(set_attr "type" "load_16")
11305 (set_attr "predicable" "yes")
11306 (set (attr "length")
11307 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11308 /*write_back_p=*/true)"))]
11311 (define_insn "*pop_multiple_with_return"
11312 [(match_parallel 0 "pop_multiple_return"
11314 (set (match_operand:SI 2 "s_register_operand" "=rk")
11315 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11317 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11320 arm_output_multireg_pop (operands, /*return_pc=*/true,
11321 /*cond=*/const_true_rtx,
11327 [(set_attr "type" "load_16")
11328 (set_attr "predicable" "yes")
11329 (set (attr "length")
11330 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11331 /*write_back_p=*/false)"))]
11334 ;; Load into PC and return
11335 (define_insn "*ldr_with_return"
11337 (set (reg:SI PC_REGNUM)
11338 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11339 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11340 "ldr%?\t%|pc, [%0], #4"
11341 [(set_attr "type" "load_4")
11342 (set_attr "predicable" "yes")]
11344 ;; Pop for floating point registers (as used in epilogue RTL)
11345 (define_insn "*vfp_pop_multiple_with_writeback"
11346 [(match_parallel 0 "pop_multiple_fp"
11347 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11348 (plus:SI (match_dup 1)
11349 (match_operand:SI 2 "const_int_I_operand" "I")))
11350 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11351 (mem:DF (match_dup 1)))])]
11352 "TARGET_32BIT && TARGET_HARD_FLOAT"
11355 int num_regs = XVECLEN (operands[0], 0);
11358 strcpy (pattern, \"vldm\\t\");
11359 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11360 strcat (pattern, \"!, {\");
11361 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11362 strcat (pattern, \"%P0\");
11363 if ((num_regs - 1) > 1)
11365 strcat (pattern, \"-%P1\");
11366 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11369 strcat (pattern, \"}\");
11370 output_asm_insn (pattern, op_list);
11374 [(set_attr "type" "load_16")
11375 (set_attr "conds" "unconditional")
11376 (set_attr "predicable" "no")]
11379 ;; Special patterns for dealing with the constant pool
11381 (define_insn "align_4"
11382 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11385 assemble_align (32);
11388 [(set_attr "type" "no_insn")]
11391 (define_insn "align_8"
11392 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11395 assemble_align (64);
11398 [(set_attr "type" "no_insn")]
11401 (define_insn "consttable_end"
11402 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11405 making_const_table = FALSE;
11408 [(set_attr "type" "no_insn")]
11411 (define_insn "consttable_1"
11412 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11415 making_const_table = TRUE;
11416 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11417 assemble_zeros (3);
11420 [(set_attr "length" "4")
11421 (set_attr "type" "no_insn")]
11424 (define_insn "consttable_2"
11425 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11429 rtx x = operands[0];
11430 making_const_table = TRUE;
11431 switch (GET_MODE_CLASS (GET_MODE (x)))
11434 arm_emit_fp16_const (x);
11437 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11438 assemble_zeros (2);
11443 [(set_attr "length" "4")
11444 (set_attr "type" "no_insn")]
11447 (define_insn "consttable_4"
11448 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11452 rtx x = operands[0];
11453 making_const_table = TRUE;
11454 scalar_float_mode float_mode;
11455 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11456 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11459 /* XXX: Sometimes gcc does something really dumb and ends up with
11460 a HIGH in a constant pool entry, usually because it's trying to
11461 load into a VFP register. We know this will always be used in
11462 combination with a LO_SUM which ignores the high bits, so just
11463 strip off the HIGH. */
11464 if (GET_CODE (x) == HIGH)
11466 assemble_integer (x, 4, BITS_PER_WORD, 1);
11467 mark_symbol_refs_as_used (x);
11471 [(set_attr "length" "4")
11472 (set_attr "type" "no_insn")]
11475 (define_insn "consttable_8"
11476 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11480 making_const_table = TRUE;
11481 scalar_float_mode float_mode;
11482 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11483 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11484 float_mode, BITS_PER_WORD);
11486 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11489 [(set_attr "length" "8")
11490 (set_attr "type" "no_insn")]
11493 (define_insn "consttable_16"
11494 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11498 making_const_table = TRUE;
11499 scalar_float_mode float_mode;
11500 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11501 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11502 float_mode, BITS_PER_WORD);
11504 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11507 [(set_attr "length" "16")
11508 (set_attr "type" "no_insn")]
11511 ;; V5 Instructions,
11513 (define_insn "clzsi2"
11514 [(set (match_operand:SI 0 "s_register_operand" "=r")
11515 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11516 "TARGET_32BIT && arm_arch5t"
11518 [(set_attr "predicable" "yes")
11519 (set_attr "type" "clz")])
11521 (define_insn "rbitsi2"
11522 [(set (match_operand:SI 0 "s_register_operand" "=r")
11523 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11524 "TARGET_32BIT && arm_arch_thumb2"
11526 [(set_attr "predicable" "yes")
11527 (set_attr "type" "clz")])
11529 ;; Keep this as a CTZ expression until after reload and then split
11530 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11531 ;; to fold with any other expression.
11533 (define_insn_and_split "ctzsi2"
11534 [(set (match_operand:SI 0 "s_register_operand" "=r")
11535 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11536 "TARGET_32BIT && arm_arch_thumb2"
11538 "&& reload_completed"
11541 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11542 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11546 ;; V5E instructions.
11548 (define_insn "prefetch"
11549 [(prefetch (match_operand:SI 0 "address_operand" "p")
11550 (match_operand:SI 1 "" "")
11551 (match_operand:SI 2 "" ""))]
11552 "TARGET_32BIT && arm_arch5te"
11554 [(set_attr "type" "load_4")]
11557 ;; General predication pattern
11560 [(match_operator 0 "arm_comparison_operator"
11561 [(match_operand 1 "cc_register" "")
11564 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11566 [(set_attr "predicated" "yes")]
11569 (define_insn "force_register_use"
11570 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11573 [(set_attr "length" "0")
11574 (set_attr "type" "no_insn")]
11578 ;; Patterns for exception handling
11580 (define_expand "eh_return"
11581 [(use (match_operand 0 "general_operand" ""))]
11586 emit_insn (gen_arm_eh_return (operands[0]));
11588 emit_insn (gen_thumb_eh_return (operands[0]));
11593 ;; We can't expand this before we know where the link register is stored.
11594 (define_insn_and_split "arm_eh_return"
11595 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11597 (clobber (match_scratch:SI 1 "=&r"))]
11600 "&& reload_completed"
11604 arm_set_return_address (operands[0], operands[1]);
11612 (define_insn "load_tp_hard"
11613 [(set (match_operand:SI 0 "register_operand" "=r")
11614 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11616 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11617 [(set_attr "predicable" "yes")
11618 (set_attr "type" "mrs")]
11621 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11622 (define_insn "load_tp_soft"
11623 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11624 (clobber (reg:SI LR_REGNUM))
11625 (clobber (reg:SI IP_REGNUM))
11626 (clobber (reg:CC CC_REGNUM))]
11628 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11629 [(set_attr "conds" "clob")
11630 (set_attr "type" "branch")]
11633 ;; tls descriptor call
11634 (define_insn "tlscall"
11635 [(set (reg:SI R0_REGNUM)
11636 (unspec:SI [(reg:SI R0_REGNUM)
11637 (match_operand:SI 0 "" "X")
11638 (match_operand 1 "" "")] UNSPEC_TLS))
11639 (clobber (reg:SI R1_REGNUM))
11640 (clobber (reg:SI LR_REGNUM))
11641 (clobber (reg:SI CC_REGNUM))]
11644 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11645 INTVAL (operands[1]));
11646 return "bl\\t%c0(tlscall)";
11648 [(set_attr "conds" "clob")
11649 (set_attr "length" "4")
11650 (set_attr "type" "branch")]
11653 ;; For thread pointer builtin
11654 (define_expand "get_thread_pointersi"
11655 [(match_operand:SI 0 "s_register_operand" "=r")]
11659 arm_load_tp (operands[0]);
11665 ;; We only care about the lower 16 bits of the constant
11666 ;; being inserted into the upper 16 bits of the register.
11667 (define_insn "*arm_movtas_ze"
11668 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11671 (match_operand:SI 1 "const_int_operand" ""))]
11676 [(set_attr "arch" "32,v8mb")
11677 (set_attr "predicable" "yes")
11678 (set_attr "length" "4")
11679 (set_attr "type" "alu_sreg")]
11682 (define_insn "*arm_rev"
11683 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11684 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11690 [(set_attr "arch" "t1,t2,32")
11691 (set_attr "length" "2,2,4")
11692 (set_attr "predicable" "no,yes,yes")
11693 (set_attr "type" "rev")]
11696 (define_expand "arm_legacy_rev"
11697 [(set (match_operand:SI 2 "s_register_operand" "")
11698 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11702 (lshiftrt:SI (match_dup 2)
11704 (set (match_operand:SI 3 "s_register_operand" "")
11705 (rotatert:SI (match_dup 1)
11708 (and:SI (match_dup 2)
11709 (const_int -65281)))
11710 (set (match_operand:SI 0 "s_register_operand" "")
11711 (xor:SI (match_dup 3)
11717 ;; Reuse temporaries to keep register pressure down.
11718 (define_expand "thumb_legacy_rev"
11719 [(set (match_operand:SI 2 "s_register_operand" "")
11720 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11722 (set (match_operand:SI 3 "s_register_operand" "")
11723 (lshiftrt:SI (match_dup 1)
11726 (ior:SI (match_dup 3)
11728 (set (match_operand:SI 4 "s_register_operand" "")
11730 (set (match_operand:SI 5 "s_register_operand" "")
11731 (rotatert:SI (match_dup 1)
11734 (ashift:SI (match_dup 5)
11737 (lshiftrt:SI (match_dup 5)
11740 (ior:SI (match_dup 5)
11743 (rotatert:SI (match_dup 5)
11745 (set (match_operand:SI 0 "s_register_operand" "")
11746 (ior:SI (match_dup 5)
11752 ;; ARM-specific expansion of signed mod by power of 2
11753 ;; using conditional negate.
11754 ;; For r0 % n where n is a power of 2 produce:
11756 ;; and r0, r0, #(n - 1)
11757 ;; and r1, r1, #(n - 1)
11758 ;; rsbpl r0, r1, #0
11760 (define_expand "modsi3"
11761 [(match_operand:SI 0 "register_operand" "")
11762 (match_operand:SI 1 "register_operand" "")
11763 (match_operand:SI 2 "const_int_operand" "")]
11766 HOST_WIDE_INT val = INTVAL (operands[2]);
11769 || exact_log2 (val) <= 0)
11772 rtx mask = GEN_INT (val - 1);
11774 /* In the special case of x0 % 2 we can do the even shorter:
11777 rsblt r0, r0, #0. */
11781 rtx cc_reg = arm_gen_compare_reg (LT,
11782 operands[1], const0_rtx, NULL_RTX);
11783 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11784 rtx masked = gen_reg_rtx (SImode);
11786 emit_insn (gen_andsi3 (masked, operands[1], mask));
11787 emit_move_insn (operands[0],
11788 gen_rtx_IF_THEN_ELSE (SImode, cond,
11789 gen_rtx_NEG (SImode,
11795 rtx neg_op = gen_reg_rtx (SImode);
11796 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11799 /* Extract the condition register and mode. */
11800 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11801 rtx cc_reg = SET_DEST (cmp);
11802 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11804 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11806 rtx masked_neg = gen_reg_rtx (SImode);
11807 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11809 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11810 during expand does not always work. Do an IF_THEN_ELSE instead. */
11811 emit_move_insn (operands[0],
11812 gen_rtx_IF_THEN_ELSE (SImode, cond,
11813 gen_rtx_NEG (SImode, masked_neg),
11821 (define_expand "bswapsi2"
11822 [(set (match_operand:SI 0 "s_register_operand" "=r")
11823 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11824 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11828 rtx op2 = gen_reg_rtx (SImode);
11829 rtx op3 = gen_reg_rtx (SImode);
11833 rtx op4 = gen_reg_rtx (SImode);
11834 rtx op5 = gen_reg_rtx (SImode);
11836 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11837 op2, op3, op4, op5));
11841 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11850 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11851 ;; and unsigned variants, respectively. For rev16, expose
11852 ;; byte-swapping in the lower 16 bits only.
11853 (define_insn "*arm_revsh"
11854 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11855 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11861 [(set_attr "arch" "t1,t2,32")
11862 (set_attr "length" "2,2,4")
11863 (set_attr "type" "rev")]
11866 (define_insn "*arm_rev16"
11867 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11868 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11874 [(set_attr "arch" "t1,t2,32")
11875 (set_attr "length" "2,2,4")
11876 (set_attr "type" "rev")]
11879 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11880 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11881 ;; each valid permutation.
11883 (define_insn "arm_rev16si2"
11884 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11885 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11887 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11888 (and:SI (lshiftrt:SI (match_dup 1)
11890 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11892 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11893 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11895 [(set_attr "arch" "t1,t2,32")
11896 (set_attr "length" "2,2,4")
11897 (set_attr "type" "rev")]
11900 (define_insn "arm_rev16si2_alt"
11901 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11902 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11904 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11905 (and:SI (ashift:SI (match_dup 1)
11907 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11909 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11910 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11912 [(set_attr "arch" "t1,t2,32")
11913 (set_attr "length" "2,2,4")
11914 (set_attr "type" "rev")]
11917 (define_expand "bswaphi2"
11918 [(set (match_operand:HI 0 "s_register_operand" "=r")
11919 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11924 ;; Patterns for LDRD/STRD in Thumb2 mode
11926 (define_insn "*thumb2_ldrd"
11927 [(set (match_operand:SI 0 "s_register_operand" "=r")
11928 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11929 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11930 (set (match_operand:SI 3 "s_register_operand" "=r")
11931 (mem:SI (plus:SI (match_dup 1)
11932 (match_operand:SI 4 "const_int_operand" ""))))]
11933 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11934 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11935 && (operands_ok_ldrd_strd (operands[0], operands[3],
11936 operands[1], INTVAL (operands[2]),
11938 "ldrd%?\t%0, %3, [%1, %2]"
11939 [(set_attr "type" "load_8")
11940 (set_attr "predicable" "yes")])
11942 (define_insn "*thumb2_ldrd_base"
11943 [(set (match_operand:SI 0 "s_register_operand" "=r")
11944 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11945 (set (match_operand:SI 2 "s_register_operand" "=r")
11946 (mem:SI (plus:SI (match_dup 1)
11948 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11949 && (operands_ok_ldrd_strd (operands[0], operands[2],
11950 operands[1], 0, false, true))"
11951 "ldrd%?\t%0, %2, [%1]"
11952 [(set_attr "type" "load_8")
11953 (set_attr "predicable" "yes")])
11955 (define_insn "*thumb2_ldrd_base_neg"
11956 [(set (match_operand:SI 0 "s_register_operand" "=r")
11957 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11959 (set (match_operand:SI 2 "s_register_operand" "=r")
11960 (mem:SI (match_dup 1)))]
11961 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11962 && (operands_ok_ldrd_strd (operands[0], operands[2],
11963 operands[1], -4, false, true))"
11964 "ldrd%?\t%0, %2, [%1, #-4]"
11965 [(set_attr "type" "load_8")
11966 (set_attr "predicable" "yes")])
11968 (define_insn "*thumb2_strd"
11969 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11970 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11971 (match_operand:SI 2 "s_register_operand" "r"))
11972 (set (mem:SI (plus:SI (match_dup 0)
11973 (match_operand:SI 3 "const_int_operand" "")))
11974 (match_operand:SI 4 "s_register_operand" "r"))]
11975 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11976 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11977 && (operands_ok_ldrd_strd (operands[2], operands[4],
11978 operands[0], INTVAL (operands[1]),
11980 "strd%?\t%2, %4, [%0, %1]"
11981 [(set_attr "type" "store_8")
11982 (set_attr "predicable" "yes")])
11984 (define_insn "*thumb2_strd_base"
11985 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11986 (match_operand:SI 1 "s_register_operand" "r"))
11987 (set (mem:SI (plus:SI (match_dup 0)
11989 (match_operand:SI 2 "s_register_operand" "r"))]
11990 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11991 && (operands_ok_ldrd_strd (operands[1], operands[2],
11992 operands[0], 0, false, false))"
11993 "strd%?\t%1, %2, [%0]"
11994 [(set_attr "type" "store_8")
11995 (set_attr "predicable" "yes")])
11997 (define_insn "*thumb2_strd_base_neg"
11998 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12000 (match_operand:SI 1 "s_register_operand" "r"))
12001 (set (mem:SI (match_dup 0))
12002 (match_operand:SI 2 "s_register_operand" "r"))]
12003 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12004 && (operands_ok_ldrd_strd (operands[1], operands[2],
12005 operands[0], -4, false, false))"
12006 "strd%?\t%1, %2, [%0, #-4]"
12007 [(set_attr "type" "store_8")
12008 (set_attr "predicable" "yes")])
12010 ;; ARMv8 CRC32 instructions.
12011 (define_insn "<crc_variant>"
12012 [(set (match_operand:SI 0 "s_register_operand" "=r")
12013 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
12014 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
12017 "<crc_variant>\\t%0, %1, %2"
12018 [(set_attr "type" "crc")
12019 (set_attr "conds" "unconditional")]
12022 ;; Load the load/store double peephole optimizations.
12023 (include "ldrdstrd.md")
12025 ;; Load the load/store multiple patterns
12026 (include "ldmstm.md")
12028 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12029 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12030 ;; The operands are validated through the load_multiple_operation
12031 ;; match_parallel predicate rather than through constraints so enable it only
12033 (define_insn "*load_multiple"
12034 [(match_parallel 0 "load_multiple_operation"
12035 [(set (match_operand:SI 2 "s_register_operand" "=rk")
12036 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12038 "TARGET_32BIT && reload_completed"
12041 arm_output_multireg_pop (operands, /*return_pc=*/false,
12042 /*cond=*/const_true_rtx,
12048 [(set_attr "predicable" "yes")]
12051 (define_expand "copysignsf3"
12052 [(match_operand:SF 0 "register_operand")
12053 (match_operand:SF 1 "register_operand")
12054 (match_operand:SF 2 "register_operand")]
12055 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12057 emit_move_insn (operands[0], operands[2]);
12058 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
12059 GEN_INT (31), GEN_INT (0),
12060 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
12065 (define_expand "copysigndf3"
12066 [(match_operand:DF 0 "register_operand")
12067 (match_operand:DF 1 "register_operand")
12068 (match_operand:DF 2 "register_operand")]
12069 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12071 rtx op0_low = gen_lowpart (SImode, operands[0]);
12072 rtx op0_high = gen_highpart (SImode, operands[0]);
12073 rtx op1_low = gen_lowpart (SImode, operands[1]);
12074 rtx op1_high = gen_highpart (SImode, operands[1]);
12075 rtx op2_high = gen_highpart (SImode, operands[2]);
12077 rtx scratch1 = gen_reg_rtx (SImode);
12078 rtx scratch2 = gen_reg_rtx (SImode);
12079 emit_move_insn (scratch1, op2_high);
12080 emit_move_insn (scratch2, op1_high);
12082 emit_insn(gen_rtx_SET(scratch1,
12083 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
12084 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
12085 emit_move_insn (op0_low, op1_low);
12086 emit_move_insn (op0_high, scratch2);
12092 ;; movmisalign patterns for HImode and SImode.
12093 (define_expand "movmisalign<mode>"
12094 [(match_operand:HSI 0 "general_operand")
12095 (match_operand:HSI 1 "general_operand")]
12098 /* This pattern is not permitted to fail during expansion: if both arguments
12099 are non-registers (e.g. memory := constant), force operand 1 into a
12101 rtx (* gen_unaligned_load)(rtx, rtx);
12102 rtx tmp_dest = operands[0];
12103 if (!s_register_operand (operands[0], <MODE>mode)
12104 && !s_register_operand (operands[1], <MODE>mode))
12105 operands[1] = force_reg (<MODE>mode, operands[1]);
12107 if (<MODE>mode == HImode)
12109 gen_unaligned_load = gen_unaligned_loadhiu;
12110 tmp_dest = gen_reg_rtx (SImode);
12113 gen_unaligned_load = gen_unaligned_loadsi;
12115 if (MEM_P (operands[1]))
12117 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
12118 if (<MODE>mode == HImode)
12119 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
12122 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
12127 (define_insn "<cdp>"
12128 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12129 (match_operand:SI 1 "immediate_operand" "n")
12130 (match_operand:SI 2 "immediate_operand" "n")
12131 (match_operand:SI 3 "immediate_operand" "n")
12132 (match_operand:SI 4 "immediate_operand" "n")
12133 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
12134 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
12136 arm_const_bounds (operands[0], 0, 16);
12137 arm_const_bounds (operands[1], 0, 16);
12138 arm_const_bounds (operands[2], 0, (1 << 5));
12139 arm_const_bounds (operands[3], 0, (1 << 5));
12140 arm_const_bounds (operands[4], 0, (1 << 5));
12141 arm_const_bounds (operands[5], 0, 8);
12142 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
12144 [(set_attr "length" "4")
12145 (set_attr "type" "coproc")])
12147 (define_insn "*ldc"
12148 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12149 (match_operand:SI 1 "immediate_operand" "n")
12150 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
12151 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
12153 arm_const_bounds (operands[0], 0, 16);
12154 arm_const_bounds (operands[1], 0, (1 << 5));
12155 return "<ldc>\\tp%c0, CR%c1, %2";
12157 [(set_attr "length" "4")
12158 (set_attr "type" "coproc")])
12160 (define_insn "*stc"
12161 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12162 (match_operand:SI 1 "immediate_operand" "n")
12163 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
12164 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
12166 arm_const_bounds (operands[0], 0, 16);
12167 arm_const_bounds (operands[1], 0, (1 << 5));
12168 return "<stc>\\tp%c0, CR%c1, %2";
12170 [(set_attr "length" "4")
12171 (set_attr "type" "coproc")])
12173 (define_expand "<ldc>"
12174 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12175 (match_operand:SI 1 "immediate_operand")
12176 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
12177 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
12179 (define_expand "<stc>"
12180 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12181 (match_operand:SI 1 "immediate_operand")
12182 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12183 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12185 (define_insn "<mcr>"
12186 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12187 (match_operand:SI 1 "immediate_operand" "n")
12188 (match_operand:SI 2 "s_register_operand" "r")
12189 (match_operand:SI 3 "immediate_operand" "n")
12190 (match_operand:SI 4 "immediate_operand" "n")
12191 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12192 (use (match_dup 2))]
12193 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12195 arm_const_bounds (operands[0], 0, 16);
12196 arm_const_bounds (operands[1], 0, 8);
12197 arm_const_bounds (operands[3], 0, (1 << 5));
12198 arm_const_bounds (operands[4], 0, (1 << 5));
12199 arm_const_bounds (operands[5], 0, 8);
12200 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12202 [(set_attr "length" "4")
12203 (set_attr "type" "coproc")])
12205 (define_insn "<mrc>"
12206 [(set (match_operand:SI 0 "s_register_operand" "=r")
12207 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12208 (match_operand:SI 2 "immediate_operand" "n")
12209 (match_operand:SI 3 "immediate_operand" "n")
12210 (match_operand:SI 4 "immediate_operand" "n")
12211 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12212 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12214 arm_const_bounds (operands[1], 0, 16);
12215 arm_const_bounds (operands[2], 0, 8);
12216 arm_const_bounds (operands[3], 0, (1 << 5));
12217 arm_const_bounds (operands[4], 0, (1 << 5));
12218 arm_const_bounds (operands[5], 0, 8);
12219 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12221 [(set_attr "length" "4")
12222 (set_attr "type" "coproc")])
12224 (define_insn "<mcrr>"
12225 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12226 (match_operand:SI 1 "immediate_operand" "n")
12227 (match_operand:DI 2 "s_register_operand" "r")
12228 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12229 (use (match_dup 2))]
12230 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12232 arm_const_bounds (operands[0], 0, 16);
12233 arm_const_bounds (operands[1], 0, 8);
12234 arm_const_bounds (operands[3], 0, (1 << 5));
12235 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12237 [(set_attr "length" "4")
12238 (set_attr "type" "coproc")])
12240 (define_insn "<mrrc>"
12241 [(set (match_operand:DI 0 "s_register_operand" "=r")
12242 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12243 (match_operand:SI 2 "immediate_operand" "n")
12244 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12245 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12247 arm_const_bounds (operands[1], 0, 16);
12248 arm_const_bounds (operands[2], 0, 8);
12249 arm_const_bounds (operands[3], 0, (1 << 5));
12250 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12252 [(set_attr "length" "4")
12253 (set_attr "type" "coproc")])
12255 (define_expand "speculation_barrier"
12256 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12259 /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
12260 have a usable barrier (and probably don't need one in practice).
12261 But to be safe if such code is run on later architectures, call a
12262 helper function in libgcc that will do the thing for the active
12264 if (!(arm_arch7 || arm_arch8))
12266 arm_emit_speculation_barrier_function ();
12272 ;; Generate a hard speculation barrier when we have not enabled speculation
12274 (define_insn "*speculation_barrier_insn"
12275 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12276 "arm_arch7 || arm_arch8"
12278 [(set_attr "type" "block")
12279 (set_attr "length" "8")]
12282 ;; Vector bits common to IWMMXT and Neon
12283 (include "vec-common.md")
12284 ;; Load the Intel Wireless Multimedia Extension patterns
12285 (include "iwmmxt.md")
12286 ;; Load the VFP co-processor patterns
12288 ;; Thumb-1 patterns
12289 (include "thumb1.md")
12290 ;; Thumb-2 patterns
12291 (include "thumb2.md")
12293 (include "neon.md")
12295 (include "crypto.md")
12296 ;; Synchronization Primitives
12297 (include "sync.md")
12298 ;; Fixed-point patterns
12299 (include "arm-fixed.md")