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_expand "extendsfdf2"
5062 [(set (match_operand:DF 0 "s_register_operand")
5063 (float_extend:DF (match_operand:SF 1 "s_register_operand")))]
5064 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5068 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5069 ;; must go through SFmode.
5071 ;; This is always safe for an extend.
5073 (define_expand "extendhfdf2"
5074 [(set (match_operand:DF 0 "s_register_operand")
5075 (float_extend:DF (match_operand:HF 1 "s_register_operand")))]
5078 /* We don't have a direct instruction for this, so go via SFmode. */
5079 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5082 op1 = convert_to_mode (SFmode, operands[1], 0);
5083 op1 = convert_to_mode (DFmode, op1, 0);
5084 emit_insn (gen_movdf (operands[0], op1));
5087 /* Otherwise, we're done producing RTL and will pick up the correct
5088 pattern to do this with one rounding-step in a single instruction. */
5092 ;; Move insns (including loads and stores)
5094 ;; XXX Just some ideas about movti.
5095 ;; I don't think these are a good idea on the arm, there just aren't enough
5097 ;;(define_expand "loadti"
5098 ;; [(set (match_operand:TI 0 "s_register_operand")
5099 ;; (mem:TI (match_operand:SI 1 "address_operand")))]
5102 ;;(define_expand "storeti"
5103 ;; [(set (mem:TI (match_operand:TI 0 "address_operand"))
5104 ;; (match_operand:TI 1 "s_register_operand"))]
5107 ;;(define_expand "movti"
5108 ;; [(set (match_operand:TI 0 "general_operand")
5109 ;; (match_operand:TI 1 "general_operand"))]
5115 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5116 ;; operands[1] = copy_to_reg (operands[1]);
5117 ;; if (MEM_P (operands[0]))
5118 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5119 ;; else if (MEM_P (operands[1]))
5120 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5124 ;; emit_insn (insn);
5128 ;; Recognize garbage generated above.
5131 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5132 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5136 ;; register mem = (which_alternative < 3);
5137 ;; register const char *template;
5139 ;; operands[mem] = XEXP (operands[mem], 0);
5140 ;; switch (which_alternative)
5142 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5143 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5144 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5145 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5146 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5147 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5149 ;; output_asm_insn (template, operands);
5153 (define_expand "movdi"
5154 [(set (match_operand:DI 0 "general_operand")
5155 (match_operand:DI 1 "general_operand"))]
5158 gcc_checking_assert (aligned_operand (operands[0], DImode));
5159 gcc_checking_assert (aligned_operand (operands[1], DImode));
5160 if (can_create_pseudo_p ())
5162 if (!REG_P (operands[0]))
5163 operands[1] = force_reg (DImode, operands[1]);
5165 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5166 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5168 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5169 when expanding function calls. */
5170 gcc_assert (can_create_pseudo_p ());
5171 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5173 /* Perform load into legal reg pair first, then move. */
5174 rtx reg = gen_reg_rtx (DImode);
5175 emit_insn (gen_movdi (reg, operands[1]));
5178 emit_move_insn (gen_lowpart (SImode, operands[0]),
5179 gen_lowpart (SImode, operands[1]));
5180 emit_move_insn (gen_highpart (SImode, operands[0]),
5181 gen_highpart (SImode, operands[1]));
5184 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5185 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5187 /* Avoid STRD's from an odd-numbered register pair in ARM state
5188 when expanding function prologue. */
5189 gcc_assert (can_create_pseudo_p ());
5190 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5191 ? gen_reg_rtx (DImode)
5193 emit_move_insn (gen_lowpart (SImode, split_dest),
5194 gen_lowpart (SImode, operands[1]));
5195 emit_move_insn (gen_highpart (SImode, split_dest),
5196 gen_highpart (SImode, operands[1]));
5197 if (split_dest != operands[0])
5198 emit_insn (gen_movdi (operands[0], split_dest));
5204 (define_insn "*arm_movdi"
5205 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
5206 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
5208 && !(TARGET_HARD_FLOAT)
5210 && ( register_operand (operands[0], DImode)
5211 || register_operand (operands[1], DImode))"
5213 switch (which_alternative)
5220 /* Cannot load it directly, split to load it via MOV / MOVT. */
5221 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
5225 return output_move_double (operands, true, NULL);
5228 [(set_attr "length" "8,12,16,8,8")
5229 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5230 (set_attr "arm_pool_range" "*,*,*,1020,*")
5231 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5232 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5233 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5237 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5238 (match_operand:ANY64 1 "immediate_operand" ""))]
5241 && (arm_disable_literal_pool
5242 || (arm_const_double_inline_cost (operands[1])
5243 <= arm_max_const_double_inline_cost ()))"
5246 arm_split_constant (SET, SImode, curr_insn,
5247 INTVAL (gen_lowpart (SImode, operands[1])),
5248 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5249 arm_split_constant (SET, SImode, curr_insn,
5250 INTVAL (gen_highpart_mode (SImode,
5251 GET_MODE (operands[0]),
5253 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5258 ; If optimizing for size, or if we have load delay slots, then
5259 ; we want to split the constant into two separate operations.
5260 ; In both cases this may split a trivial part into a single data op
5261 ; leaving a single complex constant to load. We can also get longer
5262 ; offsets in a LDR which means we get better chances of sharing the pool
5263 ; entries. Finally, we can normally do a better job of scheduling
5264 ; LDR instructions than we can with LDM.
5265 ; This pattern will only match if the one above did not.
5267 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5268 (match_operand:ANY64 1 "const_double_operand" ""))]
5269 "TARGET_ARM && reload_completed
5270 && arm_const_double_by_parts (operands[1])"
5271 [(set (match_dup 0) (match_dup 1))
5272 (set (match_dup 2) (match_dup 3))]
5274 operands[2] = gen_highpart (SImode, operands[0]);
5275 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5277 operands[0] = gen_lowpart (SImode, operands[0]);
5278 operands[1] = gen_lowpart (SImode, operands[1]);
5283 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5284 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5285 "TARGET_EITHER && reload_completed"
5286 [(set (match_dup 0) (match_dup 1))
5287 (set (match_dup 2) (match_dup 3))]
5289 operands[2] = gen_highpart (SImode, operands[0]);
5290 operands[3] = gen_highpart (SImode, operands[1]);
5291 operands[0] = gen_lowpart (SImode, operands[0]);
5292 operands[1] = gen_lowpart (SImode, operands[1]);
5294 /* Handle a partial overlap. */
5295 if (rtx_equal_p (operands[0], operands[3]))
5297 rtx tmp0 = operands[0];
5298 rtx tmp1 = operands[1];
5300 operands[0] = operands[2];
5301 operands[1] = operands[3];
5308 ;; We can't actually do base+index doubleword loads if the index and
5309 ;; destination overlap. Split here so that we at least have chance to
5312 [(set (match_operand:DI 0 "s_register_operand" "")
5313 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5314 (match_operand:SI 2 "s_register_operand" ""))))]
5316 && reg_overlap_mentioned_p (operands[0], operands[1])
5317 && reg_overlap_mentioned_p (operands[0], operands[2])"
5319 (plus:SI (match_dup 1)
5322 (mem:DI (match_dup 4)))]
5324 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5328 (define_expand "movsi"
5329 [(set (match_operand:SI 0 "general_operand")
5330 (match_operand:SI 1 "general_operand"))]
5334 rtx base, offset, tmp;
5336 gcc_checking_assert (aligned_operand (operands[0], SImode));
5337 gcc_checking_assert (aligned_operand (operands[1], SImode));
5338 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5340 /* Everything except mem = const or mem = mem can be done easily. */
5341 if (MEM_P (operands[0]))
5342 operands[1] = force_reg (SImode, operands[1]);
5343 if (arm_general_register_operand (operands[0], SImode)
5344 && CONST_INT_P (operands[1])
5345 && !(const_ok_for_arm (INTVAL (operands[1]))
5346 || const_ok_for_arm (~INTVAL (operands[1]))))
5348 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5350 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5355 arm_split_constant (SET, SImode, NULL_RTX,
5356 INTVAL (operands[1]), operands[0], NULL_RTX,
5357 optimize && can_create_pseudo_p ());
5362 else /* Target doesn't have MOVT... */
5364 if (can_create_pseudo_p ())
5366 if (!REG_P (operands[0]))
5367 operands[1] = force_reg (SImode, operands[1]);
5371 split_const (operands[1], &base, &offset);
5372 if (INTVAL (offset) != 0
5373 && targetm.cannot_force_const_mem (SImode, operands[1]))
5375 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5376 emit_move_insn (tmp, base);
5377 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5381 tmp = can_create_pseudo_p () ? NULL_RTX : operands[0];
5383 /* Recognize the case where operand[1] is a reference to thread-local
5384 data and load its address to a register. Offsets have been split off
5386 if (arm_tls_referenced_p (operands[1]))
5387 operands[1] = legitimize_tls_address (operands[1], tmp);
5389 && (CONSTANT_P (operands[1])
5390 || symbol_mentioned_p (operands[1])
5391 || label_mentioned_p (operands[1])))
5393 legitimize_pic_address (operands[1], SImode, tmp, NULL_RTX, false);
5398 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5399 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5400 ;; so this does not matter.
5401 (define_insn "*arm_movt"
5402 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
5403 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5404 (match_operand:SI 2 "general_operand" "i,i")))]
5405 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
5407 movt%?\t%0, #:upper16:%c2
5408 movt\t%0, #:upper16:%c2"
5409 [(set_attr "arch" "32,v8mb")
5410 (set_attr "predicable" "yes")
5411 (set_attr "length" "4")
5412 (set_attr "type" "alu_sreg")]
5415 (define_insn "*arm_movsi_insn"
5416 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5417 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
5418 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
5419 && ( register_operand (operands[0], SImode)
5420 || register_operand (operands[1], SImode))"
5428 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
5429 (set_attr "predicable" "yes")
5430 (set_attr "arch" "*,*,*,v6t2,*,*")
5431 (set_attr "pool_range" "*,*,*,*,4096,*")
5432 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5436 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5437 (match_operand:SI 1 "const_int_operand" ""))]
5438 "(TARGET_32BIT || TARGET_HAVE_MOVT)
5439 && (!(const_ok_for_arm (INTVAL (operands[1]))
5440 || const_ok_for_arm (~INTVAL (operands[1]))))"
5441 [(clobber (const_int 0))]
5443 arm_split_constant (SET, SImode, NULL_RTX,
5444 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5449 ;; A normal way to do (symbol + offset) requires three instructions at least
5450 ;; (depends on how big the offset is) as below:
5451 ;; movw r0, #:lower16:g
5452 ;; movw r0, #:upper16:g
5455 ;; A better way would be:
5456 ;; movw r0, #:lower16:g+4
5457 ;; movw r0, #:upper16:g+4
5459 ;; The limitation of this way is that the length of offset should be a 16-bit
5460 ;; signed value, because current assembler only supports REL type relocation for
5461 ;; such case. If the more powerful RELA type is supported in future, we should
5462 ;; update this pattern to go with better way.
5464 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5465 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5466 (match_operand:SI 2 "const_int_operand" ""))))]
5469 && arm_disable_literal_pool
5471 && GET_CODE (operands[1]) == SYMBOL_REF"
5472 [(clobber (const_int 0))]
5474 int offset = INTVAL (operands[2]);
5476 if (offset < -0x8000 || offset > 0x7fff)
5478 arm_emit_movpair (operands[0], operands[1]);
5479 emit_insn (gen_rtx_SET (operands[0],
5480 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5484 rtx op = gen_rtx_CONST (SImode,
5485 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5486 arm_emit_movpair (operands[0], op);
5491 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5492 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5493 ;; and lo_sum would be merged back into memory load at cprop. However,
5494 ;; if the default is to prefer movt/movw rather than a load from the constant
5495 ;; pool, the performance is better.
5497 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5498 (match_operand:SI 1 "general_operand" ""))]
5499 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5500 && !target_word_relocations
5501 && !arm_tls_referenced_p (operands[1])"
5502 [(clobber (const_int 0))]
5504 arm_emit_movpair (operands[0], operands[1]);
5508 ;; When generating pic, we need to load the symbol offset into a register.
5509 ;; So that the optimizer does not confuse this with a normal symbol load
5510 ;; we use an unspec. The offset will be loaded from a constant pool entry,
5511 ;; since that is the only type of relocation we can use.
5513 ;; Wrap calculation of the whole PIC address in a single pattern for the
5514 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5515 ;; a PIC address involves two loads from memory, so we want to CSE it
5516 ;; as often as possible.
5517 ;; This pattern will be split into one of the pic_load_addr_* patterns
5518 ;; and a move after GCSE optimizations.
5520 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5521 (define_expand "calculate_pic_address"
5522 [(set (match_operand:SI 0 "register_operand")
5523 (mem:SI (plus:SI (match_operand:SI 1 "register_operand")
5524 (unspec:SI [(match_operand:SI 2 "" "")]
5529 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5531 [(set (match_operand:SI 0 "register_operand" "")
5532 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5533 (unspec:SI [(match_operand:SI 2 "" "")]
5536 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5537 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5538 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5541 ;; operand1 is the memory address to go into
5542 ;; pic_load_addr_32bit.
5543 ;; operand2 is the PIC label to be emitted
5544 ;; from pic_add_dot_plus_eight.
5545 ;; We do this to allow hoisting of the entire insn.
5546 (define_insn_and_split "pic_load_addr_unified"
5547 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5548 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5549 (match_operand:SI 2 "" "")]
5550 UNSPEC_PIC_UNIFIED))]
5553 "&& reload_completed"
5554 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5555 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5556 (match_dup 2)] UNSPEC_PIC_BASE))]
5557 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5558 [(set_attr "type" "load_4,load_4,load_4")
5559 (set_attr "pool_range" "4096,4094,1022")
5560 (set_attr "neg_pool_range" "4084,0,0")
5561 (set_attr "arch" "a,t2,t1")
5562 (set_attr "length" "8,6,4")]
5565 ;; The rather odd constraints on the following are to force reload to leave
5566 ;; the insn alone, and to force the minipool generation pass to then move
5567 ;; the GOT symbol to memory.
5569 (define_insn "pic_load_addr_32bit"
5570 [(set (match_operand:SI 0 "s_register_operand" "=r")
5571 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5572 "TARGET_32BIT && flag_pic"
5574 [(set_attr "type" "load_4")
5575 (set (attr "pool_range")
5576 (if_then_else (eq_attr "is_thumb" "no")
5579 (set (attr "neg_pool_range")
5580 (if_then_else (eq_attr "is_thumb" "no")
5585 (define_insn "pic_load_addr_thumb1"
5586 [(set (match_operand:SI 0 "s_register_operand" "=l")
5587 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5588 "TARGET_THUMB1 && flag_pic"
5590 [(set_attr "type" "load_4")
5591 (set (attr "pool_range") (const_int 1018))]
5594 (define_insn "pic_add_dot_plus_four"
5595 [(set (match_operand:SI 0 "register_operand" "=r")
5596 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5598 (match_operand 2 "" "")]
5602 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5603 INTVAL (operands[2]));
5604 return \"add\\t%0, %|pc\";
5606 [(set_attr "length" "2")
5607 (set_attr "type" "alu_sreg")]
5610 (define_insn "pic_add_dot_plus_eight"
5611 [(set (match_operand:SI 0 "register_operand" "=r")
5612 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5614 (match_operand 2 "" "")]
5618 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5619 INTVAL (operands[2]));
5620 return \"add%?\\t%0, %|pc, %1\";
5622 [(set_attr "predicable" "yes")
5623 (set_attr "type" "alu_sreg")]
5626 (define_insn "tls_load_dot_plus_eight"
5627 [(set (match_operand:SI 0 "register_operand" "=r")
5628 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5630 (match_operand 2 "" "")]
5634 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5635 INTVAL (operands[2]));
5636 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5638 [(set_attr "predicable" "yes")
5639 (set_attr "type" "load_4")]
5642 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5643 ;; followed by a load. These sequences can be crunched down to
5644 ;; tls_load_dot_plus_eight by a peephole.
5647 [(set (match_operand:SI 0 "register_operand" "")
5648 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5650 (match_operand 1 "" "")]
5652 (set (match_operand:SI 2 "arm_general_register_operand" "")
5653 (mem:SI (match_dup 0)))]
5654 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5656 (mem:SI (unspec:SI [(match_dup 3)
5663 (define_insn "pic_offset_arm"
5664 [(set (match_operand:SI 0 "register_operand" "=r")
5665 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5666 (unspec:SI [(match_operand:SI 2 "" "X")]
5667 UNSPEC_PIC_OFFSET))))]
5668 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5669 "ldr%?\\t%0, [%1,%2]"
5670 [(set_attr "type" "load_4")]
5673 (define_expand "builtin_setjmp_receiver"
5674 [(label_ref (match_operand 0 "" ""))]
5678 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5680 if (arm_pic_register != INVALID_REGNUM)
5681 arm_load_pic_register (1UL << 3, NULL_RTX);
5685 ;; If copying one reg to another we can set the condition codes according to
5686 ;; its value. Such a move is common after a return from subroutine and the
5687 ;; result is being tested against zero.
5689 (define_insn "*movsi_compare0"
5690 [(set (reg:CC CC_REGNUM)
5691 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5693 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5698 subs%?\\t%0, %1, #0"
5699 [(set_attr "conds" "set")
5700 (set_attr "type" "alus_imm,alus_imm")]
5703 ;; Subroutine to store a half word from a register into memory.
5704 ;; Operand 0 is the source register (HImode)
5705 ;; Operand 1 is the destination address in a register (SImode)
5707 ;; In both this routine and the next, we must be careful not to spill
5708 ;; a memory address of reg+large_const into a separate PLUS insn, since this
5709 ;; can generate unrecognizable rtl.
5711 (define_expand "storehi"
5712 [;; store the low byte
5713 (set (match_operand 1 "" "") (match_dup 3))
5714 ;; extract the high byte
5716 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5717 ;; store the high byte
5718 (set (match_dup 4) (match_dup 5))]
5722 rtx op1 = operands[1];
5723 rtx addr = XEXP (op1, 0);
5724 enum rtx_code code = GET_CODE (addr);
5726 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5728 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
5730 operands[4] = adjust_address (op1, QImode, 1);
5731 operands[1] = adjust_address (operands[1], QImode, 0);
5732 operands[3] = gen_lowpart (QImode, operands[0]);
5733 operands[0] = gen_lowpart (SImode, operands[0]);
5734 operands[2] = gen_reg_rtx (SImode);
5735 operands[5] = gen_lowpart (QImode, operands[2]);
5739 (define_expand "storehi_bigend"
5740 [(set (match_dup 4) (match_dup 3))
5742 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5743 (set (match_operand 1 "" "") (match_dup 5))]
5747 rtx op1 = operands[1];
5748 rtx addr = XEXP (op1, 0);
5749 enum rtx_code code = GET_CODE (addr);
5751 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5753 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
5755 operands[4] = adjust_address (op1, QImode, 1);
5756 operands[1] = adjust_address (operands[1], QImode, 0);
5757 operands[3] = gen_lowpart (QImode, operands[0]);
5758 operands[0] = gen_lowpart (SImode, operands[0]);
5759 operands[2] = gen_reg_rtx (SImode);
5760 operands[5] = gen_lowpart (QImode, operands[2]);
5764 ;; Subroutine to store a half word integer constant into memory.
5765 (define_expand "storeinthi"
5766 [(set (match_operand 0 "" "")
5767 (match_operand 1 "" ""))
5768 (set (match_dup 3) (match_dup 2))]
5772 HOST_WIDE_INT value = INTVAL (operands[1]);
5773 rtx addr = XEXP (operands[0], 0);
5774 rtx op0 = operands[0];
5775 enum rtx_code code = GET_CODE (addr);
5777 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5779 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
5781 operands[1] = gen_reg_rtx (SImode);
5782 if (BYTES_BIG_ENDIAN)
5784 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
5785 if ((value & 255) == ((value >> 8) & 255))
5786 operands[2] = operands[1];
5789 operands[2] = gen_reg_rtx (SImode);
5790 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
5795 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
5796 if ((value & 255) == ((value >> 8) & 255))
5797 operands[2] = operands[1];
5800 operands[2] = gen_reg_rtx (SImode);
5801 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
5805 operands[3] = adjust_address (op0, QImode, 1);
5806 operands[0] = adjust_address (operands[0], QImode, 0);
5807 operands[2] = gen_lowpart (QImode, operands[2]);
5808 operands[1] = gen_lowpart (QImode, operands[1]);
5812 (define_expand "storehi_single_op"
5813 [(set (match_operand:HI 0 "memory_operand")
5814 (match_operand:HI 1 "general_operand"))]
5815 "TARGET_32BIT && arm_arch4"
5817 if (!s_register_operand (operands[1], HImode))
5818 operands[1] = copy_to_mode_reg (HImode, operands[1]);
5822 (define_expand "movhi"
5823 [(set (match_operand:HI 0 "general_operand")
5824 (match_operand:HI 1 "general_operand"))]
5827 gcc_checking_assert (aligned_operand (operands[0], HImode));
5828 gcc_checking_assert (aligned_operand (operands[1], HImode));
5831 if (can_create_pseudo_p ())
5833 if (MEM_P (operands[0]))
5837 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
5840 if (CONST_INT_P (operands[1]))
5841 emit_insn (gen_storeinthi (operands[0], operands[1]));
5844 if (MEM_P (operands[1]))
5845 operands[1] = force_reg (HImode, operands[1]);
5846 if (BYTES_BIG_ENDIAN)
5847 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
5849 emit_insn (gen_storehi (operands[1], operands[0]));
5853 /* Sign extend a constant, and keep it in an SImode reg. */
5854 else if (CONST_INT_P (operands[1]))
5856 rtx reg = gen_reg_rtx (SImode);
5857 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
5859 /* If the constant is already valid, leave it alone. */
5860 if (!const_ok_for_arm (val))
5862 /* If setting all the top bits will make the constant
5863 loadable in a single instruction, then set them.
5864 Otherwise, sign extend the number. */
5866 if (const_ok_for_arm (~(val | ~0xffff)))
5868 else if (val & 0x8000)
5872 emit_insn (gen_movsi (reg, GEN_INT (val)));
5873 operands[1] = gen_lowpart (HImode, reg);
5875 else if (arm_arch4 && optimize && can_create_pseudo_p ()
5876 && MEM_P (operands[1]))
5878 rtx reg = gen_reg_rtx (SImode);
5880 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
5881 operands[1] = gen_lowpart (HImode, reg);
5883 else if (!arm_arch4)
5885 if (MEM_P (operands[1]))
5888 rtx offset = const0_rtx;
5889 rtx reg = gen_reg_rtx (SImode);
5891 if ((REG_P (base = XEXP (operands[1], 0))
5892 || (GET_CODE (base) == PLUS
5893 && (CONST_INT_P (offset = XEXP (base, 1)))
5894 && ((INTVAL(offset) & 1) != 1)
5895 && REG_P (base = XEXP (base, 0))))
5896 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
5900 new_rtx = widen_memory_access (operands[1], SImode,
5901 ((INTVAL (offset) & ~3)
5902 - INTVAL (offset)));
5903 emit_insn (gen_movsi (reg, new_rtx));
5904 if (((INTVAL (offset) & 2) != 0)
5905 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
5907 rtx reg2 = gen_reg_rtx (SImode);
5909 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
5914 emit_insn (gen_movhi_bytes (reg, operands[1]));
5916 operands[1] = gen_lowpart (HImode, reg);
5920 /* Handle loading a large integer during reload. */
5921 else if (CONST_INT_P (operands[1])
5922 && !const_ok_for_arm (INTVAL (operands[1]))
5923 && !const_ok_for_arm (~INTVAL (operands[1])))
5925 /* Writing a constant to memory needs a scratch, which should
5926 be handled with SECONDARY_RELOADs. */
5927 gcc_assert (REG_P (operands[0]));
5929 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
5930 emit_insn (gen_movsi (operands[0], operands[1]));
5934 else if (TARGET_THUMB2)
5936 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
5937 if (can_create_pseudo_p ())
5939 if (!REG_P (operands[0]))
5940 operands[1] = force_reg (HImode, operands[1]);
5941 /* Zero extend a constant, and keep it in an SImode reg. */
5942 else if (CONST_INT_P (operands[1]))
5944 rtx reg = gen_reg_rtx (SImode);
5945 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
5947 emit_insn (gen_movsi (reg, GEN_INT (val)));
5948 operands[1] = gen_lowpart (HImode, reg);
5952 else /* TARGET_THUMB1 */
5954 if (can_create_pseudo_p ())
5956 if (CONST_INT_P (operands[1]))
5958 rtx reg = gen_reg_rtx (SImode);
5960 emit_insn (gen_movsi (reg, operands[1]));
5961 operands[1] = gen_lowpart (HImode, reg);
5964 /* ??? We shouldn't really get invalid addresses here, but this can
5965 happen if we are passed a SP (never OK for HImode/QImode) or
5966 virtual register (also rejected as illegitimate for HImode/QImode)
5967 relative address. */
5968 /* ??? This should perhaps be fixed elsewhere, for instance, in
5969 fixup_stack_1, by checking for other kinds of invalid addresses,
5970 e.g. a bare reference to a virtual register. This may confuse the
5971 alpha though, which must handle this case differently. */
5972 if (MEM_P (operands[0])
5973 && !memory_address_p (GET_MODE (operands[0]),
5974 XEXP (operands[0], 0)))
5976 = replace_equiv_address (operands[0],
5977 copy_to_reg (XEXP (operands[0], 0)));
5979 if (MEM_P (operands[1])
5980 && !memory_address_p (GET_MODE (operands[1]),
5981 XEXP (operands[1], 0)))
5983 = replace_equiv_address (operands[1],
5984 copy_to_reg (XEXP (operands[1], 0)));
5986 if (MEM_P (operands[1]) && optimize > 0)
5988 rtx reg = gen_reg_rtx (SImode);
5990 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
5991 operands[1] = gen_lowpart (HImode, reg);
5994 if (MEM_P (operands[0]))
5995 operands[1] = force_reg (HImode, operands[1]);
5997 else if (CONST_INT_P (operands[1])
5998 && !satisfies_constraint_I (operands[1]))
6000 /* Handle loading a large integer during reload. */
6002 /* Writing a constant to memory needs a scratch, which should
6003 be handled with SECONDARY_RELOADs. */
6004 gcc_assert (REG_P (operands[0]));
6006 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6007 emit_insn (gen_movsi (operands[0], operands[1]));
6014 (define_expand "movhi_bytes"
6015 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6017 (zero_extend:SI (match_dup 6)))
6018 (set (match_operand:SI 0 "" "")
6019 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6024 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6026 mem1 = change_address (operands[1], QImode, addr);
6027 mem2 = change_address (operands[1], QImode,
6028 plus_constant (Pmode, addr, 1));
6029 operands[0] = gen_lowpart (SImode, operands[0]);
6031 operands[2] = gen_reg_rtx (SImode);
6032 operands[3] = gen_reg_rtx (SImode);
6035 if (BYTES_BIG_ENDIAN)
6037 operands[4] = operands[2];
6038 operands[5] = operands[3];
6042 operands[4] = operands[3];
6043 operands[5] = operands[2];
6048 (define_expand "movhi_bigend"
6050 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand") 0)
6053 (ashiftrt:SI (match_dup 2) (const_int 16)))
6054 (set (match_operand:HI 0 "s_register_operand")
6058 operands[2] = gen_reg_rtx (SImode);
6059 operands[3] = gen_reg_rtx (SImode);
6060 operands[4] = gen_lowpart (HImode, operands[3]);
6064 ;; Pattern to recognize insn generated default case above
6065 (define_insn "*movhi_insn_arch4"
6066 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6067 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6069 && arm_arch4 && !TARGET_HARD_FLOAT
6070 && (register_operand (operands[0], HImode)
6071 || register_operand (operands[1], HImode))"
6073 mov%?\\t%0, %1\\t%@ movhi
6074 mvn%?\\t%0, #%B1\\t%@ movhi
6075 movw%?\\t%0, %L1\\t%@ movhi
6076 strh%?\\t%1, %0\\t%@ movhi
6077 ldrh%?\\t%0, %1\\t%@ movhi"
6078 [(set_attr "predicable" "yes")
6079 (set_attr "pool_range" "*,*,*,*,256")
6080 (set_attr "neg_pool_range" "*,*,*,*,244")
6081 (set_attr "arch" "*,*,v6t2,*,*")
6082 (set_attr_alternative "type"
6083 [(if_then_else (match_operand 1 "const_int_operand" "")
6084 (const_string "mov_imm" )
6085 (const_string "mov_reg"))
6086 (const_string "mvn_imm")
6087 (const_string "mov_imm")
6088 (const_string "store_4")
6089 (const_string "load_4")])]
6092 (define_insn "*movhi_bytes"
6093 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6094 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6095 "TARGET_ARM && !TARGET_HARD_FLOAT"
6097 mov%?\\t%0, %1\\t%@ movhi
6098 mov%?\\t%0, %1\\t%@ movhi
6099 mvn%?\\t%0, #%B1\\t%@ movhi"
6100 [(set_attr "predicable" "yes")
6101 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6104 ;; We use a DImode scratch because we may occasionally need an additional
6105 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6106 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6107 ;; The reload_in<m> and reload_out<m> patterns require special constraints
6108 ;; to be correctly handled in default_secondary_reload function.
6109 (define_expand "reload_outhi"
6110 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6111 (match_operand:HI 1 "s_register_operand" "r")
6112 (match_operand:DI 2 "s_register_operand" "=&l")])]
6115 arm_reload_out_hi (operands);
6117 thumb_reload_out_hi (operands);
6122 (define_expand "reload_inhi"
6123 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6124 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6125 (match_operand:DI 2 "s_register_operand" "=&r")])]
6129 arm_reload_in_hi (operands);
6131 thumb_reload_out_hi (operands);
6135 (define_expand "movqi"
6136 [(set (match_operand:QI 0 "general_operand")
6137 (match_operand:QI 1 "general_operand"))]
6140 /* Everything except mem = const or mem = mem can be done easily */
6142 if (can_create_pseudo_p ())
6144 if (CONST_INT_P (operands[1]))
6146 rtx reg = gen_reg_rtx (SImode);
6148 /* For thumb we want an unsigned immediate, then we are more likely
6149 to be able to use a movs insn. */
6151 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6153 emit_insn (gen_movsi (reg, operands[1]));
6154 operands[1] = gen_lowpart (QImode, reg);
6159 /* ??? We shouldn't really get invalid addresses here, but this can
6160 happen if we are passed a SP (never OK for HImode/QImode) or
6161 virtual register (also rejected as illegitimate for HImode/QImode)
6162 relative address. */
6163 /* ??? This should perhaps be fixed elsewhere, for instance, in
6164 fixup_stack_1, by checking for other kinds of invalid addresses,
6165 e.g. a bare reference to a virtual register. This may confuse the
6166 alpha though, which must handle this case differently. */
6167 if (MEM_P (operands[0])
6168 && !memory_address_p (GET_MODE (operands[0]),
6169 XEXP (operands[0], 0)))
6171 = replace_equiv_address (operands[0],
6172 copy_to_reg (XEXP (operands[0], 0)));
6173 if (MEM_P (operands[1])
6174 && !memory_address_p (GET_MODE (operands[1]),
6175 XEXP (operands[1], 0)))
6177 = replace_equiv_address (operands[1],
6178 copy_to_reg (XEXP (operands[1], 0)));
6181 if (MEM_P (operands[1]) && optimize > 0)
6183 rtx reg = gen_reg_rtx (SImode);
6185 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6186 operands[1] = gen_lowpart (QImode, reg);
6189 if (MEM_P (operands[0]))
6190 operands[1] = force_reg (QImode, operands[1]);
6192 else if (TARGET_THUMB
6193 && CONST_INT_P (operands[1])
6194 && !satisfies_constraint_I (operands[1]))
6196 /* Handle loading a large integer during reload. */
6198 /* Writing a constant to memory needs a scratch, which should
6199 be handled with SECONDARY_RELOADs. */
6200 gcc_assert (REG_P (operands[0]));
6202 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6203 emit_insn (gen_movsi (operands[0], operands[1]));
6209 (define_insn "*arm_movqi_insn"
6210 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6211 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6213 && ( register_operand (operands[0], QImode)
6214 || register_operand (operands[1], QImode))"
6225 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6226 (set_attr "predicable" "yes")
6227 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6228 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6229 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6233 (define_expand "movhf"
6234 [(set (match_operand:HF 0 "general_operand")
6235 (match_operand:HF 1 "general_operand"))]
6238 gcc_checking_assert (aligned_operand (operands[0], HFmode));
6239 gcc_checking_assert (aligned_operand (operands[1], HFmode));
6242 if (MEM_P (operands[0]))
6243 operands[1] = force_reg (HFmode, operands[1]);
6245 else /* TARGET_THUMB1 */
6247 if (can_create_pseudo_p ())
6249 if (!REG_P (operands[0]))
6250 operands[1] = force_reg (HFmode, operands[1]);
6256 (define_insn "*arm32_movhf"
6257 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6258 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6259 "TARGET_32BIT && !TARGET_HARD_FLOAT
6260 && ( s_register_operand (operands[0], HFmode)
6261 || s_register_operand (operands[1], HFmode))"
6263 switch (which_alternative)
6265 case 0: /* ARM register from memory */
6266 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6267 case 1: /* memory from ARM register */
6268 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6269 case 2: /* ARM register from ARM register */
6270 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6271 case 3: /* ARM register from constant */
6276 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6278 ops[0] = operands[0];
6279 ops[1] = GEN_INT (bits);
6280 ops[2] = GEN_INT (bits & 0xff00);
6281 ops[3] = GEN_INT (bits & 0x00ff);
6283 if (arm_arch_thumb2)
6284 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6286 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6293 [(set_attr "conds" "unconditional")
6294 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6295 (set_attr "length" "4,4,4,8")
6296 (set_attr "predicable" "yes")]
6299 (define_expand "movsf"
6300 [(set (match_operand:SF 0 "general_operand")
6301 (match_operand:SF 1 "general_operand"))]
6304 gcc_checking_assert (aligned_operand (operands[0], SFmode));
6305 gcc_checking_assert (aligned_operand (operands[1], SFmode));
6308 if (MEM_P (operands[0]))
6309 operands[1] = force_reg (SFmode, operands[1]);
6311 else /* TARGET_THUMB1 */
6313 if (can_create_pseudo_p ())
6315 if (!REG_P (operands[0]))
6316 operands[1] = force_reg (SFmode, operands[1]);
6320 /* Cannot load it directly, generate a load with clobber so that it can be
6321 loaded via GPR with MOV / MOVT. */
6322 if (arm_disable_literal_pool
6323 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6324 && CONST_DOUBLE_P (operands[1])
6325 && TARGET_HARD_FLOAT
6326 && !vfp3_const_double_rtx (operands[1]))
6328 rtx clobreg = gen_reg_rtx (SFmode);
6329 emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
6336 ;; Transform a floating-point move of a constant into a core register into
6337 ;; an SImode operation.
6339 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6340 (match_operand:SF 1 "immediate_operand" ""))]
6343 && CONST_DOUBLE_P (operands[1])"
6344 [(set (match_dup 2) (match_dup 3))]
6346 operands[2] = gen_lowpart (SImode, operands[0]);
6347 operands[3] = gen_lowpart (SImode, operands[1]);
6348 if (operands[2] == 0 || operands[3] == 0)
6353 (define_insn "*arm_movsf_soft_insn"
6354 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6355 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6357 && TARGET_SOFT_FLOAT
6358 && (!MEM_P (operands[0])
6359 || register_operand (operands[1], SFmode))"
6361 switch (which_alternative)
6363 case 0: return \"mov%?\\t%0, %1\";
6365 /* Cannot load it directly, split to load it via MOV / MOVT. */
6366 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
6368 return \"ldr%?\\t%0, %1\\t%@ float\";
6369 case 2: return \"str%?\\t%1, %0\\t%@ float\";
6370 default: gcc_unreachable ();
6373 [(set_attr "predicable" "yes")
6374 (set_attr "type" "mov_reg,load_4,store_4")
6375 (set_attr "arm_pool_range" "*,4096,*")
6376 (set_attr "thumb2_pool_range" "*,4094,*")
6377 (set_attr "arm_neg_pool_range" "*,4084,*")
6378 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6381 ;; Splitter for the above.
6383 [(set (match_operand:SF 0 "s_register_operand")
6384 (match_operand:SF 1 "const_double_operand"))]
6385 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
6389 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
6390 rtx cst = gen_int_mode (buf, SImode);
6391 emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
6396 (define_expand "movdf"
6397 [(set (match_operand:DF 0 "general_operand")
6398 (match_operand:DF 1 "general_operand"))]
6401 gcc_checking_assert (aligned_operand (operands[0], DFmode));
6402 gcc_checking_assert (aligned_operand (operands[1], DFmode));
6405 if (MEM_P (operands[0]))
6406 operands[1] = force_reg (DFmode, operands[1]);
6408 else /* TARGET_THUMB */
6410 if (can_create_pseudo_p ())
6412 if (!REG_P (operands[0]))
6413 operands[1] = force_reg (DFmode, operands[1]);
6417 /* Cannot load it directly, generate a load with clobber so that it can be
6418 loaded via GPR with MOV / MOVT. */
6419 if (arm_disable_literal_pool
6420 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6421 && CONSTANT_P (operands[1])
6422 && TARGET_HARD_FLOAT
6423 && !arm_const_double_rtx (operands[1])
6424 && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
6426 rtx clobreg = gen_reg_rtx (DFmode);
6427 emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
6434 ;; Reloading a df mode value stored in integer regs to memory can require a
6436 ;; Another reload_out<m> pattern that requires special constraints.
6437 (define_expand "reload_outdf"
6438 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6439 (match_operand:DF 1 "s_register_operand" "r")
6440 (match_operand:SI 2 "s_register_operand" "=&r")]
6444 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6447 operands[2] = XEXP (operands[0], 0);
6448 else if (code == POST_INC || code == PRE_DEC)
6450 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6451 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6452 emit_insn (gen_movdi (operands[0], operands[1]));
6455 else if (code == PRE_INC)
6457 rtx reg = XEXP (XEXP (operands[0], 0), 0);
6459 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6462 else if (code == POST_DEC)
6463 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6465 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6466 XEXP (XEXP (operands[0], 0), 1)));
6468 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
6471 if (code == POST_DEC)
6472 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6478 (define_insn "*movdf_soft_insn"
6479 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
6480 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
6481 "TARGET_32BIT && TARGET_SOFT_FLOAT
6482 && ( register_operand (operands[0], DFmode)
6483 || register_operand (operands[1], DFmode))"
6485 switch (which_alternative)
6492 /* Cannot load it directly, split to load it via MOV / MOVT. */
6493 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
6497 return output_move_double (operands, true, NULL);
6500 [(set_attr "length" "8,12,16,8,8")
6501 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
6502 (set_attr "arm_pool_range" "*,*,*,1020,*")
6503 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6504 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6505 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6508 ;; Splitter for the above.
6510 [(set (match_operand:DF 0 "s_register_operand")
6511 (match_operand:DF 1 "const_double_operand"))]
6512 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
6516 int order = BYTES_BIG_ENDIAN ? 1 : 0;
6517 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
6518 unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
6519 ival |= (zext_hwi (buf[1 - order], 32) << 32);
6520 rtx cst = gen_int_mode (ival, DImode);
6521 emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
6527 ;; load- and store-multiple insns
6528 ;; The arm can load/store any set of registers, provided that they are in
6529 ;; ascending order, but these expanders assume a contiguous set.
6531 (define_expand "load_multiple"
6532 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6533 (match_operand:SI 1 "" ""))
6534 (use (match_operand:SI 2 "" ""))])]
6537 HOST_WIDE_INT offset = 0;
6539 /* Support only fixed point registers. */
6540 if (!CONST_INT_P (operands[2])
6541 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6542 || INTVAL (operands[2]) < 2
6543 || !MEM_P (operands[1])
6544 || !REG_P (operands[0])
6545 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6546 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6550 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6551 INTVAL (operands[2]),
6552 force_reg (SImode, XEXP (operands[1], 0)),
6553 FALSE, operands[1], &offset);
6556 (define_expand "store_multiple"
6557 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6558 (match_operand:SI 1 "" ""))
6559 (use (match_operand:SI 2 "" ""))])]
6562 HOST_WIDE_INT offset = 0;
6564 /* Support only fixed point registers. */
6565 if (!CONST_INT_P (operands[2])
6566 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6567 || INTVAL (operands[2]) < 2
6568 || !REG_P (operands[1])
6569 || !MEM_P (operands[0])
6570 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6571 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6575 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6576 INTVAL (operands[2]),
6577 force_reg (SImode, XEXP (operands[0], 0)),
6578 FALSE, operands[0], &offset);
6582 (define_expand "setmemsi"
6583 [(match_operand:BLK 0 "general_operand")
6584 (match_operand:SI 1 "const_int_operand")
6585 (match_operand:SI 2 "const_int_operand")
6586 (match_operand:SI 3 "const_int_operand")]
6589 if (arm_gen_setmem (operands))
6596 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6597 ;; We could let this apply for blocks of less than this, but it clobbers so
6598 ;; many registers that there is then probably a better way.
6600 (define_expand "cpymemqi"
6601 [(match_operand:BLK 0 "general_operand")
6602 (match_operand:BLK 1 "general_operand")
6603 (match_operand:SI 2 "const_int_operand")
6604 (match_operand:SI 3 "const_int_operand")]
6609 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6610 && !optimize_function_for_size_p (cfun))
6612 if (gen_cpymem_ldrd_strd (operands))
6617 if (arm_gen_cpymemqi (operands))
6621 else /* TARGET_THUMB1 */
6623 if ( INTVAL (operands[3]) != 4
6624 || INTVAL (operands[2]) > 48)
6627 thumb_expand_cpymemqi (operands);
6634 ;; Compare & branch insns
6635 ;; The range calculations are based as follows:
6636 ;; For forward branches, the address calculation returns the address of
6637 ;; the next instruction. This is 2 beyond the branch instruction.
6638 ;; For backward branches, the address calculation returns the address of
6639 ;; the first instruction in this pattern (cmp). This is 2 before the branch
6640 ;; instruction for the shortest sequence, and 4 before the branch instruction
6641 ;; if we have to jump around an unconditional branch.
6642 ;; To the basic branch range the PC offset must be added (this is +4).
6643 ;; So for forward branches we have
6644 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6645 ;; And for backward branches we have
6646 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6648 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6649 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
6651 (define_expand "cbranchsi4"
6652 [(set (pc) (if_then_else
6653 (match_operator 0 "expandable_comparison_operator"
6654 [(match_operand:SI 1 "s_register_operand")
6655 (match_operand:SI 2 "nonmemory_operand")])
6656 (label_ref (match_operand 3 "" ""))
6662 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6664 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6668 if (thumb1_cmpneg_operand (operands[2], SImode))
6670 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6671 operands[3], operands[0]));
6674 if (!thumb1_cmp_operand (operands[2], SImode))
6675 operands[2] = force_reg (SImode, operands[2]);
6678 (define_expand "cbranchsf4"
6679 [(set (pc) (if_then_else
6680 (match_operator 0 "expandable_comparison_operator"
6681 [(match_operand:SF 1 "s_register_operand")
6682 (match_operand:SF 2 "vfp_compare_operand")])
6683 (label_ref (match_operand 3 "" ""))
6685 "TARGET_32BIT && TARGET_HARD_FLOAT"
6686 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6687 operands[3])); DONE;"
6690 (define_expand "cbranchdf4"
6691 [(set (pc) (if_then_else
6692 (match_operator 0 "expandable_comparison_operator"
6693 [(match_operand:DF 1 "s_register_operand")
6694 (match_operand:DF 2 "vfp_compare_operand")])
6695 (label_ref (match_operand 3 "" ""))
6697 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6698 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6699 operands[3])); DONE;"
6702 (define_expand "cbranchdi4"
6703 [(set (pc) (if_then_else
6704 (match_operator 0 "expandable_comparison_operator"
6705 [(match_operand:DI 1 "s_register_operand")
6706 (match_operand:DI 2 "cmpdi_operand")])
6707 (label_ref (match_operand 3 "" ""))
6711 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6713 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6719 ;; Comparison and test insns
6721 (define_insn "*arm_cmpsi_insn"
6722 [(set (reg:CC CC_REGNUM)
6723 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6724 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
6732 [(set_attr "conds" "set")
6733 (set_attr "arch" "t2,t2,any,any,any")
6734 (set_attr "length" "2,2,4,4,4")
6735 (set_attr "predicable" "yes")
6736 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6737 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6740 (define_insn "*cmpsi_shiftsi"
6741 [(set (reg:CC CC_REGNUM)
6742 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
6743 (match_operator:SI 3 "shift_operator"
6744 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6745 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6748 [(set_attr "conds" "set")
6749 (set_attr "shift" "1")
6750 (set_attr "arch" "32,a,a")
6751 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6753 (define_insn "*cmpsi_shiftsi_swp"
6754 [(set (reg:CC_SWP CC_REGNUM)
6755 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6756 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6757 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6758 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6761 [(set_attr "conds" "set")
6762 (set_attr "shift" "1")
6763 (set_attr "arch" "32,a,a")
6764 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6766 (define_insn "*arm_cmpsi_negshiftsi_si"
6767 [(set (reg:CC_Z CC_REGNUM)
6769 (neg:SI (match_operator:SI 1 "shift_operator"
6770 [(match_operand:SI 2 "s_register_operand" "r")
6771 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6772 (match_operand:SI 0 "s_register_operand" "r")))]
6775 [(set_attr "conds" "set")
6776 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6777 (const_string "alus_shift_imm")
6778 (const_string "alus_shift_reg")))
6779 (set_attr "predicable" "yes")]
6782 ;; DImode comparisons. The generic code generates branches that
6783 ;; if-conversion cannot reduce to a conditional compare, so we do
6786 (define_insn_and_split "*arm_cmpdi_insn"
6787 [(set (reg:CC_NCV CC_REGNUM)
6788 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6789 (match_operand:DI 1 "arm_di_operand" "rDi")))
6790 (clobber (match_scratch:SI 2 "=r"))]
6792 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6793 "&& reload_completed"
6794 [(set (reg:CC CC_REGNUM)
6795 (compare:CC (match_dup 0) (match_dup 1)))
6796 (parallel [(set (reg:CC CC_REGNUM)
6797 (compare:CC (match_dup 3) (match_dup 4)))
6799 (minus:SI (match_dup 5)
6800 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))])]
6802 operands[3] = gen_highpart (SImode, operands[0]);
6803 operands[0] = gen_lowpart (SImode, operands[0]);
6804 if (CONST_INT_P (operands[1]))
6806 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);
6807 if (operands[4] == const0_rtx)
6808 operands[5] = operands[3];
6810 operands[5] = gen_rtx_PLUS (SImode, operands[3],
6811 gen_int_mode (-UINTVAL (operands[4]),
6816 operands[4] = gen_highpart (SImode, operands[1]);
6817 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6819 operands[1] = gen_lowpart (SImode, operands[1]);
6820 operands[2] = gen_lowpart (SImode, operands[2]);
6822 [(set_attr "conds" "set")
6823 (set_attr "length" "8")
6824 (set_attr "type" "multiple")]
6827 (define_insn_and_split "*arm_cmpdi_unsigned"
6828 [(set (reg:CC_CZ CC_REGNUM)
6829 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6830 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
6833 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6834 "&& reload_completed"
6835 [(set (reg:CC CC_REGNUM)
6836 (compare:CC (match_dup 2) (match_dup 3)))
6837 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6838 (set (reg:CC CC_REGNUM)
6839 (compare:CC (match_dup 0) (match_dup 1))))]
6841 operands[2] = gen_highpart (SImode, operands[0]);
6842 operands[0] = gen_lowpart (SImode, operands[0]);
6843 if (CONST_INT_P (operands[1]))
6844 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6846 operands[3] = gen_highpart (SImode, operands[1]);
6847 operands[1] = gen_lowpart (SImode, operands[1]);
6849 [(set_attr "conds" "set")
6850 (set_attr "enabled_for_short_it" "yes,yes,no,*")
6851 (set_attr "arch" "t2,t2,t2,a")
6852 (set_attr "length" "6,6,10,8")
6853 (set_attr "type" "multiple")]
6856 (define_insn "*arm_cmpdi_zero"
6857 [(set (reg:CC_Z CC_REGNUM)
6858 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6860 (clobber (match_scratch:SI 1 "=r"))]
6862 "orrs%?\\t%1, %Q0, %R0"
6863 [(set_attr "conds" "set")
6864 (set_attr "type" "logics_reg")]
6867 ; This insn allows redundant compares to be removed by cse, nothing should
6868 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6869 ; is deleted later on. The match_dup will match the mode here, so that
6870 ; mode changes of the condition codes aren't lost by this even though we don't
6871 ; specify what they are.
6873 (define_insn "*deleted_compare"
6874 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6876 "\\t%@ deleted compare"
6877 [(set_attr "conds" "set")
6878 (set_attr "length" "0")
6879 (set_attr "type" "no_insn")]
6883 ;; Conditional branch insns
6885 (define_expand "cbranch_cc"
6887 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
6888 (match_operand 2 "" "")])
6889 (label_ref (match_operand 3 "" ""))
6892 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
6893 operands[1], operands[2], NULL_RTX);
6894 operands[2] = const0_rtx;"
6898 ;; Patterns to match conditional branch insns.
6901 (define_insn "arm_cond_branch"
6903 (if_then_else (match_operator 1 "arm_comparison_operator"
6904 [(match_operand 2 "cc_register" "") (const_int 0)])
6905 (label_ref (match_operand 0 "" ""))
6909 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
6911 arm_ccfsm_state += 2;
6914 return \"b%d1\\t%l0\";
6916 [(set_attr "conds" "use")
6917 (set_attr "type" "branch")
6918 (set (attr "length")
6920 (and (match_test "TARGET_THUMB2")
6921 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
6922 (le (minus (match_dup 0) (pc)) (const_int 256))))
6927 (define_insn "*arm_cond_branch_reversed"
6929 (if_then_else (match_operator 1 "arm_comparison_operator"
6930 [(match_operand 2 "cc_register" "") (const_int 0)])
6932 (label_ref (match_operand 0 "" ""))))]
6935 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
6937 arm_ccfsm_state += 2;
6940 return \"b%D1\\t%l0\";
6942 [(set_attr "conds" "use")
6943 (set_attr "type" "branch")
6944 (set (attr "length")
6946 (and (match_test "TARGET_THUMB2")
6947 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
6948 (le (minus (match_dup 0) (pc)) (const_int 256))))
6957 (define_expand "cstore_cc"
6958 [(set (match_operand:SI 0 "s_register_operand")
6959 (match_operator:SI 1 "" [(match_operand 2 "" "")
6960 (match_operand 3 "" "")]))]
6962 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
6963 operands[2], operands[3], NULL_RTX);
6964 operands[3] = const0_rtx;"
6967 (define_insn_and_split "*mov_scc"
6968 [(set (match_operand:SI 0 "s_register_operand" "=r")
6969 (match_operator:SI 1 "arm_comparison_operator_mode"
6970 [(match_operand 2 "cc_register" "") (const_int 0)]))]
6972 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
6975 (if_then_else:SI (match_dup 1)
6979 [(set_attr "conds" "use")
6980 (set_attr "length" "8")
6981 (set_attr "type" "multiple")]
6984 (define_insn_and_split "*mov_negscc"
6985 [(set (match_operand:SI 0 "s_register_operand" "=r")
6986 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
6987 [(match_operand 2 "cc_register" "") (const_int 0)])))]
6989 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
6992 (if_then_else:SI (match_dup 1)
6996 operands[3] = GEN_INT (~0);
6998 [(set_attr "conds" "use")
6999 (set_attr "length" "8")
7000 (set_attr "type" "multiple")]
7003 (define_insn_and_split "*mov_notscc"
7004 [(set (match_operand:SI 0 "s_register_operand" "=r")
7005 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7006 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7008 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7011 (if_then_else:SI (match_dup 1)
7015 operands[3] = GEN_INT (~1);
7016 operands[4] = GEN_INT (~0);
7018 [(set_attr "conds" "use")
7019 (set_attr "length" "8")
7020 (set_attr "type" "multiple")]
7023 (define_expand "cstoresi4"
7024 [(set (match_operand:SI 0 "s_register_operand")
7025 (match_operator:SI 1 "expandable_comparison_operator"
7026 [(match_operand:SI 2 "s_register_operand")
7027 (match_operand:SI 3 "reg_or_int_operand")]))]
7028 "TARGET_32BIT || TARGET_THUMB1"
7030 rtx op3, scratch, scratch2;
7034 if (!arm_add_operand (operands[3], SImode))
7035 operands[3] = force_reg (SImode, operands[3]);
7036 emit_insn (gen_cstore_cc (operands[0], operands[1],
7037 operands[2], operands[3]));
7041 if (operands[3] == const0_rtx)
7043 switch (GET_CODE (operands[1]))
7046 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7050 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7054 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7055 NULL_RTX, 0, OPTAB_WIDEN);
7056 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7057 NULL_RTX, 0, OPTAB_WIDEN);
7058 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7059 operands[0], 1, OPTAB_WIDEN);
7063 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7065 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7066 NULL_RTX, 1, OPTAB_WIDEN);
7070 scratch = expand_binop (SImode, ashr_optab, operands[2],
7071 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7072 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7073 NULL_RTX, 0, OPTAB_WIDEN);
7074 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7078 /* LT is handled by generic code. No need for unsigned with 0. */
7085 switch (GET_CODE (operands[1]))
7088 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7089 NULL_RTX, 0, OPTAB_WIDEN);
7090 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7094 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7095 NULL_RTX, 0, OPTAB_WIDEN);
7096 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7100 op3 = force_reg (SImode, operands[3]);
7102 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7103 NULL_RTX, 1, OPTAB_WIDEN);
7104 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7105 NULL_RTX, 0, OPTAB_WIDEN);
7106 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7112 if (!thumb1_cmp_operand (op3, SImode))
7113 op3 = force_reg (SImode, op3);
7114 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7115 NULL_RTX, 0, OPTAB_WIDEN);
7116 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7117 NULL_RTX, 1, OPTAB_WIDEN);
7118 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7123 op3 = force_reg (SImode, operands[3]);
7124 scratch = force_reg (SImode, const0_rtx);
7125 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7131 if (!thumb1_cmp_operand (op3, SImode))
7132 op3 = force_reg (SImode, op3);
7133 scratch = force_reg (SImode, const0_rtx);
7134 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7140 if (!thumb1_cmp_operand (op3, SImode))
7141 op3 = force_reg (SImode, op3);
7142 scratch = gen_reg_rtx (SImode);
7143 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7147 op3 = force_reg (SImode, operands[3]);
7148 scratch = gen_reg_rtx (SImode);
7149 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7152 /* No good sequences for GT, LT. */
7159 (define_expand "cstorehf4"
7160 [(set (match_operand:SI 0 "s_register_operand")
7161 (match_operator:SI 1 "expandable_comparison_operator"
7162 [(match_operand:HF 2 "s_register_operand")
7163 (match_operand:HF 3 "vfp_compare_operand")]))]
7164 "TARGET_VFP_FP16INST"
7166 if (!arm_validize_comparison (&operands[1],
7171 emit_insn (gen_cstore_cc (operands[0], operands[1],
7172 operands[2], operands[3]));
7177 (define_expand "cstoresf4"
7178 [(set (match_operand:SI 0 "s_register_operand")
7179 (match_operator:SI 1 "expandable_comparison_operator"
7180 [(match_operand:SF 2 "s_register_operand")
7181 (match_operand:SF 3 "vfp_compare_operand")]))]
7182 "TARGET_32BIT && TARGET_HARD_FLOAT"
7183 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7184 operands[2], operands[3])); DONE;"
7187 (define_expand "cstoredf4"
7188 [(set (match_operand:SI 0 "s_register_operand")
7189 (match_operator:SI 1 "expandable_comparison_operator"
7190 [(match_operand:DF 2 "s_register_operand")
7191 (match_operand:DF 3 "vfp_compare_operand")]))]
7192 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7193 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7194 operands[2], operands[3])); DONE;"
7197 (define_expand "cstoredi4"
7198 [(set (match_operand:SI 0 "s_register_operand")
7199 (match_operator:SI 1 "expandable_comparison_operator"
7200 [(match_operand:DI 2 "s_register_operand")
7201 (match_operand:DI 3 "cmpdi_operand")]))]
7204 if (!arm_validize_comparison (&operands[1],
7208 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7215 ;; Conditional move insns
7217 (define_expand "movsicc"
7218 [(set (match_operand:SI 0 "s_register_operand")
7219 (if_then_else:SI (match_operand 1 "expandable_comparison_operator")
7220 (match_operand:SI 2 "arm_not_operand")
7221 (match_operand:SI 3 "arm_not_operand")))]
7228 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7229 &XEXP (operands[1], 1)))
7232 code = GET_CODE (operands[1]);
7233 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7234 XEXP (operands[1], 1), NULL_RTX);
7235 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7239 (define_expand "movhfcc"
7240 [(set (match_operand:HF 0 "s_register_operand")
7241 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7242 (match_operand:HF 2 "s_register_operand")
7243 (match_operand:HF 3 "s_register_operand")))]
7244 "TARGET_VFP_FP16INST"
7247 enum rtx_code code = GET_CODE (operands[1]);
7250 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7251 &XEXP (operands[1], 1)))
7254 code = GET_CODE (operands[1]);
7255 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7256 XEXP (operands[1], 1), NULL_RTX);
7257 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7261 (define_expand "movsfcc"
7262 [(set (match_operand:SF 0 "s_register_operand")
7263 (if_then_else:SF (match_operand 1 "arm_cond_move_operator")
7264 (match_operand:SF 2 "s_register_operand")
7265 (match_operand:SF 3 "s_register_operand")))]
7266 "TARGET_32BIT && TARGET_HARD_FLOAT"
7269 enum rtx_code code = GET_CODE (operands[1]);
7272 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7273 &XEXP (operands[1], 1)))
7276 code = GET_CODE (operands[1]);
7277 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7278 XEXP (operands[1], 1), NULL_RTX);
7279 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7283 (define_expand "movdfcc"
7284 [(set (match_operand:DF 0 "s_register_operand")
7285 (if_then_else:DF (match_operand 1 "arm_cond_move_operator")
7286 (match_operand:DF 2 "s_register_operand")
7287 (match_operand:DF 3 "s_register_operand")))]
7288 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7291 enum rtx_code code = GET_CODE (operands[1]);
7294 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7295 &XEXP (operands[1], 1)))
7297 code = GET_CODE (operands[1]);
7298 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7299 XEXP (operands[1], 1), NULL_RTX);
7300 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7304 (define_insn "*cmov<mode>"
7305 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7306 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7307 [(match_operand 2 "cc_register" "") (const_int 0)])
7308 (match_operand:SDF 3 "s_register_operand"
7310 (match_operand:SDF 4 "s_register_operand"
7311 "<F_constraint>")))]
7312 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7315 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7322 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7327 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7333 [(set_attr "conds" "use")
7334 (set_attr "type" "fcsel")]
7337 (define_insn "*cmovhf"
7338 [(set (match_operand:HF 0 "s_register_operand" "=t")
7339 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7340 [(match_operand 2 "cc_register" "") (const_int 0)])
7341 (match_operand:HF 3 "s_register_operand" "t")
7342 (match_operand:HF 4 "s_register_operand" "t")))]
7343 "TARGET_VFP_FP16INST"
7346 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7353 return \"vsel%d1.f16\\t%0, %3, %4\";
7358 return \"vsel%D1.f16\\t%0, %4, %3\";
7364 [(set_attr "conds" "use")
7365 (set_attr "type" "fcsel")]
7368 (define_insn_and_split "*movsicc_insn"
7369 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7371 (match_operator 3 "arm_comparison_operator"
7372 [(match_operand 4 "cc_register" "") (const_int 0)])
7373 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7374 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7385 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7386 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7387 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7388 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7389 "&& reload_completed"
7392 enum rtx_code rev_code;
7396 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7398 gen_rtx_SET (operands[0], operands[1])));
7400 rev_code = GET_CODE (operands[3]);
7401 mode = GET_MODE (operands[4]);
7402 if (mode == CCFPmode || mode == CCFPEmode)
7403 rev_code = reverse_condition_maybe_unordered (rev_code);
7405 rev_code = reverse_condition (rev_code);
7407 rev_cond = gen_rtx_fmt_ee (rev_code,
7411 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7413 gen_rtx_SET (operands[0], operands[2])));
7416 [(set_attr "length" "4,4,4,4,8,8,8,8")
7417 (set_attr "conds" "use")
7418 (set_attr_alternative "type"
7419 [(if_then_else (match_operand 2 "const_int_operand" "")
7420 (const_string "mov_imm")
7421 (const_string "mov_reg"))
7422 (const_string "mvn_imm")
7423 (if_then_else (match_operand 1 "const_int_operand" "")
7424 (const_string "mov_imm")
7425 (const_string "mov_reg"))
7426 (const_string "mvn_imm")
7427 (const_string "multiple")
7428 (const_string "multiple")
7429 (const_string "multiple")
7430 (const_string "multiple")])]
7433 (define_insn "*movsfcc_soft_insn"
7434 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7435 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7436 [(match_operand 4 "cc_register" "") (const_int 0)])
7437 (match_operand:SF 1 "s_register_operand" "0,r")
7438 (match_operand:SF 2 "s_register_operand" "r,0")))]
7439 "TARGET_ARM && TARGET_SOFT_FLOAT"
7443 [(set_attr "conds" "use")
7444 (set_attr "type" "mov_reg")]
7448 ;; Jump and linkage insns
7450 (define_expand "jump"
7452 (label_ref (match_operand 0 "" "")))]
7457 (define_insn "*arm_jump"
7459 (label_ref (match_operand 0 "" "")))]
7463 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7465 arm_ccfsm_state += 2;
7468 return \"b%?\\t%l0\";
7471 [(set_attr "predicable" "yes")
7472 (set (attr "length")
7474 (and (match_test "TARGET_THUMB2")
7475 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7476 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7479 (set_attr "type" "branch")]
7482 (define_expand "call"
7483 [(parallel [(call (match_operand 0 "memory_operand")
7484 (match_operand 1 "general_operand"))
7485 (use (match_operand 2 "" ""))
7486 (clobber (reg:SI LR_REGNUM))])]
7491 tree addr = MEM_EXPR (operands[0]);
7493 /* In an untyped call, we can get NULL for operand 2. */
7494 if (operands[2] == NULL_RTX)
7495 operands[2] = const0_rtx;
7497 /* Decide if we should generate indirect calls by loading the
7498 32-bit address of the callee into a register before performing the
7500 callee = XEXP (operands[0], 0);
7501 if (GET_CODE (callee) == SYMBOL_REF
7502 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7504 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7506 if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[0], 0)))
7507 /* Indirect call: set r9 with FDPIC value of callee. */
7508 XEXP (operands[0], 0)
7509 = arm_load_function_descriptor (XEXP (operands[0], 0));
7511 if (detect_cmse_nonsecure_call (addr))
7513 pat = gen_nonsecure_call_internal (operands[0], operands[1],
7515 emit_call_insn (pat);
7519 pat = gen_call_internal (operands[0], operands[1], operands[2]);
7520 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7523 /* Restore FDPIC register (r9) after call. */
7526 rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
7527 rtx initial_fdpic_reg
7528 = get_hard_reg_initial_val (Pmode, FDPIC_REGNUM);
7530 emit_insn (gen_restore_pic_register_after_call (fdpic_reg,
7531 initial_fdpic_reg));
7538 (define_insn "restore_pic_register_after_call"
7539 [(set (match_operand:SI 0 "s_register_operand" "+r,r")
7540 (unspec:SI [(match_dup 0)
7541 (match_operand:SI 1 "nonimmediate_operand" "r,m")]
7542 UNSPEC_PIC_RESTORE))]
7549 (define_expand "call_internal"
7550 [(parallel [(call (match_operand 0 "memory_operand")
7551 (match_operand 1 "general_operand"))
7552 (use (match_operand 2 "" ""))
7553 (clobber (reg:SI LR_REGNUM))])])
7555 (define_expand "nonsecure_call_internal"
7556 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand")]
7557 UNSPEC_NONSECURE_MEM)
7558 (match_operand 1 "general_operand"))
7559 (use (match_operand 2 "" ""))
7560 (clobber (reg:SI LR_REGNUM))])]
7565 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
7566 gen_rtx_REG (SImode, R4_REGNUM),
7569 operands[0] = replace_equiv_address (operands[0], tmp);
7572 (define_insn "*call_reg_armv5"
7573 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7574 (match_operand 1 "" ""))
7575 (use (match_operand 2 "" ""))
7576 (clobber (reg:SI LR_REGNUM))]
7577 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
7579 [(set_attr "type" "call")]
7582 (define_insn "*call_reg_arm"
7583 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7584 (match_operand 1 "" ""))
7585 (use (match_operand 2 "" ""))
7586 (clobber (reg:SI LR_REGNUM))]
7587 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
7589 return output_call (operands);
7591 ;; length is worst case, normally it is only two
7592 [(set_attr "length" "12")
7593 (set_attr "type" "call")]
7597 (define_expand "call_value"
7598 [(parallel [(set (match_operand 0 "" "")
7599 (call (match_operand 1 "memory_operand")
7600 (match_operand 2 "general_operand")))
7601 (use (match_operand 3 "" ""))
7602 (clobber (reg:SI LR_REGNUM))])]
7607 tree addr = MEM_EXPR (operands[1]);
7609 /* In an untyped call, we can get NULL for operand 2. */
7610 if (operands[3] == 0)
7611 operands[3] = const0_rtx;
7613 /* Decide if we should generate indirect calls by loading the
7614 32-bit address of the callee into a register before performing the
7616 callee = XEXP (operands[1], 0);
7617 if (GET_CODE (callee) == SYMBOL_REF
7618 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7620 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7622 if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[1], 0)))
7623 /* Indirect call: set r9 with FDPIC value of callee. */
7624 XEXP (operands[1], 0)
7625 = arm_load_function_descriptor (XEXP (operands[1], 0));
7627 if (detect_cmse_nonsecure_call (addr))
7629 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
7630 operands[2], operands[3]);
7631 emit_call_insn (pat);
7635 pat = gen_call_value_internal (operands[0], operands[1],
7636 operands[2], operands[3]);
7637 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7640 /* Restore FDPIC register (r9) after call. */
7643 rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
7644 rtx initial_fdpic_reg
7645 = get_hard_reg_initial_val (Pmode, FDPIC_REGNUM);
7647 emit_insn (gen_restore_pic_register_after_call (fdpic_reg,
7648 initial_fdpic_reg));
7655 (define_expand "call_value_internal"
7656 [(parallel [(set (match_operand 0 "" "")
7657 (call (match_operand 1 "memory_operand")
7658 (match_operand 2 "general_operand")))
7659 (use (match_operand 3 "" ""))
7660 (clobber (reg:SI LR_REGNUM))])])
7662 (define_expand "nonsecure_call_value_internal"
7663 [(parallel [(set (match_operand 0 "" "")
7664 (call (unspec:SI [(match_operand 1 "memory_operand")]
7665 UNSPEC_NONSECURE_MEM)
7666 (match_operand 2 "general_operand")))
7667 (use (match_operand 3 "" ""))
7668 (clobber (reg:SI LR_REGNUM))])]
7673 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
7674 gen_rtx_REG (SImode, R4_REGNUM),
7677 operands[1] = replace_equiv_address (operands[1], tmp);
7680 (define_insn "*call_value_reg_armv5"
7681 [(set (match_operand 0 "" "")
7682 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7683 (match_operand 2 "" "")))
7684 (use (match_operand 3 "" ""))
7685 (clobber (reg:SI LR_REGNUM))]
7686 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
7688 [(set_attr "type" "call")]
7691 (define_insn "*call_value_reg_arm"
7692 [(set (match_operand 0 "" "")
7693 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7694 (match_operand 2 "" "")))
7695 (use (match_operand 3 "" ""))
7696 (clobber (reg:SI LR_REGNUM))]
7697 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
7699 return output_call (&operands[1]);
7701 [(set_attr "length" "12")
7702 (set_attr "type" "call")]
7705 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7706 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7708 (define_insn "*call_symbol"
7709 [(call (mem:SI (match_operand:SI 0 "" ""))
7710 (match_operand 1 "" ""))
7711 (use (match_operand 2 "" ""))
7712 (clobber (reg:SI LR_REGNUM))]
7714 && !SIBLING_CALL_P (insn)
7715 && (GET_CODE (operands[0]) == SYMBOL_REF)
7716 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7719 rtx op = operands[0];
7721 /* Switch mode now when possible. */
7722 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7723 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7724 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7726 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7728 [(set_attr "type" "call")]
7731 (define_insn "*call_value_symbol"
7732 [(set (match_operand 0 "" "")
7733 (call (mem:SI (match_operand:SI 1 "" ""))
7734 (match_operand:SI 2 "" "")))
7735 (use (match_operand 3 "" ""))
7736 (clobber (reg:SI LR_REGNUM))]
7738 && !SIBLING_CALL_P (insn)
7739 && (GET_CODE (operands[1]) == SYMBOL_REF)
7740 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7743 rtx op = operands[1];
7745 /* Switch mode now when possible. */
7746 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7747 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7748 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
7750 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7752 [(set_attr "type" "call")]
7755 (define_expand "sibcall_internal"
7756 [(parallel [(call (match_operand 0 "memory_operand")
7757 (match_operand 1 "general_operand"))
7759 (use (match_operand 2 "" ""))])])
7761 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7762 (define_expand "sibcall"
7763 [(parallel [(call (match_operand 0 "memory_operand")
7764 (match_operand 1 "general_operand"))
7766 (use (match_operand 2 "" ""))])]
7772 if ((!REG_P (XEXP (operands[0], 0))
7773 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7774 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7775 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7776 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7778 if (operands[2] == NULL_RTX)
7779 operands[2] = const0_rtx;
7781 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7782 arm_emit_call_insn (pat, operands[0], true);
7787 (define_expand "sibcall_value_internal"
7788 [(parallel [(set (match_operand 0 "" "")
7789 (call (match_operand 1 "memory_operand")
7790 (match_operand 2 "general_operand")))
7792 (use (match_operand 3 "" ""))])])
7794 (define_expand "sibcall_value"
7795 [(parallel [(set (match_operand 0 "" "")
7796 (call (match_operand 1 "memory_operand")
7797 (match_operand 2 "general_operand")))
7799 (use (match_operand 3 "" ""))])]
7805 if ((!REG_P (XEXP (operands[1], 0))
7806 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7807 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7808 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7809 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7811 if (operands[3] == NULL_RTX)
7812 operands[3] = const0_rtx;
7814 pat = gen_sibcall_value_internal (operands[0], operands[1],
7815 operands[2], operands[3]);
7816 arm_emit_call_insn (pat, operands[1], true);
7821 (define_insn "*sibcall_insn"
7822 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7823 (match_operand 1 "" ""))
7825 (use (match_operand 2 "" ""))]
7826 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7828 if (which_alternative == 1)
7829 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7832 if (arm_arch5t || arm_arch4t)
7833 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7835 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7838 [(set_attr "type" "call")]
7841 (define_insn "*sibcall_value_insn"
7842 [(set (match_operand 0 "" "")
7843 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7844 (match_operand 2 "" "")))
7846 (use (match_operand 3 "" ""))]
7847 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7849 if (which_alternative == 1)
7850 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7853 if (arm_arch5t || arm_arch4t)
7854 return \"bx%?\\t%1\";
7856 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7859 [(set_attr "type" "call")]
7862 (define_expand "<return_str>return"
7864 "(TARGET_ARM || (TARGET_THUMB2
7865 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7866 && !IS_STACKALIGN (arm_current_func_type ())))
7867 <return_cond_false>"
7872 thumb2_expand_return (<return_simple_p>);
7879 ;; Often the return insn will be the same as loading from memory, so set attr
7880 (define_insn "*arm_return"
7882 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7885 if (arm_ccfsm_state == 2)
7887 arm_ccfsm_state += 2;
7890 return output_return_instruction (const_true_rtx, true, false, false);
7892 [(set_attr "type" "load_4")
7893 (set_attr "length" "12")
7894 (set_attr "predicable" "yes")]
7897 (define_insn "*cond_<return_str>return"
7899 (if_then_else (match_operator 0 "arm_comparison_operator"
7900 [(match_operand 1 "cc_register" "") (const_int 0)])
7903 "TARGET_ARM <return_cond_true>"
7906 if (arm_ccfsm_state == 2)
7908 arm_ccfsm_state += 2;
7911 return output_return_instruction (operands[0], true, false,
7914 [(set_attr "conds" "use")
7915 (set_attr "length" "12")
7916 (set_attr "type" "load_4")]
7919 (define_insn "*cond_<return_str>return_inverted"
7921 (if_then_else (match_operator 0 "arm_comparison_operator"
7922 [(match_operand 1 "cc_register" "") (const_int 0)])
7925 "TARGET_ARM <return_cond_true>"
7928 if (arm_ccfsm_state == 2)
7930 arm_ccfsm_state += 2;
7933 return output_return_instruction (operands[0], true, true,
7936 [(set_attr "conds" "use")
7937 (set_attr "length" "12")
7938 (set_attr "type" "load_4")]
7941 (define_insn "*arm_simple_return"
7946 if (arm_ccfsm_state == 2)
7948 arm_ccfsm_state += 2;
7951 return output_return_instruction (const_true_rtx, true, false, true);
7953 [(set_attr "type" "branch")
7954 (set_attr "length" "4")
7955 (set_attr "predicable" "yes")]
7958 ;; Generate a sequence of instructions to determine if the processor is
7959 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7962 (define_expand "return_addr_mask"
7964 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7966 (set (match_operand:SI 0 "s_register_operand")
7967 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7969 (const_int 67108860)))] ; 0x03fffffc
7972 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7975 (define_insn "*check_arch2"
7976 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7977 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7980 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
7981 [(set_attr "length" "8")
7982 (set_attr "conds" "set")
7983 (set_attr "type" "multiple")]
7986 ;; Call subroutine returning any type.
7988 (define_expand "untyped_call"
7989 [(parallel [(call (match_operand 0 "" "")
7991 (match_operand 1 "" "")
7992 (match_operand 2 "" "")])]
7993 "TARGET_EITHER && !TARGET_FDPIC"
7997 rtx par = gen_rtx_PARALLEL (VOIDmode,
7998 rtvec_alloc (XVECLEN (operands[2], 0)));
7999 rtx addr = gen_reg_rtx (Pmode);
8003 emit_move_insn (addr, XEXP (operands[1], 0));
8004 mem = change_address (operands[1], BLKmode, addr);
8006 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8008 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8010 /* Default code only uses r0 as a return value, but we could
8011 be using anything up to 4 registers. */
8012 if (REGNO (src) == R0_REGNUM)
8013 src = gen_rtx_REG (TImode, R0_REGNUM);
8015 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8017 size += GET_MODE_SIZE (GET_MODE (src));
8020 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8024 for (i = 0; i < XVECLEN (par, 0); i++)
8026 HOST_WIDE_INT offset = 0;
8027 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8030 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8032 mem = change_address (mem, GET_MODE (reg), NULL);
8033 if (REGNO (reg) == R0_REGNUM)
8035 /* On thumb we have to use a write-back instruction. */
8036 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8037 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8038 size = TARGET_ARM ? 16 : 0;
8042 emit_move_insn (mem, reg);
8043 size = GET_MODE_SIZE (GET_MODE (reg));
8047 /* The optimizer does not know that the call sets the function value
8048 registers we stored in the result block. We avoid problems by
8049 claiming that all hard registers are used and clobbered at this
8051 emit_insn (gen_blockage ());
8057 (define_expand "untyped_return"
8058 [(match_operand:BLK 0 "memory_operand")
8059 (match_operand 1 "" "")]
8060 "TARGET_EITHER && !TARGET_FDPIC"
8064 rtx addr = gen_reg_rtx (Pmode);
8068 emit_move_insn (addr, XEXP (operands[0], 0));
8069 mem = change_address (operands[0], BLKmode, addr);
8071 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8073 HOST_WIDE_INT offset = 0;
8074 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8077 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8079 mem = change_address (mem, GET_MODE (reg), NULL);
8080 if (REGNO (reg) == R0_REGNUM)
8082 /* On thumb we have to use a write-back instruction. */
8083 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8084 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8085 size = TARGET_ARM ? 16 : 0;
8089 emit_move_insn (reg, mem);
8090 size = GET_MODE_SIZE (GET_MODE (reg));
8094 /* Emit USE insns before the return. */
8095 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8096 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8098 /* Construct the return. */
8099 expand_naked_return ();
8105 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8106 ;; all of memory. This blocks insns from being moved across this point.
8108 (define_insn "blockage"
8109 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8112 [(set_attr "length" "0")
8113 (set_attr "type" "block")]
8116 ;; Since we hard code r0 here use the 'o' constraint to prevent
8117 ;; provoking undefined behaviour in the hardware with putting out
8118 ;; auto-increment operations with potentially r0 as the base register.
8119 (define_insn "probe_stack"
8120 [(set (match_operand:SI 0 "memory_operand" "=o")
8121 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8124 [(set_attr "type" "store_4")
8125 (set_attr "predicable" "yes")]
8128 (define_insn "probe_stack_range"
8129 [(set (match_operand:SI 0 "register_operand" "=r")
8130 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8131 (match_operand:SI 2 "register_operand" "r")]
8132 VUNSPEC_PROBE_STACK_RANGE))]
8135 return output_probe_stack_range (operands[0], operands[2]);
8137 [(set_attr "type" "multiple")
8138 (set_attr "conds" "clob")]
8141 ;; Named patterns for stack smashing protection.
8142 (define_expand "stack_protect_combined_set"
8144 [(set (match_operand:SI 0 "memory_operand")
8145 (unspec:SI [(match_operand:SI 1 "guard_operand")]
8147 (clobber (match_scratch:SI 2 ""))
8148 (clobber (match_scratch:SI 3 ""))])]
8153 ;; Use a separate insn from the above expand to be able to have the mem outside
8154 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8155 ;; try to reload the guard since we need to control how PIC access is done in
8156 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8157 ;; legitimize_pic_address ()).
8158 (define_insn_and_split "*stack_protect_combined_set_insn"
8159 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8160 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8162 (clobber (match_scratch:SI 2 "=&l,&r"))
8163 (clobber (match_scratch:SI 3 "=&l,&r"))]
8167 [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))]
8169 (clobber (match_dup 2))])]
8177 pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
8179 pic_reg = operands[3];
8181 /* Forces recomputing of GOT base now. */
8182 legitimize_pic_address (operands[1], SImode, operands[2], pic_reg,
8183 true /*compute_now*/);
8187 if (address_operand (operands[1], SImode))
8188 operands[2] = operands[1];
8191 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8192 emit_move_insn (operands[2], mem);
8196 [(set_attr "arch" "t1,32")]
8199 ;; DO NOT SPLIT THIS INSN. It's important for security reasons that the
8200 ;; canary value does not live beyond the life of this sequence.
8201 (define_insn "*stack_protect_set_insn"
8202 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8203 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))]
8205 (clobber (match_dup 1))]
8208 ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1, #0
8209 ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1, #0"
8210 [(set_attr "length" "8,12")
8211 (set_attr "conds" "clob,nocond")
8212 (set_attr "type" "multiple")
8213 (set_attr "arch" "t1,32")]
8216 (define_expand "stack_protect_combined_test"
8220 (eq (match_operand:SI 0 "memory_operand")
8221 (unspec:SI [(match_operand:SI 1 "guard_operand")]
8223 (label_ref (match_operand 2))
8225 (clobber (match_scratch:SI 3 ""))
8226 (clobber (match_scratch:SI 4 ""))
8227 (clobber (reg:CC CC_REGNUM))])]
8232 ;; Use a separate insn from the above expand to be able to have the mem outside
8233 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8234 ;; try to reload the guard since we need to control how PIC access is done in
8235 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8236 ;; legitimize_pic_address ()).
8237 (define_insn_and_split "*stack_protect_combined_test_insn"
8240 (eq (match_operand:SI 0 "memory_operand" "m,m")
8241 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8243 (label_ref (match_operand 2))
8245 (clobber (match_scratch:SI 3 "=&l,&r"))
8246 (clobber (match_scratch:SI 4 "=&l,&r"))
8247 (clobber (reg:CC CC_REGNUM))]
8260 pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
8262 pic_reg = operands[4];
8264 /* Forces recomputing of GOT base now. */
8265 legitimize_pic_address (operands[1], SImode, operands[3], pic_reg,
8266 true /*compute_now*/);
8270 if (address_operand (operands[1], SImode))
8271 operands[3] = operands[1];
8274 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8275 emit_move_insn (operands[3], mem);
8280 emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0],
8282 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
8283 eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx);
8284 emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg));
8288 emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0],
8290 eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
8291 emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx,
8296 [(set_attr "arch" "t1,32")]
8299 (define_insn "arm_stack_protect_test_insn"
8300 [(set (reg:CC_Z CC_REGNUM)
8301 (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m")
8302 (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))]
8305 (clobber (match_operand:SI 0 "register_operand" "=&l,&r"))
8306 (clobber (match_dup 2))]
8308 "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0"
8309 [(set_attr "length" "8,12")
8310 (set_attr "conds" "set")
8311 (set_attr "type" "multiple")
8312 (set_attr "arch" "t,32")]
8315 (define_expand "casesi"
8316 [(match_operand:SI 0 "s_register_operand") ; index to jump on
8317 (match_operand:SI 1 "const_int_operand") ; lower bound
8318 (match_operand:SI 2 "const_int_operand") ; total range
8319 (match_operand:SI 3 "" "") ; table label
8320 (match_operand:SI 4 "" "")] ; Out of range label
8321 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8324 enum insn_code code;
8325 if (operands[1] != const0_rtx)
8327 rtx reg = gen_reg_rtx (SImode);
8329 emit_insn (gen_addsi3 (reg, operands[0],
8330 gen_int_mode (-INTVAL (operands[1]),
8336 code = CODE_FOR_arm_casesi_internal;
8337 else if (TARGET_THUMB1)
8338 code = CODE_FOR_thumb1_casesi_internal_pic;
8340 code = CODE_FOR_thumb2_casesi_internal_pic;
8342 code = CODE_FOR_thumb2_casesi_internal;
8344 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8345 operands[2] = force_reg (SImode, operands[2]);
8347 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8348 operands[3], operands[4]));
8353 ;; The USE in this pattern is needed to tell flow analysis that this is
8354 ;; a CASESI insn. It has no other purpose.
8355 (define_expand "arm_casesi_internal"
8356 [(parallel [(set (pc)
8358 (leu (match_operand:SI 0 "s_register_operand")
8359 (match_operand:SI 1 "arm_rhs_operand"))
8361 (label_ref:SI (match_operand 3 ""))))
8362 (clobber (reg:CC CC_REGNUM))
8363 (use (label_ref:SI (match_operand 2 "")))])]
8366 operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
8367 operands[4] = gen_rtx_PLUS (SImode, operands[4],
8368 gen_rtx_LABEL_REF (SImode, operands[2]));
8369 operands[4] = gen_rtx_MEM (SImode, operands[4]);
8370 MEM_READONLY_P (operands[4]) = 1;
8371 MEM_NOTRAP_P (operands[4]) = 1;
8374 (define_insn "*arm_casesi_internal"
8375 [(parallel [(set (pc)
8377 (leu (match_operand:SI 0 "s_register_operand" "r")
8378 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8379 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8380 (label_ref:SI (match_operand 2 "" ""))))
8381 (label_ref:SI (match_operand 3 "" ""))))
8382 (clobber (reg:CC CC_REGNUM))
8383 (use (label_ref:SI (match_dup 2)))])]
8387 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8388 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8390 [(set_attr "conds" "clob")
8391 (set_attr "length" "12")
8392 (set_attr "type" "multiple")]
8395 (define_expand "indirect_jump"
8397 (match_operand:SI 0 "s_register_operand"))]
8400 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8401 address and use bx. */
8405 tmp = gen_reg_rtx (SImode);
8406 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8412 ;; NB Never uses BX.
8413 (define_insn "*arm_indirect_jump"
8415 (match_operand:SI 0 "s_register_operand" "r"))]
8417 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8418 [(set_attr "predicable" "yes")
8419 (set_attr "type" "branch")]
8422 (define_insn "*load_indirect_jump"
8424 (match_operand:SI 0 "memory_operand" "m"))]
8426 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8427 [(set_attr "type" "load_4")
8428 (set_attr "pool_range" "4096")
8429 (set_attr "neg_pool_range" "4084")
8430 (set_attr "predicable" "yes")]
8440 [(set (attr "length")
8441 (if_then_else (eq_attr "is_thumb" "yes")
8444 (set_attr "type" "mov_reg")]
8448 [(trap_if (const_int 1) (const_int 0))]
8452 return \".inst\\t0xe7f000f0\";
8454 return \".inst\\t0xdeff\";
8456 [(set (attr "length")
8457 (if_then_else (eq_attr "is_thumb" "yes")
8460 (set_attr "type" "trap")
8461 (set_attr "conds" "unconditional")]
8465 ;; Patterns to allow combination of arithmetic, cond code and shifts
8467 (define_insn "*<arith_shift_insn>_multsi"
8468 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8470 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8471 (match_operand:SI 3 "power_of_two_operand" ""))
8472 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8474 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8475 [(set_attr "predicable" "yes")
8476 (set_attr "shift" "2")
8477 (set_attr "arch" "a,t2")
8478 (set_attr "type" "alu_shift_imm")])
8480 (define_insn "*<arith_shift_insn>_shiftsi"
8481 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8483 (match_operator:SI 2 "shift_nomul_operator"
8484 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8485 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8486 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8487 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8488 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8489 [(set_attr "predicable" "yes")
8490 (set_attr "shift" "3")
8491 (set_attr "arch" "a,t2,a")
8492 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8495 [(set (match_operand:SI 0 "s_register_operand" "")
8496 (match_operator:SI 1 "shiftable_operator"
8497 [(match_operator:SI 2 "shiftable_operator"
8498 [(match_operator:SI 3 "shift_operator"
8499 [(match_operand:SI 4 "s_register_operand" "")
8500 (match_operand:SI 5 "reg_or_int_operand" "")])
8501 (match_operand:SI 6 "s_register_operand" "")])
8502 (match_operand:SI 7 "arm_rhs_operand" "")]))
8503 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8506 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8509 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8512 (define_insn "*arith_shiftsi_compare0"
8513 [(set (reg:CC_NOOV CC_REGNUM)
8515 (match_operator:SI 1 "shiftable_operator"
8516 [(match_operator:SI 3 "shift_operator"
8517 [(match_operand:SI 4 "s_register_operand" "r,r")
8518 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8519 (match_operand:SI 2 "s_register_operand" "r,r")])
8521 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8522 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8525 "%i1s%?\\t%0, %2, %4%S3"
8526 [(set_attr "conds" "set")
8527 (set_attr "shift" "4")
8528 (set_attr "arch" "32,a")
8529 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8531 (define_insn "*arith_shiftsi_compare0_scratch"
8532 [(set (reg:CC_NOOV CC_REGNUM)
8534 (match_operator:SI 1 "shiftable_operator"
8535 [(match_operator:SI 3 "shift_operator"
8536 [(match_operand:SI 4 "s_register_operand" "r,r")
8537 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8538 (match_operand:SI 2 "s_register_operand" "r,r")])
8540 (clobber (match_scratch:SI 0 "=r,r"))]
8542 "%i1s%?\\t%0, %2, %4%S3"
8543 [(set_attr "conds" "set")
8544 (set_attr "shift" "4")
8545 (set_attr "arch" "32,a")
8546 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8548 (define_insn "*sub_shiftsi"
8549 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8550 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8551 (match_operator:SI 2 "shift_operator"
8552 [(match_operand:SI 3 "s_register_operand" "r,r")
8553 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8555 "sub%?\\t%0, %1, %3%S2"
8556 [(set_attr "predicable" "yes")
8557 (set_attr "predicable_short_it" "no")
8558 (set_attr "shift" "3")
8559 (set_attr "arch" "32,a")
8560 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8562 (define_insn "*sub_shiftsi_compare0"
8563 [(set (reg:CC_NOOV CC_REGNUM)
8565 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8566 (match_operator:SI 2 "shift_operator"
8567 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8568 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8570 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8571 (minus:SI (match_dup 1)
8572 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8574 "subs%?\\t%0, %1, %3%S2"
8575 [(set_attr "conds" "set")
8576 (set_attr "shift" "3")
8577 (set_attr "arch" "32,a,a")
8578 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8580 (define_insn "*sub_shiftsi_compare0_scratch"
8581 [(set (reg:CC_NOOV CC_REGNUM)
8583 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8584 (match_operator:SI 2 "shift_operator"
8585 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8586 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8588 (clobber (match_scratch:SI 0 "=r,r,r"))]
8590 "subs%?\\t%0, %1, %3%S2"
8591 [(set_attr "conds" "set")
8592 (set_attr "shift" "3")
8593 (set_attr "arch" "32,a,a")
8594 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8597 (define_insn_and_split "*and_scc"
8598 [(set (match_operand:SI 0 "s_register_operand" "=r")
8599 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8600 [(match_operand 2 "cc_register" "") (const_int 0)])
8601 (match_operand:SI 3 "s_register_operand" "r")))]
8603 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8604 "&& reload_completed"
8605 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8606 (cond_exec (match_dup 4) (set (match_dup 0)
8607 (and:SI (match_dup 3) (const_int 1))))]
8609 machine_mode mode = GET_MODE (operands[2]);
8610 enum rtx_code rc = GET_CODE (operands[1]);
8612 /* Note that operands[4] is the same as operands[1],
8613 but with VOIDmode as the result. */
8614 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8615 if (mode == CCFPmode || mode == CCFPEmode)
8616 rc = reverse_condition_maybe_unordered (rc);
8618 rc = reverse_condition (rc);
8619 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8621 [(set_attr "conds" "use")
8622 (set_attr "type" "multiple")
8623 (set_attr "length" "8")]
8626 (define_insn_and_split "*ior_scc"
8627 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8628 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8629 [(match_operand 2 "cc_register" "") (const_int 0)])
8630 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8635 "&& reload_completed
8636 && REGNO (operands [0]) != REGNO (operands[3])"
8637 ;; && which_alternative == 1
8638 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8639 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8640 (cond_exec (match_dup 4) (set (match_dup 0)
8641 (ior:SI (match_dup 3) (const_int 1))))]
8643 machine_mode mode = GET_MODE (operands[2]);
8644 enum rtx_code rc = GET_CODE (operands[1]);
8646 /* Note that operands[4] is the same as operands[1],
8647 but with VOIDmode as the result. */
8648 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8649 if (mode == CCFPmode || mode == CCFPEmode)
8650 rc = reverse_condition_maybe_unordered (rc);
8652 rc = reverse_condition (rc);
8653 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8655 [(set_attr "conds" "use")
8656 (set_attr "length" "4,8")
8657 (set_attr "type" "logic_imm,multiple")]
8660 ; A series of splitters for the compare_scc pattern below. Note that
8661 ; order is important.
8663 [(set (match_operand:SI 0 "s_register_operand" "")
8664 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8666 (clobber (reg:CC CC_REGNUM))]
8667 "TARGET_32BIT && reload_completed"
8668 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8671 [(set (match_operand:SI 0 "s_register_operand" "")
8672 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8674 (clobber (reg:CC CC_REGNUM))]
8675 "TARGET_32BIT && reload_completed"
8676 [(set (match_dup 0) (not:SI (match_dup 1)))
8677 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8680 [(set (match_operand:SI 0 "s_register_operand" "")
8681 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8683 (clobber (reg:CC CC_REGNUM))]
8684 "arm_arch5t && TARGET_32BIT"
8685 [(set (match_dup 0) (clz:SI (match_dup 1)))
8686 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8690 [(set (match_operand:SI 0 "s_register_operand" "")
8691 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8693 (clobber (reg:CC CC_REGNUM))]
8694 "TARGET_32BIT && reload_completed"
8696 [(set (reg:CC CC_REGNUM)
8697 (compare:CC (const_int 1) (match_dup 1)))
8699 (minus:SI (const_int 1) (match_dup 1)))])
8700 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8701 (set (match_dup 0) (const_int 0)))])
8704 [(set (match_operand:SI 0 "s_register_operand" "")
8705 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8706 (match_operand:SI 2 "const_int_operand" "")))
8707 (clobber (reg:CC CC_REGNUM))]
8708 "TARGET_32BIT && reload_completed"
8710 [(set (reg:CC CC_REGNUM)
8711 (compare:CC (match_dup 1) (match_dup 2)))
8712 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8713 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8714 (set (match_dup 0) (const_int 1)))]
8716 operands[3] = gen_int_mode (-INTVAL (operands[2]), SImode);
8720 [(set (match_operand:SI 0 "s_register_operand" "")
8721 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8722 (match_operand:SI 2 "arm_add_operand" "")))
8723 (clobber (reg:CC CC_REGNUM))]
8724 "TARGET_32BIT && reload_completed"
8726 [(set (reg:CC_NOOV CC_REGNUM)
8727 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8729 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8730 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8731 (set (match_dup 0) (const_int 1)))])
8733 (define_insn_and_split "*compare_scc"
8734 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8735 (match_operator:SI 1 "arm_comparison_operator"
8736 [(match_operand:SI 2 "s_register_operand" "r,r")
8737 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8738 (clobber (reg:CC CC_REGNUM))]
8741 "&& reload_completed"
8742 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8743 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8744 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8747 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8748 operands[2], operands[3]);
8749 enum rtx_code rc = GET_CODE (operands[1]);
8751 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8753 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8754 if (mode == CCFPmode || mode == CCFPEmode)
8755 rc = reverse_condition_maybe_unordered (rc);
8757 rc = reverse_condition (rc);
8758 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8760 [(set_attr "type" "multiple")]
8763 ;; Attempt to improve the sequence generated by the compare_scc splitters
8764 ;; not to use conditional execution.
8766 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
8770 [(set (reg:CC CC_REGNUM)
8771 (compare:CC (match_operand:SI 1 "register_operand" "")
8773 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8774 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8775 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8776 (set (match_dup 0) (const_int 1)))]
8777 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8778 [(set (match_dup 0) (clz:SI (match_dup 1)))
8779 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8782 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8786 [(set (reg:CC CC_REGNUM)
8787 (compare:CC (match_operand:SI 1 "register_operand" "")
8789 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8790 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8791 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8792 (set (match_dup 0) (const_int 1)))
8793 (match_scratch:SI 2 "r")]
8794 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8796 [(set (reg:CC CC_REGNUM)
8797 (compare:CC (const_int 0) (match_dup 1)))
8798 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8800 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8801 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8804 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
8805 ;; sub Rd, Reg1, reg2
8809 [(set (reg:CC CC_REGNUM)
8810 (compare:CC (match_operand:SI 1 "register_operand" "")
8811 (match_operand:SI 2 "arm_rhs_operand" "")))
8812 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8813 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8814 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8815 (set (match_dup 0) (const_int 1)))]
8816 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8817 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8818 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8819 (set (match_dup 0) (clz:SI (match_dup 0)))
8820 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8824 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
8825 ;; sub T1, Reg1, reg2
8829 [(set (reg:CC CC_REGNUM)
8830 (compare:CC (match_operand:SI 1 "register_operand" "")
8831 (match_operand:SI 2 "arm_rhs_operand" "")))
8832 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8833 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8834 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8835 (set (match_dup 0) (const_int 1)))
8836 (match_scratch:SI 3 "r")]
8837 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8838 [(set (match_dup 3) (match_dup 4))
8840 [(set (reg:CC CC_REGNUM)
8841 (compare:CC (const_int 0) (match_dup 3)))
8842 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8844 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8845 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8847 if (CONST_INT_P (operands[2]))
8848 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8850 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8853 (define_insn "*cond_move"
8854 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8855 (if_then_else:SI (match_operator 3 "equality_operator"
8856 [(match_operator 4 "arm_comparison_operator"
8857 [(match_operand 5 "cc_register" "") (const_int 0)])
8859 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8860 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8863 if (GET_CODE (operands[3]) == NE)
8865 if (which_alternative != 1)
8866 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8867 if (which_alternative != 0)
8868 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8871 if (which_alternative != 0)
8872 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8873 if (which_alternative != 1)
8874 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8877 [(set_attr "conds" "use")
8878 (set_attr_alternative "type"
8879 [(if_then_else (match_operand 2 "const_int_operand" "")
8880 (const_string "mov_imm")
8881 (const_string "mov_reg"))
8882 (if_then_else (match_operand 1 "const_int_operand" "")
8883 (const_string "mov_imm")
8884 (const_string "mov_reg"))
8885 (const_string "multiple")])
8886 (set_attr "length" "4,4,8")]
8889 (define_insn "*cond_arith"
8890 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8891 (match_operator:SI 5 "shiftable_operator"
8892 [(match_operator:SI 4 "arm_comparison_operator"
8893 [(match_operand:SI 2 "s_register_operand" "r,r")
8894 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8895 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8896 (clobber (reg:CC CC_REGNUM))]
8899 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8900 return \"%i5\\t%0, %1, %2, lsr #31\";
8902 output_asm_insn (\"cmp\\t%2, %3\", operands);
8903 if (GET_CODE (operands[5]) == AND)
8904 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8905 else if (GET_CODE (operands[5]) == MINUS)
8906 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8907 else if (which_alternative != 0)
8908 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8909 return \"%i5%d4\\t%0, %1, #1\";
8911 [(set_attr "conds" "clob")
8912 (set_attr "length" "12")
8913 (set_attr "type" "multiple")]
8916 (define_insn "*cond_sub"
8917 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8918 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8919 (match_operator:SI 4 "arm_comparison_operator"
8920 [(match_operand:SI 2 "s_register_operand" "r,r")
8921 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8922 (clobber (reg:CC CC_REGNUM))]
8925 output_asm_insn (\"cmp\\t%2, %3\", operands);
8926 if (which_alternative != 0)
8927 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8928 return \"sub%d4\\t%0, %1, #1\";
8930 [(set_attr "conds" "clob")
8931 (set_attr "length" "8,12")
8932 (set_attr "type" "multiple")]
8935 (define_insn "*cmp_ite0"
8936 [(set (match_operand 6 "dominant_cc_register" "")
8939 (match_operator 4 "arm_comparison_operator"
8940 [(match_operand:SI 0 "s_register_operand"
8941 "l,l,l,r,r,r,r,r,r")
8942 (match_operand:SI 1 "arm_add_operand"
8943 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8944 (match_operator:SI 5 "arm_comparison_operator"
8945 [(match_operand:SI 2 "s_register_operand"
8946 "l,r,r,l,l,r,r,r,r")
8947 (match_operand:SI 3 "arm_add_operand"
8948 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8954 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8956 {\"cmp%d5\\t%0, %1\",
8957 \"cmp%d4\\t%2, %3\"},
8958 {\"cmn%d5\\t%0, #%n1\",
8959 \"cmp%d4\\t%2, %3\"},
8960 {\"cmp%d5\\t%0, %1\",
8961 \"cmn%d4\\t%2, #%n3\"},
8962 {\"cmn%d5\\t%0, #%n1\",
8963 \"cmn%d4\\t%2, #%n3\"}
8965 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8970 \"cmn\\t%0, #%n1\"},
8971 {\"cmn\\t%2, #%n3\",
8973 {\"cmn\\t%2, #%n3\",
8976 static const char * const ite[2] =
8981 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
8982 CMP_CMP, CMN_CMP, CMP_CMP,
8983 CMN_CMP, CMP_CMN, CMN_CMN};
8985 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
8987 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
8988 if (TARGET_THUMB2) {
8989 output_asm_insn (ite[swap], operands);
8991 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
8994 [(set_attr "conds" "set")
8995 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
8996 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
8997 (set_attr "type" "multiple")
8998 (set_attr_alternative "length"
9004 (if_then_else (eq_attr "is_thumb" "no")
9007 (if_then_else (eq_attr "is_thumb" "no")
9010 (if_then_else (eq_attr "is_thumb" "no")
9013 (if_then_else (eq_attr "is_thumb" "no")
9018 (define_insn "*cmp_ite1"
9019 [(set (match_operand 6 "dominant_cc_register" "")
9022 (match_operator 4 "arm_comparison_operator"
9023 [(match_operand:SI 0 "s_register_operand"
9024 "l,l,l,r,r,r,r,r,r")
9025 (match_operand:SI 1 "arm_add_operand"
9026 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9027 (match_operator:SI 5 "arm_comparison_operator"
9028 [(match_operand:SI 2 "s_register_operand"
9029 "l,r,r,l,l,r,r,r,r")
9030 (match_operand:SI 3 "arm_add_operand"
9031 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9037 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9041 {\"cmn\\t%0, #%n1\",
9044 \"cmn\\t%2, #%n3\"},
9045 {\"cmn\\t%0, #%n1\",
9048 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9050 {\"cmp%d4\\t%2, %3\",
9051 \"cmp%D5\\t%0, %1\"},
9052 {\"cmp%d4\\t%2, %3\",
9053 \"cmn%D5\\t%0, #%n1\"},
9054 {\"cmn%d4\\t%2, #%n3\",
9055 \"cmp%D5\\t%0, %1\"},
9056 {\"cmn%d4\\t%2, #%n3\",
9057 \"cmn%D5\\t%0, #%n1\"}
9059 static const char * const ite[2] =
9064 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9065 CMP_CMP, CMN_CMP, CMP_CMP,
9066 CMN_CMP, CMP_CMN, CMN_CMN};
9068 comparison_dominates_p (GET_CODE (operands[5]),
9069 reverse_condition (GET_CODE (operands[4])));
9071 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9072 if (TARGET_THUMB2) {
9073 output_asm_insn (ite[swap], operands);
9075 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9078 [(set_attr "conds" "set")
9079 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9080 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9081 (set_attr_alternative "length"
9087 (if_then_else (eq_attr "is_thumb" "no")
9090 (if_then_else (eq_attr "is_thumb" "no")
9093 (if_then_else (eq_attr "is_thumb" "no")
9096 (if_then_else (eq_attr "is_thumb" "no")
9099 (set_attr "type" "multiple")]
9102 (define_insn "*cmp_and"
9103 [(set (match_operand 6 "dominant_cc_register" "")
9106 (match_operator 4 "arm_comparison_operator"
9107 [(match_operand:SI 0 "s_register_operand"
9108 "l,l,l,r,r,r,r,r,r,r")
9109 (match_operand:SI 1 "arm_add_operand"
9110 "lPy,lPy,lPy,rI,L,r,rI,L,rI,L")])
9111 (match_operator:SI 5 "arm_comparison_operator"
9112 [(match_operand:SI 2 "s_register_operand"
9113 "l,r,r,l,l,r,r,r,r,r")
9114 (match_operand:SI 3 "arm_add_operand"
9115 "lPy,rI,L,lPy,lPy,r,rI,rI,L,L")]))
9120 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9122 {\"cmp%d5\\t%0, %1\",
9123 \"cmp%d4\\t%2, %3\"},
9124 {\"cmn%d5\\t%0, #%n1\",
9125 \"cmp%d4\\t%2, %3\"},
9126 {\"cmp%d5\\t%0, %1\",
9127 \"cmn%d4\\t%2, #%n3\"},
9128 {\"cmn%d5\\t%0, #%n1\",
9129 \"cmn%d4\\t%2, #%n3\"}
9131 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9136 \"cmn\\t%0, #%n1\"},
9137 {\"cmn\\t%2, #%n3\",
9139 {\"cmn\\t%2, #%n3\",
9142 static const char *const ite[2] =
9147 static const int cmp_idx[] = {CMP_CMP, CMP_CMP, CMP_CMN,
9148 CMP_CMP, CMN_CMP, CMP_CMP,
9149 CMP_CMP, CMN_CMP, CMP_CMN,
9152 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9154 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9155 if (TARGET_THUMB2) {
9156 output_asm_insn (ite[swap], operands);
9158 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9161 [(set_attr "conds" "set")
9162 (set_attr "predicable" "no")
9163 (set_attr "arch" "t2,t2,t2,t2,t2,t2,any,any,any,any")
9164 (set_attr "enabled_for_short_it" "yes,no,no,no,no,yes,no,no,no,no")
9165 (set_attr_alternative "length"
9172 (if_then_else (eq_attr "is_thumb" "no")
9175 (if_then_else (eq_attr "is_thumb" "no")
9178 (if_then_else (eq_attr "is_thumb" "no")
9181 (if_then_else (eq_attr "is_thumb" "no")
9184 (set_attr "type" "multiple")]
9187 (define_insn "*cmp_ior"
9188 [(set (match_operand 6 "dominant_cc_register" "")
9191 (match_operator 4 "arm_comparison_operator"
9192 [(match_operand:SI 0 "s_register_operand"
9193 "l,l,l,r,r,r,r,r,r,r")
9194 (match_operand:SI 1 "arm_add_operand"
9195 "lPy,lPy,lPy,rI,L,r,rI,L,rI,L")])
9196 (match_operator:SI 5 "arm_comparison_operator"
9197 [(match_operand:SI 2 "s_register_operand"
9198 "l,r,r,l,l,r,r,r,r,r")
9199 (match_operand:SI 3 "arm_add_operand"
9200 "lPy,rI,L,lPy,lPy,r,rI,rI,L,L")]))
9205 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9209 {\"cmn\\t%0, #%n1\",
9212 \"cmn\\t%2, #%n3\"},
9213 {\"cmn\\t%0, #%n1\",
9216 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9218 {\"cmp%D4\\t%2, %3\",
9219 \"cmp%D5\\t%0, %1\"},
9220 {\"cmp%D4\\t%2, %3\",
9221 \"cmn%D5\\t%0, #%n1\"},
9222 {\"cmn%D4\\t%2, #%n3\",
9223 \"cmp%D5\\t%0, %1\"},
9224 {\"cmn%D4\\t%2, #%n3\",
9225 \"cmn%D5\\t%0, #%n1\"}
9227 static const char *const ite[2] =
9232 static const int cmp_idx[] = {CMP_CMP, CMP_CMP, CMP_CMN,
9233 CMP_CMP, CMN_CMP, CMP_CMP,
9234 CMP_CMP, CMN_CMP, CMP_CMN,
9237 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9239 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9240 if (TARGET_THUMB2) {
9241 output_asm_insn (ite[swap], operands);
9243 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9247 [(set_attr "conds" "set")
9248 (set_attr "arch" "t2,t2,t2,t2,t2,t2,any,any,any,any")
9249 (set_attr "enabled_for_short_it" "yes,no,no,no,no,yes,no,no,no,no")
9250 (set_attr_alternative "length"
9257 (if_then_else (eq_attr "is_thumb" "no")
9260 (if_then_else (eq_attr "is_thumb" "no")
9263 (if_then_else (eq_attr "is_thumb" "no")
9266 (if_then_else (eq_attr "is_thumb" "no")
9269 (set_attr "type" "multiple")]
9272 (define_insn_and_split "*ior_scc_scc"
9273 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9274 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9275 [(match_operand:SI 1 "s_register_operand" "l,r")
9276 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9277 (match_operator:SI 6 "arm_comparison_operator"
9278 [(match_operand:SI 4 "s_register_operand" "l,r")
9279 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9280 (clobber (reg:CC CC_REGNUM))]
9282 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9285 "TARGET_32BIT && reload_completed"
9289 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9290 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9292 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9294 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9297 [(set_attr "conds" "clob")
9298 (set_attr "enabled_for_short_it" "yes,no")
9299 (set_attr "length" "16")
9300 (set_attr "type" "multiple")]
9303 ; If the above pattern is followed by a CMP insn, then the compare is
9304 ; redundant, since we can rework the conditional instruction that follows.
9305 (define_insn_and_split "*ior_scc_scc_cmp"
9306 [(set (match_operand 0 "dominant_cc_register" "")
9307 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9308 [(match_operand:SI 1 "s_register_operand" "l,r")
9309 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9310 (match_operator:SI 6 "arm_comparison_operator"
9311 [(match_operand:SI 4 "s_register_operand" "l,r")
9312 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9314 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9315 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9316 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9319 "TARGET_32BIT && reload_completed"
9323 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9324 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9326 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9328 [(set_attr "conds" "set")
9329 (set_attr "enabled_for_short_it" "yes,no")
9330 (set_attr "length" "16")
9331 (set_attr "type" "multiple")]
9334 (define_insn_and_split "*and_scc_scc"
9335 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9336 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9337 [(match_operand:SI 1 "s_register_operand" "l,r")
9338 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9339 (match_operator:SI 6 "arm_comparison_operator"
9340 [(match_operand:SI 4 "s_register_operand" "l,r")
9341 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9342 (clobber (reg:CC CC_REGNUM))]
9344 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9347 "TARGET_32BIT && reload_completed
9348 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9353 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9354 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9356 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9358 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9361 [(set_attr "conds" "clob")
9362 (set_attr "enabled_for_short_it" "yes,no")
9363 (set_attr "length" "16")
9364 (set_attr "type" "multiple")]
9367 ; If the above pattern is followed by a CMP insn, then the compare is
9368 ; redundant, since we can rework the conditional instruction that follows.
9369 (define_insn_and_split "*and_scc_scc_cmp"
9370 [(set (match_operand 0 "dominant_cc_register" "")
9371 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9372 [(match_operand:SI 1 "s_register_operand" "l,r")
9373 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9374 (match_operator:SI 6 "arm_comparison_operator"
9375 [(match_operand:SI 4 "s_register_operand" "l,r")
9376 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9378 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9379 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9380 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9383 "TARGET_32BIT && reload_completed"
9387 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9388 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9390 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9392 [(set_attr "conds" "set")
9393 (set_attr "enabled_for_short_it" "yes,no")
9394 (set_attr "length" "16")
9395 (set_attr "type" "multiple")]
9398 ;; If there is no dominance in the comparison, then we can still save an
9399 ;; instruction in the AND case, since we can know that the second compare
9400 ;; need only zero the value if false (if true, then the value is already
9402 (define_insn_and_split "*and_scc_scc_nodom"
9403 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9404 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9405 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9406 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9407 (match_operator:SI 6 "arm_comparison_operator"
9408 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9409 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9410 (clobber (reg:CC CC_REGNUM))]
9412 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9415 "TARGET_32BIT && reload_completed"
9416 [(parallel [(set (match_dup 0)
9417 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9418 (clobber (reg:CC CC_REGNUM))])
9419 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9421 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9424 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9425 operands[4], operands[5]),
9427 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9429 [(set_attr "conds" "clob")
9430 (set_attr "length" "20")
9431 (set_attr "type" "multiple")]
9435 [(set (reg:CC_NOOV CC_REGNUM)
9436 (compare:CC_NOOV (ior:SI
9437 (and:SI (match_operand:SI 0 "s_register_operand" "")
9439 (match_operator:SI 1 "arm_comparison_operator"
9440 [(match_operand:SI 2 "s_register_operand" "")
9441 (match_operand:SI 3 "arm_add_operand" "")]))
9443 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9446 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9448 (set (reg:CC_NOOV CC_REGNUM)
9449 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9454 [(set (reg:CC_NOOV CC_REGNUM)
9455 (compare:CC_NOOV (ior:SI
9456 (match_operator:SI 1 "arm_comparison_operator"
9457 [(match_operand:SI 2 "s_register_operand" "")
9458 (match_operand:SI 3 "arm_add_operand" "")])
9459 (and:SI (match_operand:SI 0 "s_register_operand" "")
9462 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9465 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9467 (set (reg:CC_NOOV CC_REGNUM)
9468 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9471 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9473 (define_insn_and_split "*negscc"
9474 [(set (match_operand:SI 0 "s_register_operand" "=r")
9475 (neg:SI (match_operator 3 "arm_comparison_operator"
9476 [(match_operand:SI 1 "s_register_operand" "r")
9477 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9478 (clobber (reg:CC CC_REGNUM))]
9481 "&& reload_completed"
9484 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9486 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9488 /* Emit mov\\t%0, %1, asr #31 */
9489 emit_insn (gen_rtx_SET (operands[0],
9490 gen_rtx_ASHIFTRT (SImode,
9495 else if (GET_CODE (operands[3]) == NE)
9497 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9498 if (CONST_INT_P (operands[2]))
9499 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9500 gen_int_mode (-INTVAL (operands[2]),
9503 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9505 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9509 gen_rtx_SET (operands[0],
9515 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9516 emit_insn (gen_rtx_SET (cc_reg,
9517 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9518 enum rtx_code rc = GET_CODE (operands[3]);
9520 rc = reverse_condition (rc);
9521 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9526 gen_rtx_SET (operands[0], const0_rtx)));
9527 rc = GET_CODE (operands[3]);
9528 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9533 gen_rtx_SET (operands[0],
9539 [(set_attr "conds" "clob")
9540 (set_attr "length" "12")
9541 (set_attr "type" "multiple")]
9544 (define_insn_and_split "movcond_addsi"
9545 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9547 (match_operator 5 "comparison_operator"
9548 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9549 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9551 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9552 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9553 (clobber (reg:CC CC_REGNUM))]
9556 "&& reload_completed"
9557 [(set (reg:CC_NOOV CC_REGNUM)
9559 (plus:SI (match_dup 3)
9562 (set (match_dup 0) (match_dup 1))
9563 (cond_exec (match_dup 6)
9564 (set (match_dup 0) (match_dup 2)))]
9567 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9568 operands[3], operands[4]);
9569 enum rtx_code rc = GET_CODE (operands[5]);
9570 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9571 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9572 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9573 rc = reverse_condition (rc);
9575 std::swap (operands[1], operands[2]);
9577 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9580 [(set_attr "conds" "clob")
9581 (set_attr "enabled_for_short_it" "no,yes,yes")
9582 (set_attr "type" "multiple")]
9585 (define_insn "movcond"
9586 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9588 (match_operator 5 "arm_comparison_operator"
9589 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9590 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9591 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9592 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9593 (clobber (reg:CC CC_REGNUM))]
9596 if (GET_CODE (operands[5]) == LT
9597 && (operands[4] == const0_rtx))
9599 if (which_alternative != 1 && REG_P (operands[1]))
9601 if (operands[2] == const0_rtx)
9602 return \"and\\t%0, %1, %3, asr #31\";
9603 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9605 else if (which_alternative != 0 && REG_P (operands[2]))
9607 if (operands[1] == const0_rtx)
9608 return \"bic\\t%0, %2, %3, asr #31\";
9609 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9611 /* The only case that falls through to here is when both ops 1 & 2
9615 if (GET_CODE (operands[5]) == GE
9616 && (operands[4] == const0_rtx))
9618 if (which_alternative != 1 && REG_P (operands[1]))
9620 if (operands[2] == const0_rtx)
9621 return \"bic\\t%0, %1, %3, asr #31\";
9622 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9624 else if (which_alternative != 0 && REG_P (operands[2]))
9626 if (operands[1] == const0_rtx)
9627 return \"and\\t%0, %2, %3, asr #31\";
9628 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9630 /* The only case that falls through to here is when both ops 1 & 2
9633 if (CONST_INT_P (operands[4])
9634 && !const_ok_for_arm (INTVAL (operands[4])))
9635 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9637 output_asm_insn (\"cmp\\t%3, %4\", operands);
9638 if (which_alternative != 0)
9639 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9640 if (which_alternative != 1)
9641 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9644 [(set_attr "conds" "clob")
9645 (set_attr "length" "8,8,12")
9646 (set_attr "type" "multiple")]
9649 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9651 (define_insn "*ifcompare_plus_move"
9652 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9653 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9654 [(match_operand:SI 4 "s_register_operand" "r,r")
9655 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9657 (match_operand:SI 2 "s_register_operand" "r,r")
9658 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9659 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9660 (clobber (reg:CC CC_REGNUM))]
9663 [(set_attr "conds" "clob")
9664 (set_attr "length" "8,12")
9665 (set_attr "type" "multiple")]
9668 (define_insn "*if_plus_move"
9669 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9671 (match_operator 4 "arm_comparison_operator"
9672 [(match_operand 5 "cc_register" "") (const_int 0)])
9674 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9675 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9676 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9680 sub%d4\\t%0, %2, #%n3
9681 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9682 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9683 [(set_attr "conds" "use")
9684 (set_attr "length" "4,4,8,8")
9685 (set_attr_alternative "type"
9686 [(if_then_else (match_operand 3 "const_int_operand" "")
9687 (const_string "alu_imm" )
9688 (const_string "alu_sreg"))
9689 (const_string "alu_imm")
9690 (const_string "multiple")
9691 (const_string "multiple")])]
9694 (define_insn "*ifcompare_move_plus"
9695 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9696 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9697 [(match_operand:SI 4 "s_register_operand" "r,r")
9698 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9699 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9701 (match_operand:SI 2 "s_register_operand" "r,r")
9702 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9703 (clobber (reg:CC CC_REGNUM))]
9706 [(set_attr "conds" "clob")
9707 (set_attr "length" "8,12")
9708 (set_attr "type" "multiple")]
9711 (define_insn "*if_move_plus"
9712 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9714 (match_operator 4 "arm_comparison_operator"
9715 [(match_operand 5 "cc_register" "") (const_int 0)])
9716 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9718 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9719 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9723 sub%D4\\t%0, %2, #%n3
9724 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9725 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9726 [(set_attr "conds" "use")
9727 (set_attr "length" "4,4,8,8")
9728 (set_attr_alternative "type"
9729 [(if_then_else (match_operand 3 "const_int_operand" "")
9730 (const_string "alu_imm" )
9731 (const_string "alu_sreg"))
9732 (const_string "alu_imm")
9733 (const_string "multiple")
9734 (const_string "multiple")])]
9737 (define_insn "*ifcompare_arith_arith"
9738 [(set (match_operand:SI 0 "s_register_operand" "=r")
9739 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9740 [(match_operand:SI 5 "s_register_operand" "r")
9741 (match_operand:SI 6 "arm_add_operand" "rIL")])
9742 (match_operator:SI 8 "shiftable_operator"
9743 [(match_operand:SI 1 "s_register_operand" "r")
9744 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9745 (match_operator:SI 7 "shiftable_operator"
9746 [(match_operand:SI 3 "s_register_operand" "r")
9747 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9748 (clobber (reg:CC CC_REGNUM))]
9751 [(set_attr "conds" "clob")
9752 (set_attr "length" "12")
9753 (set_attr "type" "multiple")]
9756 (define_insn "*if_arith_arith"
9757 [(set (match_operand:SI 0 "s_register_operand" "=r")
9758 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9759 [(match_operand 8 "cc_register" "") (const_int 0)])
9760 (match_operator:SI 6 "shiftable_operator"
9761 [(match_operand:SI 1 "s_register_operand" "r")
9762 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9763 (match_operator:SI 7 "shiftable_operator"
9764 [(match_operand:SI 3 "s_register_operand" "r")
9765 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9767 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9768 [(set_attr "conds" "use")
9769 (set_attr "length" "8")
9770 (set_attr "type" "multiple")]
9773 (define_insn "*ifcompare_arith_move"
9774 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9775 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9776 [(match_operand:SI 2 "s_register_operand" "r,r")
9777 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9778 (match_operator:SI 7 "shiftable_operator"
9779 [(match_operand:SI 4 "s_register_operand" "r,r")
9780 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9781 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9782 (clobber (reg:CC CC_REGNUM))]
9785 /* If we have an operation where (op x 0) is the identity operation and
9786 the conditional operator is LT or GE and we are comparing against zero and
9787 everything is in registers then we can do this in two instructions. */
9788 if (operands[3] == const0_rtx
9789 && GET_CODE (operands[7]) != AND
9790 && REG_P (operands[5])
9791 && REG_P (operands[1])
9792 && REGNO (operands[1]) == REGNO (operands[4])
9793 && REGNO (operands[4]) != REGNO (operands[0]))
9795 if (GET_CODE (operands[6]) == LT)
9796 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9797 else if (GET_CODE (operands[6]) == GE)
9798 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9800 if (CONST_INT_P (operands[3])
9801 && !const_ok_for_arm (INTVAL (operands[3])))
9802 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9804 output_asm_insn (\"cmp\\t%2, %3\", operands);
9805 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9806 if (which_alternative != 0)
9807 return \"mov%D6\\t%0, %1\";
9810 [(set_attr "conds" "clob")
9811 (set_attr "length" "8,12")
9812 (set_attr "type" "multiple")]
9815 (define_insn "*if_arith_move"
9816 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9817 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9818 [(match_operand 6 "cc_register" "") (const_int 0)])
9819 (match_operator:SI 5 "shiftable_operator"
9820 [(match_operand:SI 2 "s_register_operand" "r,r")
9821 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9822 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9826 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9827 [(set_attr "conds" "use")
9828 (set_attr "length" "4,8")
9829 (set_attr_alternative "type"
9830 [(if_then_else (match_operand 3 "const_int_operand" "")
9831 (const_string "alu_shift_imm" )
9832 (const_string "alu_shift_reg"))
9833 (const_string "multiple")])]
9836 (define_insn "*ifcompare_move_arith"
9837 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9838 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9839 [(match_operand:SI 4 "s_register_operand" "r,r")
9840 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9841 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9842 (match_operator:SI 7 "shiftable_operator"
9843 [(match_operand:SI 2 "s_register_operand" "r,r")
9844 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9845 (clobber (reg:CC CC_REGNUM))]
9848 /* If we have an operation where (op x 0) is the identity operation and
9849 the conditional operator is LT or GE and we are comparing against zero and
9850 everything is in registers then we can do this in two instructions */
9851 if (operands[5] == const0_rtx
9852 && GET_CODE (operands[7]) != AND
9853 && REG_P (operands[3])
9854 && REG_P (operands[1])
9855 && REGNO (operands[1]) == REGNO (operands[2])
9856 && REGNO (operands[2]) != REGNO (operands[0]))
9858 if (GET_CODE (operands[6]) == GE)
9859 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9860 else if (GET_CODE (operands[6]) == LT)
9861 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9864 if (CONST_INT_P (operands[5])
9865 && !const_ok_for_arm (INTVAL (operands[5])))
9866 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9868 output_asm_insn (\"cmp\\t%4, %5\", operands);
9870 if (which_alternative != 0)
9871 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9872 return \"%I7%D6\\t%0, %2, %3\";
9874 [(set_attr "conds" "clob")
9875 (set_attr "length" "8,12")
9876 (set_attr "type" "multiple")]
9879 (define_insn "*if_move_arith"
9880 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9882 (match_operator 4 "arm_comparison_operator"
9883 [(match_operand 6 "cc_register" "") (const_int 0)])
9884 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9885 (match_operator:SI 5 "shiftable_operator"
9886 [(match_operand:SI 2 "s_register_operand" "r,r")
9887 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9891 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9892 [(set_attr "conds" "use")
9893 (set_attr "length" "4,8")
9894 (set_attr_alternative "type"
9895 [(if_then_else (match_operand 3 "const_int_operand" "")
9896 (const_string "alu_shift_imm" )
9897 (const_string "alu_shift_reg"))
9898 (const_string "multiple")])]
9901 (define_insn "*ifcompare_move_not"
9902 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9904 (match_operator 5 "arm_comparison_operator"
9905 [(match_operand:SI 3 "s_register_operand" "r,r")
9906 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9907 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9909 (match_operand:SI 2 "s_register_operand" "r,r"))))
9910 (clobber (reg:CC CC_REGNUM))]
9913 [(set_attr "conds" "clob")
9914 (set_attr "length" "8,12")
9915 (set_attr "type" "multiple")]
9918 (define_insn "*if_move_not"
9919 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9921 (match_operator 4 "arm_comparison_operator"
9922 [(match_operand 3 "cc_register" "") (const_int 0)])
9923 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9924 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9928 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9929 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9930 [(set_attr "conds" "use")
9931 (set_attr "type" "mvn_reg")
9932 (set_attr "length" "4,8,8")
9933 (set_attr "type" "mvn_reg,multiple,multiple")]
9936 (define_insn "*ifcompare_not_move"
9937 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9939 (match_operator 5 "arm_comparison_operator"
9940 [(match_operand:SI 3 "s_register_operand" "r,r")
9941 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9943 (match_operand:SI 2 "s_register_operand" "r,r"))
9944 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9945 (clobber (reg:CC CC_REGNUM))]
9948 [(set_attr "conds" "clob")
9949 (set_attr "length" "8,12")
9950 (set_attr "type" "multiple")]
9953 (define_insn "*if_not_move"
9954 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9956 (match_operator 4 "arm_comparison_operator"
9957 [(match_operand 3 "cc_register" "") (const_int 0)])
9958 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9959 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9963 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9964 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9965 [(set_attr "conds" "use")
9966 (set_attr "type" "mvn_reg,multiple,multiple")
9967 (set_attr "length" "4,8,8")]
9970 (define_insn "*ifcompare_shift_move"
9971 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9973 (match_operator 6 "arm_comparison_operator"
9974 [(match_operand:SI 4 "s_register_operand" "r,r")
9975 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9976 (match_operator:SI 7 "shift_operator"
9977 [(match_operand:SI 2 "s_register_operand" "r,r")
9978 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
9979 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9980 (clobber (reg:CC CC_REGNUM))]
9983 [(set_attr "conds" "clob")
9984 (set_attr "length" "8,12")
9985 (set_attr "type" "multiple")]
9988 (define_insn "*if_shift_move"
9989 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9991 (match_operator 5 "arm_comparison_operator"
9992 [(match_operand 6 "cc_register" "") (const_int 0)])
9993 (match_operator:SI 4 "shift_operator"
9994 [(match_operand:SI 2 "s_register_operand" "r,r,r")
9995 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
9996 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10000 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10001 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10002 [(set_attr "conds" "use")
10003 (set_attr "shift" "2")
10004 (set_attr "length" "4,8,8")
10005 (set_attr_alternative "type"
10006 [(if_then_else (match_operand 3 "const_int_operand" "")
10007 (const_string "mov_shift" )
10008 (const_string "mov_shift_reg"))
10009 (const_string "multiple")
10010 (const_string "multiple")])]
10013 (define_insn "*ifcompare_move_shift"
10014 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10016 (match_operator 6 "arm_comparison_operator"
10017 [(match_operand:SI 4 "s_register_operand" "r,r")
10018 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10019 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10020 (match_operator:SI 7 "shift_operator"
10021 [(match_operand:SI 2 "s_register_operand" "r,r")
10022 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10023 (clobber (reg:CC CC_REGNUM))]
10026 [(set_attr "conds" "clob")
10027 (set_attr "length" "8,12")
10028 (set_attr "type" "multiple")]
10031 (define_insn "*if_move_shift"
10032 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10034 (match_operator 5 "arm_comparison_operator"
10035 [(match_operand 6 "cc_register" "") (const_int 0)])
10036 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10037 (match_operator:SI 4 "shift_operator"
10038 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10039 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10043 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10044 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10045 [(set_attr "conds" "use")
10046 (set_attr "shift" "2")
10047 (set_attr "length" "4,8,8")
10048 (set_attr_alternative "type"
10049 [(if_then_else (match_operand 3 "const_int_operand" "")
10050 (const_string "mov_shift" )
10051 (const_string "mov_shift_reg"))
10052 (const_string "multiple")
10053 (const_string "multiple")])]
10056 (define_insn "*ifcompare_shift_shift"
10057 [(set (match_operand:SI 0 "s_register_operand" "=r")
10059 (match_operator 7 "arm_comparison_operator"
10060 [(match_operand:SI 5 "s_register_operand" "r")
10061 (match_operand:SI 6 "arm_add_operand" "rIL")])
10062 (match_operator:SI 8 "shift_operator"
10063 [(match_operand:SI 1 "s_register_operand" "r")
10064 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10065 (match_operator:SI 9 "shift_operator"
10066 [(match_operand:SI 3 "s_register_operand" "r")
10067 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10068 (clobber (reg:CC CC_REGNUM))]
10071 [(set_attr "conds" "clob")
10072 (set_attr "length" "12")
10073 (set_attr "type" "multiple")]
10076 (define_insn "*if_shift_shift"
10077 [(set (match_operand:SI 0 "s_register_operand" "=r")
10079 (match_operator 5 "arm_comparison_operator"
10080 [(match_operand 8 "cc_register" "") (const_int 0)])
10081 (match_operator:SI 6 "shift_operator"
10082 [(match_operand:SI 1 "s_register_operand" "r")
10083 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10084 (match_operator:SI 7 "shift_operator"
10085 [(match_operand:SI 3 "s_register_operand" "r")
10086 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10088 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10089 [(set_attr "conds" "use")
10090 (set_attr "shift" "1")
10091 (set_attr "length" "8")
10092 (set (attr "type") (if_then_else
10093 (and (match_operand 2 "const_int_operand" "")
10094 (match_operand 4 "const_int_operand" ""))
10095 (const_string "mov_shift")
10096 (const_string "mov_shift_reg")))]
10099 (define_insn "*ifcompare_not_arith"
10100 [(set (match_operand:SI 0 "s_register_operand" "=r")
10102 (match_operator 6 "arm_comparison_operator"
10103 [(match_operand:SI 4 "s_register_operand" "r")
10104 (match_operand:SI 5 "arm_add_operand" "rIL")])
10105 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10106 (match_operator:SI 7 "shiftable_operator"
10107 [(match_operand:SI 2 "s_register_operand" "r")
10108 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
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_not_arith"
10118 [(set (match_operand:SI 0 "s_register_operand" "=r")
10120 (match_operator 5 "arm_comparison_operator"
10121 [(match_operand 4 "cc_register" "") (const_int 0)])
10122 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10123 (match_operator:SI 6 "shiftable_operator"
10124 [(match_operand:SI 2 "s_register_operand" "r")
10125 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10127 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10128 [(set_attr "conds" "use")
10129 (set_attr "type" "mvn_reg")
10130 (set_attr "length" "8")]
10133 (define_insn "*ifcompare_arith_not"
10134 [(set (match_operand:SI 0 "s_register_operand" "=r")
10136 (match_operator 6 "arm_comparison_operator"
10137 [(match_operand:SI 4 "s_register_operand" "r")
10138 (match_operand:SI 5 "arm_add_operand" "rIL")])
10139 (match_operator:SI 7 "shiftable_operator"
10140 [(match_operand:SI 2 "s_register_operand" "r")
10141 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10142 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10143 (clobber (reg:CC CC_REGNUM))]
10146 [(set_attr "conds" "clob")
10147 (set_attr "length" "12")
10148 (set_attr "type" "multiple")]
10151 (define_insn "*if_arith_not"
10152 [(set (match_operand:SI 0 "s_register_operand" "=r")
10154 (match_operator 5 "arm_comparison_operator"
10155 [(match_operand 4 "cc_register" "") (const_int 0)])
10156 (match_operator:SI 6 "shiftable_operator"
10157 [(match_operand:SI 2 "s_register_operand" "r")
10158 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10159 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10161 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10162 [(set_attr "conds" "use")
10163 (set_attr "type" "multiple")
10164 (set_attr "length" "8")]
10167 (define_insn "*ifcompare_neg_move"
10168 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10170 (match_operator 5 "arm_comparison_operator"
10171 [(match_operand:SI 3 "s_register_operand" "r,r")
10172 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10173 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10174 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10175 (clobber (reg:CC CC_REGNUM))]
10178 [(set_attr "conds" "clob")
10179 (set_attr "length" "8,12")
10180 (set_attr "type" "multiple")]
10183 (define_insn_and_split "*if_neg_move"
10184 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10186 (match_operator 4 "arm_comparison_operator"
10187 [(match_operand 3 "cc_register" "") (const_int 0)])
10188 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10189 (match_operand:SI 1 "s_register_operand" "0,0")))]
10192 "&& reload_completed"
10193 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10194 (set (match_dup 0) (neg:SI (match_dup 2))))]
10196 [(set_attr "conds" "use")
10197 (set_attr "length" "4")
10198 (set_attr "arch" "t2,32")
10199 (set_attr "enabled_for_short_it" "yes,no")
10200 (set_attr "type" "logic_shift_imm")]
10203 (define_insn "*ifcompare_move_neg"
10204 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10206 (match_operator 5 "arm_comparison_operator"
10207 [(match_operand:SI 3 "s_register_operand" "r,r")
10208 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10209 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10210 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10211 (clobber (reg:CC CC_REGNUM))]
10214 [(set_attr "conds" "clob")
10215 (set_attr "length" "8,12")
10216 (set_attr "type" "multiple")]
10219 (define_insn_and_split "*if_move_neg"
10220 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10222 (match_operator 4 "arm_comparison_operator"
10223 [(match_operand 3 "cc_register" "") (const_int 0)])
10224 (match_operand:SI 1 "s_register_operand" "0,0")
10225 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10228 "&& reload_completed"
10229 [(cond_exec (match_dup 5)
10230 (set (match_dup 0) (neg:SI (match_dup 2))))]
10232 machine_mode mode = GET_MODE (operands[3]);
10233 rtx_code rc = GET_CODE (operands[4]);
10235 if (mode == CCFPmode || mode == CCFPEmode)
10236 rc = reverse_condition_maybe_unordered (rc);
10238 rc = reverse_condition (rc);
10240 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10242 [(set_attr "conds" "use")
10243 (set_attr "length" "4")
10244 (set_attr "arch" "t2,32")
10245 (set_attr "enabled_for_short_it" "yes,no")
10246 (set_attr "type" "logic_shift_imm")]
10249 (define_insn "*arith_adjacentmem"
10250 [(set (match_operand:SI 0 "s_register_operand" "=r")
10251 (match_operator:SI 1 "shiftable_operator"
10252 [(match_operand:SI 2 "memory_operand" "m")
10253 (match_operand:SI 3 "memory_operand" "m")]))
10254 (clobber (match_scratch:SI 4 "=r"))]
10255 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10261 HOST_WIDE_INT val1 = 0, val2 = 0;
10263 if (REGNO (operands[0]) > REGNO (operands[4]))
10265 ldm[1] = operands[4];
10266 ldm[2] = operands[0];
10270 ldm[1] = operands[0];
10271 ldm[2] = operands[4];
10274 base_reg = XEXP (operands[2], 0);
10276 if (!REG_P (base_reg))
10278 val1 = INTVAL (XEXP (base_reg, 1));
10279 base_reg = XEXP (base_reg, 0);
10282 if (!REG_P (XEXP (operands[3], 0)))
10283 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10285 arith[0] = operands[0];
10286 arith[3] = operands[1];
10300 if (val1 !=0 && val2 != 0)
10304 if (val1 == 4 || val2 == 4)
10305 /* Other val must be 8, since we know they are adjacent and neither
10307 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10308 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10310 ldm[0] = ops[0] = operands[4];
10312 ops[2] = GEN_INT (val1);
10313 output_add_immediate (ops);
10315 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10317 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10321 /* Offset is out of range for a single add, so use two ldr. */
10324 ops[2] = GEN_INT (val1);
10325 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10327 ops[2] = GEN_INT (val2);
10328 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10331 else if (val1 != 0)
10334 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10336 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10341 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10343 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10345 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10348 [(set_attr "length" "12")
10349 (set_attr "predicable" "yes")
10350 (set_attr "type" "load_4")]
10353 ; This pattern is never tried by combine, so do it as a peephole
10356 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10357 (match_operand:SI 1 "arm_general_register_operand" ""))
10358 (set (reg:CC CC_REGNUM)
10359 (compare:CC (match_dup 1) (const_int 0)))]
10361 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10362 (set (match_dup 0) (match_dup 1))])]
10367 [(set (match_operand:SI 0 "s_register_operand" "")
10368 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10370 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10371 [(match_operand:SI 3 "s_register_operand" "")
10372 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10373 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10375 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10376 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10381 ;; This split can be used because CC_Z mode implies that the following
10382 ;; branch will be an equality, or an unsigned inequality, so the sign
10383 ;; extension is not needed.
10386 [(set (reg:CC_Z CC_REGNUM)
10388 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10390 (match_operand 1 "const_int_operand" "")))
10391 (clobber (match_scratch:SI 2 ""))]
10393 && ((UINTVAL (operands[1]))
10394 == ((UINTVAL (operands[1])) >> 24) << 24)"
10395 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10396 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10398 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10401 ;; ??? Check the patterns above for Thumb-2 usefulness
10403 (define_expand "prologue"
10404 [(clobber (const_int 0))]
10407 arm_expand_prologue ();
10409 thumb1_expand_prologue ();
10414 (define_expand "epilogue"
10415 [(clobber (const_int 0))]
10418 if (crtl->calls_eh_return)
10419 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10422 thumb1_expand_epilogue ();
10423 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10424 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10426 else if (HAVE_return)
10428 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10429 no need for explicit testing again. */
10430 emit_jump_insn (gen_return ());
10432 else if (TARGET_32BIT)
10434 arm_expand_epilogue (true);
10440 ;; Note - although unspec_volatile's USE all hard registers,
10441 ;; USEs are ignored after relaod has completed. Thus we need
10442 ;; to add an unspec of the link register to ensure that flow
10443 ;; does not think that it is unused by the sibcall branch that
10444 ;; will replace the standard function epilogue.
10445 (define_expand "sibcall_epilogue"
10446 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10447 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10450 arm_expand_epilogue (false);
10455 (define_expand "eh_epilogue"
10456 [(use (match_operand:SI 0 "register_operand"))
10457 (use (match_operand:SI 1 "register_operand"))
10458 (use (match_operand:SI 2 "register_operand"))]
10462 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10463 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10465 rtx ra = gen_rtx_REG (Pmode, 2);
10467 emit_move_insn (ra, operands[2]);
10470 /* This is a hack -- we may have crystalized the function type too
10472 cfun->machine->func_type = 0;
10476 ;; This split is only used during output to reduce the number of patterns
10477 ;; that need assembler instructions adding to them. We allowed the setting
10478 ;; of the conditions to be implicit during rtl generation so that
10479 ;; the conditional compare patterns would work. However this conflicts to
10480 ;; some extent with the conditional data operations, so we have to split them
10483 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10484 ;; conditional execution sufficient?
10487 [(set (match_operand:SI 0 "s_register_operand" "")
10488 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10489 [(match_operand 2 "" "") (match_operand 3 "" "")])
10491 (match_operand 4 "" "")))
10492 (clobber (reg:CC CC_REGNUM))]
10493 "TARGET_ARM && reload_completed"
10494 [(set (match_dup 5) (match_dup 6))
10495 (cond_exec (match_dup 7)
10496 (set (match_dup 0) (match_dup 4)))]
10499 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10500 operands[2], operands[3]);
10501 enum rtx_code rc = GET_CODE (operands[1]);
10503 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10504 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10505 if (mode == CCFPmode || mode == CCFPEmode)
10506 rc = reverse_condition_maybe_unordered (rc);
10508 rc = reverse_condition (rc);
10510 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10515 [(set (match_operand:SI 0 "s_register_operand" "")
10516 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10517 [(match_operand 2 "" "") (match_operand 3 "" "")])
10518 (match_operand 4 "" "")
10520 (clobber (reg:CC CC_REGNUM))]
10521 "TARGET_ARM && reload_completed"
10522 [(set (match_dup 5) (match_dup 6))
10523 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10524 (set (match_dup 0) (match_dup 4)))]
10527 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10528 operands[2], operands[3]);
10530 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10531 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10536 [(set (match_operand:SI 0 "s_register_operand" "")
10537 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10538 [(match_operand 2 "" "") (match_operand 3 "" "")])
10539 (match_operand 4 "" "")
10540 (match_operand 5 "" "")))
10541 (clobber (reg:CC CC_REGNUM))]
10542 "TARGET_ARM && reload_completed"
10543 [(set (match_dup 6) (match_dup 7))
10544 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10545 (set (match_dup 0) (match_dup 4)))
10546 (cond_exec (match_dup 8)
10547 (set (match_dup 0) (match_dup 5)))]
10550 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10551 operands[2], operands[3]);
10552 enum rtx_code rc = GET_CODE (operands[1]);
10554 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10555 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10556 if (mode == CCFPmode || mode == CCFPEmode)
10557 rc = reverse_condition_maybe_unordered (rc);
10559 rc = reverse_condition (rc);
10561 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10566 [(set (match_operand:SI 0 "s_register_operand" "")
10567 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10568 [(match_operand:SI 2 "s_register_operand" "")
10569 (match_operand:SI 3 "arm_add_operand" "")])
10570 (match_operand:SI 4 "arm_rhs_operand" "")
10572 (match_operand:SI 5 "s_register_operand" ""))))
10573 (clobber (reg:CC CC_REGNUM))]
10574 "TARGET_ARM && reload_completed"
10575 [(set (match_dup 6) (match_dup 7))
10576 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10577 (set (match_dup 0) (match_dup 4)))
10578 (cond_exec (match_dup 8)
10579 (set (match_dup 0) (not:SI (match_dup 5))))]
10582 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10583 operands[2], operands[3]);
10584 enum rtx_code rc = GET_CODE (operands[1]);
10586 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10587 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10588 if (mode == CCFPmode || mode == CCFPEmode)
10589 rc = reverse_condition_maybe_unordered (rc);
10591 rc = reverse_condition (rc);
10593 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10597 (define_insn "*cond_move_not"
10598 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10599 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10600 [(match_operand 3 "cc_register" "") (const_int 0)])
10601 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10603 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10607 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10608 [(set_attr "conds" "use")
10609 (set_attr "type" "mvn_reg,multiple")
10610 (set_attr "length" "4,8")]
10613 ;; The next two patterns occur when an AND operation is followed by a
10614 ;; scc insn sequence
10616 (define_insn "*sign_extract_onebit"
10617 [(set (match_operand:SI 0 "s_register_operand" "=r")
10618 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10620 (match_operand:SI 2 "const_int_operand" "n")))
10621 (clobber (reg:CC CC_REGNUM))]
10624 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10625 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10626 return \"mvnne\\t%0, #0\";
10628 [(set_attr "conds" "clob")
10629 (set_attr "length" "8")
10630 (set_attr "type" "multiple")]
10633 (define_insn "*not_signextract_onebit"
10634 [(set (match_operand:SI 0 "s_register_operand" "=r")
10636 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10638 (match_operand:SI 2 "const_int_operand" "n"))))
10639 (clobber (reg:CC CC_REGNUM))]
10642 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10643 output_asm_insn (\"tst\\t%1, %2\", operands);
10644 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10645 return \"movne\\t%0, #0\";
10647 [(set_attr "conds" "clob")
10648 (set_attr "length" "12")
10649 (set_attr "type" "multiple")]
10651 ;; ??? The above patterns need auditing for Thumb-2
10653 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10654 ;; expressions. For simplicity, the first register is also in the unspec
10656 ;; To avoid the usage of GNU extension, the length attribute is computed
10657 ;; in a C function arm_attr_length_push_multi.
10658 (define_insn "*push_multi"
10659 [(match_parallel 2 "multi_register_push"
10660 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10661 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10662 UNSPEC_PUSH_MULT))])]
10666 int num_saves = XVECLEN (operands[2], 0);
10668 /* For the StrongARM at least it is faster to
10669 use STR to store only a single register.
10670 In Thumb mode always use push, and the assembler will pick
10671 something appropriate. */
10672 if (num_saves == 1 && TARGET_ARM)
10673 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10680 strcpy (pattern, \"push%?\\t{%1\");
10682 strcpy (pattern, \"push\\t{%1\");
10684 for (i = 1; i < num_saves; i++)
10686 strcat (pattern, \", %|\");
10688 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10691 strcat (pattern, \"}\");
10692 output_asm_insn (pattern, operands);
10697 [(set_attr "type" "store_16")
10698 (set (attr "length")
10699 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10702 (define_insn "stack_tie"
10703 [(set (mem:BLK (scratch))
10704 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10705 (match_operand:SI 1 "s_register_operand" "rk")]
10709 [(set_attr "length" "0")
10710 (set_attr "type" "block")]
10713 ;; Pop (as used in epilogue RTL)
10715 (define_insn "*load_multiple_with_writeback"
10716 [(match_parallel 0 "load_multiple_operation"
10717 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10718 (plus:SI (match_dup 1)
10719 (match_operand:SI 2 "const_int_I_operand" "I")))
10720 (set (match_operand:SI 3 "s_register_operand" "=rk")
10721 (mem:SI (match_dup 1)))
10723 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10726 arm_output_multireg_pop (operands, /*return_pc=*/false,
10727 /*cond=*/const_true_rtx,
10733 [(set_attr "type" "load_16")
10734 (set_attr "predicable" "yes")
10735 (set (attr "length")
10736 (symbol_ref "arm_attr_length_pop_multi (operands,
10737 /*return_pc=*/false,
10738 /*write_back_p=*/true)"))]
10741 ;; Pop with return (as used in epilogue RTL)
10743 ;; This instruction is generated when the registers are popped at the end of
10744 ;; epilogue. Here, instead of popping the value into LR and then generating
10745 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10747 (define_insn "*pop_multiple_with_writeback_and_return"
10748 [(match_parallel 0 "pop_multiple_return"
10750 (set (match_operand:SI 1 "s_register_operand" "+rk")
10751 (plus:SI (match_dup 1)
10752 (match_operand:SI 2 "const_int_I_operand" "I")))
10753 (set (match_operand:SI 3 "s_register_operand" "=rk")
10754 (mem:SI (match_dup 1)))
10756 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10759 arm_output_multireg_pop (operands, /*return_pc=*/true,
10760 /*cond=*/const_true_rtx,
10766 [(set_attr "type" "load_16")
10767 (set_attr "predicable" "yes")
10768 (set (attr "length")
10769 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10770 /*write_back_p=*/true)"))]
10773 (define_insn "*pop_multiple_with_return"
10774 [(match_parallel 0 "pop_multiple_return"
10776 (set (match_operand:SI 2 "s_register_operand" "=rk")
10777 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10779 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10782 arm_output_multireg_pop (operands, /*return_pc=*/true,
10783 /*cond=*/const_true_rtx,
10789 [(set_attr "type" "load_16")
10790 (set_attr "predicable" "yes")
10791 (set (attr "length")
10792 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10793 /*write_back_p=*/false)"))]
10796 ;; Load into PC and return
10797 (define_insn "*ldr_with_return"
10799 (set (reg:SI PC_REGNUM)
10800 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10801 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10802 "ldr%?\t%|pc, [%0], #4"
10803 [(set_attr "type" "load_4")
10804 (set_attr "predicable" "yes")]
10806 ;; Pop for floating point registers (as used in epilogue RTL)
10807 (define_insn "*vfp_pop_multiple_with_writeback"
10808 [(match_parallel 0 "pop_multiple_fp"
10809 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10810 (plus:SI (match_dup 1)
10811 (match_operand:SI 2 "const_int_I_operand" "I")))
10812 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10813 (mem:DF (match_dup 1)))])]
10814 "TARGET_32BIT && TARGET_HARD_FLOAT"
10817 int num_regs = XVECLEN (operands[0], 0);
10820 strcpy (pattern, \"vldm\\t\");
10821 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10822 strcat (pattern, \"!, {\");
10823 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10824 strcat (pattern, \"%P0\");
10825 if ((num_regs - 1) > 1)
10827 strcat (pattern, \"-%P1\");
10828 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10831 strcat (pattern, \"}\");
10832 output_asm_insn (pattern, op_list);
10836 [(set_attr "type" "load_16")
10837 (set_attr "conds" "unconditional")
10838 (set_attr "predicable" "no")]
10841 ;; Special patterns for dealing with the constant pool
10843 (define_insn "align_4"
10844 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10847 assemble_align (32);
10850 [(set_attr "type" "no_insn")]
10853 (define_insn "align_8"
10854 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10857 assemble_align (64);
10860 [(set_attr "type" "no_insn")]
10863 (define_insn "consttable_end"
10864 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10867 making_const_table = FALSE;
10870 [(set_attr "type" "no_insn")]
10873 (define_insn "consttable_1"
10874 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10877 making_const_table = TRUE;
10878 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10879 assemble_zeros (3);
10882 [(set_attr "length" "4")
10883 (set_attr "type" "no_insn")]
10886 (define_insn "consttable_2"
10887 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10891 rtx x = operands[0];
10892 making_const_table = TRUE;
10893 switch (GET_MODE_CLASS (GET_MODE (x)))
10896 arm_emit_fp16_const (x);
10899 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10900 assemble_zeros (2);
10905 [(set_attr "length" "4")
10906 (set_attr "type" "no_insn")]
10909 (define_insn "consttable_4"
10910 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10914 rtx x = operands[0];
10915 making_const_table = TRUE;
10916 scalar_float_mode float_mode;
10917 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
10918 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
10921 /* XXX: Sometimes gcc does something really dumb and ends up with
10922 a HIGH in a constant pool entry, usually because it's trying to
10923 load into a VFP register. We know this will always be used in
10924 combination with a LO_SUM which ignores the high bits, so just
10925 strip off the HIGH. */
10926 if (GET_CODE (x) == HIGH)
10928 assemble_integer (x, 4, BITS_PER_WORD, 1);
10929 mark_symbol_refs_as_used (x);
10933 [(set_attr "length" "4")
10934 (set_attr "type" "no_insn")]
10937 (define_insn "consttable_8"
10938 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10942 making_const_table = TRUE;
10943 scalar_float_mode float_mode;
10944 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
10945 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10946 float_mode, BITS_PER_WORD);
10948 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10951 [(set_attr "length" "8")
10952 (set_attr "type" "no_insn")]
10955 (define_insn "consttable_16"
10956 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10960 making_const_table = TRUE;
10961 scalar_float_mode float_mode;
10962 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
10963 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10964 float_mode, BITS_PER_WORD);
10966 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10969 [(set_attr "length" "16")
10970 (set_attr "type" "no_insn")]
10973 ;; V5 Instructions,
10975 (define_insn "clzsi2"
10976 [(set (match_operand:SI 0 "s_register_operand" "=r")
10977 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10978 "TARGET_32BIT && arm_arch5t"
10980 [(set_attr "predicable" "yes")
10981 (set_attr "type" "clz")])
10983 (define_insn "rbitsi2"
10984 [(set (match_operand:SI 0 "s_register_operand" "=r")
10985 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
10986 "TARGET_32BIT && arm_arch_thumb2"
10988 [(set_attr "predicable" "yes")
10989 (set_attr "type" "clz")])
10991 ;; Keep this as a CTZ expression until after reload and then split
10992 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
10993 ;; to fold with any other expression.
10995 (define_insn_and_split "ctzsi2"
10996 [(set (match_operand:SI 0 "s_register_operand" "=r")
10997 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10998 "TARGET_32BIT && arm_arch_thumb2"
11000 "&& reload_completed"
11003 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11004 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11008 ;; V5E instructions.
11010 (define_insn "prefetch"
11011 [(prefetch (match_operand:SI 0 "address_operand" "p")
11012 (match_operand:SI 1 "" "")
11013 (match_operand:SI 2 "" ""))]
11014 "TARGET_32BIT && arm_arch5te"
11016 [(set_attr "type" "load_4")]
11019 ;; General predication pattern
11022 [(match_operator 0 "arm_comparison_operator"
11023 [(match_operand 1 "cc_register" "")
11026 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11028 [(set_attr "predicated" "yes")]
11031 (define_insn "force_register_use"
11032 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11035 [(set_attr "length" "0")
11036 (set_attr "type" "no_insn")]
11040 ;; Patterns for exception handling
11042 (define_expand "eh_return"
11043 [(use (match_operand 0 "general_operand"))]
11048 emit_insn (gen_arm_eh_return (operands[0]));
11050 emit_insn (gen_thumb_eh_return (operands[0]));
11055 ;; We can't expand this before we know where the link register is stored.
11056 (define_insn_and_split "arm_eh_return"
11057 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11059 (clobber (match_scratch:SI 1 "=&r"))]
11062 "&& reload_completed"
11066 arm_set_return_address (operands[0], operands[1]);
11074 (define_insn "load_tp_hard"
11075 [(set (match_operand:SI 0 "register_operand" "=r")
11076 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11078 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11079 [(set_attr "predicable" "yes")
11080 (set_attr "type" "mrs")]
11083 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11084 (define_insn "load_tp_soft_fdpic"
11085 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11086 (clobber (reg:SI FDPIC_REGNUM))
11087 (clobber (reg:SI LR_REGNUM))
11088 (clobber (reg:SI IP_REGNUM))
11089 (clobber (reg:CC CC_REGNUM))]
11090 "TARGET_SOFT_TP && TARGET_FDPIC"
11091 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11092 [(set_attr "conds" "clob")
11093 (set_attr "type" "branch")]
11096 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11097 (define_insn "load_tp_soft"
11098 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11099 (clobber (reg:SI LR_REGNUM))
11100 (clobber (reg:SI IP_REGNUM))
11101 (clobber (reg:CC CC_REGNUM))]
11102 "TARGET_SOFT_TP && !TARGET_FDPIC"
11103 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11104 [(set_attr "conds" "clob")
11105 (set_attr "type" "branch")]
11108 ;; tls descriptor call
11109 (define_insn "tlscall"
11110 [(set (reg:SI R0_REGNUM)
11111 (unspec:SI [(reg:SI R0_REGNUM)
11112 (match_operand:SI 0 "" "X")
11113 (match_operand 1 "" "")] UNSPEC_TLS))
11114 (clobber (reg:SI R1_REGNUM))
11115 (clobber (reg:SI LR_REGNUM))
11116 (clobber (reg:SI CC_REGNUM))]
11119 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11120 INTVAL (operands[1]));
11121 return "bl\\t%c0(tlscall)";
11123 [(set_attr "conds" "clob")
11124 (set_attr "length" "4")
11125 (set_attr "type" "branch")]
11128 ;; For thread pointer builtin
11129 (define_expand "get_thread_pointersi"
11130 [(match_operand:SI 0 "s_register_operand")]
11134 arm_load_tp (operands[0]);
11140 ;; We only care about the lower 16 bits of the constant
11141 ;; being inserted into the upper 16 bits of the register.
11142 (define_insn "*arm_movtas_ze"
11143 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11146 (match_operand:SI 1 "const_int_operand" ""))]
11151 [(set_attr "arch" "32,v8mb")
11152 (set_attr "predicable" "yes")
11153 (set_attr "length" "4")
11154 (set_attr "type" "alu_sreg")]
11157 (define_insn "*arm_rev"
11158 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11159 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11165 [(set_attr "arch" "t1,t2,32")
11166 (set_attr "length" "2,2,4")
11167 (set_attr "predicable" "no,yes,yes")
11168 (set_attr "type" "rev")]
11171 (define_expand "arm_legacy_rev"
11172 [(set (match_operand:SI 2 "s_register_operand")
11173 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand")
11177 (lshiftrt:SI (match_dup 2)
11179 (set (match_operand:SI 3 "s_register_operand")
11180 (rotatert:SI (match_dup 1)
11183 (and:SI (match_dup 2)
11184 (const_int -65281)))
11185 (set (match_operand:SI 0 "s_register_operand")
11186 (xor:SI (match_dup 3)
11192 ;; Reuse temporaries to keep register pressure down.
11193 (define_expand "thumb_legacy_rev"
11194 [(set (match_operand:SI 2 "s_register_operand")
11195 (ashift:SI (match_operand:SI 1 "s_register_operand")
11197 (set (match_operand:SI 3 "s_register_operand")
11198 (lshiftrt:SI (match_dup 1)
11201 (ior:SI (match_dup 3)
11203 (set (match_operand:SI 4 "s_register_operand")
11205 (set (match_operand:SI 5 "s_register_operand")
11206 (rotatert:SI (match_dup 1)
11209 (ashift:SI (match_dup 5)
11212 (lshiftrt:SI (match_dup 5)
11215 (ior:SI (match_dup 5)
11218 (rotatert:SI (match_dup 5)
11220 (set (match_operand:SI 0 "s_register_operand")
11221 (ior:SI (match_dup 5)
11227 ;; ARM-specific expansion of signed mod by power of 2
11228 ;; using conditional negate.
11229 ;; For r0 % n where n is a power of 2 produce:
11231 ;; and r0, r0, #(n - 1)
11232 ;; and r1, r1, #(n - 1)
11233 ;; rsbpl r0, r1, #0
11235 (define_expand "modsi3"
11236 [(match_operand:SI 0 "register_operand")
11237 (match_operand:SI 1 "register_operand")
11238 (match_operand:SI 2 "const_int_operand")]
11241 HOST_WIDE_INT val = INTVAL (operands[2]);
11244 || exact_log2 (val) <= 0)
11247 rtx mask = GEN_INT (val - 1);
11249 /* In the special case of x0 % 2 we can do the even shorter:
11252 rsblt r0, r0, #0. */
11256 rtx cc_reg = arm_gen_compare_reg (LT,
11257 operands[1], const0_rtx, NULL_RTX);
11258 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11259 rtx masked = gen_reg_rtx (SImode);
11261 emit_insn (gen_andsi3 (masked, operands[1], mask));
11262 emit_move_insn (operands[0],
11263 gen_rtx_IF_THEN_ELSE (SImode, cond,
11264 gen_rtx_NEG (SImode,
11270 rtx neg_op = gen_reg_rtx (SImode);
11271 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11274 /* Extract the condition register and mode. */
11275 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11276 rtx cc_reg = SET_DEST (cmp);
11277 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11279 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11281 rtx masked_neg = gen_reg_rtx (SImode);
11282 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11284 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11285 during expand does not always work. Do an IF_THEN_ELSE instead. */
11286 emit_move_insn (operands[0],
11287 gen_rtx_IF_THEN_ELSE (SImode, cond,
11288 gen_rtx_NEG (SImode, masked_neg),
11296 (define_expand "bswapsi2"
11297 [(set (match_operand:SI 0 "s_register_operand")
11298 (bswap:SI (match_operand:SI 1 "s_register_operand")))]
11299 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11303 rtx op2 = gen_reg_rtx (SImode);
11304 rtx op3 = gen_reg_rtx (SImode);
11308 rtx op4 = gen_reg_rtx (SImode);
11309 rtx op5 = gen_reg_rtx (SImode);
11311 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11312 op2, op3, op4, op5));
11316 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11325 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11326 ;; and unsigned variants, respectively. For rev16, expose
11327 ;; byte-swapping in the lower 16 bits only.
11328 (define_insn "*arm_revsh"
11329 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11330 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11336 [(set_attr "arch" "t1,t2,32")
11337 (set_attr "length" "2,2,4")
11338 (set_attr "type" "rev")]
11341 (define_insn "*arm_rev16"
11342 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11343 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11349 [(set_attr "arch" "t1,t2,32")
11350 (set_attr "length" "2,2,4")
11351 (set_attr "type" "rev")]
11354 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11355 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11356 ;; each valid permutation.
11358 (define_insn "arm_rev16si2"
11359 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11360 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11362 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11363 (and:SI (lshiftrt:SI (match_dup 1)
11365 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11367 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11368 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11370 [(set_attr "arch" "t1,t2,32")
11371 (set_attr "length" "2,2,4")
11372 (set_attr "type" "rev")]
11375 (define_insn "arm_rev16si2_alt"
11376 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11377 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11379 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11380 (and:SI (ashift:SI (match_dup 1)
11382 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11384 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11385 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11387 [(set_attr "arch" "t1,t2,32")
11388 (set_attr "length" "2,2,4")
11389 (set_attr "type" "rev")]
11392 (define_expand "bswaphi2"
11393 [(set (match_operand:HI 0 "s_register_operand")
11394 (bswap:HI (match_operand:HI 1 "s_register_operand")))]
11399 ;; Patterns for LDRD/STRD in Thumb2 mode
11401 (define_insn "*thumb2_ldrd"
11402 [(set (match_operand:SI 0 "s_register_operand" "=r")
11403 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11404 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11405 (set (match_operand:SI 3 "s_register_operand" "=r")
11406 (mem:SI (plus:SI (match_dup 1)
11407 (match_operand:SI 4 "const_int_operand" ""))))]
11408 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11409 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11410 && (operands_ok_ldrd_strd (operands[0], operands[3],
11411 operands[1], INTVAL (operands[2]),
11413 "ldrd%?\t%0, %3, [%1, %2]"
11414 [(set_attr "type" "load_8")
11415 (set_attr "predicable" "yes")])
11417 (define_insn "*thumb2_ldrd_base"
11418 [(set (match_operand:SI 0 "s_register_operand" "=r")
11419 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11420 (set (match_operand:SI 2 "s_register_operand" "=r")
11421 (mem:SI (plus:SI (match_dup 1)
11423 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11424 && (operands_ok_ldrd_strd (operands[0], operands[2],
11425 operands[1], 0, false, true))"
11426 "ldrd%?\t%0, %2, [%1]"
11427 [(set_attr "type" "load_8")
11428 (set_attr "predicable" "yes")])
11430 (define_insn "*thumb2_ldrd_base_neg"
11431 [(set (match_operand:SI 0 "s_register_operand" "=r")
11432 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11434 (set (match_operand:SI 2 "s_register_operand" "=r")
11435 (mem:SI (match_dup 1)))]
11436 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11437 && (operands_ok_ldrd_strd (operands[0], operands[2],
11438 operands[1], -4, false, true))"
11439 "ldrd%?\t%0, %2, [%1, #-4]"
11440 [(set_attr "type" "load_8")
11441 (set_attr "predicable" "yes")])
11443 (define_insn "*thumb2_strd"
11444 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11445 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11446 (match_operand:SI 2 "s_register_operand" "r"))
11447 (set (mem:SI (plus:SI (match_dup 0)
11448 (match_operand:SI 3 "const_int_operand" "")))
11449 (match_operand:SI 4 "s_register_operand" "r"))]
11450 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11451 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11452 && (operands_ok_ldrd_strd (operands[2], operands[4],
11453 operands[0], INTVAL (operands[1]),
11455 "strd%?\t%2, %4, [%0, %1]"
11456 [(set_attr "type" "store_8")
11457 (set_attr "predicable" "yes")])
11459 (define_insn "*thumb2_strd_base"
11460 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11461 (match_operand:SI 1 "s_register_operand" "r"))
11462 (set (mem:SI (plus:SI (match_dup 0)
11464 (match_operand:SI 2 "s_register_operand" "r"))]
11465 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11466 && (operands_ok_ldrd_strd (operands[1], operands[2],
11467 operands[0], 0, false, false))"
11468 "strd%?\t%1, %2, [%0]"
11469 [(set_attr "type" "store_8")
11470 (set_attr "predicable" "yes")])
11472 (define_insn "*thumb2_strd_base_neg"
11473 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11475 (match_operand:SI 1 "s_register_operand" "r"))
11476 (set (mem:SI (match_dup 0))
11477 (match_operand:SI 2 "s_register_operand" "r"))]
11478 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11479 && (operands_ok_ldrd_strd (operands[1], operands[2],
11480 operands[0], -4, false, false))"
11481 "strd%?\t%1, %2, [%0, #-4]"
11482 [(set_attr "type" "store_8")
11483 (set_attr "predicable" "yes")])
11485 ;; ARMv8 CRC32 instructions.
11486 (define_insn "arm_<crc_variant>"
11487 [(set (match_operand:SI 0 "s_register_operand" "=r")
11488 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11489 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11492 "<crc_variant>\\t%0, %1, %2"
11493 [(set_attr "type" "crc")
11494 (set_attr "conds" "unconditional")]
11497 ;; Load the load/store double peephole optimizations.
11498 (include "ldrdstrd.md")
11500 ;; Load the load/store multiple patterns
11501 (include "ldmstm.md")
11503 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11504 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11505 ;; The operands are validated through the load_multiple_operation
11506 ;; match_parallel predicate rather than through constraints so enable it only
11508 (define_insn "*load_multiple"
11509 [(match_parallel 0 "load_multiple_operation"
11510 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11511 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11513 "TARGET_32BIT && reload_completed"
11516 arm_output_multireg_pop (operands, /*return_pc=*/false,
11517 /*cond=*/const_true_rtx,
11523 [(set_attr "predicable" "yes")]
11526 (define_expand "copysignsf3"
11527 [(match_operand:SF 0 "register_operand")
11528 (match_operand:SF 1 "register_operand")
11529 (match_operand:SF 2 "register_operand")]
11530 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11532 emit_move_insn (operands[0], operands[2]);
11533 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11534 GEN_INT (31), GEN_INT (0),
11535 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11540 (define_expand "copysigndf3"
11541 [(match_operand:DF 0 "register_operand")
11542 (match_operand:DF 1 "register_operand")
11543 (match_operand:DF 2 "register_operand")]
11544 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11546 rtx op0_low = gen_lowpart (SImode, operands[0]);
11547 rtx op0_high = gen_highpart (SImode, operands[0]);
11548 rtx op1_low = gen_lowpart (SImode, operands[1]);
11549 rtx op1_high = gen_highpart (SImode, operands[1]);
11550 rtx op2_high = gen_highpart (SImode, operands[2]);
11552 rtx scratch1 = gen_reg_rtx (SImode);
11553 rtx scratch2 = gen_reg_rtx (SImode);
11554 emit_move_insn (scratch1, op2_high);
11555 emit_move_insn (scratch2, op1_high);
11557 emit_insn(gen_rtx_SET(scratch1,
11558 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11559 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11560 emit_move_insn (op0_low, op1_low);
11561 emit_move_insn (op0_high, scratch2);
11567 ;; movmisalign patterns for HImode and SImode.
11568 (define_expand "movmisalign<mode>"
11569 [(match_operand:HSI 0 "general_operand")
11570 (match_operand:HSI 1 "general_operand")]
11573 /* This pattern is not permitted to fail during expansion: if both arguments
11574 are non-registers (e.g. memory := constant), force operand 1 into a
11576 rtx (* gen_unaligned_load)(rtx, rtx);
11577 rtx tmp_dest = operands[0];
11578 if (!s_register_operand (operands[0], <MODE>mode)
11579 && !s_register_operand (operands[1], <MODE>mode))
11580 operands[1] = force_reg (<MODE>mode, operands[1]);
11582 if (<MODE>mode == HImode)
11584 gen_unaligned_load = gen_unaligned_loadhiu;
11585 tmp_dest = gen_reg_rtx (SImode);
11588 gen_unaligned_load = gen_unaligned_loadsi;
11590 if (MEM_P (operands[1]))
11592 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11593 if (<MODE>mode == HImode)
11594 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11597 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11602 (define_insn "arm_<cdp>"
11603 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11604 (match_operand:SI 1 "immediate_operand" "n")
11605 (match_operand:SI 2 "immediate_operand" "n")
11606 (match_operand:SI 3 "immediate_operand" "n")
11607 (match_operand:SI 4 "immediate_operand" "n")
11608 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11609 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11611 arm_const_bounds (operands[0], 0, 16);
11612 arm_const_bounds (operands[1], 0, 16);
11613 arm_const_bounds (operands[2], 0, (1 << 5));
11614 arm_const_bounds (operands[3], 0, (1 << 5));
11615 arm_const_bounds (operands[4], 0, (1 << 5));
11616 arm_const_bounds (operands[5], 0, 8);
11617 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11619 [(set_attr "length" "4")
11620 (set_attr "type" "coproc")])
11622 (define_insn "*ldc"
11623 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11624 (match_operand:SI 1 "immediate_operand" "n")
11625 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11626 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11628 arm_const_bounds (operands[0], 0, 16);
11629 arm_const_bounds (operands[1], 0, (1 << 5));
11630 return "<ldc>\\tp%c0, CR%c1, %2";
11632 [(set_attr "length" "4")
11633 (set_attr "type" "coproc")])
11635 (define_insn "*stc"
11636 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11637 (match_operand:SI 1 "immediate_operand" "n")
11638 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11639 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11641 arm_const_bounds (operands[0], 0, 16);
11642 arm_const_bounds (operands[1], 0, (1 << 5));
11643 return "<stc>\\tp%c0, CR%c1, %2";
11645 [(set_attr "length" "4")
11646 (set_attr "type" "coproc")])
11648 (define_expand "arm_<ldc>"
11649 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11650 (match_operand:SI 1 "immediate_operand")
11651 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11652 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11654 (define_expand "arm_<stc>"
11655 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11656 (match_operand:SI 1 "immediate_operand")
11657 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11658 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
11660 (define_insn "arm_<mcr>"
11661 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11662 (match_operand:SI 1 "immediate_operand" "n")
11663 (match_operand:SI 2 "s_register_operand" "r")
11664 (match_operand:SI 3 "immediate_operand" "n")
11665 (match_operand:SI 4 "immediate_operand" "n")
11666 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
11667 (use (match_dup 2))]
11668 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
11670 arm_const_bounds (operands[0], 0, 16);
11671 arm_const_bounds (operands[1], 0, 8);
11672 arm_const_bounds (operands[3], 0, (1 << 5));
11673 arm_const_bounds (operands[4], 0, (1 << 5));
11674 arm_const_bounds (operands[5], 0, 8);
11675 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
11677 [(set_attr "length" "4")
11678 (set_attr "type" "coproc")])
11680 (define_insn "arm_<mrc>"
11681 [(set (match_operand:SI 0 "s_register_operand" "=r")
11682 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
11683 (match_operand:SI 2 "immediate_operand" "n")
11684 (match_operand:SI 3 "immediate_operand" "n")
11685 (match_operand:SI 4 "immediate_operand" "n")
11686 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
11687 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
11689 arm_const_bounds (operands[1], 0, 16);
11690 arm_const_bounds (operands[2], 0, 8);
11691 arm_const_bounds (operands[3], 0, (1 << 5));
11692 arm_const_bounds (operands[4], 0, (1 << 5));
11693 arm_const_bounds (operands[5], 0, 8);
11694 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
11696 [(set_attr "length" "4")
11697 (set_attr "type" "coproc")])
11699 (define_insn "arm_<mcrr>"
11700 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11701 (match_operand:SI 1 "immediate_operand" "n")
11702 (match_operand:DI 2 "s_register_operand" "r")
11703 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
11704 (use (match_dup 2))]
11705 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
11707 arm_const_bounds (operands[0], 0, 16);
11708 arm_const_bounds (operands[1], 0, 8);
11709 arm_const_bounds (operands[3], 0, (1 << 5));
11710 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
11712 [(set_attr "length" "4")
11713 (set_attr "type" "coproc")])
11715 (define_insn "arm_<mrrc>"
11716 [(set (match_operand:DI 0 "s_register_operand" "=r")
11717 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
11718 (match_operand:SI 2 "immediate_operand" "n")
11719 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
11720 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
11722 arm_const_bounds (operands[1], 0, 16);
11723 arm_const_bounds (operands[2], 0, 8);
11724 arm_const_bounds (operands[3], 0, (1 << 5));
11725 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
11727 [(set_attr "length" "4")
11728 (set_attr "type" "coproc")])
11730 (define_expand "speculation_barrier"
11731 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
11734 /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
11735 have a usable barrier (and probably don't need one in practice).
11736 But to be safe if such code is run on later architectures, call a
11737 helper function in libgcc that will do the thing for the active
11739 if (!(arm_arch7 || arm_arch8))
11741 arm_emit_speculation_barrier_function ();
11747 ;; Generate a hard speculation barrier when we have not enabled speculation
11749 (define_insn "*speculation_barrier_insn"
11750 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
11751 "arm_arch7 || arm_arch8"
11753 [(set_attr "type" "block")
11754 (set_attr "length" "8")]
11757 ;; Vector bits common to IWMMXT and Neon
11758 (include "vec-common.md")
11759 ;; Load the Intel Wireless Multimedia Extension patterns
11760 (include "iwmmxt.md")
11761 ;; Load the VFP co-processor patterns
11763 ;; Thumb-1 patterns
11764 (include "thumb1.md")
11765 ;; Thumb-2 patterns
11766 (include "thumb2.md")
11768 (include "neon.md")
11770 (include "crypto.md")
11771 ;; Synchronization Primitives
11772 (include "sync.md")
11773 ;; Fixed-point patterns
11774 (include "arm-fixed.md")