1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2019 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;---------------------------------------------------------------------------
29 ;; Register numbers -- All machine registers should be defined here
31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (R4_REGNUM 4) ; Fifth CORE register
34 (FDPIC_REGNUM 9) ; FDPIC register
35 (IP_REGNUM 12) ; Scratch register
36 (SP_REGNUM 13) ; Stack pointer
37 (LR_REGNUM 14) ; Return address register
38 (PC_REGNUM 15) ; Program counter
39 (LAST_ARM_REGNUM 15) ;
40 (CC_REGNUM 100) ; Condition code pseudo register
41 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
44 ;; 3rd operand to select_dominance_cc_mode
51 ;; conditional compare combination
62 ;;---------------------------------------------------------------------------
65 ;; Processor type. This is created automatically from arm-cores.def.
66 (include "arm-tune.md")
68 ;; Instruction classification types
71 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
72 ; generating ARM code. This is used to control the length of some insn
73 ; patterns that share the same RTL in both ARM and Thumb code.
74 (define_attr "is_thumb" "yes,no"
75 (const (if_then_else (symbol_ref "TARGET_THUMB")
76 (const_string "yes") (const_string "no"))))
78 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
79 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
81 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
82 (define_attr "is_thumb1" "yes,no"
83 (const (if_then_else (symbol_ref "TARGET_THUMB1")
84 (const_string "yes") (const_string "no"))))
86 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
87 ; The arm_restrict_it flag enables the "short IT" feature which
88 ; restricts IT blocks to a single 16-bit instruction.
89 ; This attribute should only be used on 16-bit Thumb-2 instructions
90 ; which may be predicated (the "predicable" attribute must be set).
91 (define_attr "predicable_short_it" "no,yes" (const_string "no"))
93 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
94 ; This attribute should only be used on instructions which may emit
95 ; an IT block in their expansion which is not a short IT.
96 (define_attr "enabled_for_short_it" "no,yes" (const_string "yes"))
98 ;; Operand number of an input operand that is shifted. Zero if the
99 ;; given instruction does not shift one of its input operands.
100 (define_attr "shift" "" (const_int 0))
102 ;; [For compatibility with AArch64 in pipeline models]
103 ;; Attribute that specifies whether or not the instruction touches fp
105 (define_attr "fp" "no,yes" (const_string "no"))
107 ; Floating Point Unit. If we only have floating point emulation, then there
108 ; is no point in scheduling the floating point insns. (Well, for best
109 ; performance we should try and group them together).
110 (define_attr "fpu" "none,vfp"
111 (const (symbol_ref "arm_fpu_attr")))
113 ; Predicated means that the insn form is conditionally executed based on a
114 ; predicate. We default to 'no' because no Thumb patterns match this rule
115 ; and not all ARM insns do.
116 (define_attr "predicated" "yes,no" (const_string "no"))
118 ; LENGTH of an instruction (in bytes)
119 (define_attr "length" ""
122 ; The architecture which supports the instruction (or alternative).
123 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
124 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
125 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
126 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
127 ; Baseline. This attribute is used to compute attribute "enabled",
128 ; use type "any" to enable an alternative in all cases.
129 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
130 (const_string "any"))
132 (define_attr "arch_enabled" "no,yes"
133 (cond [(eq_attr "arch" "any")
136 (and (eq_attr "arch" "a")
137 (match_test "TARGET_ARM"))
140 (and (eq_attr "arch" "t")
141 (match_test "TARGET_THUMB"))
144 (and (eq_attr "arch" "t1")
145 (match_test "TARGET_THUMB1"))
148 (and (eq_attr "arch" "t2")
149 (match_test "TARGET_THUMB2"))
152 (and (eq_attr "arch" "32")
153 (match_test "TARGET_32BIT"))
156 (and (eq_attr "arch" "v6")
157 (match_test "TARGET_32BIT && arm_arch6"))
160 (and (eq_attr "arch" "nov6")
161 (match_test "TARGET_32BIT && !arm_arch6"))
164 (and (eq_attr "arch" "v6t2")
165 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
168 (and (eq_attr "arch" "v8mb")
169 (match_test "TARGET_THUMB1 && arm_arch8"))
172 (and (eq_attr "arch" "iwmmxt2")
173 (match_test "TARGET_REALLY_IWMMXT2"))
176 (and (eq_attr "arch" "armv6_or_vfpv3")
177 (match_test "arm_arch6 || TARGET_VFP3"))
180 (and (eq_attr "arch" "neon")
181 (match_test "TARGET_NEON"))
185 (const_string "no")))
187 (define_attr "opt" "any,speed,size"
188 (const_string "any"))
190 (define_attr "opt_enabled" "no,yes"
191 (cond [(eq_attr "opt" "any")
194 (and (eq_attr "opt" "speed")
195 (match_test "optimize_function_for_speed_p (cfun)"))
198 (and (eq_attr "opt" "size")
199 (match_test "optimize_function_for_size_p (cfun)"))
200 (const_string "yes")]
201 (const_string "no")))
203 (define_attr "use_literal_pool" "no,yes"
204 (cond [(and (eq_attr "type" "f_loads,f_loadd")
205 (match_test "CONSTANT_P (operands[1])"))
206 (const_string "yes")]
207 (const_string "no")))
209 ; Enable all alternatives that are both arch_enabled and insn_enabled.
210 ; FIXME:: opt_enabled has been temporarily removed till the time we have
211 ; an attribute that allows the use of such alternatives.
212 ; This depends on caching of speed_p, size_p on a per
213 ; alternative basis. The problem is that the enabled attribute
214 ; cannot depend on any state that is not cached or is not constant
215 ; for a compilation unit. We probably need a generic "hot/cold"
216 ; alternative which if implemented can help with this. We disable this
217 ; until such a time as this is implemented and / or the improvements or
218 ; regressions with removing this attribute are double checked.
219 ; See ashldi3_neon and <shift>di3_neon in neon.md.
221 (define_attr "enabled" "no,yes"
222 (cond [(and (eq_attr "predicable_short_it" "no")
223 (and (eq_attr "predicated" "yes")
224 (match_test "arm_restrict_it")))
227 (and (eq_attr "enabled_for_short_it" "no")
228 (match_test "arm_restrict_it"))
231 (eq_attr "arch_enabled" "no")
233 (const_string "yes")))
235 ; POOL_RANGE is how far away from a constant pool entry that this insn
236 ; can be placed. If the distance is zero, then this insn will never
237 ; reference the pool.
238 ; Note that for Thumb constant pools the PC value is rounded down to the
239 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
240 ; Thumb insns) should be set to <max_range> - 2.
241 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
242 ; before its address. It is set to <max_range> - (8 + <data_size>).
243 (define_attr "arm_pool_range" "" (const_int 0))
244 (define_attr "thumb2_pool_range" "" (const_int 0))
245 (define_attr "arm_neg_pool_range" "" (const_int 0))
246 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
248 (define_attr "pool_range" ""
249 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
250 (attr "arm_pool_range")))
251 (define_attr "neg_pool_range" ""
252 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
253 (attr "arm_neg_pool_range")))
255 ; An assembler sequence may clobber the condition codes without us knowing.
256 ; If such an insn references the pool, then we have no way of knowing how,
257 ; so use the most conservative value for pool_range.
258 (define_asm_attributes
259 [(set_attr "conds" "clob")
260 (set_attr "length" "4")
261 (set_attr "pool_range" "250")])
263 ; Load scheduling, set from the arm_ld_sched variable
264 ; initialized by arm_option_override()
265 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
267 ; condition codes: this one is used by final_prescan_insn to speed up
268 ; conditionalizing instructions. It saves having to scan the rtl to see if
269 ; it uses or alters the condition codes.
271 ; USE means that the condition codes are used by the insn in the process of
272 ; outputting code, this means (at present) that we can't use the insn in
275 ; SET means that the purpose of the insn is to set the condition codes in a
276 ; well defined manner.
278 ; CLOB means that the condition codes are altered in an undefined manner, if
279 ; they are altered at all
281 ; UNCONDITIONAL means the instruction cannot be conditionally executed and
282 ; that the instruction does not use or alter the condition codes.
284 ; NOCOND means that the instruction does not use or alter the condition
285 ; codes but can be converted into a conditionally exectuted instruction.
287 (define_attr "conds" "use,set,clob,unconditional,nocond"
289 (ior (eq_attr "is_thumb1" "yes")
290 (eq_attr "type" "call"))
291 (const_string "clob")
292 (if_then_else (eq_attr "is_neon_type" "no")
293 (const_string "nocond")
294 (const_string "unconditional"))))
296 ; Predicable means that the insn can be conditionally executed based on
297 ; an automatically added predicate (additional patterns are generated by
298 ; gen...). We default to 'no' because no Thumb patterns match this rule
299 ; and not all ARM patterns do.
300 (define_attr "predicable" "no,yes" (const_string "no"))
302 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
303 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
304 ; suffer blockages enough to warrant modelling this (and it can adversely
305 ; affect the schedule).
306 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
308 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
309 ; to stall the processor. Used with model_wbuf above.
310 (define_attr "write_conflict" "no,yes"
311 (if_then_else (eq_attr "type"
314 (const_string "no")))
316 ; Classify the insns into those that take one cycle and those that take more
317 ; than one on the main cpu execution unit.
318 (define_attr "core_cycles" "single,multi"
319 (if_then_else (eq_attr "type"
320 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
321 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
322 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
323 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
324 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
325 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
326 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
327 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
328 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
329 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
330 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
331 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
332 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
333 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
334 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
335 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
336 (const_string "single")
337 (const_string "multi")))
339 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
340 ;; distant label. Only applicable to Thumb code.
341 (define_attr "far_jump" "yes,no" (const_string "no"))
344 ;; The number of machine instructions this pattern expands to.
345 ;; Used for Thumb-2 conditional execution.
346 (define_attr "ce_count" "" (const_int 1))
348 ;;---------------------------------------------------------------------------
351 (include "unspecs.md")
353 ;;---------------------------------------------------------------------------
356 (include "iterators.md")
358 ;;---------------------------------------------------------------------------
361 (include "predicates.md")
362 (include "constraints.md")
364 ;;---------------------------------------------------------------------------
365 ;; Pipeline descriptions
367 (define_attr "tune_cortexr4" "yes,no"
369 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
371 (const_string "no"))))
373 ;; True if the generic scheduling description should be used.
375 (define_attr "generic_sched" "yes,no"
377 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
378 arm926ejs,arm10e,arm1026ejs,arm1136js,\
379 arm1136jfs,cortexa5,cortexa7,cortexa8,\
380 cortexa9,cortexa12,cortexa15,cortexa17,\
381 cortexa53,cortexa57,cortexm4,cortexm7,\
382 exynosm1,marvell_pj4,xgene1")
383 (eq_attr "tune_cortexr4" "yes"))
385 (const_string "yes"))))
387 (define_attr "generic_vfp" "yes,no"
389 (and (eq_attr "fpu" "vfp")
390 (eq_attr "tune" "!arm10e,cortexa5,cortexa7,\
391 cortexa8,cortexa9,cortexa53,cortexm4,\
392 cortexm7,marvell_pj4,xgene1")
393 (eq_attr "tune_cortexr4" "no"))
395 (const_string "no"))))
397 (include "marvell-f-iwmmxt.md")
398 (include "arm-generic.md")
399 (include "arm926ejs.md")
400 (include "arm1020e.md")
401 (include "arm1026ejs.md")
402 (include "arm1136jfs.md")
404 (include "fa606te.md")
405 (include "fa626te.md")
406 (include "fmp626.md")
407 (include "fa726te.md")
408 (include "cortex-a5.md")
409 (include "cortex-a7.md")
410 (include "cortex-a8.md")
411 (include "cortex-a9.md")
412 (include "cortex-a15.md")
413 (include "cortex-a17.md")
414 (include "cortex-a53.md")
415 (include "cortex-a57.md")
416 (include "cortex-r4.md")
417 (include "cortex-r4f.md")
418 (include "cortex-m7.md")
419 (include "cortex-m4.md")
420 (include "cortex-m4-fpu.md")
421 (include "exynos-m1.md")
423 (include "marvell-pj4.md")
424 (include "xgene1.md")
427 ;;---------------------------------------------------------------------------
432 ;; Note: For DImode insns, there is normally no reason why operands should
433 ;; not be in the same register, what we don't want is for something being
434 ;; written to partially overlap something that is an input.
436 (define_expand "adddi3"
438 [(set (match_operand:DI 0 "s_register_operand")
439 (plus:DI (match_operand:DI 1 "s_register_operand")
440 (match_operand:DI 2 "arm_adddi_operand")))
441 (clobber (reg:CC CC_REGNUM))])]
444 if (TARGET_THUMB1 && !REG_P (operands[2]))
445 operands[2] = force_reg (DImode, operands[2]);
449 (define_insn_and_split "*arm_adddi3"
450 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r,&r,&r")
451 (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r")
452 (match_operand:DI 2 "arm_general_adddi_operand" "r, 0, r, Dd, Dd")))
453 (clobber (reg:CC CC_REGNUM))]
457 [(parallel [(set (reg:CC_C CC_REGNUM)
458 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
460 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
461 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
462 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
465 operands[3] = gen_highpart (SImode, operands[0]);
466 operands[0] = gen_lowpart (SImode, operands[0]);
467 operands[4] = gen_highpart (SImode, operands[1]);
468 operands[1] = gen_lowpart (SImode, operands[1]);
469 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
470 operands[2] = gen_lowpart (SImode, operands[2]);
472 [(set_attr "conds" "clob")
473 (set_attr "length" "8")
474 (set_attr "type" "multiple")]
477 (define_insn_and_split "*adddi_sesidi_di"
478 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
479 (plus:DI (sign_extend:DI
480 (match_operand:SI 2 "s_register_operand" "r,r"))
481 (match_operand:DI 1 "s_register_operand" "0,r")))
482 (clobber (reg:CC CC_REGNUM))]
485 "TARGET_32BIT && reload_completed"
486 [(parallel [(set (reg:CC_C CC_REGNUM)
487 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
489 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
490 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
493 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
496 operands[3] = gen_highpart (SImode, operands[0]);
497 operands[0] = gen_lowpart (SImode, operands[0]);
498 operands[4] = gen_highpart (SImode, operands[1]);
499 operands[1] = gen_lowpart (SImode, operands[1]);
500 operands[2] = gen_lowpart (SImode, operands[2]);
502 [(set_attr "conds" "clob")
503 (set_attr "length" "8")
504 (set_attr "type" "multiple")]
507 (define_insn_and_split "*adddi_zesidi_di"
508 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
509 (plus:DI (zero_extend:DI
510 (match_operand:SI 2 "s_register_operand" "r,r"))
511 (match_operand:DI 1 "s_register_operand" "0,r")))
512 (clobber (reg:CC CC_REGNUM))]
515 "TARGET_32BIT && reload_completed"
516 [(parallel [(set (reg:CC_C CC_REGNUM)
517 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
519 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
520 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
521 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
524 operands[3] = gen_highpart (SImode, operands[0]);
525 operands[0] = gen_lowpart (SImode, operands[0]);
526 operands[4] = gen_highpart (SImode, operands[1]);
527 operands[1] = gen_lowpart (SImode, operands[1]);
528 operands[2] = gen_lowpart (SImode, operands[2]);
530 [(set_attr "conds" "clob")
531 (set_attr "length" "8")
532 (set_attr "type" "multiple")]
535 (define_expand "addv<mode>4"
536 [(match_operand:SIDI 0 "register_operand")
537 (match_operand:SIDI 1 "register_operand")
538 (match_operand:SIDI 2 "register_operand")
539 (match_operand 3 "")]
542 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
543 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
548 (define_expand "uaddv<mode>4"
549 [(match_operand:SIDI 0 "register_operand")
550 (match_operand:SIDI 1 "register_operand")
551 (match_operand:SIDI 2 "register_operand")
552 (match_operand 3 "")]
555 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
556 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
561 (define_expand "addsi3"
562 [(set (match_operand:SI 0 "s_register_operand")
563 (plus:SI (match_operand:SI 1 "s_register_operand")
564 (match_operand:SI 2 "reg_or_int_operand")))]
567 if (TARGET_32BIT && CONST_INT_P (operands[2]))
569 arm_split_constant (PLUS, SImode, NULL_RTX,
570 INTVAL (operands[2]), operands[0], operands[1],
571 optimize && can_create_pseudo_p ());
577 ; If there is a scratch available, this will be faster than synthesizing the
580 [(match_scratch:SI 3 "r")
581 (set (match_operand:SI 0 "arm_general_register_operand" "")
582 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
583 (match_operand:SI 2 "const_int_operand" "")))]
585 !(const_ok_for_arm (INTVAL (operands[2]))
586 || const_ok_for_arm (-INTVAL (operands[2])))
587 && const_ok_for_arm (~INTVAL (operands[2]))"
588 [(set (match_dup 3) (match_dup 2))
589 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
593 ;; The r/r/k alternative is required when reloading the address
594 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
595 ;; put the duplicated register first, and not try the commutative version.
596 (define_insn_and_split "*arm_addsi3"
597 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
598 (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")
599 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
615 subw%?\\t%0, %1, #%n2
616 subw%?\\t%0, %1, #%n2
619 && CONST_INT_P (operands[2])
620 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
621 && (reload_completed || !arm_eliminable_register (operands[1]))"
622 [(clobber (const_int 0))]
624 arm_split_constant (PLUS, SImode, curr_insn,
625 INTVAL (operands[2]), operands[0],
629 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
630 (set_attr "predicable" "yes")
631 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
632 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
633 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
634 (const_string "alu_imm")
635 (const_string "alu_sreg")))
639 (define_insn_and_split "adddi3_compareV"
640 [(set (reg:CC_V CC_REGNUM)
643 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
644 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
645 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
646 (set (match_operand:DI 0 "register_operand" "=&r")
647 (plus:DI (match_dup 1) (match_dup 2)))]
650 "&& reload_completed"
651 [(parallel [(set (reg:CC_C CC_REGNUM)
652 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
654 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
655 (parallel [(set (reg:CC_V CC_REGNUM)
658 (sign_extend:DI (match_dup 4))
659 (sign_extend:DI (match_dup 5)))
660 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
661 (plus:DI (sign_extend:DI
662 (plus:SI (match_dup 4) (match_dup 5)))
663 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
664 (set (match_dup 3) (plus:SI (plus:SI
665 (match_dup 4) (match_dup 5))
666 (ltu:SI (reg:CC_C CC_REGNUM)
670 operands[3] = gen_highpart (SImode, operands[0]);
671 operands[0] = gen_lowpart (SImode, operands[0]);
672 operands[4] = gen_highpart (SImode, operands[1]);
673 operands[1] = gen_lowpart (SImode, operands[1]);
674 operands[5] = gen_highpart (SImode, operands[2]);
675 operands[2] = gen_lowpart (SImode, operands[2]);
677 [(set_attr "conds" "set")
678 (set_attr "length" "8")
679 (set_attr "type" "multiple")]
682 (define_insn "addsi3_compareV"
683 [(set (reg:CC_V CC_REGNUM)
686 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
687 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
688 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
689 (set (match_operand:SI 0 "register_operand" "=r")
690 (plus:SI (match_dup 1) (match_dup 2)))]
692 "adds%?\\t%0, %1, %2"
693 [(set_attr "conds" "set")
694 (set_attr "type" "alus_sreg")]
697 (define_insn "*addsi3_compareV_upper"
698 [(set (reg:CC_V CC_REGNUM)
702 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
703 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
704 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
705 (plus:DI (sign_extend:DI
706 (plus:SI (match_dup 1) (match_dup 2)))
707 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
708 (set (match_operand:SI 0 "register_operand" "=r")
710 (plus:SI (match_dup 1) (match_dup 2))
711 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
713 "adcs%?\\t%0, %1, %2"
714 [(set_attr "conds" "set")
715 (set_attr "type" "adcs_reg")]
718 (define_insn_and_split "adddi3_compareC"
719 [(set (reg:CC_C CC_REGNUM)
722 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
723 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
724 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
725 (set (match_operand:DI 0 "register_operand" "=&r")
726 (plus:DI (match_dup 1) (match_dup 2)))]
729 "&& reload_completed"
730 [(parallel [(set (reg:CC_C CC_REGNUM)
731 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
733 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
734 (parallel [(set (reg:CC_C CC_REGNUM)
737 (zero_extend:DI (match_dup 4))
738 (zero_extend:DI (match_dup 5)))
739 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
740 (plus:DI (zero_extend:DI
741 (plus:SI (match_dup 4) (match_dup 5)))
742 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
743 (set (match_dup 3) (plus:SI
744 (plus:SI (match_dup 4) (match_dup 5))
745 (ltu:SI (reg:CC_C CC_REGNUM)
749 operands[3] = gen_highpart (SImode, operands[0]);
750 operands[0] = gen_lowpart (SImode, operands[0]);
751 operands[4] = gen_highpart (SImode, operands[1]);
752 operands[5] = gen_highpart (SImode, operands[2]);
753 operands[1] = gen_lowpart (SImode, operands[1]);
754 operands[2] = gen_lowpart (SImode, operands[2]);
756 [(set_attr "conds" "set")
757 (set_attr "length" "8")
758 (set_attr "type" "multiple")]
761 (define_insn "*addsi3_compareC_upper"
762 [(set (reg:CC_C CC_REGNUM)
766 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
767 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
768 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
769 (plus:DI (zero_extend:DI
770 (plus:SI (match_dup 1) (match_dup 2)))
771 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
772 (set (match_operand:SI 0 "register_operand" "=r")
774 (plus:SI (match_dup 1) (match_dup 2))
775 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
777 "adcs%?\\t%0, %1, %2"
778 [(set_attr "conds" "set")
779 (set_attr "type" "adcs_reg")]
782 (define_insn "addsi3_compareC"
783 [(set (reg:CC_C CC_REGNUM)
786 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
787 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
789 (plus:SI (match_dup 1) (match_dup 2)))))
790 (set (match_operand:SI 0 "register_operand" "=r")
791 (plus:SI (match_dup 1) (match_dup 2)))]
793 "adds%?\\t%0, %1, %2"
794 [(set_attr "conds" "set")
795 (set_attr "type" "alus_sreg")]
798 (define_insn "addsi3_compare0"
799 [(set (reg:CC_NOOV CC_REGNUM)
801 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
802 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
804 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
805 (plus:SI (match_dup 1) (match_dup 2)))]
809 subs%?\\t%0, %1, #%n2
811 [(set_attr "conds" "set")
812 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
815 (define_insn "*addsi3_compare0_scratch"
816 [(set (reg:CC_NOOV CC_REGNUM)
818 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
819 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
826 [(set_attr "conds" "set")
827 (set_attr "predicable" "yes")
828 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
831 (define_insn "*compare_negsi_si"
832 [(set (reg:CC_Z CC_REGNUM)
834 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
835 (match_operand:SI 1 "s_register_operand" "l,r")))]
838 [(set_attr "conds" "set")
839 (set_attr "predicable" "yes")
840 (set_attr "arch" "t2,*")
841 (set_attr "length" "2,4")
842 (set_attr "predicable_short_it" "yes,no")
843 (set_attr "type" "alus_sreg")]
846 ;; This is the canonicalization of subsi3_compare when the
847 ;; addend is a constant.
848 (define_insn "cmpsi2_addneg"
849 [(set (reg:CC CC_REGNUM)
851 (match_operand:SI 1 "s_register_operand" "r,r")
852 (match_operand:SI 2 "arm_addimm_operand" "I,L")))
853 (set (match_operand:SI 0 "s_register_operand" "=r,r")
854 (plus:SI (match_dup 1)
855 (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
857 && (INTVAL (operands[2])
858 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
860 /* For 0 and INT_MIN it is essential that we use subs, as adds will result
861 in different condition codes (like cmn rather than like cmp), so that
862 alternative comes first. Both alternatives can match for any 0x??000000
863 where except for 0 and INT_MIN it doesn't matter what we choose, and also
864 for -1 and 1 with TARGET_THUMB2, in that case prefer instruction with #1
866 if (which_alternative == 0 && operands[3] != const1_rtx)
867 return "subs%?\\t%0, %1, #%n3";
869 return "adds%?\\t%0, %1, %3";
871 [(set_attr "conds" "set")
872 (set_attr "type" "alus_sreg")]
875 ;; Convert the sequence
877 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
881 ;; bcs dest ((unsigned)rn >= 1)
882 ;; similarly for the beq variant using bcc.
883 ;; This is a common looping idiom (while (n--))
885 [(set (match_operand:SI 0 "arm_general_register_operand" "")
886 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
888 (set (match_operand 2 "cc_register" "")
889 (compare (match_dup 0) (const_int -1)))
891 (if_then_else (match_operator 3 "equality_operator"
892 [(match_dup 2) (const_int 0)])
893 (match_operand 4 "" "")
894 (match_operand 5 "" "")))]
895 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
899 (match_dup 1) (const_int 1)))
900 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
902 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
905 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
906 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
909 operands[2], const0_rtx);"
912 ;; The next four insns work because they compare the result with one of
913 ;; the operands, and we know that the use of the condition code is
914 ;; either GEU or LTU, so we can use the carry flag from the addition
915 ;; instead of doing the compare a second time.
916 (define_insn "*addsi3_compare_op1"
917 [(set (reg:CC_C CC_REGNUM)
919 (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r,r")
920 (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,I,L,r"))
922 (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r,r")
923 (plus:SI (match_dup 1) (match_dup 2)))]
928 subs%?\\t%0, %1, #%n2
929 subs%?\\t%0, %0, #%n2
931 subs%?\\t%0, %1, #%n2
933 [(set_attr "conds" "set")
934 (set_attr "arch" "t2,t2,t2,t2,*,*,*")
935 (set_attr "length" "2,2,2,2,4,4,4")
937 "alus_sreg,alus_imm,alus_sreg,alus_imm,alus_imm,alus_imm,alus_sreg")]
940 (define_insn "*addsi3_compare_op2"
941 [(set (reg:CC_C CC_REGNUM)
943 (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r,r")
944 (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,I,L,r"))
946 (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r,r")
947 (plus:SI (match_dup 1) (match_dup 2)))]
952 subs%?\\t%0, %1, #%n2
953 subs%?\\t%0, %0, #%n2
955 subs%?\\t%0, %1, #%n2
957 [(set_attr "conds" "set")
958 (set_attr "arch" "t2,t2,t2,t2,*,*,*")
959 (set_attr "length" "2,2,2,2,4,4,4")
961 "alus_sreg,alus_imm,alus_sreg,alus_imm,alus_imm,alus_imm,alus_sreg")]
964 (define_insn "*compare_addsi2_op0"
965 [(set (reg:CC_C CC_REGNUM)
967 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
968 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
977 [(set_attr "conds" "set")
978 (set_attr "predicable" "yes")
979 (set_attr "arch" "t2,t2,*,*,*")
980 (set_attr "predicable_short_it" "yes,yes,no,no,no")
981 (set_attr "length" "2,2,4,4,4")
982 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
985 (define_insn "*compare_addsi2_op1"
986 [(set (reg:CC_C CC_REGNUM)
988 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
989 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
998 [(set_attr "conds" "set")
999 (set_attr "predicable" "yes")
1000 (set_attr "arch" "t2,t2,*,*,*")
1001 (set_attr "predicable_short_it" "yes,yes,no,no,no")
1002 (set_attr "length" "2,2,4,4,4")
1003 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
1006 (define_insn "*addsi3_carryin_<optab>"
1007 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1008 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
1009 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
1010 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1015 sbc%?\\t%0, %1, #%B2"
1016 [(set_attr "conds" "use")
1017 (set_attr "predicable" "yes")
1018 (set_attr "arch" "t2,*,*")
1019 (set_attr "length" "4")
1020 (set_attr "predicable_short_it" "yes,no,no")
1021 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1024 (define_insn "*addsi3_carryin_alt2_<optab>"
1025 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1026 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1027 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1028 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1033 sbc%?\\t%0, %1, #%B2"
1034 [(set_attr "conds" "use")
1035 (set_attr "predicable" "yes")
1036 (set_attr "arch" "t2,*,*")
1037 (set_attr "length" "4")
1038 (set_attr "predicable_short_it" "yes,no,no")
1039 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1042 (define_insn "*addsi3_carryin_shift_<optab>"
1043 [(set (match_operand:SI 0 "s_register_operand" "=r")
1045 (match_operator:SI 2 "shift_operator"
1046 [(match_operand:SI 3 "s_register_operand" "r")
1047 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1048 (match_operand:SI 1 "s_register_operand" "r"))
1049 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1051 "adc%?\\t%0, %1, %3%S2"
1052 [(set_attr "conds" "use")
1053 (set_attr "predicable" "yes")
1054 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1055 (const_string "alu_shift_imm")
1056 (const_string "alu_shift_reg")))]
1059 (define_insn "*addsi3_carryin_clobercc_<optab>"
1060 [(set (match_operand:SI 0 "s_register_operand" "=r")
1061 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1062 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1063 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1064 (clobber (reg:CC CC_REGNUM))]
1066 "adcs%?\\t%0, %1, %2"
1067 [(set_attr "conds" "set")
1068 (set_attr "type" "adcs_reg")]
1071 (define_expand "subv<mode>4"
1072 [(match_operand:SIDI 0 "register_operand")
1073 (match_operand:SIDI 1 "register_operand")
1074 (match_operand:SIDI 2 "register_operand")
1075 (match_operand 3 "")]
1078 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1079 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1084 (define_expand "usubv<mode>4"
1085 [(match_operand:SIDI 0 "register_operand")
1086 (match_operand:SIDI 1 "register_operand")
1087 (match_operand:SIDI 2 "register_operand")
1088 (match_operand 3 "")]
1091 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1092 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1097 (define_insn_and_split "subdi3_compare1"
1098 [(set (reg:CC CC_REGNUM)
1100 (match_operand:DI 1 "register_operand" "r")
1101 (match_operand:DI 2 "register_operand" "r")))
1102 (set (match_operand:DI 0 "register_operand" "=&r")
1103 (minus:DI (match_dup 1) (match_dup 2)))]
1106 "&& reload_completed"
1107 [(parallel [(set (reg:CC CC_REGNUM)
1108 (compare:CC (match_dup 1) (match_dup 2)))
1109 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1110 (parallel [(set (reg:CC CC_REGNUM)
1111 (compare:CC (match_dup 4) (match_dup 5)))
1112 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1113 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))])]
1115 operands[3] = gen_highpart (SImode, operands[0]);
1116 operands[0] = gen_lowpart (SImode, operands[0]);
1117 operands[4] = gen_highpart (SImode, operands[1]);
1118 operands[1] = gen_lowpart (SImode, operands[1]);
1119 operands[5] = gen_highpart (SImode, operands[2]);
1120 operands[2] = gen_lowpart (SImode, operands[2]);
1122 [(set_attr "conds" "set")
1123 (set_attr "length" "8")
1124 (set_attr "type" "multiple")]
1127 (define_insn "subsi3_compare1"
1128 [(set (reg:CC CC_REGNUM)
1130 (match_operand:SI 1 "register_operand" "r")
1131 (match_operand:SI 2 "register_operand" "r")))
1132 (set (match_operand:SI 0 "register_operand" "=r")
1133 (minus:SI (match_dup 1) (match_dup 2)))]
1135 "subs%?\\t%0, %1, %2"
1136 [(set_attr "conds" "set")
1137 (set_attr "type" "alus_sreg")]
1140 (define_insn "*subsi3_carryin"
1141 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1142 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1143 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1144 (match_operand:SI 3 "arm_borrow_operation" "")))]
1149 sbc%?\\t%0, %2, %2, lsl #1"
1150 [(set_attr "conds" "use")
1151 (set_attr "arch" "*,a,t2")
1152 (set_attr "predicable" "yes")
1153 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1156 (define_insn "*subsi3_carryin_const"
1157 [(set (match_operand:SI 0 "s_register_operand" "=r")
1159 (match_operand:SI 1 "s_register_operand" "r")
1160 (match_operand:SI 2 "arm_neg_immediate_operand" "L"))
1161 (match_operand:SI 3 "arm_borrow_operation" "")))]
1163 "sbc\\t%0, %1, #%n2"
1164 [(set_attr "conds" "use")
1165 (set_attr "type" "adc_imm")]
1168 (define_insn "*subsi3_carryin_const0"
1169 [(set (match_operand:SI 0 "s_register_operand" "=r")
1170 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
1171 (match_operand:SI 2 "arm_borrow_operation" "")))]
1174 [(set_attr "conds" "use")
1175 (set_attr "type" "adc_imm")]
1178 (define_insn "*subsi3_carryin_compare"
1179 [(set (reg:CC CC_REGNUM)
1180 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1181 (match_operand:SI 2 "s_register_operand" "r")))
1182 (set (match_operand:SI 0 "s_register_operand" "=r")
1183 (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1184 (match_operand:SI 3 "arm_borrow_operation" "")))]
1187 [(set_attr "conds" "set")
1188 (set_attr "type" "adcs_reg")]
1191 (define_insn "*subsi3_carryin_compare_const"
1192 [(set (reg:CC CC_REGNUM)
1193 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1194 (match_operand:SI 2 "const_int_I_operand" "I")))
1195 (set (match_operand:SI 0 "s_register_operand" "=r")
1198 (match_operand:SI 3 "arm_neg_immediate_operand" "L"))
1199 (match_operand:SI 4 "arm_borrow_operation" "")))]
1201 && (INTVAL (operands[2])
1202 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
1203 "sbcs\\t%0, %1, #%n3"
1204 [(set_attr "conds" "set")
1205 (set_attr "type" "adcs_imm")]
1208 (define_insn "*subsi3_carryin_compare_const0"
1209 [(set (reg:CC CC_REGNUM)
1210 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1212 (set (match_operand:SI 0 "s_register_operand" "=r")
1213 (minus:SI (match_dup 1)
1214 (match_operand:SI 2 "arm_borrow_operation" "")))]
1217 [(set_attr "conds" "set")
1218 (set_attr "type" "adcs_imm")]
1221 (define_insn "*subsi3_carryin_shift"
1222 [(set (match_operand:SI 0 "s_register_operand" "=r")
1224 (match_operand:SI 1 "s_register_operand" "r")
1225 (match_operator:SI 2 "shift_operator"
1226 [(match_operand:SI 3 "s_register_operand" "r")
1227 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1228 (match_operand:SI 5 "arm_borrow_operation" "")))]
1230 "sbc%?\\t%0, %1, %3%S2"
1231 [(set_attr "conds" "use")
1232 (set_attr "predicable" "yes")
1233 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1234 (const_string "alu_shift_imm")
1235 (const_string "alu_shift_reg")))]
1238 (define_insn "*rsbsi3_carryin_shift"
1239 [(set (match_operand:SI 0 "s_register_operand" "=r")
1241 (match_operator:SI 2 "shift_operator"
1242 [(match_operand:SI 3 "s_register_operand" "r")
1243 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1244 (match_operand:SI 1 "s_register_operand" "r"))
1245 (match_operand:SI 5 "arm_borrow_operation" "")))]
1247 "rsc%?\\t%0, %1, %3%S2"
1248 [(set_attr "conds" "use")
1249 (set_attr "predicable" "yes")
1250 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1251 (const_string "alu_shift_imm")
1252 (const_string "alu_shift_reg")))]
1255 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1257 [(set (match_operand:SI 0 "s_register_operand" "")
1258 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1259 (match_operand:SI 2 "s_register_operand" ""))
1261 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1263 [(set (match_dup 3) (match_dup 1))
1264 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1266 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1269 (define_expand "addsf3"
1270 [(set (match_operand:SF 0 "s_register_operand")
1271 (plus:SF (match_operand:SF 1 "s_register_operand")
1272 (match_operand:SF 2 "s_register_operand")))]
1273 "TARGET_32BIT && TARGET_HARD_FLOAT"
1277 (define_expand "adddf3"
1278 [(set (match_operand:DF 0 "s_register_operand")
1279 (plus:DF (match_operand:DF 1 "s_register_operand")
1280 (match_operand:DF 2 "s_register_operand")))]
1281 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1285 (define_expand "subdi3"
1287 [(set (match_operand:DI 0 "s_register_operand")
1288 (minus:DI (match_operand:DI 1 "s_register_operand")
1289 (match_operand:DI 2 "s_register_operand")))
1290 (clobber (reg:CC CC_REGNUM))])]
1295 (define_insn_and_split "*arm_subdi3"
1296 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
1297 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1298 (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1299 (clobber (reg:CC CC_REGNUM))]
1301 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1303 [(parallel [(set (reg:CC CC_REGNUM)
1304 (compare:CC (match_dup 1) (match_dup 2)))
1305 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1306 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1307 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1309 operands[3] = gen_highpart (SImode, operands[0]);
1310 operands[0] = gen_lowpart (SImode, operands[0]);
1311 operands[4] = gen_highpart (SImode, operands[1]);
1312 operands[1] = gen_lowpart (SImode, operands[1]);
1313 operands[5] = gen_highpart (SImode, operands[2]);
1314 operands[2] = gen_lowpart (SImode, operands[2]);
1316 [(set_attr "conds" "clob")
1317 (set_attr "length" "8")
1318 (set_attr "type" "multiple")]
1321 (define_insn_and_split "*subdi_di_zesidi"
1322 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1323 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1325 (match_operand:SI 2 "s_register_operand" "r,r"))))
1326 (clobber (reg:CC CC_REGNUM))]
1328 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1329 "&& reload_completed"
1330 [(parallel [(set (reg:CC CC_REGNUM)
1331 (compare:CC (match_dup 1) (match_dup 2)))
1332 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1333 (set (match_dup 3) (minus:SI (match_dup 4)
1334 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1336 operands[3] = gen_highpart (SImode, operands[0]);
1337 operands[0] = gen_lowpart (SImode, operands[0]);
1338 operands[4] = gen_highpart (SImode, operands[1]);
1339 operands[1] = gen_lowpart (SImode, operands[1]);
1341 [(set_attr "conds" "clob")
1342 (set_attr "length" "8")
1343 (set_attr "type" "multiple")]
1346 (define_insn_and_split "*subdi_di_sesidi"
1347 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1348 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1350 (match_operand:SI 2 "s_register_operand" "r,r"))))
1351 (clobber (reg:CC CC_REGNUM))]
1353 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1354 "&& reload_completed"
1355 [(parallel [(set (reg:CC CC_REGNUM)
1356 (compare:CC (match_dup 1) (match_dup 2)))
1357 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1358 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1359 (ashiftrt:SI (match_dup 2)
1361 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1363 operands[3] = gen_highpart (SImode, operands[0]);
1364 operands[0] = gen_lowpart (SImode, operands[0]);
1365 operands[4] = gen_highpart (SImode, operands[1]);
1366 operands[1] = gen_lowpart (SImode, operands[1]);
1368 [(set_attr "conds" "clob")
1369 (set_attr "length" "8")
1370 (set_attr "type" "multiple")]
1373 (define_insn_and_split "*subdi_zesidi_di"
1374 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1375 (minus:DI (zero_extend:DI
1376 (match_operand:SI 2 "s_register_operand" "r,r"))
1377 (match_operand:DI 1 "s_register_operand" "0,r")))
1378 (clobber (reg:CC CC_REGNUM))]
1380 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1382 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1383 "&& reload_completed"
1384 [(parallel [(set (reg:CC CC_REGNUM)
1385 (compare:CC (match_dup 2) (match_dup 1)))
1386 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1387 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1388 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1390 operands[3] = gen_highpart (SImode, operands[0]);
1391 operands[0] = gen_lowpart (SImode, operands[0]);
1392 operands[4] = gen_highpart (SImode, operands[1]);
1393 operands[1] = gen_lowpart (SImode, operands[1]);
1395 [(set_attr "conds" "clob")
1396 (set_attr "length" "8")
1397 (set_attr "type" "multiple")]
1400 (define_insn_and_split "*subdi_sesidi_di"
1401 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1402 (minus:DI (sign_extend:DI
1403 (match_operand:SI 2 "s_register_operand" "r,r"))
1404 (match_operand:DI 1 "s_register_operand" "0,r")))
1405 (clobber (reg:CC CC_REGNUM))]
1407 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1409 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1410 "&& reload_completed"
1411 [(parallel [(set (reg:CC CC_REGNUM)
1412 (compare:CC (match_dup 2) (match_dup 1)))
1413 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1414 (set (match_dup 3) (minus:SI (minus:SI
1415 (ashiftrt:SI (match_dup 2)
1418 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1420 operands[3] = gen_highpart (SImode, operands[0]);
1421 operands[0] = gen_lowpart (SImode, operands[0]);
1422 operands[4] = gen_highpart (SImode, operands[1]);
1423 operands[1] = gen_lowpart (SImode, operands[1]);
1425 [(set_attr "conds" "clob")
1426 (set_attr "length" "8")
1427 (set_attr "type" "multiple")]
1430 (define_insn_and_split "*subdi_zesidi_zesidi"
1431 [(set (match_operand:DI 0 "s_register_operand" "=r")
1432 (minus:DI (zero_extend:DI
1433 (match_operand:SI 1 "s_register_operand" "r"))
1435 (match_operand:SI 2 "s_register_operand" "r"))))
1436 (clobber (reg:CC CC_REGNUM))]
1438 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1439 "&& reload_completed"
1440 [(parallel [(set (reg:CC CC_REGNUM)
1441 (compare:CC (match_dup 1) (match_dup 2)))
1442 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1443 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1444 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1446 operands[3] = gen_highpart (SImode, operands[0]);
1447 operands[0] = gen_lowpart (SImode, operands[0]);
1449 [(set_attr "conds" "clob")
1450 (set_attr "length" "8")
1451 (set_attr "type" "multiple")]
1454 (define_expand "subsi3"
1455 [(set (match_operand:SI 0 "s_register_operand")
1456 (minus:SI (match_operand:SI 1 "reg_or_int_operand")
1457 (match_operand:SI 2 "s_register_operand")))]
1460 if (CONST_INT_P (operands[1]))
1464 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1465 operands[1] = force_reg (SImode, operands[1]);
1468 arm_split_constant (MINUS, SImode, NULL_RTX,
1469 INTVAL (operands[1]), operands[0],
1471 optimize && can_create_pseudo_p ());
1475 else /* TARGET_THUMB1 */
1476 operands[1] = force_reg (SImode, operands[1]);
1481 ; ??? Check Thumb-2 split length
1482 (define_insn_and_split "*arm_subsi3_insn"
1483 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1484 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1485 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1497 "&& (CONST_INT_P (operands[1])
1498 && !const_ok_for_arm (INTVAL (operands[1])))"
1499 [(clobber (const_int 0))]
1501 arm_split_constant (MINUS, SImode, curr_insn,
1502 INTVAL (operands[1]), operands[0], operands[2], 0);
1505 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1506 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1507 (set_attr "predicable" "yes")
1508 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1509 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1513 [(match_scratch:SI 3 "r")
1514 (set (match_operand:SI 0 "arm_general_register_operand" "")
1515 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1516 (match_operand:SI 2 "arm_general_register_operand" "")))]
1518 && !const_ok_for_arm (INTVAL (operands[1]))
1519 && const_ok_for_arm (~INTVAL (operands[1]))"
1520 [(set (match_dup 3) (match_dup 1))
1521 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1525 (define_insn "subsi3_compare0"
1526 [(set (reg:CC_NOOV CC_REGNUM)
1528 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1529 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1531 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1532 (minus:SI (match_dup 1) (match_dup 2)))]
1537 rsbs%?\\t%0, %2, %1"
1538 [(set_attr "conds" "set")
1539 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1542 (define_insn "subsi3_compare"
1543 [(set (reg:CC CC_REGNUM)
1544 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1545 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1546 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1547 (minus:SI (match_dup 1) (match_dup 2)))]
1552 rsbs%?\\t%0, %2, %1"
1553 [(set_attr "conds" "set")
1554 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1557 (define_expand "subsf3"
1558 [(set (match_operand:SF 0 "s_register_operand")
1559 (minus:SF (match_operand:SF 1 "s_register_operand")
1560 (match_operand:SF 2 "s_register_operand")))]
1561 "TARGET_32BIT && TARGET_HARD_FLOAT"
1565 (define_expand "subdf3"
1566 [(set (match_operand:DF 0 "s_register_operand")
1567 (minus:DF (match_operand:DF 1 "s_register_operand")
1568 (match_operand:DF 2 "s_register_operand")))]
1569 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1574 ;; Multiplication insns
1576 (define_expand "mulhi3"
1577 [(set (match_operand:HI 0 "s_register_operand")
1578 (mult:HI (match_operand:HI 1 "s_register_operand")
1579 (match_operand:HI 2 "s_register_operand")))]
1580 "TARGET_DSP_MULTIPLY"
1583 rtx result = gen_reg_rtx (SImode);
1584 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1585 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1590 (define_expand "mulsi3"
1591 [(set (match_operand:SI 0 "s_register_operand")
1592 (mult:SI (match_operand:SI 2 "s_register_operand")
1593 (match_operand:SI 1 "s_register_operand")))]
1598 ;; Use `&' and then `0' to prevent operands 0 and 2 being the same
1600 [(set (match_operand:SI 0 "s_register_operand" "=l,r,&r,&r")
1601 (mult:SI (match_operand:SI 2 "s_register_operand" "l,r,r,r")
1602 (match_operand:SI 1 "s_register_operand" "%0,r,0,r")))]
1604 "mul%?\\t%0, %2, %1"
1605 [(set_attr "type" "mul")
1606 (set_attr "predicable" "yes")
1607 (set_attr "arch" "t2,v6,nov6,nov6")
1608 (set_attr "length" "4")
1609 (set_attr "predicable_short_it" "yes,no,*,*")]
1612 ;; MLA and MLS instruction. Use operand 1 for the accumulator to prefer
1613 ;; reusing the same register.
1616 [(set (match_operand:SI 0 "s_register_operand" "=r,&r,&r,&r")
1618 (mult:SI (match_operand:SI 3 "s_register_operand" "r,r,r,r")
1619 (match_operand:SI 2 "s_register_operand" "%r,r,0,r"))
1620 (match_operand:SI 1 "s_register_operand" "r,0,r,r")))]
1622 "mla%?\\t%0, %3, %2, %1"
1623 [(set_attr "type" "mla")
1624 (set_attr "predicable" "yes")
1625 (set_attr "arch" "v6,nov6,nov6,nov6")]
1629 [(set (match_operand:SI 0 "s_register_operand" "=r")
1631 (match_operand:SI 1 "s_register_operand" "r")
1632 (mult:SI (match_operand:SI 3 "s_register_operand" "r")
1633 (match_operand:SI 2 "s_register_operand" "r"))))]
1634 "TARGET_32BIT && arm_arch_thumb2"
1635 "mls%?\\t%0, %3, %2, %1"
1636 [(set_attr "type" "mla")
1637 (set_attr "predicable" "yes")]
1640 (define_insn "*mulsi3_compare0"
1641 [(set (reg:CC_NOOV CC_REGNUM)
1642 (compare:CC_NOOV (mult:SI
1643 (match_operand:SI 2 "s_register_operand" "r,r")
1644 (match_operand:SI 1 "s_register_operand" "%0,r"))
1646 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1647 (mult:SI (match_dup 2) (match_dup 1)))]
1648 "TARGET_ARM && !arm_arch6"
1649 "muls%?\\t%0, %2, %1"
1650 [(set_attr "conds" "set")
1651 (set_attr "type" "muls")]
1654 (define_insn "*mulsi3_compare0_v6"
1655 [(set (reg:CC_NOOV CC_REGNUM)
1656 (compare:CC_NOOV (mult:SI
1657 (match_operand:SI 2 "s_register_operand" "r")
1658 (match_operand:SI 1 "s_register_operand" "r"))
1660 (set (match_operand:SI 0 "s_register_operand" "=r")
1661 (mult:SI (match_dup 2) (match_dup 1)))]
1662 "TARGET_ARM && arm_arch6 && optimize_size"
1663 "muls%?\\t%0, %2, %1"
1664 [(set_attr "conds" "set")
1665 (set_attr "type" "muls")]
1668 (define_insn "*mulsi_compare0_scratch"
1669 [(set (reg:CC_NOOV CC_REGNUM)
1670 (compare:CC_NOOV (mult:SI
1671 (match_operand:SI 2 "s_register_operand" "r,r")
1672 (match_operand:SI 1 "s_register_operand" "%0,r"))
1674 (clobber (match_scratch:SI 0 "=&r,&r"))]
1675 "TARGET_ARM && !arm_arch6"
1676 "muls%?\\t%0, %2, %1"
1677 [(set_attr "conds" "set")
1678 (set_attr "type" "muls")]
1681 (define_insn "*mulsi_compare0_scratch_v6"
1682 [(set (reg:CC_NOOV CC_REGNUM)
1683 (compare:CC_NOOV (mult:SI
1684 (match_operand:SI 2 "s_register_operand" "r")
1685 (match_operand:SI 1 "s_register_operand" "r"))
1687 (clobber (match_scratch:SI 0 "=r"))]
1688 "TARGET_ARM && arm_arch6 && optimize_size"
1689 "muls%?\\t%0, %2, %1"
1690 [(set_attr "conds" "set")
1691 (set_attr "type" "muls")]
1694 (define_insn "*mulsi3addsi_compare0"
1695 [(set (reg:CC_NOOV CC_REGNUM)
1698 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1699 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1700 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1702 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1703 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1705 "TARGET_ARM && arm_arch6"
1706 "mlas%?\\t%0, %2, %1, %3"
1707 [(set_attr "conds" "set")
1708 (set_attr "type" "mlas")]
1711 (define_insn "*mulsi3addsi_compare0_v6"
1712 [(set (reg:CC_NOOV CC_REGNUM)
1715 (match_operand:SI 2 "s_register_operand" "r")
1716 (match_operand:SI 1 "s_register_operand" "r"))
1717 (match_operand:SI 3 "s_register_operand" "r"))
1719 (set (match_operand:SI 0 "s_register_operand" "=r")
1720 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1722 "TARGET_ARM && arm_arch6 && optimize_size"
1723 "mlas%?\\t%0, %2, %1, %3"
1724 [(set_attr "conds" "set")
1725 (set_attr "type" "mlas")]
1728 (define_insn "*mulsi3addsi_compare0_scratch"
1729 [(set (reg:CC_NOOV CC_REGNUM)
1732 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1733 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1734 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1736 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1737 "TARGET_ARM && !arm_arch6"
1738 "mlas%?\\t%0, %2, %1, %3"
1739 [(set_attr "conds" "set")
1740 (set_attr "type" "mlas")]
1743 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1744 [(set (reg:CC_NOOV CC_REGNUM)
1747 (match_operand:SI 2 "s_register_operand" "r")
1748 (match_operand:SI 1 "s_register_operand" "r"))
1749 (match_operand:SI 3 "s_register_operand" "r"))
1751 (clobber (match_scratch:SI 0 "=r"))]
1752 "TARGET_ARM && arm_arch6 && optimize_size"
1753 "mlas%?\\t%0, %2, %1, %3"
1754 [(set_attr "conds" "set")
1755 (set_attr "type" "mlas")]
1758 ;; 32x32->64 widening multiply.
1759 ;; The only difference between the v3-5 and v6+ versions is the requirement
1760 ;; that the output does not overlap with either input.
1762 (define_expand "<Us>mulsidi3"
1763 [(set (match_operand:DI 0 "s_register_operand")
1765 (SE:DI (match_operand:SI 1 "s_register_operand"))
1766 (SE:DI (match_operand:SI 2 "s_register_operand"))))]
1769 emit_insn (gen_<US>mull (gen_lowpart (SImode, operands[0]),
1770 gen_highpart (SImode, operands[0]),
1771 operands[1], operands[2]));
1776 (define_insn "<US>mull"
1777 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1779 (match_operand:SI 2 "s_register_operand" "%r,r")
1780 (match_operand:SI 3 "s_register_operand" "r,r")))
1781 (set (match_operand:SI 1 "s_register_operand" "=r,&r")
1784 (mult:DI (SE:DI (match_dup 2)) (SE:DI (match_dup 3)))
1787 "<US>mull%?\\t%0, %1, %2, %3"
1788 [(set_attr "type" "umull")
1789 (set_attr "predicable" "yes")
1790 (set_attr "arch" "v6,nov6")]
1793 (define_expand "<Us>maddsidi4"
1794 [(set (match_operand:DI 0 "s_register_operand")
1797 (SE:DI (match_operand:SI 1 "s_register_operand"))
1798 (SE:DI (match_operand:SI 2 "s_register_operand")))
1799 (match_operand:DI 3 "s_register_operand")))]
1802 emit_insn (gen_<US>mlal (gen_lowpart (SImode, operands[0]),
1803 gen_lowpart (SImode, operands[3]),
1804 gen_highpart (SImode, operands[0]),
1805 gen_highpart (SImode, operands[3]),
1806 operands[1], operands[2]));
1811 (define_insn "<US>mlal"
1812 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
1815 (SE:DI (match_operand:SI 4 "s_register_operand" "%r,r"))
1816 (SE:DI (match_operand:SI 5 "s_register_operand" "r,r")))
1817 (match_operand:SI 1 "s_register_operand" "0,0")))
1818 (set (match_operand:SI 2 "s_register_operand" "=r,&r")
1823 (mult:DI (SE:DI (match_dup 4)) (SE:DI (match_dup 5)))
1824 (zero_extend:DI (match_dup 1)))
1826 (match_operand:SI 3 "s_register_operand" "2,2")))]
1828 "<US>mlal%?\\t%0, %2, %4, %5"
1829 [(set_attr "type" "umlal")
1830 (set_attr "predicable" "yes")
1831 (set_attr "arch" "v6,nov6")]
1834 (define_expand "<US>mulsi3_highpart"
1836 [(set (match_operand:SI 0 "s_register_operand")
1840 (SE:DI (match_operand:SI 1 "s_register_operand"))
1841 (SE:DI (match_operand:SI 2 "s_register_operand")))
1843 (clobber (match_scratch:SI 3 ""))])]
1848 (define_insn "*<US>mull_high"
1849 [(set (match_operand:SI 0 "s_register_operand" "=r,&r,&r")
1853 (SE:DI (match_operand:SI 1 "s_register_operand" "%r,0,r"))
1854 (SE:DI (match_operand:SI 2 "s_register_operand" "r,r,r")))
1856 (clobber (match_scratch:SI 3 "=r,&r,&r"))]
1858 "<US>mull%?\\t%3, %0, %2, %1"
1859 [(set_attr "type" "umull")
1860 (set_attr "predicable" "yes")
1861 (set_attr "arch" "v6,nov6,nov6")]
1864 (define_insn "mulhisi3"
1865 [(set (match_operand:SI 0 "s_register_operand" "=r")
1866 (mult:SI (sign_extend:SI
1867 (match_operand:HI 1 "s_register_operand" "%r"))
1869 (match_operand:HI 2 "s_register_operand" "r"))))]
1870 "TARGET_DSP_MULTIPLY"
1871 "smulbb%?\\t%0, %1, %2"
1872 [(set_attr "type" "smulxy")
1873 (set_attr "predicable" "yes")]
1876 (define_insn "*mulhisi3tb"
1877 [(set (match_operand:SI 0 "s_register_operand" "=r")
1878 (mult:SI (ashiftrt:SI
1879 (match_operand:SI 1 "s_register_operand" "r")
1882 (match_operand:HI 2 "s_register_operand" "r"))))]
1883 "TARGET_DSP_MULTIPLY"
1884 "smultb%?\\t%0, %1, %2"
1885 [(set_attr "type" "smulxy")
1886 (set_attr "predicable" "yes")]
1889 (define_insn "*mulhisi3bt"
1890 [(set (match_operand:SI 0 "s_register_operand" "=r")
1891 (mult:SI (sign_extend:SI
1892 (match_operand:HI 1 "s_register_operand" "r"))
1894 (match_operand:SI 2 "s_register_operand" "r")
1896 "TARGET_DSP_MULTIPLY"
1897 "smulbt%?\\t%0, %1, %2"
1898 [(set_attr "type" "smulxy")
1899 (set_attr "predicable" "yes")]
1902 (define_insn "*mulhisi3tt"
1903 [(set (match_operand:SI 0 "s_register_operand" "=r")
1904 (mult:SI (ashiftrt:SI
1905 (match_operand:SI 1 "s_register_operand" "r")
1908 (match_operand:SI 2 "s_register_operand" "r")
1910 "TARGET_DSP_MULTIPLY"
1911 "smultt%?\\t%0, %1, %2"
1912 [(set_attr "type" "smulxy")
1913 (set_attr "predicable" "yes")]
1916 (define_insn "maddhisi4"
1917 [(set (match_operand:SI 0 "s_register_operand" "=r")
1918 (plus:SI (mult:SI (sign_extend:SI
1919 (match_operand:HI 1 "s_register_operand" "r"))
1921 (match_operand:HI 2 "s_register_operand" "r")))
1922 (match_operand:SI 3 "s_register_operand" "r")))]
1923 "TARGET_DSP_MULTIPLY"
1924 "smlabb%?\\t%0, %1, %2, %3"
1925 [(set_attr "type" "smlaxy")
1926 (set_attr "predicable" "yes")]
1929 ;; Note: there is no maddhisi4ibt because this one is canonical form
1930 (define_insn "*maddhisi4tb"
1931 [(set (match_operand:SI 0 "s_register_operand" "=r")
1932 (plus:SI (mult:SI (ashiftrt:SI
1933 (match_operand:SI 1 "s_register_operand" "r")
1936 (match_operand:HI 2 "s_register_operand" "r")))
1937 (match_operand:SI 3 "s_register_operand" "r")))]
1938 "TARGET_DSP_MULTIPLY"
1939 "smlatb%?\\t%0, %1, %2, %3"
1940 [(set_attr "type" "smlaxy")
1941 (set_attr "predicable" "yes")]
1944 (define_insn "*maddhisi4tt"
1945 [(set (match_operand:SI 0 "s_register_operand" "=r")
1946 (plus:SI (mult:SI (ashiftrt:SI
1947 (match_operand:SI 1 "s_register_operand" "r")
1950 (match_operand:SI 2 "s_register_operand" "r")
1952 (match_operand:SI 3 "s_register_operand" "r")))]
1953 "TARGET_DSP_MULTIPLY"
1954 "smlatt%?\\t%0, %1, %2, %3"
1955 [(set_attr "type" "smlaxy")
1956 (set_attr "predicable" "yes")]
1959 (define_insn "maddhidi4"
1960 [(set (match_operand:DI 0 "s_register_operand" "=r")
1962 (mult:DI (sign_extend:DI
1963 (match_operand:HI 1 "s_register_operand" "r"))
1965 (match_operand:HI 2 "s_register_operand" "r")))
1966 (match_operand:DI 3 "s_register_operand" "0")))]
1967 "TARGET_DSP_MULTIPLY"
1968 "smlalbb%?\\t%Q0, %R0, %1, %2"
1969 [(set_attr "type" "smlalxy")
1970 (set_attr "predicable" "yes")])
1972 ;; Note: there is no maddhidi4ibt because this one is canonical form
1973 (define_insn "*maddhidi4tb"
1974 [(set (match_operand:DI 0 "s_register_operand" "=r")
1976 (mult:DI (sign_extend:DI
1978 (match_operand:SI 1 "s_register_operand" "r")
1981 (match_operand:HI 2 "s_register_operand" "r")))
1982 (match_operand:DI 3 "s_register_operand" "0")))]
1983 "TARGET_DSP_MULTIPLY"
1984 "smlaltb%?\\t%Q0, %R0, %1, %2"
1985 [(set_attr "type" "smlalxy")
1986 (set_attr "predicable" "yes")])
1988 (define_insn "*maddhidi4tt"
1989 [(set (match_operand:DI 0 "s_register_operand" "=r")
1991 (mult:DI (sign_extend:DI
1993 (match_operand:SI 1 "s_register_operand" "r")
1997 (match_operand:SI 2 "s_register_operand" "r")
1999 (match_operand:DI 3 "s_register_operand" "0")))]
2000 "TARGET_DSP_MULTIPLY"
2001 "smlaltt%?\\t%Q0, %R0, %1, %2"
2002 [(set_attr "type" "smlalxy")
2003 (set_attr "predicable" "yes")])
2005 (define_expand "mulsf3"
2006 [(set (match_operand:SF 0 "s_register_operand")
2007 (mult:SF (match_operand:SF 1 "s_register_operand")
2008 (match_operand:SF 2 "s_register_operand")))]
2009 "TARGET_32BIT && TARGET_HARD_FLOAT"
2013 (define_expand "muldf3"
2014 [(set (match_operand:DF 0 "s_register_operand")
2015 (mult:DF (match_operand:DF 1 "s_register_operand")
2016 (match_operand:DF 2 "s_register_operand")))]
2017 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2023 (define_expand "divsf3"
2024 [(set (match_operand:SF 0 "s_register_operand")
2025 (div:SF (match_operand:SF 1 "s_register_operand")
2026 (match_operand:SF 2 "s_register_operand")))]
2027 "TARGET_32BIT && TARGET_HARD_FLOAT"
2030 (define_expand "divdf3"
2031 [(set (match_operand:DF 0 "s_register_operand")
2032 (div:DF (match_operand:DF 1 "s_register_operand")
2033 (match_operand:DF 2 "s_register_operand")))]
2034 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2038 ; Expand logical operations. The mid-end expander does not split off memory
2039 ; operands or complex immediates, which leads to fewer LDRD/STRD instructions.
2040 ; So an explicit expander is needed to generate better code.
2042 (define_expand "<LOGICAL:optab>di3"
2043 [(set (match_operand:DI 0 "s_register_operand")
2044 (LOGICAL:DI (match_operand:DI 1 "s_register_operand")
2045 (match_operand:DI 2 "arm_<optab>di_operand")))]
2048 rtx low = simplify_gen_binary (<CODE>, SImode,
2049 gen_lowpart (SImode, operands[1]),
2050 gen_lowpart (SImode, operands[2]));
2051 rtx high = simplify_gen_binary (<CODE>, SImode,
2052 gen_highpart (SImode, operands[1]),
2053 gen_highpart_mode (SImode, DImode,
2056 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2057 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2062 (define_expand "one_cmpldi2"
2063 [(set (match_operand:DI 0 "s_register_operand")
2064 (not:DI (match_operand:DI 1 "s_register_operand")))]
2067 rtx low = simplify_gen_unary (NOT, SImode,
2068 gen_lowpart (SImode, operands[1]),
2070 rtx high = simplify_gen_unary (NOT, SImode,
2071 gen_highpart_mode (SImode, DImode,
2075 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2076 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2081 ;; Split DImode and, ior, xor operations. Simply perform the logical
2082 ;; operation on the upper and lower halves of the registers.
2083 ;; This is needed for atomic operations in arm_split_atomic_op.
2084 ;; Avoid splitting IWMMXT instructions.
2086 [(set (match_operand:DI 0 "s_register_operand" "")
2087 (match_operator:DI 6 "logical_binary_operator"
2088 [(match_operand:DI 1 "s_register_operand" "")
2089 (match_operand:DI 2 "s_register_operand" "")]))]
2090 "TARGET_32BIT && reload_completed
2091 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2092 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2093 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2096 operands[3] = gen_highpart (SImode, operands[0]);
2097 operands[0] = gen_lowpart (SImode, operands[0]);
2098 operands[4] = gen_highpart (SImode, operands[1]);
2099 operands[1] = gen_lowpart (SImode, operands[1]);
2100 operands[5] = gen_highpart (SImode, operands[2]);
2101 operands[2] = gen_lowpart (SImode, operands[2]);
2105 ;; Split DImode not (needed for atomic operations in arm_split_atomic_op).
2106 ;; Unconditionally split since there is no SIMD DImode NOT pattern.
2108 [(set (match_operand:DI 0 "s_register_operand")
2109 (not:DI (match_operand:DI 1 "s_register_operand")))]
2111 [(set (match_dup 0) (not:SI (match_dup 1)))
2112 (set (match_dup 2) (not:SI (match_dup 3)))]
2115 operands[2] = gen_highpart (SImode, operands[0]);
2116 operands[0] = gen_lowpart (SImode, operands[0]);
2117 operands[3] = gen_highpart (SImode, operands[1]);
2118 operands[1] = gen_lowpart (SImode, operands[1]);
2122 (define_expand "andsi3"
2123 [(set (match_operand:SI 0 "s_register_operand")
2124 (and:SI (match_operand:SI 1 "s_register_operand")
2125 (match_operand:SI 2 "reg_or_int_operand")))]
2130 if (CONST_INT_P (operands[2]))
2132 if (INTVAL (operands[2]) == 255 && arm_arch6)
2134 operands[1] = convert_to_mode (QImode, operands[1], 1);
2135 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2139 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2140 operands[2] = force_reg (SImode, operands[2]);
2143 arm_split_constant (AND, SImode, NULL_RTX,
2144 INTVAL (operands[2]), operands[0],
2146 optimize && can_create_pseudo_p ());
2152 else /* TARGET_THUMB1 */
2154 if (!CONST_INT_P (operands[2]))
2156 rtx tmp = force_reg (SImode, operands[2]);
2157 if (rtx_equal_p (operands[0], operands[1]))
2161 operands[2] = operands[1];
2169 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2171 operands[2] = force_reg (SImode,
2172 GEN_INT (~INTVAL (operands[2])));
2174 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2179 for (i = 9; i <= 31; i++)
2181 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2183 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2187 else if ((HOST_WIDE_INT_1 << i) - 1
2188 == ~INTVAL (operands[2]))
2190 rtx shift = GEN_INT (i);
2191 rtx reg = gen_reg_rtx (SImode);
2193 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2194 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2200 operands[2] = force_reg (SImode, operands[2]);
2206 ; ??? Check split length for Thumb-2
2207 (define_insn_and_split "*arm_andsi3_insn"
2208 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2209 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2210 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2215 bic%?\\t%0, %1, #%B2
2219 && CONST_INT_P (operands[2])
2220 && !(const_ok_for_arm (INTVAL (operands[2]))
2221 || const_ok_for_arm (~INTVAL (operands[2])))"
2222 [(clobber (const_int 0))]
2224 arm_split_constant (AND, SImode, curr_insn,
2225 INTVAL (operands[2]), operands[0], operands[1], 0);
2228 [(set_attr "length" "4,4,4,4,16")
2229 (set_attr "predicable" "yes")
2230 (set_attr "predicable_short_it" "no,yes,no,no,no")
2231 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2234 (define_insn "*andsi3_compare0"
2235 [(set (reg:CC_NOOV CC_REGNUM)
2237 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2238 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2240 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2241 (and:SI (match_dup 1) (match_dup 2)))]
2245 bics%?\\t%0, %1, #%B2
2246 ands%?\\t%0, %1, %2"
2247 [(set_attr "conds" "set")
2248 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2251 (define_insn "*andsi3_compare0_scratch"
2252 [(set (reg:CC_NOOV CC_REGNUM)
2254 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2255 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2257 (clobber (match_scratch:SI 2 "=X,r,X"))]
2261 bics%?\\t%2, %0, #%B1
2263 [(set_attr "conds" "set")
2264 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2267 (define_insn "*zeroextractsi_compare0_scratch"
2268 [(set (reg:CC_NOOV CC_REGNUM)
2269 (compare:CC_NOOV (zero_extract:SI
2270 (match_operand:SI 0 "s_register_operand" "r")
2271 (match_operand 1 "const_int_operand" "n")
2272 (match_operand 2 "const_int_operand" "n"))
2275 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2276 && INTVAL (operands[1]) > 0
2277 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2278 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2280 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2281 << INTVAL (operands[2]));
2282 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2285 [(set_attr "conds" "set")
2286 (set_attr "predicable" "yes")
2287 (set_attr "type" "logics_imm")]
2290 (define_insn_and_split "*ne_zeroextractsi"
2291 [(set (match_operand:SI 0 "s_register_operand" "=r")
2292 (ne:SI (zero_extract:SI
2293 (match_operand:SI 1 "s_register_operand" "r")
2294 (match_operand:SI 2 "const_int_operand" "n")
2295 (match_operand:SI 3 "const_int_operand" "n"))
2297 (clobber (reg:CC CC_REGNUM))]
2299 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2300 && INTVAL (operands[2]) > 0
2301 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2302 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2305 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2306 && INTVAL (operands[2]) > 0
2307 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2308 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2309 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2310 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2312 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2314 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2315 (match_dup 0) (const_int 1)))]
2317 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2318 << INTVAL (operands[3]));
2320 [(set_attr "conds" "clob")
2321 (set (attr "length")
2322 (if_then_else (eq_attr "is_thumb" "yes")
2325 (set_attr "type" "multiple")]
2328 (define_insn_and_split "*ne_zeroextractsi_shifted"
2329 [(set (match_operand:SI 0 "s_register_operand" "=r")
2330 (ne:SI (zero_extract:SI
2331 (match_operand:SI 1 "s_register_operand" "r")
2332 (match_operand:SI 2 "const_int_operand" "n")
2335 (clobber (reg:CC CC_REGNUM))]
2339 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2340 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2342 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2344 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2345 (match_dup 0) (const_int 1)))]
2347 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2349 [(set_attr "conds" "clob")
2350 (set_attr "length" "8")
2351 (set_attr "type" "multiple")]
2354 (define_insn_and_split "*ite_ne_zeroextractsi"
2355 [(set (match_operand:SI 0 "s_register_operand" "=r")
2356 (if_then_else:SI (ne (zero_extract:SI
2357 (match_operand:SI 1 "s_register_operand" "r")
2358 (match_operand:SI 2 "const_int_operand" "n")
2359 (match_operand:SI 3 "const_int_operand" "n"))
2361 (match_operand:SI 4 "arm_not_operand" "rIK")
2363 (clobber (reg:CC CC_REGNUM))]
2365 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2366 && INTVAL (operands[2]) > 0
2367 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2368 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2369 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2372 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2373 && INTVAL (operands[2]) > 0
2374 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2375 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2376 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2377 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2378 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2380 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2382 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2383 (match_dup 0) (match_dup 4)))]
2385 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2386 << INTVAL (operands[3]));
2388 [(set_attr "conds" "clob")
2389 (set_attr "length" "8")
2390 (set_attr "type" "multiple")]
2393 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2394 [(set (match_operand:SI 0 "s_register_operand" "=r")
2395 (if_then_else:SI (ne (zero_extract:SI
2396 (match_operand:SI 1 "s_register_operand" "r")
2397 (match_operand:SI 2 "const_int_operand" "n")
2400 (match_operand:SI 3 "arm_not_operand" "rIK")
2402 (clobber (reg:CC CC_REGNUM))]
2403 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2405 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2406 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2407 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2409 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2411 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2412 (match_dup 0) (match_dup 3)))]
2414 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2416 [(set_attr "conds" "clob")
2417 (set_attr "length" "8")
2418 (set_attr "type" "multiple")]
2421 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2423 [(set (match_operand:SI 0 "s_register_operand" "")
2424 (match_operator:SI 1 "shiftable_operator"
2425 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2426 (match_operand:SI 3 "const_int_operand" "")
2427 (match_operand:SI 4 "const_int_operand" ""))
2428 (match_operand:SI 5 "s_register_operand" "")]))
2429 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2431 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2434 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2437 HOST_WIDE_INT temp = INTVAL (operands[3]);
2439 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2440 operands[4] = GEN_INT (32 - temp);
2445 [(set (match_operand:SI 0 "s_register_operand" "")
2446 (match_operator:SI 1 "shiftable_operator"
2447 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2448 (match_operand:SI 3 "const_int_operand" "")
2449 (match_operand:SI 4 "const_int_operand" ""))
2450 (match_operand:SI 5 "s_register_operand" "")]))
2451 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2453 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2456 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2459 HOST_WIDE_INT temp = INTVAL (operands[3]);
2461 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2462 operands[4] = GEN_INT (32 - temp);
2466 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2467 ;;; represented by the bitfield, then this will produce incorrect results.
2468 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2469 ;;; which have a real bit-field insert instruction, the truncation happens
2470 ;;; in the bit-field insert instruction itself. Since arm does not have a
2471 ;;; bit-field insert instruction, we would have to emit code here to truncate
2472 ;;; the value before we insert. This loses some of the advantage of having
2473 ;;; this insv pattern, so this pattern needs to be reevalutated.
2475 (define_expand "insv"
2476 [(set (zero_extract (match_operand 0 "nonimmediate_operand")
2477 (match_operand 1 "general_operand")
2478 (match_operand 2 "general_operand"))
2479 (match_operand 3 "reg_or_int_operand"))]
2480 "TARGET_ARM || arm_arch_thumb2"
2483 int start_bit = INTVAL (operands[2]);
2484 int width = INTVAL (operands[1]);
2485 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2486 rtx target, subtarget;
2488 if (arm_arch_thumb2)
2490 if (unaligned_access && MEM_P (operands[0])
2491 && s_register_operand (operands[3], GET_MODE (operands[3]))
2492 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2496 if (BYTES_BIG_ENDIAN)
2497 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2502 base_addr = adjust_address (operands[0], SImode,
2503 start_bit / BITS_PER_UNIT);
2504 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2508 rtx tmp = gen_reg_rtx (HImode);
2510 base_addr = adjust_address (operands[0], HImode,
2511 start_bit / BITS_PER_UNIT);
2512 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2513 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2517 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2519 bool use_bfi = TRUE;
2521 if (CONST_INT_P (operands[3]))
2523 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2527 emit_insn (gen_insv_zero (operands[0], operands[1],
2532 /* See if the set can be done with a single orr instruction. */
2533 if (val == mask && const_ok_for_arm (val << start_bit))
2539 if (!REG_P (operands[3]))
2540 operands[3] = force_reg (SImode, operands[3]);
2542 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2551 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2554 target = copy_rtx (operands[0]);
2555 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2556 subreg as the final target. */
2557 if (GET_CODE (target) == SUBREG)
2559 subtarget = gen_reg_rtx (SImode);
2560 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2561 < GET_MODE_SIZE (SImode))
2562 target = SUBREG_REG (target);
2567 if (CONST_INT_P (operands[3]))
2569 /* Since we are inserting a known constant, we may be able to
2570 reduce the number of bits that we have to clear so that
2571 the mask becomes simple. */
2572 /* ??? This code does not check to see if the new mask is actually
2573 simpler. It may not be. */
2574 rtx op1 = gen_reg_rtx (SImode);
2575 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2576 start of this pattern. */
2577 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2578 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2580 emit_insn (gen_andsi3 (op1, operands[0],
2581 gen_int_mode (~mask2, SImode)));
2582 emit_insn (gen_iorsi3 (subtarget, op1,
2583 gen_int_mode (op3_value << start_bit, SImode)));
2585 else if (start_bit == 0
2586 && !(const_ok_for_arm (mask)
2587 || const_ok_for_arm (~mask)))
2589 /* A Trick, since we are setting the bottom bits in the word,
2590 we can shift operand[3] up, operand[0] down, OR them together
2591 and rotate the result back again. This takes 3 insns, and
2592 the third might be mergeable into another op. */
2593 /* The shift up copes with the possibility that operand[3] is
2594 wider than the bitfield. */
2595 rtx op0 = gen_reg_rtx (SImode);
2596 rtx op1 = gen_reg_rtx (SImode);
2598 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2599 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2600 emit_insn (gen_iorsi3 (op1, op1, op0));
2601 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2603 else if ((width + start_bit == 32)
2604 && !(const_ok_for_arm (mask)
2605 || const_ok_for_arm (~mask)))
2607 /* Similar trick, but slightly less efficient. */
2609 rtx op0 = gen_reg_rtx (SImode);
2610 rtx op1 = gen_reg_rtx (SImode);
2612 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2613 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2614 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2615 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2619 rtx op0 = gen_int_mode (mask, SImode);
2620 rtx op1 = gen_reg_rtx (SImode);
2621 rtx op2 = gen_reg_rtx (SImode);
2623 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2625 rtx tmp = gen_reg_rtx (SImode);
2627 emit_insn (gen_movsi (tmp, op0));
2631 /* Mask out any bits in operand[3] that are not needed. */
2632 emit_insn (gen_andsi3 (op1, operands[3], op0));
2634 if (CONST_INT_P (op0)
2635 && (const_ok_for_arm (mask << start_bit)
2636 || const_ok_for_arm (~(mask << start_bit))))
2638 op0 = gen_int_mode (~(mask << start_bit), SImode);
2639 emit_insn (gen_andsi3 (op2, operands[0], op0));
2643 if (CONST_INT_P (op0))
2645 rtx tmp = gen_reg_rtx (SImode);
2647 emit_insn (gen_movsi (tmp, op0));
2652 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2654 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2658 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2660 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2663 if (subtarget != target)
2665 /* If TARGET is still a SUBREG, then it must be wider than a word,
2666 so we must be careful only to set the subword we were asked to. */
2667 if (GET_CODE (target) == SUBREG)
2668 emit_move_insn (target, subtarget);
2670 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2677 (define_insn "insv_zero"
2678 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2679 (match_operand:SI 1 "const_int_M_operand" "M")
2680 (match_operand:SI 2 "const_int_M_operand" "M"))
2684 [(set_attr "length" "4")
2685 (set_attr "predicable" "yes")
2686 (set_attr "type" "bfm")]
2689 (define_insn "insv_t2"
2690 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2691 (match_operand:SI 1 "const_int_M_operand" "M")
2692 (match_operand:SI 2 "const_int_M_operand" "M"))
2693 (match_operand:SI 3 "s_register_operand" "r"))]
2695 "bfi%?\t%0, %3, %2, %1"
2696 [(set_attr "length" "4")
2697 (set_attr "predicable" "yes")
2698 (set_attr "type" "bfm")]
2701 (define_insn "andsi_notsi_si"
2702 [(set (match_operand:SI 0 "s_register_operand" "=r")
2703 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2704 (match_operand:SI 1 "s_register_operand" "r")))]
2706 "bic%?\\t%0, %1, %2"
2707 [(set_attr "predicable" "yes")
2708 (set_attr "type" "logic_reg")]
2711 (define_insn "andsi_not_shiftsi_si"
2712 [(set (match_operand:SI 0 "s_register_operand" "=r")
2713 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2714 [(match_operand:SI 2 "s_register_operand" "r")
2715 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2716 (match_operand:SI 1 "s_register_operand" "r")))]
2718 "bic%?\\t%0, %1, %2%S4"
2719 [(set_attr "predicable" "yes")
2720 (set_attr "shift" "2")
2721 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2722 (const_string "logic_shift_imm")
2723 (const_string "logic_shift_reg")))]
2726 ;; Shifted bics pattern used to set up CC status register and not reusing
2727 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
2728 ;; does not support shift by register.
2729 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
2730 [(set (reg:CC_NOOV CC_REGNUM)
2732 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2733 [(match_operand:SI 1 "s_register_operand" "r")
2734 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2735 (match_operand:SI 3 "s_register_operand" "r"))
2737 (clobber (match_scratch:SI 4 "=r"))]
2738 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2739 "bics%?\\t%4, %3, %1%S0"
2740 [(set_attr "predicable" "yes")
2741 (set_attr "conds" "set")
2742 (set_attr "shift" "1")
2743 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2744 (const_string "logic_shift_imm")
2745 (const_string "logic_shift_reg")))]
2748 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
2749 ;; getting reused later.
2750 (define_insn "andsi_not_shiftsi_si_scc"
2751 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2753 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2754 [(match_operand:SI 1 "s_register_operand" "r")
2755 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2756 (match_operand:SI 3 "s_register_operand" "r"))
2758 (set (match_operand:SI 4 "s_register_operand" "=r")
2759 (and:SI (not:SI (match_op_dup 0
2763 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2764 "bics%?\\t%4, %3, %1%S0"
2765 [(set_attr "predicable" "yes")
2766 (set_attr "conds" "set")
2767 (set_attr "shift" "1")
2768 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2769 (const_string "logic_shift_imm")
2770 (const_string "logic_shift_reg")))]
2773 (define_insn "*andsi_notsi_si_compare0"
2774 [(set (reg:CC_NOOV CC_REGNUM)
2776 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2777 (match_operand:SI 1 "s_register_operand" "r"))
2779 (set (match_operand:SI 0 "s_register_operand" "=r")
2780 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2783 [(set_attr "conds" "set")
2784 (set_attr "type" "logics_shift_reg")]
2787 (define_insn "*andsi_notsi_si_compare0_scratch"
2788 [(set (reg:CC_NOOV CC_REGNUM)
2790 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2791 (match_operand:SI 1 "s_register_operand" "r"))
2793 (clobber (match_scratch:SI 0 "=r"))]
2796 [(set_attr "conds" "set")
2797 (set_attr "type" "logics_shift_reg")]
2800 (define_expand "iorsi3"
2801 [(set (match_operand:SI 0 "s_register_operand")
2802 (ior:SI (match_operand:SI 1 "s_register_operand")
2803 (match_operand:SI 2 "reg_or_int_operand")))]
2806 if (CONST_INT_P (operands[2]))
2810 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
2811 operands[2] = force_reg (SImode, operands[2]);
2814 arm_split_constant (IOR, SImode, NULL_RTX,
2815 INTVAL (operands[2]), operands[0],
2817 optimize && can_create_pseudo_p ());
2821 else /* TARGET_THUMB1 */
2823 rtx tmp = force_reg (SImode, operands[2]);
2824 if (rtx_equal_p (operands[0], operands[1]))
2828 operands[2] = operands[1];
2836 (define_insn_and_split "*iorsi3_insn"
2837 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2838 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2839 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2844 orn%?\\t%0, %1, #%B2
2848 && CONST_INT_P (operands[2])
2849 && !(const_ok_for_arm (INTVAL (operands[2]))
2850 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
2851 [(clobber (const_int 0))]
2853 arm_split_constant (IOR, SImode, curr_insn,
2854 INTVAL (operands[2]), operands[0], operands[1], 0);
2857 [(set_attr "length" "4,4,4,4,16")
2858 (set_attr "arch" "32,t2,t2,32,32")
2859 (set_attr "predicable" "yes")
2860 (set_attr "predicable_short_it" "no,yes,no,no,no")
2861 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
2865 [(match_scratch:SI 3 "r")
2866 (set (match_operand:SI 0 "arm_general_register_operand" "")
2867 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2868 (match_operand:SI 2 "const_int_operand" "")))]
2870 && !const_ok_for_arm (INTVAL (operands[2]))
2871 && const_ok_for_arm (~INTVAL (operands[2]))"
2872 [(set (match_dup 3) (match_dup 2))
2873 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2877 (define_insn "*iorsi3_compare0"
2878 [(set (reg:CC_NOOV CC_REGNUM)
2880 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r")
2881 (match_operand:SI 2 "arm_rhs_operand" "I,l,r"))
2883 (set (match_operand:SI 0 "s_register_operand" "=r,l,r")
2884 (ior:SI (match_dup 1) (match_dup 2)))]
2886 "orrs%?\\t%0, %1, %2"
2887 [(set_attr "conds" "set")
2888 (set_attr "arch" "*,t2,*")
2889 (set_attr "length" "4,2,4")
2890 (set_attr "type" "logics_imm,logics_reg,logics_reg")]
2893 (define_insn "*iorsi3_compare0_scratch"
2894 [(set (reg:CC_NOOV CC_REGNUM)
2896 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r")
2897 (match_operand:SI 2 "arm_rhs_operand" "I,l,r"))
2899 (clobber (match_scratch:SI 0 "=r,l,r"))]
2901 "orrs%?\\t%0, %1, %2"
2902 [(set_attr "conds" "set")
2903 (set_attr "arch" "*,t2,*")
2904 (set_attr "length" "4,2,4")
2905 (set_attr "type" "logics_imm,logics_reg,logics_reg")]
2908 (define_expand "xorsi3"
2909 [(set (match_operand:SI 0 "s_register_operand")
2910 (xor:SI (match_operand:SI 1 "s_register_operand")
2911 (match_operand:SI 2 "reg_or_int_operand")))]
2913 "if (CONST_INT_P (operands[2]))
2917 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
2918 operands[2] = force_reg (SImode, operands[2]);
2921 arm_split_constant (XOR, SImode, NULL_RTX,
2922 INTVAL (operands[2]), operands[0],
2924 optimize && can_create_pseudo_p ());
2928 else /* TARGET_THUMB1 */
2930 rtx tmp = force_reg (SImode, operands[2]);
2931 if (rtx_equal_p (operands[0], operands[1]))
2935 operands[2] = operands[1];
2942 (define_insn_and_split "*arm_xorsi3"
2943 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
2944 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
2945 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
2953 && CONST_INT_P (operands[2])
2954 && !const_ok_for_arm (INTVAL (operands[2]))"
2955 [(clobber (const_int 0))]
2957 arm_split_constant (XOR, SImode, curr_insn,
2958 INTVAL (operands[2]), operands[0], operands[1], 0);
2961 [(set_attr "length" "4,4,4,16")
2962 (set_attr "predicable" "yes")
2963 (set_attr "predicable_short_it" "no,yes,no,no")
2964 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
2967 (define_insn "*xorsi3_compare0"
2968 [(set (reg:CC_NOOV CC_REGNUM)
2969 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
2970 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
2972 (set (match_operand:SI 0 "s_register_operand" "=r,r")
2973 (xor:SI (match_dup 1) (match_dup 2)))]
2975 "eors%?\\t%0, %1, %2"
2976 [(set_attr "conds" "set")
2977 (set_attr "type" "logics_imm,logics_reg")]
2980 (define_insn "*xorsi3_compare0_scratch"
2981 [(set (reg:CC_NOOV CC_REGNUM)
2982 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
2983 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
2987 [(set_attr "conds" "set")
2988 (set_attr "type" "logics_imm,logics_reg")]
2991 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
2992 ; (NOT D) we can sometimes merge the final NOT into one of the following
2996 [(set (match_operand:SI 0 "s_register_operand" "")
2997 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
2998 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
2999 (match_operand:SI 3 "arm_rhs_operand" "")))
3000 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3002 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3003 (not:SI (match_dup 3))))
3004 (set (match_dup 0) (not:SI (match_dup 4)))]
3008 (define_insn_and_split "*andsi_iorsi3_notsi"
3009 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3010 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3011 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3012 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3014 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3015 "&& reload_completed"
3016 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3017 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3019 /* If operands[3] is a constant make sure to fold the NOT into it
3020 to avoid creating a NOT of a CONST_INT. */
3021 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3022 if (CONST_INT_P (not_rtx))
3024 operands[4] = operands[0];
3025 operands[5] = not_rtx;
3029 operands[5] = operands[0];
3030 operands[4] = not_rtx;
3033 [(set_attr "length" "8")
3034 (set_attr "ce_count" "2")
3035 (set_attr "predicable" "yes")
3036 (set_attr "type" "multiple")]
3039 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3040 ; insns are available?
3042 [(set (match_operand:SI 0 "s_register_operand" "")
3043 (match_operator:SI 1 "logical_binary_operator"
3044 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3045 (match_operand:SI 3 "const_int_operand" "")
3046 (match_operand:SI 4 "const_int_operand" ""))
3047 (match_operator:SI 9 "logical_binary_operator"
3048 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3049 (match_operand:SI 6 "const_int_operand" ""))
3050 (match_operand:SI 7 "s_register_operand" "")])]))
3051 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3053 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3054 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3057 [(ashift:SI (match_dup 2) (match_dup 4))
3061 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3064 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3068 [(set (match_operand:SI 0 "s_register_operand" "")
3069 (match_operator:SI 1 "logical_binary_operator"
3070 [(match_operator:SI 9 "logical_binary_operator"
3071 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3072 (match_operand:SI 6 "const_int_operand" ""))
3073 (match_operand:SI 7 "s_register_operand" "")])
3074 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3075 (match_operand:SI 3 "const_int_operand" "")
3076 (match_operand:SI 4 "const_int_operand" ""))]))
3077 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3079 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3080 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3083 [(ashift:SI (match_dup 2) (match_dup 4))
3087 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3090 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3094 [(set (match_operand:SI 0 "s_register_operand" "")
3095 (match_operator:SI 1 "logical_binary_operator"
3096 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3097 (match_operand:SI 3 "const_int_operand" "")
3098 (match_operand:SI 4 "const_int_operand" ""))
3099 (match_operator:SI 9 "logical_binary_operator"
3100 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3101 (match_operand:SI 6 "const_int_operand" ""))
3102 (match_operand:SI 7 "s_register_operand" "")])]))
3103 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3105 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3106 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3109 [(ashift:SI (match_dup 2) (match_dup 4))
3113 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3116 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3120 [(set (match_operand:SI 0 "s_register_operand" "")
3121 (match_operator:SI 1 "logical_binary_operator"
3122 [(match_operator:SI 9 "logical_binary_operator"
3123 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3124 (match_operand:SI 6 "const_int_operand" ""))
3125 (match_operand:SI 7 "s_register_operand" "")])
3126 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3127 (match_operand:SI 3 "const_int_operand" "")
3128 (match_operand:SI 4 "const_int_operand" ""))]))
3129 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3131 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3132 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3135 [(ashift:SI (match_dup 2) (match_dup 4))
3139 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3142 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3146 ;; Minimum and maximum insns
3148 (define_expand "smaxsi3"
3150 (set (match_operand:SI 0 "s_register_operand")
3151 (smax:SI (match_operand:SI 1 "s_register_operand")
3152 (match_operand:SI 2 "arm_rhs_operand")))
3153 (clobber (reg:CC CC_REGNUM))])]
3156 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3158 /* No need for a clobber of the condition code register here. */
3159 emit_insn (gen_rtx_SET (operands[0],
3160 gen_rtx_SMAX (SImode, operands[1],
3166 (define_insn "*smax_0"
3167 [(set (match_operand:SI 0 "s_register_operand" "=r")
3168 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3171 "bic%?\\t%0, %1, %1, asr #31"
3172 [(set_attr "predicable" "yes")
3173 (set_attr "type" "logic_shift_reg")]
3176 (define_insn "*smax_m1"
3177 [(set (match_operand:SI 0 "s_register_operand" "=r")
3178 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3181 "orr%?\\t%0, %1, %1, asr #31"
3182 [(set_attr "predicable" "yes")
3183 (set_attr "type" "logic_shift_reg")]
3186 (define_insn_and_split "*arm_smax_insn"
3187 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3188 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3189 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3190 (clobber (reg:CC CC_REGNUM))]
3193 ; cmp\\t%1, %2\;movlt\\t%0, %2
3194 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3196 [(set (reg:CC CC_REGNUM)
3197 (compare:CC (match_dup 1) (match_dup 2)))
3199 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3203 [(set_attr "conds" "clob")
3204 (set_attr "length" "8,12")
3205 (set_attr "type" "multiple")]
3208 (define_expand "sminsi3"
3210 (set (match_operand:SI 0 "s_register_operand")
3211 (smin:SI (match_operand:SI 1 "s_register_operand")
3212 (match_operand:SI 2 "arm_rhs_operand")))
3213 (clobber (reg:CC CC_REGNUM))])]
3216 if (operands[2] == const0_rtx)
3218 /* No need for a clobber of the condition code register here. */
3219 emit_insn (gen_rtx_SET (operands[0],
3220 gen_rtx_SMIN (SImode, operands[1],
3226 (define_insn "*smin_0"
3227 [(set (match_operand:SI 0 "s_register_operand" "=r")
3228 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3231 "and%?\\t%0, %1, %1, asr #31"
3232 [(set_attr "predicable" "yes")
3233 (set_attr "type" "logic_shift_reg")]
3236 (define_insn_and_split "*arm_smin_insn"
3237 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3238 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3239 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3240 (clobber (reg:CC CC_REGNUM))]
3243 ; cmp\\t%1, %2\;movge\\t%0, %2
3244 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3246 [(set (reg:CC CC_REGNUM)
3247 (compare:CC (match_dup 1) (match_dup 2)))
3249 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3253 [(set_attr "conds" "clob")
3254 (set_attr "length" "8,12")
3255 (set_attr "type" "multiple,multiple")]
3258 (define_expand "umaxsi3"
3260 (set (match_operand:SI 0 "s_register_operand")
3261 (umax:SI (match_operand:SI 1 "s_register_operand")
3262 (match_operand:SI 2 "arm_rhs_operand")))
3263 (clobber (reg:CC CC_REGNUM))])]
3268 (define_insn_and_split "*arm_umaxsi3"
3269 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3270 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3271 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3272 (clobber (reg:CC CC_REGNUM))]
3275 ; cmp\\t%1, %2\;movcc\\t%0, %2
3276 ; cmp\\t%1, %2\;movcs\\t%0, %1
3277 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3279 [(set (reg:CC CC_REGNUM)
3280 (compare:CC (match_dup 1) (match_dup 2)))
3282 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3286 [(set_attr "conds" "clob")
3287 (set_attr "length" "8,8,12")
3288 (set_attr "type" "store_4")]
3291 (define_expand "uminsi3"
3293 (set (match_operand:SI 0 "s_register_operand")
3294 (umin:SI (match_operand:SI 1 "s_register_operand")
3295 (match_operand:SI 2 "arm_rhs_operand")))
3296 (clobber (reg:CC CC_REGNUM))])]
3301 (define_insn_and_split "*arm_uminsi3"
3302 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3303 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3304 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3305 (clobber (reg:CC CC_REGNUM))]
3308 ; cmp\\t%1, %2\;movcs\\t%0, %2
3309 ; cmp\\t%1, %2\;movcc\\t%0, %1
3310 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3312 [(set (reg:CC CC_REGNUM)
3313 (compare:CC (match_dup 1) (match_dup 2)))
3315 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3319 [(set_attr "conds" "clob")
3320 (set_attr "length" "8,8,12")
3321 (set_attr "type" "store_4")]
3324 (define_insn "*store_minmaxsi"
3325 [(set (match_operand:SI 0 "memory_operand" "=m")
3326 (match_operator:SI 3 "minmax_operator"
3327 [(match_operand:SI 1 "s_register_operand" "r")
3328 (match_operand:SI 2 "s_register_operand" "r")]))
3329 (clobber (reg:CC CC_REGNUM))]
3330 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3332 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3333 operands[1], operands[2]);
3334 output_asm_insn (\"cmp\\t%1, %2\", operands);
3336 output_asm_insn (\"ite\t%d3\", operands);
3337 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3338 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3341 [(set_attr "conds" "clob")
3342 (set (attr "length")
3343 (if_then_else (eq_attr "is_thumb" "yes")
3346 (set_attr "type" "store_4")]
3349 ; Reject the frame pointer in operand[1], since reloading this after
3350 ; it has been eliminated can cause carnage.
3351 (define_insn "*minmax_arithsi"
3352 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3353 (match_operator:SI 4 "shiftable_operator"
3354 [(match_operator:SI 5 "minmax_operator"
3355 [(match_operand:SI 2 "s_register_operand" "r,r")
3356 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3357 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3358 (clobber (reg:CC CC_REGNUM))]
3359 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3362 enum rtx_code code = GET_CODE (operands[4]);
3365 if (which_alternative != 0 || operands[3] != const0_rtx
3366 || (code != PLUS && code != IOR && code != XOR))
3371 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3372 operands[2], operands[3]);
3373 output_asm_insn (\"cmp\\t%2, %3\", operands);
3377 output_asm_insn (\"ite\\t%d5\", operands);
3379 output_asm_insn (\"it\\t%d5\", operands);
3381 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3383 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3386 [(set_attr "conds" "clob")
3387 (set (attr "length")
3388 (if_then_else (eq_attr "is_thumb" "yes")
3391 (set_attr "type" "multiple")]
3394 ; Reject the frame pointer in operand[1], since reloading this after
3395 ; it has been eliminated can cause carnage.
3396 (define_insn_and_split "*minmax_arithsi_non_canon"
3397 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3399 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3400 (match_operator:SI 4 "minmax_operator"
3401 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3402 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3403 (clobber (reg:CC CC_REGNUM))]
3404 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3405 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3407 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3408 [(set (reg:CC CC_REGNUM)
3409 (compare:CC (match_dup 2) (match_dup 3)))
3411 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3413 (minus:SI (match_dup 1)
3415 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3419 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3420 operands[2], operands[3]);
3421 enum rtx_code rc = minmax_code (operands[4]);
3422 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3423 operands[2], operands[3]);
3425 if (mode == CCFPmode || mode == CCFPEmode)
3426 rc = reverse_condition_maybe_unordered (rc);
3428 rc = reverse_condition (rc);
3429 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3430 if (CONST_INT_P (operands[3]))
3431 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3433 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3435 [(set_attr "conds" "clob")
3436 (set (attr "length")
3437 (if_then_else (eq_attr "is_thumb" "yes")
3440 (set_attr "type" "multiple")]
3443 (define_code_iterator SAT [smin smax])
3444 (define_code_attr SATrev [(smin "smax") (smax "smin")])
3445 (define_code_attr SATlo [(smin "1") (smax "2")])
3446 (define_code_attr SAThi [(smin "2") (smax "1")])
3448 (define_insn "*satsi_<SAT:code>"
3449 [(set (match_operand:SI 0 "s_register_operand" "=r")
3450 (SAT:SI (<SATrev>:SI (match_operand:SI 3 "s_register_operand" "r")
3451 (match_operand:SI 1 "const_int_operand" "i"))
3452 (match_operand:SI 2 "const_int_operand" "i")))]
3453 "TARGET_32BIT && arm_arch6
3454 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3458 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3459 &mask, &signed_sat))
3462 operands[1] = GEN_INT (mask);
3464 return "ssat%?\t%0, %1, %3";
3466 return "usat%?\t%0, %1, %3";
3468 [(set_attr "predicable" "yes")
3469 (set_attr "type" "alus_imm")]
3472 (define_insn "*satsi_<SAT:code>_shift"
3473 [(set (match_operand:SI 0 "s_register_operand" "=r")
3474 (SAT:SI (<SATrev>:SI (match_operator:SI 3 "sat_shift_operator"
3475 [(match_operand:SI 4 "s_register_operand" "r")
3476 (match_operand:SI 5 "const_int_operand" "i")])
3477 (match_operand:SI 1 "const_int_operand" "i"))
3478 (match_operand:SI 2 "const_int_operand" "i")))]
3479 "TARGET_32BIT && arm_arch6
3480 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3484 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3485 &mask, &signed_sat))
3488 operands[1] = GEN_INT (mask);
3490 return "ssat%?\t%0, %1, %4%S3";
3492 return "usat%?\t%0, %1, %4%S3";
3494 [(set_attr "predicable" "yes")
3495 (set_attr "shift" "3")
3496 (set_attr "type" "logic_shift_reg")])
3498 ;; Shift and rotation insns
3500 (define_expand "ashldi3"
3501 [(set (match_operand:DI 0 "s_register_operand")
3502 (ashift:DI (match_operand:DI 1 "s_register_operand")
3503 (match_operand:SI 2 "reg_or_int_operand")))]
3506 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3507 operands[2], gen_reg_rtx (SImode),
3508 gen_reg_rtx (SImode));
3512 (define_expand "ashlsi3"
3513 [(set (match_operand:SI 0 "s_register_operand")
3514 (ashift:SI (match_operand:SI 1 "s_register_operand")
3515 (match_operand:SI 2 "arm_rhs_operand")))]
3518 if (CONST_INT_P (operands[2])
3519 && (UINTVAL (operands[2])) > 31)
3521 emit_insn (gen_movsi (operands[0], const0_rtx));
3527 (define_expand "ashrdi3"
3528 [(set (match_operand:DI 0 "s_register_operand")
3529 (ashiftrt:DI (match_operand:DI 1 "s_register_operand")
3530 (match_operand:SI 2 "reg_or_int_operand")))]
3533 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3534 operands[2], gen_reg_rtx (SImode),
3535 gen_reg_rtx (SImode));
3539 (define_expand "ashrsi3"
3540 [(set (match_operand:SI 0 "s_register_operand")
3541 (ashiftrt:SI (match_operand:SI 1 "s_register_operand")
3542 (match_operand:SI 2 "arm_rhs_operand")))]
3545 if (CONST_INT_P (operands[2])
3546 && UINTVAL (operands[2]) > 31)
3547 operands[2] = GEN_INT (31);
3551 (define_expand "lshrdi3"
3552 [(set (match_operand:DI 0 "s_register_operand")
3553 (lshiftrt:DI (match_operand:DI 1 "s_register_operand")
3554 (match_operand:SI 2 "reg_or_int_operand")))]
3557 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3558 operands[2], gen_reg_rtx (SImode),
3559 gen_reg_rtx (SImode));
3563 (define_expand "lshrsi3"
3564 [(set (match_operand:SI 0 "s_register_operand")
3565 (lshiftrt:SI (match_operand:SI 1 "s_register_operand")
3566 (match_operand:SI 2 "arm_rhs_operand")))]
3569 if (CONST_INT_P (operands[2])
3570 && (UINTVAL (operands[2])) > 31)
3572 emit_insn (gen_movsi (operands[0], const0_rtx));
3578 (define_expand "rotlsi3"
3579 [(set (match_operand:SI 0 "s_register_operand")
3580 (rotatert:SI (match_operand:SI 1 "s_register_operand")
3581 (match_operand:SI 2 "reg_or_int_operand")))]
3584 if (CONST_INT_P (operands[2]))
3585 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3588 rtx reg = gen_reg_rtx (SImode);
3589 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3595 (define_expand "rotrsi3"
3596 [(set (match_operand:SI 0 "s_register_operand")
3597 (rotatert:SI (match_operand:SI 1 "s_register_operand")
3598 (match_operand:SI 2 "arm_rhs_operand")))]
3603 if (CONST_INT_P (operands[2])
3604 && UINTVAL (operands[2]) > 31)
3605 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3607 else /* TARGET_THUMB1 */
3609 if (CONST_INT_P (operands [2]))
3610 operands [2] = force_reg (SImode, operands[2]);
3615 (define_insn "*arm_shiftsi3"
3616 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
3617 (match_operator:SI 3 "shift_operator"
3618 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
3619 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
3621 "* return arm_output_shift(operands, 0);"
3622 [(set_attr "predicable" "yes")
3623 (set_attr "arch" "t2,t2,*,*")
3624 (set_attr "predicable_short_it" "yes,yes,no,no")
3625 (set_attr "length" "4")
3626 (set_attr "shift" "1")
3627 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
3630 (define_insn "*shiftsi3_compare0"
3631 [(set (reg:CC_NOOV CC_REGNUM)
3632 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3633 [(match_operand:SI 1 "s_register_operand" "r,r")
3634 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3636 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3637 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
3639 "* return arm_output_shift(operands, 1);"
3640 [(set_attr "conds" "set")
3641 (set_attr "shift" "1")
3642 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
3645 (define_insn "*shiftsi3_compare0_scratch"
3646 [(set (reg:CC_NOOV CC_REGNUM)
3647 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3648 [(match_operand:SI 1 "s_register_operand" "r,r")
3649 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3651 (clobber (match_scratch:SI 0 "=r,r"))]
3653 "* return arm_output_shift(operands, 1);"
3654 [(set_attr "conds" "set")
3655 (set_attr "shift" "1")
3656 (set_attr "type" "shift_imm,shift_reg")]
3659 (define_insn "*not_shiftsi"
3660 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3661 (not:SI (match_operator:SI 3 "shift_operator"
3662 [(match_operand:SI 1 "s_register_operand" "r,r")
3663 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3666 [(set_attr "predicable" "yes")
3667 (set_attr "shift" "1")
3668 (set_attr "arch" "32,a")
3669 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3671 (define_insn "*not_shiftsi_compare0"
3672 [(set (reg:CC_NOOV CC_REGNUM)
3674 (not:SI (match_operator:SI 3 "shift_operator"
3675 [(match_operand:SI 1 "s_register_operand" "r,r")
3676 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3678 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3679 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
3681 "mvns%?\\t%0, %1%S3"
3682 [(set_attr "conds" "set")
3683 (set_attr "shift" "1")
3684 (set_attr "arch" "32,a")
3685 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3687 (define_insn "*not_shiftsi_compare0_scratch"
3688 [(set (reg:CC_NOOV CC_REGNUM)
3690 (not:SI (match_operator:SI 3 "shift_operator"
3691 [(match_operand:SI 1 "s_register_operand" "r,r")
3692 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3694 (clobber (match_scratch:SI 0 "=r,r"))]
3696 "mvns%?\\t%0, %1%S3"
3697 [(set_attr "conds" "set")
3698 (set_attr "shift" "1")
3699 (set_attr "arch" "32,a")
3700 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3702 ;; We don't really have extzv, but defining this using shifts helps
3703 ;; to reduce register pressure later on.
3705 (define_expand "extzv"
3706 [(set (match_operand 0 "s_register_operand")
3707 (zero_extract (match_operand 1 "nonimmediate_operand")
3708 (match_operand 2 "const_int_operand")
3709 (match_operand 3 "const_int_operand")))]
3710 "TARGET_THUMB1 || arm_arch_thumb2"
3713 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3714 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3716 if (arm_arch_thumb2)
3718 HOST_WIDE_INT width = INTVAL (operands[2]);
3719 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3721 if (unaligned_access && MEM_P (operands[1])
3722 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
3726 if (BYTES_BIG_ENDIAN)
3727 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
3732 base_addr = adjust_address (operands[1], SImode,
3733 bitpos / BITS_PER_UNIT);
3734 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
3738 rtx dest = operands[0];
3739 rtx tmp = gen_reg_rtx (SImode);
3741 /* We may get a paradoxical subreg here. Strip it off. */
3742 if (GET_CODE (dest) == SUBREG
3743 && GET_MODE (dest) == SImode
3744 && GET_MODE (SUBREG_REG (dest)) == HImode)
3745 dest = SUBREG_REG (dest);
3747 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
3750 base_addr = adjust_address (operands[1], HImode,
3751 bitpos / BITS_PER_UNIT);
3752 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
3753 emit_move_insn (gen_lowpart (SImode, dest), tmp);
3757 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
3759 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
3767 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
3770 operands[3] = GEN_INT (rshift);
3774 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
3778 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
3779 operands[3], gen_reg_rtx (SImode)));
3784 ;; Helper for extzv, for the Thumb-1 register-shifts case.
3786 (define_expand "extzv_t1"
3787 [(set (match_operand:SI 4 "s_register_operand")
3788 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
3789 (match_operand:SI 2 "const_int_operand")))
3790 (set (match_operand:SI 0 "s_register_operand")
3791 (lshiftrt:SI (match_dup 4)
3792 (match_operand:SI 3 "const_int_operand")))]
3796 (define_expand "extv"
3797 [(set (match_operand 0 "s_register_operand")
3798 (sign_extract (match_operand 1 "nonimmediate_operand")
3799 (match_operand 2 "const_int_operand")
3800 (match_operand 3 "const_int_operand")))]
3803 HOST_WIDE_INT width = INTVAL (operands[2]);
3804 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3806 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
3807 && (bitpos % BITS_PER_UNIT) == 0)
3811 if (BYTES_BIG_ENDIAN)
3812 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
3816 base_addr = adjust_address (operands[1], SImode,
3817 bitpos / BITS_PER_UNIT);
3818 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
3822 rtx dest = operands[0];
3823 rtx tmp = gen_reg_rtx (SImode);
3825 /* We may get a paradoxical subreg here. Strip it off. */
3826 if (GET_CODE (dest) == SUBREG
3827 && GET_MODE (dest) == SImode
3828 && GET_MODE (SUBREG_REG (dest)) == HImode)
3829 dest = SUBREG_REG (dest);
3831 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
3834 base_addr = adjust_address (operands[1], HImode,
3835 bitpos / BITS_PER_UNIT);
3836 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
3837 emit_move_insn (gen_lowpart (SImode, dest), tmp);
3842 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
3844 else if (GET_MODE (operands[0]) == SImode
3845 && GET_MODE (operands[1]) == SImode)
3847 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
3855 ; Helper to expand register forms of extv with the proper modes.
3857 (define_expand "extv_regsi"
3858 [(set (match_operand:SI 0 "s_register_operand")
3859 (sign_extract:SI (match_operand:SI 1 "s_register_operand")
3860 (match_operand 2 "const_int_operand")
3861 (match_operand 3 "const_int_operand")))]
3866 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
3868 (define_insn "unaligned_loaddi"
3869 [(set (match_operand:DI 0 "s_register_operand" "=r")
3870 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")]
3871 UNSPEC_UNALIGNED_LOAD))]
3872 "TARGET_32BIT && TARGET_LDRD"
3874 return output_move_double (operands, true, NULL);
3876 [(set_attr "length" "8")
3877 (set_attr "type" "load_8")])
3879 (define_insn "unaligned_loadsi"
3880 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
3881 (unspec:SI [(match_operand:SI 1 "memory_operand" "m,Uw,m")]
3882 UNSPEC_UNALIGNED_LOAD))]
3885 ldr\t%0, %1\t@ unaligned
3886 ldr%?\t%0, %1\t@ unaligned
3887 ldr%?\t%0, %1\t@ unaligned"
3888 [(set_attr "arch" "t1,t2,32")
3889 (set_attr "length" "2,2,4")
3890 (set_attr "predicable" "no,yes,yes")
3891 (set_attr "predicable_short_it" "no,yes,no")
3892 (set_attr "type" "load_4")])
3894 ;; The 16-bit Thumb1 variant of ldrsh requires two registers in the
3895 ;; address (there's no immediate format). That's tricky to support
3896 ;; here and we don't really need this pattern for that case, so only
3897 ;; enable for 32-bit ISAs.
3898 (define_insn "unaligned_loadhis"
3899 [(set (match_operand:SI 0 "s_register_operand" "=r")
3901 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
3902 UNSPEC_UNALIGNED_LOAD)))]
3903 "unaligned_access && TARGET_32BIT"
3904 "ldrsh%?\t%0, %1\t@ unaligned"
3905 [(set_attr "predicable" "yes")
3906 (set_attr "type" "load_byte")])
3908 (define_insn "unaligned_loadhiu"
3909 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
3911 (unspec:HI [(match_operand:HI 1 "memory_operand" "m,Uw,m")]
3912 UNSPEC_UNALIGNED_LOAD)))]
3915 ldrh\t%0, %1\t@ unaligned
3916 ldrh%?\t%0, %1\t@ unaligned
3917 ldrh%?\t%0, %1\t@ unaligned"
3918 [(set_attr "arch" "t1,t2,32")
3919 (set_attr "length" "2,2,4")
3920 (set_attr "predicable" "no,yes,yes")
3921 (set_attr "predicable_short_it" "no,yes,no")
3922 (set_attr "type" "load_byte")])
3924 (define_insn "unaligned_storedi"
3925 [(set (match_operand:DI 0 "memory_operand" "=m")
3926 (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")]
3927 UNSPEC_UNALIGNED_STORE))]
3928 "TARGET_32BIT && TARGET_LDRD"
3930 return output_move_double (operands, true, NULL);
3932 [(set_attr "length" "8")
3933 (set_attr "type" "store_8")])
3935 (define_insn "unaligned_storesi"
3936 [(set (match_operand:SI 0 "memory_operand" "=m,Uw,m")
3937 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,l,r")]
3938 UNSPEC_UNALIGNED_STORE))]
3941 str\t%1, %0\t@ unaligned
3942 str%?\t%1, %0\t@ unaligned
3943 str%?\t%1, %0\t@ unaligned"
3944 [(set_attr "arch" "t1,t2,32")
3945 (set_attr "length" "2,2,4")
3946 (set_attr "predicable" "no,yes,yes")
3947 (set_attr "predicable_short_it" "no,yes,no")
3948 (set_attr "type" "store_4")])
3950 (define_insn "unaligned_storehi"
3951 [(set (match_operand:HI 0 "memory_operand" "=m,Uw,m")
3952 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,l,r")]
3953 UNSPEC_UNALIGNED_STORE))]
3956 strh\t%1, %0\t@ unaligned
3957 strh%?\t%1, %0\t@ unaligned
3958 strh%?\t%1, %0\t@ unaligned"
3959 [(set_attr "arch" "t1,t2,32")
3960 (set_attr "length" "2,2,4")
3961 (set_attr "predicable" "no,yes,yes")
3962 (set_attr "predicable_short_it" "no,yes,no")
3963 (set_attr "type" "store_4")])
3966 (define_insn "*extv_reg"
3967 [(set (match_operand:SI 0 "s_register_operand" "=r")
3968 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
3969 (match_operand:SI 2 "const_int_operand" "n")
3970 (match_operand:SI 3 "const_int_operand" "n")))]
3972 && IN_RANGE (INTVAL (operands[3]), 0, 31)
3973 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
3974 "sbfx%?\t%0, %1, %3, %2"
3975 [(set_attr "length" "4")
3976 (set_attr "predicable" "yes")
3977 (set_attr "type" "bfm")]
3980 (define_insn "extzv_t2"
3981 [(set (match_operand:SI 0 "s_register_operand" "=r")
3982 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
3983 (match_operand:SI 2 "const_int_operand" "n")
3984 (match_operand:SI 3 "const_int_operand" "n")))]
3986 && IN_RANGE (INTVAL (operands[3]), 0, 31)
3987 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
3988 "ubfx%?\t%0, %1, %3, %2"
3989 [(set_attr "length" "4")
3990 (set_attr "predicable" "yes")
3991 (set_attr "type" "bfm")]
3995 ;; Division instructions
3996 (define_insn "divsi3"
3997 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3998 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
3999 (match_operand:SI 2 "s_register_operand" "r,r")))]
4004 [(set_attr "arch" "32,v8mb")
4005 (set_attr "predicable" "yes")
4006 (set_attr "type" "sdiv")]
4009 (define_insn "udivsi3"
4010 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4011 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4012 (match_operand:SI 2 "s_register_operand" "r,r")))]
4017 [(set_attr "arch" "32,v8mb")
4018 (set_attr "predicable" "yes")
4019 (set_attr "type" "udiv")]
4023 ;; Unary arithmetic insns
4025 (define_expand "negvsi3"
4026 [(match_operand:SI 0 "register_operand")
4027 (match_operand:SI 1 "register_operand")
4028 (match_operand 2 "")]
4031 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4032 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4037 (define_expand "negvdi3"
4038 [(match_operand:DI 0 "register_operand")
4039 (match_operand:DI 1 "register_operand")
4040 (match_operand 2 "")]
4043 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4044 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4050 (define_insn_and_split "negdi2_compare"
4051 [(set (reg:CC CC_REGNUM)
4054 (match_operand:DI 1 "register_operand" "0,r")))
4055 (set (match_operand:DI 0 "register_operand" "=r,&r")
4056 (minus:DI (const_int 0) (match_dup 1)))]
4059 "&& reload_completed"
4060 [(parallel [(set (reg:CC CC_REGNUM)
4061 (compare:CC (const_int 0) (match_dup 1)))
4062 (set (match_dup 0) (minus:SI (const_int 0)
4064 (parallel [(set (reg:CC CC_REGNUM)
4065 (compare:CC (const_int 0) (match_dup 3)))
4068 (minus:SI (const_int 0) (match_dup 3))
4069 (ltu:SI (reg:CC CC_REGNUM)
4072 operands[2] = gen_highpart (SImode, operands[0]);
4073 operands[0] = gen_lowpart (SImode, operands[0]);
4074 operands[3] = gen_highpart (SImode, operands[1]);
4075 operands[1] = gen_lowpart (SImode, operands[1]);
4077 [(set_attr "conds" "set")
4078 (set_attr "length" "8")
4079 (set_attr "type" "multiple")]
4082 (define_expand "negdi2"
4084 [(set (match_operand:DI 0 "s_register_operand")
4085 (neg:DI (match_operand:DI 1 "s_register_operand")))
4086 (clobber (reg:CC CC_REGNUM))])]
4090 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4091 ;; The first alternative allows the common case of a *full* overlap.
4092 (define_insn_and_split "*negdi2_insn"
4093 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4094 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4095 (clobber (reg:CC CC_REGNUM))]
4097 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4098 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4100 [(parallel [(set (reg:CC CC_REGNUM)
4101 (compare:CC (const_int 0) (match_dup 1)))
4102 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4103 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4104 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
4106 operands[2] = gen_highpart (SImode, operands[0]);
4107 operands[0] = gen_lowpart (SImode, operands[0]);
4108 operands[3] = gen_highpart (SImode, operands[1]);
4109 operands[1] = gen_lowpart (SImode, operands[1]);
4111 [(set_attr "conds" "clob")
4112 (set_attr "length" "8")
4113 (set_attr "type" "multiple")]
4116 (define_insn "*negsi2_carryin_compare"
4117 [(set (reg:CC CC_REGNUM)
4118 (compare:CC (const_int 0)
4119 (match_operand:SI 1 "s_register_operand" "r")))
4120 (set (match_operand:SI 0 "s_register_operand" "=r")
4121 (minus:SI (minus:SI (const_int 0)
4123 (match_operand:SI 2 "arm_borrow_operation" "")))]
4126 [(set_attr "conds" "set")
4127 (set_attr "type" "alus_imm")]
4130 (define_expand "negsi2"
4131 [(set (match_operand:SI 0 "s_register_operand")
4132 (neg:SI (match_operand:SI 1 "s_register_operand")))]
4137 (define_insn "*arm_negsi2"
4138 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4139 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4141 "rsb%?\\t%0, %1, #0"
4142 [(set_attr "predicable" "yes")
4143 (set_attr "predicable_short_it" "yes,no")
4144 (set_attr "arch" "t2,*")
4145 (set_attr "length" "4")
4146 (set_attr "type" "alu_sreg")]
4149 (define_expand "negsf2"
4150 [(set (match_operand:SF 0 "s_register_operand")
4151 (neg:SF (match_operand:SF 1 "s_register_operand")))]
4152 "TARGET_32BIT && TARGET_HARD_FLOAT"
4156 (define_expand "negdf2"
4157 [(set (match_operand:DF 0 "s_register_operand")
4158 (neg:DF (match_operand:DF 1 "s_register_operand")))]
4159 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4162 (define_insn_and_split "*zextendsidi_negsi"
4163 [(set (match_operand:DI 0 "s_register_operand" "=r")
4164 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4169 (neg:SI (match_dup 1)))
4173 operands[2] = gen_lowpart (SImode, operands[0]);
4174 operands[3] = gen_highpart (SImode, operands[0]);
4176 [(set_attr "length" "8")
4177 (set_attr "type" "multiple")]
4180 ;; Negate an extended 32-bit value.
4181 (define_insn_and_split "*negdi_extendsidi"
4182 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4183 (neg:DI (sign_extend:DI
4184 (match_operand:SI 1 "s_register_operand" "l,r"))))
4185 (clobber (reg:CC CC_REGNUM))]
4188 "&& reload_completed"
4191 rtx low = gen_lowpart (SImode, operands[0]);
4192 rtx high = gen_highpart (SImode, operands[0]);
4194 if (reg_overlap_mentioned_p (low, operands[1]))
4196 /* Input overlaps the low word of the output. Use:
4199 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4200 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
4202 emit_insn (gen_rtx_SET (high,
4203 gen_rtx_ASHIFTRT (SImode, operands[1],
4206 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4208 emit_insn (gen_rtx_SET (high,
4209 gen_rtx_MINUS (SImode,
4210 gen_rtx_MINUS (SImode,
4213 gen_rtx_LTU (SImode,
4218 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4219 emit_insn (gen_rtx_SET (high,
4220 gen_rtx_MINUS (SImode,
4221 gen_rtx_MINUS (SImode,
4224 gen_rtx_LTU (SImode,
4231 /* No overlap, or overlap on high word. Use:
4235 Flags not needed for this sequence. */
4236 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4237 emit_insn (gen_rtx_SET (high,
4238 gen_rtx_AND (SImode,
4239 gen_rtx_NOT (SImode, operands[1]),
4241 emit_insn (gen_rtx_SET (high,
4242 gen_rtx_ASHIFTRT (SImode, high,
4247 [(set_attr "length" "12")
4248 (set_attr "arch" "t2,*")
4249 (set_attr "type" "multiple")]
4252 (define_insn_and_split "*negdi_zero_extendsidi"
4253 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4254 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4255 (clobber (reg:CC CC_REGNUM))]
4257 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4258 ;; Don't care what register is input to sbc,
4259 ;; since we just need to propagate the carry.
4260 "&& reload_completed"
4261 [(parallel [(set (reg:CC CC_REGNUM)
4262 (compare:CC (const_int 0) (match_dup 1)))
4263 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4264 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4265 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
4267 operands[2] = gen_highpart (SImode, operands[0]);
4268 operands[0] = gen_lowpart (SImode, operands[0]);
4270 [(set_attr "conds" "clob")
4271 (set_attr "length" "8")
4272 (set_attr "type" "multiple")] ;; length in thumb is 4
4275 ;; abssi2 doesn't really clobber the condition codes if a different register
4276 ;; is being set. To keep things simple, assume during rtl manipulations that
4277 ;; it does, but tell the final scan operator the truth. Similarly for
4280 (define_expand "abssi2"
4282 [(set (match_operand:SI 0 "s_register_operand")
4283 (abs:SI (match_operand:SI 1 "s_register_operand")))
4284 (clobber (match_dup 2))])]
4288 operands[2] = gen_rtx_SCRATCH (SImode);
4290 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4293 (define_insn_and_split "*arm_abssi2"
4294 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4295 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4296 (clobber (reg:CC CC_REGNUM))]
4299 "&& reload_completed"
4302 /* if (which_alternative == 0) */
4303 if (REGNO(operands[0]) == REGNO(operands[1]))
4305 /* Emit the pattern:
4306 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4307 [(set (reg:CC CC_REGNUM)
4308 (compare:CC (match_dup 0) (const_int 0)))
4309 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4310 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4312 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4313 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4314 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4315 (gen_rtx_LT (SImode,
4316 gen_rtx_REG (CCmode, CC_REGNUM),
4318 (gen_rtx_SET (operands[0],
4319 (gen_rtx_MINUS (SImode,
4326 /* Emit the pattern:
4327 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4329 (xor:SI (match_dup 1)
4330 (ashiftrt:SI (match_dup 1) (const_int 31))))
4332 (minus:SI (match_dup 0)
4333 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4335 emit_insn (gen_rtx_SET (operands[0],
4336 gen_rtx_XOR (SImode,
4337 gen_rtx_ASHIFTRT (SImode,
4341 emit_insn (gen_rtx_SET (operands[0],
4342 gen_rtx_MINUS (SImode,
4344 gen_rtx_ASHIFTRT (SImode,
4350 [(set_attr "conds" "clob,*")
4351 (set_attr "shift" "1")
4352 (set_attr "predicable" "no, yes")
4353 (set_attr "length" "8")
4354 (set_attr "type" "multiple")]
4357 (define_insn_and_split "*arm_neg_abssi2"
4358 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4359 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4360 (clobber (reg:CC CC_REGNUM))]
4363 "&& reload_completed"
4366 /* if (which_alternative == 0) */
4367 if (REGNO (operands[0]) == REGNO (operands[1]))
4369 /* Emit the pattern:
4370 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4372 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4373 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4374 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4376 gen_rtx_REG (CCmode, CC_REGNUM),
4378 gen_rtx_SET (operands[0],
4379 (gen_rtx_MINUS (SImode,
4385 /* Emit the pattern:
4386 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4388 emit_insn (gen_rtx_SET (operands[0],
4389 gen_rtx_XOR (SImode,
4390 gen_rtx_ASHIFTRT (SImode,
4394 emit_insn (gen_rtx_SET (operands[0],
4395 gen_rtx_MINUS (SImode,
4396 gen_rtx_ASHIFTRT (SImode,
4403 [(set_attr "conds" "clob,*")
4404 (set_attr "shift" "1")
4405 (set_attr "predicable" "no, yes")
4406 (set_attr "length" "8")
4407 (set_attr "type" "multiple")]
4410 (define_expand "abssf2"
4411 [(set (match_operand:SF 0 "s_register_operand")
4412 (abs:SF (match_operand:SF 1 "s_register_operand")))]
4413 "TARGET_32BIT && TARGET_HARD_FLOAT"
4416 (define_expand "absdf2"
4417 [(set (match_operand:DF 0 "s_register_operand")
4418 (abs:DF (match_operand:DF 1 "s_register_operand")))]
4419 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4422 (define_expand "sqrtsf2"
4423 [(set (match_operand:SF 0 "s_register_operand")
4424 (sqrt:SF (match_operand:SF 1 "s_register_operand")))]
4425 "TARGET_32BIT && TARGET_HARD_FLOAT"
4428 (define_expand "sqrtdf2"
4429 [(set (match_operand:DF 0 "s_register_operand")
4430 (sqrt:DF (match_operand:DF 1 "s_register_operand")))]
4431 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4434 (define_expand "one_cmplsi2"
4435 [(set (match_operand:SI 0 "s_register_operand")
4436 (not:SI (match_operand:SI 1 "s_register_operand")))]
4441 (define_insn "*arm_one_cmplsi2"
4442 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4443 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4446 [(set_attr "predicable" "yes")
4447 (set_attr "predicable_short_it" "yes,no")
4448 (set_attr "arch" "t2,*")
4449 (set_attr "length" "4")
4450 (set_attr "type" "mvn_reg")]
4453 (define_insn "*notsi_compare0"
4454 [(set (reg:CC_NOOV CC_REGNUM)
4455 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4457 (set (match_operand:SI 0 "s_register_operand" "=r")
4458 (not:SI (match_dup 1)))]
4461 [(set_attr "conds" "set")
4462 (set_attr "type" "mvn_reg")]
4465 (define_insn "*notsi_compare0_scratch"
4466 [(set (reg:CC_NOOV CC_REGNUM)
4467 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4469 (clobber (match_scratch:SI 0 "=r"))]
4472 [(set_attr "conds" "set")
4473 (set_attr "type" "mvn_reg")]
4476 ;; Fixed <--> Floating conversion insns
4478 (define_expand "floatsihf2"
4479 [(set (match_operand:HF 0 "general_operand")
4480 (float:HF (match_operand:SI 1 "general_operand")))]
4484 rtx op1 = gen_reg_rtx (SFmode);
4485 expand_float (op1, operands[1], 0);
4486 op1 = convert_to_mode (HFmode, op1, 0);
4487 emit_move_insn (operands[0], op1);
4492 (define_expand "floatdihf2"
4493 [(set (match_operand:HF 0 "general_operand")
4494 (float:HF (match_operand:DI 1 "general_operand")))]
4498 rtx op1 = gen_reg_rtx (SFmode);
4499 expand_float (op1, operands[1], 0);
4500 op1 = convert_to_mode (HFmode, op1, 0);
4501 emit_move_insn (operands[0], op1);
4506 (define_expand "floatsisf2"
4507 [(set (match_operand:SF 0 "s_register_operand")
4508 (float:SF (match_operand:SI 1 "s_register_operand")))]
4509 "TARGET_32BIT && TARGET_HARD_FLOAT"
4513 (define_expand "floatsidf2"
4514 [(set (match_operand:DF 0 "s_register_operand")
4515 (float:DF (match_operand:SI 1 "s_register_operand")))]
4516 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4520 (define_expand "fix_trunchfsi2"
4521 [(set (match_operand:SI 0 "general_operand")
4522 (fix:SI (fix:HF (match_operand:HF 1 "general_operand"))))]
4526 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4527 expand_fix (operands[0], op1, 0);
4532 (define_expand "fix_trunchfdi2"
4533 [(set (match_operand:DI 0 "general_operand")
4534 (fix:DI (fix:HF (match_operand:HF 1 "general_operand"))))]
4538 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4539 expand_fix (operands[0], op1, 0);
4544 (define_expand "fix_truncsfsi2"
4545 [(set (match_operand:SI 0 "s_register_operand")
4546 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"))))]
4547 "TARGET_32BIT && TARGET_HARD_FLOAT"
4551 (define_expand "fix_truncdfsi2"
4552 [(set (match_operand:SI 0 "s_register_operand")
4553 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"))))]
4554 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4560 (define_expand "truncdfsf2"
4561 [(set (match_operand:SF 0 "s_register_operand")
4563 (match_operand:DF 1 "s_register_operand")))]
4564 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4568 ;; DFmode to HFmode conversions on targets without a single-step hardware
4569 ;; instruction for it would have to go through SFmode. This is dangerous
4570 ;; as it introduces double rounding.
4572 ;; Disable this pattern unless we are in an unsafe math mode, or we have
4573 ;; a single-step instruction.
4575 (define_expand "truncdfhf2"
4576 [(set (match_operand:HF 0 "s_register_operand")
4578 (match_operand:DF 1 "s_register_operand")))]
4579 "(TARGET_EITHER && flag_unsafe_math_optimizations)
4580 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
4582 /* We don't have a direct instruction for this, so we must be in
4583 an unsafe math mode, and going via SFmode. */
4585 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
4588 op1 = convert_to_mode (SFmode, operands[1], 0);
4589 op1 = convert_to_mode (HFmode, op1, 0);
4590 emit_move_insn (operands[0], op1);
4593 /* Otherwise, we will pick this up as a single instruction with
4594 no intermediary rounding. */
4598 ;; Zero and sign extension instructions.
4600 (define_insn "zero_extend<mode>di2"
4601 [(set (match_operand:DI 0 "s_register_operand" "=r,?r")
4602 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4603 "<qhs_zextenddi_cstr>")))]
4604 "TARGET_32BIT <qhs_zextenddi_cond>"
4606 [(set_attr "length" "4,8")
4607 (set_attr "arch" "*,*")
4608 (set_attr "ce_count" "2")
4609 (set_attr "predicable" "yes")
4610 (set_attr "type" "mov_reg,multiple")]
4613 (define_insn "extend<mode>di2"
4614 [(set (match_operand:DI 0 "s_register_operand" "=r,?r,?r")
4615 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4616 "<qhs_extenddi_cstr>")))]
4617 "TARGET_32BIT <qhs_sextenddi_cond>"
4619 [(set_attr "length" "4,8,8")
4620 (set_attr "ce_count" "2")
4621 (set_attr "shift" "1")
4622 (set_attr "predicable" "yes")
4623 (set_attr "arch" "*,a,t")
4624 (set_attr "type" "mov_reg,multiple,multiple")]
4627 ;; Splits for all extensions to DImode
4629 [(set (match_operand:DI 0 "s_register_operand" "")
4630 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4632 [(set (match_dup 0) (match_dup 1))]
4634 rtx lo_part = gen_lowpart (SImode, operands[0]);
4635 machine_mode src_mode = GET_MODE (operands[1]);
4637 if (src_mode == SImode)
4638 emit_move_insn (lo_part, operands[1]);
4640 emit_insn (gen_rtx_SET (lo_part,
4641 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4642 operands[0] = gen_highpart (SImode, operands[0]);
4643 operands[1] = const0_rtx;
4647 [(set (match_operand:DI 0 "s_register_operand" "")
4648 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4650 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4652 rtx lo_part = gen_lowpart (SImode, operands[0]);
4653 machine_mode src_mode = GET_MODE (operands[1]);
4655 if (src_mode == SImode)
4656 emit_move_insn (lo_part, operands[1]);
4658 emit_insn (gen_rtx_SET (lo_part,
4659 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4660 operands[1] = lo_part;
4661 operands[0] = gen_highpart (SImode, operands[0]);
4664 (define_expand "zero_extendhisi2"
4665 [(set (match_operand:SI 0 "s_register_operand")
4666 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
4669 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4671 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4674 if (!arm_arch6 && !MEM_P (operands[1]))
4676 rtx t = gen_lowpart (SImode, operands[1]);
4677 rtx tmp = gen_reg_rtx (SImode);
4678 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4679 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4685 [(set (match_operand:SI 0 "s_register_operand" "")
4686 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4687 "!TARGET_THUMB2 && !arm_arch6"
4688 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4689 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4691 operands[2] = gen_lowpart (SImode, operands[1]);
4694 (define_insn "*arm_zero_extendhisi2"
4695 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4696 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4697 "TARGET_ARM && arm_arch4 && !arm_arch6"
4701 [(set_attr "type" "alu_shift_reg,load_byte")
4702 (set_attr "predicable" "yes")]
4705 (define_insn "*arm_zero_extendhisi2_v6"
4706 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4707 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4708 "TARGET_ARM && arm_arch6"
4712 [(set_attr "predicable" "yes")
4713 (set_attr "type" "extend,load_byte")]
4716 (define_insn "*arm_zero_extendhisi2addsi"
4717 [(set (match_operand:SI 0 "s_register_operand" "=r")
4718 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4719 (match_operand:SI 2 "s_register_operand" "r")))]
4721 "uxtah%?\\t%0, %2, %1"
4722 [(set_attr "type" "alu_shift_reg")
4723 (set_attr "predicable" "yes")]
4726 (define_expand "zero_extendqisi2"
4727 [(set (match_operand:SI 0 "s_register_operand")
4728 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
4731 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
4733 emit_insn (gen_andsi3 (operands[0],
4734 gen_lowpart (SImode, operands[1]),
4738 if (!arm_arch6 && !MEM_P (operands[1]))
4740 rtx t = gen_lowpart (SImode, operands[1]);
4741 rtx tmp = gen_reg_rtx (SImode);
4742 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
4743 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
4749 [(set (match_operand:SI 0 "s_register_operand" "")
4750 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
4752 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4753 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
4755 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
4758 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
4763 (define_insn "*arm_zero_extendqisi2"
4764 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4765 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
4766 "TARGET_ARM && !arm_arch6"
4769 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
4770 [(set_attr "length" "8,4")
4771 (set_attr "type" "alu_shift_reg,load_byte")
4772 (set_attr "predicable" "yes")]
4775 (define_insn "*arm_zero_extendqisi2_v6"
4776 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4777 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
4778 "TARGET_ARM && arm_arch6"
4781 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
4782 [(set_attr "type" "extend,load_byte")
4783 (set_attr "predicable" "yes")]
4786 (define_insn "*arm_zero_extendqisi2addsi"
4787 [(set (match_operand:SI 0 "s_register_operand" "=r")
4788 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
4789 (match_operand:SI 2 "s_register_operand" "r")))]
4791 "uxtab%?\\t%0, %2, %1"
4792 [(set_attr "predicable" "yes")
4793 (set_attr "type" "alu_shift_reg")]
4797 [(set (match_operand:SI 0 "s_register_operand" "")
4798 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
4799 (clobber (match_operand:SI 2 "s_register_operand" ""))]
4800 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
4801 [(set (match_dup 2) (match_dup 1))
4802 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
4807 [(set (match_operand:SI 0 "s_register_operand" "")
4808 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
4809 (clobber (match_operand:SI 2 "s_register_operand" ""))]
4810 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
4811 [(set (match_dup 2) (match_dup 1))
4812 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
4818 [(set (match_operand:SI 0 "s_register_operand" "")
4819 (IOR_XOR:SI (and:SI (ashift:SI
4820 (match_operand:SI 1 "s_register_operand" "")
4821 (match_operand:SI 2 "const_int_operand" ""))
4822 (match_operand:SI 3 "const_int_operand" ""))
4824 (match_operator 5 "subreg_lowpart_operator"
4825 [(match_operand:SI 4 "s_register_operand" "")]))))]
4827 && (UINTVAL (operands[3])
4828 == (GET_MODE_MASK (GET_MODE (operands[5]))
4829 & (GET_MODE_MASK (GET_MODE (operands[5]))
4830 << (INTVAL (operands[2])))))"
4831 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
4833 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
4834 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
4837 (define_insn "*compareqi_eq0"
4838 [(set (reg:CC_Z CC_REGNUM)
4839 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
4843 [(set_attr "conds" "set")
4844 (set_attr "predicable" "yes")
4845 (set_attr "type" "logic_imm")]
4848 (define_expand "extendhisi2"
4849 [(set (match_operand:SI 0 "s_register_operand")
4850 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
4855 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
4858 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
4860 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
4864 if (!arm_arch6 && !MEM_P (operands[1]))
4866 rtx t = gen_lowpart (SImode, operands[1]);
4867 rtx tmp = gen_reg_rtx (SImode);
4868 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4869 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
4876 [(set (match_operand:SI 0 "register_operand" "")
4877 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
4878 (clobber (match_scratch:SI 2 ""))])]
4880 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4881 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4883 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
4886 ;; This pattern will only be used when ldsh is not available
4887 (define_expand "extendhisi2_mem"
4888 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
4890 (zero_extend:SI (match_dup 7)))
4891 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
4892 (set (match_operand:SI 0 "" "")
4893 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
4898 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
4900 mem1 = change_address (operands[1], QImode, addr);
4901 mem2 = change_address (operands[1], QImode,
4902 plus_constant (Pmode, addr, 1));
4903 operands[0] = gen_lowpart (SImode, operands[0]);
4905 operands[2] = gen_reg_rtx (SImode);
4906 operands[3] = gen_reg_rtx (SImode);
4907 operands[6] = gen_reg_rtx (SImode);
4910 if (BYTES_BIG_ENDIAN)
4912 operands[4] = operands[2];
4913 operands[5] = operands[3];
4917 operands[4] = operands[3];
4918 operands[5] = operands[2];
4924 [(set (match_operand:SI 0 "register_operand" "")
4925 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4927 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4928 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4930 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
4933 (define_insn "*arm_extendhisi2"
4934 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4935 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4936 "TARGET_ARM && arm_arch4 && !arm_arch6"
4940 [(set_attr "length" "8,4")
4941 (set_attr "type" "alu_shift_reg,load_byte")
4942 (set_attr "predicable" "yes")]
4945 ;; ??? Check Thumb-2 pool range
4946 (define_insn "*arm_extendhisi2_v6"
4947 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4948 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4949 "TARGET_32BIT && arm_arch6"
4953 [(set_attr "type" "extend,load_byte")
4954 (set_attr "predicable" "yes")]
4957 (define_insn "*arm_extendhisi2addsi"
4958 [(set (match_operand:SI 0 "s_register_operand" "=r")
4959 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4960 (match_operand:SI 2 "s_register_operand" "r")))]
4962 "sxtah%?\\t%0, %2, %1"
4963 [(set_attr "type" "alu_shift_reg")]
4966 (define_expand "extendqihi2"
4968 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op")
4970 (set (match_operand:HI 0 "s_register_operand")
4971 (ashiftrt:SI (match_dup 2)
4976 if (arm_arch4 && MEM_P (operands[1]))
4978 emit_insn (gen_rtx_SET (operands[0],
4979 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
4982 if (!s_register_operand (operands[1], QImode))
4983 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4984 operands[0] = gen_lowpart (SImode, operands[0]);
4985 operands[1] = gen_lowpart (SImode, operands[1]);
4986 operands[2] = gen_reg_rtx (SImode);
4990 (define_insn "*arm_extendqihi_insn"
4991 [(set (match_operand:HI 0 "s_register_operand" "=r")
4992 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
4993 "TARGET_ARM && arm_arch4"
4995 [(set_attr "type" "load_byte")
4996 (set_attr "predicable" "yes")]
4999 (define_expand "extendqisi2"
5000 [(set (match_operand:SI 0 "s_register_operand")
5001 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op")))]
5004 if (!arm_arch4 && MEM_P (operands[1]))
5005 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5007 if (!arm_arch6 && !MEM_P (operands[1]))
5009 rtx t = gen_lowpart (SImode, operands[1]);
5010 rtx tmp = gen_reg_rtx (SImode);
5011 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5012 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5018 [(set (match_operand:SI 0 "register_operand" "")
5019 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5021 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5022 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5024 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5027 (define_insn "*arm_extendqisi"
5028 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5029 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5030 "TARGET_ARM && arm_arch4 && !arm_arch6"
5034 [(set_attr "length" "8,4")
5035 (set_attr "type" "alu_shift_reg,load_byte")
5036 (set_attr "predicable" "yes")]
5039 (define_insn "*arm_extendqisi_v6"
5040 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5042 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5043 "TARGET_ARM && arm_arch6"
5047 [(set_attr "type" "extend,load_byte")
5048 (set_attr "predicable" "yes")]
5051 (define_insn "*arm_extendqisi2addsi"
5052 [(set (match_operand:SI 0 "s_register_operand" "=r")
5053 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5054 (match_operand:SI 2 "s_register_operand" "r")))]
5056 "sxtab%?\\t%0, %2, %1"
5057 [(set_attr "type" "alu_shift_reg")
5058 (set_attr "predicable" "yes")]
5061 (define_insn "arm_<sup>xtb16"
5062 [(set (match_operand:SI 0 "s_register_operand" "=r")
5064 [(match_operand:SI 1 "s_register_operand" "r")] USXTB16))]
5066 "<sup>xtb16%?\\t%0, %1"
5067 [(set_attr "predicable" "yes")
5068 (set_attr "type" "alu_dsp_reg")])
5070 (define_insn "arm_<simd32_op>"
5071 [(set (match_operand:SI 0 "s_register_operand" "=r")
5073 [(match_operand:SI 1 "s_register_operand" "r")
5074 (match_operand:SI 2 "s_register_operand" "r")] SIMD32_NOGE_BINOP))]
5076 "<simd32_op>%?\\t%0, %1, %2"
5077 [(set_attr "predicable" "yes")
5078 (set_attr "type" "alu_dsp_reg")])
5080 (define_insn "arm_usada8"
5081 [(set (match_operand:SI 0 "s_register_operand" "=r")
5083 [(match_operand:SI 1 "s_register_operand" "r")
5084 (match_operand:SI 2 "s_register_operand" "r")
5085 (match_operand:SI 3 "s_register_operand" "r")] UNSPEC_USADA8))]
5087 "usada8%?\\t%0, %1, %2, %3"
5088 [(set_attr "predicable" "yes")
5089 (set_attr "type" "alu_dsp_reg")])
5091 (define_insn "arm_<simd32_op>"
5092 [(set (match_operand:DI 0 "s_register_operand" "=r")
5094 [(match_operand:SI 1 "s_register_operand" "r")
5095 (match_operand:SI 2 "s_register_operand" "r")
5096 (match_operand:DI 3 "s_register_operand" "0")] SIMD32_DIMODE))]
5098 "<simd32_op>%?\\t%Q0, %R0, %1, %2"
5099 [(set_attr "predicable" "yes")
5100 (set_attr "type" "smlald")])
5102 (define_expand "extendsfdf2"
5103 [(set (match_operand:DF 0 "s_register_operand")
5104 (float_extend:DF (match_operand:SF 1 "s_register_operand")))]
5105 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5109 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5110 ;; must go through SFmode.
5112 ;; This is always safe for an extend.
5114 (define_expand "extendhfdf2"
5115 [(set (match_operand:DF 0 "s_register_operand")
5116 (float_extend:DF (match_operand:HF 1 "s_register_operand")))]
5119 /* We don't have a direct instruction for this, so go via SFmode. */
5120 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5123 op1 = convert_to_mode (SFmode, operands[1], 0);
5124 op1 = convert_to_mode (DFmode, op1, 0);
5125 emit_insn (gen_movdf (operands[0], op1));
5128 /* Otherwise, we're done producing RTL and will pick up the correct
5129 pattern to do this with one rounding-step in a single instruction. */
5133 ;; Move insns (including loads and stores)
5135 ;; XXX Just some ideas about movti.
5136 ;; I don't think these are a good idea on the arm, there just aren't enough
5138 ;;(define_expand "loadti"
5139 ;; [(set (match_operand:TI 0 "s_register_operand")
5140 ;; (mem:TI (match_operand:SI 1 "address_operand")))]
5143 ;;(define_expand "storeti"
5144 ;; [(set (mem:TI (match_operand:TI 0 "address_operand"))
5145 ;; (match_operand:TI 1 "s_register_operand"))]
5148 ;;(define_expand "movti"
5149 ;; [(set (match_operand:TI 0 "general_operand")
5150 ;; (match_operand:TI 1 "general_operand"))]
5156 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5157 ;; operands[1] = copy_to_reg (operands[1]);
5158 ;; if (MEM_P (operands[0]))
5159 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5160 ;; else if (MEM_P (operands[1]))
5161 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5165 ;; emit_insn (insn);
5169 ;; Recognize garbage generated above.
5172 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5173 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5177 ;; register mem = (which_alternative < 3);
5178 ;; register const char *template;
5180 ;; operands[mem] = XEXP (operands[mem], 0);
5181 ;; switch (which_alternative)
5183 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5184 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5185 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5186 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5187 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5188 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5190 ;; output_asm_insn (template, operands);
5194 (define_expand "movdi"
5195 [(set (match_operand:DI 0 "general_operand")
5196 (match_operand:DI 1 "general_operand"))]
5199 gcc_checking_assert (aligned_operand (operands[0], DImode));
5200 gcc_checking_assert (aligned_operand (operands[1], DImode));
5201 if (can_create_pseudo_p ())
5203 if (!REG_P (operands[0]))
5204 operands[1] = force_reg (DImode, operands[1]);
5206 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5207 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5209 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5210 when expanding function calls. */
5211 gcc_assert (can_create_pseudo_p ());
5212 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5214 /* Perform load into legal reg pair first, then move. */
5215 rtx reg = gen_reg_rtx (DImode);
5216 emit_insn (gen_movdi (reg, operands[1]));
5219 emit_move_insn (gen_lowpart (SImode, operands[0]),
5220 gen_lowpart (SImode, operands[1]));
5221 emit_move_insn (gen_highpart (SImode, operands[0]),
5222 gen_highpart (SImode, operands[1]));
5225 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5226 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5228 /* Avoid STRD's from an odd-numbered register pair in ARM state
5229 when expanding function prologue. */
5230 gcc_assert (can_create_pseudo_p ());
5231 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5232 ? gen_reg_rtx (DImode)
5234 emit_move_insn (gen_lowpart (SImode, split_dest),
5235 gen_lowpart (SImode, operands[1]));
5236 emit_move_insn (gen_highpart (SImode, split_dest),
5237 gen_highpart (SImode, operands[1]));
5238 if (split_dest != operands[0])
5239 emit_insn (gen_movdi (operands[0], split_dest));
5245 (define_insn "*arm_movdi"
5246 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
5247 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
5249 && !(TARGET_HARD_FLOAT)
5251 && ( register_operand (operands[0], DImode)
5252 || register_operand (operands[1], DImode))"
5254 switch (which_alternative)
5261 /* Cannot load it directly, split to load it via MOV / MOVT. */
5262 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
5266 return output_move_double (operands, true, NULL);
5269 [(set_attr "length" "8,12,16,8,8")
5270 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5271 (set_attr "arm_pool_range" "*,*,*,1020,*")
5272 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5273 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5274 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5278 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5279 (match_operand:ANY64 1 "immediate_operand" ""))]
5282 && (arm_disable_literal_pool
5283 || (arm_const_double_inline_cost (operands[1])
5284 <= arm_max_const_double_inline_cost ()))"
5287 arm_split_constant (SET, SImode, curr_insn,
5288 INTVAL (gen_lowpart (SImode, operands[1])),
5289 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5290 arm_split_constant (SET, SImode, curr_insn,
5291 INTVAL (gen_highpart_mode (SImode,
5292 GET_MODE (operands[0]),
5294 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5299 ; If optimizing for size, or if we have load delay slots, then
5300 ; we want to split the constant into two separate operations.
5301 ; In both cases this may split a trivial part into a single data op
5302 ; leaving a single complex constant to load. We can also get longer
5303 ; offsets in a LDR which means we get better chances of sharing the pool
5304 ; entries. Finally, we can normally do a better job of scheduling
5305 ; LDR instructions than we can with LDM.
5306 ; This pattern will only match if the one above did not.
5308 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5309 (match_operand:ANY64 1 "const_double_operand" ""))]
5310 "TARGET_ARM && reload_completed
5311 && arm_const_double_by_parts (operands[1])"
5312 [(set (match_dup 0) (match_dup 1))
5313 (set (match_dup 2) (match_dup 3))]
5315 operands[2] = gen_highpart (SImode, operands[0]);
5316 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5318 operands[0] = gen_lowpart (SImode, operands[0]);
5319 operands[1] = gen_lowpart (SImode, operands[1]);
5324 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5325 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5326 "TARGET_EITHER && reload_completed"
5327 [(set (match_dup 0) (match_dup 1))
5328 (set (match_dup 2) (match_dup 3))]
5330 operands[2] = gen_highpart (SImode, operands[0]);
5331 operands[3] = gen_highpart (SImode, operands[1]);
5332 operands[0] = gen_lowpart (SImode, operands[0]);
5333 operands[1] = gen_lowpart (SImode, operands[1]);
5335 /* Handle a partial overlap. */
5336 if (rtx_equal_p (operands[0], operands[3]))
5338 rtx tmp0 = operands[0];
5339 rtx tmp1 = operands[1];
5341 operands[0] = operands[2];
5342 operands[1] = operands[3];
5349 ;; We can't actually do base+index doubleword loads if the index and
5350 ;; destination overlap. Split here so that we at least have chance to
5353 [(set (match_operand:DI 0 "s_register_operand" "")
5354 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5355 (match_operand:SI 2 "s_register_operand" ""))))]
5357 && reg_overlap_mentioned_p (operands[0], operands[1])
5358 && reg_overlap_mentioned_p (operands[0], operands[2])"
5360 (plus:SI (match_dup 1)
5363 (mem:DI (match_dup 4)))]
5365 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5369 (define_expand "movsi"
5370 [(set (match_operand:SI 0 "general_operand")
5371 (match_operand:SI 1 "general_operand"))]
5375 rtx base, offset, tmp;
5377 gcc_checking_assert (aligned_operand (operands[0], SImode));
5378 gcc_checking_assert (aligned_operand (operands[1], SImode));
5379 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5381 /* Everything except mem = const or mem = mem can be done easily. */
5382 if (MEM_P (operands[0]))
5383 operands[1] = force_reg (SImode, operands[1]);
5384 if (arm_general_register_operand (operands[0], SImode)
5385 && CONST_INT_P (operands[1])
5386 && !(const_ok_for_arm (INTVAL (operands[1]))
5387 || const_ok_for_arm (~INTVAL (operands[1]))))
5389 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5391 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5396 arm_split_constant (SET, SImode, NULL_RTX,
5397 INTVAL (operands[1]), operands[0], NULL_RTX,
5398 optimize && can_create_pseudo_p ());
5403 else /* Target doesn't have MOVT... */
5405 if (can_create_pseudo_p ())
5407 if (!REG_P (operands[0]))
5408 operands[1] = force_reg (SImode, operands[1]);
5412 split_const (operands[1], &base, &offset);
5413 if (INTVAL (offset) != 0
5414 && targetm.cannot_force_const_mem (SImode, operands[1]))
5416 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5417 emit_move_insn (tmp, base);
5418 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5422 tmp = can_create_pseudo_p () ? NULL_RTX : operands[0];
5424 /* Recognize the case where operand[1] is a reference to thread-local
5425 data and load its address to a register. Offsets have been split off
5427 if (arm_tls_referenced_p (operands[1]))
5428 operands[1] = legitimize_tls_address (operands[1], tmp);
5430 && (CONSTANT_P (operands[1])
5431 || symbol_mentioned_p (operands[1])
5432 || label_mentioned_p (operands[1])))
5434 legitimize_pic_address (operands[1], SImode, tmp, NULL_RTX, false);
5439 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5440 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5441 ;; so this does not matter.
5442 (define_insn "*arm_movt"
5443 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
5444 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5445 (match_operand:SI 2 "general_operand" "i,i")))]
5446 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
5448 movt%?\t%0, #:upper16:%c2
5449 movt\t%0, #:upper16:%c2"
5450 [(set_attr "arch" "32,v8mb")
5451 (set_attr "predicable" "yes")
5452 (set_attr "length" "4")
5453 (set_attr "type" "alu_sreg")]
5456 (define_insn "*arm_movsi_insn"
5457 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5458 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
5459 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
5460 && ( register_operand (operands[0], SImode)
5461 || register_operand (operands[1], SImode))"
5469 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
5470 (set_attr "predicable" "yes")
5471 (set_attr "arch" "*,*,*,v6t2,*,*")
5472 (set_attr "pool_range" "*,*,*,*,4096,*")
5473 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5477 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5478 (match_operand:SI 1 "const_int_operand" ""))]
5479 "(TARGET_32BIT || TARGET_HAVE_MOVT)
5480 && (!(const_ok_for_arm (INTVAL (operands[1]))
5481 || const_ok_for_arm (~INTVAL (operands[1]))))"
5482 [(clobber (const_int 0))]
5484 arm_split_constant (SET, SImode, NULL_RTX,
5485 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5490 ;; A normal way to do (symbol + offset) requires three instructions at least
5491 ;; (depends on how big the offset is) as below:
5492 ;; movw r0, #:lower16:g
5493 ;; movw r0, #:upper16:g
5496 ;; A better way would be:
5497 ;; movw r0, #:lower16:g+4
5498 ;; movw r0, #:upper16:g+4
5500 ;; The limitation of this way is that the length of offset should be a 16-bit
5501 ;; signed value, because current assembler only supports REL type relocation for
5502 ;; such case. If the more powerful RELA type is supported in future, we should
5503 ;; update this pattern to go with better way.
5505 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5506 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5507 (match_operand:SI 2 "const_int_operand" ""))))]
5510 && arm_disable_literal_pool
5512 && GET_CODE (operands[1]) == SYMBOL_REF"
5513 [(clobber (const_int 0))]
5515 int offset = INTVAL (operands[2]);
5517 if (offset < -0x8000 || offset > 0x7fff)
5519 arm_emit_movpair (operands[0], operands[1]);
5520 emit_insn (gen_rtx_SET (operands[0],
5521 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5525 rtx op = gen_rtx_CONST (SImode,
5526 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5527 arm_emit_movpair (operands[0], op);
5532 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5533 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5534 ;; and lo_sum would be merged back into memory load at cprop. However,
5535 ;; if the default is to prefer movt/movw rather than a load from the constant
5536 ;; pool, the performance is better.
5538 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5539 (match_operand:SI 1 "general_operand" ""))]
5540 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5541 && !target_word_relocations
5542 && !arm_tls_referenced_p (operands[1])"
5543 [(clobber (const_int 0))]
5545 arm_emit_movpair (operands[0], operands[1]);
5549 ;; When generating pic, we need to load the symbol offset into a register.
5550 ;; So that the optimizer does not confuse this with a normal symbol load
5551 ;; we use an unspec. The offset will be loaded from a constant pool entry,
5552 ;; since that is the only type of relocation we can use.
5554 ;; Wrap calculation of the whole PIC address in a single pattern for the
5555 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5556 ;; a PIC address involves two loads from memory, so we want to CSE it
5557 ;; as often as possible.
5558 ;; This pattern will be split into one of the pic_load_addr_* patterns
5559 ;; and a move after GCSE optimizations.
5561 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5562 (define_expand "calculate_pic_address"
5563 [(set (match_operand:SI 0 "register_operand")
5564 (mem:SI (plus:SI (match_operand:SI 1 "register_operand")
5565 (unspec:SI [(match_operand:SI 2 "" "")]
5570 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5572 [(set (match_operand:SI 0 "register_operand" "")
5573 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5574 (unspec:SI [(match_operand:SI 2 "" "")]
5577 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5578 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5579 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5582 ;; operand1 is the memory address to go into
5583 ;; pic_load_addr_32bit.
5584 ;; operand2 is the PIC label to be emitted
5585 ;; from pic_add_dot_plus_eight.
5586 ;; We do this to allow hoisting of the entire insn.
5587 (define_insn_and_split "pic_load_addr_unified"
5588 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5589 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5590 (match_operand:SI 2 "" "")]
5591 UNSPEC_PIC_UNIFIED))]
5594 "&& reload_completed"
5595 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5596 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5597 (match_dup 2)] UNSPEC_PIC_BASE))]
5598 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5599 [(set_attr "type" "load_4,load_4,load_4")
5600 (set_attr "pool_range" "4096,4094,1022")
5601 (set_attr "neg_pool_range" "4084,0,0")
5602 (set_attr "arch" "a,t2,t1")
5603 (set_attr "length" "8,6,4")]
5606 ;; The rather odd constraints on the following are to force reload to leave
5607 ;; the insn alone, and to force the minipool generation pass to then move
5608 ;; the GOT symbol to memory.
5610 (define_insn "pic_load_addr_32bit"
5611 [(set (match_operand:SI 0 "s_register_operand" "=r")
5612 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5613 "TARGET_32BIT && flag_pic"
5615 [(set_attr "type" "load_4")
5616 (set (attr "pool_range")
5617 (if_then_else (eq_attr "is_thumb" "no")
5620 (set (attr "neg_pool_range")
5621 (if_then_else (eq_attr "is_thumb" "no")
5626 (define_insn "pic_load_addr_thumb1"
5627 [(set (match_operand:SI 0 "s_register_operand" "=l")
5628 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5629 "TARGET_THUMB1 && flag_pic"
5631 [(set_attr "type" "load_4")
5632 (set (attr "pool_range") (const_int 1018))]
5635 (define_insn "pic_add_dot_plus_four"
5636 [(set (match_operand:SI 0 "register_operand" "=r")
5637 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5639 (match_operand 2 "" "")]
5643 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5644 INTVAL (operands[2]));
5645 return \"add\\t%0, %|pc\";
5647 [(set_attr "length" "2")
5648 (set_attr "type" "alu_sreg")]
5651 (define_insn "pic_add_dot_plus_eight"
5652 [(set (match_operand:SI 0 "register_operand" "=r")
5653 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5655 (match_operand 2 "" "")]
5659 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5660 INTVAL (operands[2]));
5661 return \"add%?\\t%0, %|pc, %1\";
5663 [(set_attr "predicable" "yes")
5664 (set_attr "type" "alu_sreg")]
5667 (define_insn "tls_load_dot_plus_eight"
5668 [(set (match_operand:SI 0 "register_operand" "=r")
5669 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5671 (match_operand 2 "" "")]
5675 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5676 INTVAL (operands[2]));
5677 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5679 [(set_attr "predicable" "yes")
5680 (set_attr "type" "load_4")]
5683 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5684 ;; followed by a load. These sequences can be crunched down to
5685 ;; tls_load_dot_plus_eight by a peephole.
5688 [(set (match_operand:SI 0 "register_operand" "")
5689 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5691 (match_operand 1 "" "")]
5693 (set (match_operand:SI 2 "arm_general_register_operand" "")
5694 (mem:SI (match_dup 0)))]
5695 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5697 (mem:SI (unspec:SI [(match_dup 3)
5704 (define_insn "pic_offset_arm"
5705 [(set (match_operand:SI 0 "register_operand" "=r")
5706 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5707 (unspec:SI [(match_operand:SI 2 "" "X")]
5708 UNSPEC_PIC_OFFSET))))]
5709 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5710 "ldr%?\\t%0, [%1,%2]"
5711 [(set_attr "type" "load_4")]
5714 (define_expand "builtin_setjmp_receiver"
5715 [(label_ref (match_operand 0 "" ""))]
5719 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5721 if (arm_pic_register != INVALID_REGNUM)
5722 arm_load_pic_register (1UL << 3, NULL_RTX);
5726 ;; If copying one reg to another we can set the condition codes according to
5727 ;; its value. Such a move is common after a return from subroutine and the
5728 ;; result is being tested against zero.
5730 (define_insn "*movsi_compare0"
5731 [(set (reg:CC CC_REGNUM)
5732 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5734 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5739 subs%?\\t%0, %1, #0"
5740 [(set_attr "conds" "set")
5741 (set_attr "type" "alus_imm,alus_imm")]
5744 ;; Subroutine to store a half word from a register into memory.
5745 ;; Operand 0 is the source register (HImode)
5746 ;; Operand 1 is the destination address in a register (SImode)
5748 ;; In both this routine and the next, we must be careful not to spill
5749 ;; a memory address of reg+large_const into a separate PLUS insn, since this
5750 ;; can generate unrecognizable rtl.
5752 (define_expand "storehi"
5753 [;; store the low byte
5754 (set (match_operand 1 "" "") (match_dup 3))
5755 ;; extract the high byte
5757 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5758 ;; store the high byte
5759 (set (match_dup 4) (match_dup 5))]
5763 rtx op1 = operands[1];
5764 rtx addr = XEXP (op1, 0);
5765 enum rtx_code code = GET_CODE (addr);
5767 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5769 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
5771 operands[4] = adjust_address (op1, QImode, 1);
5772 operands[1] = adjust_address (operands[1], QImode, 0);
5773 operands[3] = gen_lowpart (QImode, operands[0]);
5774 operands[0] = gen_lowpart (SImode, operands[0]);
5775 operands[2] = gen_reg_rtx (SImode);
5776 operands[5] = gen_lowpart (QImode, operands[2]);
5780 (define_expand "storehi_bigend"
5781 [(set (match_dup 4) (match_dup 3))
5783 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5784 (set (match_operand 1 "" "") (match_dup 5))]
5788 rtx op1 = operands[1];
5789 rtx addr = XEXP (op1, 0);
5790 enum rtx_code code = GET_CODE (addr);
5792 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5794 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
5796 operands[4] = adjust_address (op1, QImode, 1);
5797 operands[1] = adjust_address (operands[1], QImode, 0);
5798 operands[3] = gen_lowpart (QImode, operands[0]);
5799 operands[0] = gen_lowpart (SImode, operands[0]);
5800 operands[2] = gen_reg_rtx (SImode);
5801 operands[5] = gen_lowpart (QImode, operands[2]);
5805 ;; Subroutine to store a half word integer constant into memory.
5806 (define_expand "storeinthi"
5807 [(set (match_operand 0 "" "")
5808 (match_operand 1 "" ""))
5809 (set (match_dup 3) (match_dup 2))]
5813 HOST_WIDE_INT value = INTVAL (operands[1]);
5814 rtx addr = XEXP (operands[0], 0);
5815 rtx op0 = operands[0];
5816 enum rtx_code code = GET_CODE (addr);
5818 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5820 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
5822 operands[1] = gen_reg_rtx (SImode);
5823 if (BYTES_BIG_ENDIAN)
5825 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
5826 if ((value & 255) == ((value >> 8) & 255))
5827 operands[2] = operands[1];
5830 operands[2] = gen_reg_rtx (SImode);
5831 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
5836 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
5837 if ((value & 255) == ((value >> 8) & 255))
5838 operands[2] = operands[1];
5841 operands[2] = gen_reg_rtx (SImode);
5842 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
5846 operands[3] = adjust_address (op0, QImode, 1);
5847 operands[0] = adjust_address (operands[0], QImode, 0);
5848 operands[2] = gen_lowpart (QImode, operands[2]);
5849 operands[1] = gen_lowpart (QImode, operands[1]);
5853 (define_expand "storehi_single_op"
5854 [(set (match_operand:HI 0 "memory_operand")
5855 (match_operand:HI 1 "general_operand"))]
5856 "TARGET_32BIT && arm_arch4"
5858 if (!s_register_operand (operands[1], HImode))
5859 operands[1] = copy_to_mode_reg (HImode, operands[1]);
5863 (define_expand "movhi"
5864 [(set (match_operand:HI 0 "general_operand")
5865 (match_operand:HI 1 "general_operand"))]
5868 gcc_checking_assert (aligned_operand (operands[0], HImode));
5869 gcc_checking_assert (aligned_operand (operands[1], HImode));
5872 if (can_create_pseudo_p ())
5874 if (MEM_P (operands[0]))
5878 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
5881 if (CONST_INT_P (operands[1]))
5882 emit_insn (gen_storeinthi (operands[0], operands[1]));
5885 if (MEM_P (operands[1]))
5886 operands[1] = force_reg (HImode, operands[1]);
5887 if (BYTES_BIG_ENDIAN)
5888 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
5890 emit_insn (gen_storehi (operands[1], operands[0]));
5894 /* Sign extend a constant, and keep it in an SImode reg. */
5895 else if (CONST_INT_P (operands[1]))
5897 rtx reg = gen_reg_rtx (SImode);
5898 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
5900 /* If the constant is already valid, leave it alone. */
5901 if (!const_ok_for_arm (val))
5903 /* If setting all the top bits will make the constant
5904 loadable in a single instruction, then set them.
5905 Otherwise, sign extend the number. */
5907 if (const_ok_for_arm (~(val | ~0xffff)))
5909 else if (val & 0x8000)
5913 emit_insn (gen_movsi (reg, GEN_INT (val)));
5914 operands[1] = gen_lowpart (HImode, reg);
5916 else if (arm_arch4 && optimize && can_create_pseudo_p ()
5917 && MEM_P (operands[1]))
5919 rtx reg = gen_reg_rtx (SImode);
5921 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
5922 operands[1] = gen_lowpart (HImode, reg);
5924 else if (!arm_arch4)
5926 if (MEM_P (operands[1]))
5929 rtx offset = const0_rtx;
5930 rtx reg = gen_reg_rtx (SImode);
5932 if ((REG_P (base = XEXP (operands[1], 0))
5933 || (GET_CODE (base) == PLUS
5934 && (CONST_INT_P (offset = XEXP (base, 1)))
5935 && ((INTVAL(offset) & 1) != 1)
5936 && REG_P (base = XEXP (base, 0))))
5937 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
5941 new_rtx = widen_memory_access (operands[1], SImode,
5942 ((INTVAL (offset) & ~3)
5943 - INTVAL (offset)));
5944 emit_insn (gen_movsi (reg, new_rtx));
5945 if (((INTVAL (offset) & 2) != 0)
5946 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
5948 rtx reg2 = gen_reg_rtx (SImode);
5950 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
5955 emit_insn (gen_movhi_bytes (reg, operands[1]));
5957 operands[1] = gen_lowpart (HImode, reg);
5961 /* Handle loading a large integer during reload. */
5962 else if (CONST_INT_P (operands[1])
5963 && !const_ok_for_arm (INTVAL (operands[1]))
5964 && !const_ok_for_arm (~INTVAL (operands[1])))
5966 /* Writing a constant to memory needs a scratch, which should
5967 be handled with SECONDARY_RELOADs. */
5968 gcc_assert (REG_P (operands[0]));
5970 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
5971 emit_insn (gen_movsi (operands[0], operands[1]));
5975 else if (TARGET_THUMB2)
5977 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
5978 if (can_create_pseudo_p ())
5980 if (!REG_P (operands[0]))
5981 operands[1] = force_reg (HImode, operands[1]);
5982 /* Zero extend a constant, and keep it in an SImode reg. */
5983 else if (CONST_INT_P (operands[1]))
5985 rtx reg = gen_reg_rtx (SImode);
5986 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
5988 emit_insn (gen_movsi (reg, GEN_INT (val)));
5989 operands[1] = gen_lowpart (HImode, reg);
5993 else /* TARGET_THUMB1 */
5995 if (can_create_pseudo_p ())
5997 if (CONST_INT_P (operands[1]))
5999 rtx reg = gen_reg_rtx (SImode);
6001 emit_insn (gen_movsi (reg, operands[1]));
6002 operands[1] = gen_lowpart (HImode, reg);
6005 /* ??? We shouldn't really get invalid addresses here, but this can
6006 happen if we are passed a SP (never OK for HImode/QImode) or
6007 virtual register (also rejected as illegitimate for HImode/QImode)
6008 relative address. */
6009 /* ??? This should perhaps be fixed elsewhere, for instance, in
6010 fixup_stack_1, by checking for other kinds of invalid addresses,
6011 e.g. a bare reference to a virtual register. This may confuse the
6012 alpha though, which must handle this case differently. */
6013 if (MEM_P (operands[0])
6014 && !memory_address_p (GET_MODE (operands[0]),
6015 XEXP (operands[0], 0)))
6017 = replace_equiv_address (operands[0],
6018 copy_to_reg (XEXP (operands[0], 0)));
6020 if (MEM_P (operands[1])
6021 && !memory_address_p (GET_MODE (operands[1]),
6022 XEXP (operands[1], 0)))
6024 = replace_equiv_address (operands[1],
6025 copy_to_reg (XEXP (operands[1], 0)));
6027 if (MEM_P (operands[1]) && optimize > 0)
6029 rtx reg = gen_reg_rtx (SImode);
6031 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6032 operands[1] = gen_lowpart (HImode, reg);
6035 if (MEM_P (operands[0]))
6036 operands[1] = force_reg (HImode, operands[1]);
6038 else if (CONST_INT_P (operands[1])
6039 && !satisfies_constraint_I (operands[1]))
6041 /* Handle loading a large integer during reload. */
6043 /* Writing a constant to memory needs a scratch, which should
6044 be handled with SECONDARY_RELOADs. */
6045 gcc_assert (REG_P (operands[0]));
6047 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6048 emit_insn (gen_movsi (operands[0], operands[1]));
6055 (define_expand "movhi_bytes"
6056 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6058 (zero_extend:SI (match_dup 6)))
6059 (set (match_operand:SI 0 "" "")
6060 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6065 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6067 mem1 = change_address (operands[1], QImode, addr);
6068 mem2 = change_address (operands[1], QImode,
6069 plus_constant (Pmode, addr, 1));
6070 operands[0] = gen_lowpart (SImode, operands[0]);
6072 operands[2] = gen_reg_rtx (SImode);
6073 operands[3] = gen_reg_rtx (SImode);
6076 if (BYTES_BIG_ENDIAN)
6078 operands[4] = operands[2];
6079 operands[5] = operands[3];
6083 operands[4] = operands[3];
6084 operands[5] = operands[2];
6089 (define_expand "movhi_bigend"
6091 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand") 0)
6094 (ashiftrt:SI (match_dup 2) (const_int 16)))
6095 (set (match_operand:HI 0 "s_register_operand")
6099 operands[2] = gen_reg_rtx (SImode);
6100 operands[3] = gen_reg_rtx (SImode);
6101 operands[4] = gen_lowpart (HImode, operands[3]);
6105 ;; Pattern to recognize insn generated default case above
6106 (define_insn "*movhi_insn_arch4"
6107 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6108 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6110 && arm_arch4 && !TARGET_HARD_FLOAT
6111 && (register_operand (operands[0], HImode)
6112 || register_operand (operands[1], HImode))"
6114 mov%?\\t%0, %1\\t%@ movhi
6115 mvn%?\\t%0, #%B1\\t%@ movhi
6116 movw%?\\t%0, %L1\\t%@ movhi
6117 strh%?\\t%1, %0\\t%@ movhi
6118 ldrh%?\\t%0, %1\\t%@ movhi"
6119 [(set_attr "predicable" "yes")
6120 (set_attr "pool_range" "*,*,*,*,256")
6121 (set_attr "neg_pool_range" "*,*,*,*,244")
6122 (set_attr "arch" "*,*,v6t2,*,*")
6123 (set_attr_alternative "type"
6124 [(if_then_else (match_operand 1 "const_int_operand" "")
6125 (const_string "mov_imm" )
6126 (const_string "mov_reg"))
6127 (const_string "mvn_imm")
6128 (const_string "mov_imm")
6129 (const_string "store_4")
6130 (const_string "load_4")])]
6133 (define_insn "*movhi_bytes"
6134 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6135 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6136 "TARGET_ARM && !TARGET_HARD_FLOAT"
6138 mov%?\\t%0, %1\\t%@ movhi
6139 mov%?\\t%0, %1\\t%@ movhi
6140 mvn%?\\t%0, #%B1\\t%@ movhi"
6141 [(set_attr "predicable" "yes")
6142 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6145 ;; We use a DImode scratch because we may occasionally need an additional
6146 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6147 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6148 ;; The reload_in<m> and reload_out<m> patterns require special constraints
6149 ;; to be correctly handled in default_secondary_reload function.
6150 (define_expand "reload_outhi"
6151 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6152 (match_operand:HI 1 "s_register_operand" "r")
6153 (match_operand:DI 2 "s_register_operand" "=&l")])]
6156 arm_reload_out_hi (operands);
6158 thumb_reload_out_hi (operands);
6163 (define_expand "reload_inhi"
6164 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6165 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6166 (match_operand:DI 2 "s_register_operand" "=&r")])]
6170 arm_reload_in_hi (operands);
6172 thumb_reload_out_hi (operands);
6176 (define_expand "movqi"
6177 [(set (match_operand:QI 0 "general_operand")
6178 (match_operand:QI 1 "general_operand"))]
6181 /* Everything except mem = const or mem = mem can be done easily */
6183 if (can_create_pseudo_p ())
6185 if (CONST_INT_P (operands[1]))
6187 rtx reg = gen_reg_rtx (SImode);
6189 /* For thumb we want an unsigned immediate, then we are more likely
6190 to be able to use a movs insn. */
6192 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6194 emit_insn (gen_movsi (reg, operands[1]));
6195 operands[1] = gen_lowpart (QImode, reg);
6200 /* ??? We shouldn't really get invalid addresses here, but this can
6201 happen if we are passed a SP (never OK for HImode/QImode) or
6202 virtual register (also rejected as illegitimate for HImode/QImode)
6203 relative address. */
6204 /* ??? This should perhaps be fixed elsewhere, for instance, in
6205 fixup_stack_1, by checking for other kinds of invalid addresses,
6206 e.g. a bare reference to a virtual register. This may confuse the
6207 alpha though, which must handle this case differently. */
6208 if (MEM_P (operands[0])
6209 && !memory_address_p (GET_MODE (operands[0]),
6210 XEXP (operands[0], 0)))
6212 = replace_equiv_address (operands[0],
6213 copy_to_reg (XEXP (operands[0], 0)));
6214 if (MEM_P (operands[1])
6215 && !memory_address_p (GET_MODE (operands[1]),
6216 XEXP (operands[1], 0)))
6218 = replace_equiv_address (operands[1],
6219 copy_to_reg (XEXP (operands[1], 0)));
6222 if (MEM_P (operands[1]) && optimize > 0)
6224 rtx reg = gen_reg_rtx (SImode);
6226 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6227 operands[1] = gen_lowpart (QImode, reg);
6230 if (MEM_P (operands[0]))
6231 operands[1] = force_reg (QImode, operands[1]);
6233 else if (TARGET_THUMB
6234 && CONST_INT_P (operands[1])
6235 && !satisfies_constraint_I (operands[1]))
6237 /* Handle loading a large integer during reload. */
6239 /* Writing a constant to memory needs a scratch, which should
6240 be handled with SECONDARY_RELOADs. */
6241 gcc_assert (REG_P (operands[0]));
6243 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6244 emit_insn (gen_movsi (operands[0], operands[1]));
6250 (define_insn "*arm_movqi_insn"
6251 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6252 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6254 && ( register_operand (operands[0], QImode)
6255 || register_operand (operands[1], QImode))"
6266 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6267 (set_attr "predicable" "yes")
6268 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6269 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6270 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6274 (define_expand "movhf"
6275 [(set (match_operand:HF 0 "general_operand")
6276 (match_operand:HF 1 "general_operand"))]
6279 gcc_checking_assert (aligned_operand (operands[0], HFmode));
6280 gcc_checking_assert (aligned_operand (operands[1], HFmode));
6283 if (MEM_P (operands[0]))
6284 operands[1] = force_reg (HFmode, operands[1]);
6286 else /* TARGET_THUMB1 */
6288 if (can_create_pseudo_p ())
6290 if (!REG_P (operands[0]))
6291 operands[1] = force_reg (HFmode, operands[1]);
6297 (define_insn "*arm32_movhf"
6298 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6299 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6300 "TARGET_32BIT && !TARGET_HARD_FLOAT
6301 && ( s_register_operand (operands[0], HFmode)
6302 || s_register_operand (operands[1], HFmode))"
6304 switch (which_alternative)
6306 case 0: /* ARM register from memory */
6307 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6308 case 1: /* memory from ARM register */
6309 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6310 case 2: /* ARM register from ARM register */
6311 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6312 case 3: /* ARM register from constant */
6317 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6319 ops[0] = operands[0];
6320 ops[1] = GEN_INT (bits);
6321 ops[2] = GEN_INT (bits & 0xff00);
6322 ops[3] = GEN_INT (bits & 0x00ff);
6324 if (arm_arch_thumb2)
6325 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6327 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6334 [(set_attr "conds" "unconditional")
6335 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6336 (set_attr "length" "4,4,4,8")
6337 (set_attr "predicable" "yes")]
6340 (define_expand "movsf"
6341 [(set (match_operand:SF 0 "general_operand")
6342 (match_operand:SF 1 "general_operand"))]
6345 gcc_checking_assert (aligned_operand (operands[0], SFmode));
6346 gcc_checking_assert (aligned_operand (operands[1], SFmode));
6349 if (MEM_P (operands[0]))
6350 operands[1] = force_reg (SFmode, operands[1]);
6352 else /* TARGET_THUMB1 */
6354 if (can_create_pseudo_p ())
6356 if (!REG_P (operands[0]))
6357 operands[1] = force_reg (SFmode, operands[1]);
6361 /* Cannot load it directly, generate a load with clobber so that it can be
6362 loaded via GPR with MOV / MOVT. */
6363 if (arm_disable_literal_pool
6364 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6365 && CONST_DOUBLE_P (operands[1])
6366 && TARGET_HARD_FLOAT
6367 && !vfp3_const_double_rtx (operands[1]))
6369 rtx clobreg = gen_reg_rtx (SFmode);
6370 emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
6377 ;; Transform a floating-point move of a constant into a core register into
6378 ;; an SImode operation.
6380 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6381 (match_operand:SF 1 "immediate_operand" ""))]
6384 && CONST_DOUBLE_P (operands[1])"
6385 [(set (match_dup 2) (match_dup 3))]
6387 operands[2] = gen_lowpart (SImode, operands[0]);
6388 operands[3] = gen_lowpart (SImode, operands[1]);
6389 if (operands[2] == 0 || operands[3] == 0)
6394 (define_insn "*arm_movsf_soft_insn"
6395 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6396 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6398 && TARGET_SOFT_FLOAT
6399 && (!MEM_P (operands[0])
6400 || register_operand (operands[1], SFmode))"
6402 switch (which_alternative)
6404 case 0: return \"mov%?\\t%0, %1\";
6406 /* Cannot load it directly, split to load it via MOV / MOVT. */
6407 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
6409 return \"ldr%?\\t%0, %1\\t%@ float\";
6410 case 2: return \"str%?\\t%1, %0\\t%@ float\";
6411 default: gcc_unreachable ();
6414 [(set_attr "predicable" "yes")
6415 (set_attr "type" "mov_reg,load_4,store_4")
6416 (set_attr "arm_pool_range" "*,4096,*")
6417 (set_attr "thumb2_pool_range" "*,4094,*")
6418 (set_attr "arm_neg_pool_range" "*,4084,*")
6419 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6422 ;; Splitter for the above.
6424 [(set (match_operand:SF 0 "s_register_operand")
6425 (match_operand:SF 1 "const_double_operand"))]
6426 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
6430 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
6431 rtx cst = gen_int_mode (buf, SImode);
6432 emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
6437 (define_expand "movdf"
6438 [(set (match_operand:DF 0 "general_operand")
6439 (match_operand:DF 1 "general_operand"))]
6442 gcc_checking_assert (aligned_operand (operands[0], DFmode));
6443 gcc_checking_assert (aligned_operand (operands[1], DFmode));
6446 if (MEM_P (operands[0]))
6447 operands[1] = force_reg (DFmode, operands[1]);
6449 else /* TARGET_THUMB */
6451 if (can_create_pseudo_p ())
6453 if (!REG_P (operands[0]))
6454 operands[1] = force_reg (DFmode, operands[1]);
6458 /* Cannot load it directly, generate a load with clobber so that it can be
6459 loaded via GPR with MOV / MOVT. */
6460 if (arm_disable_literal_pool
6461 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6462 && CONSTANT_P (operands[1])
6463 && TARGET_HARD_FLOAT
6464 && !arm_const_double_rtx (operands[1])
6465 && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
6467 rtx clobreg = gen_reg_rtx (DFmode);
6468 emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
6475 ;; Reloading a df mode value stored in integer regs to memory can require a
6477 ;; Another reload_out<m> pattern that requires special constraints.
6478 (define_expand "reload_outdf"
6479 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6480 (match_operand:DF 1 "s_register_operand" "r")
6481 (match_operand:SI 2 "s_register_operand" "=&r")]
6485 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6488 operands[2] = XEXP (operands[0], 0);
6489 else if (code == POST_INC || code == PRE_DEC)
6491 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6492 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6493 emit_insn (gen_movdi (operands[0], operands[1]));
6496 else if (code == PRE_INC)
6498 rtx reg = XEXP (XEXP (operands[0], 0), 0);
6500 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6503 else if (code == POST_DEC)
6504 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6506 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6507 XEXP (XEXP (operands[0], 0), 1)));
6509 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
6512 if (code == POST_DEC)
6513 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6519 (define_insn "*movdf_soft_insn"
6520 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
6521 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
6522 "TARGET_32BIT && TARGET_SOFT_FLOAT
6523 && ( register_operand (operands[0], DFmode)
6524 || register_operand (operands[1], DFmode))"
6526 switch (which_alternative)
6533 /* Cannot load it directly, split to load it via MOV / MOVT. */
6534 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
6538 return output_move_double (operands, true, NULL);
6541 [(set_attr "length" "8,12,16,8,8")
6542 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
6543 (set_attr "arm_pool_range" "*,*,*,1020,*")
6544 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6545 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6546 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6549 ;; Splitter for the above.
6551 [(set (match_operand:DF 0 "s_register_operand")
6552 (match_operand:DF 1 "const_double_operand"))]
6553 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
6557 int order = BYTES_BIG_ENDIAN ? 1 : 0;
6558 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
6559 unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
6560 ival |= (zext_hwi (buf[1 - order], 32) << 32);
6561 rtx cst = gen_int_mode (ival, DImode);
6562 emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
6568 ;; load- and store-multiple insns
6569 ;; The arm can load/store any set of registers, provided that they are in
6570 ;; ascending order, but these expanders assume a contiguous set.
6572 (define_expand "load_multiple"
6573 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6574 (match_operand:SI 1 "" ""))
6575 (use (match_operand:SI 2 "" ""))])]
6578 HOST_WIDE_INT offset = 0;
6580 /* Support only fixed point registers. */
6581 if (!CONST_INT_P (operands[2])
6582 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6583 || INTVAL (operands[2]) < 2
6584 || !MEM_P (operands[1])
6585 || !REG_P (operands[0])
6586 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6587 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6591 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6592 INTVAL (operands[2]),
6593 force_reg (SImode, XEXP (operands[1], 0)),
6594 FALSE, operands[1], &offset);
6597 (define_expand "store_multiple"
6598 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6599 (match_operand:SI 1 "" ""))
6600 (use (match_operand:SI 2 "" ""))])]
6603 HOST_WIDE_INT offset = 0;
6605 /* Support only fixed point registers. */
6606 if (!CONST_INT_P (operands[2])
6607 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6608 || INTVAL (operands[2]) < 2
6609 || !REG_P (operands[1])
6610 || !MEM_P (operands[0])
6611 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6612 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6616 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6617 INTVAL (operands[2]),
6618 force_reg (SImode, XEXP (operands[0], 0)),
6619 FALSE, operands[0], &offset);
6623 (define_expand "setmemsi"
6624 [(match_operand:BLK 0 "general_operand")
6625 (match_operand:SI 1 "const_int_operand")
6626 (match_operand:SI 2 "const_int_operand")
6627 (match_operand:SI 3 "const_int_operand")]
6630 if (arm_gen_setmem (operands))
6637 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6638 ;; We could let this apply for blocks of less than this, but it clobbers so
6639 ;; many registers that there is then probably a better way.
6641 (define_expand "cpymemqi"
6642 [(match_operand:BLK 0 "general_operand")
6643 (match_operand:BLK 1 "general_operand")
6644 (match_operand:SI 2 "const_int_operand")
6645 (match_operand:SI 3 "const_int_operand")]
6650 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6651 && !optimize_function_for_size_p (cfun))
6653 if (gen_cpymem_ldrd_strd (operands))
6658 if (arm_gen_cpymemqi (operands))
6662 else /* TARGET_THUMB1 */
6664 if ( INTVAL (operands[3]) != 4
6665 || INTVAL (operands[2]) > 48)
6668 thumb_expand_cpymemqi (operands);
6675 ;; Compare & branch insns
6676 ;; The range calculations are based as follows:
6677 ;; For forward branches, the address calculation returns the address of
6678 ;; the next instruction. This is 2 beyond the branch instruction.
6679 ;; For backward branches, the address calculation returns the address of
6680 ;; the first instruction in this pattern (cmp). This is 2 before the branch
6681 ;; instruction for the shortest sequence, and 4 before the branch instruction
6682 ;; if we have to jump around an unconditional branch.
6683 ;; To the basic branch range the PC offset must be added (this is +4).
6684 ;; So for forward branches we have
6685 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6686 ;; And for backward branches we have
6687 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6689 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6690 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
6692 (define_expand "cbranchsi4"
6693 [(set (pc) (if_then_else
6694 (match_operator 0 "expandable_comparison_operator"
6695 [(match_operand:SI 1 "s_register_operand")
6696 (match_operand:SI 2 "nonmemory_operand")])
6697 (label_ref (match_operand 3 "" ""))
6703 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6705 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6709 if (thumb1_cmpneg_operand (operands[2], SImode))
6711 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6712 operands[3], operands[0]));
6715 if (!thumb1_cmp_operand (operands[2], SImode))
6716 operands[2] = force_reg (SImode, operands[2]);
6719 (define_expand "cbranchsf4"
6720 [(set (pc) (if_then_else
6721 (match_operator 0 "expandable_comparison_operator"
6722 [(match_operand:SF 1 "s_register_operand")
6723 (match_operand:SF 2 "vfp_compare_operand")])
6724 (label_ref (match_operand 3 "" ""))
6726 "TARGET_32BIT && TARGET_HARD_FLOAT"
6727 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6728 operands[3])); DONE;"
6731 (define_expand "cbranchdf4"
6732 [(set (pc) (if_then_else
6733 (match_operator 0 "expandable_comparison_operator"
6734 [(match_operand:DF 1 "s_register_operand")
6735 (match_operand:DF 2 "vfp_compare_operand")])
6736 (label_ref (match_operand 3 "" ""))
6738 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6739 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6740 operands[3])); DONE;"
6743 (define_expand "cbranchdi4"
6744 [(set (pc) (if_then_else
6745 (match_operator 0 "expandable_comparison_operator"
6746 [(match_operand:DI 1 "s_register_operand")
6747 (match_operand:DI 2 "cmpdi_operand")])
6748 (label_ref (match_operand 3 "" ""))
6752 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6754 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6760 ;; Comparison and test insns
6762 (define_insn "*arm_cmpsi_insn"
6763 [(set (reg:CC CC_REGNUM)
6764 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6765 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
6773 [(set_attr "conds" "set")
6774 (set_attr "arch" "t2,t2,any,any,any")
6775 (set_attr "length" "2,2,4,4,4")
6776 (set_attr "predicable" "yes")
6777 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6778 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6781 (define_insn "*cmpsi_shiftsi"
6782 [(set (reg:CC CC_REGNUM)
6783 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
6784 (match_operator:SI 3 "shift_operator"
6785 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6786 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6789 [(set_attr "conds" "set")
6790 (set_attr "shift" "1")
6791 (set_attr "arch" "32,a,a")
6792 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6794 (define_insn "*cmpsi_shiftsi_swp"
6795 [(set (reg:CC_SWP CC_REGNUM)
6796 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6797 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6798 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6799 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6802 [(set_attr "conds" "set")
6803 (set_attr "shift" "1")
6804 (set_attr "arch" "32,a,a")
6805 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6807 (define_insn "*arm_cmpsi_negshiftsi_si"
6808 [(set (reg:CC_Z CC_REGNUM)
6810 (neg:SI (match_operator:SI 1 "shift_operator"
6811 [(match_operand:SI 2 "s_register_operand" "r")
6812 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6813 (match_operand:SI 0 "s_register_operand" "r")))]
6816 [(set_attr "conds" "set")
6817 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6818 (const_string "alus_shift_imm")
6819 (const_string "alus_shift_reg")))
6820 (set_attr "predicable" "yes")]
6823 ;; DImode comparisons. The generic code generates branches that
6824 ;; if-conversion cannot reduce to a conditional compare, so we do
6827 (define_insn_and_split "*arm_cmpdi_insn"
6828 [(set (reg:CC_NCV CC_REGNUM)
6829 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6830 (match_operand:DI 1 "arm_di_operand" "rDi")))
6831 (clobber (match_scratch:SI 2 "=r"))]
6833 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6834 "&& reload_completed"
6835 [(set (reg:CC CC_REGNUM)
6836 (compare:CC (match_dup 0) (match_dup 1)))
6837 (parallel [(set (reg:CC CC_REGNUM)
6838 (compare:CC (match_dup 3) (match_dup 4)))
6840 (minus:SI (match_dup 5)
6841 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))])]
6843 operands[3] = gen_highpart (SImode, operands[0]);
6844 operands[0] = gen_lowpart (SImode, operands[0]);
6845 if (CONST_INT_P (operands[1]))
6847 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);
6848 if (operands[4] == const0_rtx)
6849 operands[5] = operands[3];
6851 operands[5] = gen_rtx_PLUS (SImode, operands[3],
6852 gen_int_mode (-UINTVAL (operands[4]),
6857 operands[4] = gen_highpart (SImode, operands[1]);
6858 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6860 operands[1] = gen_lowpart (SImode, operands[1]);
6861 operands[2] = gen_lowpart (SImode, operands[2]);
6863 [(set_attr "conds" "set")
6864 (set_attr "length" "8")
6865 (set_attr "type" "multiple")]
6868 (define_insn_and_split "*arm_cmpdi_unsigned"
6869 [(set (reg:CC_CZ CC_REGNUM)
6870 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6871 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
6874 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6875 "&& reload_completed"
6876 [(set (reg:CC CC_REGNUM)
6877 (compare:CC (match_dup 2) (match_dup 3)))
6878 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6879 (set (reg:CC CC_REGNUM)
6880 (compare:CC (match_dup 0) (match_dup 1))))]
6882 operands[2] = gen_highpart (SImode, operands[0]);
6883 operands[0] = gen_lowpart (SImode, operands[0]);
6884 if (CONST_INT_P (operands[1]))
6885 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6887 operands[3] = gen_highpart (SImode, operands[1]);
6888 operands[1] = gen_lowpart (SImode, operands[1]);
6890 [(set_attr "conds" "set")
6891 (set_attr "enabled_for_short_it" "yes,yes,no,*")
6892 (set_attr "arch" "t2,t2,t2,a")
6893 (set_attr "length" "6,6,10,8")
6894 (set_attr "type" "multiple")]
6897 (define_insn "*arm_cmpdi_zero"
6898 [(set (reg:CC_Z CC_REGNUM)
6899 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6901 (clobber (match_scratch:SI 1 "=r"))]
6903 "orrs%?\\t%1, %Q0, %R0"
6904 [(set_attr "conds" "set")
6905 (set_attr "type" "logics_reg")]
6908 ; This insn allows redundant compares to be removed by cse, nothing should
6909 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6910 ; is deleted later on. The match_dup will match the mode here, so that
6911 ; mode changes of the condition codes aren't lost by this even though we don't
6912 ; specify what they are.
6914 (define_insn "*deleted_compare"
6915 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6917 "\\t%@ deleted compare"
6918 [(set_attr "conds" "set")
6919 (set_attr "length" "0")
6920 (set_attr "type" "no_insn")]
6924 ;; Conditional branch insns
6926 (define_expand "cbranch_cc"
6928 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
6929 (match_operand 2 "" "")])
6930 (label_ref (match_operand 3 "" ""))
6933 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
6934 operands[1], operands[2], NULL_RTX);
6935 operands[2] = const0_rtx;"
6939 ;; Patterns to match conditional branch insns.
6942 (define_insn "arm_cond_branch"
6944 (if_then_else (match_operator 1 "arm_comparison_operator"
6945 [(match_operand 2 "cc_register" "") (const_int 0)])
6946 (label_ref (match_operand 0 "" ""))
6950 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
6952 arm_ccfsm_state += 2;
6955 return \"b%d1\\t%l0\";
6957 [(set_attr "conds" "use")
6958 (set_attr "type" "branch")
6959 (set (attr "length")
6961 (and (match_test "TARGET_THUMB2")
6962 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
6963 (le (minus (match_dup 0) (pc)) (const_int 256))))
6968 (define_insn "*arm_cond_branch_reversed"
6970 (if_then_else (match_operator 1 "arm_comparison_operator"
6971 [(match_operand 2 "cc_register" "") (const_int 0)])
6973 (label_ref (match_operand 0 "" ""))))]
6976 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
6978 arm_ccfsm_state += 2;
6981 return \"b%D1\\t%l0\";
6983 [(set_attr "conds" "use")
6984 (set_attr "type" "branch")
6985 (set (attr "length")
6987 (and (match_test "TARGET_THUMB2")
6988 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
6989 (le (minus (match_dup 0) (pc)) (const_int 256))))
6998 (define_expand "cstore_cc"
6999 [(set (match_operand:SI 0 "s_register_operand")
7000 (match_operator:SI 1 "" [(match_operand 2 "" "")
7001 (match_operand 3 "" "")]))]
7003 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7004 operands[2], operands[3], NULL_RTX);
7005 operands[3] = const0_rtx;"
7008 (define_insn_and_split "*mov_scc"
7009 [(set (match_operand:SI 0 "s_register_operand" "=r")
7010 (match_operator:SI 1 "arm_comparison_operator_mode"
7011 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7013 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7016 (if_then_else:SI (match_dup 1)
7020 [(set_attr "conds" "use")
7021 (set_attr "length" "8")
7022 (set_attr "type" "multiple")]
7025 (define_insn_and_split "*mov_negscc"
7026 [(set (match_operand:SI 0 "s_register_operand" "=r")
7027 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7028 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7030 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7033 (if_then_else:SI (match_dup 1)
7037 operands[3] = GEN_INT (~0);
7039 [(set_attr "conds" "use")
7040 (set_attr "length" "8")
7041 (set_attr "type" "multiple")]
7044 (define_insn_and_split "*mov_notscc"
7045 [(set (match_operand:SI 0 "s_register_operand" "=r")
7046 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7047 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7049 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7052 (if_then_else:SI (match_dup 1)
7056 operands[3] = GEN_INT (~1);
7057 operands[4] = GEN_INT (~0);
7059 [(set_attr "conds" "use")
7060 (set_attr "length" "8")
7061 (set_attr "type" "multiple")]
7064 (define_expand "cstoresi4"
7065 [(set (match_operand:SI 0 "s_register_operand")
7066 (match_operator:SI 1 "expandable_comparison_operator"
7067 [(match_operand:SI 2 "s_register_operand")
7068 (match_operand:SI 3 "reg_or_int_operand")]))]
7069 "TARGET_32BIT || TARGET_THUMB1"
7071 rtx op3, scratch, scratch2;
7075 if (!arm_add_operand (operands[3], SImode))
7076 operands[3] = force_reg (SImode, operands[3]);
7077 emit_insn (gen_cstore_cc (operands[0], operands[1],
7078 operands[2], operands[3]));
7082 if (operands[3] == const0_rtx)
7084 switch (GET_CODE (operands[1]))
7087 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7091 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7095 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7096 NULL_RTX, 0, OPTAB_WIDEN);
7097 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7098 NULL_RTX, 0, OPTAB_WIDEN);
7099 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7100 operands[0], 1, OPTAB_WIDEN);
7104 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7106 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7107 NULL_RTX, 1, OPTAB_WIDEN);
7111 scratch = expand_binop (SImode, ashr_optab, operands[2],
7112 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7113 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7114 NULL_RTX, 0, OPTAB_WIDEN);
7115 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7119 /* LT is handled by generic code. No need for unsigned with 0. */
7126 switch (GET_CODE (operands[1]))
7129 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7130 NULL_RTX, 0, OPTAB_WIDEN);
7131 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7135 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7136 NULL_RTX, 0, OPTAB_WIDEN);
7137 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7141 op3 = force_reg (SImode, operands[3]);
7143 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7144 NULL_RTX, 1, OPTAB_WIDEN);
7145 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7146 NULL_RTX, 0, OPTAB_WIDEN);
7147 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7153 if (!thumb1_cmp_operand (op3, SImode))
7154 op3 = force_reg (SImode, op3);
7155 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7156 NULL_RTX, 0, OPTAB_WIDEN);
7157 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7158 NULL_RTX, 1, OPTAB_WIDEN);
7159 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7164 op3 = force_reg (SImode, operands[3]);
7165 scratch = force_reg (SImode, const0_rtx);
7166 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7172 if (!thumb1_cmp_operand (op3, SImode))
7173 op3 = force_reg (SImode, op3);
7174 scratch = force_reg (SImode, const0_rtx);
7175 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7181 if (!thumb1_cmp_operand (op3, SImode))
7182 op3 = force_reg (SImode, op3);
7183 scratch = gen_reg_rtx (SImode);
7184 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7188 op3 = force_reg (SImode, operands[3]);
7189 scratch = gen_reg_rtx (SImode);
7190 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7193 /* No good sequences for GT, LT. */
7200 (define_expand "cstorehf4"
7201 [(set (match_operand:SI 0 "s_register_operand")
7202 (match_operator:SI 1 "expandable_comparison_operator"
7203 [(match_operand:HF 2 "s_register_operand")
7204 (match_operand:HF 3 "vfp_compare_operand")]))]
7205 "TARGET_VFP_FP16INST"
7207 if (!arm_validize_comparison (&operands[1],
7212 emit_insn (gen_cstore_cc (operands[0], operands[1],
7213 operands[2], operands[3]));
7218 (define_expand "cstoresf4"
7219 [(set (match_operand:SI 0 "s_register_operand")
7220 (match_operator:SI 1 "expandable_comparison_operator"
7221 [(match_operand:SF 2 "s_register_operand")
7222 (match_operand:SF 3 "vfp_compare_operand")]))]
7223 "TARGET_32BIT && TARGET_HARD_FLOAT"
7224 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7225 operands[2], operands[3])); DONE;"
7228 (define_expand "cstoredf4"
7229 [(set (match_operand:SI 0 "s_register_operand")
7230 (match_operator:SI 1 "expandable_comparison_operator"
7231 [(match_operand:DF 2 "s_register_operand")
7232 (match_operand:DF 3 "vfp_compare_operand")]))]
7233 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7234 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7235 operands[2], operands[3])); DONE;"
7238 (define_expand "cstoredi4"
7239 [(set (match_operand:SI 0 "s_register_operand")
7240 (match_operator:SI 1 "expandable_comparison_operator"
7241 [(match_operand:DI 2 "s_register_operand")
7242 (match_operand:DI 3 "cmpdi_operand")]))]
7245 if (!arm_validize_comparison (&operands[1],
7249 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7256 ;; Conditional move insns
7258 (define_expand "movsicc"
7259 [(set (match_operand:SI 0 "s_register_operand")
7260 (if_then_else:SI (match_operand 1 "expandable_comparison_operator")
7261 (match_operand:SI 2 "arm_not_operand")
7262 (match_operand:SI 3 "arm_not_operand")))]
7269 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7270 &XEXP (operands[1], 1)))
7273 code = GET_CODE (operands[1]);
7274 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7275 XEXP (operands[1], 1), NULL_RTX);
7276 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7280 (define_expand "movhfcc"
7281 [(set (match_operand:HF 0 "s_register_operand")
7282 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7283 (match_operand:HF 2 "s_register_operand")
7284 (match_operand:HF 3 "s_register_operand")))]
7285 "TARGET_VFP_FP16INST"
7288 enum rtx_code code = GET_CODE (operands[1]);
7291 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7292 &XEXP (operands[1], 1)))
7295 code = GET_CODE (operands[1]);
7296 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7297 XEXP (operands[1], 1), NULL_RTX);
7298 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7302 (define_expand "movsfcc"
7303 [(set (match_operand:SF 0 "s_register_operand")
7304 (if_then_else:SF (match_operand 1 "arm_cond_move_operator")
7305 (match_operand:SF 2 "s_register_operand")
7306 (match_operand:SF 3 "s_register_operand")))]
7307 "TARGET_32BIT && TARGET_HARD_FLOAT"
7310 enum rtx_code code = GET_CODE (operands[1]);
7313 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7314 &XEXP (operands[1], 1)))
7317 code = GET_CODE (operands[1]);
7318 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7319 XEXP (operands[1], 1), NULL_RTX);
7320 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7324 (define_expand "movdfcc"
7325 [(set (match_operand:DF 0 "s_register_operand")
7326 (if_then_else:DF (match_operand 1 "arm_cond_move_operator")
7327 (match_operand:DF 2 "s_register_operand")
7328 (match_operand:DF 3 "s_register_operand")))]
7329 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7332 enum rtx_code code = GET_CODE (operands[1]);
7335 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7336 &XEXP (operands[1], 1)))
7338 code = GET_CODE (operands[1]);
7339 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7340 XEXP (operands[1], 1), NULL_RTX);
7341 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7345 (define_insn "*cmov<mode>"
7346 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7347 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7348 [(match_operand 2 "cc_register" "") (const_int 0)])
7349 (match_operand:SDF 3 "s_register_operand"
7351 (match_operand:SDF 4 "s_register_operand"
7352 "<F_constraint>")))]
7353 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7356 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7363 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7368 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7374 [(set_attr "conds" "use")
7375 (set_attr "type" "fcsel")]
7378 (define_insn "*cmovhf"
7379 [(set (match_operand:HF 0 "s_register_operand" "=t")
7380 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7381 [(match_operand 2 "cc_register" "") (const_int 0)])
7382 (match_operand:HF 3 "s_register_operand" "t")
7383 (match_operand:HF 4 "s_register_operand" "t")))]
7384 "TARGET_VFP_FP16INST"
7387 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7394 return \"vsel%d1.f16\\t%0, %3, %4\";
7399 return \"vsel%D1.f16\\t%0, %4, %3\";
7405 [(set_attr "conds" "use")
7406 (set_attr "type" "fcsel")]
7409 (define_insn_and_split "*movsicc_insn"
7410 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7412 (match_operator 3 "arm_comparison_operator"
7413 [(match_operand 4 "cc_register" "") (const_int 0)])
7414 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7415 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7426 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7427 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7428 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7429 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7430 "&& reload_completed"
7433 enum rtx_code rev_code;
7437 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7439 gen_rtx_SET (operands[0], operands[1])));
7441 rev_code = GET_CODE (operands[3]);
7442 mode = GET_MODE (operands[4]);
7443 if (mode == CCFPmode || mode == CCFPEmode)
7444 rev_code = reverse_condition_maybe_unordered (rev_code);
7446 rev_code = reverse_condition (rev_code);
7448 rev_cond = gen_rtx_fmt_ee (rev_code,
7452 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7454 gen_rtx_SET (operands[0], operands[2])));
7457 [(set_attr "length" "4,4,4,4,8,8,8,8")
7458 (set_attr "conds" "use")
7459 (set_attr_alternative "type"
7460 [(if_then_else (match_operand 2 "const_int_operand" "")
7461 (const_string "mov_imm")
7462 (const_string "mov_reg"))
7463 (const_string "mvn_imm")
7464 (if_then_else (match_operand 1 "const_int_operand" "")
7465 (const_string "mov_imm")
7466 (const_string "mov_reg"))
7467 (const_string "mvn_imm")
7468 (const_string "multiple")
7469 (const_string "multiple")
7470 (const_string "multiple")
7471 (const_string "multiple")])]
7474 (define_insn "*movsfcc_soft_insn"
7475 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7476 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7477 [(match_operand 4 "cc_register" "") (const_int 0)])
7478 (match_operand:SF 1 "s_register_operand" "0,r")
7479 (match_operand:SF 2 "s_register_operand" "r,0")))]
7480 "TARGET_ARM && TARGET_SOFT_FLOAT"
7484 [(set_attr "conds" "use")
7485 (set_attr "type" "mov_reg")]
7489 ;; Jump and linkage insns
7491 (define_expand "jump"
7493 (label_ref (match_operand 0 "" "")))]
7498 (define_insn "*arm_jump"
7500 (label_ref (match_operand 0 "" "")))]
7504 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7506 arm_ccfsm_state += 2;
7509 return \"b%?\\t%l0\";
7512 [(set_attr "predicable" "yes")
7513 (set (attr "length")
7515 (and (match_test "TARGET_THUMB2")
7516 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7517 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7520 (set_attr "type" "branch")]
7523 (define_expand "call"
7524 [(parallel [(call (match_operand 0 "memory_operand")
7525 (match_operand 1 "general_operand"))
7526 (use (match_operand 2 "" ""))
7527 (clobber (reg:SI LR_REGNUM))])]
7532 tree addr = MEM_EXPR (operands[0]);
7534 /* In an untyped call, we can get NULL for operand 2. */
7535 if (operands[2] == NULL_RTX)
7536 operands[2] = const0_rtx;
7538 /* Decide if we should generate indirect calls by loading the
7539 32-bit address of the callee into a register before performing the
7541 callee = XEXP (operands[0], 0);
7542 if (GET_CODE (callee) == SYMBOL_REF
7543 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7545 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7547 if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[0], 0)))
7548 /* Indirect call: set r9 with FDPIC value of callee. */
7549 XEXP (operands[0], 0)
7550 = arm_load_function_descriptor (XEXP (operands[0], 0));
7552 if (detect_cmse_nonsecure_call (addr))
7554 pat = gen_nonsecure_call_internal (operands[0], operands[1],
7556 emit_call_insn (pat);
7560 pat = gen_call_internal (operands[0], operands[1], operands[2]);
7561 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7564 /* Restore FDPIC register (r9) after call. */
7567 rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
7568 rtx initial_fdpic_reg
7569 = get_hard_reg_initial_val (Pmode, FDPIC_REGNUM);
7571 emit_insn (gen_restore_pic_register_after_call (fdpic_reg,
7572 initial_fdpic_reg));
7579 (define_insn "restore_pic_register_after_call"
7580 [(set (match_operand:SI 0 "s_register_operand" "+r,r")
7581 (unspec:SI [(match_dup 0)
7582 (match_operand:SI 1 "nonimmediate_operand" "r,m")]
7583 UNSPEC_PIC_RESTORE))]
7590 (define_expand "call_internal"
7591 [(parallel [(call (match_operand 0 "memory_operand")
7592 (match_operand 1 "general_operand"))
7593 (use (match_operand 2 "" ""))
7594 (clobber (reg:SI LR_REGNUM))])])
7596 (define_expand "nonsecure_call_internal"
7597 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand")]
7598 UNSPEC_NONSECURE_MEM)
7599 (match_operand 1 "general_operand"))
7600 (use (match_operand 2 "" ""))
7601 (clobber (reg:SI LR_REGNUM))])]
7606 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
7607 gen_rtx_REG (SImode, R4_REGNUM),
7610 operands[0] = replace_equiv_address (operands[0], tmp);
7613 (define_insn "*call_reg_armv5"
7614 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7615 (match_operand 1 "" ""))
7616 (use (match_operand 2 "" ""))
7617 (clobber (reg:SI LR_REGNUM))]
7618 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
7620 [(set_attr "type" "call")]
7623 (define_insn "*call_reg_arm"
7624 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7625 (match_operand 1 "" ""))
7626 (use (match_operand 2 "" ""))
7627 (clobber (reg:SI LR_REGNUM))]
7628 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
7630 return output_call (operands);
7632 ;; length is worst case, normally it is only two
7633 [(set_attr "length" "12")
7634 (set_attr "type" "call")]
7638 (define_expand "call_value"
7639 [(parallel [(set (match_operand 0 "" "")
7640 (call (match_operand 1 "memory_operand")
7641 (match_operand 2 "general_operand")))
7642 (use (match_operand 3 "" ""))
7643 (clobber (reg:SI LR_REGNUM))])]
7648 tree addr = MEM_EXPR (operands[1]);
7650 /* In an untyped call, we can get NULL for operand 2. */
7651 if (operands[3] == 0)
7652 operands[3] = const0_rtx;
7654 /* Decide if we should generate indirect calls by loading the
7655 32-bit address of the callee into a register before performing the
7657 callee = XEXP (operands[1], 0);
7658 if (GET_CODE (callee) == SYMBOL_REF
7659 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7661 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7663 if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[1], 0)))
7664 /* Indirect call: set r9 with FDPIC value of callee. */
7665 XEXP (operands[1], 0)
7666 = arm_load_function_descriptor (XEXP (operands[1], 0));
7668 if (detect_cmse_nonsecure_call (addr))
7670 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
7671 operands[2], operands[3]);
7672 emit_call_insn (pat);
7676 pat = gen_call_value_internal (operands[0], operands[1],
7677 operands[2], operands[3]);
7678 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7681 /* Restore FDPIC register (r9) after call. */
7684 rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
7685 rtx initial_fdpic_reg
7686 = get_hard_reg_initial_val (Pmode, FDPIC_REGNUM);
7688 emit_insn (gen_restore_pic_register_after_call (fdpic_reg,
7689 initial_fdpic_reg));
7696 (define_expand "call_value_internal"
7697 [(parallel [(set (match_operand 0 "" "")
7698 (call (match_operand 1 "memory_operand")
7699 (match_operand 2 "general_operand")))
7700 (use (match_operand 3 "" ""))
7701 (clobber (reg:SI LR_REGNUM))])])
7703 (define_expand "nonsecure_call_value_internal"
7704 [(parallel [(set (match_operand 0 "" "")
7705 (call (unspec:SI [(match_operand 1 "memory_operand")]
7706 UNSPEC_NONSECURE_MEM)
7707 (match_operand 2 "general_operand")))
7708 (use (match_operand 3 "" ""))
7709 (clobber (reg:SI LR_REGNUM))])]
7714 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
7715 gen_rtx_REG (SImode, R4_REGNUM),
7718 operands[1] = replace_equiv_address (operands[1], tmp);
7721 (define_insn "*call_value_reg_armv5"
7722 [(set (match_operand 0 "" "")
7723 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7724 (match_operand 2 "" "")))
7725 (use (match_operand 3 "" ""))
7726 (clobber (reg:SI LR_REGNUM))]
7727 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
7729 [(set_attr "type" "call")]
7732 (define_insn "*call_value_reg_arm"
7733 [(set (match_operand 0 "" "")
7734 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7735 (match_operand 2 "" "")))
7736 (use (match_operand 3 "" ""))
7737 (clobber (reg:SI LR_REGNUM))]
7738 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
7740 return output_call (&operands[1]);
7742 [(set_attr "length" "12")
7743 (set_attr "type" "call")]
7746 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7747 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7749 (define_insn "*call_symbol"
7750 [(call (mem:SI (match_operand:SI 0 "" ""))
7751 (match_operand 1 "" ""))
7752 (use (match_operand 2 "" ""))
7753 (clobber (reg:SI LR_REGNUM))]
7755 && !SIBLING_CALL_P (insn)
7756 && (GET_CODE (operands[0]) == SYMBOL_REF)
7757 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7760 rtx op = operands[0];
7762 /* Switch mode now when possible. */
7763 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7764 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7765 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7767 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7769 [(set_attr "type" "call")]
7772 (define_insn "*call_value_symbol"
7773 [(set (match_operand 0 "" "")
7774 (call (mem:SI (match_operand:SI 1 "" ""))
7775 (match_operand:SI 2 "" "")))
7776 (use (match_operand 3 "" ""))
7777 (clobber (reg:SI LR_REGNUM))]
7779 && !SIBLING_CALL_P (insn)
7780 && (GET_CODE (operands[1]) == SYMBOL_REF)
7781 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7784 rtx op = operands[1];
7786 /* Switch mode now when possible. */
7787 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7788 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7789 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
7791 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7793 [(set_attr "type" "call")]
7796 (define_expand "sibcall_internal"
7797 [(parallel [(call (match_operand 0 "memory_operand")
7798 (match_operand 1 "general_operand"))
7800 (use (match_operand 2 "" ""))])])
7802 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7803 (define_expand "sibcall"
7804 [(parallel [(call (match_operand 0 "memory_operand")
7805 (match_operand 1 "general_operand"))
7807 (use (match_operand 2 "" ""))])]
7813 if ((!REG_P (XEXP (operands[0], 0))
7814 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7815 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7816 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7817 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7819 if (operands[2] == NULL_RTX)
7820 operands[2] = const0_rtx;
7822 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7823 arm_emit_call_insn (pat, operands[0], true);
7828 (define_expand "sibcall_value_internal"
7829 [(parallel [(set (match_operand 0 "" "")
7830 (call (match_operand 1 "memory_operand")
7831 (match_operand 2 "general_operand")))
7833 (use (match_operand 3 "" ""))])])
7835 (define_expand "sibcall_value"
7836 [(parallel [(set (match_operand 0 "" "")
7837 (call (match_operand 1 "memory_operand")
7838 (match_operand 2 "general_operand")))
7840 (use (match_operand 3 "" ""))])]
7846 if ((!REG_P (XEXP (operands[1], 0))
7847 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7848 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7849 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7850 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7852 if (operands[3] == NULL_RTX)
7853 operands[3] = const0_rtx;
7855 pat = gen_sibcall_value_internal (operands[0], operands[1],
7856 operands[2], operands[3]);
7857 arm_emit_call_insn (pat, operands[1], true);
7862 (define_insn "*sibcall_insn"
7863 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7864 (match_operand 1 "" ""))
7866 (use (match_operand 2 "" ""))]
7867 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7869 if (which_alternative == 1)
7870 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7873 if (arm_arch5t || arm_arch4t)
7874 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7876 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7879 [(set_attr "type" "call")]
7882 (define_insn "*sibcall_value_insn"
7883 [(set (match_operand 0 "" "")
7884 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7885 (match_operand 2 "" "")))
7887 (use (match_operand 3 "" ""))]
7888 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7890 if (which_alternative == 1)
7891 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7894 if (arm_arch5t || arm_arch4t)
7895 return \"bx%?\\t%1\";
7897 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7900 [(set_attr "type" "call")]
7903 (define_expand "<return_str>return"
7905 "(TARGET_ARM || (TARGET_THUMB2
7906 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7907 && !IS_STACKALIGN (arm_current_func_type ())))
7908 <return_cond_false>"
7913 thumb2_expand_return (<return_simple_p>);
7920 ;; Often the return insn will be the same as loading from memory, so set attr
7921 (define_insn "*arm_return"
7923 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7926 if (arm_ccfsm_state == 2)
7928 arm_ccfsm_state += 2;
7931 return output_return_instruction (const_true_rtx, true, false, false);
7933 [(set_attr "type" "load_4")
7934 (set_attr "length" "12")
7935 (set_attr "predicable" "yes")]
7938 (define_insn "*cond_<return_str>return"
7940 (if_then_else (match_operator 0 "arm_comparison_operator"
7941 [(match_operand 1 "cc_register" "") (const_int 0)])
7944 "TARGET_ARM <return_cond_true>"
7947 if (arm_ccfsm_state == 2)
7949 arm_ccfsm_state += 2;
7952 return output_return_instruction (operands[0], true, false,
7955 [(set_attr "conds" "use")
7956 (set_attr "length" "12")
7957 (set_attr "type" "load_4")]
7960 (define_insn "*cond_<return_str>return_inverted"
7962 (if_then_else (match_operator 0 "arm_comparison_operator"
7963 [(match_operand 1 "cc_register" "") (const_int 0)])
7966 "TARGET_ARM <return_cond_true>"
7969 if (arm_ccfsm_state == 2)
7971 arm_ccfsm_state += 2;
7974 return output_return_instruction (operands[0], true, true,
7977 [(set_attr "conds" "use")
7978 (set_attr "length" "12")
7979 (set_attr "type" "load_4")]
7982 (define_insn "*arm_simple_return"
7987 if (arm_ccfsm_state == 2)
7989 arm_ccfsm_state += 2;
7992 return output_return_instruction (const_true_rtx, true, false, true);
7994 [(set_attr "type" "branch")
7995 (set_attr "length" "4")
7996 (set_attr "predicable" "yes")]
7999 ;; Generate a sequence of instructions to determine if the processor is
8000 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8003 (define_expand "return_addr_mask"
8005 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8007 (set (match_operand:SI 0 "s_register_operand")
8008 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8010 (const_int 67108860)))] ; 0x03fffffc
8013 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8016 (define_insn "*check_arch2"
8017 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8018 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8021 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8022 [(set_attr "length" "8")
8023 (set_attr "conds" "set")
8024 (set_attr "type" "multiple")]
8027 ;; Call subroutine returning any type.
8029 (define_expand "untyped_call"
8030 [(parallel [(call (match_operand 0 "" "")
8032 (match_operand 1 "" "")
8033 (match_operand 2 "" "")])]
8034 "TARGET_EITHER && !TARGET_FDPIC"
8038 rtx par = gen_rtx_PARALLEL (VOIDmode,
8039 rtvec_alloc (XVECLEN (operands[2], 0)));
8040 rtx addr = gen_reg_rtx (Pmode);
8044 emit_move_insn (addr, XEXP (operands[1], 0));
8045 mem = change_address (operands[1], BLKmode, addr);
8047 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8049 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8051 /* Default code only uses r0 as a return value, but we could
8052 be using anything up to 4 registers. */
8053 if (REGNO (src) == R0_REGNUM)
8054 src = gen_rtx_REG (TImode, R0_REGNUM);
8056 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8058 size += GET_MODE_SIZE (GET_MODE (src));
8061 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8065 for (i = 0; i < XVECLEN (par, 0); i++)
8067 HOST_WIDE_INT offset = 0;
8068 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8071 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8073 mem = change_address (mem, GET_MODE (reg), NULL);
8074 if (REGNO (reg) == R0_REGNUM)
8076 /* On thumb we have to use a write-back instruction. */
8077 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8078 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8079 size = TARGET_ARM ? 16 : 0;
8083 emit_move_insn (mem, reg);
8084 size = GET_MODE_SIZE (GET_MODE (reg));
8088 /* The optimizer does not know that the call sets the function value
8089 registers we stored in the result block. We avoid problems by
8090 claiming that all hard registers are used and clobbered at this
8092 emit_insn (gen_blockage ());
8098 (define_expand "untyped_return"
8099 [(match_operand:BLK 0 "memory_operand")
8100 (match_operand 1 "" "")]
8101 "TARGET_EITHER && !TARGET_FDPIC"
8105 rtx addr = gen_reg_rtx (Pmode);
8109 emit_move_insn (addr, XEXP (operands[0], 0));
8110 mem = change_address (operands[0], BLKmode, addr);
8112 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8114 HOST_WIDE_INT offset = 0;
8115 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8118 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8120 mem = change_address (mem, GET_MODE (reg), NULL);
8121 if (REGNO (reg) == R0_REGNUM)
8123 /* On thumb we have to use a write-back instruction. */
8124 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8125 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8126 size = TARGET_ARM ? 16 : 0;
8130 emit_move_insn (reg, mem);
8131 size = GET_MODE_SIZE (GET_MODE (reg));
8135 /* Emit USE insns before the return. */
8136 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8137 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8139 /* Construct the return. */
8140 expand_naked_return ();
8146 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8147 ;; all of memory. This blocks insns from being moved across this point.
8149 (define_insn "blockage"
8150 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8153 [(set_attr "length" "0")
8154 (set_attr "type" "block")]
8157 ;; Since we hard code r0 here use the 'o' constraint to prevent
8158 ;; provoking undefined behaviour in the hardware with putting out
8159 ;; auto-increment operations with potentially r0 as the base register.
8160 (define_insn "probe_stack"
8161 [(set (match_operand:SI 0 "memory_operand" "=o")
8162 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8165 [(set_attr "type" "store_4")
8166 (set_attr "predicable" "yes")]
8169 (define_insn "probe_stack_range"
8170 [(set (match_operand:SI 0 "register_operand" "=r")
8171 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8172 (match_operand:SI 2 "register_operand" "r")]
8173 VUNSPEC_PROBE_STACK_RANGE))]
8176 return output_probe_stack_range (operands[0], operands[2]);
8178 [(set_attr "type" "multiple")
8179 (set_attr "conds" "clob")]
8182 ;; Named patterns for stack smashing protection.
8183 (define_expand "stack_protect_combined_set"
8185 [(set (match_operand:SI 0 "memory_operand")
8186 (unspec:SI [(match_operand:SI 1 "guard_operand")]
8188 (clobber (match_scratch:SI 2 ""))
8189 (clobber (match_scratch:SI 3 ""))])]
8194 ;; Use a separate insn from the above expand to be able to have the mem outside
8195 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8196 ;; try to reload the guard since we need to control how PIC access is done in
8197 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8198 ;; legitimize_pic_address ()).
8199 (define_insn_and_split "*stack_protect_combined_set_insn"
8200 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8201 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8203 (clobber (match_scratch:SI 2 "=&l,&r"))
8204 (clobber (match_scratch:SI 3 "=&l,&r"))]
8208 [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))]
8210 (clobber (match_dup 2))])]
8218 pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
8220 pic_reg = operands[3];
8222 /* Forces recomputing of GOT base now. */
8223 legitimize_pic_address (operands[1], SImode, operands[2], pic_reg,
8224 true /*compute_now*/);
8228 if (address_operand (operands[1], SImode))
8229 operands[2] = operands[1];
8232 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8233 emit_move_insn (operands[2], mem);
8237 [(set_attr "arch" "t1,32")]
8240 ;; DO NOT SPLIT THIS INSN. It's important for security reasons that the
8241 ;; canary value does not live beyond the life of this sequence.
8242 (define_insn "*stack_protect_set_insn"
8243 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8244 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))]
8246 (clobber (match_dup 1))]
8249 ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1, #0
8250 ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1, #0"
8251 [(set_attr "length" "8,12")
8252 (set_attr "conds" "clob,nocond")
8253 (set_attr "type" "multiple")
8254 (set_attr "arch" "t1,32")]
8257 (define_expand "stack_protect_combined_test"
8261 (eq (match_operand:SI 0 "memory_operand")
8262 (unspec:SI [(match_operand:SI 1 "guard_operand")]
8264 (label_ref (match_operand 2))
8266 (clobber (match_scratch:SI 3 ""))
8267 (clobber (match_scratch:SI 4 ""))
8268 (clobber (reg:CC CC_REGNUM))])]
8273 ;; Use a separate insn from the above expand to be able to have the mem outside
8274 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8275 ;; try to reload the guard since we need to control how PIC access is done in
8276 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8277 ;; legitimize_pic_address ()).
8278 (define_insn_and_split "*stack_protect_combined_test_insn"
8281 (eq (match_operand:SI 0 "memory_operand" "m,m")
8282 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8284 (label_ref (match_operand 2))
8286 (clobber (match_scratch:SI 3 "=&l,&r"))
8287 (clobber (match_scratch:SI 4 "=&l,&r"))
8288 (clobber (reg:CC CC_REGNUM))]
8301 pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
8303 pic_reg = operands[4];
8305 /* Forces recomputing of GOT base now. */
8306 legitimize_pic_address (operands[1], SImode, operands[3], pic_reg,
8307 true /*compute_now*/);
8311 if (address_operand (operands[1], SImode))
8312 operands[3] = operands[1];
8315 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8316 emit_move_insn (operands[3], mem);
8321 emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0],
8323 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
8324 eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx);
8325 emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg));
8329 emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0],
8331 eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
8332 emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx,
8337 [(set_attr "arch" "t1,32")]
8340 (define_insn "arm_stack_protect_test_insn"
8341 [(set (reg:CC_Z CC_REGNUM)
8342 (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m")
8343 (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))]
8346 (clobber (match_operand:SI 0 "register_operand" "=&l,&r"))
8347 (clobber (match_dup 2))]
8349 "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0"
8350 [(set_attr "length" "8,12")
8351 (set_attr "conds" "set")
8352 (set_attr "type" "multiple")
8353 (set_attr "arch" "t,32")]
8356 (define_expand "casesi"
8357 [(match_operand:SI 0 "s_register_operand") ; index to jump on
8358 (match_operand:SI 1 "const_int_operand") ; lower bound
8359 (match_operand:SI 2 "const_int_operand") ; total range
8360 (match_operand:SI 3 "" "") ; table label
8361 (match_operand:SI 4 "" "")] ; Out of range label
8362 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8365 enum insn_code code;
8366 if (operands[1] != const0_rtx)
8368 rtx reg = gen_reg_rtx (SImode);
8370 emit_insn (gen_addsi3 (reg, operands[0],
8371 gen_int_mode (-INTVAL (operands[1]),
8377 code = CODE_FOR_arm_casesi_internal;
8378 else if (TARGET_THUMB1)
8379 code = CODE_FOR_thumb1_casesi_internal_pic;
8381 code = CODE_FOR_thumb2_casesi_internal_pic;
8383 code = CODE_FOR_thumb2_casesi_internal;
8385 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8386 operands[2] = force_reg (SImode, operands[2]);
8388 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8389 operands[3], operands[4]));
8394 ;; The USE in this pattern is needed to tell flow analysis that this is
8395 ;; a CASESI insn. It has no other purpose.
8396 (define_expand "arm_casesi_internal"
8397 [(parallel [(set (pc)
8399 (leu (match_operand:SI 0 "s_register_operand")
8400 (match_operand:SI 1 "arm_rhs_operand"))
8402 (label_ref:SI (match_operand 3 ""))))
8403 (clobber (reg:CC CC_REGNUM))
8404 (use (label_ref:SI (match_operand 2 "")))])]
8407 operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
8408 operands[4] = gen_rtx_PLUS (SImode, operands[4],
8409 gen_rtx_LABEL_REF (SImode, operands[2]));
8410 operands[4] = gen_rtx_MEM (SImode, operands[4]);
8411 MEM_READONLY_P (operands[4]) = 1;
8412 MEM_NOTRAP_P (operands[4]) = 1;
8415 (define_insn "*arm_casesi_internal"
8416 [(parallel [(set (pc)
8418 (leu (match_operand:SI 0 "s_register_operand" "r")
8419 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8420 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8421 (label_ref:SI (match_operand 2 "" ""))))
8422 (label_ref:SI (match_operand 3 "" ""))))
8423 (clobber (reg:CC CC_REGNUM))
8424 (use (label_ref:SI (match_dup 2)))])]
8428 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8429 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8431 [(set_attr "conds" "clob")
8432 (set_attr "length" "12")
8433 (set_attr "type" "multiple")]
8436 (define_expand "indirect_jump"
8438 (match_operand:SI 0 "s_register_operand"))]
8441 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8442 address and use bx. */
8446 tmp = gen_reg_rtx (SImode);
8447 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8453 ;; NB Never uses BX.
8454 (define_insn "*arm_indirect_jump"
8456 (match_operand:SI 0 "s_register_operand" "r"))]
8458 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8459 [(set_attr "predicable" "yes")
8460 (set_attr "type" "branch")]
8463 (define_insn "*load_indirect_jump"
8465 (match_operand:SI 0 "memory_operand" "m"))]
8467 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8468 [(set_attr "type" "load_4")
8469 (set_attr "pool_range" "4096")
8470 (set_attr "neg_pool_range" "4084")
8471 (set_attr "predicable" "yes")]
8481 [(set (attr "length")
8482 (if_then_else (eq_attr "is_thumb" "yes")
8485 (set_attr "type" "mov_reg")]
8489 [(trap_if (const_int 1) (const_int 0))]
8493 return \".inst\\t0xe7f000f0\";
8495 return \".inst\\t0xdeff\";
8497 [(set (attr "length")
8498 (if_then_else (eq_attr "is_thumb" "yes")
8501 (set_attr "type" "trap")
8502 (set_attr "conds" "unconditional")]
8506 ;; Patterns to allow combination of arithmetic, cond code and shifts
8508 (define_insn "*<arith_shift_insn>_multsi"
8509 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8511 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8512 (match_operand:SI 3 "power_of_two_operand" ""))
8513 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8515 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8516 [(set_attr "predicable" "yes")
8517 (set_attr "shift" "2")
8518 (set_attr "arch" "a,t2")
8519 (set_attr "type" "alu_shift_imm")])
8521 (define_insn "*<arith_shift_insn>_shiftsi"
8522 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8524 (match_operator:SI 2 "shift_nomul_operator"
8525 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8526 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8527 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8528 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8529 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8530 [(set_attr "predicable" "yes")
8531 (set_attr "shift" "3")
8532 (set_attr "arch" "a,t2,a")
8533 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8536 [(set (match_operand:SI 0 "s_register_operand" "")
8537 (match_operator:SI 1 "shiftable_operator"
8538 [(match_operator:SI 2 "shiftable_operator"
8539 [(match_operator:SI 3 "shift_operator"
8540 [(match_operand:SI 4 "s_register_operand" "")
8541 (match_operand:SI 5 "reg_or_int_operand" "")])
8542 (match_operand:SI 6 "s_register_operand" "")])
8543 (match_operand:SI 7 "arm_rhs_operand" "")]))
8544 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8547 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8550 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8553 (define_insn "*arith_shiftsi_compare0"
8554 [(set (reg:CC_NOOV CC_REGNUM)
8556 (match_operator:SI 1 "shiftable_operator"
8557 [(match_operator:SI 3 "shift_operator"
8558 [(match_operand:SI 4 "s_register_operand" "r,r")
8559 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8560 (match_operand:SI 2 "s_register_operand" "r,r")])
8562 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8563 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8566 "%i1s%?\\t%0, %2, %4%S3"
8567 [(set_attr "conds" "set")
8568 (set_attr "shift" "4")
8569 (set_attr "arch" "32,a")
8570 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8572 (define_insn "*arith_shiftsi_compare0_scratch"
8573 [(set (reg:CC_NOOV CC_REGNUM)
8575 (match_operator:SI 1 "shiftable_operator"
8576 [(match_operator:SI 3 "shift_operator"
8577 [(match_operand:SI 4 "s_register_operand" "r,r")
8578 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8579 (match_operand:SI 2 "s_register_operand" "r,r")])
8581 (clobber (match_scratch:SI 0 "=r,r"))]
8583 "%i1s%?\\t%0, %2, %4%S3"
8584 [(set_attr "conds" "set")
8585 (set_attr "shift" "4")
8586 (set_attr "arch" "32,a")
8587 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8589 (define_insn "*sub_shiftsi"
8590 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8591 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8592 (match_operator:SI 2 "shift_operator"
8593 [(match_operand:SI 3 "s_register_operand" "r,r")
8594 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8596 "sub%?\\t%0, %1, %3%S2"
8597 [(set_attr "predicable" "yes")
8598 (set_attr "predicable_short_it" "no")
8599 (set_attr "shift" "3")
8600 (set_attr "arch" "32,a")
8601 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8603 (define_insn "*sub_shiftsi_compare0"
8604 [(set (reg:CC_NOOV CC_REGNUM)
8606 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8607 (match_operator:SI 2 "shift_operator"
8608 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8609 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8611 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8612 (minus:SI (match_dup 1)
8613 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8615 "subs%?\\t%0, %1, %3%S2"
8616 [(set_attr "conds" "set")
8617 (set_attr "shift" "3")
8618 (set_attr "arch" "32,a,a")
8619 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8621 (define_insn "*sub_shiftsi_compare0_scratch"
8622 [(set (reg:CC_NOOV CC_REGNUM)
8624 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8625 (match_operator:SI 2 "shift_operator"
8626 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8627 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8629 (clobber (match_scratch:SI 0 "=r,r,r"))]
8631 "subs%?\\t%0, %1, %3%S2"
8632 [(set_attr "conds" "set")
8633 (set_attr "shift" "3")
8634 (set_attr "arch" "32,a,a")
8635 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8638 (define_insn_and_split "*and_scc"
8639 [(set (match_operand:SI 0 "s_register_operand" "=r")
8640 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8641 [(match_operand 2 "cc_register" "") (const_int 0)])
8642 (match_operand:SI 3 "s_register_operand" "r")))]
8644 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8645 "&& reload_completed"
8646 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8647 (cond_exec (match_dup 4) (set (match_dup 0)
8648 (and:SI (match_dup 3) (const_int 1))))]
8650 machine_mode mode = GET_MODE (operands[2]);
8651 enum rtx_code rc = GET_CODE (operands[1]);
8653 /* Note that operands[4] is the same as operands[1],
8654 but with VOIDmode as the result. */
8655 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8656 if (mode == CCFPmode || mode == CCFPEmode)
8657 rc = reverse_condition_maybe_unordered (rc);
8659 rc = reverse_condition (rc);
8660 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8662 [(set_attr "conds" "use")
8663 (set_attr "type" "multiple")
8664 (set_attr "length" "8")]
8667 (define_insn_and_split "*ior_scc"
8668 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8669 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8670 [(match_operand 2 "cc_register" "") (const_int 0)])
8671 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8676 "&& reload_completed
8677 && REGNO (operands [0]) != REGNO (operands[3])"
8678 ;; && which_alternative == 1
8679 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8680 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8681 (cond_exec (match_dup 4) (set (match_dup 0)
8682 (ior:SI (match_dup 3) (const_int 1))))]
8684 machine_mode mode = GET_MODE (operands[2]);
8685 enum rtx_code rc = GET_CODE (operands[1]);
8687 /* Note that operands[4] is the same as operands[1],
8688 but with VOIDmode as the result. */
8689 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8690 if (mode == CCFPmode || mode == CCFPEmode)
8691 rc = reverse_condition_maybe_unordered (rc);
8693 rc = reverse_condition (rc);
8694 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8696 [(set_attr "conds" "use")
8697 (set_attr "length" "4,8")
8698 (set_attr "type" "logic_imm,multiple")]
8701 ; A series of splitters for the compare_scc pattern below. Note that
8702 ; order is important.
8704 [(set (match_operand:SI 0 "s_register_operand" "")
8705 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8707 (clobber (reg:CC CC_REGNUM))]
8708 "TARGET_32BIT && reload_completed"
8709 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8712 [(set (match_operand:SI 0 "s_register_operand" "")
8713 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8715 (clobber (reg:CC CC_REGNUM))]
8716 "TARGET_32BIT && reload_completed"
8717 [(set (match_dup 0) (not:SI (match_dup 1)))
8718 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8721 [(set (match_operand:SI 0 "s_register_operand" "")
8722 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8724 (clobber (reg:CC CC_REGNUM))]
8725 "arm_arch5t && TARGET_32BIT"
8726 [(set (match_dup 0) (clz:SI (match_dup 1)))
8727 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8731 [(set (match_operand:SI 0 "s_register_operand" "")
8732 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8734 (clobber (reg:CC CC_REGNUM))]
8735 "TARGET_32BIT && reload_completed"
8737 [(set (reg:CC CC_REGNUM)
8738 (compare:CC (const_int 1) (match_dup 1)))
8740 (minus:SI (const_int 1) (match_dup 1)))])
8741 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8742 (set (match_dup 0) (const_int 0)))])
8745 [(set (match_operand:SI 0 "s_register_operand" "")
8746 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8747 (match_operand:SI 2 "const_int_operand" "")))
8748 (clobber (reg:CC CC_REGNUM))]
8749 "TARGET_32BIT && reload_completed"
8751 [(set (reg:CC CC_REGNUM)
8752 (compare:CC (match_dup 1) (match_dup 2)))
8753 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8754 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8755 (set (match_dup 0) (const_int 1)))]
8757 operands[3] = gen_int_mode (-INTVAL (operands[2]), SImode);
8761 [(set (match_operand:SI 0 "s_register_operand" "")
8762 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8763 (match_operand:SI 2 "arm_add_operand" "")))
8764 (clobber (reg:CC CC_REGNUM))]
8765 "TARGET_32BIT && reload_completed"
8767 [(set (reg:CC_NOOV CC_REGNUM)
8768 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8770 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8771 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8772 (set (match_dup 0) (const_int 1)))])
8774 (define_insn_and_split "*compare_scc"
8775 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8776 (match_operator:SI 1 "arm_comparison_operator"
8777 [(match_operand:SI 2 "s_register_operand" "r,r")
8778 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8779 (clobber (reg:CC CC_REGNUM))]
8782 "&& reload_completed"
8783 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8784 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8785 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8788 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8789 operands[2], operands[3]);
8790 enum rtx_code rc = GET_CODE (operands[1]);
8792 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8794 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8795 if (mode == CCFPmode || mode == CCFPEmode)
8796 rc = reverse_condition_maybe_unordered (rc);
8798 rc = reverse_condition (rc);
8799 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8801 [(set_attr "type" "multiple")]
8804 ;; Attempt to improve the sequence generated by the compare_scc splitters
8805 ;; not to use conditional execution.
8807 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
8811 [(set (reg:CC CC_REGNUM)
8812 (compare:CC (match_operand:SI 1 "register_operand" "")
8814 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8815 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8816 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8817 (set (match_dup 0) (const_int 1)))]
8818 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8819 [(set (match_dup 0) (clz:SI (match_dup 1)))
8820 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8823 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8827 [(set (reg:CC CC_REGNUM)
8828 (compare:CC (match_operand:SI 1 "register_operand" "")
8830 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8831 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8832 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8833 (set (match_dup 0) (const_int 1)))
8834 (match_scratch:SI 2 "r")]
8835 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8837 [(set (reg:CC CC_REGNUM)
8838 (compare:CC (const_int 0) (match_dup 1)))
8839 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8841 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8842 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8845 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
8846 ;; sub Rd, Reg1, reg2
8850 [(set (reg:CC CC_REGNUM)
8851 (compare:CC (match_operand:SI 1 "register_operand" "")
8852 (match_operand:SI 2 "arm_rhs_operand" "")))
8853 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8854 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8855 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8856 (set (match_dup 0) (const_int 1)))]
8857 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8858 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8859 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8860 (set (match_dup 0) (clz:SI (match_dup 0)))
8861 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8865 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
8866 ;; sub T1, Reg1, reg2
8870 [(set (reg:CC CC_REGNUM)
8871 (compare:CC (match_operand:SI 1 "register_operand" "")
8872 (match_operand:SI 2 "arm_rhs_operand" "")))
8873 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8874 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8875 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8876 (set (match_dup 0) (const_int 1)))
8877 (match_scratch:SI 3 "r")]
8878 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8879 [(set (match_dup 3) (match_dup 4))
8881 [(set (reg:CC CC_REGNUM)
8882 (compare:CC (const_int 0) (match_dup 3)))
8883 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8885 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8886 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8888 if (CONST_INT_P (operands[2]))
8889 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8891 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8894 (define_insn "*cond_move"
8895 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8896 (if_then_else:SI (match_operator 3 "equality_operator"
8897 [(match_operator 4 "arm_comparison_operator"
8898 [(match_operand 5 "cc_register" "") (const_int 0)])
8900 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8901 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8904 if (GET_CODE (operands[3]) == NE)
8906 if (which_alternative != 1)
8907 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8908 if (which_alternative != 0)
8909 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8912 if (which_alternative != 0)
8913 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8914 if (which_alternative != 1)
8915 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8918 [(set_attr "conds" "use")
8919 (set_attr_alternative "type"
8920 [(if_then_else (match_operand 2 "const_int_operand" "")
8921 (const_string "mov_imm")
8922 (const_string "mov_reg"))
8923 (if_then_else (match_operand 1 "const_int_operand" "")
8924 (const_string "mov_imm")
8925 (const_string "mov_reg"))
8926 (const_string "multiple")])
8927 (set_attr "length" "4,4,8")]
8930 (define_insn "*cond_arith"
8931 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8932 (match_operator:SI 5 "shiftable_operator"
8933 [(match_operator:SI 4 "arm_comparison_operator"
8934 [(match_operand:SI 2 "s_register_operand" "r,r")
8935 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8936 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8937 (clobber (reg:CC CC_REGNUM))]
8940 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8941 return \"%i5\\t%0, %1, %2, lsr #31\";
8943 output_asm_insn (\"cmp\\t%2, %3\", operands);
8944 if (GET_CODE (operands[5]) == AND)
8945 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8946 else if (GET_CODE (operands[5]) == MINUS)
8947 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8948 else if (which_alternative != 0)
8949 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8950 return \"%i5%d4\\t%0, %1, #1\";
8952 [(set_attr "conds" "clob")
8953 (set_attr "length" "12")
8954 (set_attr "type" "multiple")]
8957 (define_insn "*cond_sub"
8958 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8959 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8960 (match_operator:SI 4 "arm_comparison_operator"
8961 [(match_operand:SI 2 "s_register_operand" "r,r")
8962 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8963 (clobber (reg:CC CC_REGNUM))]
8966 output_asm_insn (\"cmp\\t%2, %3\", operands);
8967 if (which_alternative != 0)
8968 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8969 return \"sub%d4\\t%0, %1, #1\";
8971 [(set_attr "conds" "clob")
8972 (set_attr "length" "8,12")
8973 (set_attr "type" "multiple")]
8976 (define_insn "*cmp_ite0"
8977 [(set (match_operand 6 "dominant_cc_register" "")
8980 (match_operator 4 "arm_comparison_operator"
8981 [(match_operand:SI 0 "s_register_operand"
8982 "l,l,l,r,r,r,r,r,r")
8983 (match_operand:SI 1 "arm_add_operand"
8984 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8985 (match_operator:SI 5 "arm_comparison_operator"
8986 [(match_operand:SI 2 "s_register_operand"
8987 "l,r,r,l,l,r,r,r,r")
8988 (match_operand:SI 3 "arm_add_operand"
8989 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8995 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8997 {\"cmp%d5\\t%0, %1\",
8998 \"cmp%d4\\t%2, %3\"},
8999 {\"cmn%d5\\t%0, #%n1\",
9000 \"cmp%d4\\t%2, %3\"},
9001 {\"cmp%d5\\t%0, %1\",
9002 \"cmn%d4\\t%2, #%n3\"},
9003 {\"cmn%d5\\t%0, #%n1\",
9004 \"cmn%d4\\t%2, #%n3\"}
9006 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9011 \"cmn\\t%0, #%n1\"},
9012 {\"cmn\\t%2, #%n3\",
9014 {\"cmn\\t%2, #%n3\",
9017 static const char * const ite[2] =
9022 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9023 CMP_CMP, CMN_CMP, CMP_CMP,
9024 CMN_CMP, CMP_CMN, CMN_CMN};
9026 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9028 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9029 if (TARGET_THUMB2) {
9030 output_asm_insn (ite[swap], operands);
9032 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9035 [(set_attr "conds" "set")
9036 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9037 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9038 (set_attr "type" "multiple")
9039 (set_attr_alternative "length"
9045 (if_then_else (eq_attr "is_thumb" "no")
9048 (if_then_else (eq_attr "is_thumb" "no")
9051 (if_then_else (eq_attr "is_thumb" "no")
9054 (if_then_else (eq_attr "is_thumb" "no")
9059 (define_insn "*cmp_ite1"
9060 [(set (match_operand 6 "dominant_cc_register" "")
9063 (match_operator 4 "arm_comparison_operator"
9064 [(match_operand:SI 0 "s_register_operand"
9065 "l,l,l,r,r,r,r,r,r")
9066 (match_operand:SI 1 "arm_add_operand"
9067 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9068 (match_operator:SI 5 "arm_comparison_operator"
9069 [(match_operand:SI 2 "s_register_operand"
9070 "l,r,r,l,l,r,r,r,r")
9071 (match_operand:SI 3 "arm_add_operand"
9072 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9078 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9082 {\"cmn\\t%0, #%n1\",
9085 \"cmn\\t%2, #%n3\"},
9086 {\"cmn\\t%0, #%n1\",
9089 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9091 {\"cmp%d4\\t%2, %3\",
9092 \"cmp%D5\\t%0, %1\"},
9093 {\"cmp%d4\\t%2, %3\",
9094 \"cmn%D5\\t%0, #%n1\"},
9095 {\"cmn%d4\\t%2, #%n3\",
9096 \"cmp%D5\\t%0, %1\"},
9097 {\"cmn%d4\\t%2, #%n3\",
9098 \"cmn%D5\\t%0, #%n1\"}
9100 static const char * const ite[2] =
9105 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9106 CMP_CMP, CMN_CMP, CMP_CMP,
9107 CMN_CMP, CMP_CMN, CMN_CMN};
9109 comparison_dominates_p (GET_CODE (operands[5]),
9110 reverse_condition (GET_CODE (operands[4])));
9112 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9113 if (TARGET_THUMB2) {
9114 output_asm_insn (ite[swap], operands);
9116 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9119 [(set_attr "conds" "set")
9120 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9121 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9122 (set_attr_alternative "length"
9128 (if_then_else (eq_attr "is_thumb" "no")
9131 (if_then_else (eq_attr "is_thumb" "no")
9134 (if_then_else (eq_attr "is_thumb" "no")
9137 (if_then_else (eq_attr "is_thumb" "no")
9140 (set_attr "type" "multiple")]
9143 (define_insn "*cmp_and"
9144 [(set (match_operand 6 "dominant_cc_register" "")
9147 (match_operator 4 "arm_comparison_operator"
9148 [(match_operand:SI 0 "s_register_operand"
9149 "l,l,l,r,r,r,r,r,r,r")
9150 (match_operand:SI 1 "arm_add_operand"
9151 "lPy,lPy,lPy,rI,L,r,rI,L,rI,L")])
9152 (match_operator:SI 5 "arm_comparison_operator"
9153 [(match_operand:SI 2 "s_register_operand"
9154 "l,r,r,l,l,r,r,r,r,r")
9155 (match_operand:SI 3 "arm_add_operand"
9156 "lPy,rI,L,lPy,lPy,r,rI,rI,L,L")]))
9161 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9163 {\"cmp%d5\\t%0, %1\",
9164 \"cmp%d4\\t%2, %3\"},
9165 {\"cmn%d5\\t%0, #%n1\",
9166 \"cmp%d4\\t%2, %3\"},
9167 {\"cmp%d5\\t%0, %1\",
9168 \"cmn%d4\\t%2, #%n3\"},
9169 {\"cmn%d5\\t%0, #%n1\",
9170 \"cmn%d4\\t%2, #%n3\"}
9172 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9177 \"cmn\\t%0, #%n1\"},
9178 {\"cmn\\t%2, #%n3\",
9180 {\"cmn\\t%2, #%n3\",
9183 static const char *const ite[2] =
9188 static const int cmp_idx[] = {CMP_CMP, CMP_CMP, CMP_CMN,
9189 CMP_CMP, CMN_CMP, CMP_CMP,
9190 CMP_CMP, CMN_CMP, CMP_CMN,
9193 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9195 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9196 if (TARGET_THUMB2) {
9197 output_asm_insn (ite[swap], operands);
9199 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9202 [(set_attr "conds" "set")
9203 (set_attr "predicable" "no")
9204 (set_attr "arch" "t2,t2,t2,t2,t2,t2,any,any,any,any")
9205 (set_attr "enabled_for_short_it" "yes,no,no,no,no,yes,no,no,no,no")
9206 (set_attr_alternative "length"
9213 (if_then_else (eq_attr "is_thumb" "no")
9216 (if_then_else (eq_attr "is_thumb" "no")
9219 (if_then_else (eq_attr "is_thumb" "no")
9222 (if_then_else (eq_attr "is_thumb" "no")
9225 (set_attr "type" "multiple")]
9228 (define_insn "*cmp_ior"
9229 [(set (match_operand 6 "dominant_cc_register" "")
9232 (match_operator 4 "arm_comparison_operator"
9233 [(match_operand:SI 0 "s_register_operand"
9234 "l,l,l,r,r,r,r,r,r,r")
9235 (match_operand:SI 1 "arm_add_operand"
9236 "lPy,lPy,lPy,rI,L,r,rI,L,rI,L")])
9237 (match_operator:SI 5 "arm_comparison_operator"
9238 [(match_operand:SI 2 "s_register_operand"
9239 "l,r,r,l,l,r,r,r,r,r")
9240 (match_operand:SI 3 "arm_add_operand"
9241 "lPy,rI,L,lPy,lPy,r,rI,rI,L,L")]))
9246 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9250 {\"cmn\\t%0, #%n1\",
9253 \"cmn\\t%2, #%n3\"},
9254 {\"cmn\\t%0, #%n1\",
9257 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9259 {\"cmp%D4\\t%2, %3\",
9260 \"cmp%D5\\t%0, %1\"},
9261 {\"cmp%D4\\t%2, %3\",
9262 \"cmn%D5\\t%0, #%n1\"},
9263 {\"cmn%D4\\t%2, #%n3\",
9264 \"cmp%D5\\t%0, %1\"},
9265 {\"cmn%D4\\t%2, #%n3\",
9266 \"cmn%D5\\t%0, #%n1\"}
9268 static const char *const ite[2] =
9273 static const int cmp_idx[] = {CMP_CMP, CMP_CMP, CMP_CMN,
9274 CMP_CMP, CMN_CMP, CMP_CMP,
9275 CMP_CMP, CMN_CMP, CMP_CMN,
9278 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9280 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9281 if (TARGET_THUMB2) {
9282 output_asm_insn (ite[swap], operands);
9284 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9288 [(set_attr "conds" "set")
9289 (set_attr "arch" "t2,t2,t2,t2,t2,t2,any,any,any,any")
9290 (set_attr "enabled_for_short_it" "yes,no,no,no,no,yes,no,no,no,no")
9291 (set_attr_alternative "length"
9298 (if_then_else (eq_attr "is_thumb" "no")
9301 (if_then_else (eq_attr "is_thumb" "no")
9304 (if_then_else (eq_attr "is_thumb" "no")
9307 (if_then_else (eq_attr "is_thumb" "no")
9310 (set_attr "type" "multiple")]
9313 (define_insn_and_split "*ior_scc_scc"
9314 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9315 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9316 [(match_operand:SI 1 "s_register_operand" "l,r")
9317 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9318 (match_operator:SI 6 "arm_comparison_operator"
9319 [(match_operand:SI 4 "s_register_operand" "l,r")
9320 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9321 (clobber (reg:CC CC_REGNUM))]
9323 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9326 "TARGET_32BIT && reload_completed"
9330 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9331 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9333 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9335 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9338 [(set_attr "conds" "clob")
9339 (set_attr "enabled_for_short_it" "yes,no")
9340 (set_attr "length" "16")
9341 (set_attr "type" "multiple")]
9344 ; If the above pattern is followed by a CMP insn, then the compare is
9345 ; redundant, since we can rework the conditional instruction that follows.
9346 (define_insn_and_split "*ior_scc_scc_cmp"
9347 [(set (match_operand 0 "dominant_cc_register" "")
9348 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9349 [(match_operand:SI 1 "s_register_operand" "l,r")
9350 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9351 (match_operator:SI 6 "arm_comparison_operator"
9352 [(match_operand:SI 4 "s_register_operand" "l,r")
9353 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9355 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9356 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9357 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9360 "TARGET_32BIT && reload_completed"
9364 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9365 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9367 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9369 [(set_attr "conds" "set")
9370 (set_attr "enabled_for_short_it" "yes,no")
9371 (set_attr "length" "16")
9372 (set_attr "type" "multiple")]
9375 (define_insn_and_split "*and_scc_scc"
9376 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9377 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9378 [(match_operand:SI 1 "s_register_operand" "l,r")
9379 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9380 (match_operator:SI 6 "arm_comparison_operator"
9381 [(match_operand:SI 4 "s_register_operand" "l,r")
9382 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9383 (clobber (reg:CC CC_REGNUM))]
9385 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9388 "TARGET_32BIT && reload_completed
9389 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9394 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9395 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9397 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9399 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9402 [(set_attr "conds" "clob")
9403 (set_attr "enabled_for_short_it" "yes,no")
9404 (set_attr "length" "16")
9405 (set_attr "type" "multiple")]
9408 ; If the above pattern is followed by a CMP insn, then the compare is
9409 ; redundant, since we can rework the conditional instruction that follows.
9410 (define_insn_and_split "*and_scc_scc_cmp"
9411 [(set (match_operand 0 "dominant_cc_register" "")
9412 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9413 [(match_operand:SI 1 "s_register_operand" "l,r")
9414 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9415 (match_operator:SI 6 "arm_comparison_operator"
9416 [(match_operand:SI 4 "s_register_operand" "l,r")
9417 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9419 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9420 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9421 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9424 "TARGET_32BIT && reload_completed"
9428 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9429 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9431 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9433 [(set_attr "conds" "set")
9434 (set_attr "enabled_for_short_it" "yes,no")
9435 (set_attr "length" "16")
9436 (set_attr "type" "multiple")]
9439 ;; If there is no dominance in the comparison, then we can still save an
9440 ;; instruction in the AND case, since we can know that the second compare
9441 ;; need only zero the value if false (if true, then the value is already
9443 (define_insn_and_split "*and_scc_scc_nodom"
9444 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9445 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9446 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9447 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9448 (match_operator:SI 6 "arm_comparison_operator"
9449 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9450 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9451 (clobber (reg:CC CC_REGNUM))]
9453 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9456 "TARGET_32BIT && reload_completed"
9457 [(parallel [(set (match_dup 0)
9458 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9459 (clobber (reg:CC CC_REGNUM))])
9460 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9462 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9465 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9466 operands[4], operands[5]),
9468 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9470 [(set_attr "conds" "clob")
9471 (set_attr "length" "20")
9472 (set_attr "type" "multiple")]
9476 [(set (reg:CC_NOOV CC_REGNUM)
9477 (compare:CC_NOOV (ior:SI
9478 (and:SI (match_operand:SI 0 "s_register_operand" "")
9480 (match_operator:SI 1 "arm_comparison_operator"
9481 [(match_operand:SI 2 "s_register_operand" "")
9482 (match_operand:SI 3 "arm_add_operand" "")]))
9484 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9487 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9489 (set (reg:CC_NOOV CC_REGNUM)
9490 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9495 [(set (reg:CC_NOOV CC_REGNUM)
9496 (compare:CC_NOOV (ior:SI
9497 (match_operator:SI 1 "arm_comparison_operator"
9498 [(match_operand:SI 2 "s_register_operand" "")
9499 (match_operand:SI 3 "arm_add_operand" "")])
9500 (and:SI (match_operand:SI 0 "s_register_operand" "")
9503 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9506 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9508 (set (reg:CC_NOOV CC_REGNUM)
9509 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9512 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9514 (define_insn_and_split "*negscc"
9515 [(set (match_operand:SI 0 "s_register_operand" "=r")
9516 (neg:SI (match_operator 3 "arm_comparison_operator"
9517 [(match_operand:SI 1 "s_register_operand" "r")
9518 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9519 (clobber (reg:CC CC_REGNUM))]
9522 "&& reload_completed"
9525 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9527 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9529 /* Emit mov\\t%0, %1, asr #31 */
9530 emit_insn (gen_rtx_SET (operands[0],
9531 gen_rtx_ASHIFTRT (SImode,
9536 else if (GET_CODE (operands[3]) == NE)
9538 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9539 if (CONST_INT_P (operands[2]))
9540 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9541 gen_int_mode (-INTVAL (operands[2]),
9544 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9546 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9550 gen_rtx_SET (operands[0],
9556 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9557 emit_insn (gen_rtx_SET (cc_reg,
9558 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9559 enum rtx_code rc = GET_CODE (operands[3]);
9561 rc = reverse_condition (rc);
9562 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9567 gen_rtx_SET (operands[0], const0_rtx)));
9568 rc = GET_CODE (operands[3]);
9569 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9574 gen_rtx_SET (operands[0],
9580 [(set_attr "conds" "clob")
9581 (set_attr "length" "12")
9582 (set_attr "type" "multiple")]
9585 (define_insn_and_split "movcond_addsi"
9586 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9588 (match_operator 5 "comparison_operator"
9589 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9590 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9592 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9593 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9594 (clobber (reg:CC CC_REGNUM))]
9597 "&& reload_completed"
9598 [(set (reg:CC_NOOV CC_REGNUM)
9600 (plus:SI (match_dup 3)
9603 (set (match_dup 0) (match_dup 1))
9604 (cond_exec (match_dup 6)
9605 (set (match_dup 0) (match_dup 2)))]
9608 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9609 operands[3], operands[4]);
9610 enum rtx_code rc = GET_CODE (operands[5]);
9611 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9612 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9613 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9614 rc = reverse_condition (rc);
9616 std::swap (operands[1], operands[2]);
9618 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9621 [(set_attr "conds" "clob")
9622 (set_attr "enabled_for_short_it" "no,yes,yes")
9623 (set_attr "type" "multiple")]
9626 (define_insn "movcond"
9627 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9629 (match_operator 5 "arm_comparison_operator"
9630 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9631 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9632 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9633 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9634 (clobber (reg:CC CC_REGNUM))]
9637 if (GET_CODE (operands[5]) == LT
9638 && (operands[4] == const0_rtx))
9640 if (which_alternative != 1 && REG_P (operands[1]))
9642 if (operands[2] == const0_rtx)
9643 return \"and\\t%0, %1, %3, asr #31\";
9644 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9646 else if (which_alternative != 0 && REG_P (operands[2]))
9648 if (operands[1] == const0_rtx)
9649 return \"bic\\t%0, %2, %3, asr #31\";
9650 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9652 /* The only case that falls through to here is when both ops 1 & 2
9656 if (GET_CODE (operands[5]) == GE
9657 && (operands[4] == const0_rtx))
9659 if (which_alternative != 1 && REG_P (operands[1]))
9661 if (operands[2] == const0_rtx)
9662 return \"bic\\t%0, %1, %3, asr #31\";
9663 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9665 else if (which_alternative != 0 && REG_P (operands[2]))
9667 if (operands[1] == const0_rtx)
9668 return \"and\\t%0, %2, %3, asr #31\";
9669 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9671 /* The only case that falls through to here is when both ops 1 & 2
9674 if (CONST_INT_P (operands[4])
9675 && !const_ok_for_arm (INTVAL (operands[4])))
9676 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9678 output_asm_insn (\"cmp\\t%3, %4\", operands);
9679 if (which_alternative != 0)
9680 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9681 if (which_alternative != 1)
9682 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9685 [(set_attr "conds" "clob")
9686 (set_attr "length" "8,8,12")
9687 (set_attr "type" "multiple")]
9690 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9692 (define_insn "*ifcompare_plus_move"
9693 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9694 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9695 [(match_operand:SI 4 "s_register_operand" "r,r")
9696 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9698 (match_operand:SI 2 "s_register_operand" "r,r")
9699 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9700 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9701 (clobber (reg:CC CC_REGNUM))]
9704 [(set_attr "conds" "clob")
9705 (set_attr "length" "8,12")
9706 (set_attr "type" "multiple")]
9709 (define_insn "*if_plus_move"
9710 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9712 (match_operator 4 "arm_comparison_operator"
9713 [(match_operand 5 "cc_register" "") (const_int 0)])
9715 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9716 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9717 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9721 sub%d4\\t%0, %2, #%n3
9722 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9723 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9724 [(set_attr "conds" "use")
9725 (set_attr "length" "4,4,8,8")
9726 (set_attr_alternative "type"
9727 [(if_then_else (match_operand 3 "const_int_operand" "")
9728 (const_string "alu_imm" )
9729 (const_string "alu_sreg"))
9730 (const_string "alu_imm")
9731 (const_string "multiple")
9732 (const_string "multiple")])]
9735 (define_insn "*ifcompare_move_plus"
9736 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9737 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9738 [(match_operand:SI 4 "s_register_operand" "r,r")
9739 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9740 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9742 (match_operand:SI 2 "s_register_operand" "r,r")
9743 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9744 (clobber (reg:CC CC_REGNUM))]
9747 [(set_attr "conds" "clob")
9748 (set_attr "length" "8,12")
9749 (set_attr "type" "multiple")]
9752 (define_insn "*if_move_plus"
9753 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9755 (match_operator 4 "arm_comparison_operator"
9756 [(match_operand 5 "cc_register" "") (const_int 0)])
9757 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9759 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9760 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9764 sub%D4\\t%0, %2, #%n3
9765 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9766 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9767 [(set_attr "conds" "use")
9768 (set_attr "length" "4,4,8,8")
9769 (set_attr_alternative "type"
9770 [(if_then_else (match_operand 3 "const_int_operand" "")
9771 (const_string "alu_imm" )
9772 (const_string "alu_sreg"))
9773 (const_string "alu_imm")
9774 (const_string "multiple")
9775 (const_string "multiple")])]
9778 (define_insn "*ifcompare_arith_arith"
9779 [(set (match_operand:SI 0 "s_register_operand" "=r")
9780 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9781 [(match_operand:SI 5 "s_register_operand" "r")
9782 (match_operand:SI 6 "arm_add_operand" "rIL")])
9783 (match_operator:SI 8 "shiftable_operator"
9784 [(match_operand:SI 1 "s_register_operand" "r")
9785 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9786 (match_operator:SI 7 "shiftable_operator"
9787 [(match_operand:SI 3 "s_register_operand" "r")
9788 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9789 (clobber (reg:CC CC_REGNUM))]
9792 [(set_attr "conds" "clob")
9793 (set_attr "length" "12")
9794 (set_attr "type" "multiple")]
9797 (define_insn "*if_arith_arith"
9798 [(set (match_operand:SI 0 "s_register_operand" "=r")
9799 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9800 [(match_operand 8 "cc_register" "") (const_int 0)])
9801 (match_operator:SI 6 "shiftable_operator"
9802 [(match_operand:SI 1 "s_register_operand" "r")
9803 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9804 (match_operator:SI 7 "shiftable_operator"
9805 [(match_operand:SI 3 "s_register_operand" "r")
9806 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9808 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9809 [(set_attr "conds" "use")
9810 (set_attr "length" "8")
9811 (set_attr "type" "multiple")]
9814 (define_insn "*ifcompare_arith_move"
9815 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9816 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9817 [(match_operand:SI 2 "s_register_operand" "r,r")
9818 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9819 (match_operator:SI 7 "shiftable_operator"
9820 [(match_operand:SI 4 "s_register_operand" "r,r")
9821 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9822 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9823 (clobber (reg:CC CC_REGNUM))]
9826 /* If we have an operation where (op x 0) is the identity operation and
9827 the conditional operator is LT or GE and we are comparing against zero and
9828 everything is in registers then we can do this in two instructions. */
9829 if (operands[3] == const0_rtx
9830 && GET_CODE (operands[7]) != AND
9831 && REG_P (operands[5])
9832 && REG_P (operands[1])
9833 && REGNO (operands[1]) == REGNO (operands[4])
9834 && REGNO (operands[4]) != REGNO (operands[0]))
9836 if (GET_CODE (operands[6]) == LT)
9837 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9838 else if (GET_CODE (operands[6]) == GE)
9839 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9841 if (CONST_INT_P (operands[3])
9842 && !const_ok_for_arm (INTVAL (operands[3])))
9843 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9845 output_asm_insn (\"cmp\\t%2, %3\", operands);
9846 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9847 if (which_alternative != 0)
9848 return \"mov%D6\\t%0, %1\";
9851 [(set_attr "conds" "clob")
9852 (set_attr "length" "8,12")
9853 (set_attr "type" "multiple")]
9856 (define_insn "*if_arith_move"
9857 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9858 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9859 [(match_operand 6 "cc_register" "") (const_int 0)])
9860 (match_operator:SI 5 "shiftable_operator"
9861 [(match_operand:SI 2 "s_register_operand" "r,r")
9862 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9863 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9867 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9868 [(set_attr "conds" "use")
9869 (set_attr "length" "4,8")
9870 (set_attr_alternative "type"
9871 [(if_then_else (match_operand 3 "const_int_operand" "")
9872 (const_string "alu_shift_imm" )
9873 (const_string "alu_shift_reg"))
9874 (const_string "multiple")])]
9877 (define_insn "*ifcompare_move_arith"
9878 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9879 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9880 [(match_operand:SI 4 "s_register_operand" "r,r")
9881 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9882 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9883 (match_operator:SI 7 "shiftable_operator"
9884 [(match_operand:SI 2 "s_register_operand" "r,r")
9885 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9886 (clobber (reg:CC CC_REGNUM))]
9889 /* If we have an operation where (op x 0) is the identity operation and
9890 the conditional operator is LT or GE and we are comparing against zero and
9891 everything is in registers then we can do this in two instructions */
9892 if (operands[5] == const0_rtx
9893 && GET_CODE (operands[7]) != AND
9894 && REG_P (operands[3])
9895 && REG_P (operands[1])
9896 && REGNO (operands[1]) == REGNO (operands[2])
9897 && REGNO (operands[2]) != REGNO (operands[0]))
9899 if (GET_CODE (operands[6]) == GE)
9900 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9901 else if (GET_CODE (operands[6]) == LT)
9902 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9905 if (CONST_INT_P (operands[5])
9906 && !const_ok_for_arm (INTVAL (operands[5])))
9907 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9909 output_asm_insn (\"cmp\\t%4, %5\", operands);
9911 if (which_alternative != 0)
9912 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9913 return \"%I7%D6\\t%0, %2, %3\";
9915 [(set_attr "conds" "clob")
9916 (set_attr "length" "8,12")
9917 (set_attr "type" "multiple")]
9920 (define_insn "*if_move_arith"
9921 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9923 (match_operator 4 "arm_comparison_operator"
9924 [(match_operand 6 "cc_register" "") (const_int 0)])
9925 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9926 (match_operator:SI 5 "shiftable_operator"
9927 [(match_operand:SI 2 "s_register_operand" "r,r")
9928 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9932 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9933 [(set_attr "conds" "use")
9934 (set_attr "length" "4,8")
9935 (set_attr_alternative "type"
9936 [(if_then_else (match_operand 3 "const_int_operand" "")
9937 (const_string "alu_shift_imm" )
9938 (const_string "alu_shift_reg"))
9939 (const_string "multiple")])]
9942 (define_insn "*ifcompare_move_not"
9943 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9945 (match_operator 5 "arm_comparison_operator"
9946 [(match_operand:SI 3 "s_register_operand" "r,r")
9947 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9948 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9950 (match_operand:SI 2 "s_register_operand" "r,r"))))
9951 (clobber (reg:CC CC_REGNUM))]
9954 [(set_attr "conds" "clob")
9955 (set_attr "length" "8,12")
9956 (set_attr "type" "multiple")]
9959 (define_insn "*if_move_not"
9960 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9962 (match_operator 4 "arm_comparison_operator"
9963 [(match_operand 3 "cc_register" "") (const_int 0)])
9964 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9965 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9969 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9970 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9971 [(set_attr "conds" "use")
9972 (set_attr "type" "mvn_reg")
9973 (set_attr "length" "4,8,8")
9974 (set_attr "type" "mvn_reg,multiple,multiple")]
9977 (define_insn "*ifcompare_not_move"
9978 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9980 (match_operator 5 "arm_comparison_operator"
9981 [(match_operand:SI 3 "s_register_operand" "r,r")
9982 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9984 (match_operand:SI 2 "s_register_operand" "r,r"))
9985 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9986 (clobber (reg:CC CC_REGNUM))]
9989 [(set_attr "conds" "clob")
9990 (set_attr "length" "8,12")
9991 (set_attr "type" "multiple")]
9994 (define_insn "*if_not_move"
9995 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9997 (match_operator 4 "arm_comparison_operator"
9998 [(match_operand 3 "cc_register" "") (const_int 0)])
9999 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10000 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10004 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10005 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10006 [(set_attr "conds" "use")
10007 (set_attr "type" "mvn_reg,multiple,multiple")
10008 (set_attr "length" "4,8,8")]
10011 (define_insn "*ifcompare_shift_move"
10012 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10014 (match_operator 6 "arm_comparison_operator"
10015 [(match_operand:SI 4 "s_register_operand" "r,r")
10016 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10017 (match_operator:SI 7 "shift_operator"
10018 [(match_operand:SI 2 "s_register_operand" "r,r")
10019 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10020 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10021 (clobber (reg:CC CC_REGNUM))]
10024 [(set_attr "conds" "clob")
10025 (set_attr "length" "8,12")
10026 (set_attr "type" "multiple")]
10029 (define_insn "*if_shift_move"
10030 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10032 (match_operator 5 "arm_comparison_operator"
10033 [(match_operand 6 "cc_register" "") (const_int 0)])
10034 (match_operator:SI 4 "shift_operator"
10035 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10036 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10037 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10041 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10042 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10043 [(set_attr "conds" "use")
10044 (set_attr "shift" "2")
10045 (set_attr "length" "4,8,8")
10046 (set_attr_alternative "type"
10047 [(if_then_else (match_operand 3 "const_int_operand" "")
10048 (const_string "mov_shift" )
10049 (const_string "mov_shift_reg"))
10050 (const_string "multiple")
10051 (const_string "multiple")])]
10054 (define_insn "*ifcompare_move_shift"
10055 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10057 (match_operator 6 "arm_comparison_operator"
10058 [(match_operand:SI 4 "s_register_operand" "r,r")
10059 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10060 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10061 (match_operator:SI 7 "shift_operator"
10062 [(match_operand:SI 2 "s_register_operand" "r,r")
10063 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10064 (clobber (reg:CC CC_REGNUM))]
10067 [(set_attr "conds" "clob")
10068 (set_attr "length" "8,12")
10069 (set_attr "type" "multiple")]
10072 (define_insn "*if_move_shift"
10073 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10075 (match_operator 5 "arm_comparison_operator"
10076 [(match_operand 6 "cc_register" "") (const_int 0)])
10077 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10078 (match_operator:SI 4 "shift_operator"
10079 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10080 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10084 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10085 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10086 [(set_attr "conds" "use")
10087 (set_attr "shift" "2")
10088 (set_attr "length" "4,8,8")
10089 (set_attr_alternative "type"
10090 [(if_then_else (match_operand 3 "const_int_operand" "")
10091 (const_string "mov_shift" )
10092 (const_string "mov_shift_reg"))
10093 (const_string "multiple")
10094 (const_string "multiple")])]
10097 (define_insn "*ifcompare_shift_shift"
10098 [(set (match_operand:SI 0 "s_register_operand" "=r")
10100 (match_operator 7 "arm_comparison_operator"
10101 [(match_operand:SI 5 "s_register_operand" "r")
10102 (match_operand:SI 6 "arm_add_operand" "rIL")])
10103 (match_operator:SI 8 "shift_operator"
10104 [(match_operand:SI 1 "s_register_operand" "r")
10105 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10106 (match_operator:SI 9 "shift_operator"
10107 [(match_operand:SI 3 "s_register_operand" "r")
10108 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10109 (clobber (reg:CC CC_REGNUM))]
10112 [(set_attr "conds" "clob")
10113 (set_attr "length" "12")
10114 (set_attr "type" "multiple")]
10117 (define_insn "*if_shift_shift"
10118 [(set (match_operand:SI 0 "s_register_operand" "=r")
10120 (match_operator 5 "arm_comparison_operator"
10121 [(match_operand 8 "cc_register" "") (const_int 0)])
10122 (match_operator:SI 6 "shift_operator"
10123 [(match_operand:SI 1 "s_register_operand" "r")
10124 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10125 (match_operator:SI 7 "shift_operator"
10126 [(match_operand:SI 3 "s_register_operand" "r")
10127 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10129 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10130 [(set_attr "conds" "use")
10131 (set_attr "shift" "1")
10132 (set_attr "length" "8")
10133 (set (attr "type") (if_then_else
10134 (and (match_operand 2 "const_int_operand" "")
10135 (match_operand 4 "const_int_operand" ""))
10136 (const_string "mov_shift")
10137 (const_string "mov_shift_reg")))]
10140 (define_insn "*ifcompare_not_arith"
10141 [(set (match_operand:SI 0 "s_register_operand" "=r")
10143 (match_operator 6 "arm_comparison_operator"
10144 [(match_operand:SI 4 "s_register_operand" "r")
10145 (match_operand:SI 5 "arm_add_operand" "rIL")])
10146 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10147 (match_operator:SI 7 "shiftable_operator"
10148 [(match_operand:SI 2 "s_register_operand" "r")
10149 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10150 (clobber (reg:CC CC_REGNUM))]
10153 [(set_attr "conds" "clob")
10154 (set_attr "length" "12")
10155 (set_attr "type" "multiple")]
10158 (define_insn "*if_not_arith"
10159 [(set (match_operand:SI 0 "s_register_operand" "=r")
10161 (match_operator 5 "arm_comparison_operator"
10162 [(match_operand 4 "cc_register" "") (const_int 0)])
10163 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10164 (match_operator:SI 6 "shiftable_operator"
10165 [(match_operand:SI 2 "s_register_operand" "r")
10166 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10168 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10169 [(set_attr "conds" "use")
10170 (set_attr "type" "mvn_reg")
10171 (set_attr "length" "8")]
10174 (define_insn "*ifcompare_arith_not"
10175 [(set (match_operand:SI 0 "s_register_operand" "=r")
10177 (match_operator 6 "arm_comparison_operator"
10178 [(match_operand:SI 4 "s_register_operand" "r")
10179 (match_operand:SI 5 "arm_add_operand" "rIL")])
10180 (match_operator:SI 7 "shiftable_operator"
10181 [(match_operand:SI 2 "s_register_operand" "r")
10182 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10183 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10184 (clobber (reg:CC CC_REGNUM))]
10187 [(set_attr "conds" "clob")
10188 (set_attr "length" "12")
10189 (set_attr "type" "multiple")]
10192 (define_insn "*if_arith_not"
10193 [(set (match_operand:SI 0 "s_register_operand" "=r")
10195 (match_operator 5 "arm_comparison_operator"
10196 [(match_operand 4 "cc_register" "") (const_int 0)])
10197 (match_operator:SI 6 "shiftable_operator"
10198 [(match_operand:SI 2 "s_register_operand" "r")
10199 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10200 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10202 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10203 [(set_attr "conds" "use")
10204 (set_attr "type" "multiple")
10205 (set_attr "length" "8")]
10208 (define_insn "*ifcompare_neg_move"
10209 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10211 (match_operator 5 "arm_comparison_operator"
10212 [(match_operand:SI 3 "s_register_operand" "r,r")
10213 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10214 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10215 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10216 (clobber (reg:CC CC_REGNUM))]
10219 [(set_attr "conds" "clob")
10220 (set_attr "length" "8,12")
10221 (set_attr "type" "multiple")]
10224 (define_insn_and_split "*if_neg_move"
10225 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10227 (match_operator 4 "arm_comparison_operator"
10228 [(match_operand 3 "cc_register" "") (const_int 0)])
10229 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10230 (match_operand:SI 1 "s_register_operand" "0,0")))]
10233 "&& reload_completed"
10234 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10235 (set (match_dup 0) (neg:SI (match_dup 2))))]
10237 [(set_attr "conds" "use")
10238 (set_attr "length" "4")
10239 (set_attr "arch" "t2,32")
10240 (set_attr "enabled_for_short_it" "yes,no")
10241 (set_attr "type" "logic_shift_imm")]
10244 (define_insn "*ifcompare_move_neg"
10245 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10247 (match_operator 5 "arm_comparison_operator"
10248 [(match_operand:SI 3 "s_register_operand" "r,r")
10249 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10250 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10251 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10252 (clobber (reg:CC CC_REGNUM))]
10255 [(set_attr "conds" "clob")
10256 (set_attr "length" "8,12")
10257 (set_attr "type" "multiple")]
10260 (define_insn_and_split "*if_move_neg"
10261 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10263 (match_operator 4 "arm_comparison_operator"
10264 [(match_operand 3 "cc_register" "") (const_int 0)])
10265 (match_operand:SI 1 "s_register_operand" "0,0")
10266 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10269 "&& reload_completed"
10270 [(cond_exec (match_dup 5)
10271 (set (match_dup 0) (neg:SI (match_dup 2))))]
10273 machine_mode mode = GET_MODE (operands[3]);
10274 rtx_code rc = GET_CODE (operands[4]);
10276 if (mode == CCFPmode || mode == CCFPEmode)
10277 rc = reverse_condition_maybe_unordered (rc);
10279 rc = reverse_condition (rc);
10281 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10283 [(set_attr "conds" "use")
10284 (set_attr "length" "4")
10285 (set_attr "arch" "t2,32")
10286 (set_attr "enabled_for_short_it" "yes,no")
10287 (set_attr "type" "logic_shift_imm")]
10290 (define_insn "*arith_adjacentmem"
10291 [(set (match_operand:SI 0 "s_register_operand" "=r")
10292 (match_operator:SI 1 "shiftable_operator"
10293 [(match_operand:SI 2 "memory_operand" "m")
10294 (match_operand:SI 3 "memory_operand" "m")]))
10295 (clobber (match_scratch:SI 4 "=r"))]
10296 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10302 HOST_WIDE_INT val1 = 0, val2 = 0;
10304 if (REGNO (operands[0]) > REGNO (operands[4]))
10306 ldm[1] = operands[4];
10307 ldm[2] = operands[0];
10311 ldm[1] = operands[0];
10312 ldm[2] = operands[4];
10315 base_reg = XEXP (operands[2], 0);
10317 if (!REG_P (base_reg))
10319 val1 = INTVAL (XEXP (base_reg, 1));
10320 base_reg = XEXP (base_reg, 0);
10323 if (!REG_P (XEXP (operands[3], 0)))
10324 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10326 arith[0] = operands[0];
10327 arith[3] = operands[1];
10341 if (val1 !=0 && val2 != 0)
10345 if (val1 == 4 || val2 == 4)
10346 /* Other val must be 8, since we know they are adjacent and neither
10348 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10349 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10351 ldm[0] = ops[0] = operands[4];
10353 ops[2] = GEN_INT (val1);
10354 output_add_immediate (ops);
10356 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10358 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10362 /* Offset is out of range for a single add, so use two ldr. */
10365 ops[2] = GEN_INT (val1);
10366 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10368 ops[2] = GEN_INT (val2);
10369 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10372 else if (val1 != 0)
10375 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10377 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10382 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10384 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10386 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10389 [(set_attr "length" "12")
10390 (set_attr "predicable" "yes")
10391 (set_attr "type" "load_4")]
10394 ; This pattern is never tried by combine, so do it as a peephole
10397 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10398 (match_operand:SI 1 "arm_general_register_operand" ""))
10399 (set (reg:CC CC_REGNUM)
10400 (compare:CC (match_dup 1) (const_int 0)))]
10402 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10403 (set (match_dup 0) (match_dup 1))])]
10408 [(set (match_operand:SI 0 "s_register_operand" "")
10409 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10411 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10412 [(match_operand:SI 3 "s_register_operand" "")
10413 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10414 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10416 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10417 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10422 ;; This split can be used because CC_Z mode implies that the following
10423 ;; branch will be an equality, or an unsigned inequality, so the sign
10424 ;; extension is not needed.
10427 [(set (reg:CC_Z CC_REGNUM)
10429 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10431 (match_operand 1 "const_int_operand" "")))
10432 (clobber (match_scratch:SI 2 ""))]
10434 && ((UINTVAL (operands[1]))
10435 == ((UINTVAL (operands[1])) >> 24) << 24)"
10436 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10437 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10439 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10442 ;; ??? Check the patterns above for Thumb-2 usefulness
10444 (define_expand "prologue"
10445 [(clobber (const_int 0))]
10448 arm_expand_prologue ();
10450 thumb1_expand_prologue ();
10455 (define_expand "epilogue"
10456 [(clobber (const_int 0))]
10459 if (crtl->calls_eh_return)
10460 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10463 thumb1_expand_epilogue ();
10464 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10465 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10467 else if (HAVE_return)
10469 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10470 no need for explicit testing again. */
10471 emit_jump_insn (gen_return ());
10473 else if (TARGET_32BIT)
10475 arm_expand_epilogue (true);
10481 ;; Note - although unspec_volatile's USE all hard registers,
10482 ;; USEs are ignored after relaod has completed. Thus we need
10483 ;; to add an unspec of the link register to ensure that flow
10484 ;; does not think that it is unused by the sibcall branch that
10485 ;; will replace the standard function epilogue.
10486 (define_expand "sibcall_epilogue"
10487 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10488 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10491 arm_expand_epilogue (false);
10496 (define_expand "eh_epilogue"
10497 [(use (match_operand:SI 0 "register_operand"))
10498 (use (match_operand:SI 1 "register_operand"))
10499 (use (match_operand:SI 2 "register_operand"))]
10503 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10504 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10506 rtx ra = gen_rtx_REG (Pmode, 2);
10508 emit_move_insn (ra, operands[2]);
10511 /* This is a hack -- we may have crystalized the function type too
10513 cfun->machine->func_type = 0;
10517 ;; This split is only used during output to reduce the number of patterns
10518 ;; that need assembler instructions adding to them. We allowed the setting
10519 ;; of the conditions to be implicit during rtl generation so that
10520 ;; the conditional compare patterns would work. However this conflicts to
10521 ;; some extent with the conditional data operations, so we have to split them
10524 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10525 ;; conditional execution sufficient?
10528 [(set (match_operand:SI 0 "s_register_operand" "")
10529 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10530 [(match_operand 2 "" "") (match_operand 3 "" "")])
10532 (match_operand 4 "" "")))
10533 (clobber (reg:CC CC_REGNUM))]
10534 "TARGET_ARM && reload_completed"
10535 [(set (match_dup 5) (match_dup 6))
10536 (cond_exec (match_dup 7)
10537 (set (match_dup 0) (match_dup 4)))]
10540 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10541 operands[2], operands[3]);
10542 enum rtx_code rc = GET_CODE (operands[1]);
10544 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10545 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10546 if (mode == CCFPmode || mode == CCFPEmode)
10547 rc = reverse_condition_maybe_unordered (rc);
10549 rc = reverse_condition (rc);
10551 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10556 [(set (match_operand:SI 0 "s_register_operand" "")
10557 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10558 [(match_operand 2 "" "") (match_operand 3 "" "")])
10559 (match_operand 4 "" "")
10561 (clobber (reg:CC CC_REGNUM))]
10562 "TARGET_ARM && reload_completed"
10563 [(set (match_dup 5) (match_dup 6))
10564 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10565 (set (match_dup 0) (match_dup 4)))]
10568 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10569 operands[2], operands[3]);
10571 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10572 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10577 [(set (match_operand:SI 0 "s_register_operand" "")
10578 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10579 [(match_operand 2 "" "") (match_operand 3 "" "")])
10580 (match_operand 4 "" "")
10581 (match_operand 5 "" "")))
10582 (clobber (reg:CC CC_REGNUM))]
10583 "TARGET_ARM && reload_completed"
10584 [(set (match_dup 6) (match_dup 7))
10585 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10586 (set (match_dup 0) (match_dup 4)))
10587 (cond_exec (match_dup 8)
10588 (set (match_dup 0) (match_dup 5)))]
10591 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10592 operands[2], operands[3]);
10593 enum rtx_code rc = GET_CODE (operands[1]);
10595 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10596 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10597 if (mode == CCFPmode || mode == CCFPEmode)
10598 rc = reverse_condition_maybe_unordered (rc);
10600 rc = reverse_condition (rc);
10602 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10607 [(set (match_operand:SI 0 "s_register_operand" "")
10608 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10609 [(match_operand:SI 2 "s_register_operand" "")
10610 (match_operand:SI 3 "arm_add_operand" "")])
10611 (match_operand:SI 4 "arm_rhs_operand" "")
10613 (match_operand:SI 5 "s_register_operand" ""))))
10614 (clobber (reg:CC CC_REGNUM))]
10615 "TARGET_ARM && reload_completed"
10616 [(set (match_dup 6) (match_dup 7))
10617 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10618 (set (match_dup 0) (match_dup 4)))
10619 (cond_exec (match_dup 8)
10620 (set (match_dup 0) (not:SI (match_dup 5))))]
10623 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10624 operands[2], operands[3]);
10625 enum rtx_code rc = GET_CODE (operands[1]);
10627 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10628 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10629 if (mode == CCFPmode || mode == CCFPEmode)
10630 rc = reverse_condition_maybe_unordered (rc);
10632 rc = reverse_condition (rc);
10634 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10638 (define_insn "*cond_move_not"
10639 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10640 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10641 [(match_operand 3 "cc_register" "") (const_int 0)])
10642 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10644 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10648 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10649 [(set_attr "conds" "use")
10650 (set_attr "type" "mvn_reg,multiple")
10651 (set_attr "length" "4,8")]
10654 ;; The next two patterns occur when an AND operation is followed by a
10655 ;; scc insn sequence
10657 (define_insn "*sign_extract_onebit"
10658 [(set (match_operand:SI 0 "s_register_operand" "=r")
10659 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10661 (match_operand:SI 2 "const_int_operand" "n")))
10662 (clobber (reg:CC CC_REGNUM))]
10665 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10666 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10667 return \"mvnne\\t%0, #0\";
10669 [(set_attr "conds" "clob")
10670 (set_attr "length" "8")
10671 (set_attr "type" "multiple")]
10674 (define_insn "*not_signextract_onebit"
10675 [(set (match_operand:SI 0 "s_register_operand" "=r")
10677 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10679 (match_operand:SI 2 "const_int_operand" "n"))))
10680 (clobber (reg:CC CC_REGNUM))]
10683 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10684 output_asm_insn (\"tst\\t%1, %2\", operands);
10685 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10686 return \"movne\\t%0, #0\";
10688 [(set_attr "conds" "clob")
10689 (set_attr "length" "12")
10690 (set_attr "type" "multiple")]
10692 ;; ??? The above patterns need auditing for Thumb-2
10694 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10695 ;; expressions. For simplicity, the first register is also in the unspec
10697 ;; To avoid the usage of GNU extension, the length attribute is computed
10698 ;; in a C function arm_attr_length_push_multi.
10699 (define_insn "*push_multi"
10700 [(match_parallel 2 "multi_register_push"
10701 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10702 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10703 UNSPEC_PUSH_MULT))])]
10707 int num_saves = XVECLEN (operands[2], 0);
10709 /* For the StrongARM at least it is faster to
10710 use STR to store only a single register.
10711 In Thumb mode always use push, and the assembler will pick
10712 something appropriate. */
10713 if (num_saves == 1 && TARGET_ARM)
10714 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10721 strcpy (pattern, \"push%?\\t{%1\");
10723 strcpy (pattern, \"push\\t{%1\");
10725 for (i = 1; i < num_saves; i++)
10727 strcat (pattern, \", %|\");
10729 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10732 strcat (pattern, \"}\");
10733 output_asm_insn (pattern, operands);
10738 [(set_attr "type" "store_16")
10739 (set (attr "length")
10740 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10743 (define_insn "stack_tie"
10744 [(set (mem:BLK (scratch))
10745 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10746 (match_operand:SI 1 "s_register_operand" "rk")]
10750 [(set_attr "length" "0")
10751 (set_attr "type" "block")]
10754 ;; Pop (as used in epilogue RTL)
10756 (define_insn "*load_multiple_with_writeback"
10757 [(match_parallel 0 "load_multiple_operation"
10758 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10759 (plus:SI (match_dup 1)
10760 (match_operand:SI 2 "const_int_I_operand" "I")))
10761 (set (match_operand:SI 3 "s_register_operand" "=rk")
10762 (mem:SI (match_dup 1)))
10764 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10767 arm_output_multireg_pop (operands, /*return_pc=*/false,
10768 /*cond=*/const_true_rtx,
10774 [(set_attr "type" "load_16")
10775 (set_attr "predicable" "yes")
10776 (set (attr "length")
10777 (symbol_ref "arm_attr_length_pop_multi (operands,
10778 /*return_pc=*/false,
10779 /*write_back_p=*/true)"))]
10782 ;; Pop with return (as used in epilogue RTL)
10784 ;; This instruction is generated when the registers are popped at the end of
10785 ;; epilogue. Here, instead of popping the value into LR and then generating
10786 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10788 (define_insn "*pop_multiple_with_writeback_and_return"
10789 [(match_parallel 0 "pop_multiple_return"
10791 (set (match_operand:SI 1 "s_register_operand" "+rk")
10792 (plus:SI (match_dup 1)
10793 (match_operand:SI 2 "const_int_I_operand" "I")))
10794 (set (match_operand:SI 3 "s_register_operand" "=rk")
10795 (mem:SI (match_dup 1)))
10797 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10800 arm_output_multireg_pop (operands, /*return_pc=*/true,
10801 /*cond=*/const_true_rtx,
10807 [(set_attr "type" "load_16")
10808 (set_attr "predicable" "yes")
10809 (set (attr "length")
10810 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10811 /*write_back_p=*/true)"))]
10814 (define_insn "*pop_multiple_with_return"
10815 [(match_parallel 0 "pop_multiple_return"
10817 (set (match_operand:SI 2 "s_register_operand" "=rk")
10818 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10820 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10823 arm_output_multireg_pop (operands, /*return_pc=*/true,
10824 /*cond=*/const_true_rtx,
10830 [(set_attr "type" "load_16")
10831 (set_attr "predicable" "yes")
10832 (set (attr "length")
10833 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10834 /*write_back_p=*/false)"))]
10837 ;; Load into PC and return
10838 (define_insn "*ldr_with_return"
10840 (set (reg:SI PC_REGNUM)
10841 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10842 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10843 "ldr%?\t%|pc, [%0], #4"
10844 [(set_attr "type" "load_4")
10845 (set_attr "predicable" "yes")]
10847 ;; Pop for floating point registers (as used in epilogue RTL)
10848 (define_insn "*vfp_pop_multiple_with_writeback"
10849 [(match_parallel 0 "pop_multiple_fp"
10850 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10851 (plus:SI (match_dup 1)
10852 (match_operand:SI 2 "const_int_I_operand" "I")))
10853 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10854 (mem:DF (match_dup 1)))])]
10855 "TARGET_32BIT && TARGET_HARD_FLOAT"
10858 int num_regs = XVECLEN (operands[0], 0);
10861 strcpy (pattern, \"vldm\\t\");
10862 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10863 strcat (pattern, \"!, {\");
10864 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10865 strcat (pattern, \"%P0\");
10866 if ((num_regs - 1) > 1)
10868 strcat (pattern, \"-%P1\");
10869 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10872 strcat (pattern, \"}\");
10873 output_asm_insn (pattern, op_list);
10877 [(set_attr "type" "load_16")
10878 (set_attr "conds" "unconditional")
10879 (set_attr "predicable" "no")]
10882 ;; Special patterns for dealing with the constant pool
10884 (define_insn "align_4"
10885 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10888 assemble_align (32);
10891 [(set_attr "type" "no_insn")]
10894 (define_insn "align_8"
10895 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10898 assemble_align (64);
10901 [(set_attr "type" "no_insn")]
10904 (define_insn "consttable_end"
10905 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10908 making_const_table = FALSE;
10911 [(set_attr "type" "no_insn")]
10914 (define_insn "consttable_1"
10915 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10918 making_const_table = TRUE;
10919 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10920 assemble_zeros (3);
10923 [(set_attr "length" "4")
10924 (set_attr "type" "no_insn")]
10927 (define_insn "consttable_2"
10928 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10932 rtx x = operands[0];
10933 making_const_table = TRUE;
10934 switch (GET_MODE_CLASS (GET_MODE (x)))
10937 arm_emit_fp16_const (x);
10940 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10941 assemble_zeros (2);
10946 [(set_attr "length" "4")
10947 (set_attr "type" "no_insn")]
10950 (define_insn "consttable_4"
10951 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10955 rtx x = operands[0];
10956 making_const_table = TRUE;
10957 scalar_float_mode float_mode;
10958 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
10959 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
10962 /* XXX: Sometimes gcc does something really dumb and ends up with
10963 a HIGH in a constant pool entry, usually because it's trying to
10964 load into a VFP register. We know this will always be used in
10965 combination with a LO_SUM which ignores the high bits, so just
10966 strip off the HIGH. */
10967 if (GET_CODE (x) == HIGH)
10969 assemble_integer (x, 4, BITS_PER_WORD, 1);
10970 mark_symbol_refs_as_used (x);
10974 [(set_attr "length" "4")
10975 (set_attr "type" "no_insn")]
10978 (define_insn "consttable_8"
10979 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10983 making_const_table = TRUE;
10984 scalar_float_mode float_mode;
10985 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
10986 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10987 float_mode, BITS_PER_WORD);
10989 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10992 [(set_attr "length" "8")
10993 (set_attr "type" "no_insn")]
10996 (define_insn "consttable_16"
10997 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11001 making_const_table = TRUE;
11002 scalar_float_mode float_mode;
11003 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11004 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11005 float_mode, BITS_PER_WORD);
11007 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11010 [(set_attr "length" "16")
11011 (set_attr "type" "no_insn")]
11014 ;; V5 Instructions,
11016 (define_insn "clzsi2"
11017 [(set (match_operand:SI 0 "s_register_operand" "=r")
11018 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11019 "TARGET_32BIT && arm_arch5t"
11021 [(set_attr "predicable" "yes")
11022 (set_attr "type" "clz")])
11024 (define_insn "rbitsi2"
11025 [(set (match_operand:SI 0 "s_register_operand" "=r")
11026 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11027 "TARGET_32BIT && arm_arch_thumb2"
11029 [(set_attr "predicable" "yes")
11030 (set_attr "type" "clz")])
11032 ;; Keep this as a CTZ expression until after reload and then split
11033 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11034 ;; to fold with any other expression.
11036 (define_insn_and_split "ctzsi2"
11037 [(set (match_operand:SI 0 "s_register_operand" "=r")
11038 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11039 "TARGET_32BIT && arm_arch_thumb2"
11041 "&& reload_completed"
11044 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11045 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11049 ;; V5E instructions.
11051 (define_insn "prefetch"
11052 [(prefetch (match_operand:SI 0 "address_operand" "p")
11053 (match_operand:SI 1 "" "")
11054 (match_operand:SI 2 "" ""))]
11055 "TARGET_32BIT && arm_arch5te"
11057 [(set_attr "type" "load_4")]
11060 ;; General predication pattern
11063 [(match_operator 0 "arm_comparison_operator"
11064 [(match_operand 1 "cc_register" "")
11067 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11069 [(set_attr "predicated" "yes")]
11072 (define_insn "force_register_use"
11073 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11076 [(set_attr "length" "0")
11077 (set_attr "type" "no_insn")]
11081 ;; Patterns for exception handling
11083 (define_expand "eh_return"
11084 [(use (match_operand 0 "general_operand"))]
11089 emit_insn (gen_arm_eh_return (operands[0]));
11091 emit_insn (gen_thumb_eh_return (operands[0]));
11096 ;; We can't expand this before we know where the link register is stored.
11097 (define_insn_and_split "arm_eh_return"
11098 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11100 (clobber (match_scratch:SI 1 "=&r"))]
11103 "&& reload_completed"
11107 arm_set_return_address (operands[0], operands[1]);
11115 (define_insn "load_tp_hard"
11116 [(set (match_operand:SI 0 "register_operand" "=r")
11117 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11119 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11120 [(set_attr "predicable" "yes")
11121 (set_attr "type" "mrs")]
11124 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11125 (define_insn "load_tp_soft_fdpic"
11126 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11127 (clobber (reg:SI FDPIC_REGNUM))
11128 (clobber (reg:SI LR_REGNUM))
11129 (clobber (reg:SI IP_REGNUM))
11130 (clobber (reg:CC CC_REGNUM))]
11131 "TARGET_SOFT_TP && TARGET_FDPIC"
11132 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11133 [(set_attr "conds" "clob")
11134 (set_attr "type" "branch")]
11137 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11138 (define_insn "load_tp_soft"
11139 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11140 (clobber (reg:SI LR_REGNUM))
11141 (clobber (reg:SI IP_REGNUM))
11142 (clobber (reg:CC CC_REGNUM))]
11143 "TARGET_SOFT_TP && !TARGET_FDPIC"
11144 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11145 [(set_attr "conds" "clob")
11146 (set_attr "type" "branch")]
11149 ;; tls descriptor call
11150 (define_insn "tlscall"
11151 [(set (reg:SI R0_REGNUM)
11152 (unspec:SI [(reg:SI R0_REGNUM)
11153 (match_operand:SI 0 "" "X")
11154 (match_operand 1 "" "")] UNSPEC_TLS))
11155 (clobber (reg:SI R1_REGNUM))
11156 (clobber (reg:SI LR_REGNUM))
11157 (clobber (reg:SI CC_REGNUM))]
11160 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11161 INTVAL (operands[1]));
11162 return "bl\\t%c0(tlscall)";
11164 [(set_attr "conds" "clob")
11165 (set_attr "length" "4")
11166 (set_attr "type" "branch")]
11169 ;; For thread pointer builtin
11170 (define_expand "get_thread_pointersi"
11171 [(match_operand:SI 0 "s_register_operand")]
11175 arm_load_tp (operands[0]);
11181 ;; We only care about the lower 16 bits of the constant
11182 ;; being inserted into the upper 16 bits of the register.
11183 (define_insn "*arm_movtas_ze"
11184 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11187 (match_operand:SI 1 "const_int_operand" ""))]
11192 [(set_attr "arch" "32,v8mb")
11193 (set_attr "predicable" "yes")
11194 (set_attr "length" "4")
11195 (set_attr "type" "alu_sreg")]
11198 (define_insn "*arm_rev"
11199 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11200 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11206 [(set_attr "arch" "t1,t2,32")
11207 (set_attr "length" "2,2,4")
11208 (set_attr "predicable" "no,yes,yes")
11209 (set_attr "type" "rev")]
11212 (define_expand "arm_legacy_rev"
11213 [(set (match_operand:SI 2 "s_register_operand")
11214 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand")
11218 (lshiftrt:SI (match_dup 2)
11220 (set (match_operand:SI 3 "s_register_operand")
11221 (rotatert:SI (match_dup 1)
11224 (and:SI (match_dup 2)
11225 (const_int -65281)))
11226 (set (match_operand:SI 0 "s_register_operand")
11227 (xor:SI (match_dup 3)
11233 ;; Reuse temporaries to keep register pressure down.
11234 (define_expand "thumb_legacy_rev"
11235 [(set (match_operand:SI 2 "s_register_operand")
11236 (ashift:SI (match_operand:SI 1 "s_register_operand")
11238 (set (match_operand:SI 3 "s_register_operand")
11239 (lshiftrt:SI (match_dup 1)
11242 (ior:SI (match_dup 3)
11244 (set (match_operand:SI 4 "s_register_operand")
11246 (set (match_operand:SI 5 "s_register_operand")
11247 (rotatert:SI (match_dup 1)
11250 (ashift:SI (match_dup 5)
11253 (lshiftrt:SI (match_dup 5)
11256 (ior:SI (match_dup 5)
11259 (rotatert:SI (match_dup 5)
11261 (set (match_operand:SI 0 "s_register_operand")
11262 (ior:SI (match_dup 5)
11268 ;; ARM-specific expansion of signed mod by power of 2
11269 ;; using conditional negate.
11270 ;; For r0 % n where n is a power of 2 produce:
11272 ;; and r0, r0, #(n - 1)
11273 ;; and r1, r1, #(n - 1)
11274 ;; rsbpl r0, r1, #0
11276 (define_expand "modsi3"
11277 [(match_operand:SI 0 "register_operand")
11278 (match_operand:SI 1 "register_operand")
11279 (match_operand:SI 2 "const_int_operand")]
11282 HOST_WIDE_INT val = INTVAL (operands[2]);
11285 || exact_log2 (val) <= 0)
11288 rtx mask = GEN_INT (val - 1);
11290 /* In the special case of x0 % 2 we can do the even shorter:
11293 rsblt r0, r0, #0. */
11297 rtx cc_reg = arm_gen_compare_reg (LT,
11298 operands[1], const0_rtx, NULL_RTX);
11299 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11300 rtx masked = gen_reg_rtx (SImode);
11302 emit_insn (gen_andsi3 (masked, operands[1], mask));
11303 emit_move_insn (operands[0],
11304 gen_rtx_IF_THEN_ELSE (SImode, cond,
11305 gen_rtx_NEG (SImode,
11311 rtx neg_op = gen_reg_rtx (SImode);
11312 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11315 /* Extract the condition register and mode. */
11316 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11317 rtx cc_reg = SET_DEST (cmp);
11318 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11320 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11322 rtx masked_neg = gen_reg_rtx (SImode);
11323 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11325 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11326 during expand does not always work. Do an IF_THEN_ELSE instead. */
11327 emit_move_insn (operands[0],
11328 gen_rtx_IF_THEN_ELSE (SImode, cond,
11329 gen_rtx_NEG (SImode, masked_neg),
11337 (define_expand "bswapsi2"
11338 [(set (match_operand:SI 0 "s_register_operand")
11339 (bswap:SI (match_operand:SI 1 "s_register_operand")))]
11340 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11344 rtx op2 = gen_reg_rtx (SImode);
11345 rtx op3 = gen_reg_rtx (SImode);
11349 rtx op4 = gen_reg_rtx (SImode);
11350 rtx op5 = gen_reg_rtx (SImode);
11352 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11353 op2, op3, op4, op5));
11357 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11366 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11367 ;; and unsigned variants, respectively. For rev16, expose
11368 ;; byte-swapping in the lower 16 bits only.
11369 (define_insn "*arm_revsh"
11370 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11371 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11377 [(set_attr "arch" "t1,t2,32")
11378 (set_attr "length" "2,2,4")
11379 (set_attr "type" "rev")]
11382 (define_insn "*arm_rev16"
11383 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11384 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11390 [(set_attr "arch" "t1,t2,32")
11391 (set_attr "length" "2,2,4")
11392 (set_attr "type" "rev")]
11395 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11396 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11397 ;; each valid permutation.
11399 (define_insn "arm_rev16si2"
11400 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11401 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11403 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11404 (and:SI (lshiftrt:SI (match_dup 1)
11406 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11408 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11409 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11411 [(set_attr "arch" "t1,t2,32")
11412 (set_attr "length" "2,2,4")
11413 (set_attr "type" "rev")]
11416 (define_insn "arm_rev16si2_alt"
11417 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11418 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11420 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11421 (and:SI (ashift:SI (match_dup 1)
11423 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11425 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11426 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11428 [(set_attr "arch" "t1,t2,32")
11429 (set_attr "length" "2,2,4")
11430 (set_attr "type" "rev")]
11433 (define_expand "bswaphi2"
11434 [(set (match_operand:HI 0 "s_register_operand")
11435 (bswap:HI (match_operand:HI 1 "s_register_operand")))]
11440 ;; Patterns for LDRD/STRD in Thumb2 mode
11442 (define_insn "*thumb2_ldrd"
11443 [(set (match_operand:SI 0 "s_register_operand" "=r")
11444 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11445 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11446 (set (match_operand:SI 3 "s_register_operand" "=r")
11447 (mem:SI (plus:SI (match_dup 1)
11448 (match_operand:SI 4 "const_int_operand" ""))))]
11449 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11450 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11451 && (operands_ok_ldrd_strd (operands[0], operands[3],
11452 operands[1], INTVAL (operands[2]),
11454 "ldrd%?\t%0, %3, [%1, %2]"
11455 [(set_attr "type" "load_8")
11456 (set_attr "predicable" "yes")])
11458 (define_insn "*thumb2_ldrd_base"
11459 [(set (match_operand:SI 0 "s_register_operand" "=r")
11460 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11461 (set (match_operand:SI 2 "s_register_operand" "=r")
11462 (mem:SI (plus:SI (match_dup 1)
11464 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11465 && (operands_ok_ldrd_strd (operands[0], operands[2],
11466 operands[1], 0, false, true))"
11467 "ldrd%?\t%0, %2, [%1]"
11468 [(set_attr "type" "load_8")
11469 (set_attr "predicable" "yes")])
11471 (define_insn "*thumb2_ldrd_base_neg"
11472 [(set (match_operand:SI 0 "s_register_operand" "=r")
11473 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11475 (set (match_operand:SI 2 "s_register_operand" "=r")
11476 (mem:SI (match_dup 1)))]
11477 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11478 && (operands_ok_ldrd_strd (operands[0], operands[2],
11479 operands[1], -4, false, true))"
11480 "ldrd%?\t%0, %2, [%1, #-4]"
11481 [(set_attr "type" "load_8")
11482 (set_attr "predicable" "yes")])
11484 (define_insn "*thumb2_strd"
11485 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11486 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11487 (match_operand:SI 2 "s_register_operand" "r"))
11488 (set (mem:SI (plus:SI (match_dup 0)
11489 (match_operand:SI 3 "const_int_operand" "")))
11490 (match_operand:SI 4 "s_register_operand" "r"))]
11491 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11492 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11493 && (operands_ok_ldrd_strd (operands[2], operands[4],
11494 operands[0], INTVAL (operands[1]),
11496 "strd%?\t%2, %4, [%0, %1]"
11497 [(set_attr "type" "store_8")
11498 (set_attr "predicable" "yes")])
11500 (define_insn "*thumb2_strd_base"
11501 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11502 (match_operand:SI 1 "s_register_operand" "r"))
11503 (set (mem:SI (plus:SI (match_dup 0)
11505 (match_operand:SI 2 "s_register_operand" "r"))]
11506 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11507 && (operands_ok_ldrd_strd (operands[1], operands[2],
11508 operands[0], 0, false, false))"
11509 "strd%?\t%1, %2, [%0]"
11510 [(set_attr "type" "store_8")
11511 (set_attr "predicable" "yes")])
11513 (define_insn "*thumb2_strd_base_neg"
11514 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11516 (match_operand:SI 1 "s_register_operand" "r"))
11517 (set (mem:SI (match_dup 0))
11518 (match_operand:SI 2 "s_register_operand" "r"))]
11519 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11520 && (operands_ok_ldrd_strd (operands[1], operands[2],
11521 operands[0], -4, false, false))"
11522 "strd%?\t%1, %2, [%0, #-4]"
11523 [(set_attr "type" "store_8")
11524 (set_attr "predicable" "yes")])
11526 ;; ARMv8 CRC32 instructions.
11527 (define_insn "arm_<crc_variant>"
11528 [(set (match_operand:SI 0 "s_register_operand" "=r")
11529 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11530 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11533 "<crc_variant>\\t%0, %1, %2"
11534 [(set_attr "type" "crc")
11535 (set_attr "conds" "unconditional")]
11538 ;; Load the load/store double peephole optimizations.
11539 (include "ldrdstrd.md")
11541 ;; Load the load/store multiple patterns
11542 (include "ldmstm.md")
11544 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11545 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11546 ;; The operands are validated through the load_multiple_operation
11547 ;; match_parallel predicate rather than through constraints so enable it only
11549 (define_insn "*load_multiple"
11550 [(match_parallel 0 "load_multiple_operation"
11551 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11552 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11554 "TARGET_32BIT && reload_completed"
11557 arm_output_multireg_pop (operands, /*return_pc=*/false,
11558 /*cond=*/const_true_rtx,
11564 [(set_attr "predicable" "yes")]
11567 (define_expand "copysignsf3"
11568 [(match_operand:SF 0 "register_operand")
11569 (match_operand:SF 1 "register_operand")
11570 (match_operand:SF 2 "register_operand")]
11571 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11573 emit_move_insn (operands[0], operands[2]);
11574 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11575 GEN_INT (31), GEN_INT (0),
11576 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11581 (define_expand "copysigndf3"
11582 [(match_operand:DF 0 "register_operand")
11583 (match_operand:DF 1 "register_operand")
11584 (match_operand:DF 2 "register_operand")]
11585 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11587 rtx op0_low = gen_lowpart (SImode, operands[0]);
11588 rtx op0_high = gen_highpart (SImode, operands[0]);
11589 rtx op1_low = gen_lowpart (SImode, operands[1]);
11590 rtx op1_high = gen_highpart (SImode, operands[1]);
11591 rtx op2_high = gen_highpart (SImode, operands[2]);
11593 rtx scratch1 = gen_reg_rtx (SImode);
11594 rtx scratch2 = gen_reg_rtx (SImode);
11595 emit_move_insn (scratch1, op2_high);
11596 emit_move_insn (scratch2, op1_high);
11598 emit_insn(gen_rtx_SET(scratch1,
11599 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11600 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11601 emit_move_insn (op0_low, op1_low);
11602 emit_move_insn (op0_high, scratch2);
11608 ;; movmisalign patterns for HImode and SImode.
11609 (define_expand "movmisalign<mode>"
11610 [(match_operand:HSI 0 "general_operand")
11611 (match_operand:HSI 1 "general_operand")]
11614 /* This pattern is not permitted to fail during expansion: if both arguments
11615 are non-registers (e.g. memory := constant), force operand 1 into a
11617 rtx (* gen_unaligned_load)(rtx, rtx);
11618 rtx tmp_dest = operands[0];
11619 if (!s_register_operand (operands[0], <MODE>mode)
11620 && !s_register_operand (operands[1], <MODE>mode))
11621 operands[1] = force_reg (<MODE>mode, operands[1]);
11623 if (<MODE>mode == HImode)
11625 gen_unaligned_load = gen_unaligned_loadhiu;
11626 tmp_dest = gen_reg_rtx (SImode);
11629 gen_unaligned_load = gen_unaligned_loadsi;
11631 if (MEM_P (operands[1]))
11633 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11634 if (<MODE>mode == HImode)
11635 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11638 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11643 (define_insn "arm_<cdp>"
11644 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11645 (match_operand:SI 1 "immediate_operand" "n")
11646 (match_operand:SI 2 "immediate_operand" "n")
11647 (match_operand:SI 3 "immediate_operand" "n")
11648 (match_operand:SI 4 "immediate_operand" "n")
11649 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11650 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11652 arm_const_bounds (operands[0], 0, 16);
11653 arm_const_bounds (operands[1], 0, 16);
11654 arm_const_bounds (operands[2], 0, (1 << 5));
11655 arm_const_bounds (operands[3], 0, (1 << 5));
11656 arm_const_bounds (operands[4], 0, (1 << 5));
11657 arm_const_bounds (operands[5], 0, 8);
11658 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11660 [(set_attr "length" "4")
11661 (set_attr "type" "coproc")])
11663 (define_insn "*ldc"
11664 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11665 (match_operand:SI 1 "immediate_operand" "n")
11666 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11667 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11669 arm_const_bounds (operands[0], 0, 16);
11670 arm_const_bounds (operands[1], 0, (1 << 5));
11671 return "<ldc>\\tp%c0, CR%c1, %2";
11673 [(set_attr "length" "4")
11674 (set_attr "type" "coproc")])
11676 (define_insn "*stc"
11677 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11678 (match_operand:SI 1 "immediate_operand" "n")
11679 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11680 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11682 arm_const_bounds (operands[0], 0, 16);
11683 arm_const_bounds (operands[1], 0, (1 << 5));
11684 return "<stc>\\tp%c0, CR%c1, %2";
11686 [(set_attr "length" "4")
11687 (set_attr "type" "coproc")])
11689 (define_expand "arm_<ldc>"
11690 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11691 (match_operand:SI 1 "immediate_operand")
11692 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11693 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11695 (define_expand "arm_<stc>"
11696 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11697 (match_operand:SI 1 "immediate_operand")
11698 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11699 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
11701 (define_insn "arm_<mcr>"
11702 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11703 (match_operand:SI 1 "immediate_operand" "n")
11704 (match_operand:SI 2 "s_register_operand" "r")
11705 (match_operand:SI 3 "immediate_operand" "n")
11706 (match_operand:SI 4 "immediate_operand" "n")
11707 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
11708 (use (match_dup 2))]
11709 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
11711 arm_const_bounds (operands[0], 0, 16);
11712 arm_const_bounds (operands[1], 0, 8);
11713 arm_const_bounds (operands[3], 0, (1 << 5));
11714 arm_const_bounds (operands[4], 0, (1 << 5));
11715 arm_const_bounds (operands[5], 0, 8);
11716 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
11718 [(set_attr "length" "4")
11719 (set_attr "type" "coproc")])
11721 (define_insn "arm_<mrc>"
11722 [(set (match_operand:SI 0 "s_register_operand" "=r")
11723 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
11724 (match_operand:SI 2 "immediate_operand" "n")
11725 (match_operand:SI 3 "immediate_operand" "n")
11726 (match_operand:SI 4 "immediate_operand" "n")
11727 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
11728 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
11730 arm_const_bounds (operands[1], 0, 16);
11731 arm_const_bounds (operands[2], 0, 8);
11732 arm_const_bounds (operands[3], 0, (1 << 5));
11733 arm_const_bounds (operands[4], 0, (1 << 5));
11734 arm_const_bounds (operands[5], 0, 8);
11735 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
11737 [(set_attr "length" "4")
11738 (set_attr "type" "coproc")])
11740 (define_insn "arm_<mcrr>"
11741 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11742 (match_operand:SI 1 "immediate_operand" "n")
11743 (match_operand:DI 2 "s_register_operand" "r")
11744 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
11745 (use (match_dup 2))]
11746 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
11748 arm_const_bounds (operands[0], 0, 16);
11749 arm_const_bounds (operands[1], 0, 8);
11750 arm_const_bounds (operands[3], 0, (1 << 5));
11751 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
11753 [(set_attr "length" "4")
11754 (set_attr "type" "coproc")])
11756 (define_insn "arm_<mrrc>"
11757 [(set (match_operand:DI 0 "s_register_operand" "=r")
11758 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
11759 (match_operand:SI 2 "immediate_operand" "n")
11760 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
11761 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
11763 arm_const_bounds (operands[1], 0, 16);
11764 arm_const_bounds (operands[2], 0, 8);
11765 arm_const_bounds (operands[3], 0, (1 << 5));
11766 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
11768 [(set_attr "length" "4")
11769 (set_attr "type" "coproc")])
11771 (define_expand "speculation_barrier"
11772 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
11775 /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
11776 have a usable barrier (and probably don't need one in practice).
11777 But to be safe if such code is run on later architectures, call a
11778 helper function in libgcc that will do the thing for the active
11780 if (!(arm_arch7 || arm_arch8))
11782 arm_emit_speculation_barrier_function ();
11788 ;; Generate a hard speculation barrier when we have not enabled speculation
11790 (define_insn "*speculation_barrier_insn"
11791 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
11792 "arm_arch7 || arm_arch8"
11794 [(set_attr "type" "block")
11795 (set_attr "length" "8")]
11798 ;; Vector bits common to IWMMXT and Neon
11799 (include "vec-common.md")
11800 ;; Load the Intel Wireless Multimedia Extension patterns
11801 (include "iwmmxt.md")
11802 ;; Load the VFP co-processor patterns
11804 ;; Thumb-1 patterns
11805 (include "thumb1.md")
11806 ;; Thumb-2 patterns
11807 (include "thumb2.md")
11809 (include "neon.md")
11811 (include "crypto.md")
11812 ;; Synchronization Primitives
11813 (include "sync.md")
11814 ;; Fixed-point patterns
11815 (include "arm-fixed.md")