1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2018 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 can not 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,arm1020e,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" "!arm1020e,arm1022e,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, q, m")
5821 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5823 && !(TARGET_HARD_FLOAT)
5825 && ( register_operand (operands[0], DImode)
5826 || register_operand (operands[1], DImode))"
5828 switch (which_alternative)
5835 return output_move_double (operands, true, NULL);
5838 [(set_attr "length" "8,12,16,8,8")
5839 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5840 (set_attr "arm_pool_range" "*,*,*,1020,*")
5841 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5842 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5843 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5847 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5848 (match_operand:ANY64 1 "immediate_operand" ""))]
5851 && (arm_disable_literal_pool
5852 || (arm_const_double_inline_cost (operands[1])
5853 <= arm_max_const_double_inline_cost ()))"
5856 arm_split_constant (SET, SImode, curr_insn,
5857 INTVAL (gen_lowpart (SImode, operands[1])),
5858 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5859 arm_split_constant (SET, SImode, curr_insn,
5860 INTVAL (gen_highpart_mode (SImode,
5861 GET_MODE (operands[0]),
5863 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5868 ; If optimizing for size, or if we have load delay slots, then
5869 ; we want to split the constant into two separate operations.
5870 ; In both cases this may split a trivial part into a single data op
5871 ; leaving a single complex constant to load. We can also get longer
5872 ; offsets in a LDR which means we get better chances of sharing the pool
5873 ; entries. Finally, we can normally do a better job of scheduling
5874 ; LDR instructions than we can with LDM.
5875 ; This pattern will only match if the one above did not.
5877 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5878 (match_operand:ANY64 1 "const_double_operand" ""))]
5879 "TARGET_ARM && reload_completed
5880 && arm_const_double_by_parts (operands[1])"
5881 [(set (match_dup 0) (match_dup 1))
5882 (set (match_dup 2) (match_dup 3))]
5884 operands[2] = gen_highpart (SImode, operands[0]);
5885 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5887 operands[0] = gen_lowpart (SImode, operands[0]);
5888 operands[1] = gen_lowpart (SImode, operands[1]);
5893 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5894 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5895 "TARGET_EITHER && reload_completed"
5896 [(set (match_dup 0) (match_dup 1))
5897 (set (match_dup 2) (match_dup 3))]
5899 operands[2] = gen_highpart (SImode, operands[0]);
5900 operands[3] = gen_highpart (SImode, operands[1]);
5901 operands[0] = gen_lowpart (SImode, operands[0]);
5902 operands[1] = gen_lowpart (SImode, operands[1]);
5904 /* Handle a partial overlap. */
5905 if (rtx_equal_p (operands[0], operands[3]))
5907 rtx tmp0 = operands[0];
5908 rtx tmp1 = operands[1];
5910 operands[0] = operands[2];
5911 operands[1] = operands[3];
5918 ;; We can't actually do base+index doubleword loads if the index and
5919 ;; destination overlap. Split here so that we at least have chance to
5922 [(set (match_operand:DI 0 "s_register_operand" "")
5923 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5924 (match_operand:SI 2 "s_register_operand" ""))))]
5926 && reg_overlap_mentioned_p (operands[0], operands[1])
5927 && reg_overlap_mentioned_p (operands[0], operands[2])"
5929 (plus:SI (match_dup 1)
5932 (mem:DI (match_dup 4)))]
5934 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5938 (define_expand "movsi"
5939 [(set (match_operand:SI 0 "general_operand" "")
5940 (match_operand:SI 1 "general_operand" ""))]
5944 rtx base, offset, tmp;
5946 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5948 /* Everything except mem = const or mem = mem can be done easily. */
5949 if (MEM_P (operands[0]))
5950 operands[1] = force_reg (SImode, operands[1]);
5951 if (arm_general_register_operand (operands[0], SImode)
5952 && CONST_INT_P (operands[1])
5953 && !(const_ok_for_arm (INTVAL (operands[1]))
5954 || const_ok_for_arm (~INTVAL (operands[1]))))
5956 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5958 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5963 arm_split_constant (SET, SImode, NULL_RTX,
5964 INTVAL (operands[1]), operands[0], NULL_RTX,
5965 optimize && can_create_pseudo_p ());
5970 else /* Target doesn't have MOVT... */
5972 if (can_create_pseudo_p ())
5974 if (!REG_P (operands[0]))
5975 operands[1] = force_reg (SImode, operands[1]);
5979 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5981 split_const (operands[1], &base, &offset);
5982 if (GET_CODE (base) == SYMBOL_REF
5983 && !offset_within_block_p (base, INTVAL (offset)))
5985 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5986 emit_move_insn (tmp, base);
5987 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5992 /* Recognize the case where operand[1] is a reference to thread-local
5993 data and load its address to a register. */
5994 if (arm_tls_referenced_p (operands[1]))
5996 rtx tmp = operands[1];
5999 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6001 addend = XEXP (XEXP (tmp, 0), 1);
6002 tmp = XEXP (XEXP (tmp, 0), 0);
6005 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6006 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6008 tmp = legitimize_tls_address (tmp,
6009 !can_create_pseudo_p () ? operands[0] : 0);
6012 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6013 tmp = force_operand (tmp, operands[0]);
6018 && (CONSTANT_P (operands[1])
6019 || symbol_mentioned_p (operands[1])
6020 || label_mentioned_p (operands[1])))
6021 operands[1] = legitimize_pic_address (operands[1], SImode,
6022 (!can_create_pseudo_p ()
6029 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6030 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6031 ;; so this does not matter.
6032 (define_insn "*arm_movt"
6033 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6034 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6035 (match_operand:SI 2 "general_operand" "i,i")))]
6036 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6038 movt%?\t%0, #:upper16:%c2
6039 movt\t%0, #:upper16:%c2"
6040 [(set_attr "arch" "32,v8mb")
6041 (set_attr "predicable" "yes")
6042 (set_attr "length" "4")
6043 (set_attr "type" "alu_sreg")]
6046 (define_insn "*arm_movsi_insn"
6047 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6048 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6049 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6050 && ( register_operand (operands[0], SImode)
6051 || register_operand (operands[1], SImode))"
6059 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6060 (set_attr "predicable" "yes")
6061 (set_attr "arch" "*,*,*,v6t2,*,*")
6062 (set_attr "pool_range" "*,*,*,*,4096,*")
6063 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6067 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6068 (match_operand:SI 1 "const_int_operand" ""))]
6069 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6070 && (!(const_ok_for_arm (INTVAL (operands[1]))
6071 || const_ok_for_arm (~INTVAL (operands[1]))))"
6072 [(clobber (const_int 0))]
6074 arm_split_constant (SET, SImode, NULL_RTX,
6075 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6080 ;; A normal way to do (symbol + offset) requires three instructions at least
6081 ;; (depends on how big the offset is) as below:
6082 ;; movw r0, #:lower16:g
6083 ;; movw r0, #:upper16:g
6086 ;; A better way would be:
6087 ;; movw r0, #:lower16:g+4
6088 ;; movw r0, #:upper16:g+4
6090 ;; The limitation of this way is that the length of offset should be a 16-bit
6091 ;; signed value, because current assembler only supports REL type relocation for
6092 ;; such case. If the more powerful RELA type is supported in future, we should
6093 ;; update this pattern to go with better way.
6095 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6096 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6097 (match_operand:SI 2 "const_int_operand" ""))))]
6100 && arm_disable_literal_pool
6102 && GET_CODE (operands[1]) == SYMBOL_REF"
6103 [(clobber (const_int 0))]
6105 int offset = INTVAL (operands[2]);
6107 if (offset < -0x8000 || offset > 0x7fff)
6109 arm_emit_movpair (operands[0], operands[1]);
6110 emit_insn (gen_rtx_SET (operands[0],
6111 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6115 rtx op = gen_rtx_CONST (SImode,
6116 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6117 arm_emit_movpair (operands[0], op);
6122 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6123 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6124 ;; and lo_sum would be merged back into memory load at cprop. However,
6125 ;; if the default is to prefer movt/movw rather than a load from the constant
6126 ;; pool, the performance is better.
6128 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6129 (match_operand:SI 1 "general_operand" ""))]
6130 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6131 && !flag_pic && !target_word_relocations
6132 && !arm_tls_referenced_p (operands[1])"
6133 [(clobber (const_int 0))]
6135 arm_emit_movpair (operands[0], operands[1]);
6139 ;; When generating pic, we need to load the symbol offset into a register.
6140 ;; So that the optimizer does not confuse this with a normal symbol load
6141 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6142 ;; since that is the only type of relocation we can use.
6144 ;; Wrap calculation of the whole PIC address in a single pattern for the
6145 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6146 ;; a PIC address involves two loads from memory, so we want to CSE it
6147 ;; as often as possible.
6148 ;; This pattern will be split into one of the pic_load_addr_* patterns
6149 ;; and a move after GCSE optimizations.
6151 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6152 (define_expand "calculate_pic_address"
6153 [(set (match_operand:SI 0 "register_operand" "")
6154 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6155 (unspec:SI [(match_operand:SI 2 "" "")]
6160 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6162 [(set (match_operand:SI 0 "register_operand" "")
6163 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6164 (unspec:SI [(match_operand:SI 2 "" "")]
6167 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6168 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6169 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6172 ;; operand1 is the memory address to go into
6173 ;; pic_load_addr_32bit.
6174 ;; operand2 is the PIC label to be emitted
6175 ;; from pic_add_dot_plus_eight.
6176 ;; We do this to allow hoisting of the entire insn.
6177 (define_insn_and_split "pic_load_addr_unified"
6178 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6179 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6180 (match_operand:SI 2 "" "")]
6181 UNSPEC_PIC_UNIFIED))]
6184 "&& reload_completed"
6185 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6186 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6187 (match_dup 2)] UNSPEC_PIC_BASE))]
6188 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6189 [(set_attr "type" "load_4,load_4,load_4")
6190 (set_attr "pool_range" "4096,4094,1022")
6191 (set_attr "neg_pool_range" "4084,0,0")
6192 (set_attr "arch" "a,t2,t1")
6193 (set_attr "length" "8,6,4")]
6196 ;; The rather odd constraints on the following are to force reload to leave
6197 ;; the insn alone, and to force the minipool generation pass to then move
6198 ;; the GOT symbol to memory.
6200 (define_insn "pic_load_addr_32bit"
6201 [(set (match_operand:SI 0 "s_register_operand" "=r")
6202 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6203 "TARGET_32BIT && flag_pic"
6205 [(set_attr "type" "load_4")
6206 (set (attr "pool_range")
6207 (if_then_else (eq_attr "is_thumb" "no")
6210 (set (attr "neg_pool_range")
6211 (if_then_else (eq_attr "is_thumb" "no")
6216 (define_insn "pic_load_addr_thumb1"
6217 [(set (match_operand:SI 0 "s_register_operand" "=l")
6218 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6219 "TARGET_THUMB1 && flag_pic"
6221 [(set_attr "type" "load_4")
6222 (set (attr "pool_range") (const_int 1018))]
6225 (define_insn "pic_add_dot_plus_four"
6226 [(set (match_operand:SI 0 "register_operand" "=r")
6227 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6229 (match_operand 2 "" "")]
6233 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6234 INTVAL (operands[2]));
6235 return \"add\\t%0, %|pc\";
6237 [(set_attr "length" "2")
6238 (set_attr "type" "alu_sreg")]
6241 (define_insn "pic_add_dot_plus_eight"
6242 [(set (match_operand:SI 0 "register_operand" "=r")
6243 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6245 (match_operand 2 "" "")]
6249 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6250 INTVAL (operands[2]));
6251 return \"add%?\\t%0, %|pc, %1\";
6253 [(set_attr "predicable" "yes")
6254 (set_attr "type" "alu_sreg")]
6257 (define_insn "tls_load_dot_plus_eight"
6258 [(set (match_operand:SI 0 "register_operand" "=r")
6259 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6261 (match_operand 2 "" "")]
6265 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6266 INTVAL (operands[2]));
6267 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6269 [(set_attr "predicable" "yes")
6270 (set_attr "type" "load_4")]
6273 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6274 ;; followed by a load. These sequences can be crunched down to
6275 ;; tls_load_dot_plus_eight by a peephole.
6278 [(set (match_operand:SI 0 "register_operand" "")
6279 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6281 (match_operand 1 "" "")]
6283 (set (match_operand:SI 2 "arm_general_register_operand" "")
6284 (mem:SI (match_dup 0)))]
6285 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6287 (mem:SI (unspec:SI [(match_dup 3)
6294 (define_insn "pic_offset_arm"
6295 [(set (match_operand:SI 0 "register_operand" "=r")
6296 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6297 (unspec:SI [(match_operand:SI 2 "" "X")]
6298 UNSPEC_PIC_OFFSET))))]
6299 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6300 "ldr%?\\t%0, [%1,%2]"
6301 [(set_attr "type" "load_4")]
6304 (define_expand "builtin_setjmp_receiver"
6305 [(label_ref (match_operand 0 "" ""))]
6309 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6311 if (arm_pic_register != INVALID_REGNUM)
6312 arm_load_pic_register (1UL << 3);
6316 ;; If copying one reg to another we can set the condition codes according to
6317 ;; its value. Such a move is common after a return from subroutine and the
6318 ;; result is being tested against zero.
6320 (define_insn "*movsi_compare0"
6321 [(set (reg:CC CC_REGNUM)
6322 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6324 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6329 subs%?\\t%0, %1, #0"
6330 [(set_attr "conds" "set")
6331 (set_attr "type" "alus_imm,alus_imm")]
6334 ;; Subroutine to store a half word from a register into memory.
6335 ;; Operand 0 is the source register (HImode)
6336 ;; Operand 1 is the destination address in a register (SImode)
6338 ;; In both this routine and the next, we must be careful not to spill
6339 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6340 ;; can generate unrecognizable rtl.
6342 (define_expand "storehi"
6343 [;; store the low byte
6344 (set (match_operand 1 "" "") (match_dup 3))
6345 ;; extract the high byte
6347 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6348 ;; store the high byte
6349 (set (match_dup 4) (match_dup 5))]
6353 rtx op1 = operands[1];
6354 rtx addr = XEXP (op1, 0);
6355 enum rtx_code code = GET_CODE (addr);
6357 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6359 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6361 operands[4] = adjust_address (op1, QImode, 1);
6362 operands[1] = adjust_address (operands[1], QImode, 0);
6363 operands[3] = gen_lowpart (QImode, operands[0]);
6364 operands[0] = gen_lowpart (SImode, operands[0]);
6365 operands[2] = gen_reg_rtx (SImode);
6366 operands[5] = gen_lowpart (QImode, operands[2]);
6370 (define_expand "storehi_bigend"
6371 [(set (match_dup 4) (match_dup 3))
6373 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6374 (set (match_operand 1 "" "") (match_dup 5))]
6378 rtx op1 = operands[1];
6379 rtx addr = XEXP (op1, 0);
6380 enum rtx_code code = GET_CODE (addr);
6382 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6384 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6386 operands[4] = adjust_address (op1, QImode, 1);
6387 operands[1] = adjust_address (operands[1], QImode, 0);
6388 operands[3] = gen_lowpart (QImode, operands[0]);
6389 operands[0] = gen_lowpart (SImode, operands[0]);
6390 operands[2] = gen_reg_rtx (SImode);
6391 operands[5] = gen_lowpart (QImode, operands[2]);
6395 ;; Subroutine to store a half word integer constant into memory.
6396 (define_expand "storeinthi"
6397 [(set (match_operand 0 "" "")
6398 (match_operand 1 "" ""))
6399 (set (match_dup 3) (match_dup 2))]
6403 HOST_WIDE_INT value = INTVAL (operands[1]);
6404 rtx addr = XEXP (operands[0], 0);
6405 rtx op0 = operands[0];
6406 enum rtx_code code = GET_CODE (addr);
6408 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6410 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6412 operands[1] = gen_reg_rtx (SImode);
6413 if (BYTES_BIG_ENDIAN)
6415 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6416 if ((value & 255) == ((value >> 8) & 255))
6417 operands[2] = operands[1];
6420 operands[2] = gen_reg_rtx (SImode);
6421 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6426 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6427 if ((value & 255) == ((value >> 8) & 255))
6428 operands[2] = operands[1];
6431 operands[2] = gen_reg_rtx (SImode);
6432 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6436 operands[3] = adjust_address (op0, QImode, 1);
6437 operands[0] = adjust_address (operands[0], QImode, 0);
6438 operands[2] = gen_lowpart (QImode, operands[2]);
6439 operands[1] = gen_lowpart (QImode, operands[1]);
6443 (define_expand "storehi_single_op"
6444 [(set (match_operand:HI 0 "memory_operand" "")
6445 (match_operand:HI 1 "general_operand" ""))]
6446 "TARGET_32BIT && arm_arch4"
6448 if (!s_register_operand (operands[1], HImode))
6449 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6453 (define_expand "movhi"
6454 [(set (match_operand:HI 0 "general_operand" "")
6455 (match_operand:HI 1 "general_operand" ""))]
6460 if (can_create_pseudo_p ())
6462 if (MEM_P (operands[0]))
6466 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6469 if (CONST_INT_P (operands[1]))
6470 emit_insn (gen_storeinthi (operands[0], operands[1]));
6473 if (MEM_P (operands[1]))
6474 operands[1] = force_reg (HImode, operands[1]);
6475 if (BYTES_BIG_ENDIAN)
6476 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6478 emit_insn (gen_storehi (operands[1], operands[0]));
6482 /* Sign extend a constant, and keep it in an SImode reg. */
6483 else if (CONST_INT_P (operands[1]))
6485 rtx reg = gen_reg_rtx (SImode);
6486 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6488 /* If the constant is already valid, leave it alone. */
6489 if (!const_ok_for_arm (val))
6491 /* If setting all the top bits will make the constant
6492 loadable in a single instruction, then set them.
6493 Otherwise, sign extend the number. */
6495 if (const_ok_for_arm (~(val | ~0xffff)))
6497 else if (val & 0x8000)
6501 emit_insn (gen_movsi (reg, GEN_INT (val)));
6502 operands[1] = gen_lowpart (HImode, reg);
6504 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6505 && MEM_P (operands[1]))
6507 rtx reg = gen_reg_rtx (SImode);
6509 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6510 operands[1] = gen_lowpart (HImode, reg);
6512 else if (!arm_arch4)
6514 if (MEM_P (operands[1]))
6517 rtx offset = const0_rtx;
6518 rtx reg = gen_reg_rtx (SImode);
6520 if ((REG_P (base = XEXP (operands[1], 0))
6521 || (GET_CODE (base) == PLUS
6522 && (CONST_INT_P (offset = XEXP (base, 1)))
6523 && ((INTVAL(offset) & 1) != 1)
6524 && REG_P (base = XEXP (base, 0))))
6525 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6529 new_rtx = widen_memory_access (operands[1], SImode,
6530 ((INTVAL (offset) & ~3)
6531 - INTVAL (offset)));
6532 emit_insn (gen_movsi (reg, new_rtx));
6533 if (((INTVAL (offset) & 2) != 0)
6534 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6536 rtx reg2 = gen_reg_rtx (SImode);
6538 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6543 emit_insn (gen_movhi_bytes (reg, operands[1]));
6545 operands[1] = gen_lowpart (HImode, reg);
6549 /* Handle loading a large integer during reload. */
6550 else if (CONST_INT_P (operands[1])
6551 && !const_ok_for_arm (INTVAL (operands[1]))
6552 && !const_ok_for_arm (~INTVAL (operands[1])))
6554 /* Writing a constant to memory needs a scratch, which should
6555 be handled with SECONDARY_RELOADs. */
6556 gcc_assert (REG_P (operands[0]));
6558 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6559 emit_insn (gen_movsi (operands[0], operands[1]));
6563 else if (TARGET_THUMB2)
6565 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6566 if (can_create_pseudo_p ())
6568 if (!REG_P (operands[0]))
6569 operands[1] = force_reg (HImode, operands[1]);
6570 /* Zero extend a constant, and keep it in an SImode reg. */
6571 else if (CONST_INT_P (operands[1]))
6573 rtx reg = gen_reg_rtx (SImode);
6574 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6576 emit_insn (gen_movsi (reg, GEN_INT (val)));
6577 operands[1] = gen_lowpart (HImode, reg);
6581 else /* TARGET_THUMB1 */
6583 if (can_create_pseudo_p ())
6585 if (CONST_INT_P (operands[1]))
6587 rtx reg = gen_reg_rtx (SImode);
6589 emit_insn (gen_movsi (reg, operands[1]));
6590 operands[1] = gen_lowpart (HImode, reg);
6593 /* ??? We shouldn't really get invalid addresses here, but this can
6594 happen if we are passed a SP (never OK for HImode/QImode) or
6595 virtual register (also rejected as illegitimate for HImode/QImode)
6596 relative address. */
6597 /* ??? This should perhaps be fixed elsewhere, for instance, in
6598 fixup_stack_1, by checking for other kinds of invalid addresses,
6599 e.g. a bare reference to a virtual register. This may confuse the
6600 alpha though, which must handle this case differently. */
6601 if (MEM_P (operands[0])
6602 && !memory_address_p (GET_MODE (operands[0]),
6603 XEXP (operands[0], 0)))
6605 = replace_equiv_address (operands[0],
6606 copy_to_reg (XEXP (operands[0], 0)));
6608 if (MEM_P (operands[1])
6609 && !memory_address_p (GET_MODE (operands[1]),
6610 XEXP (operands[1], 0)))
6612 = replace_equiv_address (operands[1],
6613 copy_to_reg (XEXP (operands[1], 0)));
6615 if (MEM_P (operands[1]) && optimize > 0)
6617 rtx reg = gen_reg_rtx (SImode);
6619 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6620 operands[1] = gen_lowpart (HImode, reg);
6623 if (MEM_P (operands[0]))
6624 operands[1] = force_reg (HImode, operands[1]);
6626 else if (CONST_INT_P (operands[1])
6627 && !satisfies_constraint_I (operands[1]))
6629 /* Handle loading a large integer during reload. */
6631 /* Writing a constant to memory needs a scratch, which should
6632 be handled with SECONDARY_RELOADs. */
6633 gcc_assert (REG_P (operands[0]));
6635 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6636 emit_insn (gen_movsi (operands[0], operands[1]));
6643 (define_expand "movhi_bytes"
6644 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6646 (zero_extend:SI (match_dup 6)))
6647 (set (match_operand:SI 0 "" "")
6648 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6653 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6655 mem1 = change_address (operands[1], QImode, addr);
6656 mem2 = change_address (operands[1], QImode,
6657 plus_constant (Pmode, addr, 1));
6658 operands[0] = gen_lowpart (SImode, operands[0]);
6660 operands[2] = gen_reg_rtx (SImode);
6661 operands[3] = gen_reg_rtx (SImode);
6664 if (BYTES_BIG_ENDIAN)
6666 operands[4] = operands[2];
6667 operands[5] = operands[3];
6671 operands[4] = operands[3];
6672 operands[5] = operands[2];
6677 (define_expand "movhi_bigend"
6679 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6682 (ashiftrt:SI (match_dup 2) (const_int 16)))
6683 (set (match_operand:HI 0 "s_register_operand" "")
6687 operands[2] = gen_reg_rtx (SImode);
6688 operands[3] = gen_reg_rtx (SImode);
6689 operands[4] = gen_lowpart (HImode, operands[3]);
6693 ;; Pattern to recognize insn generated default case above
6694 (define_insn "*movhi_insn_arch4"
6695 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6696 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6698 && arm_arch4 && !TARGET_HARD_FLOAT
6699 && (register_operand (operands[0], HImode)
6700 || register_operand (operands[1], HImode))"
6702 mov%?\\t%0, %1\\t%@ movhi
6703 mvn%?\\t%0, #%B1\\t%@ movhi
6704 movw%?\\t%0, %L1\\t%@ movhi
6705 strh%?\\t%1, %0\\t%@ movhi
6706 ldrh%?\\t%0, %1\\t%@ movhi"
6707 [(set_attr "predicable" "yes")
6708 (set_attr "pool_range" "*,*,*,*,256")
6709 (set_attr "neg_pool_range" "*,*,*,*,244")
6710 (set_attr "arch" "*,*,v6t2,*,*")
6711 (set_attr_alternative "type"
6712 [(if_then_else (match_operand 1 "const_int_operand" "")
6713 (const_string "mov_imm" )
6714 (const_string "mov_reg"))
6715 (const_string "mvn_imm")
6716 (const_string "mov_imm")
6717 (const_string "store_4")
6718 (const_string "load_4")])]
6721 (define_insn "*movhi_bytes"
6722 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6723 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6724 "TARGET_ARM && !TARGET_HARD_FLOAT"
6726 mov%?\\t%0, %1\\t%@ movhi
6727 mov%?\\t%0, %1\\t%@ movhi
6728 mvn%?\\t%0, #%B1\\t%@ movhi"
6729 [(set_attr "predicable" "yes")
6730 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6733 ;; We use a DImode scratch because we may occasionally need an additional
6734 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6735 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6736 (define_expand "reload_outhi"
6737 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6738 (match_operand:HI 1 "s_register_operand" "r")
6739 (match_operand:DI 2 "s_register_operand" "=&l")])]
6742 arm_reload_out_hi (operands);
6744 thumb_reload_out_hi (operands);
6749 (define_expand "reload_inhi"
6750 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6751 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6752 (match_operand:DI 2 "s_register_operand" "=&r")])]
6756 arm_reload_in_hi (operands);
6758 thumb_reload_out_hi (operands);
6762 (define_expand "movqi"
6763 [(set (match_operand:QI 0 "general_operand" "")
6764 (match_operand:QI 1 "general_operand" ""))]
6767 /* Everything except mem = const or mem = mem can be done easily */
6769 if (can_create_pseudo_p ())
6771 if (CONST_INT_P (operands[1]))
6773 rtx reg = gen_reg_rtx (SImode);
6775 /* For thumb we want an unsigned immediate, then we are more likely
6776 to be able to use a movs insn. */
6778 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6780 emit_insn (gen_movsi (reg, operands[1]));
6781 operands[1] = gen_lowpart (QImode, reg);
6786 /* ??? We shouldn't really get invalid addresses here, but this can
6787 happen if we are passed a SP (never OK for HImode/QImode) or
6788 virtual register (also rejected as illegitimate for HImode/QImode)
6789 relative address. */
6790 /* ??? This should perhaps be fixed elsewhere, for instance, in
6791 fixup_stack_1, by checking for other kinds of invalid addresses,
6792 e.g. a bare reference to a virtual register. This may confuse the
6793 alpha though, which must handle this case differently. */
6794 if (MEM_P (operands[0])
6795 && !memory_address_p (GET_MODE (operands[0]),
6796 XEXP (operands[0], 0)))
6798 = replace_equiv_address (operands[0],
6799 copy_to_reg (XEXP (operands[0], 0)));
6800 if (MEM_P (operands[1])
6801 && !memory_address_p (GET_MODE (operands[1]),
6802 XEXP (operands[1], 0)))
6804 = replace_equiv_address (operands[1],
6805 copy_to_reg (XEXP (operands[1], 0)));
6808 if (MEM_P (operands[1]) && optimize > 0)
6810 rtx reg = gen_reg_rtx (SImode);
6812 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6813 operands[1] = gen_lowpart (QImode, reg);
6816 if (MEM_P (operands[0]))
6817 operands[1] = force_reg (QImode, operands[1]);
6819 else if (TARGET_THUMB
6820 && CONST_INT_P (operands[1])
6821 && !satisfies_constraint_I (operands[1]))
6823 /* Handle loading a large integer during reload. */
6825 /* Writing a constant to memory needs a scratch, which should
6826 be handled with SECONDARY_RELOADs. */
6827 gcc_assert (REG_P (operands[0]));
6829 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6830 emit_insn (gen_movsi (operands[0], operands[1]));
6836 (define_insn "*arm_movqi_insn"
6837 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6838 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6840 && ( register_operand (operands[0], QImode)
6841 || register_operand (operands[1], QImode))"
6852 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6853 (set_attr "predicable" "yes")
6854 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6855 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6856 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6860 (define_expand "movhf"
6861 [(set (match_operand:HF 0 "general_operand" "")
6862 (match_operand:HF 1 "general_operand" ""))]
6867 if (MEM_P (operands[0]))
6868 operands[1] = force_reg (HFmode, operands[1]);
6870 else /* TARGET_THUMB1 */
6872 if (can_create_pseudo_p ())
6874 if (!REG_P (operands[0]))
6875 operands[1] = force_reg (HFmode, operands[1]);
6881 (define_insn "*arm32_movhf"
6882 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6883 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6884 "TARGET_32BIT && !TARGET_HARD_FLOAT
6885 && ( s_register_operand (operands[0], HFmode)
6886 || s_register_operand (operands[1], HFmode))"
6888 switch (which_alternative)
6890 case 0: /* ARM register from memory */
6891 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6892 case 1: /* memory from ARM register */
6893 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6894 case 2: /* ARM register from ARM register */
6895 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6896 case 3: /* ARM register from constant */
6901 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6903 ops[0] = operands[0];
6904 ops[1] = GEN_INT (bits);
6905 ops[2] = GEN_INT (bits & 0xff00);
6906 ops[3] = GEN_INT (bits & 0x00ff);
6908 if (arm_arch_thumb2)
6909 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6911 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6918 [(set_attr "conds" "unconditional")
6919 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6920 (set_attr "length" "4,4,4,8")
6921 (set_attr "predicable" "yes")]
6924 (define_expand "movsf"
6925 [(set (match_operand:SF 0 "general_operand" "")
6926 (match_operand:SF 1 "general_operand" ""))]
6931 if (MEM_P (operands[0]))
6932 operands[1] = force_reg (SFmode, operands[1]);
6934 else /* TARGET_THUMB1 */
6936 if (can_create_pseudo_p ())
6938 if (!REG_P (operands[0]))
6939 operands[1] = force_reg (SFmode, operands[1]);
6945 ;; Transform a floating-point move of a constant into a core register into
6946 ;; an SImode operation.
6948 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6949 (match_operand:SF 1 "immediate_operand" ""))]
6952 && CONST_DOUBLE_P (operands[1])"
6953 [(set (match_dup 2) (match_dup 3))]
6955 operands[2] = gen_lowpart (SImode, operands[0]);
6956 operands[3] = gen_lowpart (SImode, operands[1]);
6957 if (operands[2] == 0 || operands[3] == 0)
6962 (define_insn "*arm_movsf_soft_insn"
6963 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6964 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6966 && TARGET_SOFT_FLOAT
6967 && (!MEM_P (operands[0])
6968 || register_operand (operands[1], SFmode))"
6971 ldr%?\\t%0, %1\\t%@ float
6972 str%?\\t%1, %0\\t%@ float"
6973 [(set_attr "predicable" "yes")
6974 (set_attr "type" "mov_reg,load_4,store_4")
6975 (set_attr "arm_pool_range" "*,4096,*")
6976 (set_attr "thumb2_pool_range" "*,4094,*")
6977 (set_attr "arm_neg_pool_range" "*,4084,*")
6978 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6981 (define_expand "movdf"
6982 [(set (match_operand:DF 0 "general_operand" "")
6983 (match_operand:DF 1 "general_operand" ""))]
6988 if (MEM_P (operands[0]))
6989 operands[1] = force_reg (DFmode, operands[1]);
6991 else /* TARGET_THUMB */
6993 if (can_create_pseudo_p ())
6995 if (!REG_P (operands[0]))
6996 operands[1] = force_reg (DFmode, operands[1]);
7002 ;; Reloading a df mode value stored in integer regs to memory can require a
7004 (define_expand "reload_outdf"
7005 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7006 (match_operand:DF 1 "s_register_operand" "r")
7007 (match_operand:SI 2 "s_register_operand" "=&r")]
7011 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7014 operands[2] = XEXP (operands[0], 0);
7015 else if (code == POST_INC || code == PRE_DEC)
7017 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7018 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7019 emit_insn (gen_movdi (operands[0], operands[1]));
7022 else if (code == PRE_INC)
7024 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7026 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7029 else if (code == POST_DEC)
7030 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7032 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7033 XEXP (XEXP (operands[0], 0), 1)));
7035 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7038 if (code == POST_DEC)
7039 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7045 (define_insn "*movdf_soft_insn"
7046 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7047 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7048 "TARGET_32BIT && TARGET_SOFT_FLOAT
7049 && ( register_operand (operands[0], DFmode)
7050 || register_operand (operands[1], DFmode))"
7052 switch (which_alternative)
7059 return output_move_double (operands, true, NULL);
7062 [(set_attr "length" "8,12,16,8,8")
7063 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7064 (set_attr "arm_pool_range" "*,*,*,1020,*")
7065 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7066 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7067 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7071 ;; load- and store-multiple insns
7072 ;; The arm can load/store any set of registers, provided that they are in
7073 ;; ascending order, but these expanders assume a contiguous set.
7075 (define_expand "load_multiple"
7076 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7077 (match_operand:SI 1 "" ""))
7078 (use (match_operand:SI 2 "" ""))])]
7081 HOST_WIDE_INT offset = 0;
7083 /* Support only fixed point registers. */
7084 if (!CONST_INT_P (operands[2])
7085 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7086 || INTVAL (operands[2]) < 2
7087 || !MEM_P (operands[1])
7088 || !REG_P (operands[0])
7089 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7090 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7094 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7095 INTVAL (operands[2]),
7096 force_reg (SImode, XEXP (operands[1], 0)),
7097 FALSE, operands[1], &offset);
7100 (define_expand "store_multiple"
7101 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7102 (match_operand:SI 1 "" ""))
7103 (use (match_operand:SI 2 "" ""))])]
7106 HOST_WIDE_INT offset = 0;
7108 /* Support only fixed point registers. */
7109 if (!CONST_INT_P (operands[2])
7110 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7111 || INTVAL (operands[2]) < 2
7112 || !REG_P (operands[1])
7113 || !MEM_P (operands[0])
7114 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7115 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7119 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7120 INTVAL (operands[2]),
7121 force_reg (SImode, XEXP (operands[0], 0)),
7122 FALSE, operands[0], &offset);
7126 (define_expand "setmemsi"
7127 [(match_operand:BLK 0 "general_operand" "")
7128 (match_operand:SI 1 "const_int_operand" "")
7129 (match_operand:SI 2 "const_int_operand" "")
7130 (match_operand:SI 3 "const_int_operand" "")]
7133 if (arm_gen_setmem (operands))
7140 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7141 ;; We could let this apply for blocks of less than this, but it clobbers so
7142 ;; many registers that there is then probably a better way.
7144 (define_expand "movmemqi"
7145 [(match_operand:BLK 0 "general_operand" "")
7146 (match_operand:BLK 1 "general_operand" "")
7147 (match_operand:SI 2 "const_int_operand" "")
7148 (match_operand:SI 3 "const_int_operand" "")]
7153 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7154 && !optimize_function_for_size_p (cfun))
7156 if (gen_movmem_ldrd_strd (operands))
7161 if (arm_gen_movmemqi (operands))
7165 else /* TARGET_THUMB1 */
7167 if ( INTVAL (operands[3]) != 4
7168 || INTVAL (operands[2]) > 48)
7171 thumb_expand_movmemqi (operands);
7178 ;; Compare & branch insns
7179 ;; The range calculations are based as follows:
7180 ;; For forward branches, the address calculation returns the address of
7181 ;; the next instruction. This is 2 beyond the branch instruction.
7182 ;; For backward branches, the address calculation returns the address of
7183 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7184 ;; instruction for the shortest sequence, and 4 before the branch instruction
7185 ;; if we have to jump around an unconditional branch.
7186 ;; To the basic branch range the PC offset must be added (this is +4).
7187 ;; So for forward branches we have
7188 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7189 ;; And for backward branches we have
7190 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7192 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7193 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7195 (define_expand "cbranchsi4"
7196 [(set (pc) (if_then_else
7197 (match_operator 0 "expandable_comparison_operator"
7198 [(match_operand:SI 1 "s_register_operand" "")
7199 (match_operand:SI 2 "nonmemory_operand" "")])
7200 (label_ref (match_operand 3 "" ""))
7206 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7208 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7212 if (thumb1_cmpneg_operand (operands[2], SImode))
7214 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7215 operands[3], operands[0]));
7218 if (!thumb1_cmp_operand (operands[2], SImode))
7219 operands[2] = force_reg (SImode, operands[2]);
7222 (define_expand "cbranchsf4"
7223 [(set (pc) (if_then_else
7224 (match_operator 0 "expandable_comparison_operator"
7225 [(match_operand:SF 1 "s_register_operand" "")
7226 (match_operand:SF 2 "vfp_compare_operand" "")])
7227 (label_ref (match_operand 3 "" ""))
7229 "TARGET_32BIT && TARGET_HARD_FLOAT"
7230 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7231 operands[3])); DONE;"
7234 (define_expand "cbranchdf4"
7235 [(set (pc) (if_then_else
7236 (match_operator 0 "expandable_comparison_operator"
7237 [(match_operand:DF 1 "s_register_operand" "")
7238 (match_operand:DF 2 "vfp_compare_operand" "")])
7239 (label_ref (match_operand 3 "" ""))
7241 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7242 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7243 operands[3])); DONE;"
7246 (define_expand "cbranchdi4"
7247 [(set (pc) (if_then_else
7248 (match_operator 0 "expandable_comparison_operator"
7249 [(match_operand:DI 1 "s_register_operand" "")
7250 (match_operand:DI 2 "cmpdi_operand" "")])
7251 (label_ref (match_operand 3 "" ""))
7255 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7257 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7263 ;; Comparison and test insns
7265 (define_insn "*arm_cmpsi_insn"
7266 [(set (reg:CC CC_REGNUM)
7267 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7268 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7276 [(set_attr "conds" "set")
7277 (set_attr "arch" "t2,t2,any,any,any")
7278 (set_attr "length" "2,2,4,4,4")
7279 (set_attr "predicable" "yes")
7280 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7281 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7284 (define_insn "*cmpsi_shiftsi"
7285 [(set (reg:CC CC_REGNUM)
7286 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7287 (match_operator:SI 3 "shift_operator"
7288 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7289 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7292 [(set_attr "conds" "set")
7293 (set_attr "shift" "1")
7294 (set_attr "arch" "32,a,a")
7295 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7297 (define_insn "*cmpsi_shiftsi_swp"
7298 [(set (reg:CC_SWP CC_REGNUM)
7299 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7300 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7301 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7302 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7305 [(set_attr "conds" "set")
7306 (set_attr "shift" "1")
7307 (set_attr "arch" "32,a,a")
7308 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7310 (define_insn "*arm_cmpsi_negshiftsi_si"
7311 [(set (reg:CC_Z CC_REGNUM)
7313 (neg:SI (match_operator:SI 1 "shift_operator"
7314 [(match_operand:SI 2 "s_register_operand" "r")
7315 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7316 (match_operand:SI 0 "s_register_operand" "r")))]
7319 [(set_attr "conds" "set")
7320 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7321 (const_string "alus_shift_imm")
7322 (const_string "alus_shift_reg")))
7323 (set_attr "predicable" "yes")]
7326 ;; DImode comparisons. The generic code generates branches that
7327 ;; if-conversion can not reduce to a conditional compare, so we do
7330 (define_insn_and_split "*arm_cmpdi_insn"
7331 [(set (reg:CC_NCV CC_REGNUM)
7332 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7333 (match_operand:DI 1 "arm_di_operand" "rDi")))
7334 (clobber (match_scratch:SI 2 "=r"))]
7336 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7337 "&& reload_completed"
7338 [(set (reg:CC CC_REGNUM)
7339 (compare:CC (match_dup 0) (match_dup 1)))
7340 (parallel [(set (reg:CC CC_REGNUM)
7341 (compare:CC (match_dup 3) (match_dup 4)))
7343 (minus:SI (match_dup 5)
7344 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7346 operands[3] = gen_highpart (SImode, operands[0]);
7347 operands[0] = gen_lowpart (SImode, operands[0]);
7348 if (CONST_INT_P (operands[1]))
7350 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7353 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7357 operands[4] = gen_highpart (SImode, operands[1]);
7358 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7360 operands[1] = gen_lowpart (SImode, operands[1]);
7361 operands[2] = gen_lowpart (SImode, operands[2]);
7363 [(set_attr "conds" "set")
7364 (set_attr "length" "8")
7365 (set_attr "type" "multiple")]
7368 (define_insn_and_split "*arm_cmpdi_unsigned"
7369 [(set (reg:CC_CZ CC_REGNUM)
7370 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7371 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7374 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7375 "&& reload_completed"
7376 [(set (reg:CC CC_REGNUM)
7377 (compare:CC (match_dup 2) (match_dup 3)))
7378 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7379 (set (reg:CC CC_REGNUM)
7380 (compare:CC (match_dup 0) (match_dup 1))))]
7382 operands[2] = gen_highpart (SImode, operands[0]);
7383 operands[0] = gen_lowpart (SImode, operands[0]);
7384 if (CONST_INT_P (operands[1]))
7385 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7387 operands[3] = gen_highpart (SImode, operands[1]);
7388 operands[1] = gen_lowpart (SImode, operands[1]);
7390 [(set_attr "conds" "set")
7391 (set_attr "enabled_for_short_it" "yes,yes,no,*")
7392 (set_attr "arch" "t2,t2,t2,a")
7393 (set_attr "length" "6,6,10,8")
7394 (set_attr "type" "multiple")]
7397 (define_insn "*arm_cmpdi_zero"
7398 [(set (reg:CC_Z CC_REGNUM)
7399 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7401 (clobber (match_scratch:SI 1 "=r"))]
7403 "orrs%?\\t%1, %Q0, %R0"
7404 [(set_attr "conds" "set")
7405 (set_attr "type" "logics_reg")]
7408 ; This insn allows redundant compares to be removed by cse, nothing should
7409 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7410 ; is deleted later on. The match_dup will match the mode here, so that
7411 ; mode changes of the condition codes aren't lost by this even though we don't
7412 ; specify what they are.
7414 (define_insn "*deleted_compare"
7415 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7417 "\\t%@ deleted compare"
7418 [(set_attr "conds" "set")
7419 (set_attr "length" "0")
7420 (set_attr "type" "no_insn")]
7424 ;; Conditional branch insns
7426 (define_expand "cbranch_cc"
7428 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7429 (match_operand 2 "" "")])
7430 (label_ref (match_operand 3 "" ""))
7433 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7434 operands[1], operands[2], NULL_RTX);
7435 operands[2] = const0_rtx;"
7439 ;; Patterns to match conditional branch insns.
7442 (define_insn "arm_cond_branch"
7444 (if_then_else (match_operator 1 "arm_comparison_operator"
7445 [(match_operand 2 "cc_register" "") (const_int 0)])
7446 (label_ref (match_operand 0 "" ""))
7450 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7452 arm_ccfsm_state += 2;
7455 return \"b%d1\\t%l0\";
7457 [(set_attr "conds" "use")
7458 (set_attr "type" "branch")
7459 (set (attr "length")
7461 (and (match_test "TARGET_THUMB2")
7462 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7463 (le (minus (match_dup 0) (pc)) (const_int 256))))
7468 (define_insn "*arm_cond_branch_reversed"
7470 (if_then_else (match_operator 1 "arm_comparison_operator"
7471 [(match_operand 2 "cc_register" "") (const_int 0)])
7473 (label_ref (match_operand 0 "" ""))))]
7476 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7478 arm_ccfsm_state += 2;
7481 return \"b%D1\\t%l0\";
7483 [(set_attr "conds" "use")
7484 (set_attr "type" "branch")
7485 (set (attr "length")
7487 (and (match_test "TARGET_THUMB2")
7488 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7489 (le (minus (match_dup 0) (pc)) (const_int 256))))
7498 (define_expand "cstore_cc"
7499 [(set (match_operand:SI 0 "s_register_operand" "")
7500 (match_operator:SI 1 "" [(match_operand 2 "" "")
7501 (match_operand 3 "" "")]))]
7503 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7504 operands[2], operands[3], NULL_RTX);
7505 operands[3] = const0_rtx;"
7508 (define_insn_and_split "*mov_scc"
7509 [(set (match_operand:SI 0 "s_register_operand" "=r")
7510 (match_operator:SI 1 "arm_comparison_operator_mode"
7511 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7513 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7516 (if_then_else:SI (match_dup 1)
7520 [(set_attr "conds" "use")
7521 (set_attr "length" "8")
7522 (set_attr "type" "multiple")]
7525 (define_insn_and_split "*mov_negscc"
7526 [(set (match_operand:SI 0 "s_register_operand" "=r")
7527 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7528 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7530 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7533 (if_then_else:SI (match_dup 1)
7537 operands[3] = GEN_INT (~0);
7539 [(set_attr "conds" "use")
7540 (set_attr "length" "8")
7541 (set_attr "type" "multiple")]
7544 (define_insn_and_split "*mov_notscc"
7545 [(set (match_operand:SI 0 "s_register_operand" "=r")
7546 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7547 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7549 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7552 (if_then_else:SI (match_dup 1)
7556 operands[3] = GEN_INT (~1);
7557 operands[4] = GEN_INT (~0);
7559 [(set_attr "conds" "use")
7560 (set_attr "length" "8")
7561 (set_attr "type" "multiple")]
7564 (define_expand "cstoresi4"
7565 [(set (match_operand:SI 0 "s_register_operand" "")
7566 (match_operator:SI 1 "expandable_comparison_operator"
7567 [(match_operand:SI 2 "s_register_operand" "")
7568 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7569 "TARGET_32BIT || TARGET_THUMB1"
7571 rtx op3, scratch, scratch2;
7575 if (!arm_add_operand (operands[3], SImode))
7576 operands[3] = force_reg (SImode, operands[3]);
7577 emit_insn (gen_cstore_cc (operands[0], operands[1],
7578 operands[2], operands[3]));
7582 if (operands[3] == const0_rtx)
7584 switch (GET_CODE (operands[1]))
7587 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7591 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7595 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7596 NULL_RTX, 0, OPTAB_WIDEN);
7597 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7598 NULL_RTX, 0, OPTAB_WIDEN);
7599 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7600 operands[0], 1, OPTAB_WIDEN);
7604 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7606 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7607 NULL_RTX, 1, OPTAB_WIDEN);
7611 scratch = expand_binop (SImode, ashr_optab, operands[2],
7612 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7613 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7614 NULL_RTX, 0, OPTAB_WIDEN);
7615 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7619 /* LT is handled by generic code. No need for unsigned with 0. */
7626 switch (GET_CODE (operands[1]))
7629 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7630 NULL_RTX, 0, OPTAB_WIDEN);
7631 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7635 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7636 NULL_RTX, 0, OPTAB_WIDEN);
7637 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7641 op3 = force_reg (SImode, operands[3]);
7643 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7644 NULL_RTX, 1, OPTAB_WIDEN);
7645 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7646 NULL_RTX, 0, OPTAB_WIDEN);
7647 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7653 if (!thumb1_cmp_operand (op3, SImode))
7654 op3 = force_reg (SImode, op3);
7655 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7656 NULL_RTX, 0, OPTAB_WIDEN);
7657 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7658 NULL_RTX, 1, OPTAB_WIDEN);
7659 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7664 op3 = force_reg (SImode, operands[3]);
7665 scratch = force_reg (SImode, const0_rtx);
7666 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7672 if (!thumb1_cmp_operand (op3, SImode))
7673 op3 = force_reg (SImode, op3);
7674 scratch = force_reg (SImode, const0_rtx);
7675 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7681 if (!thumb1_cmp_operand (op3, SImode))
7682 op3 = force_reg (SImode, op3);
7683 scratch = gen_reg_rtx (SImode);
7684 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7688 op3 = force_reg (SImode, operands[3]);
7689 scratch = gen_reg_rtx (SImode);
7690 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7693 /* No good sequences for GT, LT. */
7700 (define_expand "cstorehf4"
7701 [(set (match_operand:SI 0 "s_register_operand")
7702 (match_operator:SI 1 "expandable_comparison_operator"
7703 [(match_operand:HF 2 "s_register_operand")
7704 (match_operand:HF 3 "vfp_compare_operand")]))]
7705 "TARGET_VFP_FP16INST"
7707 if (!arm_validize_comparison (&operands[1],
7712 emit_insn (gen_cstore_cc (operands[0], operands[1],
7713 operands[2], operands[3]));
7718 (define_expand "cstoresf4"
7719 [(set (match_operand:SI 0 "s_register_operand" "")
7720 (match_operator:SI 1 "expandable_comparison_operator"
7721 [(match_operand:SF 2 "s_register_operand" "")
7722 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7723 "TARGET_32BIT && TARGET_HARD_FLOAT"
7724 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7725 operands[2], operands[3])); DONE;"
7728 (define_expand "cstoredf4"
7729 [(set (match_operand:SI 0 "s_register_operand" "")
7730 (match_operator:SI 1 "expandable_comparison_operator"
7731 [(match_operand:DF 2 "s_register_operand" "")
7732 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7733 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7734 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7735 operands[2], operands[3])); DONE;"
7738 (define_expand "cstoredi4"
7739 [(set (match_operand:SI 0 "s_register_operand" "")
7740 (match_operator:SI 1 "expandable_comparison_operator"
7741 [(match_operand:DI 2 "s_register_operand" "")
7742 (match_operand:DI 3 "cmpdi_operand" "")]))]
7745 if (!arm_validize_comparison (&operands[1],
7749 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7756 ;; Conditional move insns
7758 (define_expand "movsicc"
7759 [(set (match_operand:SI 0 "s_register_operand" "")
7760 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7761 (match_operand:SI 2 "arm_not_operand" "")
7762 (match_operand:SI 3 "arm_not_operand" "")))]
7769 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7770 &XEXP (operands[1], 1)))
7773 code = GET_CODE (operands[1]);
7774 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7775 XEXP (operands[1], 1), NULL_RTX);
7776 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7780 (define_expand "movhfcc"
7781 [(set (match_operand:HF 0 "s_register_operand")
7782 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7783 (match_operand:HF 2 "s_register_operand")
7784 (match_operand:HF 3 "s_register_operand")))]
7785 "TARGET_VFP_FP16INST"
7788 enum rtx_code code = GET_CODE (operands[1]);
7791 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7792 &XEXP (operands[1], 1)))
7795 code = GET_CODE (operands[1]);
7796 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7797 XEXP (operands[1], 1), NULL_RTX);
7798 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7802 (define_expand "movsfcc"
7803 [(set (match_operand:SF 0 "s_register_operand" "")
7804 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7805 (match_operand:SF 2 "s_register_operand" "")
7806 (match_operand:SF 3 "s_register_operand" "")))]
7807 "TARGET_32BIT && TARGET_HARD_FLOAT"
7810 enum rtx_code code = GET_CODE (operands[1]);
7813 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7814 &XEXP (operands[1], 1)))
7817 code = GET_CODE (operands[1]);
7818 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7819 XEXP (operands[1], 1), NULL_RTX);
7820 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7824 (define_expand "movdfcc"
7825 [(set (match_operand:DF 0 "s_register_operand" "")
7826 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7827 (match_operand:DF 2 "s_register_operand" "")
7828 (match_operand:DF 3 "s_register_operand" "")))]
7829 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7832 enum rtx_code code = GET_CODE (operands[1]);
7835 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7836 &XEXP (operands[1], 1)))
7838 code = GET_CODE (operands[1]);
7839 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7840 XEXP (operands[1], 1), NULL_RTX);
7841 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7845 (define_insn "*cmov<mode>"
7846 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7847 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7848 [(match_operand 2 "cc_register" "") (const_int 0)])
7849 (match_operand:SDF 3 "s_register_operand"
7851 (match_operand:SDF 4 "s_register_operand"
7852 "<F_constraint>")))]
7853 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7856 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7863 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7868 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7874 [(set_attr "conds" "use")
7875 (set_attr "type" "fcsel")]
7878 (define_insn "*cmovhf"
7879 [(set (match_operand:HF 0 "s_register_operand" "=t")
7880 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7881 [(match_operand 2 "cc_register" "") (const_int 0)])
7882 (match_operand:HF 3 "s_register_operand" "t")
7883 (match_operand:HF 4 "s_register_operand" "t")))]
7884 "TARGET_VFP_FP16INST"
7887 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7894 return \"vsel%d1.f16\\t%0, %3, %4\";
7899 return \"vsel%D1.f16\\t%0, %4, %3\";
7905 [(set_attr "conds" "use")
7906 (set_attr "type" "fcsel")]
7909 (define_insn_and_split "*movsicc_insn"
7910 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7912 (match_operator 3 "arm_comparison_operator"
7913 [(match_operand 4 "cc_register" "") (const_int 0)])
7914 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7915 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7926 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7927 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7928 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7929 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7930 "&& reload_completed"
7933 enum rtx_code rev_code;
7937 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7939 gen_rtx_SET (operands[0], operands[1])));
7941 rev_code = GET_CODE (operands[3]);
7942 mode = GET_MODE (operands[4]);
7943 if (mode == CCFPmode || mode == CCFPEmode)
7944 rev_code = reverse_condition_maybe_unordered (rev_code);
7946 rev_code = reverse_condition (rev_code);
7948 rev_cond = gen_rtx_fmt_ee (rev_code,
7952 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7954 gen_rtx_SET (operands[0], operands[2])));
7957 [(set_attr "length" "4,4,4,4,8,8,8,8")
7958 (set_attr "conds" "use")
7959 (set_attr_alternative "type"
7960 [(if_then_else (match_operand 2 "const_int_operand" "")
7961 (const_string "mov_imm")
7962 (const_string "mov_reg"))
7963 (const_string "mvn_imm")
7964 (if_then_else (match_operand 1 "const_int_operand" "")
7965 (const_string "mov_imm")
7966 (const_string "mov_reg"))
7967 (const_string "mvn_imm")
7968 (const_string "multiple")
7969 (const_string "multiple")
7970 (const_string "multiple")
7971 (const_string "multiple")])]
7974 (define_insn "*movsfcc_soft_insn"
7975 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7976 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7977 [(match_operand 4 "cc_register" "") (const_int 0)])
7978 (match_operand:SF 1 "s_register_operand" "0,r")
7979 (match_operand:SF 2 "s_register_operand" "r,0")))]
7980 "TARGET_ARM && TARGET_SOFT_FLOAT"
7984 [(set_attr "conds" "use")
7985 (set_attr "type" "mov_reg")]
7989 ;; Jump and linkage insns
7991 (define_expand "jump"
7993 (label_ref (match_operand 0 "" "")))]
7998 (define_insn "*arm_jump"
8000 (label_ref (match_operand 0 "" "")))]
8004 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8006 arm_ccfsm_state += 2;
8009 return \"b%?\\t%l0\";
8012 [(set_attr "predicable" "yes")
8013 (set (attr "length")
8015 (and (match_test "TARGET_THUMB2")
8016 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8017 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8020 (set_attr "type" "branch")]
8023 (define_expand "call"
8024 [(parallel [(call (match_operand 0 "memory_operand" "")
8025 (match_operand 1 "general_operand" ""))
8026 (use (match_operand 2 "" ""))
8027 (clobber (reg:SI LR_REGNUM))])]
8032 tree addr = MEM_EXPR (operands[0]);
8034 /* In an untyped call, we can get NULL for operand 2. */
8035 if (operands[2] == NULL_RTX)
8036 operands[2] = const0_rtx;
8038 /* Decide if we should generate indirect calls by loading the
8039 32-bit address of the callee into a register before performing the
8041 callee = XEXP (operands[0], 0);
8042 if (GET_CODE (callee) == SYMBOL_REF
8043 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8045 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8047 if (detect_cmse_nonsecure_call (addr))
8049 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8051 emit_call_insn (pat);
8055 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8056 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8062 (define_expand "call_internal"
8063 [(parallel [(call (match_operand 0 "memory_operand" "")
8064 (match_operand 1 "general_operand" ""))
8065 (use (match_operand 2 "" ""))
8066 (clobber (reg:SI LR_REGNUM))])])
8068 (define_expand "nonsecure_call_internal"
8069 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8070 UNSPEC_NONSECURE_MEM)
8071 (match_operand 1 "general_operand" ""))
8072 (use (match_operand 2 "" ""))
8073 (clobber (reg:SI LR_REGNUM))])]
8078 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8079 gen_rtx_REG (SImode, R4_REGNUM),
8082 operands[0] = replace_equiv_address (operands[0], tmp);
8085 (define_insn "*call_reg_armv5"
8086 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8087 (match_operand 1 "" ""))
8088 (use (match_operand 2 "" ""))
8089 (clobber (reg:SI LR_REGNUM))]
8090 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8092 [(set_attr "type" "call")]
8095 (define_insn "*call_reg_arm"
8096 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8097 (match_operand 1 "" ""))
8098 (use (match_operand 2 "" ""))
8099 (clobber (reg:SI LR_REGNUM))]
8100 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8102 return output_call (operands);
8104 ;; length is worst case, normally it is only two
8105 [(set_attr "length" "12")
8106 (set_attr "type" "call")]
8110 (define_expand "call_value"
8111 [(parallel [(set (match_operand 0 "" "")
8112 (call (match_operand 1 "memory_operand" "")
8113 (match_operand 2 "general_operand" "")))
8114 (use (match_operand 3 "" ""))
8115 (clobber (reg:SI LR_REGNUM))])]
8120 tree addr = MEM_EXPR (operands[1]);
8122 /* In an untyped call, we can get NULL for operand 2. */
8123 if (operands[3] == 0)
8124 operands[3] = const0_rtx;
8126 /* Decide if we should generate indirect calls by loading the
8127 32-bit address of the callee into a register before performing the
8129 callee = XEXP (operands[1], 0);
8130 if (GET_CODE (callee) == SYMBOL_REF
8131 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8133 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8135 if (detect_cmse_nonsecure_call (addr))
8137 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8138 operands[2], operands[3]);
8139 emit_call_insn (pat);
8143 pat = gen_call_value_internal (operands[0], operands[1],
8144 operands[2], operands[3]);
8145 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8151 (define_expand "call_value_internal"
8152 [(parallel [(set (match_operand 0 "" "")
8153 (call (match_operand 1 "memory_operand" "")
8154 (match_operand 2 "general_operand" "")))
8155 (use (match_operand 3 "" ""))
8156 (clobber (reg:SI LR_REGNUM))])])
8158 (define_expand "nonsecure_call_value_internal"
8159 [(parallel [(set (match_operand 0 "" "")
8160 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8161 UNSPEC_NONSECURE_MEM)
8162 (match_operand 2 "general_operand" "")))
8163 (use (match_operand 3 "" ""))
8164 (clobber (reg:SI LR_REGNUM))])]
8169 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8170 gen_rtx_REG (SImode, R4_REGNUM),
8173 operands[1] = replace_equiv_address (operands[1], tmp);
8176 (define_insn "*call_value_reg_armv5"
8177 [(set (match_operand 0 "" "")
8178 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8179 (match_operand 2 "" "")))
8180 (use (match_operand 3 "" ""))
8181 (clobber (reg:SI LR_REGNUM))]
8182 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8184 [(set_attr "type" "call")]
8187 (define_insn "*call_value_reg_arm"
8188 [(set (match_operand 0 "" "")
8189 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8190 (match_operand 2 "" "")))
8191 (use (match_operand 3 "" ""))
8192 (clobber (reg:SI LR_REGNUM))]
8193 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8195 return output_call (&operands[1]);
8197 [(set_attr "length" "12")
8198 (set_attr "type" "call")]
8201 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8202 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8204 (define_insn "*call_symbol"
8205 [(call (mem:SI (match_operand:SI 0 "" ""))
8206 (match_operand 1 "" ""))
8207 (use (match_operand 2 "" ""))
8208 (clobber (reg:SI LR_REGNUM))]
8210 && !SIBLING_CALL_P (insn)
8211 && (GET_CODE (operands[0]) == SYMBOL_REF)
8212 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8215 rtx op = operands[0];
8217 /* Switch mode now when possible. */
8218 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8219 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8220 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8222 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8224 [(set_attr "type" "call")]
8227 (define_insn "*call_value_symbol"
8228 [(set (match_operand 0 "" "")
8229 (call (mem:SI (match_operand:SI 1 "" ""))
8230 (match_operand:SI 2 "" "")))
8231 (use (match_operand 3 "" ""))
8232 (clobber (reg:SI LR_REGNUM))]
8234 && !SIBLING_CALL_P (insn)
8235 && (GET_CODE (operands[1]) == SYMBOL_REF)
8236 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8239 rtx op = operands[1];
8241 /* Switch mode now when possible. */
8242 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8243 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8244 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8246 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8248 [(set_attr "type" "call")]
8251 (define_expand "sibcall_internal"
8252 [(parallel [(call (match_operand 0 "memory_operand" "")
8253 (match_operand 1 "general_operand" ""))
8255 (use (match_operand 2 "" ""))])])
8257 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8258 (define_expand "sibcall"
8259 [(parallel [(call (match_operand 0 "memory_operand" "")
8260 (match_operand 1 "general_operand" ""))
8262 (use (match_operand 2 "" ""))])]
8268 if ((!REG_P (XEXP (operands[0], 0))
8269 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8270 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8271 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8272 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8274 if (operands[2] == NULL_RTX)
8275 operands[2] = const0_rtx;
8277 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8278 arm_emit_call_insn (pat, operands[0], true);
8283 (define_expand "sibcall_value_internal"
8284 [(parallel [(set (match_operand 0 "" "")
8285 (call (match_operand 1 "memory_operand" "")
8286 (match_operand 2 "general_operand" "")))
8288 (use (match_operand 3 "" ""))])])
8290 (define_expand "sibcall_value"
8291 [(parallel [(set (match_operand 0 "" "")
8292 (call (match_operand 1 "memory_operand" "")
8293 (match_operand 2 "general_operand" "")))
8295 (use (match_operand 3 "" ""))])]
8301 if ((!REG_P (XEXP (operands[1], 0))
8302 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8303 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8304 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8305 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8307 if (operands[3] == NULL_RTX)
8308 operands[3] = const0_rtx;
8310 pat = gen_sibcall_value_internal (operands[0], operands[1],
8311 operands[2], operands[3]);
8312 arm_emit_call_insn (pat, operands[1], true);
8317 (define_insn "*sibcall_insn"
8318 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8319 (match_operand 1 "" ""))
8321 (use (match_operand 2 "" ""))]
8322 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8324 if (which_alternative == 1)
8325 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8328 if (arm_arch5t || arm_arch4t)
8329 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8331 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8334 [(set_attr "type" "call")]
8337 (define_insn "*sibcall_value_insn"
8338 [(set (match_operand 0 "" "")
8339 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8340 (match_operand 2 "" "")))
8342 (use (match_operand 3 "" ""))]
8343 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8345 if (which_alternative == 1)
8346 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8349 if (arm_arch5t || arm_arch4t)
8350 return \"bx%?\\t%1\";
8352 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8355 [(set_attr "type" "call")]
8358 (define_expand "<return_str>return"
8360 "(TARGET_ARM || (TARGET_THUMB2
8361 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8362 && !IS_STACKALIGN (arm_current_func_type ())))
8363 <return_cond_false>"
8368 thumb2_expand_return (<return_simple_p>);
8375 ;; Often the return insn will be the same as loading from memory, so set attr
8376 (define_insn "*arm_return"
8378 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8381 if (arm_ccfsm_state == 2)
8383 arm_ccfsm_state += 2;
8386 return output_return_instruction (const_true_rtx, true, false, false);
8388 [(set_attr "type" "load_4")
8389 (set_attr "length" "12")
8390 (set_attr "predicable" "yes")]
8393 (define_insn "*cond_<return_str>return"
8395 (if_then_else (match_operator 0 "arm_comparison_operator"
8396 [(match_operand 1 "cc_register" "") (const_int 0)])
8399 "TARGET_ARM <return_cond_true>"
8402 if (arm_ccfsm_state == 2)
8404 arm_ccfsm_state += 2;
8407 return output_return_instruction (operands[0], true, false,
8410 [(set_attr "conds" "use")
8411 (set_attr "length" "12")
8412 (set_attr "type" "load_4")]
8415 (define_insn "*cond_<return_str>return_inverted"
8417 (if_then_else (match_operator 0 "arm_comparison_operator"
8418 [(match_operand 1 "cc_register" "") (const_int 0)])
8421 "TARGET_ARM <return_cond_true>"
8424 if (arm_ccfsm_state == 2)
8426 arm_ccfsm_state += 2;
8429 return output_return_instruction (operands[0], true, true,
8432 [(set_attr "conds" "use")
8433 (set_attr "length" "12")
8434 (set_attr "type" "load_4")]
8437 (define_insn "*arm_simple_return"
8442 if (arm_ccfsm_state == 2)
8444 arm_ccfsm_state += 2;
8447 return output_return_instruction (const_true_rtx, true, false, true);
8449 [(set_attr "type" "branch")
8450 (set_attr "length" "4")
8451 (set_attr "predicable" "yes")]
8454 ;; Generate a sequence of instructions to determine if the processor is
8455 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8458 (define_expand "return_addr_mask"
8460 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8462 (set (match_operand:SI 0 "s_register_operand" "")
8463 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8465 (const_int 67108860)))] ; 0x03fffffc
8468 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8471 (define_insn "*check_arch2"
8472 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8473 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8476 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8477 [(set_attr "length" "8")
8478 (set_attr "conds" "set")
8479 (set_attr "type" "multiple")]
8482 ;; Call subroutine returning any type.
8484 (define_expand "untyped_call"
8485 [(parallel [(call (match_operand 0 "" "")
8487 (match_operand 1 "" "")
8488 (match_operand 2 "" "")])]
8493 rtx par = gen_rtx_PARALLEL (VOIDmode,
8494 rtvec_alloc (XVECLEN (operands[2], 0)));
8495 rtx addr = gen_reg_rtx (Pmode);
8499 emit_move_insn (addr, XEXP (operands[1], 0));
8500 mem = change_address (operands[1], BLKmode, addr);
8502 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8504 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8506 /* Default code only uses r0 as a return value, but we could
8507 be using anything up to 4 registers. */
8508 if (REGNO (src) == R0_REGNUM)
8509 src = gen_rtx_REG (TImode, R0_REGNUM);
8511 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8513 size += GET_MODE_SIZE (GET_MODE (src));
8516 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8520 for (i = 0; i < XVECLEN (par, 0); i++)
8522 HOST_WIDE_INT offset = 0;
8523 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8526 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8528 mem = change_address (mem, GET_MODE (reg), NULL);
8529 if (REGNO (reg) == R0_REGNUM)
8531 /* On thumb we have to use a write-back instruction. */
8532 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8533 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8534 size = TARGET_ARM ? 16 : 0;
8538 emit_move_insn (mem, reg);
8539 size = GET_MODE_SIZE (GET_MODE (reg));
8543 /* The optimizer does not know that the call sets the function value
8544 registers we stored in the result block. We avoid problems by
8545 claiming that all hard registers are used and clobbered at this
8547 emit_insn (gen_blockage ());
8553 (define_expand "untyped_return"
8554 [(match_operand:BLK 0 "memory_operand" "")
8555 (match_operand 1 "" "")]
8560 rtx addr = gen_reg_rtx (Pmode);
8564 emit_move_insn (addr, XEXP (operands[0], 0));
8565 mem = change_address (operands[0], BLKmode, addr);
8567 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8569 HOST_WIDE_INT offset = 0;
8570 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8573 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8575 mem = change_address (mem, GET_MODE (reg), NULL);
8576 if (REGNO (reg) == R0_REGNUM)
8578 /* On thumb we have to use a write-back instruction. */
8579 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8580 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8581 size = TARGET_ARM ? 16 : 0;
8585 emit_move_insn (reg, mem);
8586 size = GET_MODE_SIZE (GET_MODE (reg));
8590 /* Emit USE insns before the return. */
8591 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8592 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8594 /* Construct the return. */
8595 expand_naked_return ();
8601 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8602 ;; all of memory. This blocks insns from being moved across this point.
8604 (define_insn "blockage"
8605 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8608 [(set_attr "length" "0")
8609 (set_attr "type" "block")]
8612 ;; Since we hard code r0 here use the 'o' constraint to prevent
8613 ;; provoking undefined behaviour in the hardware with putting out
8614 ;; auto-increment operations with potentially r0 as the base register.
8615 (define_insn "probe_stack"
8616 [(set (match_operand:SI 0 "memory_operand" "=o")
8617 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8620 [(set_attr "type" "store_4")
8621 (set_attr "predicable" "yes")]
8624 (define_insn "probe_stack_range"
8625 [(set (match_operand:SI 0 "register_operand" "=r")
8626 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8627 (match_operand:SI 2 "register_operand" "r")]
8628 VUNSPEC_PROBE_STACK_RANGE))]
8631 return output_probe_stack_range (operands[0], operands[2]);
8633 [(set_attr "type" "multiple")
8634 (set_attr "conds" "clob")]
8637 (define_expand "casesi"
8638 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8639 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8640 (match_operand:SI 2 "const_int_operand" "") ; total range
8641 (match_operand:SI 3 "" "") ; table label
8642 (match_operand:SI 4 "" "")] ; Out of range label
8643 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8646 enum insn_code code;
8647 if (operands[1] != const0_rtx)
8649 rtx reg = gen_reg_rtx (SImode);
8651 emit_insn (gen_addsi3 (reg, operands[0],
8652 gen_int_mode (-INTVAL (operands[1]),
8658 code = CODE_FOR_arm_casesi_internal;
8659 else if (TARGET_THUMB1)
8660 code = CODE_FOR_thumb1_casesi_internal_pic;
8662 code = CODE_FOR_thumb2_casesi_internal_pic;
8664 code = CODE_FOR_thumb2_casesi_internal;
8666 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8667 operands[2] = force_reg (SImode, operands[2]);
8669 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8670 operands[3], operands[4]));
8675 ;; The USE in this pattern is needed to tell flow analysis that this is
8676 ;; a CASESI insn. It has no other purpose.
8677 (define_insn "arm_casesi_internal"
8678 [(parallel [(set (pc)
8680 (leu (match_operand:SI 0 "s_register_operand" "r")
8681 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8682 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8683 (label_ref (match_operand 2 "" ""))))
8684 (label_ref (match_operand 3 "" ""))))
8685 (clobber (reg:CC CC_REGNUM))
8686 (use (label_ref (match_dup 2)))])]
8690 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8691 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8693 [(set_attr "conds" "clob")
8694 (set_attr "length" "12")
8695 (set_attr "type" "multiple")]
8698 (define_expand "indirect_jump"
8700 (match_operand:SI 0 "s_register_operand" ""))]
8703 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8704 address and use bx. */
8708 tmp = gen_reg_rtx (SImode);
8709 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8715 ;; NB Never uses BX.
8716 (define_insn "*arm_indirect_jump"
8718 (match_operand:SI 0 "s_register_operand" "r"))]
8720 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8721 [(set_attr "predicable" "yes")
8722 (set_attr "type" "branch")]
8725 (define_insn "*load_indirect_jump"
8727 (match_operand:SI 0 "memory_operand" "m"))]
8729 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8730 [(set_attr "type" "load_4")
8731 (set_attr "pool_range" "4096")
8732 (set_attr "neg_pool_range" "4084")
8733 (set_attr "predicable" "yes")]
8743 [(set (attr "length")
8744 (if_then_else (eq_attr "is_thumb" "yes")
8747 (set_attr "type" "mov_reg")]
8751 [(trap_if (const_int 1) (const_int 0))]
8755 return \".inst\\t0xe7f000f0\";
8757 return \".inst\\t0xdeff\";
8759 [(set (attr "length")
8760 (if_then_else (eq_attr "is_thumb" "yes")
8763 (set_attr "type" "trap")
8764 (set_attr "conds" "unconditional")]
8768 ;; Patterns to allow combination of arithmetic, cond code and shifts
8770 (define_insn "*<arith_shift_insn>_multsi"
8771 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8773 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8774 (match_operand:SI 3 "power_of_two_operand" ""))
8775 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8777 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8778 [(set_attr "predicable" "yes")
8779 (set_attr "shift" "2")
8780 (set_attr "arch" "a,t2")
8781 (set_attr "type" "alu_shift_imm")])
8783 (define_insn "*<arith_shift_insn>_shiftsi"
8784 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8786 (match_operator:SI 2 "shift_nomul_operator"
8787 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8788 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8789 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8790 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8791 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8792 [(set_attr "predicable" "yes")
8793 (set_attr "shift" "3")
8794 (set_attr "arch" "a,t2,a")
8795 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8798 [(set (match_operand:SI 0 "s_register_operand" "")
8799 (match_operator:SI 1 "shiftable_operator"
8800 [(match_operator:SI 2 "shiftable_operator"
8801 [(match_operator:SI 3 "shift_operator"
8802 [(match_operand:SI 4 "s_register_operand" "")
8803 (match_operand:SI 5 "reg_or_int_operand" "")])
8804 (match_operand:SI 6 "s_register_operand" "")])
8805 (match_operand:SI 7 "arm_rhs_operand" "")]))
8806 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8809 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8812 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8815 (define_insn "*arith_shiftsi_compare0"
8816 [(set (reg:CC_NOOV CC_REGNUM)
8818 (match_operator:SI 1 "shiftable_operator"
8819 [(match_operator:SI 3 "shift_operator"
8820 [(match_operand:SI 4 "s_register_operand" "r,r")
8821 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8822 (match_operand:SI 2 "s_register_operand" "r,r")])
8824 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8825 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8828 "%i1s%?\\t%0, %2, %4%S3"
8829 [(set_attr "conds" "set")
8830 (set_attr "shift" "4")
8831 (set_attr "arch" "32,a")
8832 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8834 (define_insn "*arith_shiftsi_compare0_scratch"
8835 [(set (reg:CC_NOOV CC_REGNUM)
8837 (match_operator:SI 1 "shiftable_operator"
8838 [(match_operator:SI 3 "shift_operator"
8839 [(match_operand:SI 4 "s_register_operand" "r,r")
8840 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8841 (match_operand:SI 2 "s_register_operand" "r,r")])
8843 (clobber (match_scratch:SI 0 "=r,r"))]
8845 "%i1s%?\\t%0, %2, %4%S3"
8846 [(set_attr "conds" "set")
8847 (set_attr "shift" "4")
8848 (set_attr "arch" "32,a")
8849 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8851 (define_insn "*sub_shiftsi"
8852 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8853 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8854 (match_operator:SI 2 "shift_operator"
8855 [(match_operand:SI 3 "s_register_operand" "r,r")
8856 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8858 "sub%?\\t%0, %1, %3%S2"
8859 [(set_attr "predicable" "yes")
8860 (set_attr "predicable_short_it" "no")
8861 (set_attr "shift" "3")
8862 (set_attr "arch" "32,a")
8863 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8865 (define_insn "*sub_shiftsi_compare0"
8866 [(set (reg:CC_NOOV CC_REGNUM)
8868 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8869 (match_operator:SI 2 "shift_operator"
8870 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8871 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8873 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8874 (minus:SI (match_dup 1)
8875 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8877 "subs%?\\t%0, %1, %3%S2"
8878 [(set_attr "conds" "set")
8879 (set_attr "shift" "3")
8880 (set_attr "arch" "32,a,a")
8881 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8883 (define_insn "*sub_shiftsi_compare0_scratch"
8884 [(set (reg:CC_NOOV CC_REGNUM)
8886 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8887 (match_operator:SI 2 "shift_operator"
8888 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8889 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8891 (clobber (match_scratch:SI 0 "=r,r,r"))]
8893 "subs%?\\t%0, %1, %3%S2"
8894 [(set_attr "conds" "set")
8895 (set_attr "shift" "3")
8896 (set_attr "arch" "32,a,a")
8897 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8900 (define_insn_and_split "*and_scc"
8901 [(set (match_operand:SI 0 "s_register_operand" "=r")
8902 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8903 [(match_operand 2 "cc_register" "") (const_int 0)])
8904 (match_operand:SI 3 "s_register_operand" "r")))]
8906 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8907 "&& reload_completed"
8908 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8909 (cond_exec (match_dup 4) (set (match_dup 0)
8910 (and:SI (match_dup 3) (const_int 1))))]
8912 machine_mode mode = GET_MODE (operands[2]);
8913 enum rtx_code rc = GET_CODE (operands[1]);
8915 /* Note that operands[4] is the same as operands[1],
8916 but with VOIDmode as the result. */
8917 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8918 if (mode == CCFPmode || mode == CCFPEmode)
8919 rc = reverse_condition_maybe_unordered (rc);
8921 rc = reverse_condition (rc);
8922 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8924 [(set_attr "conds" "use")
8925 (set_attr "type" "multiple")
8926 (set_attr "length" "8")]
8929 (define_insn_and_split "*ior_scc"
8930 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8931 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8932 [(match_operand 2 "cc_register" "") (const_int 0)])
8933 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8938 "&& reload_completed
8939 && REGNO (operands [0]) != REGNO (operands[3])"
8940 ;; && which_alternative == 1
8941 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8942 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8943 (cond_exec (match_dup 4) (set (match_dup 0)
8944 (ior:SI (match_dup 3) (const_int 1))))]
8946 machine_mode mode = GET_MODE (operands[2]);
8947 enum rtx_code rc = GET_CODE (operands[1]);
8949 /* Note that operands[4] is the same as operands[1],
8950 but with VOIDmode as the result. */
8951 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8952 if (mode == CCFPmode || mode == CCFPEmode)
8953 rc = reverse_condition_maybe_unordered (rc);
8955 rc = reverse_condition (rc);
8956 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8958 [(set_attr "conds" "use")
8959 (set_attr "length" "4,8")
8960 (set_attr "type" "logic_imm,multiple")]
8963 ; A series of splitters for the compare_scc pattern below. Note that
8964 ; order is important.
8966 [(set (match_operand:SI 0 "s_register_operand" "")
8967 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8969 (clobber (reg:CC CC_REGNUM))]
8970 "TARGET_32BIT && reload_completed"
8971 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8974 [(set (match_operand:SI 0 "s_register_operand" "")
8975 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8977 (clobber (reg:CC CC_REGNUM))]
8978 "TARGET_32BIT && reload_completed"
8979 [(set (match_dup 0) (not:SI (match_dup 1)))
8980 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8983 [(set (match_operand:SI 0 "s_register_operand" "")
8984 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8986 (clobber (reg:CC CC_REGNUM))]
8987 "arm_arch5t && TARGET_32BIT"
8988 [(set (match_dup 0) (clz:SI (match_dup 1)))
8989 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8993 [(set (match_operand:SI 0 "s_register_operand" "")
8994 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8996 (clobber (reg:CC CC_REGNUM))]
8997 "TARGET_32BIT && reload_completed"
8999 [(set (reg:CC CC_REGNUM)
9000 (compare:CC (const_int 1) (match_dup 1)))
9002 (minus:SI (const_int 1) (match_dup 1)))])
9003 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9004 (set (match_dup 0) (const_int 0)))])
9007 [(set (match_operand:SI 0 "s_register_operand" "")
9008 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9009 (match_operand:SI 2 "const_int_operand" "")))
9010 (clobber (reg:CC CC_REGNUM))]
9011 "TARGET_32BIT && reload_completed"
9013 [(set (reg:CC CC_REGNUM)
9014 (compare:CC (match_dup 1) (match_dup 2)))
9015 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9016 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9017 (set (match_dup 0) (const_int 1)))]
9019 operands[3] = GEN_INT (-INTVAL (operands[2]));
9023 [(set (match_operand:SI 0 "s_register_operand" "")
9024 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9025 (match_operand:SI 2 "arm_add_operand" "")))
9026 (clobber (reg:CC CC_REGNUM))]
9027 "TARGET_32BIT && reload_completed"
9029 [(set (reg:CC_NOOV CC_REGNUM)
9030 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9032 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9033 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9034 (set (match_dup 0) (const_int 1)))])
9036 (define_insn_and_split "*compare_scc"
9037 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9038 (match_operator:SI 1 "arm_comparison_operator"
9039 [(match_operand:SI 2 "s_register_operand" "r,r")
9040 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9041 (clobber (reg:CC CC_REGNUM))]
9044 "&& reload_completed"
9045 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9046 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9047 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9050 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9051 operands[2], operands[3]);
9052 enum rtx_code rc = GET_CODE (operands[1]);
9054 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9056 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9057 if (mode == CCFPmode || mode == CCFPEmode)
9058 rc = reverse_condition_maybe_unordered (rc);
9060 rc = reverse_condition (rc);
9061 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9063 [(set_attr "type" "multiple")]
9066 ;; Attempt to improve the sequence generated by the compare_scc splitters
9067 ;; not to use conditional execution.
9069 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9073 [(set (reg:CC CC_REGNUM)
9074 (compare:CC (match_operand:SI 1 "register_operand" "")
9076 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9077 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9078 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9079 (set (match_dup 0) (const_int 1)))]
9080 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9081 [(set (match_dup 0) (clz:SI (match_dup 1)))
9082 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9085 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9089 [(set (reg:CC CC_REGNUM)
9090 (compare:CC (match_operand:SI 1 "register_operand" "")
9092 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9093 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9094 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9095 (set (match_dup 0) (const_int 1)))
9096 (match_scratch:SI 2 "r")]
9097 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9099 [(set (reg:CC CC_REGNUM)
9100 (compare:CC (const_int 0) (match_dup 1)))
9101 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9103 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9104 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9107 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9108 ;; sub Rd, Reg1, reg2
9112 [(set (reg:CC CC_REGNUM)
9113 (compare:CC (match_operand:SI 1 "register_operand" "")
9114 (match_operand:SI 2 "arm_rhs_operand" "")))
9115 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9116 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9117 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9118 (set (match_dup 0) (const_int 1)))]
9119 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9120 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9121 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9122 (set (match_dup 0) (clz:SI (match_dup 0)))
9123 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9127 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9128 ;; sub T1, Reg1, reg2
9132 [(set (reg:CC CC_REGNUM)
9133 (compare:CC (match_operand:SI 1 "register_operand" "")
9134 (match_operand:SI 2 "arm_rhs_operand" "")))
9135 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9136 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9137 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9138 (set (match_dup 0) (const_int 1)))
9139 (match_scratch:SI 3 "r")]
9140 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9141 [(set (match_dup 3) (match_dup 4))
9143 [(set (reg:CC CC_REGNUM)
9144 (compare:CC (const_int 0) (match_dup 3)))
9145 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9147 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9148 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9150 if (CONST_INT_P (operands[2]))
9151 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9153 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9156 (define_insn "*cond_move"
9157 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9158 (if_then_else:SI (match_operator 3 "equality_operator"
9159 [(match_operator 4 "arm_comparison_operator"
9160 [(match_operand 5 "cc_register" "") (const_int 0)])
9162 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9163 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9166 if (GET_CODE (operands[3]) == NE)
9168 if (which_alternative != 1)
9169 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9170 if (which_alternative != 0)
9171 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9174 if (which_alternative != 0)
9175 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9176 if (which_alternative != 1)
9177 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9180 [(set_attr "conds" "use")
9181 (set_attr_alternative "type"
9182 [(if_then_else (match_operand 2 "const_int_operand" "")
9183 (const_string "mov_imm")
9184 (const_string "mov_reg"))
9185 (if_then_else (match_operand 1 "const_int_operand" "")
9186 (const_string "mov_imm")
9187 (const_string "mov_reg"))
9188 (const_string "multiple")])
9189 (set_attr "length" "4,4,8")]
9192 (define_insn "*cond_arith"
9193 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9194 (match_operator:SI 5 "shiftable_operator"
9195 [(match_operator:SI 4 "arm_comparison_operator"
9196 [(match_operand:SI 2 "s_register_operand" "r,r")
9197 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9198 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9199 (clobber (reg:CC CC_REGNUM))]
9202 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9203 return \"%i5\\t%0, %1, %2, lsr #31\";
9205 output_asm_insn (\"cmp\\t%2, %3\", operands);
9206 if (GET_CODE (operands[5]) == AND)
9207 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9208 else if (GET_CODE (operands[5]) == MINUS)
9209 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9210 else if (which_alternative != 0)
9211 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9212 return \"%i5%d4\\t%0, %1, #1\";
9214 [(set_attr "conds" "clob")
9215 (set_attr "length" "12")
9216 (set_attr "type" "multiple")]
9219 (define_insn "*cond_sub"
9220 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9221 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9222 (match_operator:SI 4 "arm_comparison_operator"
9223 [(match_operand:SI 2 "s_register_operand" "r,r")
9224 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9225 (clobber (reg:CC CC_REGNUM))]
9228 output_asm_insn (\"cmp\\t%2, %3\", operands);
9229 if (which_alternative != 0)
9230 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9231 return \"sub%d4\\t%0, %1, #1\";
9233 [(set_attr "conds" "clob")
9234 (set_attr "length" "8,12")
9235 (set_attr "type" "multiple")]
9238 (define_insn "*cmp_ite0"
9239 [(set (match_operand 6 "dominant_cc_register" "")
9242 (match_operator 4 "arm_comparison_operator"
9243 [(match_operand:SI 0 "s_register_operand"
9244 "l,l,l,r,r,r,r,r,r")
9245 (match_operand:SI 1 "arm_add_operand"
9246 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9247 (match_operator:SI 5 "arm_comparison_operator"
9248 [(match_operand:SI 2 "s_register_operand"
9249 "l,r,r,l,l,r,r,r,r")
9250 (match_operand:SI 3 "arm_add_operand"
9251 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9257 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9259 {\"cmp%d5\\t%0, %1\",
9260 \"cmp%d4\\t%2, %3\"},
9261 {\"cmn%d5\\t%0, #%n1\",
9262 \"cmp%d4\\t%2, %3\"},
9263 {\"cmp%d5\\t%0, %1\",
9264 \"cmn%d4\\t%2, #%n3\"},
9265 {\"cmn%d5\\t%0, #%n1\",
9266 \"cmn%d4\\t%2, #%n3\"}
9268 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9273 \"cmn\\t%0, #%n1\"},
9274 {\"cmn\\t%2, #%n3\",
9276 {\"cmn\\t%2, #%n3\",
9279 static const char * const ite[2] =
9284 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9285 CMP_CMP, CMN_CMP, CMP_CMP,
9286 CMN_CMP, CMP_CMN, CMN_CMN};
9288 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9290 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9291 if (TARGET_THUMB2) {
9292 output_asm_insn (ite[swap], operands);
9294 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9297 [(set_attr "conds" "set")
9298 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9299 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9300 (set_attr "type" "multiple")
9301 (set_attr_alternative "length"
9307 (if_then_else (eq_attr "is_thumb" "no")
9310 (if_then_else (eq_attr "is_thumb" "no")
9313 (if_then_else (eq_attr "is_thumb" "no")
9316 (if_then_else (eq_attr "is_thumb" "no")
9321 (define_insn "*cmp_ite1"
9322 [(set (match_operand 6 "dominant_cc_register" "")
9325 (match_operator 4 "arm_comparison_operator"
9326 [(match_operand:SI 0 "s_register_operand"
9327 "l,l,l,r,r,r,r,r,r")
9328 (match_operand:SI 1 "arm_add_operand"
9329 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9330 (match_operator:SI 5 "arm_comparison_operator"
9331 [(match_operand:SI 2 "s_register_operand"
9332 "l,r,r,l,l,r,r,r,r")
9333 (match_operand:SI 3 "arm_add_operand"
9334 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9340 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9344 {\"cmn\\t%0, #%n1\",
9347 \"cmn\\t%2, #%n3\"},
9348 {\"cmn\\t%0, #%n1\",
9351 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9353 {\"cmp%d4\\t%2, %3\",
9354 \"cmp%D5\\t%0, %1\"},
9355 {\"cmp%d4\\t%2, %3\",
9356 \"cmn%D5\\t%0, #%n1\"},
9357 {\"cmn%d4\\t%2, #%n3\",
9358 \"cmp%D5\\t%0, %1\"},
9359 {\"cmn%d4\\t%2, #%n3\",
9360 \"cmn%D5\\t%0, #%n1\"}
9362 static const char * const ite[2] =
9367 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9368 CMP_CMP, CMN_CMP, CMP_CMP,
9369 CMN_CMP, CMP_CMN, CMN_CMN};
9371 comparison_dominates_p (GET_CODE (operands[5]),
9372 reverse_condition (GET_CODE (operands[4])));
9374 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9375 if (TARGET_THUMB2) {
9376 output_asm_insn (ite[swap], operands);
9378 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9381 [(set_attr "conds" "set")
9382 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9383 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9384 (set_attr_alternative "length"
9390 (if_then_else (eq_attr "is_thumb" "no")
9393 (if_then_else (eq_attr "is_thumb" "no")
9396 (if_then_else (eq_attr "is_thumb" "no")
9399 (if_then_else (eq_attr "is_thumb" "no")
9402 (set_attr "type" "multiple")]
9405 (define_insn "*cmp_and"
9406 [(set (match_operand 6 "dominant_cc_register" "")
9409 (match_operator 4 "arm_comparison_operator"
9410 [(match_operand:SI 0 "s_register_operand"
9411 "l,l,l,r,r,r,r,r,r")
9412 (match_operand:SI 1 "arm_add_operand"
9413 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9414 (match_operator:SI 5 "arm_comparison_operator"
9415 [(match_operand:SI 2 "s_register_operand"
9416 "l,r,r,l,l,r,r,r,r")
9417 (match_operand:SI 3 "arm_add_operand"
9418 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9423 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9425 {\"cmp%d5\\t%0, %1\",
9426 \"cmp%d4\\t%2, %3\"},
9427 {\"cmn%d5\\t%0, #%n1\",
9428 \"cmp%d4\\t%2, %3\"},
9429 {\"cmp%d5\\t%0, %1\",
9430 \"cmn%d4\\t%2, #%n3\"},
9431 {\"cmn%d5\\t%0, #%n1\",
9432 \"cmn%d4\\t%2, #%n3\"}
9434 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9439 \"cmn\\t%0, #%n1\"},
9440 {\"cmn\\t%2, #%n3\",
9442 {\"cmn\\t%2, #%n3\",
9445 static const char *const ite[2] =
9450 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9451 CMP_CMP, CMN_CMP, CMP_CMP,
9452 CMN_CMP, CMP_CMN, CMN_CMN};
9454 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9456 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9457 if (TARGET_THUMB2) {
9458 output_asm_insn (ite[swap], operands);
9460 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9463 [(set_attr "conds" "set")
9464 (set_attr "predicable" "no")
9465 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9466 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9467 (set_attr_alternative "length"
9473 (if_then_else (eq_attr "is_thumb" "no")
9476 (if_then_else (eq_attr "is_thumb" "no")
9479 (if_then_else (eq_attr "is_thumb" "no")
9482 (if_then_else (eq_attr "is_thumb" "no")
9485 (set_attr "type" "multiple")]
9488 (define_insn "*cmp_ior"
9489 [(set (match_operand 6 "dominant_cc_register" "")
9492 (match_operator 4 "arm_comparison_operator"
9493 [(match_operand:SI 0 "s_register_operand"
9494 "l,l,l,r,r,r,r,r,r")
9495 (match_operand:SI 1 "arm_add_operand"
9496 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9497 (match_operator:SI 5 "arm_comparison_operator"
9498 [(match_operand:SI 2 "s_register_operand"
9499 "l,r,r,l,l,r,r,r,r")
9500 (match_operand:SI 3 "arm_add_operand"
9501 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9506 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9510 {\"cmn\\t%0, #%n1\",
9513 \"cmn\\t%2, #%n3\"},
9514 {\"cmn\\t%0, #%n1\",
9517 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9519 {\"cmp%D4\\t%2, %3\",
9520 \"cmp%D5\\t%0, %1\"},
9521 {\"cmp%D4\\t%2, %3\",
9522 \"cmn%D5\\t%0, #%n1\"},
9523 {\"cmn%D4\\t%2, #%n3\",
9524 \"cmp%D5\\t%0, %1\"},
9525 {\"cmn%D4\\t%2, #%n3\",
9526 \"cmn%D5\\t%0, #%n1\"}
9528 static const char *const ite[2] =
9533 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9534 CMP_CMP, CMN_CMP, CMP_CMP,
9535 CMN_CMP, CMP_CMN, CMN_CMN};
9537 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9539 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9540 if (TARGET_THUMB2) {
9541 output_asm_insn (ite[swap], operands);
9543 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9547 [(set_attr "conds" "set")
9548 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9549 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9550 (set_attr_alternative "length"
9556 (if_then_else (eq_attr "is_thumb" "no")
9559 (if_then_else (eq_attr "is_thumb" "no")
9562 (if_then_else (eq_attr "is_thumb" "no")
9565 (if_then_else (eq_attr "is_thumb" "no")
9568 (set_attr "type" "multiple")]
9571 (define_insn_and_split "*ior_scc_scc"
9572 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9573 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9574 [(match_operand:SI 1 "s_register_operand" "l,r")
9575 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9576 (match_operator:SI 6 "arm_comparison_operator"
9577 [(match_operand:SI 4 "s_register_operand" "l,r")
9578 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9579 (clobber (reg:CC CC_REGNUM))]
9581 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9584 "TARGET_32BIT && reload_completed"
9588 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9589 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9591 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9593 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9596 [(set_attr "conds" "clob")
9597 (set_attr "enabled_for_short_it" "yes,no")
9598 (set_attr "length" "16")
9599 (set_attr "type" "multiple")]
9602 ; If the above pattern is followed by a CMP insn, then the compare is
9603 ; redundant, since we can rework the conditional instruction that follows.
9604 (define_insn_and_split "*ior_scc_scc_cmp"
9605 [(set (match_operand 0 "dominant_cc_register" "")
9606 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9607 [(match_operand:SI 1 "s_register_operand" "l,r")
9608 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9609 (match_operator:SI 6 "arm_comparison_operator"
9610 [(match_operand:SI 4 "s_register_operand" "l,r")
9611 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9613 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9614 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9615 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9618 "TARGET_32BIT && reload_completed"
9622 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9623 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9625 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9627 [(set_attr "conds" "set")
9628 (set_attr "enabled_for_short_it" "yes,no")
9629 (set_attr "length" "16")
9630 (set_attr "type" "multiple")]
9633 (define_insn_and_split "*and_scc_scc"
9634 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9635 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9636 [(match_operand:SI 1 "s_register_operand" "l,r")
9637 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9638 (match_operator:SI 6 "arm_comparison_operator"
9639 [(match_operand:SI 4 "s_register_operand" "l,r")
9640 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9641 (clobber (reg:CC CC_REGNUM))]
9643 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9646 "TARGET_32BIT && reload_completed
9647 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9652 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9653 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9655 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9657 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9660 [(set_attr "conds" "clob")
9661 (set_attr "enabled_for_short_it" "yes,no")
9662 (set_attr "length" "16")
9663 (set_attr "type" "multiple")]
9666 ; If the above pattern is followed by a CMP insn, then the compare is
9667 ; redundant, since we can rework the conditional instruction that follows.
9668 (define_insn_and_split "*and_scc_scc_cmp"
9669 [(set (match_operand 0 "dominant_cc_register" "")
9670 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9671 [(match_operand:SI 1 "s_register_operand" "l,r")
9672 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9673 (match_operator:SI 6 "arm_comparison_operator"
9674 [(match_operand:SI 4 "s_register_operand" "l,r")
9675 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9677 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9678 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9679 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9682 "TARGET_32BIT && reload_completed"
9686 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9687 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9689 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9691 [(set_attr "conds" "set")
9692 (set_attr "enabled_for_short_it" "yes,no")
9693 (set_attr "length" "16")
9694 (set_attr "type" "multiple")]
9697 ;; If there is no dominance in the comparison, then we can still save an
9698 ;; instruction in the AND case, since we can know that the second compare
9699 ;; need only zero the value if false (if true, then the value is already
9701 (define_insn_and_split "*and_scc_scc_nodom"
9702 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9703 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9704 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9705 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9706 (match_operator:SI 6 "arm_comparison_operator"
9707 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9708 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9709 (clobber (reg:CC CC_REGNUM))]
9711 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9714 "TARGET_32BIT && reload_completed"
9715 [(parallel [(set (match_dup 0)
9716 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9717 (clobber (reg:CC CC_REGNUM))])
9718 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9720 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9723 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9724 operands[4], operands[5]),
9726 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9728 [(set_attr "conds" "clob")
9729 (set_attr "length" "20")
9730 (set_attr "type" "multiple")]
9734 [(set (reg:CC_NOOV CC_REGNUM)
9735 (compare:CC_NOOV (ior:SI
9736 (and:SI (match_operand:SI 0 "s_register_operand" "")
9738 (match_operator:SI 1 "arm_comparison_operator"
9739 [(match_operand:SI 2 "s_register_operand" "")
9740 (match_operand:SI 3 "arm_add_operand" "")]))
9742 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9745 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9747 (set (reg:CC_NOOV CC_REGNUM)
9748 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9753 [(set (reg:CC_NOOV CC_REGNUM)
9754 (compare:CC_NOOV (ior:SI
9755 (match_operator:SI 1 "arm_comparison_operator"
9756 [(match_operand:SI 2 "s_register_operand" "")
9757 (match_operand:SI 3 "arm_add_operand" "")])
9758 (and:SI (match_operand:SI 0 "s_register_operand" "")
9761 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9764 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9766 (set (reg:CC_NOOV CC_REGNUM)
9767 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9770 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9772 (define_insn_and_split "*negscc"
9773 [(set (match_operand:SI 0 "s_register_operand" "=r")
9774 (neg:SI (match_operator 3 "arm_comparison_operator"
9775 [(match_operand:SI 1 "s_register_operand" "r")
9776 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9777 (clobber (reg:CC CC_REGNUM))]
9780 "&& reload_completed"
9783 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9785 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9787 /* Emit mov\\t%0, %1, asr #31 */
9788 emit_insn (gen_rtx_SET (operands[0],
9789 gen_rtx_ASHIFTRT (SImode,
9794 else if (GET_CODE (operands[3]) == NE)
9796 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9797 if (CONST_INT_P (operands[2]))
9798 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9799 GEN_INT (- INTVAL (operands[2]))));
9801 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9803 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9807 gen_rtx_SET (operands[0],
9813 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9814 emit_insn (gen_rtx_SET (cc_reg,
9815 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9816 enum rtx_code rc = GET_CODE (operands[3]);
9818 rc = reverse_condition (rc);
9819 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9824 gen_rtx_SET (operands[0], const0_rtx)));
9825 rc = GET_CODE (operands[3]);
9826 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9831 gen_rtx_SET (operands[0],
9837 [(set_attr "conds" "clob")
9838 (set_attr "length" "12")
9839 (set_attr "type" "multiple")]
9842 (define_insn_and_split "movcond_addsi"
9843 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9845 (match_operator 5 "comparison_operator"
9846 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9847 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9849 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9850 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9851 (clobber (reg:CC CC_REGNUM))]
9854 "&& reload_completed"
9855 [(set (reg:CC_NOOV CC_REGNUM)
9857 (plus:SI (match_dup 3)
9860 (set (match_dup 0) (match_dup 1))
9861 (cond_exec (match_dup 6)
9862 (set (match_dup 0) (match_dup 2)))]
9865 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9866 operands[3], operands[4]);
9867 enum rtx_code rc = GET_CODE (operands[5]);
9868 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9869 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9870 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9871 rc = reverse_condition (rc);
9873 std::swap (operands[1], operands[2]);
9875 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9878 [(set_attr "conds" "clob")
9879 (set_attr "enabled_for_short_it" "no,yes,yes")
9880 (set_attr "type" "multiple")]
9883 (define_insn "movcond"
9884 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9886 (match_operator 5 "arm_comparison_operator"
9887 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9888 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9889 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9890 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9891 (clobber (reg:CC CC_REGNUM))]
9894 if (GET_CODE (operands[5]) == LT
9895 && (operands[4] == const0_rtx))
9897 if (which_alternative != 1 && REG_P (operands[1]))
9899 if (operands[2] == const0_rtx)
9900 return \"and\\t%0, %1, %3, asr #31\";
9901 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9903 else if (which_alternative != 0 && REG_P (operands[2]))
9905 if (operands[1] == const0_rtx)
9906 return \"bic\\t%0, %2, %3, asr #31\";
9907 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9909 /* The only case that falls through to here is when both ops 1 & 2
9913 if (GET_CODE (operands[5]) == GE
9914 && (operands[4] == const0_rtx))
9916 if (which_alternative != 1 && REG_P (operands[1]))
9918 if (operands[2] == const0_rtx)
9919 return \"bic\\t%0, %1, %3, asr #31\";
9920 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9922 else if (which_alternative != 0 && REG_P (operands[2]))
9924 if (operands[1] == const0_rtx)
9925 return \"and\\t%0, %2, %3, asr #31\";
9926 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9928 /* The only case that falls through to here is when both ops 1 & 2
9931 if (CONST_INT_P (operands[4])
9932 && !const_ok_for_arm (INTVAL (operands[4])))
9933 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9935 output_asm_insn (\"cmp\\t%3, %4\", operands);
9936 if (which_alternative != 0)
9937 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9938 if (which_alternative != 1)
9939 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9942 [(set_attr "conds" "clob")
9943 (set_attr "length" "8,8,12")
9944 (set_attr "type" "multiple")]
9947 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9949 (define_insn "*ifcompare_plus_move"
9950 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9951 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9952 [(match_operand:SI 4 "s_register_operand" "r,r")
9953 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9955 (match_operand:SI 2 "s_register_operand" "r,r")
9956 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9957 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9958 (clobber (reg:CC CC_REGNUM))]
9961 [(set_attr "conds" "clob")
9962 (set_attr "length" "8,12")
9963 (set_attr "type" "multiple")]
9966 (define_insn "*if_plus_move"
9967 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9969 (match_operator 4 "arm_comparison_operator"
9970 [(match_operand 5 "cc_register" "") (const_int 0)])
9972 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9973 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9974 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9978 sub%d4\\t%0, %2, #%n3
9979 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9980 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9981 [(set_attr "conds" "use")
9982 (set_attr "length" "4,4,8,8")
9983 (set_attr_alternative "type"
9984 [(if_then_else (match_operand 3 "const_int_operand" "")
9985 (const_string "alu_imm" )
9986 (const_string "alu_sreg"))
9987 (const_string "alu_imm")
9988 (const_string "multiple")
9989 (const_string "multiple")])]
9992 (define_insn "*ifcompare_move_plus"
9993 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9994 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9995 [(match_operand:SI 4 "s_register_operand" "r,r")
9996 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9997 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9999 (match_operand:SI 2 "s_register_operand" "r,r")
10000 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10001 (clobber (reg:CC CC_REGNUM))]
10004 [(set_attr "conds" "clob")
10005 (set_attr "length" "8,12")
10006 (set_attr "type" "multiple")]
10009 (define_insn "*if_move_plus"
10010 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10012 (match_operator 4 "arm_comparison_operator"
10013 [(match_operand 5 "cc_register" "") (const_int 0)])
10014 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10016 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10017 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10020 add%D4\\t%0, %2, %3
10021 sub%D4\\t%0, %2, #%n3
10022 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10023 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10024 [(set_attr "conds" "use")
10025 (set_attr "length" "4,4,8,8")
10026 (set_attr_alternative "type"
10027 [(if_then_else (match_operand 3 "const_int_operand" "")
10028 (const_string "alu_imm" )
10029 (const_string "alu_sreg"))
10030 (const_string "alu_imm")
10031 (const_string "multiple")
10032 (const_string "multiple")])]
10035 (define_insn "*ifcompare_arith_arith"
10036 [(set (match_operand:SI 0 "s_register_operand" "=r")
10037 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10038 [(match_operand:SI 5 "s_register_operand" "r")
10039 (match_operand:SI 6 "arm_add_operand" "rIL")])
10040 (match_operator:SI 8 "shiftable_operator"
10041 [(match_operand:SI 1 "s_register_operand" "r")
10042 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10043 (match_operator:SI 7 "shiftable_operator"
10044 [(match_operand:SI 3 "s_register_operand" "r")
10045 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10046 (clobber (reg:CC CC_REGNUM))]
10049 [(set_attr "conds" "clob")
10050 (set_attr "length" "12")
10051 (set_attr "type" "multiple")]
10054 (define_insn "*if_arith_arith"
10055 [(set (match_operand:SI 0 "s_register_operand" "=r")
10056 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10057 [(match_operand 8 "cc_register" "") (const_int 0)])
10058 (match_operator:SI 6 "shiftable_operator"
10059 [(match_operand:SI 1 "s_register_operand" "r")
10060 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10061 (match_operator:SI 7 "shiftable_operator"
10062 [(match_operand:SI 3 "s_register_operand" "r")
10063 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10065 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10066 [(set_attr "conds" "use")
10067 (set_attr "length" "8")
10068 (set_attr "type" "multiple")]
10071 (define_insn "*ifcompare_arith_move"
10072 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10073 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10074 [(match_operand:SI 2 "s_register_operand" "r,r")
10075 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10076 (match_operator:SI 7 "shiftable_operator"
10077 [(match_operand:SI 4 "s_register_operand" "r,r")
10078 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10079 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10080 (clobber (reg:CC CC_REGNUM))]
10083 /* If we have an operation where (op x 0) is the identity operation and
10084 the conditional operator is LT or GE and we are comparing against zero and
10085 everything is in registers then we can do this in two instructions. */
10086 if (operands[3] == const0_rtx
10087 && GET_CODE (operands[7]) != AND
10088 && REG_P (operands[5])
10089 && REG_P (operands[1])
10090 && REGNO (operands[1]) == REGNO (operands[4])
10091 && REGNO (operands[4]) != REGNO (operands[0]))
10093 if (GET_CODE (operands[6]) == LT)
10094 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10095 else if (GET_CODE (operands[6]) == GE)
10096 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10098 if (CONST_INT_P (operands[3])
10099 && !const_ok_for_arm (INTVAL (operands[3])))
10100 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10102 output_asm_insn (\"cmp\\t%2, %3\", operands);
10103 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10104 if (which_alternative != 0)
10105 return \"mov%D6\\t%0, %1\";
10108 [(set_attr "conds" "clob")
10109 (set_attr "length" "8,12")
10110 (set_attr "type" "multiple")]
10113 (define_insn "*if_arith_move"
10114 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10115 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10116 [(match_operand 6 "cc_register" "") (const_int 0)])
10117 (match_operator:SI 5 "shiftable_operator"
10118 [(match_operand:SI 2 "s_register_operand" "r,r")
10119 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10120 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10123 %I5%d4\\t%0, %2, %3
10124 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10125 [(set_attr "conds" "use")
10126 (set_attr "length" "4,8")
10127 (set_attr_alternative "type"
10128 [(if_then_else (match_operand 3 "const_int_operand" "")
10129 (const_string "alu_shift_imm" )
10130 (const_string "alu_shift_reg"))
10131 (const_string "multiple")])]
10134 (define_insn "*ifcompare_move_arith"
10135 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10136 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10137 [(match_operand:SI 4 "s_register_operand" "r,r")
10138 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10139 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10140 (match_operator:SI 7 "shiftable_operator"
10141 [(match_operand:SI 2 "s_register_operand" "r,r")
10142 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10143 (clobber (reg:CC CC_REGNUM))]
10146 /* If we have an operation where (op x 0) is the identity operation and
10147 the conditional operator is LT or GE and we are comparing against zero and
10148 everything is in registers then we can do this in two instructions */
10149 if (operands[5] == const0_rtx
10150 && GET_CODE (operands[7]) != AND
10151 && REG_P (operands[3])
10152 && REG_P (operands[1])
10153 && REGNO (operands[1]) == REGNO (operands[2])
10154 && REGNO (operands[2]) != REGNO (operands[0]))
10156 if (GET_CODE (operands[6]) == GE)
10157 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10158 else if (GET_CODE (operands[6]) == LT)
10159 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10162 if (CONST_INT_P (operands[5])
10163 && !const_ok_for_arm (INTVAL (operands[5])))
10164 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10166 output_asm_insn (\"cmp\\t%4, %5\", operands);
10168 if (which_alternative != 0)
10169 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10170 return \"%I7%D6\\t%0, %2, %3\";
10172 [(set_attr "conds" "clob")
10173 (set_attr "length" "8,12")
10174 (set_attr "type" "multiple")]
10177 (define_insn "*if_move_arith"
10178 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10180 (match_operator 4 "arm_comparison_operator"
10181 [(match_operand 6 "cc_register" "") (const_int 0)])
10182 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10183 (match_operator:SI 5 "shiftable_operator"
10184 [(match_operand:SI 2 "s_register_operand" "r,r")
10185 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10188 %I5%D4\\t%0, %2, %3
10189 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10190 [(set_attr "conds" "use")
10191 (set_attr "length" "4,8")
10192 (set_attr_alternative "type"
10193 [(if_then_else (match_operand 3 "const_int_operand" "")
10194 (const_string "alu_shift_imm" )
10195 (const_string "alu_shift_reg"))
10196 (const_string "multiple")])]
10199 (define_insn "*ifcompare_move_not"
10200 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10202 (match_operator 5 "arm_comparison_operator"
10203 [(match_operand:SI 3 "s_register_operand" "r,r")
10204 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10205 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10207 (match_operand:SI 2 "s_register_operand" "r,r"))))
10208 (clobber (reg:CC CC_REGNUM))]
10211 [(set_attr "conds" "clob")
10212 (set_attr "length" "8,12")
10213 (set_attr "type" "multiple")]
10216 (define_insn "*if_move_not"
10217 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10219 (match_operator 4 "arm_comparison_operator"
10220 [(match_operand 3 "cc_register" "") (const_int 0)])
10221 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10222 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10226 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10227 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10228 [(set_attr "conds" "use")
10229 (set_attr "type" "mvn_reg")
10230 (set_attr "length" "4,8,8")
10231 (set_attr "type" "mvn_reg,multiple,multiple")]
10234 (define_insn "*ifcompare_not_move"
10235 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10237 (match_operator 5 "arm_comparison_operator"
10238 [(match_operand:SI 3 "s_register_operand" "r,r")
10239 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10241 (match_operand:SI 2 "s_register_operand" "r,r"))
10242 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10243 (clobber (reg:CC CC_REGNUM))]
10246 [(set_attr "conds" "clob")
10247 (set_attr "length" "8,12")
10248 (set_attr "type" "multiple")]
10251 (define_insn "*if_not_move"
10252 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10254 (match_operator 4 "arm_comparison_operator"
10255 [(match_operand 3 "cc_register" "") (const_int 0)])
10256 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10257 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10261 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10262 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10263 [(set_attr "conds" "use")
10264 (set_attr "type" "mvn_reg,multiple,multiple")
10265 (set_attr "length" "4,8,8")]
10268 (define_insn "*ifcompare_shift_move"
10269 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10271 (match_operator 6 "arm_comparison_operator"
10272 [(match_operand:SI 4 "s_register_operand" "r,r")
10273 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10274 (match_operator:SI 7 "shift_operator"
10275 [(match_operand:SI 2 "s_register_operand" "r,r")
10276 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10277 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10278 (clobber (reg:CC CC_REGNUM))]
10281 [(set_attr "conds" "clob")
10282 (set_attr "length" "8,12")
10283 (set_attr "type" "multiple")]
10286 (define_insn "*if_shift_move"
10287 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10289 (match_operator 5 "arm_comparison_operator"
10290 [(match_operand 6 "cc_register" "") (const_int 0)])
10291 (match_operator:SI 4 "shift_operator"
10292 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10293 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10294 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10298 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10299 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10300 [(set_attr "conds" "use")
10301 (set_attr "shift" "2")
10302 (set_attr "length" "4,8,8")
10303 (set_attr_alternative "type"
10304 [(if_then_else (match_operand 3 "const_int_operand" "")
10305 (const_string "mov_shift" )
10306 (const_string "mov_shift_reg"))
10307 (const_string "multiple")
10308 (const_string "multiple")])]
10311 (define_insn "*ifcompare_move_shift"
10312 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10314 (match_operator 6 "arm_comparison_operator"
10315 [(match_operand:SI 4 "s_register_operand" "r,r")
10316 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10317 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10318 (match_operator:SI 7 "shift_operator"
10319 [(match_operand:SI 2 "s_register_operand" "r,r")
10320 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10321 (clobber (reg:CC CC_REGNUM))]
10324 [(set_attr "conds" "clob")
10325 (set_attr "length" "8,12")
10326 (set_attr "type" "multiple")]
10329 (define_insn "*if_move_shift"
10330 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10332 (match_operator 5 "arm_comparison_operator"
10333 [(match_operand 6 "cc_register" "") (const_int 0)])
10334 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10335 (match_operator:SI 4 "shift_operator"
10336 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10337 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10341 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10342 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10343 [(set_attr "conds" "use")
10344 (set_attr "shift" "2")
10345 (set_attr "length" "4,8,8")
10346 (set_attr_alternative "type"
10347 [(if_then_else (match_operand 3 "const_int_operand" "")
10348 (const_string "mov_shift" )
10349 (const_string "mov_shift_reg"))
10350 (const_string "multiple")
10351 (const_string "multiple")])]
10354 (define_insn "*ifcompare_shift_shift"
10355 [(set (match_operand:SI 0 "s_register_operand" "=r")
10357 (match_operator 7 "arm_comparison_operator"
10358 [(match_operand:SI 5 "s_register_operand" "r")
10359 (match_operand:SI 6 "arm_add_operand" "rIL")])
10360 (match_operator:SI 8 "shift_operator"
10361 [(match_operand:SI 1 "s_register_operand" "r")
10362 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10363 (match_operator:SI 9 "shift_operator"
10364 [(match_operand:SI 3 "s_register_operand" "r")
10365 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10366 (clobber (reg:CC CC_REGNUM))]
10369 [(set_attr "conds" "clob")
10370 (set_attr "length" "12")
10371 (set_attr "type" "multiple")]
10374 (define_insn "*if_shift_shift"
10375 [(set (match_operand:SI 0 "s_register_operand" "=r")
10377 (match_operator 5 "arm_comparison_operator"
10378 [(match_operand 8 "cc_register" "") (const_int 0)])
10379 (match_operator:SI 6 "shift_operator"
10380 [(match_operand:SI 1 "s_register_operand" "r")
10381 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10382 (match_operator:SI 7 "shift_operator"
10383 [(match_operand:SI 3 "s_register_operand" "r")
10384 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10386 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10387 [(set_attr "conds" "use")
10388 (set_attr "shift" "1")
10389 (set_attr "length" "8")
10390 (set (attr "type") (if_then_else
10391 (and (match_operand 2 "const_int_operand" "")
10392 (match_operand 4 "const_int_operand" ""))
10393 (const_string "mov_shift")
10394 (const_string "mov_shift_reg")))]
10397 (define_insn "*ifcompare_not_arith"
10398 [(set (match_operand:SI 0 "s_register_operand" "=r")
10400 (match_operator 6 "arm_comparison_operator"
10401 [(match_operand:SI 4 "s_register_operand" "r")
10402 (match_operand:SI 5 "arm_add_operand" "rIL")])
10403 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10404 (match_operator:SI 7 "shiftable_operator"
10405 [(match_operand:SI 2 "s_register_operand" "r")
10406 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10407 (clobber (reg:CC CC_REGNUM))]
10410 [(set_attr "conds" "clob")
10411 (set_attr "length" "12")
10412 (set_attr "type" "multiple")]
10415 (define_insn "*if_not_arith"
10416 [(set (match_operand:SI 0 "s_register_operand" "=r")
10418 (match_operator 5 "arm_comparison_operator"
10419 [(match_operand 4 "cc_register" "") (const_int 0)])
10420 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10421 (match_operator:SI 6 "shiftable_operator"
10422 [(match_operand:SI 2 "s_register_operand" "r")
10423 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10425 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10426 [(set_attr "conds" "use")
10427 (set_attr "type" "mvn_reg")
10428 (set_attr "length" "8")]
10431 (define_insn "*ifcompare_arith_not"
10432 [(set (match_operand:SI 0 "s_register_operand" "=r")
10434 (match_operator 6 "arm_comparison_operator"
10435 [(match_operand:SI 4 "s_register_operand" "r")
10436 (match_operand:SI 5 "arm_add_operand" "rIL")])
10437 (match_operator:SI 7 "shiftable_operator"
10438 [(match_operand:SI 2 "s_register_operand" "r")
10439 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10440 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10441 (clobber (reg:CC CC_REGNUM))]
10444 [(set_attr "conds" "clob")
10445 (set_attr "length" "12")
10446 (set_attr "type" "multiple")]
10449 (define_insn "*if_arith_not"
10450 [(set (match_operand:SI 0 "s_register_operand" "=r")
10452 (match_operator 5 "arm_comparison_operator"
10453 [(match_operand 4 "cc_register" "") (const_int 0)])
10454 (match_operator:SI 6 "shiftable_operator"
10455 [(match_operand:SI 2 "s_register_operand" "r")
10456 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10457 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10459 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10460 [(set_attr "conds" "use")
10461 (set_attr "type" "multiple")
10462 (set_attr "length" "8")]
10465 (define_insn "*ifcompare_neg_move"
10466 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10468 (match_operator 5 "arm_comparison_operator"
10469 [(match_operand:SI 3 "s_register_operand" "r,r")
10470 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10471 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10472 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10473 (clobber (reg:CC CC_REGNUM))]
10476 [(set_attr "conds" "clob")
10477 (set_attr "length" "8,12")
10478 (set_attr "type" "multiple")]
10481 (define_insn_and_split "*if_neg_move"
10482 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10484 (match_operator 4 "arm_comparison_operator"
10485 [(match_operand 3 "cc_register" "") (const_int 0)])
10486 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10487 (match_operand:SI 1 "s_register_operand" "0,0")))]
10490 "&& reload_completed"
10491 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10492 (set (match_dup 0) (neg:SI (match_dup 2))))]
10494 [(set_attr "conds" "use")
10495 (set_attr "length" "4")
10496 (set_attr "arch" "t2,32")
10497 (set_attr "enabled_for_short_it" "yes,no")
10498 (set_attr "type" "logic_shift_imm")]
10501 (define_insn "*ifcompare_move_neg"
10502 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10504 (match_operator 5 "arm_comparison_operator"
10505 [(match_operand:SI 3 "s_register_operand" "r,r")
10506 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10507 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10508 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10509 (clobber (reg:CC CC_REGNUM))]
10512 [(set_attr "conds" "clob")
10513 (set_attr "length" "8,12")
10514 (set_attr "type" "multiple")]
10517 (define_insn_and_split "*if_move_neg"
10518 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10520 (match_operator 4 "arm_comparison_operator"
10521 [(match_operand 3 "cc_register" "") (const_int 0)])
10522 (match_operand:SI 1 "s_register_operand" "0,0")
10523 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10526 "&& reload_completed"
10527 [(cond_exec (match_dup 5)
10528 (set (match_dup 0) (neg:SI (match_dup 2))))]
10530 machine_mode mode = GET_MODE (operands[3]);
10531 rtx_code rc = GET_CODE (operands[4]);
10533 if (mode == CCFPmode || mode == CCFPEmode)
10534 rc = reverse_condition_maybe_unordered (rc);
10536 rc = reverse_condition (rc);
10538 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10540 [(set_attr "conds" "use")
10541 (set_attr "length" "4")
10542 (set_attr "arch" "t2,32")
10543 (set_attr "enabled_for_short_it" "yes,no")
10544 (set_attr "type" "logic_shift_imm")]
10547 (define_insn "*arith_adjacentmem"
10548 [(set (match_operand:SI 0 "s_register_operand" "=r")
10549 (match_operator:SI 1 "shiftable_operator"
10550 [(match_operand:SI 2 "memory_operand" "m")
10551 (match_operand:SI 3 "memory_operand" "m")]))
10552 (clobber (match_scratch:SI 4 "=r"))]
10553 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10559 HOST_WIDE_INT val1 = 0, val2 = 0;
10561 if (REGNO (operands[0]) > REGNO (operands[4]))
10563 ldm[1] = operands[4];
10564 ldm[2] = operands[0];
10568 ldm[1] = operands[0];
10569 ldm[2] = operands[4];
10572 base_reg = XEXP (operands[2], 0);
10574 if (!REG_P (base_reg))
10576 val1 = INTVAL (XEXP (base_reg, 1));
10577 base_reg = XEXP (base_reg, 0);
10580 if (!REG_P (XEXP (operands[3], 0)))
10581 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10583 arith[0] = operands[0];
10584 arith[3] = operands[1];
10598 if (val1 !=0 && val2 != 0)
10602 if (val1 == 4 || val2 == 4)
10603 /* Other val must be 8, since we know they are adjacent and neither
10605 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10606 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10608 ldm[0] = ops[0] = operands[4];
10610 ops[2] = GEN_INT (val1);
10611 output_add_immediate (ops);
10613 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10615 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10619 /* Offset is out of range for a single add, so use two ldr. */
10622 ops[2] = GEN_INT (val1);
10623 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10625 ops[2] = GEN_INT (val2);
10626 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10629 else if (val1 != 0)
10632 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10634 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10639 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10641 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10643 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10646 [(set_attr "length" "12")
10647 (set_attr "predicable" "yes")
10648 (set_attr "type" "load_4")]
10651 ; This pattern is never tried by combine, so do it as a peephole
10654 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10655 (match_operand:SI 1 "arm_general_register_operand" ""))
10656 (set (reg:CC CC_REGNUM)
10657 (compare:CC (match_dup 1) (const_int 0)))]
10659 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10660 (set (match_dup 0) (match_dup 1))])]
10665 [(set (match_operand:SI 0 "s_register_operand" "")
10666 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10668 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10669 [(match_operand:SI 3 "s_register_operand" "")
10670 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10671 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10673 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10674 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10679 ;; This split can be used because CC_Z mode implies that the following
10680 ;; branch will be an equality, or an unsigned inequality, so the sign
10681 ;; extension is not needed.
10684 [(set (reg:CC_Z CC_REGNUM)
10686 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10688 (match_operand 1 "const_int_operand" "")))
10689 (clobber (match_scratch:SI 2 ""))]
10691 && ((UINTVAL (operands[1]))
10692 == ((UINTVAL (operands[1])) >> 24) << 24)"
10693 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10694 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10696 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10699 ;; ??? Check the patterns above for Thumb-2 usefulness
10701 (define_expand "prologue"
10702 [(clobber (const_int 0))]
10705 arm_expand_prologue ();
10707 thumb1_expand_prologue ();
10712 (define_expand "epilogue"
10713 [(clobber (const_int 0))]
10716 if (crtl->calls_eh_return)
10717 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10720 thumb1_expand_epilogue ();
10721 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10722 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10724 else if (HAVE_return)
10726 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10727 no need for explicit testing again. */
10728 emit_jump_insn (gen_return ());
10730 else if (TARGET_32BIT)
10732 arm_expand_epilogue (true);
10738 ;; Note - although unspec_volatile's USE all hard registers,
10739 ;; USEs are ignored after relaod has completed. Thus we need
10740 ;; to add an unspec of the link register to ensure that flow
10741 ;; does not think that it is unused by the sibcall branch that
10742 ;; will replace the standard function epilogue.
10743 (define_expand "sibcall_epilogue"
10744 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10745 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10748 arm_expand_epilogue (false);
10753 (define_expand "eh_epilogue"
10754 [(use (match_operand:SI 0 "register_operand" ""))
10755 (use (match_operand:SI 1 "register_operand" ""))
10756 (use (match_operand:SI 2 "register_operand" ""))]
10760 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10761 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10763 rtx ra = gen_rtx_REG (Pmode, 2);
10765 emit_move_insn (ra, operands[2]);
10768 /* This is a hack -- we may have crystalized the function type too
10770 cfun->machine->func_type = 0;
10774 ;; This split is only used during output to reduce the number of patterns
10775 ;; that need assembler instructions adding to them. We allowed the setting
10776 ;; of the conditions to be implicit during rtl generation so that
10777 ;; the conditional compare patterns would work. However this conflicts to
10778 ;; some extent with the conditional data operations, so we have to split them
10781 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10782 ;; conditional execution sufficient?
10785 [(set (match_operand:SI 0 "s_register_operand" "")
10786 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10787 [(match_operand 2 "" "") (match_operand 3 "" "")])
10789 (match_operand 4 "" "")))
10790 (clobber (reg:CC CC_REGNUM))]
10791 "TARGET_ARM && reload_completed"
10792 [(set (match_dup 5) (match_dup 6))
10793 (cond_exec (match_dup 7)
10794 (set (match_dup 0) (match_dup 4)))]
10797 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10798 operands[2], operands[3]);
10799 enum rtx_code rc = GET_CODE (operands[1]);
10801 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10802 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10803 if (mode == CCFPmode || mode == CCFPEmode)
10804 rc = reverse_condition_maybe_unordered (rc);
10806 rc = reverse_condition (rc);
10808 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10813 [(set (match_operand:SI 0 "s_register_operand" "")
10814 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10815 [(match_operand 2 "" "") (match_operand 3 "" "")])
10816 (match_operand 4 "" "")
10818 (clobber (reg:CC CC_REGNUM))]
10819 "TARGET_ARM && reload_completed"
10820 [(set (match_dup 5) (match_dup 6))
10821 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10822 (set (match_dup 0) (match_dup 4)))]
10825 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10826 operands[2], operands[3]);
10828 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10829 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10834 [(set (match_operand:SI 0 "s_register_operand" "")
10835 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10836 [(match_operand 2 "" "") (match_operand 3 "" "")])
10837 (match_operand 4 "" "")
10838 (match_operand 5 "" "")))
10839 (clobber (reg:CC CC_REGNUM))]
10840 "TARGET_ARM && reload_completed"
10841 [(set (match_dup 6) (match_dup 7))
10842 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10843 (set (match_dup 0) (match_dup 4)))
10844 (cond_exec (match_dup 8)
10845 (set (match_dup 0) (match_dup 5)))]
10848 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10849 operands[2], operands[3]);
10850 enum rtx_code rc = GET_CODE (operands[1]);
10852 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10853 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10854 if (mode == CCFPmode || mode == CCFPEmode)
10855 rc = reverse_condition_maybe_unordered (rc);
10857 rc = reverse_condition (rc);
10859 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10864 [(set (match_operand:SI 0 "s_register_operand" "")
10865 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10866 [(match_operand:SI 2 "s_register_operand" "")
10867 (match_operand:SI 3 "arm_add_operand" "")])
10868 (match_operand:SI 4 "arm_rhs_operand" "")
10870 (match_operand:SI 5 "s_register_operand" ""))))
10871 (clobber (reg:CC CC_REGNUM))]
10872 "TARGET_ARM && reload_completed"
10873 [(set (match_dup 6) (match_dup 7))
10874 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10875 (set (match_dup 0) (match_dup 4)))
10876 (cond_exec (match_dup 8)
10877 (set (match_dup 0) (not:SI (match_dup 5))))]
10880 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10881 operands[2], operands[3]);
10882 enum rtx_code rc = GET_CODE (operands[1]);
10884 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10885 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10886 if (mode == CCFPmode || mode == CCFPEmode)
10887 rc = reverse_condition_maybe_unordered (rc);
10889 rc = reverse_condition (rc);
10891 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10895 (define_insn "*cond_move_not"
10896 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10897 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10898 [(match_operand 3 "cc_register" "") (const_int 0)])
10899 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10901 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10905 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10906 [(set_attr "conds" "use")
10907 (set_attr "type" "mvn_reg,multiple")
10908 (set_attr "length" "4,8")]
10911 ;; The next two patterns occur when an AND operation is followed by a
10912 ;; scc insn sequence
10914 (define_insn "*sign_extract_onebit"
10915 [(set (match_operand:SI 0 "s_register_operand" "=r")
10916 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10918 (match_operand:SI 2 "const_int_operand" "n")))
10919 (clobber (reg:CC CC_REGNUM))]
10922 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10923 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10924 return \"mvnne\\t%0, #0\";
10926 [(set_attr "conds" "clob")
10927 (set_attr "length" "8")
10928 (set_attr "type" "multiple")]
10931 (define_insn "*not_signextract_onebit"
10932 [(set (match_operand:SI 0 "s_register_operand" "=r")
10934 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10936 (match_operand:SI 2 "const_int_operand" "n"))))
10937 (clobber (reg:CC CC_REGNUM))]
10940 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10941 output_asm_insn (\"tst\\t%1, %2\", operands);
10942 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10943 return \"movne\\t%0, #0\";
10945 [(set_attr "conds" "clob")
10946 (set_attr "length" "12")
10947 (set_attr "type" "multiple")]
10949 ;; ??? The above patterns need auditing for Thumb-2
10951 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10952 ;; expressions. For simplicity, the first register is also in the unspec
10954 ;; To avoid the usage of GNU extension, the length attribute is computed
10955 ;; in a C function arm_attr_length_push_multi.
10956 (define_insn "*push_multi"
10957 [(match_parallel 2 "multi_register_push"
10958 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10959 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10960 UNSPEC_PUSH_MULT))])]
10964 int num_saves = XVECLEN (operands[2], 0);
10966 /* For the StrongARM at least it is faster to
10967 use STR to store only a single register.
10968 In Thumb mode always use push, and the assembler will pick
10969 something appropriate. */
10970 if (num_saves == 1 && TARGET_ARM)
10971 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10978 strcpy (pattern, \"push%?\\t{%1\");
10980 strcpy (pattern, \"push\\t{%1\");
10982 for (i = 1; i < num_saves; i++)
10984 strcat (pattern, \", %|\");
10986 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10989 strcat (pattern, \"}\");
10990 output_asm_insn (pattern, operands);
10995 [(set_attr "type" "store_16")
10996 (set (attr "length")
10997 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11000 (define_insn "stack_tie"
11001 [(set (mem:BLK (scratch))
11002 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11003 (match_operand:SI 1 "s_register_operand" "rk")]
11007 [(set_attr "length" "0")
11008 (set_attr "type" "block")]
11011 ;; Pop (as used in epilogue RTL)
11013 (define_insn "*load_multiple_with_writeback"
11014 [(match_parallel 0 "load_multiple_operation"
11015 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11016 (plus:SI (match_dup 1)
11017 (match_operand:SI 2 "const_int_I_operand" "I")))
11018 (set (match_operand:SI 3 "s_register_operand" "=rk")
11019 (mem:SI (match_dup 1)))
11021 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11024 arm_output_multireg_pop (operands, /*return_pc=*/false,
11025 /*cond=*/const_true_rtx,
11031 [(set_attr "type" "load_16")
11032 (set_attr "predicable" "yes")
11033 (set (attr "length")
11034 (symbol_ref "arm_attr_length_pop_multi (operands,
11035 /*return_pc=*/false,
11036 /*write_back_p=*/true)"))]
11039 ;; Pop with return (as used in epilogue RTL)
11041 ;; This instruction is generated when the registers are popped at the end of
11042 ;; epilogue. Here, instead of popping the value into LR and then generating
11043 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11045 (define_insn "*pop_multiple_with_writeback_and_return"
11046 [(match_parallel 0 "pop_multiple_return"
11048 (set (match_operand:SI 1 "s_register_operand" "+rk")
11049 (plus:SI (match_dup 1)
11050 (match_operand:SI 2 "const_int_I_operand" "I")))
11051 (set (match_operand:SI 3 "s_register_operand" "=rk")
11052 (mem:SI (match_dup 1)))
11054 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11057 arm_output_multireg_pop (operands, /*return_pc=*/true,
11058 /*cond=*/const_true_rtx,
11064 [(set_attr "type" "load_16")
11065 (set_attr "predicable" "yes")
11066 (set (attr "length")
11067 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11068 /*write_back_p=*/true)"))]
11071 (define_insn "*pop_multiple_with_return"
11072 [(match_parallel 0 "pop_multiple_return"
11074 (set (match_operand:SI 2 "s_register_operand" "=rk")
11075 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11077 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11080 arm_output_multireg_pop (operands, /*return_pc=*/true,
11081 /*cond=*/const_true_rtx,
11087 [(set_attr "type" "load_16")
11088 (set_attr "predicable" "yes")
11089 (set (attr "length")
11090 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11091 /*write_back_p=*/false)"))]
11094 ;; Load into PC and return
11095 (define_insn "*ldr_with_return"
11097 (set (reg:SI PC_REGNUM)
11098 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11099 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11100 "ldr%?\t%|pc, [%0], #4"
11101 [(set_attr "type" "load_4")
11102 (set_attr "predicable" "yes")]
11104 ;; Pop for floating point registers (as used in epilogue RTL)
11105 (define_insn "*vfp_pop_multiple_with_writeback"
11106 [(match_parallel 0 "pop_multiple_fp"
11107 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11108 (plus:SI (match_dup 1)
11109 (match_operand:SI 2 "const_int_I_operand" "I")))
11110 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11111 (mem:DF (match_dup 1)))])]
11112 "TARGET_32BIT && TARGET_HARD_FLOAT"
11115 int num_regs = XVECLEN (operands[0], 0);
11118 strcpy (pattern, \"vldm\\t\");
11119 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11120 strcat (pattern, \"!, {\");
11121 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11122 strcat (pattern, \"%P0\");
11123 if ((num_regs - 1) > 1)
11125 strcat (pattern, \"-%P1\");
11126 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11129 strcat (pattern, \"}\");
11130 output_asm_insn (pattern, op_list);
11134 [(set_attr "type" "load_16")
11135 (set_attr "conds" "unconditional")
11136 (set_attr "predicable" "no")]
11139 ;; Special patterns for dealing with the constant pool
11141 (define_insn "align_4"
11142 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11145 assemble_align (32);
11148 [(set_attr "type" "no_insn")]
11151 (define_insn "align_8"
11152 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11155 assemble_align (64);
11158 [(set_attr "type" "no_insn")]
11161 (define_insn "consttable_end"
11162 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11165 making_const_table = FALSE;
11168 [(set_attr "type" "no_insn")]
11171 (define_insn "consttable_1"
11172 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11175 making_const_table = TRUE;
11176 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11177 assemble_zeros (3);
11180 [(set_attr "length" "4")
11181 (set_attr "type" "no_insn")]
11184 (define_insn "consttable_2"
11185 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11189 rtx x = operands[0];
11190 making_const_table = TRUE;
11191 switch (GET_MODE_CLASS (GET_MODE (x)))
11194 arm_emit_fp16_const (x);
11197 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11198 assemble_zeros (2);
11203 [(set_attr "length" "4")
11204 (set_attr "type" "no_insn")]
11207 (define_insn "consttable_4"
11208 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11212 rtx x = operands[0];
11213 making_const_table = TRUE;
11214 scalar_float_mode float_mode;
11215 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11216 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11219 /* XXX: Sometimes gcc does something really dumb and ends up with
11220 a HIGH in a constant pool entry, usually because it's trying to
11221 load into a VFP register. We know this will always be used in
11222 combination with a LO_SUM which ignores the high bits, so just
11223 strip off the HIGH. */
11224 if (GET_CODE (x) == HIGH)
11226 assemble_integer (x, 4, BITS_PER_WORD, 1);
11227 mark_symbol_refs_as_used (x);
11231 [(set_attr "length" "4")
11232 (set_attr "type" "no_insn")]
11235 (define_insn "consttable_8"
11236 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11240 making_const_table = TRUE;
11241 scalar_float_mode float_mode;
11242 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11243 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11244 float_mode, BITS_PER_WORD);
11246 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11249 [(set_attr "length" "8")
11250 (set_attr "type" "no_insn")]
11253 (define_insn "consttable_16"
11254 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11258 making_const_table = TRUE;
11259 scalar_float_mode float_mode;
11260 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11261 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11262 float_mode, BITS_PER_WORD);
11264 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11267 [(set_attr "length" "16")
11268 (set_attr "type" "no_insn")]
11271 ;; V5 Instructions,
11273 (define_insn "clzsi2"
11274 [(set (match_operand:SI 0 "s_register_operand" "=r")
11275 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11276 "TARGET_32BIT && arm_arch5t"
11278 [(set_attr "predicable" "yes")
11279 (set_attr "type" "clz")])
11281 (define_insn "rbitsi2"
11282 [(set (match_operand:SI 0 "s_register_operand" "=r")
11283 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11284 "TARGET_32BIT && arm_arch_thumb2"
11286 [(set_attr "predicable" "yes")
11287 (set_attr "type" "clz")])
11289 ;; Keep this as a CTZ expression until after reload and then split
11290 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11291 ;; to fold with any other expression.
11293 (define_insn_and_split "ctzsi2"
11294 [(set (match_operand:SI 0 "s_register_operand" "=r")
11295 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11296 "TARGET_32BIT && arm_arch_thumb2"
11298 "&& reload_completed"
11301 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11302 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11306 ;; V5E instructions.
11308 (define_insn "prefetch"
11309 [(prefetch (match_operand:SI 0 "address_operand" "p")
11310 (match_operand:SI 1 "" "")
11311 (match_operand:SI 2 "" ""))]
11312 "TARGET_32BIT && arm_arch5te"
11314 [(set_attr "type" "load_4")]
11317 ;; General predication pattern
11320 [(match_operator 0 "arm_comparison_operator"
11321 [(match_operand 1 "cc_register" "")
11324 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11326 [(set_attr "predicated" "yes")]
11329 (define_insn "force_register_use"
11330 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11333 [(set_attr "length" "0")
11334 (set_attr "type" "no_insn")]
11338 ;; Patterns for exception handling
11340 (define_expand "eh_return"
11341 [(use (match_operand 0 "general_operand" ""))]
11346 emit_insn (gen_arm_eh_return (operands[0]));
11348 emit_insn (gen_thumb_eh_return (operands[0]));
11353 ;; We can't expand this before we know where the link register is stored.
11354 (define_insn_and_split "arm_eh_return"
11355 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11357 (clobber (match_scratch:SI 1 "=&r"))]
11360 "&& reload_completed"
11364 arm_set_return_address (operands[0], operands[1]);
11372 (define_insn "load_tp_hard"
11373 [(set (match_operand:SI 0 "register_operand" "=r")
11374 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11376 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11377 [(set_attr "predicable" "yes")
11378 (set_attr "type" "mrs")]
11381 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11382 (define_insn "load_tp_soft"
11383 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11384 (clobber (reg:SI LR_REGNUM))
11385 (clobber (reg:SI IP_REGNUM))
11386 (clobber (reg:CC CC_REGNUM))]
11388 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11389 [(set_attr "conds" "clob")
11390 (set_attr "type" "branch")]
11393 ;; tls descriptor call
11394 (define_insn "tlscall"
11395 [(set (reg:SI R0_REGNUM)
11396 (unspec:SI [(reg:SI R0_REGNUM)
11397 (match_operand:SI 0 "" "X")
11398 (match_operand 1 "" "")] UNSPEC_TLS))
11399 (clobber (reg:SI R1_REGNUM))
11400 (clobber (reg:SI LR_REGNUM))
11401 (clobber (reg:SI CC_REGNUM))]
11404 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11405 INTVAL (operands[1]));
11406 return "bl\\t%c0(tlscall)";
11408 [(set_attr "conds" "clob")
11409 (set_attr "length" "4")
11410 (set_attr "type" "branch")]
11413 ;; For thread pointer builtin
11414 (define_expand "get_thread_pointersi"
11415 [(match_operand:SI 0 "s_register_operand" "=r")]
11419 arm_load_tp (operands[0]);
11425 ;; We only care about the lower 16 bits of the constant
11426 ;; being inserted into the upper 16 bits of the register.
11427 (define_insn "*arm_movtas_ze"
11428 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11431 (match_operand:SI 1 "const_int_operand" ""))]
11436 [(set_attr "arch" "32,v8mb")
11437 (set_attr "predicable" "yes")
11438 (set_attr "length" "4")
11439 (set_attr "type" "alu_sreg")]
11442 (define_insn "*arm_rev"
11443 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11444 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11450 [(set_attr "arch" "t1,t2,32")
11451 (set_attr "length" "2,2,4")
11452 (set_attr "predicable" "no,yes,yes")
11453 (set_attr "type" "rev")]
11456 (define_expand "arm_legacy_rev"
11457 [(set (match_operand:SI 2 "s_register_operand" "")
11458 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11462 (lshiftrt:SI (match_dup 2)
11464 (set (match_operand:SI 3 "s_register_operand" "")
11465 (rotatert:SI (match_dup 1)
11468 (and:SI (match_dup 2)
11469 (const_int -65281)))
11470 (set (match_operand:SI 0 "s_register_operand" "")
11471 (xor:SI (match_dup 3)
11477 ;; Reuse temporaries to keep register pressure down.
11478 (define_expand "thumb_legacy_rev"
11479 [(set (match_operand:SI 2 "s_register_operand" "")
11480 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11482 (set (match_operand:SI 3 "s_register_operand" "")
11483 (lshiftrt:SI (match_dup 1)
11486 (ior:SI (match_dup 3)
11488 (set (match_operand:SI 4 "s_register_operand" "")
11490 (set (match_operand:SI 5 "s_register_operand" "")
11491 (rotatert:SI (match_dup 1)
11494 (ashift:SI (match_dup 5)
11497 (lshiftrt:SI (match_dup 5)
11500 (ior:SI (match_dup 5)
11503 (rotatert:SI (match_dup 5)
11505 (set (match_operand:SI 0 "s_register_operand" "")
11506 (ior:SI (match_dup 5)
11512 ;; ARM-specific expansion of signed mod by power of 2
11513 ;; using conditional negate.
11514 ;; For r0 % n where n is a power of 2 produce:
11516 ;; and r0, r0, #(n - 1)
11517 ;; and r1, r1, #(n - 1)
11518 ;; rsbpl r0, r1, #0
11520 (define_expand "modsi3"
11521 [(match_operand:SI 0 "register_operand" "")
11522 (match_operand:SI 1 "register_operand" "")
11523 (match_operand:SI 2 "const_int_operand" "")]
11526 HOST_WIDE_INT val = INTVAL (operands[2]);
11529 || exact_log2 (val) <= 0)
11532 rtx mask = GEN_INT (val - 1);
11534 /* In the special case of x0 % 2 we can do the even shorter:
11537 rsblt r0, r0, #0. */
11541 rtx cc_reg = arm_gen_compare_reg (LT,
11542 operands[1], const0_rtx, NULL_RTX);
11543 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11544 rtx masked = gen_reg_rtx (SImode);
11546 emit_insn (gen_andsi3 (masked, operands[1], mask));
11547 emit_move_insn (operands[0],
11548 gen_rtx_IF_THEN_ELSE (SImode, cond,
11549 gen_rtx_NEG (SImode,
11555 rtx neg_op = gen_reg_rtx (SImode);
11556 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11559 /* Extract the condition register and mode. */
11560 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11561 rtx cc_reg = SET_DEST (cmp);
11562 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11564 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11566 rtx masked_neg = gen_reg_rtx (SImode);
11567 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11569 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11570 during expand does not always work. Do an IF_THEN_ELSE instead. */
11571 emit_move_insn (operands[0],
11572 gen_rtx_IF_THEN_ELSE (SImode, cond,
11573 gen_rtx_NEG (SImode, masked_neg),
11581 (define_expand "bswapsi2"
11582 [(set (match_operand:SI 0 "s_register_operand" "=r")
11583 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11584 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11588 rtx op2 = gen_reg_rtx (SImode);
11589 rtx op3 = gen_reg_rtx (SImode);
11593 rtx op4 = gen_reg_rtx (SImode);
11594 rtx op5 = gen_reg_rtx (SImode);
11596 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11597 op2, op3, op4, op5));
11601 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11610 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11611 ;; and unsigned variants, respectively. For rev16, expose
11612 ;; byte-swapping in the lower 16 bits only.
11613 (define_insn "*arm_revsh"
11614 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11615 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11621 [(set_attr "arch" "t1,t2,32")
11622 (set_attr "length" "2,2,4")
11623 (set_attr "type" "rev")]
11626 (define_insn "*arm_rev16"
11627 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11628 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11634 [(set_attr "arch" "t1,t2,32")
11635 (set_attr "length" "2,2,4")
11636 (set_attr "type" "rev")]
11639 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11640 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11641 ;; each valid permutation.
11643 (define_insn "arm_rev16si2"
11644 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11645 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11647 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11648 (and:SI (lshiftrt:SI (match_dup 1)
11650 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11652 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11653 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11655 [(set_attr "arch" "t1,t2,32")
11656 (set_attr "length" "2,2,4")
11657 (set_attr "type" "rev")]
11660 (define_insn "arm_rev16si2_alt"
11661 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11662 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11664 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11665 (and:SI (ashift:SI (match_dup 1)
11667 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11669 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11670 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11672 [(set_attr "arch" "t1,t2,32")
11673 (set_attr "length" "2,2,4")
11674 (set_attr "type" "rev")]
11677 (define_expand "bswaphi2"
11678 [(set (match_operand:HI 0 "s_register_operand" "=r")
11679 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11684 ;; Patterns for LDRD/STRD in Thumb2 mode
11686 (define_insn "*thumb2_ldrd"
11687 [(set (match_operand:SI 0 "s_register_operand" "=r")
11688 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11689 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11690 (set (match_operand:SI 3 "s_register_operand" "=r")
11691 (mem:SI (plus:SI (match_dup 1)
11692 (match_operand:SI 4 "const_int_operand" ""))))]
11693 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11694 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11695 && (operands_ok_ldrd_strd (operands[0], operands[3],
11696 operands[1], INTVAL (operands[2]),
11698 "ldrd%?\t%0, %3, [%1, %2]"
11699 [(set_attr "type" "load_8")
11700 (set_attr "predicable" "yes")])
11702 (define_insn "*thumb2_ldrd_base"
11703 [(set (match_operand:SI 0 "s_register_operand" "=r")
11704 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11705 (set (match_operand:SI 2 "s_register_operand" "=r")
11706 (mem:SI (plus:SI (match_dup 1)
11708 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11709 && (operands_ok_ldrd_strd (operands[0], operands[2],
11710 operands[1], 0, false, true))"
11711 "ldrd%?\t%0, %2, [%1]"
11712 [(set_attr "type" "load_8")
11713 (set_attr "predicable" "yes")])
11715 (define_insn "*thumb2_ldrd_base_neg"
11716 [(set (match_operand:SI 0 "s_register_operand" "=r")
11717 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11719 (set (match_operand:SI 2 "s_register_operand" "=r")
11720 (mem:SI (match_dup 1)))]
11721 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11722 && (operands_ok_ldrd_strd (operands[0], operands[2],
11723 operands[1], -4, false, true))"
11724 "ldrd%?\t%0, %2, [%1, #-4]"
11725 [(set_attr "type" "load_8")
11726 (set_attr "predicable" "yes")])
11728 (define_insn "*thumb2_strd"
11729 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11730 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11731 (match_operand:SI 2 "s_register_operand" "r"))
11732 (set (mem:SI (plus:SI (match_dup 0)
11733 (match_operand:SI 3 "const_int_operand" "")))
11734 (match_operand:SI 4 "s_register_operand" "r"))]
11735 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11736 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11737 && (operands_ok_ldrd_strd (operands[2], operands[4],
11738 operands[0], INTVAL (operands[1]),
11740 "strd%?\t%2, %4, [%0, %1]"
11741 [(set_attr "type" "store_8")
11742 (set_attr "predicable" "yes")])
11744 (define_insn "*thumb2_strd_base"
11745 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11746 (match_operand:SI 1 "s_register_operand" "r"))
11747 (set (mem:SI (plus:SI (match_dup 0)
11749 (match_operand:SI 2 "s_register_operand" "r"))]
11750 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11751 && (operands_ok_ldrd_strd (operands[1], operands[2],
11752 operands[0], 0, false, false))"
11753 "strd%?\t%1, %2, [%0]"
11754 [(set_attr "type" "store_8")
11755 (set_attr "predicable" "yes")])
11757 (define_insn "*thumb2_strd_base_neg"
11758 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11760 (match_operand:SI 1 "s_register_operand" "r"))
11761 (set (mem:SI (match_dup 0))
11762 (match_operand:SI 2 "s_register_operand" "r"))]
11763 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11764 && (operands_ok_ldrd_strd (operands[1], operands[2],
11765 operands[0], -4, false, false))"
11766 "strd%?\t%1, %2, [%0, #-4]"
11767 [(set_attr "type" "store_8")
11768 (set_attr "predicable" "yes")])
11770 ;; ARMv8 CRC32 instructions.
11771 (define_insn "<crc_variant>"
11772 [(set (match_operand:SI 0 "s_register_operand" "=r")
11773 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11774 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11777 "<crc_variant>\\t%0, %1, %2"
11778 [(set_attr "type" "crc")
11779 (set_attr "conds" "unconditional")]
11782 ;; Load the load/store double peephole optimizations.
11783 (include "ldrdstrd.md")
11785 ;; Load the load/store multiple patterns
11786 (include "ldmstm.md")
11788 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11789 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11790 ;; The operands are validated through the load_multiple_operation
11791 ;; match_parallel predicate rather than through constraints so enable it only
11793 (define_insn "*load_multiple"
11794 [(match_parallel 0 "load_multiple_operation"
11795 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11796 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11798 "TARGET_32BIT && reload_completed"
11801 arm_output_multireg_pop (operands, /*return_pc=*/false,
11802 /*cond=*/const_true_rtx,
11808 [(set_attr "predicable" "yes")]
11811 (define_expand "copysignsf3"
11812 [(match_operand:SF 0 "register_operand")
11813 (match_operand:SF 1 "register_operand")
11814 (match_operand:SF 2 "register_operand")]
11815 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11817 emit_move_insn (operands[0], operands[2]);
11818 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11819 GEN_INT (31), GEN_INT (0),
11820 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11825 (define_expand "copysigndf3"
11826 [(match_operand:DF 0 "register_operand")
11827 (match_operand:DF 1 "register_operand")
11828 (match_operand:DF 2 "register_operand")]
11829 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11831 rtx op0_low = gen_lowpart (SImode, operands[0]);
11832 rtx op0_high = gen_highpart (SImode, operands[0]);
11833 rtx op1_low = gen_lowpart (SImode, operands[1]);
11834 rtx op1_high = gen_highpart (SImode, operands[1]);
11835 rtx op2_high = gen_highpart (SImode, operands[2]);
11837 rtx scratch1 = gen_reg_rtx (SImode);
11838 rtx scratch2 = gen_reg_rtx (SImode);
11839 emit_move_insn (scratch1, op2_high);
11840 emit_move_insn (scratch2, op1_high);
11842 emit_insn(gen_rtx_SET(scratch1,
11843 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11844 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11845 emit_move_insn (op0_low, op1_low);
11846 emit_move_insn (op0_high, scratch2);
11852 ;; movmisalign patterns for HImode and SImode.
11853 (define_expand "movmisalign<mode>"
11854 [(match_operand:HSI 0 "general_operand")
11855 (match_operand:HSI 1 "general_operand")]
11858 /* This pattern is not permitted to fail during expansion: if both arguments
11859 are non-registers (e.g. memory := constant), force operand 1 into a
11861 rtx (* gen_unaligned_load)(rtx, rtx);
11862 rtx tmp_dest = operands[0];
11863 if (!s_register_operand (operands[0], <MODE>mode)
11864 && !s_register_operand (operands[1], <MODE>mode))
11865 operands[1] = force_reg (<MODE>mode, operands[1]);
11867 if (<MODE>mode == HImode)
11869 gen_unaligned_load = gen_unaligned_loadhiu;
11870 tmp_dest = gen_reg_rtx (SImode);
11873 gen_unaligned_load = gen_unaligned_loadsi;
11875 if (MEM_P (operands[1]))
11877 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11878 if (<MODE>mode == HImode)
11879 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11882 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11887 (define_insn "<cdp>"
11888 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11889 (match_operand:SI 1 "immediate_operand" "n")
11890 (match_operand:SI 2 "immediate_operand" "n")
11891 (match_operand:SI 3 "immediate_operand" "n")
11892 (match_operand:SI 4 "immediate_operand" "n")
11893 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11894 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11896 arm_const_bounds (operands[0], 0, 16);
11897 arm_const_bounds (operands[1], 0, 16);
11898 arm_const_bounds (operands[2], 0, (1 << 5));
11899 arm_const_bounds (operands[3], 0, (1 << 5));
11900 arm_const_bounds (operands[4], 0, (1 << 5));
11901 arm_const_bounds (operands[5], 0, 8);
11902 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11904 [(set_attr "length" "4")
11905 (set_attr "type" "coproc")])
11907 (define_insn "*ldc"
11908 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11909 (match_operand:SI 1 "immediate_operand" "n")
11910 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11911 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11913 arm_const_bounds (operands[0], 0, 16);
11914 arm_const_bounds (operands[1], 0, (1 << 5));
11915 return "<ldc>\\tp%c0, CR%c1, %2";
11917 [(set_attr "length" "4")
11918 (set_attr "type" "coproc")])
11920 (define_insn "*stc"
11921 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11922 (match_operand:SI 1 "immediate_operand" "n")
11923 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11924 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11926 arm_const_bounds (operands[0], 0, 16);
11927 arm_const_bounds (operands[1], 0, (1 << 5));
11928 return "<stc>\\tp%c0, CR%c1, %2";
11930 [(set_attr "length" "4")
11931 (set_attr "type" "coproc")])
11933 (define_expand "<ldc>"
11934 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11935 (match_operand:SI 1 "immediate_operand")
11936 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11937 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11939 (define_expand "<stc>"
11940 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11941 (match_operand:SI 1 "immediate_operand")
11942 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11943 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
11945 (define_insn "<mcr>"
11946 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11947 (match_operand:SI 1 "immediate_operand" "n")
11948 (match_operand:SI 2 "s_register_operand" "r")
11949 (match_operand:SI 3 "immediate_operand" "n")
11950 (match_operand:SI 4 "immediate_operand" "n")
11951 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
11952 (use (match_dup 2))]
11953 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
11955 arm_const_bounds (operands[0], 0, 16);
11956 arm_const_bounds (operands[1], 0, 8);
11957 arm_const_bounds (operands[3], 0, (1 << 5));
11958 arm_const_bounds (operands[4], 0, (1 << 5));
11959 arm_const_bounds (operands[5], 0, 8);
11960 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
11962 [(set_attr "length" "4")
11963 (set_attr "type" "coproc")])
11965 (define_insn "<mrc>"
11966 [(set (match_operand:SI 0 "s_register_operand" "=r")
11967 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
11968 (match_operand:SI 2 "immediate_operand" "n")
11969 (match_operand:SI 3 "immediate_operand" "n")
11970 (match_operand:SI 4 "immediate_operand" "n")
11971 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
11972 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
11974 arm_const_bounds (operands[1], 0, 16);
11975 arm_const_bounds (operands[2], 0, 8);
11976 arm_const_bounds (operands[3], 0, (1 << 5));
11977 arm_const_bounds (operands[4], 0, (1 << 5));
11978 arm_const_bounds (operands[5], 0, 8);
11979 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
11981 [(set_attr "length" "4")
11982 (set_attr "type" "coproc")])
11984 (define_insn "<mcrr>"
11985 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11986 (match_operand:SI 1 "immediate_operand" "n")
11987 (match_operand:DI 2 "s_register_operand" "r")
11988 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
11989 (use (match_dup 2))]
11990 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
11992 arm_const_bounds (operands[0], 0, 16);
11993 arm_const_bounds (operands[1], 0, 8);
11994 arm_const_bounds (operands[3], 0, (1 << 5));
11995 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
11997 [(set_attr "length" "4")
11998 (set_attr "type" "coproc")])
12000 (define_insn "<mrrc>"
12001 [(set (match_operand:DI 0 "s_register_operand" "=r")
12002 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12003 (match_operand:SI 2 "immediate_operand" "n")
12004 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12005 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12007 arm_const_bounds (operands[1], 0, 16);
12008 arm_const_bounds (operands[2], 0, 8);
12009 arm_const_bounds (operands[3], 0, (1 << 5));
12010 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12012 [(set_attr "length" "4")
12013 (set_attr "type" "coproc")])
12015 ;; Vector bits common to IWMMXT and Neon
12016 (include "vec-common.md")
12017 ;; Load the Intel Wireless Multimedia Extension patterns
12018 (include "iwmmxt.md")
12019 ;; Load the VFP co-processor patterns
12021 ;; Thumb-1 patterns
12022 (include "thumb1.md")
12023 ;; Thumb-2 patterns
12024 (include "thumb2.md")
12026 (include "neon.md")
12028 (include "crypto.md")
12029 ;; Synchronization Primitives
12030 (include "sync.md")
12031 ;; Fixed-point patterns
12032 (include "arm-fixed.md")