]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm.md
PR other/16615 [1/5]
[thirdparty/gcc.git] / gcc / config / arm / arm.md
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).
6
7 ;; This file is part of GCC.
8
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.
13
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.
18
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/>.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 \f
26 ;;---------------------------------------------------------------------------
27 ;; Constants
28
29 ;; Register numbers -- All machine registers should be defined here
30 (define_constants
31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (R4_REGNUM 4) ; Fifth CORE register
34 (IP_REGNUM 12) ; Scratch register
35 (SP_REGNUM 13) ; Stack pointer
36 (LR_REGNUM 14) ; Return address register
37 (PC_REGNUM 15) ; Program counter
38 (LAST_ARM_REGNUM 15) ;
39 (CC_REGNUM 100) ; Condition code pseudo register
40 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
41 ]
42 )
43 ;; 3rd operand to select_dominance_cc_mode
44 (define_constants
45 [(DOM_CC_X_AND_Y 0)
46 (DOM_CC_NX_OR_Y 1)
47 (DOM_CC_X_OR_Y 2)
48 ]
49 )
50 ;; conditional compare combination
51 (define_constants
52 [(CMP_CMP 0)
53 (CMN_CMP 1)
54 (CMP_CMN 2)
55 (CMN_CMN 3)
56 (NUM_OF_COND_CMP 4)
57 ]
58 )
59
60 \f
61 ;;---------------------------------------------------------------------------
62 ;; Attributes
63
64 ;; Processor type. This is created automatically from arm-cores.def.
65 (include "arm-tune.md")
66
67 ;; Instruction classification types
68 (include "types.md")
69
70 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
71 ; generating ARM code. This is used to control the length of some insn
72 ; patterns that share the same RTL in both ARM and Thumb code.
73 (define_attr "is_thumb" "yes,no"
74 (const (if_then_else (symbol_ref "TARGET_THUMB")
75 (const_string "yes") (const_string "no"))))
76
77 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
78 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
79
80 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
81 (define_attr "is_thumb1" "yes,no"
82 (const (if_then_else (symbol_ref "TARGET_THUMB1")
83 (const_string "yes") (const_string "no"))))
84
85 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
86 ; The arm_restrict_it flag enables the "short IT" feature which
87 ; restricts IT blocks to a single 16-bit instruction.
88 ; This attribute should only be used on 16-bit Thumb-2 instructions
89 ; which may be predicated (the "predicable" attribute must be set).
90 (define_attr "predicable_short_it" "no,yes" (const_string "no"))
91
92 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
93 ; This attribute should only be used on instructions which may emit
94 ; an IT block in their expansion which is not a short IT.
95 (define_attr "enabled_for_short_it" "no,yes" (const_string "yes"))
96
97 ;; Operand number of an input operand that is shifted. Zero if the
98 ;; given instruction does not shift one of its input operands.
99 (define_attr "shift" "" (const_int 0))
100
101 ;; [For compatibility with AArch64 in pipeline models]
102 ;; Attribute that specifies whether or not the instruction touches fp
103 ;; registers.
104 (define_attr "fp" "no,yes" (const_string "no"))
105
106 ; Floating Point Unit. If we only have floating point emulation, then there
107 ; is no point in scheduling the floating point insns. (Well, for best
108 ; performance we should try and group them together).
109 (define_attr "fpu" "none,vfp"
110 (const (symbol_ref "arm_fpu_attr")))
111
112 ; Predicated means that the insn form is conditionally executed based on a
113 ; predicate. We default to 'no' because no Thumb patterns match this rule
114 ; and not all ARM insns do.
115 (define_attr "predicated" "yes,no" (const_string "no"))
116
117 ; LENGTH of an instruction (in bytes)
118 (define_attr "length" ""
119 (const_int 4))
120
121 ; The architecture which supports the instruction (or alternative).
122 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
123 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
124 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
125 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
126 ; Baseline. This attribute is used to compute attribute "enabled",
127 ; use type "any" to enable an alternative in all cases.
128 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
129 (const_string "any"))
130
131 (define_attr "arch_enabled" "no,yes"
132 (cond [(eq_attr "arch" "any")
133 (const_string "yes")
134
135 (and (eq_attr "arch" "a")
136 (match_test "TARGET_ARM"))
137 (const_string "yes")
138
139 (and (eq_attr "arch" "t")
140 (match_test "TARGET_THUMB"))
141 (const_string "yes")
142
143 (and (eq_attr "arch" "t1")
144 (match_test "TARGET_THUMB1"))
145 (const_string "yes")
146
147 (and (eq_attr "arch" "t2")
148 (match_test "TARGET_THUMB2"))
149 (const_string "yes")
150
151 (and (eq_attr "arch" "32")
152 (match_test "TARGET_32BIT"))
153 (const_string "yes")
154
155 (and (eq_attr "arch" "v6")
156 (match_test "TARGET_32BIT && arm_arch6"))
157 (const_string "yes")
158
159 (and (eq_attr "arch" "nov6")
160 (match_test "TARGET_32BIT && !arm_arch6"))
161 (const_string "yes")
162
163 (and (eq_attr "arch" "v6t2")
164 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
165 (const_string "yes")
166
167 (and (eq_attr "arch" "v8mb")
168 (match_test "TARGET_THUMB1 && arm_arch8"))
169 (const_string "yes")
170
171 (and (eq_attr "arch" "avoid_neon_for_64bits")
172 (match_test "TARGET_NEON")
173 (not (match_test "TARGET_PREFER_NEON_64BITS")))
174 (const_string "yes")
175
176 (and (eq_attr "arch" "neon_for_64bits")
177 (match_test "TARGET_NEON")
178 (match_test "TARGET_PREFER_NEON_64BITS"))
179 (const_string "yes")
180
181 (and (eq_attr "arch" "iwmmxt2")
182 (match_test "TARGET_REALLY_IWMMXT2"))
183 (const_string "yes")
184
185 (and (eq_attr "arch" "armv6_or_vfpv3")
186 (match_test "arm_arch6 || TARGET_VFP3"))
187 (const_string "yes")
188
189 (and (eq_attr "arch" "neon")
190 (match_test "TARGET_NEON"))
191 (const_string "yes")
192 ]
193
194 (const_string "no")))
195
196 (define_attr "opt" "any,speed,size"
197 (const_string "any"))
198
199 (define_attr "opt_enabled" "no,yes"
200 (cond [(eq_attr "opt" "any")
201 (const_string "yes")
202
203 (and (eq_attr "opt" "speed")
204 (match_test "optimize_function_for_speed_p (cfun)"))
205 (const_string "yes")
206
207 (and (eq_attr "opt" "size")
208 (match_test "optimize_function_for_size_p (cfun)"))
209 (const_string "yes")]
210 (const_string "no")))
211
212 (define_attr "use_literal_pool" "no,yes"
213 (cond [(and (eq_attr "type" "f_loads,f_loadd")
214 (match_test "CONSTANT_P (operands[1])"))
215 (const_string "yes")]
216 (const_string "no")))
217
218 ; Enable all alternatives that are both arch_enabled and insn_enabled.
219 ; FIXME:: opt_enabled has been temporarily removed till the time we have
220 ; an attribute that allows the use of such alternatives.
221 ; This depends on caching of speed_p, size_p on a per
222 ; alternative basis. The problem is that the enabled attribute
223 ; cannot depend on any state that is not cached or is not constant
224 ; for a compilation unit. We probably need a generic "hot/cold"
225 ; alternative which if implemented can help with this. We disable this
226 ; until such a time as this is implemented and / or the improvements or
227 ; regressions with removing this attribute are double checked.
228 ; See ashldi3_neon and <shift>di3_neon in neon.md.
229
230 (define_attr "enabled" "no,yes"
231 (cond [(and (eq_attr "predicable_short_it" "no")
232 (and (eq_attr "predicated" "yes")
233 (match_test "arm_restrict_it")))
234 (const_string "no")
235
236 (and (eq_attr "enabled_for_short_it" "no")
237 (match_test "arm_restrict_it"))
238 (const_string "no")
239
240 (eq_attr "arch_enabled" "no")
241 (const_string "no")]
242 (const_string "yes")))
243
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed. If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address. It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
256
257 (define_attr "pool_range" ""
258 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259 (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262 (attr "arm_neg_pool_range")))
263
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268 [(set_attr "conds" "clob")
269 (set_attr "length" "4")
270 (set_attr "pool_range" "250")])
271
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
275
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions. It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
279 ;
280 ; USE means that the condition codes are used by the insn in the process of
281 ; outputting code, this means (at present) that we can't use the insn in
282 ; inlined branches
283 ;
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ; well defined manner.
286 ;
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ; they are altered at all
289 ;
290 ; UNCONDITIONAL means the instruction cannot be conditionally executed and
291 ; that the instruction does not use or alter the condition codes.
292 ;
293 ; NOCOND means that the instruction does not use or alter the condition
294 ; codes but can be converted into a conditionally exectuted instruction.
295
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
297 (if_then_else
298 (ior (eq_attr "is_thumb1" "yes")
299 (eq_attr "type" "call"))
300 (const_string "clob")
301 (if_then_else (eq_attr "is_neon_type" "no")
302 (const_string "nocond")
303 (const_string "unconditional"))))
304
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by
307 ; gen...). We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
310
311 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
312 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
316
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor. Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320 (if_then_else (eq_attr "type"
321 "block,call,load_4")
322 (const_string "yes")
323 (const_string "no")))
324
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328 (if_then_else (eq_attr "type"
329 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345 (const_string "single")
346 (const_string "multi")))
347
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label. Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
351
352
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
356
357 ;;---------------------------------------------------------------------------
358 ;; Unspecs
359
360 (include "unspecs.md")
361
362 ;;---------------------------------------------------------------------------
363 ;; Mode iterators
364
365 (include "iterators.md")
366
367 ;;---------------------------------------------------------------------------
368 ;; Predicates
369
370 (include "predicates.md")
371 (include "constraints.md")
372
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
375
376 (define_attr "tune_cortexr4" "yes,no"
377 (const (if_then_else
378 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
379 (const_string "yes")
380 (const_string "no"))))
381
382 ;; True if the generic scheduling description should be used.
383
384 (define_attr "generic_sched" "yes,no"
385 (const (if_then_else
386 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387 arm926ejs,arm10e,arm1026ejs,arm1136js,\
388 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389 cortexa9,cortexa12,cortexa15,cortexa17,\
390 cortexa53,cortexa57,cortexm4,cortexm7,\
391 exynosm1,marvell_pj4,xgene1")
392 (eq_attr "tune_cortexr4" "yes"))
393 (const_string "no")
394 (const_string "yes"))))
395
396 (define_attr "generic_vfp" "yes,no"
397 (const (if_then_else
398 (and (eq_attr "fpu" "vfp")
399 (eq_attr "tune" "!arm10e,cortexa5,cortexa7,\
400 cortexa8,cortexa9,cortexa53,cortexm4,\
401 cortexm7,marvell_pj4,xgene1")
402 (eq_attr "tune_cortexr4" "no"))
403 (const_string "yes")
404 (const_string "no"))))
405
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
412 (include "fa526.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
431 (include "vfp11.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
434
435 \f
436 ;;---------------------------------------------------------------------------
437 ;; Insn patterns
438 ;;
439 ;; Addition insns.
440
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
444
445 (define_expand "adddi3"
446 [(parallel
447 [(set (match_operand:DI 0 "s_register_operand" "")
448 (plus:DI (match_operand:DI 1 "s_register_operand" "")
449 (match_operand:DI 2 "arm_adddi_operand" "")))
450 (clobber (reg:CC CC_REGNUM))])]
451 "TARGET_EITHER"
452 "
453 if (TARGET_THUMB1)
454 {
455 if (!REG_P (operands[1]))
456 operands[1] = force_reg (DImode, operands[1]);
457 if (!REG_P (operands[2]))
458 operands[2] = force_reg (DImode, operands[2]);
459 }
460 "
461 )
462
463 (define_insn_and_split "*arm_adddi3"
464 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r,&r,&r")
465 (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r")
466 (match_operand:DI 2 "arm_general_adddi_operand" "r, 0, r, Dd, Dd")))
467 (clobber (reg:CC CC_REGNUM))]
468 "TARGET_32BIT && !TARGET_NEON"
469 "#"
470 "TARGET_32BIT && ((!TARGET_NEON && !TARGET_IWMMXT) || reload_completed)"
471 [(parallel [(set (reg:CC_C CC_REGNUM)
472 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
473 (match_dup 1)))
474 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
475 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
476 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
477 "
478 {
479 operands[3] = gen_highpart (SImode, operands[0]);
480 operands[0] = gen_lowpart (SImode, operands[0]);
481 operands[4] = gen_highpart (SImode, operands[1]);
482 operands[1] = gen_lowpart (SImode, operands[1]);
483 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
484 operands[2] = gen_lowpart (SImode, operands[2]);
485 }"
486 [(set_attr "conds" "clob")
487 (set_attr "length" "8")
488 (set_attr "type" "multiple")]
489 )
490
491 (define_insn_and_split "*adddi_sesidi_di"
492 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
493 (plus:DI (sign_extend:DI
494 (match_operand:SI 2 "s_register_operand" "r,r"))
495 (match_operand:DI 1 "s_register_operand" "0,r")))
496 (clobber (reg:CC CC_REGNUM))]
497 "TARGET_32BIT"
498 "#"
499 "TARGET_32BIT && reload_completed"
500 [(parallel [(set (reg:CC_C CC_REGNUM)
501 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
502 (match_dup 1)))
503 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
504 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
505 (const_int 31))
506 (match_dup 4))
507 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
508 "
509 {
510 operands[3] = gen_highpart (SImode, operands[0]);
511 operands[0] = gen_lowpart (SImode, operands[0]);
512 operands[4] = gen_highpart (SImode, operands[1]);
513 operands[1] = gen_lowpart (SImode, operands[1]);
514 operands[2] = gen_lowpart (SImode, operands[2]);
515 }"
516 [(set_attr "conds" "clob")
517 (set_attr "length" "8")
518 (set_attr "type" "multiple")]
519 )
520
521 (define_insn_and_split "*adddi_zesidi_di"
522 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
523 (plus:DI (zero_extend:DI
524 (match_operand:SI 2 "s_register_operand" "r,r"))
525 (match_operand:DI 1 "s_register_operand" "0,r")))
526 (clobber (reg:CC CC_REGNUM))]
527 "TARGET_32BIT"
528 "#"
529 "TARGET_32BIT && reload_completed"
530 [(parallel [(set (reg:CC_C CC_REGNUM)
531 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
532 (match_dup 1)))
533 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
534 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
535 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
536 "
537 {
538 operands[3] = gen_highpart (SImode, operands[0]);
539 operands[0] = gen_lowpart (SImode, operands[0]);
540 operands[4] = gen_highpart (SImode, operands[1]);
541 operands[1] = gen_lowpart (SImode, operands[1]);
542 operands[2] = gen_lowpart (SImode, operands[2]);
543 }"
544 [(set_attr "conds" "clob")
545 (set_attr "length" "8")
546 (set_attr "type" "multiple")]
547 )
548
549 (define_expand "addv<mode>4"
550 [(match_operand:SIDI 0 "register_operand")
551 (match_operand:SIDI 1 "register_operand")
552 (match_operand:SIDI 2 "register_operand")
553 (match_operand 3 "")]
554 "TARGET_32BIT"
555 {
556 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
557 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
558
559 DONE;
560 })
561
562 (define_expand "uaddv<mode>4"
563 [(match_operand:SIDI 0 "register_operand")
564 (match_operand:SIDI 1 "register_operand")
565 (match_operand:SIDI 2 "register_operand")
566 (match_operand 3 "")]
567 "TARGET_32BIT"
568 {
569 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
570 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
571
572 DONE;
573 })
574
575 (define_expand "addsi3"
576 [(set (match_operand:SI 0 "s_register_operand" "")
577 (plus:SI (match_operand:SI 1 "s_register_operand" "")
578 (match_operand:SI 2 "reg_or_int_operand" "")))]
579 "TARGET_EITHER"
580 "
581 if (TARGET_32BIT && CONST_INT_P (operands[2]))
582 {
583 arm_split_constant (PLUS, SImode, NULL_RTX,
584 INTVAL (operands[2]), operands[0], operands[1],
585 optimize && can_create_pseudo_p ());
586 DONE;
587 }
588 "
589 )
590
591 ; If there is a scratch available, this will be faster than synthesizing the
592 ; addition.
593 (define_peephole2
594 [(match_scratch:SI 3 "r")
595 (set (match_operand:SI 0 "arm_general_register_operand" "")
596 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
597 (match_operand:SI 2 "const_int_operand" "")))]
598 "TARGET_32BIT &&
599 !(const_ok_for_arm (INTVAL (operands[2]))
600 || const_ok_for_arm (-INTVAL (operands[2])))
601 && const_ok_for_arm (~INTVAL (operands[2]))"
602 [(set (match_dup 3) (match_dup 2))
603 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
604 ""
605 )
606
607 ;; The r/r/k alternative is required when reloading the address
608 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
609 ;; put the duplicated register first, and not try the commutative version.
610 (define_insn_and_split "*arm_addsi3"
611 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
612 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,r ,rk,k ,rk,k,r,rk,k ,rk")
613 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
614 "TARGET_32BIT"
615 "@
616 add%?\\t%0, %0, %2
617 add%?\\t%0, %1, %2
618 add%?\\t%0, %1, %2
619 add%?\\t%0, %1, %2
620 add%?\\t%0, %1, %2
621 add%?\\t%0, %1, %2
622 add%?\\t%0, %2, %1
623 add%?\\t%0, %1, %2
624 addw%?\\t%0, %1, %2
625 addw%?\\t%0, %1, %2
626 sub%?\\t%0, %1, #%n2
627 sub%?\\t%0, %1, #%n2
628 sub%?\\t%0, %1, #%n2
629 subw%?\\t%0, %1, #%n2
630 subw%?\\t%0, %1, #%n2
631 #"
632 "TARGET_32BIT
633 && CONST_INT_P (operands[2])
634 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
635 && (reload_completed || !arm_eliminable_register (operands[1]))"
636 [(clobber (const_int 0))]
637 "
638 arm_split_constant (PLUS, SImode, curr_insn,
639 INTVAL (operands[2]), operands[0],
640 operands[1], 0);
641 DONE;
642 "
643 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
644 (set_attr "predicable" "yes")
645 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
646 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
647 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
648 (const_string "alu_imm")
649 (const_string "alu_sreg")))
650 ]
651 )
652
653 (define_insn_and_split "adddi3_compareV"
654 [(set (reg:CC_V CC_REGNUM)
655 (ne:CC_V
656 (plus:TI
657 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
658 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
659 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
660 (set (match_operand:DI 0 "register_operand" "=&r")
661 (plus:DI (match_dup 1) (match_dup 2)))]
662 "TARGET_32BIT"
663 "#"
664 "&& reload_completed"
665 [(parallel [(set (reg:CC_C CC_REGNUM)
666 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
667 (match_dup 1)))
668 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
669 (parallel [(set (reg:CC_V CC_REGNUM)
670 (ne:CC_V
671 (plus:DI (plus:DI
672 (sign_extend:DI (match_dup 4))
673 (sign_extend:DI (match_dup 5)))
674 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
675 (plus:DI (sign_extend:DI
676 (plus:SI (match_dup 4) (match_dup 5)))
677 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
678 (set (match_dup 3) (plus:SI (plus:SI
679 (match_dup 4) (match_dup 5))
680 (ltu:SI (reg:CC_C CC_REGNUM)
681 (const_int 0))))])]
682 "
683 {
684 operands[3] = gen_highpart (SImode, operands[0]);
685 operands[0] = gen_lowpart (SImode, operands[0]);
686 operands[4] = gen_highpart (SImode, operands[1]);
687 operands[1] = gen_lowpart (SImode, operands[1]);
688 operands[5] = gen_highpart (SImode, operands[2]);
689 operands[2] = gen_lowpart (SImode, operands[2]);
690 }"
691 [(set_attr "conds" "set")
692 (set_attr "length" "8")
693 (set_attr "type" "multiple")]
694 )
695
696 (define_insn "addsi3_compareV"
697 [(set (reg:CC_V CC_REGNUM)
698 (ne:CC_V
699 (plus:DI
700 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
701 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
702 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
703 (set (match_operand:SI 0 "register_operand" "=r")
704 (plus:SI (match_dup 1) (match_dup 2)))]
705 "TARGET_32BIT"
706 "adds%?\\t%0, %1, %2"
707 [(set_attr "conds" "set")
708 (set_attr "type" "alus_sreg")]
709 )
710
711 (define_insn "*addsi3_compareV_upper"
712 [(set (reg:CC_V CC_REGNUM)
713 (ne:CC_V
714 (plus:DI
715 (plus:DI
716 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
717 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
718 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
719 (plus:DI (sign_extend:DI
720 (plus:SI (match_dup 1) (match_dup 2)))
721 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
722 (set (match_operand:SI 0 "register_operand" "=r")
723 (plus:SI
724 (plus:SI (match_dup 1) (match_dup 2))
725 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
726 "TARGET_32BIT"
727 "adcs%?\\t%0, %1, %2"
728 [(set_attr "conds" "set")
729 (set_attr "type" "adcs_reg")]
730 )
731
732 (define_insn_and_split "adddi3_compareC"
733 [(set (reg:CC_C CC_REGNUM)
734 (ne:CC_C
735 (plus:TI
736 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
737 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
738 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
739 (set (match_operand:DI 0 "register_operand" "=&r")
740 (plus:DI (match_dup 1) (match_dup 2)))]
741 "TARGET_32BIT"
742 "#"
743 "&& reload_completed"
744 [(parallel [(set (reg:CC_C CC_REGNUM)
745 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
746 (match_dup 1)))
747 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
748 (parallel [(set (reg:CC_C CC_REGNUM)
749 (ne:CC_C
750 (plus:DI (plus:DI
751 (zero_extend:DI (match_dup 4))
752 (zero_extend:DI (match_dup 5)))
753 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
754 (plus:DI (zero_extend:DI
755 (plus:SI (match_dup 4) (match_dup 5)))
756 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
757 (set (match_dup 3) (plus:SI
758 (plus:SI (match_dup 4) (match_dup 5))
759 (ltu:SI (reg:CC_C CC_REGNUM)
760 (const_int 0))))])]
761 "
762 {
763 operands[3] = gen_highpart (SImode, operands[0]);
764 operands[0] = gen_lowpart (SImode, operands[0]);
765 operands[4] = gen_highpart (SImode, operands[1]);
766 operands[5] = gen_highpart (SImode, operands[2]);
767 operands[1] = gen_lowpart (SImode, operands[1]);
768 operands[2] = gen_lowpart (SImode, operands[2]);
769 }"
770 [(set_attr "conds" "set")
771 (set_attr "length" "8")
772 (set_attr "type" "multiple")]
773 )
774
775 (define_insn "*addsi3_compareC_upper"
776 [(set (reg:CC_C CC_REGNUM)
777 (ne:CC_C
778 (plus:DI
779 (plus:DI
780 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
781 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
782 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
783 (plus:DI (zero_extend:DI
784 (plus:SI (match_dup 1) (match_dup 2)))
785 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
786 (set (match_operand:SI 0 "register_operand" "=r")
787 (plus:SI
788 (plus:SI (match_dup 1) (match_dup 2))
789 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
790 "TARGET_32BIT"
791 "adcs%?\\t%0, %1, %2"
792 [(set_attr "conds" "set")
793 (set_attr "type" "adcs_reg")]
794 )
795
796 (define_insn "addsi3_compareC"
797 [(set (reg:CC_C CC_REGNUM)
798 (ne:CC_C
799 (plus:DI
800 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
801 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
802 (zero_extend:DI
803 (plus:SI (match_dup 1) (match_dup 2)))))
804 (set (match_operand:SI 0 "register_operand" "=r")
805 (plus:SI (match_dup 1) (match_dup 2)))]
806 "TARGET_32BIT"
807 "adds%?\\t%0, %1, %2"
808 [(set_attr "conds" "set")
809 (set_attr "type" "alus_sreg")]
810 )
811
812 (define_insn "addsi3_compare0"
813 [(set (reg:CC_NOOV CC_REGNUM)
814 (compare:CC_NOOV
815 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
816 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
817 (const_int 0)))
818 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
819 (plus:SI (match_dup 1) (match_dup 2)))]
820 "TARGET_ARM"
821 "@
822 adds%?\\t%0, %1, %2
823 subs%?\\t%0, %1, #%n2
824 adds%?\\t%0, %1, %2"
825 [(set_attr "conds" "set")
826 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
827 )
828
829 (define_insn "*addsi3_compare0_scratch"
830 [(set (reg:CC_NOOV CC_REGNUM)
831 (compare:CC_NOOV
832 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
833 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
834 (const_int 0)))]
835 "TARGET_ARM"
836 "@
837 cmn%?\\t%0, %1
838 cmp%?\\t%0, #%n1
839 cmn%?\\t%0, %1"
840 [(set_attr "conds" "set")
841 (set_attr "predicable" "yes")
842 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
843 )
844
845 (define_insn "*compare_negsi_si"
846 [(set (reg:CC_Z CC_REGNUM)
847 (compare:CC_Z
848 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
849 (match_operand:SI 1 "s_register_operand" "l,r")))]
850 "TARGET_32BIT"
851 "cmn%?\\t%1, %0"
852 [(set_attr "conds" "set")
853 (set_attr "predicable" "yes")
854 (set_attr "arch" "t2,*")
855 (set_attr "length" "2,4")
856 (set_attr "predicable_short_it" "yes,no")
857 (set_attr "type" "alus_sreg")]
858 )
859
860 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
861 ;; addend is a constant.
862 (define_insn "cmpsi2_addneg"
863 [(set (reg:CC CC_REGNUM)
864 (compare:CC
865 (match_operand:SI 1 "s_register_operand" "r,r")
866 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
867 (set (match_operand:SI 0 "s_register_operand" "=r,r")
868 (plus:SI (match_dup 1)
869 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
870 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
871 "@
872 adds%?\\t%0, %1, %3
873 subs%?\\t%0, %1, #%n3"
874 [(set_attr "conds" "set")
875 (set_attr "type" "alus_sreg")]
876 )
877
878 ;; Convert the sequence
879 ;; sub rd, rn, #1
880 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
881 ;; bne dest
882 ;; into
883 ;; subs rd, rn, #1
884 ;; bcs dest ((unsigned)rn >= 1)
885 ;; similarly for the beq variant using bcc.
886 ;; This is a common looping idiom (while (n--))
887 (define_peephole2
888 [(set (match_operand:SI 0 "arm_general_register_operand" "")
889 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
890 (const_int -1)))
891 (set (match_operand 2 "cc_register" "")
892 (compare (match_dup 0) (const_int -1)))
893 (set (pc)
894 (if_then_else (match_operator 3 "equality_operator"
895 [(match_dup 2) (const_int 0)])
896 (match_operand 4 "" "")
897 (match_operand 5 "" "")))]
898 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
899 [(parallel[
900 (set (match_dup 2)
901 (compare:CC
902 (match_dup 1) (const_int 1)))
903 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
904 (set (pc)
905 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
906 (match_dup 4)
907 (match_dup 5)))]
908 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
909 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
910 ? GEU : LTU),
911 VOIDmode,
912 operands[2], const0_rtx);"
913 )
914
915 ;; The next four insns work because they compare the result with one of
916 ;; the operands, and we know that the use of the condition code is
917 ;; either GEU or LTU, so we can use the carry flag from the addition
918 ;; instead of doing the compare a second time.
919 (define_insn "*addsi3_compare_op1"
920 [(set (reg:CC_C CC_REGNUM)
921 (compare:CC_C
922 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
923 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
924 (match_dup 1)))
925 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
926 (plus:SI (match_dup 1) (match_dup 2)))]
927 "TARGET_32BIT"
928 "@
929 adds%?\\t%0, %1, %2
930 subs%?\\t%0, %1, #%n2
931 adds%?\\t%0, %1, %2"
932 [(set_attr "conds" "set")
933 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
934 )
935
936 (define_insn "*addsi3_compare_op2"
937 [(set (reg:CC_C CC_REGNUM)
938 (compare:CC_C
939 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
940 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
941 (match_dup 2)))
942 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
943 (plus:SI (match_dup 1) (match_dup 2)))]
944 "TARGET_32BIT"
945 "@
946 adds%?\\t%0, %1, %2
947 subs%?\\t%0, %1, #%n2
948 adds%?\\t%0, %1, %2"
949 [(set_attr "conds" "set")
950 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
951 )
952
953 (define_insn "*compare_addsi2_op0"
954 [(set (reg:CC_C CC_REGNUM)
955 (compare:CC_C
956 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
957 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
958 (match_dup 0)))]
959 "TARGET_32BIT"
960 "@
961 cmp%?\\t%0, #%n1
962 cmn%?\\t%0, %1
963 cmn%?\\t%0, %1
964 cmp%?\\t%0, #%n1
965 cmn%?\\t%0, %1"
966 [(set_attr "conds" "set")
967 (set_attr "predicable" "yes")
968 (set_attr "arch" "t2,t2,*,*,*")
969 (set_attr "predicable_short_it" "yes,yes,no,no,no")
970 (set_attr "length" "2,2,4,4,4")
971 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
972 )
973
974 (define_insn "*compare_addsi2_op1"
975 [(set (reg:CC_C CC_REGNUM)
976 (compare:CC_C
977 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
978 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
979 (match_dup 1)))]
980 "TARGET_32BIT"
981 "@
982 cmp%?\\t%0, #%n1
983 cmn%?\\t%0, %1
984 cmn%?\\t%0, %1
985 cmp%?\\t%0, #%n1
986 cmn%?\\t%0, %1"
987 [(set_attr "conds" "set")
988 (set_attr "predicable" "yes")
989 (set_attr "arch" "t2,t2,*,*,*")
990 (set_attr "predicable_short_it" "yes,yes,no,no,no")
991 (set_attr "length" "2,2,4,4,4")
992 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
993 )
994
995 (define_insn "*addsi3_carryin_<optab>"
996 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
997 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
998 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
999 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1000 "TARGET_32BIT"
1001 "@
1002 adc%?\\t%0, %1, %2
1003 adc%?\\t%0, %1, %2
1004 sbc%?\\t%0, %1, #%B2"
1005 [(set_attr "conds" "use")
1006 (set_attr "predicable" "yes")
1007 (set_attr "arch" "t2,*,*")
1008 (set_attr "length" "4")
1009 (set_attr "predicable_short_it" "yes,no,no")
1010 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1011 )
1012
1013 (define_insn "*addsi3_carryin_alt2_<optab>"
1014 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1015 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1016 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1017 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1018 "TARGET_32BIT"
1019 "@
1020 adc%?\\t%0, %1, %2
1021 adc%?\\t%0, %1, %2
1022 sbc%?\\t%0, %1, #%B2"
1023 [(set_attr "conds" "use")
1024 (set_attr "predicable" "yes")
1025 (set_attr "arch" "t2,*,*")
1026 (set_attr "length" "4")
1027 (set_attr "predicable_short_it" "yes,no,no")
1028 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1029 )
1030
1031 (define_insn "*addsi3_carryin_shift_<optab>"
1032 [(set (match_operand:SI 0 "s_register_operand" "=r")
1033 (plus:SI (plus:SI
1034 (match_operator:SI 2 "shift_operator"
1035 [(match_operand:SI 3 "s_register_operand" "r")
1036 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1037 (match_operand:SI 1 "s_register_operand" "r"))
1038 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1039 "TARGET_32BIT"
1040 "adc%?\\t%0, %1, %3%S2"
1041 [(set_attr "conds" "use")
1042 (set_attr "predicable" "yes")
1043 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1044 (const_string "alu_shift_imm")
1045 (const_string "alu_shift_reg")))]
1046 )
1047
1048 (define_insn "*addsi3_carryin_clobercc_<optab>"
1049 [(set (match_operand:SI 0 "s_register_operand" "=r")
1050 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1051 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1052 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1053 (clobber (reg:CC CC_REGNUM))]
1054 "TARGET_32BIT"
1055 "adcs%?\\t%0, %1, %2"
1056 [(set_attr "conds" "set")
1057 (set_attr "type" "adcs_reg")]
1058 )
1059
1060 (define_expand "subv<mode>4"
1061 [(match_operand:SIDI 0 "register_operand")
1062 (match_operand:SIDI 1 "register_operand")
1063 (match_operand:SIDI 2 "register_operand")
1064 (match_operand 3 "")]
1065 "TARGET_32BIT"
1066 {
1067 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1068 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1069
1070 DONE;
1071 })
1072
1073 (define_expand "usubv<mode>4"
1074 [(match_operand:SIDI 0 "register_operand")
1075 (match_operand:SIDI 1 "register_operand")
1076 (match_operand:SIDI 2 "register_operand")
1077 (match_operand 3 "")]
1078 "TARGET_32BIT"
1079 {
1080 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1081 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1082
1083 DONE;
1084 })
1085
1086 (define_insn_and_split "subdi3_compare1"
1087 [(set (reg:CC CC_REGNUM)
1088 (compare:CC
1089 (match_operand:DI 1 "register_operand" "r")
1090 (match_operand:DI 2 "register_operand" "r")))
1091 (set (match_operand:DI 0 "register_operand" "=&r")
1092 (minus:DI (match_dup 1) (match_dup 2)))]
1093 "TARGET_32BIT"
1094 "#"
1095 "&& reload_completed"
1096 [(parallel [(set (reg:CC CC_REGNUM)
1097 (compare:CC (match_dup 1) (match_dup 2)))
1098 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1099 (parallel [(set (reg:CC CC_REGNUM)
1100 (compare:CC (match_dup 4) (match_dup 5)))
1101 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1102 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1103 {
1104 operands[3] = gen_highpart (SImode, operands[0]);
1105 operands[0] = gen_lowpart (SImode, operands[0]);
1106 operands[4] = gen_highpart (SImode, operands[1]);
1107 operands[1] = gen_lowpart (SImode, operands[1]);
1108 operands[5] = gen_highpart (SImode, operands[2]);
1109 operands[2] = gen_lowpart (SImode, operands[2]);
1110 }
1111 [(set_attr "conds" "set")
1112 (set_attr "length" "8")
1113 (set_attr "type" "multiple")]
1114 )
1115
1116 (define_insn "subsi3_compare1"
1117 [(set (reg:CC CC_REGNUM)
1118 (compare:CC
1119 (match_operand:SI 1 "register_operand" "r")
1120 (match_operand:SI 2 "register_operand" "r")))
1121 (set (match_operand:SI 0 "register_operand" "=r")
1122 (minus:SI (match_dup 1) (match_dup 2)))]
1123 "TARGET_32BIT"
1124 "subs%?\\t%0, %1, %2"
1125 [(set_attr "conds" "set")
1126 (set_attr "type" "alus_sreg")]
1127 )
1128
1129 (define_insn "*subsi3_carryin"
1130 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1131 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1132 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1133 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1134 "TARGET_32BIT"
1135 "@
1136 sbc%?\\t%0, %1, %2
1137 rsc%?\\t%0, %2, %1
1138 sbc%?\\t%0, %2, %2, lsl #1"
1139 [(set_attr "conds" "use")
1140 (set_attr "arch" "*,a,t2")
1141 (set_attr "predicable" "yes")
1142 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1143 )
1144
1145 (define_insn "*subsi3_carryin_const"
1146 [(set (match_operand:SI 0 "s_register_operand" "=r")
1147 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1148 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1149 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1150 "TARGET_32BIT"
1151 "sbc\\t%0, %1, #%B2"
1152 [(set_attr "conds" "use")
1153 (set_attr "type" "adc_imm")]
1154 )
1155
1156 (define_insn "*subsi3_carryin_compare"
1157 [(set (reg:CC CC_REGNUM)
1158 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1159 (match_operand:SI 2 "s_register_operand" "r")))
1160 (set (match_operand:SI 0 "s_register_operand" "=r")
1161 (minus:SI (minus:SI (match_dup 1)
1162 (match_dup 2))
1163 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1164 "TARGET_32BIT"
1165 "sbcs\\t%0, %1, %2"
1166 [(set_attr "conds" "set")
1167 (set_attr "type" "adcs_reg")]
1168 )
1169
1170 (define_insn "*subsi3_carryin_compare_const"
1171 [(set (reg:CC CC_REGNUM)
1172 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1173 (match_operand:SI 2 "arm_not_operand" "K")))
1174 (set (match_operand:SI 0 "s_register_operand" "=r")
1175 (minus:SI (plus:SI (match_dup 1)
1176 (match_dup 2))
1177 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1178 "TARGET_32BIT"
1179 "sbcs\\t%0, %1, #%B2"
1180 [(set_attr "conds" "set")
1181 (set_attr "type" "adcs_imm")]
1182 )
1183
1184 (define_insn "*subsi3_carryin_shift"
1185 [(set (match_operand:SI 0 "s_register_operand" "=r")
1186 (minus:SI (minus:SI
1187 (match_operand:SI 1 "s_register_operand" "r")
1188 (match_operator:SI 2 "shift_operator"
1189 [(match_operand:SI 3 "s_register_operand" "r")
1190 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1191 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1192 "TARGET_32BIT"
1193 "sbc%?\\t%0, %1, %3%S2"
1194 [(set_attr "conds" "use")
1195 (set_attr "predicable" "yes")
1196 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1197 (const_string "alu_shift_imm")
1198 (const_string "alu_shift_reg")))]
1199 )
1200
1201 (define_insn "*rsbsi3_carryin_shift"
1202 [(set (match_operand:SI 0 "s_register_operand" "=r")
1203 (minus:SI (minus:SI
1204 (match_operator:SI 2 "shift_operator"
1205 [(match_operand:SI 3 "s_register_operand" "r")
1206 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1207 (match_operand:SI 1 "s_register_operand" "r"))
1208 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1209 "TARGET_ARM"
1210 "rsc%?\\t%0, %1, %3%S2"
1211 [(set_attr "conds" "use")
1212 (set_attr "predicable" "yes")
1213 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1214 (const_string "alu_shift_imm")
1215 (const_string "alu_shift_reg")))]
1216 )
1217
1218 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1219 (define_split
1220 [(set (match_operand:SI 0 "s_register_operand" "")
1221 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1222 (match_operand:SI 2 "s_register_operand" ""))
1223 (const_int -1)))
1224 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1225 "TARGET_32BIT"
1226 [(set (match_dup 3) (match_dup 1))
1227 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1228 "
1229 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1230 ")
1231
1232 (define_expand "addsf3"
1233 [(set (match_operand:SF 0 "s_register_operand" "")
1234 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1235 (match_operand:SF 2 "s_register_operand" "")))]
1236 "TARGET_32BIT && TARGET_HARD_FLOAT"
1237 "
1238 ")
1239
1240 (define_expand "adddf3"
1241 [(set (match_operand:DF 0 "s_register_operand" "")
1242 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1243 (match_operand:DF 2 "s_register_operand" "")))]
1244 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1245 "
1246 ")
1247
1248 (define_expand "subdi3"
1249 [(parallel
1250 [(set (match_operand:DI 0 "s_register_operand" "")
1251 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1252 (match_operand:DI 2 "s_register_operand" "")))
1253 (clobber (reg:CC CC_REGNUM))])]
1254 "TARGET_EITHER"
1255 "
1256 if (TARGET_THUMB1)
1257 {
1258 if (!REG_P (operands[1]))
1259 operands[1] = force_reg (DImode, operands[1]);
1260 if (!REG_P (operands[2]))
1261 operands[2] = force_reg (DImode, operands[2]);
1262 }
1263 "
1264 )
1265
1266 (define_insn_and_split "*arm_subdi3"
1267 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
1268 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1269 (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1270 (clobber (reg:CC CC_REGNUM))]
1271 "TARGET_32BIT && !TARGET_NEON"
1272 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1273 "&& (!TARGET_IWMMXT || reload_completed)"
1274 [(parallel [(set (reg:CC CC_REGNUM)
1275 (compare:CC (match_dup 1) (match_dup 2)))
1276 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1277 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1278 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1279 {
1280 operands[3] = gen_highpart (SImode, operands[0]);
1281 operands[0] = gen_lowpart (SImode, operands[0]);
1282 operands[4] = gen_highpart (SImode, operands[1]);
1283 operands[1] = gen_lowpart (SImode, operands[1]);
1284 operands[5] = gen_highpart (SImode, operands[2]);
1285 operands[2] = gen_lowpart (SImode, operands[2]);
1286 }
1287 [(set_attr "conds" "clob")
1288 (set_attr "length" "8")
1289 (set_attr "type" "multiple")]
1290 )
1291
1292 (define_insn_and_split "*subdi_di_zesidi"
1293 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1294 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1295 (zero_extend:DI
1296 (match_operand:SI 2 "s_register_operand" "r,r"))))
1297 (clobber (reg:CC CC_REGNUM))]
1298 "TARGET_32BIT"
1299 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1300 "&& reload_completed"
1301 [(parallel [(set (reg:CC CC_REGNUM)
1302 (compare:CC (match_dup 1) (match_dup 2)))
1303 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1304 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1305 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1306 {
1307 operands[3] = gen_highpart (SImode, operands[0]);
1308 operands[0] = gen_lowpart (SImode, operands[0]);
1309 operands[4] = gen_highpart (SImode, operands[1]);
1310 operands[1] = gen_lowpart (SImode, operands[1]);
1311 operands[5] = GEN_INT (~0);
1312 }
1313 [(set_attr "conds" "clob")
1314 (set_attr "length" "8")
1315 (set_attr "type" "multiple")]
1316 )
1317
1318 (define_insn_and_split "*subdi_di_sesidi"
1319 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1320 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1321 (sign_extend:DI
1322 (match_operand:SI 2 "s_register_operand" "r,r"))))
1323 (clobber (reg:CC CC_REGNUM))]
1324 "TARGET_32BIT"
1325 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1326 "&& reload_completed"
1327 [(parallel [(set (reg:CC CC_REGNUM)
1328 (compare:CC (match_dup 1) (match_dup 2)))
1329 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1330 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1331 (ashiftrt:SI (match_dup 2)
1332 (const_int 31)))
1333 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1334 {
1335 operands[3] = gen_highpart (SImode, operands[0]);
1336 operands[0] = gen_lowpart (SImode, operands[0]);
1337 operands[4] = gen_highpart (SImode, operands[1]);
1338 operands[1] = gen_lowpart (SImode, operands[1]);
1339 }
1340 [(set_attr "conds" "clob")
1341 (set_attr "length" "8")
1342 (set_attr "type" "multiple")]
1343 )
1344
1345 (define_insn_and_split "*subdi_zesidi_di"
1346 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1347 (minus:DI (zero_extend:DI
1348 (match_operand:SI 2 "s_register_operand" "r,r"))
1349 (match_operand:DI 1 "s_register_operand" "0,r")))
1350 (clobber (reg:CC CC_REGNUM))]
1351 "TARGET_ARM"
1352 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1353 ; is equivalent to:
1354 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1355 "&& reload_completed"
1356 [(parallel [(set (reg:CC CC_REGNUM)
1357 (compare:CC (match_dup 2) (match_dup 1)))
1358 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1359 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1360 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1361 {
1362 operands[3] = gen_highpart (SImode, operands[0]);
1363 operands[0] = gen_lowpart (SImode, operands[0]);
1364 operands[4] = gen_highpart (SImode, operands[1]);
1365 operands[1] = gen_lowpart (SImode, operands[1]);
1366 }
1367 [(set_attr "conds" "clob")
1368 (set_attr "length" "8")
1369 (set_attr "type" "multiple")]
1370 )
1371
1372 (define_insn_and_split "*subdi_sesidi_di"
1373 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1374 (minus:DI (sign_extend:DI
1375 (match_operand:SI 2 "s_register_operand" "r,r"))
1376 (match_operand:DI 1 "s_register_operand" "0,r")))
1377 (clobber (reg:CC CC_REGNUM))]
1378 "TARGET_ARM"
1379 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1380 ; is equivalent to:
1381 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1382 "&& reload_completed"
1383 [(parallel [(set (reg:CC CC_REGNUM)
1384 (compare:CC (match_dup 2) (match_dup 1)))
1385 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1386 (set (match_dup 3) (minus:SI (minus:SI
1387 (ashiftrt:SI (match_dup 2)
1388 (const_int 31))
1389 (match_dup 4))
1390 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1391 {
1392 operands[3] = gen_highpart (SImode, operands[0]);
1393 operands[0] = gen_lowpart (SImode, operands[0]);
1394 operands[4] = gen_highpart (SImode, operands[1]);
1395 operands[1] = gen_lowpart (SImode, operands[1]);
1396 }
1397 [(set_attr "conds" "clob")
1398 (set_attr "length" "8")
1399 (set_attr "type" "multiple")]
1400 )
1401
1402 (define_insn_and_split "*subdi_zesidi_zesidi"
1403 [(set (match_operand:DI 0 "s_register_operand" "=r")
1404 (minus:DI (zero_extend:DI
1405 (match_operand:SI 1 "s_register_operand" "r"))
1406 (zero_extend:DI
1407 (match_operand:SI 2 "s_register_operand" "r"))))
1408 (clobber (reg:CC CC_REGNUM))]
1409 "TARGET_32BIT"
1410 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1411 "&& reload_completed"
1412 [(parallel [(set (reg:CC CC_REGNUM)
1413 (compare:CC (match_dup 1) (match_dup 2)))
1414 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1415 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1416 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1417 {
1418 operands[3] = gen_highpart (SImode, operands[0]);
1419 operands[0] = gen_lowpart (SImode, operands[0]);
1420 }
1421 [(set_attr "conds" "clob")
1422 (set_attr "length" "8")
1423 (set_attr "type" "multiple")]
1424 )
1425
1426 (define_expand "subsi3"
1427 [(set (match_operand:SI 0 "s_register_operand" "")
1428 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1429 (match_operand:SI 2 "s_register_operand" "")))]
1430 "TARGET_EITHER"
1431 "
1432 if (CONST_INT_P (operands[1]))
1433 {
1434 if (TARGET_32BIT)
1435 {
1436 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1437 operands[1] = force_reg (SImode, operands[1]);
1438 else
1439 {
1440 arm_split_constant (MINUS, SImode, NULL_RTX,
1441 INTVAL (operands[1]), operands[0],
1442 operands[2],
1443 optimize && can_create_pseudo_p ());
1444 DONE;
1445 }
1446 }
1447 else /* TARGET_THUMB1 */
1448 operands[1] = force_reg (SImode, operands[1]);
1449 }
1450 "
1451 )
1452
1453 ; ??? Check Thumb-2 split length
1454 (define_insn_and_split "*arm_subsi3_insn"
1455 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1456 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1457 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1458 "TARGET_32BIT"
1459 "@
1460 sub%?\\t%0, %1, %2
1461 sub%?\\t%0, %2
1462 sub%?\\t%0, %1, %2
1463 rsb%?\\t%0, %2, %1
1464 rsb%?\\t%0, %2, %1
1465 sub%?\\t%0, %1, %2
1466 sub%?\\t%0, %1, %2
1467 sub%?\\t%0, %1, %2
1468 #"
1469 "&& (CONST_INT_P (operands[1])
1470 && !const_ok_for_arm (INTVAL (operands[1])))"
1471 [(clobber (const_int 0))]
1472 "
1473 arm_split_constant (MINUS, SImode, curr_insn,
1474 INTVAL (operands[1]), operands[0], operands[2], 0);
1475 DONE;
1476 "
1477 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1478 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1479 (set_attr "predicable" "yes")
1480 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1481 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1482 )
1483
1484 (define_peephole2
1485 [(match_scratch:SI 3 "r")
1486 (set (match_operand:SI 0 "arm_general_register_operand" "")
1487 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1488 (match_operand:SI 2 "arm_general_register_operand" "")))]
1489 "TARGET_32BIT
1490 && !const_ok_for_arm (INTVAL (operands[1]))
1491 && const_ok_for_arm (~INTVAL (operands[1]))"
1492 [(set (match_dup 3) (match_dup 1))
1493 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1494 ""
1495 )
1496
1497 (define_insn "subsi3_compare0"
1498 [(set (reg:CC_NOOV CC_REGNUM)
1499 (compare:CC_NOOV
1500 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1501 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1502 (const_int 0)))
1503 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1504 (minus:SI (match_dup 1) (match_dup 2)))]
1505 "TARGET_32BIT"
1506 "@
1507 subs%?\\t%0, %1, %2
1508 subs%?\\t%0, %1, %2
1509 rsbs%?\\t%0, %2, %1"
1510 [(set_attr "conds" "set")
1511 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1512 )
1513
1514 (define_insn "subsi3_compare"
1515 [(set (reg:CC CC_REGNUM)
1516 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1517 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1518 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1519 (minus:SI (match_dup 1) (match_dup 2)))]
1520 "TARGET_32BIT"
1521 "@
1522 subs%?\\t%0, %1, %2
1523 subs%?\\t%0, %1, %2
1524 rsbs%?\\t%0, %2, %1"
1525 [(set_attr "conds" "set")
1526 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1527 )
1528
1529 (define_expand "subsf3"
1530 [(set (match_operand:SF 0 "s_register_operand" "")
1531 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1532 (match_operand:SF 2 "s_register_operand" "")))]
1533 "TARGET_32BIT && TARGET_HARD_FLOAT"
1534 "
1535 ")
1536
1537 (define_expand "subdf3"
1538 [(set (match_operand:DF 0 "s_register_operand" "")
1539 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1540 (match_operand:DF 2 "s_register_operand" "")))]
1541 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1542 "
1543 ")
1544
1545 \f
1546 ;; Multiplication insns
1547
1548 (define_expand "mulhi3"
1549 [(set (match_operand:HI 0 "s_register_operand" "")
1550 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1551 (match_operand:HI 2 "s_register_operand" "")))]
1552 "TARGET_DSP_MULTIPLY"
1553 "
1554 {
1555 rtx result = gen_reg_rtx (SImode);
1556 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1557 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1558 DONE;
1559 }"
1560 )
1561
1562 (define_expand "mulsi3"
1563 [(set (match_operand:SI 0 "s_register_operand" "")
1564 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1565 (match_operand:SI 1 "s_register_operand" "")))]
1566 "TARGET_EITHER"
1567 ""
1568 )
1569
1570 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1571 (define_insn "*arm_mulsi3"
1572 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1573 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1574 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1575 "TARGET_32BIT && !arm_arch6"
1576 "mul%?\\t%0, %2, %1"
1577 [(set_attr "type" "mul")
1578 (set_attr "predicable" "yes")]
1579 )
1580
1581 (define_insn "*arm_mulsi3_v6"
1582 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1583 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1584 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1585 "TARGET_32BIT && arm_arch6"
1586 "mul%?\\t%0, %1, %2"
1587 [(set_attr "type" "mul")
1588 (set_attr "predicable" "yes")
1589 (set_attr "arch" "t2,t2,*")
1590 (set_attr "length" "4")
1591 (set_attr "predicable_short_it" "yes,yes,no")]
1592 )
1593
1594 (define_insn "*mulsi3_compare0"
1595 [(set (reg:CC_NOOV CC_REGNUM)
1596 (compare:CC_NOOV (mult:SI
1597 (match_operand:SI 2 "s_register_operand" "r,r")
1598 (match_operand:SI 1 "s_register_operand" "%0,r"))
1599 (const_int 0)))
1600 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1601 (mult:SI (match_dup 2) (match_dup 1)))]
1602 "TARGET_ARM && !arm_arch6"
1603 "muls%?\\t%0, %2, %1"
1604 [(set_attr "conds" "set")
1605 (set_attr "type" "muls")]
1606 )
1607
1608 (define_insn "*mulsi3_compare0_v6"
1609 [(set (reg:CC_NOOV CC_REGNUM)
1610 (compare:CC_NOOV (mult:SI
1611 (match_operand:SI 2 "s_register_operand" "r")
1612 (match_operand:SI 1 "s_register_operand" "r"))
1613 (const_int 0)))
1614 (set (match_operand:SI 0 "s_register_operand" "=r")
1615 (mult:SI (match_dup 2) (match_dup 1)))]
1616 "TARGET_ARM && arm_arch6 && optimize_size"
1617 "muls%?\\t%0, %2, %1"
1618 [(set_attr "conds" "set")
1619 (set_attr "type" "muls")]
1620 )
1621
1622 (define_insn "*mulsi_compare0_scratch"
1623 [(set (reg:CC_NOOV CC_REGNUM)
1624 (compare:CC_NOOV (mult:SI
1625 (match_operand:SI 2 "s_register_operand" "r,r")
1626 (match_operand:SI 1 "s_register_operand" "%0,r"))
1627 (const_int 0)))
1628 (clobber (match_scratch:SI 0 "=&r,&r"))]
1629 "TARGET_ARM && !arm_arch6"
1630 "muls%?\\t%0, %2, %1"
1631 [(set_attr "conds" "set")
1632 (set_attr "type" "muls")]
1633 )
1634
1635 (define_insn "*mulsi_compare0_scratch_v6"
1636 [(set (reg:CC_NOOV CC_REGNUM)
1637 (compare:CC_NOOV (mult:SI
1638 (match_operand:SI 2 "s_register_operand" "r")
1639 (match_operand:SI 1 "s_register_operand" "r"))
1640 (const_int 0)))
1641 (clobber (match_scratch:SI 0 "=r"))]
1642 "TARGET_ARM && arm_arch6 && optimize_size"
1643 "muls%?\\t%0, %2, %1"
1644 [(set_attr "conds" "set")
1645 (set_attr "type" "muls")]
1646 )
1647
1648 ;; Unnamed templates to match MLA instruction.
1649
1650 (define_insn "*mulsi3addsi"
1651 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1652 (plus:SI
1653 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1654 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1655 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1656 "TARGET_32BIT && !arm_arch6"
1657 "mla%?\\t%0, %2, %1, %3"
1658 [(set_attr "type" "mla")
1659 (set_attr "predicable" "yes")]
1660 )
1661
1662 (define_insn "*mulsi3addsi_v6"
1663 [(set (match_operand:SI 0 "s_register_operand" "=r")
1664 (plus:SI
1665 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1666 (match_operand:SI 1 "s_register_operand" "r"))
1667 (match_operand:SI 3 "s_register_operand" "r")))]
1668 "TARGET_32BIT && arm_arch6"
1669 "mla%?\\t%0, %2, %1, %3"
1670 [(set_attr "type" "mla")
1671 (set_attr "predicable" "yes")]
1672 )
1673
1674 (define_insn "*mulsi3addsi_compare0"
1675 [(set (reg:CC_NOOV CC_REGNUM)
1676 (compare:CC_NOOV
1677 (plus:SI (mult:SI
1678 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1679 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1680 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1681 (const_int 0)))
1682 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1683 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1684 (match_dup 3)))]
1685 "TARGET_ARM && arm_arch6"
1686 "mlas%?\\t%0, %2, %1, %3"
1687 [(set_attr "conds" "set")
1688 (set_attr "type" "mlas")]
1689 )
1690
1691 (define_insn "*mulsi3addsi_compare0_v6"
1692 [(set (reg:CC_NOOV CC_REGNUM)
1693 (compare:CC_NOOV
1694 (plus:SI (mult:SI
1695 (match_operand:SI 2 "s_register_operand" "r")
1696 (match_operand:SI 1 "s_register_operand" "r"))
1697 (match_operand:SI 3 "s_register_operand" "r"))
1698 (const_int 0)))
1699 (set (match_operand:SI 0 "s_register_operand" "=r")
1700 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1701 (match_dup 3)))]
1702 "TARGET_ARM && arm_arch6 && optimize_size"
1703 "mlas%?\\t%0, %2, %1, %3"
1704 [(set_attr "conds" "set")
1705 (set_attr "type" "mlas")]
1706 )
1707
1708 (define_insn "*mulsi3addsi_compare0_scratch"
1709 [(set (reg:CC_NOOV CC_REGNUM)
1710 (compare:CC_NOOV
1711 (plus:SI (mult:SI
1712 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1713 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1714 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1715 (const_int 0)))
1716 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1717 "TARGET_ARM && !arm_arch6"
1718 "mlas%?\\t%0, %2, %1, %3"
1719 [(set_attr "conds" "set")
1720 (set_attr "type" "mlas")]
1721 )
1722
1723 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1724 [(set (reg:CC_NOOV CC_REGNUM)
1725 (compare:CC_NOOV
1726 (plus:SI (mult:SI
1727 (match_operand:SI 2 "s_register_operand" "r")
1728 (match_operand:SI 1 "s_register_operand" "r"))
1729 (match_operand:SI 3 "s_register_operand" "r"))
1730 (const_int 0)))
1731 (clobber (match_scratch:SI 0 "=r"))]
1732 "TARGET_ARM && arm_arch6 && optimize_size"
1733 "mlas%?\\t%0, %2, %1, %3"
1734 [(set_attr "conds" "set")
1735 (set_attr "type" "mlas")]
1736 )
1737
1738 (define_insn "*mulsi3subsi"
1739 [(set (match_operand:SI 0 "s_register_operand" "=r")
1740 (minus:SI
1741 (match_operand:SI 3 "s_register_operand" "r")
1742 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1743 (match_operand:SI 1 "s_register_operand" "r"))))]
1744 "TARGET_32BIT && arm_arch_thumb2"
1745 "mls%?\\t%0, %2, %1, %3"
1746 [(set_attr "type" "mla")
1747 (set_attr "predicable" "yes")]
1748 )
1749
1750 (define_expand "maddsidi4"
1751 [(set (match_operand:DI 0 "s_register_operand" "")
1752 (plus:DI
1753 (mult:DI
1754 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1755 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1756 (match_operand:DI 3 "s_register_operand" "")))]
1757 "TARGET_32BIT"
1758 "")
1759
1760 (define_insn "*mulsidi3adddi"
1761 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1762 (plus:DI
1763 (mult:DI
1764 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1765 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1766 (match_operand:DI 1 "s_register_operand" "0")))]
1767 "TARGET_32BIT && !arm_arch6"
1768 "smlal%?\\t%Q0, %R0, %3, %2"
1769 [(set_attr "type" "smlal")
1770 (set_attr "predicable" "yes")]
1771 )
1772
1773 (define_insn "*mulsidi3adddi_v6"
1774 [(set (match_operand:DI 0 "s_register_operand" "=r")
1775 (plus:DI
1776 (mult:DI
1777 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1778 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1779 (match_operand:DI 1 "s_register_operand" "0")))]
1780 "TARGET_32BIT && arm_arch6"
1781 "smlal%?\\t%Q0, %R0, %3, %2"
1782 [(set_attr "type" "smlal")
1783 (set_attr "predicable" "yes")]
1784 )
1785
1786 ;; 32x32->64 widening multiply.
1787 ;; As with mulsi3, the only difference between the v3-5 and v6+
1788 ;; versions of these patterns is the requirement that the output not
1789 ;; overlap the inputs, but that still means we have to have a named
1790 ;; expander and two different starred insns.
1791
1792 (define_expand "mulsidi3"
1793 [(set (match_operand:DI 0 "s_register_operand" "")
1794 (mult:DI
1795 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1796 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1797 "TARGET_32BIT"
1798 ""
1799 )
1800
1801 (define_insn "*mulsidi3_nov6"
1802 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1803 (mult:DI
1804 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1805 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1806 "TARGET_32BIT && !arm_arch6"
1807 "smull%?\\t%Q0, %R0, %1, %2"
1808 [(set_attr "type" "smull")
1809 (set_attr "predicable" "yes")]
1810 )
1811
1812 (define_insn "*mulsidi3_v6"
1813 [(set (match_operand:DI 0 "s_register_operand" "=r")
1814 (mult:DI
1815 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1816 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1817 "TARGET_32BIT && arm_arch6"
1818 "smull%?\\t%Q0, %R0, %1, %2"
1819 [(set_attr "type" "smull")
1820 (set_attr "predicable" "yes")]
1821 )
1822
1823 (define_expand "umulsidi3"
1824 [(set (match_operand:DI 0 "s_register_operand" "")
1825 (mult:DI
1826 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1827 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1828 "TARGET_32BIT"
1829 ""
1830 )
1831
1832 (define_insn "*umulsidi3_nov6"
1833 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1834 (mult:DI
1835 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1836 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1837 "TARGET_32BIT && !arm_arch6"
1838 "umull%?\\t%Q0, %R0, %1, %2"
1839 [(set_attr "type" "umull")
1840 (set_attr "predicable" "yes")]
1841 )
1842
1843 (define_insn "*umulsidi3_v6"
1844 [(set (match_operand:DI 0 "s_register_operand" "=r")
1845 (mult:DI
1846 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1847 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1848 "TARGET_32BIT && arm_arch6"
1849 "umull%?\\t%Q0, %R0, %1, %2"
1850 [(set_attr "type" "umull")
1851 (set_attr "predicable" "yes")]
1852 )
1853
1854 (define_expand "umaddsidi4"
1855 [(set (match_operand:DI 0 "s_register_operand" "")
1856 (plus:DI
1857 (mult:DI
1858 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1859 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1860 (match_operand:DI 3 "s_register_operand" "")))]
1861 "TARGET_32BIT"
1862 "")
1863
1864 (define_insn "*umulsidi3adddi"
1865 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1866 (plus:DI
1867 (mult:DI
1868 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1869 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1870 (match_operand:DI 1 "s_register_operand" "0")))]
1871 "TARGET_32BIT && !arm_arch6"
1872 "umlal%?\\t%Q0, %R0, %3, %2"
1873 [(set_attr "type" "umlal")
1874 (set_attr "predicable" "yes")]
1875 )
1876
1877 (define_insn "*umulsidi3adddi_v6"
1878 [(set (match_operand:DI 0 "s_register_operand" "=r")
1879 (plus:DI
1880 (mult:DI
1881 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1882 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1883 (match_operand:DI 1 "s_register_operand" "0")))]
1884 "TARGET_32BIT && arm_arch6"
1885 "umlal%?\\t%Q0, %R0, %3, %2"
1886 [(set_attr "type" "umlal")
1887 (set_attr "predicable" "yes")]
1888 )
1889
1890 (define_expand "smulsi3_highpart"
1891 [(parallel
1892 [(set (match_operand:SI 0 "s_register_operand" "")
1893 (truncate:SI
1894 (lshiftrt:DI
1895 (mult:DI
1896 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1897 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1898 (const_int 32))))
1899 (clobber (match_scratch:SI 3 ""))])]
1900 "TARGET_32BIT"
1901 ""
1902 )
1903
1904 (define_insn "*smulsi3_highpart_nov6"
1905 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1906 (truncate:SI
1907 (lshiftrt:DI
1908 (mult:DI
1909 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1910 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1911 (const_int 32))))
1912 (clobber (match_scratch:SI 3 "=&r,&r"))]
1913 "TARGET_32BIT && !arm_arch6"
1914 "smull%?\\t%3, %0, %2, %1"
1915 [(set_attr "type" "smull")
1916 (set_attr "predicable" "yes")]
1917 )
1918
1919 (define_insn "*smulsi3_highpart_v6"
1920 [(set (match_operand:SI 0 "s_register_operand" "=r")
1921 (truncate:SI
1922 (lshiftrt:DI
1923 (mult:DI
1924 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1925 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1926 (const_int 32))))
1927 (clobber (match_scratch:SI 3 "=r"))]
1928 "TARGET_32BIT && arm_arch6"
1929 "smull%?\\t%3, %0, %2, %1"
1930 [(set_attr "type" "smull")
1931 (set_attr "predicable" "yes")]
1932 )
1933
1934 (define_expand "umulsi3_highpart"
1935 [(parallel
1936 [(set (match_operand:SI 0 "s_register_operand" "")
1937 (truncate:SI
1938 (lshiftrt:DI
1939 (mult:DI
1940 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1941 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1942 (const_int 32))))
1943 (clobber (match_scratch:SI 3 ""))])]
1944 "TARGET_32BIT"
1945 ""
1946 )
1947
1948 (define_insn "*umulsi3_highpart_nov6"
1949 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1950 (truncate:SI
1951 (lshiftrt:DI
1952 (mult:DI
1953 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1954 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1955 (const_int 32))))
1956 (clobber (match_scratch:SI 3 "=&r,&r"))]
1957 "TARGET_32BIT && !arm_arch6"
1958 "umull%?\\t%3, %0, %2, %1"
1959 [(set_attr "type" "umull")
1960 (set_attr "predicable" "yes")]
1961 )
1962
1963 (define_insn "*umulsi3_highpart_v6"
1964 [(set (match_operand:SI 0 "s_register_operand" "=r")
1965 (truncate:SI
1966 (lshiftrt:DI
1967 (mult:DI
1968 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1969 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1970 (const_int 32))))
1971 (clobber (match_scratch:SI 3 "=r"))]
1972 "TARGET_32BIT && arm_arch6"
1973 "umull%?\\t%3, %0, %2, %1"
1974 [(set_attr "type" "umull")
1975 (set_attr "predicable" "yes")]
1976 )
1977
1978 (define_insn "mulhisi3"
1979 [(set (match_operand:SI 0 "s_register_operand" "=r")
1980 (mult:SI (sign_extend:SI
1981 (match_operand:HI 1 "s_register_operand" "%r"))
1982 (sign_extend:SI
1983 (match_operand:HI 2 "s_register_operand" "r"))))]
1984 "TARGET_DSP_MULTIPLY"
1985 "smulbb%?\\t%0, %1, %2"
1986 [(set_attr "type" "smulxy")
1987 (set_attr "predicable" "yes")]
1988 )
1989
1990 (define_insn "*mulhisi3tb"
1991 [(set (match_operand:SI 0 "s_register_operand" "=r")
1992 (mult:SI (ashiftrt:SI
1993 (match_operand:SI 1 "s_register_operand" "r")
1994 (const_int 16))
1995 (sign_extend:SI
1996 (match_operand:HI 2 "s_register_operand" "r"))))]
1997 "TARGET_DSP_MULTIPLY"
1998 "smultb%?\\t%0, %1, %2"
1999 [(set_attr "type" "smulxy")
2000 (set_attr "predicable" "yes")]
2001 )
2002
2003 (define_insn "*mulhisi3bt"
2004 [(set (match_operand:SI 0 "s_register_operand" "=r")
2005 (mult:SI (sign_extend:SI
2006 (match_operand:HI 1 "s_register_operand" "r"))
2007 (ashiftrt:SI
2008 (match_operand:SI 2 "s_register_operand" "r")
2009 (const_int 16))))]
2010 "TARGET_DSP_MULTIPLY"
2011 "smulbt%?\\t%0, %1, %2"
2012 [(set_attr "type" "smulxy")
2013 (set_attr "predicable" "yes")]
2014 )
2015
2016 (define_insn "*mulhisi3tt"
2017 [(set (match_operand:SI 0 "s_register_operand" "=r")
2018 (mult:SI (ashiftrt:SI
2019 (match_operand:SI 1 "s_register_operand" "r")
2020 (const_int 16))
2021 (ashiftrt:SI
2022 (match_operand:SI 2 "s_register_operand" "r")
2023 (const_int 16))))]
2024 "TARGET_DSP_MULTIPLY"
2025 "smultt%?\\t%0, %1, %2"
2026 [(set_attr "type" "smulxy")
2027 (set_attr "predicable" "yes")]
2028 )
2029
2030 (define_insn "maddhisi4"
2031 [(set (match_operand:SI 0 "s_register_operand" "=r")
2032 (plus:SI (mult:SI (sign_extend:SI
2033 (match_operand:HI 1 "s_register_operand" "r"))
2034 (sign_extend:SI
2035 (match_operand:HI 2 "s_register_operand" "r")))
2036 (match_operand:SI 3 "s_register_operand" "r")))]
2037 "TARGET_DSP_MULTIPLY"
2038 "smlabb%?\\t%0, %1, %2, %3"
2039 [(set_attr "type" "smlaxy")
2040 (set_attr "predicable" "yes")]
2041 )
2042
2043 ;; Note: there is no maddhisi4ibt because this one is canonical form
2044 (define_insn "*maddhisi4tb"
2045 [(set (match_operand:SI 0 "s_register_operand" "=r")
2046 (plus:SI (mult:SI (ashiftrt:SI
2047 (match_operand:SI 1 "s_register_operand" "r")
2048 (const_int 16))
2049 (sign_extend:SI
2050 (match_operand:HI 2 "s_register_operand" "r")))
2051 (match_operand:SI 3 "s_register_operand" "r")))]
2052 "TARGET_DSP_MULTIPLY"
2053 "smlatb%?\\t%0, %1, %2, %3"
2054 [(set_attr "type" "smlaxy")
2055 (set_attr "predicable" "yes")]
2056 )
2057
2058 (define_insn "*maddhisi4tt"
2059 [(set (match_operand:SI 0 "s_register_operand" "=r")
2060 (plus:SI (mult:SI (ashiftrt:SI
2061 (match_operand:SI 1 "s_register_operand" "r")
2062 (const_int 16))
2063 (ashiftrt:SI
2064 (match_operand:SI 2 "s_register_operand" "r")
2065 (const_int 16)))
2066 (match_operand:SI 3 "s_register_operand" "r")))]
2067 "TARGET_DSP_MULTIPLY"
2068 "smlatt%?\\t%0, %1, %2, %3"
2069 [(set_attr "type" "smlaxy")
2070 (set_attr "predicable" "yes")]
2071 )
2072
2073 (define_insn "maddhidi4"
2074 [(set (match_operand:DI 0 "s_register_operand" "=r")
2075 (plus:DI
2076 (mult:DI (sign_extend:DI
2077 (match_operand:HI 1 "s_register_operand" "r"))
2078 (sign_extend:DI
2079 (match_operand:HI 2 "s_register_operand" "r")))
2080 (match_operand:DI 3 "s_register_operand" "0")))]
2081 "TARGET_DSP_MULTIPLY"
2082 "smlalbb%?\\t%Q0, %R0, %1, %2"
2083 [(set_attr "type" "smlalxy")
2084 (set_attr "predicable" "yes")])
2085
2086 ;; Note: there is no maddhidi4ibt because this one is canonical form
2087 (define_insn "*maddhidi4tb"
2088 [(set (match_operand:DI 0 "s_register_operand" "=r")
2089 (plus:DI
2090 (mult:DI (sign_extend:DI
2091 (ashiftrt:SI
2092 (match_operand:SI 1 "s_register_operand" "r")
2093 (const_int 16)))
2094 (sign_extend:DI
2095 (match_operand:HI 2 "s_register_operand" "r")))
2096 (match_operand:DI 3 "s_register_operand" "0")))]
2097 "TARGET_DSP_MULTIPLY"
2098 "smlaltb%?\\t%Q0, %R0, %1, %2"
2099 [(set_attr "type" "smlalxy")
2100 (set_attr "predicable" "yes")])
2101
2102 (define_insn "*maddhidi4tt"
2103 [(set (match_operand:DI 0 "s_register_operand" "=r")
2104 (plus:DI
2105 (mult:DI (sign_extend:DI
2106 (ashiftrt:SI
2107 (match_operand:SI 1 "s_register_operand" "r")
2108 (const_int 16)))
2109 (sign_extend:DI
2110 (ashiftrt:SI
2111 (match_operand:SI 2 "s_register_operand" "r")
2112 (const_int 16))))
2113 (match_operand:DI 3 "s_register_operand" "0")))]
2114 "TARGET_DSP_MULTIPLY"
2115 "smlaltt%?\\t%Q0, %R0, %1, %2"
2116 [(set_attr "type" "smlalxy")
2117 (set_attr "predicable" "yes")])
2118
2119 (define_expand "mulsf3"
2120 [(set (match_operand:SF 0 "s_register_operand" "")
2121 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2122 (match_operand:SF 2 "s_register_operand" "")))]
2123 "TARGET_32BIT && TARGET_HARD_FLOAT"
2124 "
2125 ")
2126
2127 (define_expand "muldf3"
2128 [(set (match_operand:DF 0 "s_register_operand" "")
2129 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2130 (match_operand:DF 2 "s_register_operand" "")))]
2131 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2132 "
2133 ")
2134 \f
2135 ;; Division insns
2136
2137 (define_expand "divsf3"
2138 [(set (match_operand:SF 0 "s_register_operand" "")
2139 (div:SF (match_operand:SF 1 "s_register_operand" "")
2140 (match_operand:SF 2 "s_register_operand" "")))]
2141 "TARGET_32BIT && TARGET_HARD_FLOAT"
2142 "")
2143
2144 (define_expand "divdf3"
2145 [(set (match_operand:DF 0 "s_register_operand" "")
2146 (div:DF (match_operand:DF 1 "s_register_operand" "")
2147 (match_operand:DF 2 "s_register_operand" "")))]
2148 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2149 "")
2150 \f
2151 ;; Boolean and,ior,xor insns
2152
2153 ;; Split up double word logical operations
2154
2155 ;; Split up simple DImode logical operations. Simply perform the logical
2156 ;; operation on the upper and lower halves of the registers.
2157 (define_split
2158 [(set (match_operand:DI 0 "s_register_operand" "")
2159 (match_operator:DI 6 "logical_binary_operator"
2160 [(match_operand:DI 1 "s_register_operand" "")
2161 (match_operand:DI 2 "s_register_operand" "")]))]
2162 "TARGET_32BIT && reload_completed
2163 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2164 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2165 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2166 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2167 "
2168 {
2169 operands[3] = gen_highpart (SImode, operands[0]);
2170 operands[0] = gen_lowpart (SImode, operands[0]);
2171 operands[4] = gen_highpart (SImode, operands[1]);
2172 operands[1] = gen_lowpart (SImode, operands[1]);
2173 operands[5] = gen_highpart (SImode, operands[2]);
2174 operands[2] = gen_lowpart (SImode, operands[2]);
2175 }"
2176 )
2177
2178 (define_split
2179 [(set (match_operand:DI 0 "s_register_operand" "")
2180 (match_operator:DI 6 "logical_binary_operator"
2181 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2182 (match_operand:DI 1 "s_register_operand" "")]))]
2183 "TARGET_32BIT && reload_completed"
2184 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2185 (set (match_dup 3) (match_op_dup:SI 6
2186 [(ashiftrt:SI (match_dup 2) (const_int 31))
2187 (match_dup 4)]))]
2188 "
2189 {
2190 operands[3] = gen_highpart (SImode, operands[0]);
2191 operands[0] = gen_lowpart (SImode, operands[0]);
2192 operands[4] = gen_highpart (SImode, operands[1]);
2193 operands[1] = gen_lowpart (SImode, operands[1]);
2194 operands[5] = gen_highpart (SImode, operands[2]);
2195 operands[2] = gen_lowpart (SImode, operands[2]);
2196 }"
2197 )
2198
2199 ;; The zero extend of operand 2 means we can just copy the high part of
2200 ;; operand1 into operand0.
2201 (define_split
2202 [(set (match_operand:DI 0 "s_register_operand" "")
2203 (ior:DI
2204 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2205 (match_operand:DI 1 "s_register_operand" "")))]
2206 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2207 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2208 (set (match_dup 3) (match_dup 4))]
2209 "
2210 {
2211 operands[4] = gen_highpart (SImode, operands[1]);
2212 operands[3] = gen_highpart (SImode, operands[0]);
2213 operands[0] = gen_lowpart (SImode, operands[0]);
2214 operands[1] = gen_lowpart (SImode, operands[1]);
2215 }"
2216 )
2217
2218 ;; The zero extend of operand 2 means we can just copy the high part of
2219 ;; operand1 into operand0.
2220 (define_split
2221 [(set (match_operand:DI 0 "s_register_operand" "")
2222 (xor:DI
2223 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2224 (match_operand:DI 1 "s_register_operand" "")))]
2225 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2226 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2227 (set (match_dup 3) (match_dup 4))]
2228 "
2229 {
2230 operands[4] = gen_highpart (SImode, operands[1]);
2231 operands[3] = gen_highpart (SImode, operands[0]);
2232 operands[0] = gen_lowpart (SImode, operands[0]);
2233 operands[1] = gen_lowpart (SImode, operands[1]);
2234 }"
2235 )
2236
2237 (define_expand "anddi3"
2238 [(set (match_operand:DI 0 "s_register_operand" "")
2239 (and:DI (match_operand:DI 1 "s_register_operand" "")
2240 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2241 "TARGET_32BIT"
2242 "
2243 if (!TARGET_NEON && !TARGET_IWMMXT)
2244 {
2245 rtx low = simplify_gen_binary (AND, SImode,
2246 gen_lowpart (SImode, operands[1]),
2247 gen_lowpart (SImode, operands[2]));
2248 rtx high = simplify_gen_binary (AND, SImode,
2249 gen_highpart (SImode, operands[1]),
2250 gen_highpart_mode (SImode, DImode,
2251 operands[2]));
2252
2253 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2254 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2255
2256 DONE;
2257 }
2258 /* Otherwise expand pattern as above. */
2259 "
2260 )
2261
2262 (define_insn_and_split "*anddi3_insn"
2263 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2264 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2265 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2266 "TARGET_32BIT && !TARGET_IWMMXT"
2267 {
2268 switch (which_alternative)
2269 {
2270 case 0: /* fall through */
2271 case 6: return "vand\t%P0, %P1, %P2";
2272 case 1: /* fall through */
2273 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2274 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2275 case 2:
2276 case 3:
2277 case 4:
2278 case 5: /* fall through */
2279 return "#";
2280 default: gcc_unreachable ();
2281 }
2282 }
2283 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2284 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2285 [(set (match_dup 3) (match_dup 4))
2286 (set (match_dup 5) (match_dup 6))]
2287 "
2288 {
2289 operands[3] = gen_lowpart (SImode, operands[0]);
2290 operands[5] = gen_highpart (SImode, operands[0]);
2291
2292 operands[4] = simplify_gen_binary (AND, SImode,
2293 gen_lowpart (SImode, operands[1]),
2294 gen_lowpart (SImode, operands[2]));
2295 operands[6] = simplify_gen_binary (AND, SImode,
2296 gen_highpart (SImode, operands[1]),
2297 gen_highpart_mode (SImode, DImode, operands[2]));
2298
2299 }"
2300 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2301 multiple,multiple,neon_logic,neon_logic")
2302 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2303 avoid_neon_for_64bits,avoid_neon_for_64bits")
2304 (set_attr "length" "*,*,8,8,8,8,*,*")
2305 ]
2306 )
2307
2308 (define_insn_and_split "*anddi_zesidi_di"
2309 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2310 (and:DI (zero_extend:DI
2311 (match_operand:SI 2 "s_register_operand" "r,r"))
2312 (match_operand:DI 1 "s_register_operand" "0,r")))]
2313 "TARGET_32BIT"
2314 "#"
2315 "TARGET_32BIT && reload_completed"
2316 ; The zero extend of operand 2 clears the high word of the output
2317 ; operand.
2318 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2319 (set (match_dup 3) (const_int 0))]
2320 "
2321 {
2322 operands[3] = gen_highpart (SImode, operands[0]);
2323 operands[0] = gen_lowpart (SImode, operands[0]);
2324 operands[1] = gen_lowpart (SImode, operands[1]);
2325 }"
2326 [(set_attr "length" "8")
2327 (set_attr "type" "multiple")]
2328 )
2329
2330 (define_insn "*anddi_sesdi_di"
2331 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2332 (and:DI (sign_extend:DI
2333 (match_operand:SI 2 "s_register_operand" "r,r"))
2334 (match_operand:DI 1 "s_register_operand" "0,r")))]
2335 "TARGET_32BIT"
2336 "#"
2337 [(set_attr "length" "8")
2338 (set_attr "type" "multiple")]
2339 )
2340
2341 (define_expand "andsi3"
2342 [(set (match_operand:SI 0 "s_register_operand" "")
2343 (and:SI (match_operand:SI 1 "s_register_operand" "")
2344 (match_operand:SI 2 "reg_or_int_operand" "")))]
2345 "TARGET_EITHER"
2346 "
2347 if (TARGET_32BIT)
2348 {
2349 if (CONST_INT_P (operands[2]))
2350 {
2351 if (INTVAL (operands[2]) == 255 && arm_arch6)
2352 {
2353 operands[1] = convert_to_mode (QImode, operands[1], 1);
2354 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2355 operands[1]));
2356 DONE;
2357 }
2358 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2359 operands[2] = force_reg (SImode, operands[2]);
2360 else
2361 {
2362 arm_split_constant (AND, SImode, NULL_RTX,
2363 INTVAL (operands[2]), operands[0],
2364 operands[1],
2365 optimize && can_create_pseudo_p ());
2366
2367 DONE;
2368 }
2369 }
2370 }
2371 else /* TARGET_THUMB1 */
2372 {
2373 if (!CONST_INT_P (operands[2]))
2374 {
2375 rtx tmp = force_reg (SImode, operands[2]);
2376 if (rtx_equal_p (operands[0], operands[1]))
2377 operands[2] = tmp;
2378 else
2379 {
2380 operands[2] = operands[1];
2381 operands[1] = tmp;
2382 }
2383 }
2384 else
2385 {
2386 int i;
2387
2388 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2389 {
2390 operands[2] = force_reg (SImode,
2391 GEN_INT (~INTVAL (operands[2])));
2392
2393 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2394
2395 DONE;
2396 }
2397
2398 for (i = 9; i <= 31; i++)
2399 {
2400 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2401 {
2402 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2403 const0_rtx));
2404 DONE;
2405 }
2406 else if ((HOST_WIDE_INT_1 << i) - 1
2407 == ~INTVAL (operands[2]))
2408 {
2409 rtx shift = GEN_INT (i);
2410 rtx reg = gen_reg_rtx (SImode);
2411
2412 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2413 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2414
2415 DONE;
2416 }
2417 }
2418
2419 operands[2] = force_reg (SImode, operands[2]);
2420 }
2421 }
2422 "
2423 )
2424
2425 ; ??? Check split length for Thumb-2
2426 (define_insn_and_split "*arm_andsi3_insn"
2427 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2428 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2429 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2430 "TARGET_32BIT"
2431 "@
2432 and%?\\t%0, %1, %2
2433 and%?\\t%0, %1, %2
2434 bic%?\\t%0, %1, #%B2
2435 and%?\\t%0, %1, %2
2436 #"
2437 "TARGET_32BIT
2438 && CONST_INT_P (operands[2])
2439 && !(const_ok_for_arm (INTVAL (operands[2]))
2440 || const_ok_for_arm (~INTVAL (operands[2])))"
2441 [(clobber (const_int 0))]
2442 "
2443 arm_split_constant (AND, SImode, curr_insn,
2444 INTVAL (operands[2]), operands[0], operands[1], 0);
2445 DONE;
2446 "
2447 [(set_attr "length" "4,4,4,4,16")
2448 (set_attr "predicable" "yes")
2449 (set_attr "predicable_short_it" "no,yes,no,no,no")
2450 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2451 )
2452
2453 (define_insn "*andsi3_compare0"
2454 [(set (reg:CC_NOOV CC_REGNUM)
2455 (compare:CC_NOOV
2456 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2457 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2458 (const_int 0)))
2459 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2460 (and:SI (match_dup 1) (match_dup 2)))]
2461 "TARGET_32BIT"
2462 "@
2463 ands%?\\t%0, %1, %2
2464 bics%?\\t%0, %1, #%B2
2465 ands%?\\t%0, %1, %2"
2466 [(set_attr "conds" "set")
2467 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2468 )
2469
2470 (define_insn "*andsi3_compare0_scratch"
2471 [(set (reg:CC_NOOV CC_REGNUM)
2472 (compare:CC_NOOV
2473 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2474 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2475 (const_int 0)))
2476 (clobber (match_scratch:SI 2 "=X,r,X"))]
2477 "TARGET_32BIT"
2478 "@
2479 tst%?\\t%0, %1
2480 bics%?\\t%2, %0, #%B1
2481 tst%?\\t%0, %1"
2482 [(set_attr "conds" "set")
2483 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2484 )
2485
2486 (define_insn "*zeroextractsi_compare0_scratch"
2487 [(set (reg:CC_NOOV CC_REGNUM)
2488 (compare:CC_NOOV (zero_extract:SI
2489 (match_operand:SI 0 "s_register_operand" "r")
2490 (match_operand 1 "const_int_operand" "n")
2491 (match_operand 2 "const_int_operand" "n"))
2492 (const_int 0)))]
2493 "TARGET_32BIT
2494 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2495 && INTVAL (operands[1]) > 0
2496 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2497 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2498 "*
2499 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2500 << INTVAL (operands[2]));
2501 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2502 return \"\";
2503 "
2504 [(set_attr "conds" "set")
2505 (set_attr "predicable" "yes")
2506 (set_attr "type" "logics_imm")]
2507 )
2508
2509 (define_insn_and_split "*ne_zeroextractsi"
2510 [(set (match_operand:SI 0 "s_register_operand" "=r")
2511 (ne:SI (zero_extract:SI
2512 (match_operand:SI 1 "s_register_operand" "r")
2513 (match_operand:SI 2 "const_int_operand" "n")
2514 (match_operand:SI 3 "const_int_operand" "n"))
2515 (const_int 0)))
2516 (clobber (reg:CC CC_REGNUM))]
2517 "TARGET_32BIT
2518 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2519 && INTVAL (operands[2]) > 0
2520 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2521 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2522 "#"
2523 "TARGET_32BIT
2524 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2525 && INTVAL (operands[2]) > 0
2526 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2527 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2528 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2529 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2530 (const_int 0)))
2531 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2532 (set (match_dup 0)
2533 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2534 (match_dup 0) (const_int 1)))]
2535 "
2536 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2537 << INTVAL (operands[3]));
2538 "
2539 [(set_attr "conds" "clob")
2540 (set (attr "length")
2541 (if_then_else (eq_attr "is_thumb" "yes")
2542 (const_int 12)
2543 (const_int 8)))
2544 (set_attr "type" "multiple")]
2545 )
2546
2547 (define_insn_and_split "*ne_zeroextractsi_shifted"
2548 [(set (match_operand:SI 0 "s_register_operand" "=r")
2549 (ne:SI (zero_extract:SI
2550 (match_operand:SI 1 "s_register_operand" "r")
2551 (match_operand:SI 2 "const_int_operand" "n")
2552 (const_int 0))
2553 (const_int 0)))
2554 (clobber (reg:CC CC_REGNUM))]
2555 "TARGET_ARM"
2556 "#"
2557 "TARGET_ARM"
2558 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2559 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2560 (const_int 0)))
2561 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2562 (set (match_dup 0)
2563 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2564 (match_dup 0) (const_int 1)))]
2565 "
2566 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2567 "
2568 [(set_attr "conds" "clob")
2569 (set_attr "length" "8")
2570 (set_attr "type" "multiple")]
2571 )
2572
2573 (define_insn_and_split "*ite_ne_zeroextractsi"
2574 [(set (match_operand:SI 0 "s_register_operand" "=r")
2575 (if_then_else:SI (ne (zero_extract:SI
2576 (match_operand:SI 1 "s_register_operand" "r")
2577 (match_operand:SI 2 "const_int_operand" "n")
2578 (match_operand:SI 3 "const_int_operand" "n"))
2579 (const_int 0))
2580 (match_operand:SI 4 "arm_not_operand" "rIK")
2581 (const_int 0)))
2582 (clobber (reg:CC CC_REGNUM))]
2583 "TARGET_ARM
2584 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2585 && INTVAL (operands[2]) > 0
2586 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2587 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2588 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2589 "#"
2590 "TARGET_ARM
2591 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2592 && INTVAL (operands[2]) > 0
2593 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2594 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2595 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2596 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2597 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2598 (const_int 0)))
2599 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2600 (set (match_dup 0)
2601 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2602 (match_dup 0) (match_dup 4)))]
2603 "
2604 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2605 << INTVAL (operands[3]));
2606 "
2607 [(set_attr "conds" "clob")
2608 (set_attr "length" "8")
2609 (set_attr "type" "multiple")]
2610 )
2611
2612 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2613 [(set (match_operand:SI 0 "s_register_operand" "=r")
2614 (if_then_else:SI (ne (zero_extract:SI
2615 (match_operand:SI 1 "s_register_operand" "r")
2616 (match_operand:SI 2 "const_int_operand" "n")
2617 (const_int 0))
2618 (const_int 0))
2619 (match_operand:SI 3 "arm_not_operand" "rIK")
2620 (const_int 0)))
2621 (clobber (reg:CC CC_REGNUM))]
2622 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2623 "#"
2624 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2625 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2626 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2627 (const_int 0)))
2628 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2629 (set (match_dup 0)
2630 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2631 (match_dup 0) (match_dup 3)))]
2632 "
2633 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2634 "
2635 [(set_attr "conds" "clob")
2636 (set_attr "length" "8")
2637 (set_attr "type" "multiple")]
2638 )
2639
2640 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2641 (define_split
2642 [(set (match_operand:SI 0 "s_register_operand" "")
2643 (match_operator:SI 1 "shiftable_operator"
2644 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2645 (match_operand:SI 3 "const_int_operand" "")
2646 (match_operand:SI 4 "const_int_operand" ""))
2647 (match_operand:SI 5 "s_register_operand" "")]))
2648 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2649 "TARGET_ARM"
2650 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2651 (set (match_dup 0)
2652 (match_op_dup 1
2653 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2654 (match_dup 5)]))]
2655 "{
2656 HOST_WIDE_INT temp = INTVAL (operands[3]);
2657
2658 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2659 operands[4] = GEN_INT (32 - temp);
2660 }"
2661 )
2662
2663 (define_split
2664 [(set (match_operand:SI 0 "s_register_operand" "")
2665 (match_operator:SI 1 "shiftable_operator"
2666 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2667 (match_operand:SI 3 "const_int_operand" "")
2668 (match_operand:SI 4 "const_int_operand" ""))
2669 (match_operand:SI 5 "s_register_operand" "")]))
2670 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2671 "TARGET_ARM"
2672 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2673 (set (match_dup 0)
2674 (match_op_dup 1
2675 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2676 (match_dup 5)]))]
2677 "{
2678 HOST_WIDE_INT temp = INTVAL (operands[3]);
2679
2680 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2681 operands[4] = GEN_INT (32 - temp);
2682 }"
2683 )
2684
2685 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2686 ;;; represented by the bitfield, then this will produce incorrect results.
2687 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2688 ;;; which have a real bit-field insert instruction, the truncation happens
2689 ;;; in the bit-field insert instruction itself. Since arm does not have a
2690 ;;; bit-field insert instruction, we would have to emit code here to truncate
2691 ;;; the value before we insert. This loses some of the advantage of having
2692 ;;; this insv pattern, so this pattern needs to be reevalutated.
2693
2694 (define_expand "insv"
2695 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2696 (match_operand 1 "general_operand" "")
2697 (match_operand 2 "general_operand" ""))
2698 (match_operand 3 "reg_or_int_operand" ""))]
2699 "TARGET_ARM || arm_arch_thumb2"
2700 "
2701 {
2702 int start_bit = INTVAL (operands[2]);
2703 int width = INTVAL (operands[1]);
2704 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2705 rtx target, subtarget;
2706
2707 if (arm_arch_thumb2)
2708 {
2709 if (unaligned_access && MEM_P (operands[0])
2710 && s_register_operand (operands[3], GET_MODE (operands[3]))
2711 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2712 {
2713 rtx base_addr;
2714
2715 if (BYTES_BIG_ENDIAN)
2716 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2717 - start_bit;
2718
2719 if (width == 32)
2720 {
2721 base_addr = adjust_address (operands[0], SImode,
2722 start_bit / BITS_PER_UNIT);
2723 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2724 }
2725 else
2726 {
2727 rtx tmp = gen_reg_rtx (HImode);
2728
2729 base_addr = adjust_address (operands[0], HImode,
2730 start_bit / BITS_PER_UNIT);
2731 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2732 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2733 }
2734 DONE;
2735 }
2736 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2737 {
2738 bool use_bfi = TRUE;
2739
2740 if (CONST_INT_P (operands[3]))
2741 {
2742 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2743
2744 if (val == 0)
2745 {
2746 emit_insn (gen_insv_zero (operands[0], operands[1],
2747 operands[2]));
2748 DONE;
2749 }
2750
2751 /* See if the set can be done with a single orr instruction. */
2752 if (val == mask && const_ok_for_arm (val << start_bit))
2753 use_bfi = FALSE;
2754 }
2755
2756 if (use_bfi)
2757 {
2758 if (!REG_P (operands[3]))
2759 operands[3] = force_reg (SImode, operands[3]);
2760
2761 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2762 operands[3]));
2763 DONE;
2764 }
2765 }
2766 else
2767 FAIL;
2768 }
2769
2770 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2771 FAIL;
2772
2773 target = copy_rtx (operands[0]);
2774 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2775 subreg as the final target. */
2776 if (GET_CODE (target) == SUBREG)
2777 {
2778 subtarget = gen_reg_rtx (SImode);
2779 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2780 < GET_MODE_SIZE (SImode))
2781 target = SUBREG_REG (target);
2782 }
2783 else
2784 subtarget = target;
2785
2786 if (CONST_INT_P (operands[3]))
2787 {
2788 /* Since we are inserting a known constant, we may be able to
2789 reduce the number of bits that we have to clear so that
2790 the mask becomes simple. */
2791 /* ??? This code does not check to see if the new mask is actually
2792 simpler. It may not be. */
2793 rtx op1 = gen_reg_rtx (SImode);
2794 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2795 start of this pattern. */
2796 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2797 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2798
2799 emit_insn (gen_andsi3 (op1, operands[0],
2800 gen_int_mode (~mask2, SImode)));
2801 emit_insn (gen_iorsi3 (subtarget, op1,
2802 gen_int_mode (op3_value << start_bit, SImode)));
2803 }
2804 else if (start_bit == 0
2805 && !(const_ok_for_arm (mask)
2806 || const_ok_for_arm (~mask)))
2807 {
2808 /* A Trick, since we are setting the bottom bits in the word,
2809 we can shift operand[3] up, operand[0] down, OR them together
2810 and rotate the result back again. This takes 3 insns, and
2811 the third might be mergeable into another op. */
2812 /* The shift up copes with the possibility that operand[3] is
2813 wider than the bitfield. */
2814 rtx op0 = gen_reg_rtx (SImode);
2815 rtx op1 = gen_reg_rtx (SImode);
2816
2817 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2818 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2819 emit_insn (gen_iorsi3 (op1, op1, op0));
2820 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2821 }
2822 else if ((width + start_bit == 32)
2823 && !(const_ok_for_arm (mask)
2824 || const_ok_for_arm (~mask)))
2825 {
2826 /* Similar trick, but slightly less efficient. */
2827
2828 rtx op0 = gen_reg_rtx (SImode);
2829 rtx op1 = gen_reg_rtx (SImode);
2830
2831 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2832 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2833 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2834 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2835 }
2836 else
2837 {
2838 rtx op0 = gen_int_mode (mask, SImode);
2839 rtx op1 = gen_reg_rtx (SImode);
2840 rtx op2 = gen_reg_rtx (SImode);
2841
2842 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2843 {
2844 rtx tmp = gen_reg_rtx (SImode);
2845
2846 emit_insn (gen_movsi (tmp, op0));
2847 op0 = tmp;
2848 }
2849
2850 /* Mask out any bits in operand[3] that are not needed. */
2851 emit_insn (gen_andsi3 (op1, operands[3], op0));
2852
2853 if (CONST_INT_P (op0)
2854 && (const_ok_for_arm (mask << start_bit)
2855 || const_ok_for_arm (~(mask << start_bit))))
2856 {
2857 op0 = gen_int_mode (~(mask << start_bit), SImode);
2858 emit_insn (gen_andsi3 (op2, operands[0], op0));
2859 }
2860 else
2861 {
2862 if (CONST_INT_P (op0))
2863 {
2864 rtx tmp = gen_reg_rtx (SImode);
2865
2866 emit_insn (gen_movsi (tmp, op0));
2867 op0 = tmp;
2868 }
2869
2870 if (start_bit != 0)
2871 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2872
2873 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2874 }
2875
2876 if (start_bit != 0)
2877 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2878
2879 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2880 }
2881
2882 if (subtarget != target)
2883 {
2884 /* If TARGET is still a SUBREG, then it must be wider than a word,
2885 so we must be careful only to set the subword we were asked to. */
2886 if (GET_CODE (target) == SUBREG)
2887 emit_move_insn (target, subtarget);
2888 else
2889 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2890 }
2891
2892 DONE;
2893 }"
2894 )
2895
2896 (define_insn "insv_zero"
2897 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2898 (match_operand:SI 1 "const_int_M_operand" "M")
2899 (match_operand:SI 2 "const_int_M_operand" "M"))
2900 (const_int 0))]
2901 "arm_arch_thumb2"
2902 "bfc%?\t%0, %2, %1"
2903 [(set_attr "length" "4")
2904 (set_attr "predicable" "yes")
2905 (set_attr "type" "bfm")]
2906 )
2907
2908 (define_insn "insv_t2"
2909 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2910 (match_operand:SI 1 "const_int_M_operand" "M")
2911 (match_operand:SI 2 "const_int_M_operand" "M"))
2912 (match_operand:SI 3 "s_register_operand" "r"))]
2913 "arm_arch_thumb2"
2914 "bfi%?\t%0, %3, %2, %1"
2915 [(set_attr "length" "4")
2916 (set_attr "predicable" "yes")
2917 (set_attr "type" "bfm")]
2918 )
2919
2920 ; constants for op 2 will never be given to these patterns.
2921 (define_insn_and_split "*anddi_notdi_di"
2922 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2923 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2924 (match_operand:DI 2 "s_register_operand" "r,0")))]
2925 "TARGET_32BIT"
2926 "#"
2927 "TARGET_32BIT && reload_completed
2928 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2929 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2930 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2931 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2932 "
2933 {
2934 operands[3] = gen_highpart (SImode, operands[0]);
2935 operands[0] = gen_lowpart (SImode, operands[0]);
2936 operands[4] = gen_highpart (SImode, operands[1]);
2937 operands[1] = gen_lowpart (SImode, operands[1]);
2938 operands[5] = gen_highpart (SImode, operands[2]);
2939 operands[2] = gen_lowpart (SImode, operands[2]);
2940 }"
2941 [(set_attr "length" "8")
2942 (set_attr "predicable" "yes")
2943 (set_attr "type" "multiple")]
2944 )
2945
2946 (define_insn_and_split "*anddi_notzesidi_di"
2947 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2948 (and:DI (not:DI (zero_extend:DI
2949 (match_operand:SI 2 "s_register_operand" "r,r")))
2950 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2951 "TARGET_32BIT"
2952 "@
2953 bic%?\\t%Q0, %Q1, %2
2954 #"
2955 ; (not (zero_extend ...)) allows us to just copy the high word from
2956 ; operand1 to operand0.
2957 "TARGET_32BIT
2958 && reload_completed
2959 && operands[0] != operands[1]"
2960 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2961 (set (match_dup 3) (match_dup 4))]
2962 "
2963 {
2964 operands[3] = gen_highpart (SImode, operands[0]);
2965 operands[0] = gen_lowpart (SImode, operands[0]);
2966 operands[4] = gen_highpart (SImode, operands[1]);
2967 operands[1] = gen_lowpart (SImode, operands[1]);
2968 }"
2969 [(set_attr "length" "4,8")
2970 (set_attr "predicable" "yes")
2971 (set_attr "type" "multiple")]
2972 )
2973
2974 (define_insn_and_split "*anddi_notdi_zesidi"
2975 [(set (match_operand:DI 0 "s_register_operand" "=r")
2976 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2977 (zero_extend:DI
2978 (match_operand:SI 1 "s_register_operand" "r"))))]
2979 "TARGET_32BIT"
2980 "#"
2981 "TARGET_32BIT && reload_completed"
2982 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2983 (set (match_dup 3) (const_int 0))]
2984 "
2985 {
2986 operands[3] = gen_highpart (SImode, operands[0]);
2987 operands[0] = gen_lowpart (SImode, operands[0]);
2988 operands[2] = gen_lowpart (SImode, operands[2]);
2989 }"
2990 [(set_attr "length" "8")
2991 (set_attr "predicable" "yes")
2992 (set_attr "type" "multiple")]
2993 )
2994
2995 (define_insn_and_split "*anddi_notsesidi_di"
2996 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2997 (and:DI (not:DI (sign_extend:DI
2998 (match_operand:SI 2 "s_register_operand" "r,r")))
2999 (match_operand:DI 1 "s_register_operand" "0,r")))]
3000 "TARGET_32BIT"
3001 "#"
3002 "TARGET_32BIT && reload_completed"
3003 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3004 (set (match_dup 3) (and:SI (not:SI
3005 (ashiftrt:SI (match_dup 2) (const_int 31)))
3006 (match_dup 4)))]
3007 "
3008 {
3009 operands[3] = gen_highpart (SImode, operands[0]);
3010 operands[0] = gen_lowpart (SImode, operands[0]);
3011 operands[4] = gen_highpart (SImode, operands[1]);
3012 operands[1] = gen_lowpart (SImode, operands[1]);
3013 }"
3014 [(set_attr "length" "8")
3015 (set_attr "predicable" "yes")
3016 (set_attr "type" "multiple")]
3017 )
3018
3019 (define_insn "andsi_notsi_si"
3020 [(set (match_operand:SI 0 "s_register_operand" "=r")
3021 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3022 (match_operand:SI 1 "s_register_operand" "r")))]
3023 "TARGET_32BIT"
3024 "bic%?\\t%0, %1, %2"
3025 [(set_attr "predicable" "yes")
3026 (set_attr "type" "logic_reg")]
3027 )
3028
3029 (define_insn "andsi_not_shiftsi_si"
3030 [(set (match_operand:SI 0 "s_register_operand" "=r")
3031 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3032 [(match_operand:SI 2 "s_register_operand" "r")
3033 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3034 (match_operand:SI 1 "s_register_operand" "r")))]
3035 "TARGET_ARM"
3036 "bic%?\\t%0, %1, %2%S4"
3037 [(set_attr "predicable" "yes")
3038 (set_attr "shift" "2")
3039 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3040 (const_string "logic_shift_imm")
3041 (const_string "logic_shift_reg")))]
3042 )
3043
3044 ;; Shifted bics pattern used to set up CC status register and not reusing
3045 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3046 ;; does not support shift by register.
3047 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3048 [(set (reg:CC_NOOV CC_REGNUM)
3049 (compare:CC_NOOV
3050 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3051 [(match_operand:SI 1 "s_register_operand" "r")
3052 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3053 (match_operand:SI 3 "s_register_operand" "r"))
3054 (const_int 0)))
3055 (clobber (match_scratch:SI 4 "=r"))]
3056 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3057 "bics%?\\t%4, %3, %1%S0"
3058 [(set_attr "predicable" "yes")
3059 (set_attr "conds" "set")
3060 (set_attr "shift" "1")
3061 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3062 (const_string "logic_shift_imm")
3063 (const_string "logic_shift_reg")))]
3064 )
3065
3066 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3067 ;; getting reused later.
3068 (define_insn "andsi_not_shiftsi_si_scc"
3069 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3070 (compare:CC_NOOV
3071 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3072 [(match_operand:SI 1 "s_register_operand" "r")
3073 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3074 (match_operand:SI 3 "s_register_operand" "r"))
3075 (const_int 0)))
3076 (set (match_operand:SI 4 "s_register_operand" "=r")
3077 (and:SI (not:SI (match_op_dup 0
3078 [(match_dup 1)
3079 (match_dup 2)]))
3080 (match_dup 3)))])]
3081 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3082 "bics%?\\t%4, %3, %1%S0"
3083 [(set_attr "predicable" "yes")
3084 (set_attr "conds" "set")
3085 (set_attr "shift" "1")
3086 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3087 (const_string "logic_shift_imm")
3088 (const_string "logic_shift_reg")))]
3089 )
3090
3091 (define_insn "*andsi_notsi_si_compare0"
3092 [(set (reg:CC_NOOV CC_REGNUM)
3093 (compare:CC_NOOV
3094 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3095 (match_operand:SI 1 "s_register_operand" "r"))
3096 (const_int 0)))
3097 (set (match_operand:SI 0 "s_register_operand" "=r")
3098 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3099 "TARGET_32BIT"
3100 "bics\\t%0, %1, %2"
3101 [(set_attr "conds" "set")
3102 (set_attr "type" "logics_shift_reg")]
3103 )
3104
3105 (define_insn "*andsi_notsi_si_compare0_scratch"
3106 [(set (reg:CC_NOOV CC_REGNUM)
3107 (compare:CC_NOOV
3108 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3109 (match_operand:SI 1 "s_register_operand" "r"))
3110 (const_int 0)))
3111 (clobber (match_scratch:SI 0 "=r"))]
3112 "TARGET_32BIT"
3113 "bics\\t%0, %1, %2"
3114 [(set_attr "conds" "set")
3115 (set_attr "type" "logics_shift_reg")]
3116 )
3117
3118 (define_expand "iordi3"
3119 [(set (match_operand:DI 0 "s_register_operand" "")
3120 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3121 (match_operand:DI 2 "neon_logic_op2" "")))]
3122 "TARGET_32BIT"
3123 "
3124 if (!TARGET_NEON && !TARGET_IWMMXT)
3125 {
3126 rtx low = simplify_gen_binary (IOR, SImode,
3127 gen_lowpart (SImode, operands[1]),
3128 gen_lowpart (SImode, operands[2]));
3129 rtx high = simplify_gen_binary (IOR, SImode,
3130 gen_highpart (SImode, operands[1]),
3131 gen_highpart_mode (SImode, DImode,
3132 operands[2]));
3133
3134 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3135 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3136
3137 DONE;
3138 }
3139 /* Otherwise expand pattern as above. */
3140 "
3141 )
3142
3143 (define_insn_and_split "*iordi3_insn"
3144 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3145 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3146 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3147 "TARGET_32BIT && !TARGET_IWMMXT"
3148 {
3149 switch (which_alternative)
3150 {
3151 case 0: /* fall through */
3152 case 6: return "vorr\t%P0, %P1, %P2";
3153 case 1: /* fall through */
3154 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3155 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3156 case 2:
3157 case 3:
3158 case 4:
3159 case 5:
3160 return "#";
3161 default: gcc_unreachable ();
3162 }
3163 }
3164 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3165 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3166 [(set (match_dup 3) (match_dup 4))
3167 (set (match_dup 5) (match_dup 6))]
3168 "
3169 {
3170 operands[3] = gen_lowpart (SImode, operands[0]);
3171 operands[5] = gen_highpart (SImode, operands[0]);
3172
3173 operands[4] = simplify_gen_binary (IOR, SImode,
3174 gen_lowpart (SImode, operands[1]),
3175 gen_lowpart (SImode, operands[2]));
3176 operands[6] = simplify_gen_binary (IOR, SImode,
3177 gen_highpart (SImode, operands[1]),
3178 gen_highpart_mode (SImode, DImode, operands[2]));
3179
3180 }"
3181 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3182 multiple,neon_logic,neon_logic")
3183 (set_attr "length" "*,*,8,8,8,8,*,*")
3184 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3185 )
3186
3187 (define_insn "*iordi_zesidi_di"
3188 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3189 (ior:DI (zero_extend:DI
3190 (match_operand:SI 2 "s_register_operand" "r,r"))
3191 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3192 "TARGET_32BIT"
3193 "@
3194 orr%?\\t%Q0, %Q1, %2
3195 #"
3196 [(set_attr "length" "4,8")
3197 (set_attr "predicable" "yes")
3198 (set_attr "type" "logic_reg,multiple")]
3199 )
3200
3201 (define_insn "*iordi_sesidi_di"
3202 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3203 (ior:DI (sign_extend:DI
3204 (match_operand:SI 2 "s_register_operand" "r,r"))
3205 (match_operand:DI 1 "s_register_operand" "0,r")))]
3206 "TARGET_32BIT"
3207 "#"
3208 [(set_attr "length" "8")
3209 (set_attr "predicable" "yes")
3210 (set_attr "type" "multiple")]
3211 )
3212
3213 (define_expand "iorsi3"
3214 [(set (match_operand:SI 0 "s_register_operand" "")
3215 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3216 (match_operand:SI 2 "reg_or_int_operand" "")))]
3217 "TARGET_EITHER"
3218 "
3219 if (CONST_INT_P (operands[2]))
3220 {
3221 if (TARGET_32BIT)
3222 {
3223 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3224 operands[2] = force_reg (SImode, operands[2]);
3225 else
3226 {
3227 arm_split_constant (IOR, SImode, NULL_RTX,
3228 INTVAL (operands[2]), operands[0],
3229 operands[1],
3230 optimize && can_create_pseudo_p ());
3231 DONE;
3232 }
3233 }
3234 else /* TARGET_THUMB1 */
3235 {
3236 rtx tmp = force_reg (SImode, operands[2]);
3237 if (rtx_equal_p (operands[0], operands[1]))
3238 operands[2] = tmp;
3239 else
3240 {
3241 operands[2] = operands[1];
3242 operands[1] = tmp;
3243 }
3244 }
3245 }
3246 "
3247 )
3248
3249 (define_insn_and_split "*iorsi3_insn"
3250 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3251 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3252 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3253 "TARGET_32BIT"
3254 "@
3255 orr%?\\t%0, %1, %2
3256 orr%?\\t%0, %1, %2
3257 orn%?\\t%0, %1, #%B2
3258 orr%?\\t%0, %1, %2
3259 #"
3260 "TARGET_32BIT
3261 && CONST_INT_P (operands[2])
3262 && !(const_ok_for_arm (INTVAL (operands[2]))
3263 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3264 [(clobber (const_int 0))]
3265 {
3266 arm_split_constant (IOR, SImode, curr_insn,
3267 INTVAL (operands[2]), operands[0], operands[1], 0);
3268 DONE;
3269 }
3270 [(set_attr "length" "4,4,4,4,16")
3271 (set_attr "arch" "32,t2,t2,32,32")
3272 (set_attr "predicable" "yes")
3273 (set_attr "predicable_short_it" "no,yes,no,no,no")
3274 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3275 )
3276
3277 (define_peephole2
3278 [(match_scratch:SI 3 "r")
3279 (set (match_operand:SI 0 "arm_general_register_operand" "")
3280 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3281 (match_operand:SI 2 "const_int_operand" "")))]
3282 "TARGET_ARM
3283 && !const_ok_for_arm (INTVAL (operands[2]))
3284 && const_ok_for_arm (~INTVAL (operands[2]))"
3285 [(set (match_dup 3) (match_dup 2))
3286 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3287 ""
3288 )
3289
3290 (define_insn "*iorsi3_compare0"
3291 [(set (reg:CC_NOOV CC_REGNUM)
3292 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3293 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3294 (const_int 0)))
3295 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3296 (ior:SI (match_dup 1) (match_dup 2)))]
3297 "TARGET_32BIT"
3298 "orrs%?\\t%0, %1, %2"
3299 [(set_attr "conds" "set")
3300 (set_attr "type" "logics_imm,logics_reg")]
3301 )
3302
3303 (define_insn "*iorsi3_compare0_scratch"
3304 [(set (reg:CC_NOOV CC_REGNUM)
3305 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3306 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3307 (const_int 0)))
3308 (clobber (match_scratch:SI 0 "=r,r"))]
3309 "TARGET_32BIT"
3310 "orrs%?\\t%0, %1, %2"
3311 [(set_attr "conds" "set")
3312 (set_attr "type" "logics_imm,logics_reg")]
3313 )
3314
3315 (define_expand "xordi3"
3316 [(set (match_operand:DI 0 "s_register_operand" "")
3317 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3318 (match_operand:DI 2 "arm_xordi_operand" "")))]
3319 "TARGET_32BIT"
3320 {
3321 /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3322 to reuse this expander for all TARGET_32BIT targets so just force the
3323 constants into a register. Unlike for the anddi3 and iordi3 there are
3324 no NEON instructions that take an immediate. */
3325 if (TARGET_IWMMXT && !REG_P (operands[2]))
3326 operands[2] = force_reg (DImode, operands[2]);
3327 if (!TARGET_NEON && !TARGET_IWMMXT)
3328 {
3329 rtx low = simplify_gen_binary (XOR, SImode,
3330 gen_lowpart (SImode, operands[1]),
3331 gen_lowpart (SImode, operands[2]));
3332 rtx high = simplify_gen_binary (XOR, SImode,
3333 gen_highpart (SImode, operands[1]),
3334 gen_highpart_mode (SImode, DImode,
3335 operands[2]));
3336
3337 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3338 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3339
3340 DONE;
3341 }
3342 /* Otherwise expand pattern as above. */
3343 }
3344 )
3345
3346 (define_insn_and_split "*xordi3_insn"
3347 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3348 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3349 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3350 "TARGET_32BIT && !TARGET_IWMMXT"
3351 {
3352 switch (which_alternative)
3353 {
3354 case 1:
3355 case 2:
3356 case 3:
3357 case 4: /* fall through */
3358 return "#";
3359 case 0: /* fall through */
3360 case 5: return "veor\t%P0, %P1, %P2";
3361 default: gcc_unreachable ();
3362 }
3363 }
3364 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3365 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3366 [(set (match_dup 3) (match_dup 4))
3367 (set (match_dup 5) (match_dup 6))]
3368 "
3369 {
3370 operands[3] = gen_lowpart (SImode, operands[0]);
3371 operands[5] = gen_highpart (SImode, operands[0]);
3372
3373 operands[4] = simplify_gen_binary (XOR, SImode,
3374 gen_lowpart (SImode, operands[1]),
3375 gen_lowpart (SImode, operands[2]));
3376 operands[6] = simplify_gen_binary (XOR, SImode,
3377 gen_highpart (SImode, operands[1]),
3378 gen_highpart_mode (SImode, DImode, operands[2]));
3379
3380 }"
3381 [(set_attr "length" "*,8,8,8,8,*")
3382 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3383 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3384 )
3385
3386 (define_insn "*xordi_zesidi_di"
3387 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3388 (xor:DI (zero_extend:DI
3389 (match_operand:SI 2 "s_register_operand" "r,r"))
3390 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3391 "TARGET_32BIT"
3392 "@
3393 eor%?\\t%Q0, %Q1, %2
3394 #"
3395 [(set_attr "length" "4,8")
3396 (set_attr "predicable" "yes")
3397 (set_attr "type" "logic_reg")]
3398 )
3399
3400 (define_insn "*xordi_sesidi_di"
3401 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3402 (xor:DI (sign_extend:DI
3403 (match_operand:SI 2 "s_register_operand" "r,r"))
3404 (match_operand:DI 1 "s_register_operand" "0,r")))]
3405 "TARGET_32BIT"
3406 "#"
3407 [(set_attr "length" "8")
3408 (set_attr "predicable" "yes")
3409 (set_attr "type" "multiple")]
3410 )
3411
3412 (define_expand "xorsi3"
3413 [(set (match_operand:SI 0 "s_register_operand" "")
3414 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3415 (match_operand:SI 2 "reg_or_int_operand" "")))]
3416 "TARGET_EITHER"
3417 "if (CONST_INT_P (operands[2]))
3418 {
3419 if (TARGET_32BIT)
3420 {
3421 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3422 operands[2] = force_reg (SImode, operands[2]);
3423 else
3424 {
3425 arm_split_constant (XOR, SImode, NULL_RTX,
3426 INTVAL (operands[2]), operands[0],
3427 operands[1],
3428 optimize && can_create_pseudo_p ());
3429 DONE;
3430 }
3431 }
3432 else /* TARGET_THUMB1 */
3433 {
3434 rtx tmp = force_reg (SImode, operands[2]);
3435 if (rtx_equal_p (operands[0], operands[1]))
3436 operands[2] = tmp;
3437 else
3438 {
3439 operands[2] = operands[1];
3440 operands[1] = tmp;
3441 }
3442 }
3443 }"
3444 )
3445
3446 (define_insn_and_split "*arm_xorsi3"
3447 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3448 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3449 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3450 "TARGET_32BIT"
3451 "@
3452 eor%?\\t%0, %1, %2
3453 eor%?\\t%0, %1, %2
3454 eor%?\\t%0, %1, %2
3455 #"
3456 "TARGET_32BIT
3457 && CONST_INT_P (operands[2])
3458 && !const_ok_for_arm (INTVAL (operands[2]))"
3459 [(clobber (const_int 0))]
3460 {
3461 arm_split_constant (XOR, SImode, curr_insn,
3462 INTVAL (operands[2]), operands[0], operands[1], 0);
3463 DONE;
3464 }
3465 [(set_attr "length" "4,4,4,16")
3466 (set_attr "predicable" "yes")
3467 (set_attr "predicable_short_it" "no,yes,no,no")
3468 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3469 )
3470
3471 (define_insn "*xorsi3_compare0"
3472 [(set (reg:CC_NOOV CC_REGNUM)
3473 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3474 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3475 (const_int 0)))
3476 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3477 (xor:SI (match_dup 1) (match_dup 2)))]
3478 "TARGET_32BIT"
3479 "eors%?\\t%0, %1, %2"
3480 [(set_attr "conds" "set")
3481 (set_attr "type" "logics_imm,logics_reg")]
3482 )
3483
3484 (define_insn "*xorsi3_compare0_scratch"
3485 [(set (reg:CC_NOOV CC_REGNUM)
3486 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3487 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3488 (const_int 0)))]
3489 "TARGET_32BIT"
3490 "teq%?\\t%0, %1"
3491 [(set_attr "conds" "set")
3492 (set_attr "type" "logics_imm,logics_reg")]
3493 )
3494
3495 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3496 ; (NOT D) we can sometimes merge the final NOT into one of the following
3497 ; insns.
3498
3499 (define_split
3500 [(set (match_operand:SI 0 "s_register_operand" "")
3501 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3502 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3503 (match_operand:SI 3 "arm_rhs_operand" "")))
3504 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3505 "TARGET_32BIT"
3506 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3507 (not:SI (match_dup 3))))
3508 (set (match_dup 0) (not:SI (match_dup 4)))]
3509 ""
3510 )
3511
3512 (define_insn_and_split "*andsi_iorsi3_notsi"
3513 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3514 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3515 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3516 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3517 "TARGET_32BIT"
3518 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3519 "&& reload_completed"
3520 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3521 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3522 {
3523 /* If operands[3] is a constant make sure to fold the NOT into it
3524 to avoid creating a NOT of a CONST_INT. */
3525 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3526 if (CONST_INT_P (not_rtx))
3527 {
3528 operands[4] = operands[0];
3529 operands[5] = not_rtx;
3530 }
3531 else
3532 {
3533 operands[5] = operands[0];
3534 operands[4] = not_rtx;
3535 }
3536 }
3537 [(set_attr "length" "8")
3538 (set_attr "ce_count" "2")
3539 (set_attr "predicable" "yes")
3540 (set_attr "type" "multiple")]
3541 )
3542
3543 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3544 ; insns are available?
3545 (define_split
3546 [(set (match_operand:SI 0 "s_register_operand" "")
3547 (match_operator:SI 1 "logical_binary_operator"
3548 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3549 (match_operand:SI 3 "const_int_operand" "")
3550 (match_operand:SI 4 "const_int_operand" ""))
3551 (match_operator:SI 9 "logical_binary_operator"
3552 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3553 (match_operand:SI 6 "const_int_operand" ""))
3554 (match_operand:SI 7 "s_register_operand" "")])]))
3555 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3556 "TARGET_32BIT
3557 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3558 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3559 [(set (match_dup 8)
3560 (match_op_dup 1
3561 [(ashift:SI (match_dup 2) (match_dup 4))
3562 (match_dup 5)]))
3563 (set (match_dup 0)
3564 (match_op_dup 1
3565 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3566 (match_dup 7)]))]
3567 "
3568 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3569 ")
3570
3571 (define_split
3572 [(set (match_operand:SI 0 "s_register_operand" "")
3573 (match_operator:SI 1 "logical_binary_operator"
3574 [(match_operator:SI 9 "logical_binary_operator"
3575 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3576 (match_operand:SI 6 "const_int_operand" ""))
3577 (match_operand:SI 7 "s_register_operand" "")])
3578 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3579 (match_operand:SI 3 "const_int_operand" "")
3580 (match_operand:SI 4 "const_int_operand" ""))]))
3581 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3582 "TARGET_32BIT
3583 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3584 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3585 [(set (match_dup 8)
3586 (match_op_dup 1
3587 [(ashift:SI (match_dup 2) (match_dup 4))
3588 (match_dup 5)]))
3589 (set (match_dup 0)
3590 (match_op_dup 1
3591 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3592 (match_dup 7)]))]
3593 "
3594 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3595 ")
3596
3597 (define_split
3598 [(set (match_operand:SI 0 "s_register_operand" "")
3599 (match_operator:SI 1 "logical_binary_operator"
3600 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3601 (match_operand:SI 3 "const_int_operand" "")
3602 (match_operand:SI 4 "const_int_operand" ""))
3603 (match_operator:SI 9 "logical_binary_operator"
3604 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3605 (match_operand:SI 6 "const_int_operand" ""))
3606 (match_operand:SI 7 "s_register_operand" "")])]))
3607 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3608 "TARGET_32BIT
3609 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3610 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3611 [(set (match_dup 8)
3612 (match_op_dup 1
3613 [(ashift:SI (match_dup 2) (match_dup 4))
3614 (match_dup 5)]))
3615 (set (match_dup 0)
3616 (match_op_dup 1
3617 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3618 (match_dup 7)]))]
3619 "
3620 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3621 ")
3622
3623 (define_split
3624 [(set (match_operand:SI 0 "s_register_operand" "")
3625 (match_operator:SI 1 "logical_binary_operator"
3626 [(match_operator:SI 9 "logical_binary_operator"
3627 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3628 (match_operand:SI 6 "const_int_operand" ""))
3629 (match_operand:SI 7 "s_register_operand" "")])
3630 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3631 (match_operand:SI 3 "const_int_operand" "")
3632 (match_operand:SI 4 "const_int_operand" ""))]))
3633 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3634 "TARGET_32BIT
3635 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3636 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3637 [(set (match_dup 8)
3638 (match_op_dup 1
3639 [(ashift:SI (match_dup 2) (match_dup 4))
3640 (match_dup 5)]))
3641 (set (match_dup 0)
3642 (match_op_dup 1
3643 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3644 (match_dup 7)]))]
3645 "
3646 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3647 ")
3648 \f
3649
3650 ;; Minimum and maximum insns
3651
3652 (define_expand "smaxsi3"
3653 [(parallel [
3654 (set (match_operand:SI 0 "s_register_operand" "")
3655 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3656 (match_operand:SI 2 "arm_rhs_operand" "")))
3657 (clobber (reg:CC CC_REGNUM))])]
3658 "TARGET_32BIT"
3659 "
3660 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3661 {
3662 /* No need for a clobber of the condition code register here. */
3663 emit_insn (gen_rtx_SET (operands[0],
3664 gen_rtx_SMAX (SImode, operands[1],
3665 operands[2])));
3666 DONE;
3667 }
3668 ")
3669
3670 (define_insn "*smax_0"
3671 [(set (match_operand:SI 0 "s_register_operand" "=r")
3672 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3673 (const_int 0)))]
3674 "TARGET_32BIT"
3675 "bic%?\\t%0, %1, %1, asr #31"
3676 [(set_attr "predicable" "yes")
3677 (set_attr "type" "logic_shift_reg")]
3678 )
3679
3680 (define_insn "*smax_m1"
3681 [(set (match_operand:SI 0 "s_register_operand" "=r")
3682 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3683 (const_int -1)))]
3684 "TARGET_32BIT"
3685 "orr%?\\t%0, %1, %1, asr #31"
3686 [(set_attr "predicable" "yes")
3687 (set_attr "type" "logic_shift_reg")]
3688 )
3689
3690 (define_insn_and_split "*arm_smax_insn"
3691 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3692 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3693 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3694 (clobber (reg:CC CC_REGNUM))]
3695 "TARGET_ARM"
3696 "#"
3697 ; cmp\\t%1, %2\;movlt\\t%0, %2
3698 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3699 "TARGET_ARM"
3700 [(set (reg:CC CC_REGNUM)
3701 (compare:CC (match_dup 1) (match_dup 2)))
3702 (set (match_dup 0)
3703 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3704 (match_dup 1)
3705 (match_dup 2)))]
3706 ""
3707 [(set_attr "conds" "clob")
3708 (set_attr "length" "8,12")
3709 (set_attr "type" "multiple")]
3710 )
3711
3712 (define_expand "sminsi3"
3713 [(parallel [
3714 (set (match_operand:SI 0 "s_register_operand" "")
3715 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3716 (match_operand:SI 2 "arm_rhs_operand" "")))
3717 (clobber (reg:CC CC_REGNUM))])]
3718 "TARGET_32BIT"
3719 "
3720 if (operands[2] == const0_rtx)
3721 {
3722 /* No need for a clobber of the condition code register here. */
3723 emit_insn (gen_rtx_SET (operands[0],
3724 gen_rtx_SMIN (SImode, operands[1],
3725 operands[2])));
3726 DONE;
3727 }
3728 ")
3729
3730 (define_insn "*smin_0"
3731 [(set (match_operand:SI 0 "s_register_operand" "=r")
3732 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3733 (const_int 0)))]
3734 "TARGET_32BIT"
3735 "and%?\\t%0, %1, %1, asr #31"
3736 [(set_attr "predicable" "yes")
3737 (set_attr "type" "logic_shift_reg")]
3738 )
3739
3740 (define_insn_and_split "*arm_smin_insn"
3741 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3742 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3743 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3744 (clobber (reg:CC CC_REGNUM))]
3745 "TARGET_ARM"
3746 "#"
3747 ; cmp\\t%1, %2\;movge\\t%0, %2
3748 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3749 "TARGET_ARM"
3750 [(set (reg:CC CC_REGNUM)
3751 (compare:CC (match_dup 1) (match_dup 2)))
3752 (set (match_dup 0)
3753 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3754 (match_dup 1)
3755 (match_dup 2)))]
3756 ""
3757 [(set_attr "conds" "clob")
3758 (set_attr "length" "8,12")
3759 (set_attr "type" "multiple,multiple")]
3760 )
3761
3762 (define_expand "umaxsi3"
3763 [(parallel [
3764 (set (match_operand:SI 0 "s_register_operand" "")
3765 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3766 (match_operand:SI 2 "arm_rhs_operand" "")))
3767 (clobber (reg:CC CC_REGNUM))])]
3768 "TARGET_32BIT"
3769 ""
3770 )
3771
3772 (define_insn_and_split "*arm_umaxsi3"
3773 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3774 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3775 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3776 (clobber (reg:CC CC_REGNUM))]
3777 "TARGET_ARM"
3778 "#"
3779 ; cmp\\t%1, %2\;movcc\\t%0, %2
3780 ; cmp\\t%1, %2\;movcs\\t%0, %1
3781 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3782 "TARGET_ARM"
3783 [(set (reg:CC CC_REGNUM)
3784 (compare:CC (match_dup 1) (match_dup 2)))
3785 (set (match_dup 0)
3786 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3787 (match_dup 1)
3788 (match_dup 2)))]
3789 ""
3790 [(set_attr "conds" "clob")
3791 (set_attr "length" "8,8,12")
3792 (set_attr "type" "store_4")]
3793 )
3794
3795 (define_expand "uminsi3"
3796 [(parallel [
3797 (set (match_operand:SI 0 "s_register_operand" "")
3798 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3799 (match_operand:SI 2 "arm_rhs_operand" "")))
3800 (clobber (reg:CC CC_REGNUM))])]
3801 "TARGET_32BIT"
3802 ""
3803 )
3804
3805 (define_insn_and_split "*arm_uminsi3"
3806 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3807 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3808 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3809 (clobber (reg:CC CC_REGNUM))]
3810 "TARGET_ARM"
3811 "#"
3812 ; cmp\\t%1, %2\;movcs\\t%0, %2
3813 ; cmp\\t%1, %2\;movcc\\t%0, %1
3814 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3815 "TARGET_ARM"
3816 [(set (reg:CC CC_REGNUM)
3817 (compare:CC (match_dup 1) (match_dup 2)))
3818 (set (match_dup 0)
3819 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3820 (match_dup 1)
3821 (match_dup 2)))]
3822 ""
3823 [(set_attr "conds" "clob")
3824 (set_attr "length" "8,8,12")
3825 (set_attr "type" "store_4")]
3826 )
3827
3828 (define_insn "*store_minmaxsi"
3829 [(set (match_operand:SI 0 "memory_operand" "=m")
3830 (match_operator:SI 3 "minmax_operator"
3831 [(match_operand:SI 1 "s_register_operand" "r")
3832 (match_operand:SI 2 "s_register_operand" "r")]))
3833 (clobber (reg:CC CC_REGNUM))]
3834 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3835 "*
3836 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3837 operands[1], operands[2]);
3838 output_asm_insn (\"cmp\\t%1, %2\", operands);
3839 if (TARGET_THUMB2)
3840 output_asm_insn (\"ite\t%d3\", operands);
3841 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3842 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3843 return \"\";
3844 "
3845 [(set_attr "conds" "clob")
3846 (set (attr "length")
3847 (if_then_else (eq_attr "is_thumb" "yes")
3848 (const_int 14)
3849 (const_int 12)))
3850 (set_attr "type" "store_4")]
3851 )
3852
3853 ; Reject the frame pointer in operand[1], since reloading this after
3854 ; it has been eliminated can cause carnage.
3855 (define_insn "*minmax_arithsi"
3856 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3857 (match_operator:SI 4 "shiftable_operator"
3858 [(match_operator:SI 5 "minmax_operator"
3859 [(match_operand:SI 2 "s_register_operand" "r,r")
3860 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3861 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3862 (clobber (reg:CC CC_REGNUM))]
3863 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3864 "*
3865 {
3866 enum rtx_code code = GET_CODE (operands[4]);
3867 bool need_else;
3868
3869 if (which_alternative != 0 || operands[3] != const0_rtx
3870 || (code != PLUS && code != IOR && code != XOR))
3871 need_else = true;
3872 else
3873 need_else = false;
3874
3875 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3876 operands[2], operands[3]);
3877 output_asm_insn (\"cmp\\t%2, %3\", operands);
3878 if (TARGET_THUMB2)
3879 {
3880 if (need_else)
3881 output_asm_insn (\"ite\\t%d5\", operands);
3882 else
3883 output_asm_insn (\"it\\t%d5\", operands);
3884 }
3885 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3886 if (need_else)
3887 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3888 return \"\";
3889 }"
3890 [(set_attr "conds" "clob")
3891 (set (attr "length")
3892 (if_then_else (eq_attr "is_thumb" "yes")
3893 (const_int 14)
3894 (const_int 12)))
3895 (set_attr "type" "multiple")]
3896 )
3897
3898 ; Reject the frame pointer in operand[1], since reloading this after
3899 ; it has been eliminated can cause carnage.
3900 (define_insn_and_split "*minmax_arithsi_non_canon"
3901 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3902 (minus:SI
3903 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3904 (match_operator:SI 4 "minmax_operator"
3905 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3906 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3907 (clobber (reg:CC CC_REGNUM))]
3908 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3909 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3910 "#"
3911 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3912 [(set (reg:CC CC_REGNUM)
3913 (compare:CC (match_dup 2) (match_dup 3)))
3914
3915 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3916 (set (match_dup 0)
3917 (minus:SI (match_dup 1)
3918 (match_dup 2))))
3919 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3920 (set (match_dup 0)
3921 (match_dup 6)))]
3922 {
3923 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3924 operands[2], operands[3]);
3925 enum rtx_code rc = minmax_code (operands[4]);
3926 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3927 operands[2], operands[3]);
3928
3929 if (mode == CCFPmode || mode == CCFPEmode)
3930 rc = reverse_condition_maybe_unordered (rc);
3931 else
3932 rc = reverse_condition (rc);
3933 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3934 if (CONST_INT_P (operands[3]))
3935 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3936 else
3937 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3938 }
3939 [(set_attr "conds" "clob")
3940 (set (attr "length")
3941 (if_then_else (eq_attr "is_thumb" "yes")
3942 (const_int 14)
3943 (const_int 12)))
3944 (set_attr "type" "multiple")]
3945 )
3946
3947 (define_code_iterator SAT [smin smax])
3948 (define_code_iterator SATrev [smin smax])
3949 (define_code_attr SATlo [(smin "1") (smax "2")])
3950 (define_code_attr SAThi [(smin "2") (smax "1")])
3951
3952 (define_insn "*satsi_<SAT:code>"
3953 [(set (match_operand:SI 0 "s_register_operand" "=r")
3954 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3955 (match_operand:SI 1 "const_int_operand" "i"))
3956 (match_operand:SI 2 "const_int_operand" "i")))]
3957 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3958 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3959 {
3960 int mask;
3961 bool signed_sat;
3962 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3963 &mask, &signed_sat))
3964 gcc_unreachable ();
3965
3966 operands[1] = GEN_INT (mask);
3967 if (signed_sat)
3968 return "ssat%?\t%0, %1, %3";
3969 else
3970 return "usat%?\t%0, %1, %3";
3971 }
3972 [(set_attr "predicable" "yes")
3973 (set_attr "type" "alus_imm")]
3974 )
3975
3976 (define_insn "*satsi_<SAT:code>_shift"
3977 [(set (match_operand:SI 0 "s_register_operand" "=r")
3978 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3979 [(match_operand:SI 4 "s_register_operand" "r")
3980 (match_operand:SI 5 "const_int_operand" "i")])
3981 (match_operand:SI 1 "const_int_operand" "i"))
3982 (match_operand:SI 2 "const_int_operand" "i")))]
3983 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3984 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3985 {
3986 int mask;
3987 bool signed_sat;
3988 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3989 &mask, &signed_sat))
3990 gcc_unreachable ();
3991
3992 operands[1] = GEN_INT (mask);
3993 if (signed_sat)
3994 return "ssat%?\t%0, %1, %4%S3";
3995 else
3996 return "usat%?\t%0, %1, %4%S3";
3997 }
3998 [(set_attr "predicable" "yes")
3999 (set_attr "shift" "3")
4000 (set_attr "type" "logic_shift_reg")])
4001 \f
4002 ;; Shift and rotation insns
4003
4004 (define_expand "ashldi3"
4005 [(set (match_operand:DI 0 "s_register_operand" "")
4006 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
4007 (match_operand:SI 2 "general_operand" "")))]
4008 "TARGET_32BIT"
4009 "
4010 if (TARGET_NEON)
4011 {
4012 /* Delay the decision whether to use NEON or core-regs until
4013 register allocation. */
4014 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4015 DONE;
4016 }
4017 else
4018 {
4019 /* Only the NEON case can handle in-memory shift counts. */
4020 if (!reg_or_int_operand (operands[2], SImode))
4021 operands[2] = force_reg (SImode, operands[2]);
4022 }
4023
4024 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4025 ; /* No special preparation statements; expand pattern as above. */
4026 else
4027 {
4028 rtx scratch1, scratch2;
4029
4030 /* Ideally we should use iwmmxt here if we could know that operands[1]
4031 ends up already living in an iwmmxt register. Otherwise it's
4032 cheaper to have the alternate code being generated than moving
4033 values to iwmmxt regs and back. */
4034
4035 /* Expand operation using core-registers.
4036 'FAIL' would achieve the same thing, but this is a bit smarter. */
4037 scratch1 = gen_reg_rtx (SImode);
4038 scratch2 = gen_reg_rtx (SImode);
4039 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4040 operands[2], scratch1, scratch2);
4041 DONE;
4042 }
4043 "
4044 )
4045
4046 (define_expand "ashlsi3"
4047 [(set (match_operand:SI 0 "s_register_operand" "")
4048 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4049 (match_operand:SI 2 "arm_rhs_operand" "")))]
4050 "TARGET_EITHER"
4051 "
4052 if (CONST_INT_P (operands[2])
4053 && (UINTVAL (operands[2])) > 31)
4054 {
4055 emit_insn (gen_movsi (operands[0], const0_rtx));
4056 DONE;
4057 }
4058 "
4059 )
4060
4061 (define_expand "ashrdi3"
4062 [(set (match_operand:DI 0 "s_register_operand" "")
4063 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4064 (match_operand:SI 2 "reg_or_int_operand" "")))]
4065 "TARGET_32BIT"
4066 "
4067 if (TARGET_NEON)
4068 {
4069 /* Delay the decision whether to use NEON or core-regs until
4070 register allocation. */
4071 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4072 DONE;
4073 }
4074
4075 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4076 ; /* No special preparation statements; expand pattern as above. */
4077 else
4078 {
4079 rtx scratch1, scratch2;
4080
4081 /* Ideally we should use iwmmxt here if we could know that operands[1]
4082 ends up already living in an iwmmxt register. Otherwise it's
4083 cheaper to have the alternate code being generated than moving
4084 values to iwmmxt regs and back. */
4085
4086 /* Expand operation using core-registers.
4087 'FAIL' would achieve the same thing, but this is a bit smarter. */
4088 scratch1 = gen_reg_rtx (SImode);
4089 scratch2 = gen_reg_rtx (SImode);
4090 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4091 operands[2], scratch1, scratch2);
4092 DONE;
4093 }
4094 "
4095 )
4096
4097 (define_expand "ashrsi3"
4098 [(set (match_operand:SI 0 "s_register_operand" "")
4099 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4100 (match_operand:SI 2 "arm_rhs_operand" "")))]
4101 "TARGET_EITHER"
4102 "
4103 if (CONST_INT_P (operands[2])
4104 && UINTVAL (operands[2]) > 31)
4105 operands[2] = GEN_INT (31);
4106 "
4107 )
4108
4109 (define_expand "lshrdi3"
4110 [(set (match_operand:DI 0 "s_register_operand" "")
4111 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4112 (match_operand:SI 2 "reg_or_int_operand" "")))]
4113 "TARGET_32BIT"
4114 "
4115 if (TARGET_NEON)
4116 {
4117 /* Delay the decision whether to use NEON or core-regs until
4118 register allocation. */
4119 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4120 DONE;
4121 }
4122
4123 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4124 ; /* No special preparation statements; expand pattern as above. */
4125 else
4126 {
4127 rtx scratch1, scratch2;
4128
4129 /* Ideally we should use iwmmxt here if we could know that operands[1]
4130 ends up already living in an iwmmxt register. Otherwise it's
4131 cheaper to have the alternate code being generated than moving
4132 values to iwmmxt regs and back. */
4133
4134 /* Expand operation using core-registers.
4135 'FAIL' would achieve the same thing, but this is a bit smarter. */
4136 scratch1 = gen_reg_rtx (SImode);
4137 scratch2 = gen_reg_rtx (SImode);
4138 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4139 operands[2], scratch1, scratch2);
4140 DONE;
4141 }
4142 "
4143 )
4144
4145 (define_expand "lshrsi3"
4146 [(set (match_operand:SI 0 "s_register_operand" "")
4147 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4148 (match_operand:SI 2 "arm_rhs_operand" "")))]
4149 "TARGET_EITHER"
4150 "
4151 if (CONST_INT_P (operands[2])
4152 && (UINTVAL (operands[2])) > 31)
4153 {
4154 emit_insn (gen_movsi (operands[0], const0_rtx));
4155 DONE;
4156 }
4157 "
4158 )
4159
4160 (define_expand "rotlsi3"
4161 [(set (match_operand:SI 0 "s_register_operand" "")
4162 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4163 (match_operand:SI 2 "reg_or_int_operand" "")))]
4164 "TARGET_32BIT"
4165 "
4166 if (CONST_INT_P (operands[2]))
4167 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4168 else
4169 {
4170 rtx reg = gen_reg_rtx (SImode);
4171 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4172 operands[2] = reg;
4173 }
4174 "
4175 )
4176
4177 (define_expand "rotrsi3"
4178 [(set (match_operand:SI 0 "s_register_operand" "")
4179 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4180 (match_operand:SI 2 "arm_rhs_operand" "")))]
4181 "TARGET_EITHER"
4182 "
4183 if (TARGET_32BIT)
4184 {
4185 if (CONST_INT_P (operands[2])
4186 && UINTVAL (operands[2]) > 31)
4187 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4188 }
4189 else /* TARGET_THUMB1 */
4190 {
4191 if (CONST_INT_P (operands [2]))
4192 operands [2] = force_reg (SImode, operands[2]);
4193 }
4194 "
4195 )
4196
4197 (define_insn "*arm_shiftsi3"
4198 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4199 (match_operator:SI 3 "shift_operator"
4200 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4201 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4202 "TARGET_32BIT"
4203 "* return arm_output_shift(operands, 0);"
4204 [(set_attr "predicable" "yes")
4205 (set_attr "arch" "t2,t2,*,*")
4206 (set_attr "predicable_short_it" "yes,yes,no,no")
4207 (set_attr "length" "4")
4208 (set_attr "shift" "1")
4209 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4210 )
4211
4212 (define_insn "*shiftsi3_compare0"
4213 [(set (reg:CC_NOOV CC_REGNUM)
4214 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4215 [(match_operand:SI 1 "s_register_operand" "r,r")
4216 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4217 (const_int 0)))
4218 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4219 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4220 "TARGET_32BIT"
4221 "* return arm_output_shift(operands, 1);"
4222 [(set_attr "conds" "set")
4223 (set_attr "shift" "1")
4224 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4225 )
4226
4227 (define_insn "*shiftsi3_compare0_scratch"
4228 [(set (reg:CC_NOOV CC_REGNUM)
4229 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4230 [(match_operand:SI 1 "s_register_operand" "r,r")
4231 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4232 (const_int 0)))
4233 (clobber (match_scratch:SI 0 "=r,r"))]
4234 "TARGET_32BIT"
4235 "* return arm_output_shift(operands, 1);"
4236 [(set_attr "conds" "set")
4237 (set_attr "shift" "1")
4238 (set_attr "type" "shift_imm,shift_reg")]
4239 )
4240
4241 (define_insn "*not_shiftsi"
4242 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4243 (not:SI (match_operator:SI 3 "shift_operator"
4244 [(match_operand:SI 1 "s_register_operand" "r,r")
4245 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4246 "TARGET_32BIT"
4247 "mvn%?\\t%0, %1%S3"
4248 [(set_attr "predicable" "yes")
4249 (set_attr "shift" "1")
4250 (set_attr "arch" "32,a")
4251 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4252
4253 (define_insn "*not_shiftsi_compare0"
4254 [(set (reg:CC_NOOV CC_REGNUM)
4255 (compare:CC_NOOV
4256 (not:SI (match_operator:SI 3 "shift_operator"
4257 [(match_operand:SI 1 "s_register_operand" "r,r")
4258 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4259 (const_int 0)))
4260 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4261 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4262 "TARGET_32BIT"
4263 "mvns%?\\t%0, %1%S3"
4264 [(set_attr "conds" "set")
4265 (set_attr "shift" "1")
4266 (set_attr "arch" "32,a")
4267 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4268
4269 (define_insn "*not_shiftsi_compare0_scratch"
4270 [(set (reg:CC_NOOV CC_REGNUM)
4271 (compare:CC_NOOV
4272 (not:SI (match_operator:SI 3 "shift_operator"
4273 [(match_operand:SI 1 "s_register_operand" "r,r")
4274 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4275 (const_int 0)))
4276 (clobber (match_scratch:SI 0 "=r,r"))]
4277 "TARGET_32BIT"
4278 "mvns%?\\t%0, %1%S3"
4279 [(set_attr "conds" "set")
4280 (set_attr "shift" "1")
4281 (set_attr "arch" "32,a")
4282 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4283
4284 ;; We don't really have extzv, but defining this using shifts helps
4285 ;; to reduce register pressure later on.
4286
4287 (define_expand "extzv"
4288 [(set (match_operand 0 "s_register_operand" "")
4289 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4290 (match_operand 2 "const_int_operand" "")
4291 (match_operand 3 "const_int_operand" "")))]
4292 "TARGET_THUMB1 || arm_arch_thumb2"
4293 "
4294 {
4295 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4296 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4297
4298 if (arm_arch_thumb2)
4299 {
4300 HOST_WIDE_INT width = INTVAL (operands[2]);
4301 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4302
4303 if (unaligned_access && MEM_P (operands[1])
4304 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4305 {
4306 rtx base_addr;
4307
4308 if (BYTES_BIG_ENDIAN)
4309 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4310 - bitpos;
4311
4312 if (width == 32)
4313 {
4314 base_addr = adjust_address (operands[1], SImode,
4315 bitpos / BITS_PER_UNIT);
4316 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4317 }
4318 else
4319 {
4320 rtx dest = operands[0];
4321 rtx tmp = gen_reg_rtx (SImode);
4322
4323 /* We may get a paradoxical subreg here. Strip it off. */
4324 if (GET_CODE (dest) == SUBREG
4325 && GET_MODE (dest) == SImode
4326 && GET_MODE (SUBREG_REG (dest)) == HImode)
4327 dest = SUBREG_REG (dest);
4328
4329 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4330 FAIL;
4331
4332 base_addr = adjust_address (operands[1], HImode,
4333 bitpos / BITS_PER_UNIT);
4334 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4335 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4336 }
4337 DONE;
4338 }
4339 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4340 {
4341 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4342 operands[3]));
4343 DONE;
4344 }
4345 else
4346 FAIL;
4347 }
4348
4349 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4350 FAIL;
4351
4352 operands[3] = GEN_INT (rshift);
4353
4354 if (lshift == 0)
4355 {
4356 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4357 DONE;
4358 }
4359
4360 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4361 operands[3], gen_reg_rtx (SImode)));
4362 DONE;
4363 }"
4364 )
4365
4366 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4367
4368 (define_expand "extzv_t1"
4369 [(set (match_operand:SI 4 "s_register_operand" "")
4370 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4371 (match_operand:SI 2 "const_int_operand" "")))
4372 (set (match_operand:SI 0 "s_register_operand" "")
4373 (lshiftrt:SI (match_dup 4)
4374 (match_operand:SI 3 "const_int_operand" "")))]
4375 "TARGET_THUMB1"
4376 "")
4377
4378 (define_expand "extv"
4379 [(set (match_operand 0 "s_register_operand" "")
4380 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4381 (match_operand 2 "const_int_operand" "")
4382 (match_operand 3 "const_int_operand" "")))]
4383 "arm_arch_thumb2"
4384 {
4385 HOST_WIDE_INT width = INTVAL (operands[2]);
4386 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4387
4388 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4389 && (bitpos % BITS_PER_UNIT) == 0)
4390 {
4391 rtx base_addr;
4392
4393 if (BYTES_BIG_ENDIAN)
4394 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4395
4396 if (width == 32)
4397 {
4398 base_addr = adjust_address (operands[1], SImode,
4399 bitpos / BITS_PER_UNIT);
4400 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4401 }
4402 else
4403 {
4404 rtx dest = operands[0];
4405 rtx tmp = gen_reg_rtx (SImode);
4406
4407 /* We may get a paradoxical subreg here. Strip it off. */
4408 if (GET_CODE (dest) == SUBREG
4409 && GET_MODE (dest) == SImode
4410 && GET_MODE (SUBREG_REG (dest)) == HImode)
4411 dest = SUBREG_REG (dest);
4412
4413 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4414 FAIL;
4415
4416 base_addr = adjust_address (operands[1], HImode,
4417 bitpos / BITS_PER_UNIT);
4418 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4419 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4420 }
4421
4422 DONE;
4423 }
4424 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4425 FAIL;
4426 else if (GET_MODE (operands[0]) == SImode
4427 && GET_MODE (operands[1]) == SImode)
4428 {
4429 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4430 operands[3]));
4431 DONE;
4432 }
4433
4434 FAIL;
4435 })
4436
4437 ; Helper to expand register forms of extv with the proper modes.
4438
4439 (define_expand "extv_regsi"
4440 [(set (match_operand:SI 0 "s_register_operand" "")
4441 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4442 (match_operand 2 "const_int_operand" "")
4443 (match_operand 3 "const_int_operand" "")))]
4444 ""
4445 {
4446 })
4447
4448 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4449
4450 (define_insn "unaligned_loadsi"
4451 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4452 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4453 UNSPEC_UNALIGNED_LOAD))]
4454 "unaligned_access"
4455 "ldr%?\t%0, %1\t@ unaligned"
4456 [(set_attr "arch" "t2,any")
4457 (set_attr "length" "2,4")
4458 (set_attr "predicable" "yes")
4459 (set_attr "predicable_short_it" "yes,no")
4460 (set_attr "type" "load_4")])
4461
4462 (define_insn "unaligned_loadhis"
4463 [(set (match_operand:SI 0 "s_register_operand" "=r")
4464 (sign_extend:SI
4465 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
4466 UNSPEC_UNALIGNED_LOAD)))]
4467 "unaligned_access"
4468 "ldrsh%?\t%0, %1\t@ unaligned"
4469 [(set_attr "predicable" "yes")
4470 (set_attr "type" "load_byte")])
4471
4472 (define_insn "unaligned_loadhiu"
4473 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4474 (zero_extend:SI
4475 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4476 UNSPEC_UNALIGNED_LOAD)))]
4477 "unaligned_access"
4478 "ldrh%?\t%0, %1\t@ unaligned"
4479 [(set_attr "arch" "t2,any")
4480 (set_attr "length" "2,4")
4481 (set_attr "predicable" "yes")
4482 (set_attr "predicable_short_it" "yes,no")
4483 (set_attr "type" "load_byte")])
4484
4485 (define_insn "unaligned_storesi"
4486 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4487 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4488 UNSPEC_UNALIGNED_STORE))]
4489 "unaligned_access"
4490 "str%?\t%1, %0\t@ unaligned"
4491 [(set_attr "arch" "t2,any")
4492 (set_attr "length" "2,4")
4493 (set_attr "predicable" "yes")
4494 (set_attr "predicable_short_it" "yes,no")
4495 (set_attr "type" "store_4")])
4496
4497 (define_insn "unaligned_storehi"
4498 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4499 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4500 UNSPEC_UNALIGNED_STORE))]
4501 "unaligned_access"
4502 "strh%?\t%1, %0\t@ unaligned"
4503 [(set_attr "arch" "t2,any")
4504 (set_attr "length" "2,4")
4505 (set_attr "predicable" "yes")
4506 (set_attr "predicable_short_it" "yes,no")
4507 (set_attr "type" "store_4")])
4508
4509
4510 (define_insn "*extv_reg"
4511 [(set (match_operand:SI 0 "s_register_operand" "=r")
4512 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4513 (match_operand:SI 2 "const_int_operand" "n")
4514 (match_operand:SI 3 "const_int_operand" "n")))]
4515 "arm_arch_thumb2
4516 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4517 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4518 "sbfx%?\t%0, %1, %3, %2"
4519 [(set_attr "length" "4")
4520 (set_attr "predicable" "yes")
4521 (set_attr "type" "bfm")]
4522 )
4523
4524 (define_insn "extzv_t2"
4525 [(set (match_operand:SI 0 "s_register_operand" "=r")
4526 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4527 (match_operand:SI 2 "const_int_operand" "n")
4528 (match_operand:SI 3 "const_int_operand" "n")))]
4529 "arm_arch_thumb2
4530 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4531 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4532 "ubfx%?\t%0, %1, %3, %2"
4533 [(set_attr "length" "4")
4534 (set_attr "predicable" "yes")
4535 (set_attr "type" "bfm")]
4536 )
4537
4538
4539 ;; Division instructions
4540 (define_insn "divsi3"
4541 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4542 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4543 (match_operand:SI 2 "s_register_operand" "r,r")))]
4544 "TARGET_IDIV"
4545 "@
4546 sdiv%?\t%0, %1, %2
4547 sdiv\t%0, %1, %2"
4548 [(set_attr "arch" "32,v8mb")
4549 (set_attr "predicable" "yes")
4550 (set_attr "type" "sdiv")]
4551 )
4552
4553 (define_insn "udivsi3"
4554 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4555 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4556 (match_operand:SI 2 "s_register_operand" "r,r")))]
4557 "TARGET_IDIV"
4558 "@
4559 udiv%?\t%0, %1, %2
4560 udiv\t%0, %1, %2"
4561 [(set_attr "arch" "32,v8mb")
4562 (set_attr "predicable" "yes")
4563 (set_attr "type" "udiv")]
4564 )
4565
4566 \f
4567 ;; Unary arithmetic insns
4568
4569 (define_expand "negvsi3"
4570 [(match_operand:SI 0 "register_operand")
4571 (match_operand:SI 1 "register_operand")
4572 (match_operand 2 "")]
4573 "TARGET_32BIT"
4574 {
4575 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4576 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4577
4578 DONE;
4579 })
4580
4581 (define_expand "negvdi3"
4582 [(match_operand:DI 0 "register_operand")
4583 (match_operand:DI 1 "register_operand")
4584 (match_operand 2 "")]
4585 "TARGET_ARM"
4586 {
4587 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4588 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4589
4590 DONE;
4591 })
4592
4593
4594 (define_insn_and_split "negdi2_compare"
4595 [(set (reg:CC CC_REGNUM)
4596 (compare:CC
4597 (const_int 0)
4598 (match_operand:DI 1 "register_operand" "0,r")))
4599 (set (match_operand:DI 0 "register_operand" "=r,&r")
4600 (minus:DI (const_int 0) (match_dup 1)))]
4601 "TARGET_ARM"
4602 "#"
4603 "&& reload_completed"
4604 [(parallel [(set (reg:CC CC_REGNUM)
4605 (compare:CC (const_int 0) (match_dup 1)))
4606 (set (match_dup 0) (minus:SI (const_int 0)
4607 (match_dup 1)))])
4608 (parallel [(set (reg:CC CC_REGNUM)
4609 (compare:CC (const_int 0) (match_dup 3)))
4610 (set (match_dup 2)
4611 (minus:SI
4612 (minus:SI (const_int 0) (match_dup 3))
4613 (ltu:SI (reg:CC_C CC_REGNUM)
4614 (const_int 0))))])]
4615 {
4616 operands[2] = gen_highpart (SImode, operands[0]);
4617 operands[0] = gen_lowpart (SImode, operands[0]);
4618 operands[3] = gen_highpart (SImode, operands[1]);
4619 operands[1] = gen_lowpart (SImode, operands[1]);
4620 }
4621 [(set_attr "conds" "set")
4622 (set_attr "length" "8")
4623 (set_attr "type" "multiple")]
4624 )
4625
4626 (define_expand "negdi2"
4627 [(parallel
4628 [(set (match_operand:DI 0 "s_register_operand" "")
4629 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4630 (clobber (reg:CC CC_REGNUM))])]
4631 "TARGET_EITHER"
4632 {
4633 if (TARGET_NEON)
4634 {
4635 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4636 DONE;
4637 }
4638 }
4639 )
4640
4641 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4642 ;; The first alternative allows the common case of a *full* overlap.
4643 (define_insn_and_split "*negdi2_insn"
4644 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4645 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4646 (clobber (reg:CC CC_REGNUM))]
4647 "TARGET_32BIT"
4648 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4649 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4650 "&& reload_completed"
4651 [(parallel [(set (reg:CC CC_REGNUM)
4652 (compare:CC (const_int 0) (match_dup 1)))
4653 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4654 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4655 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4656 {
4657 operands[2] = gen_highpart (SImode, operands[0]);
4658 operands[0] = gen_lowpart (SImode, operands[0]);
4659 operands[3] = gen_highpart (SImode, operands[1]);
4660 operands[1] = gen_lowpart (SImode, operands[1]);
4661 }
4662 [(set_attr "conds" "clob")
4663 (set_attr "length" "8")
4664 (set_attr "type" "multiple")]
4665 )
4666
4667 (define_insn "*negsi2_carryin_compare"
4668 [(set (reg:CC CC_REGNUM)
4669 (compare:CC (const_int 0)
4670 (match_operand:SI 1 "s_register_operand" "r")))
4671 (set (match_operand:SI 0 "s_register_operand" "=r")
4672 (minus:SI (minus:SI (const_int 0)
4673 (match_dup 1))
4674 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4675 "TARGET_ARM"
4676 "rscs\\t%0, %1, #0"
4677 [(set_attr "conds" "set")
4678 (set_attr "type" "alus_imm")]
4679 )
4680
4681 (define_expand "negsi2"
4682 [(set (match_operand:SI 0 "s_register_operand" "")
4683 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4684 "TARGET_EITHER"
4685 ""
4686 )
4687
4688 (define_insn "*arm_negsi2"
4689 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4690 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4691 "TARGET_32BIT"
4692 "rsb%?\\t%0, %1, #0"
4693 [(set_attr "predicable" "yes")
4694 (set_attr "predicable_short_it" "yes,no")
4695 (set_attr "arch" "t2,*")
4696 (set_attr "length" "4")
4697 (set_attr "type" "alu_sreg")]
4698 )
4699
4700 (define_expand "negsf2"
4701 [(set (match_operand:SF 0 "s_register_operand" "")
4702 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4703 "TARGET_32BIT && TARGET_HARD_FLOAT"
4704 ""
4705 )
4706
4707 (define_expand "negdf2"
4708 [(set (match_operand:DF 0 "s_register_operand" "")
4709 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4710 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4711 "")
4712
4713 (define_insn_and_split "*zextendsidi_negsi"
4714 [(set (match_operand:DI 0 "s_register_operand" "=r")
4715 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4716 "TARGET_32BIT"
4717 "#"
4718 ""
4719 [(set (match_dup 2)
4720 (neg:SI (match_dup 1)))
4721 (set (match_dup 3)
4722 (const_int 0))]
4723 {
4724 operands[2] = gen_lowpart (SImode, operands[0]);
4725 operands[3] = gen_highpart (SImode, operands[0]);
4726 }
4727 [(set_attr "length" "8")
4728 (set_attr "type" "multiple")]
4729 )
4730
4731 ;; Negate an extended 32-bit value.
4732 (define_insn_and_split "*negdi_extendsidi"
4733 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4734 (neg:DI (sign_extend:DI
4735 (match_operand:SI 1 "s_register_operand" "l,r"))))
4736 (clobber (reg:CC CC_REGNUM))]
4737 "TARGET_32BIT"
4738 "#"
4739 "&& reload_completed"
4740 [(const_int 0)]
4741 {
4742 rtx low = gen_lowpart (SImode, operands[0]);
4743 rtx high = gen_highpart (SImode, operands[0]);
4744
4745 if (reg_overlap_mentioned_p (low, operands[1]))
4746 {
4747 /* Input overlaps the low word of the output. Use:
4748 asr Rhi, Rin, #31
4749 rsbs Rlo, Rin, #0
4750 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4751 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4752
4753 emit_insn (gen_rtx_SET (high,
4754 gen_rtx_ASHIFTRT (SImode, operands[1],
4755 GEN_INT (31))));
4756
4757 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4758 if (TARGET_ARM)
4759 emit_insn (gen_rtx_SET (high,
4760 gen_rtx_MINUS (SImode,
4761 gen_rtx_MINUS (SImode,
4762 const0_rtx,
4763 high),
4764 gen_rtx_LTU (SImode,
4765 cc_reg,
4766 const0_rtx))));
4767 else
4768 {
4769 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4770 emit_insn (gen_rtx_SET (high,
4771 gen_rtx_MINUS (SImode,
4772 gen_rtx_MINUS (SImode,
4773 high,
4774 two_x),
4775 gen_rtx_LTU (SImode,
4776 cc_reg,
4777 const0_rtx))));
4778 }
4779 }
4780 else
4781 {
4782 /* No overlap, or overlap on high word. Use:
4783 rsb Rlo, Rin, #0
4784 bic Rhi, Rlo, Rin
4785 asr Rhi, Rhi, #31
4786 Flags not needed for this sequence. */
4787 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4788 emit_insn (gen_rtx_SET (high,
4789 gen_rtx_AND (SImode,
4790 gen_rtx_NOT (SImode, operands[1]),
4791 low)));
4792 emit_insn (gen_rtx_SET (high,
4793 gen_rtx_ASHIFTRT (SImode, high,
4794 GEN_INT (31))));
4795 }
4796 DONE;
4797 }
4798 [(set_attr "length" "12")
4799 (set_attr "arch" "t2,*")
4800 (set_attr "type" "multiple")]
4801 )
4802
4803 (define_insn_and_split "*negdi_zero_extendsidi"
4804 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4805 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4806 (clobber (reg:CC CC_REGNUM))]
4807 "TARGET_32BIT"
4808 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4809 ;; Don't care what register is input to sbc,
4810 ;; since we just need to propagate the carry.
4811 "&& reload_completed"
4812 [(parallel [(set (reg:CC CC_REGNUM)
4813 (compare:CC (const_int 0) (match_dup 1)))
4814 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4815 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4816 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4817 {
4818 operands[2] = gen_highpart (SImode, operands[0]);
4819 operands[0] = gen_lowpart (SImode, operands[0]);
4820 }
4821 [(set_attr "conds" "clob")
4822 (set_attr "length" "8")
4823 (set_attr "type" "multiple")] ;; length in thumb is 4
4824 )
4825
4826 ;; abssi2 doesn't really clobber the condition codes if a different register
4827 ;; is being set. To keep things simple, assume during rtl manipulations that
4828 ;; it does, but tell the final scan operator the truth. Similarly for
4829 ;; (neg (abs...))
4830
4831 (define_expand "abssi2"
4832 [(parallel
4833 [(set (match_operand:SI 0 "s_register_operand" "")
4834 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4835 (clobber (match_dup 2))])]
4836 "TARGET_EITHER"
4837 "
4838 if (TARGET_THUMB1)
4839 operands[2] = gen_rtx_SCRATCH (SImode);
4840 else
4841 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4842 ")
4843
4844 (define_insn_and_split "*arm_abssi2"
4845 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4846 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4847 (clobber (reg:CC CC_REGNUM))]
4848 "TARGET_ARM"
4849 "#"
4850 "&& reload_completed"
4851 [(const_int 0)]
4852 {
4853 /* if (which_alternative == 0) */
4854 if (REGNO(operands[0]) == REGNO(operands[1]))
4855 {
4856 /* Emit the pattern:
4857 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4858 [(set (reg:CC CC_REGNUM)
4859 (compare:CC (match_dup 0) (const_int 0)))
4860 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4861 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4862 */
4863 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4864 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4865 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4866 (gen_rtx_LT (SImode,
4867 gen_rtx_REG (CCmode, CC_REGNUM),
4868 const0_rtx)),
4869 (gen_rtx_SET (operands[0],
4870 (gen_rtx_MINUS (SImode,
4871 const0_rtx,
4872 operands[1]))))));
4873 DONE;
4874 }
4875 else
4876 {
4877 /* Emit the pattern:
4878 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4879 [(set (match_dup 0)
4880 (xor:SI (match_dup 1)
4881 (ashiftrt:SI (match_dup 1) (const_int 31))))
4882 (set (match_dup 0)
4883 (minus:SI (match_dup 0)
4884 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4885 */
4886 emit_insn (gen_rtx_SET (operands[0],
4887 gen_rtx_XOR (SImode,
4888 gen_rtx_ASHIFTRT (SImode,
4889 operands[1],
4890 GEN_INT (31)),
4891 operands[1])));
4892 emit_insn (gen_rtx_SET (operands[0],
4893 gen_rtx_MINUS (SImode,
4894 operands[0],
4895 gen_rtx_ASHIFTRT (SImode,
4896 operands[1],
4897 GEN_INT (31)))));
4898 DONE;
4899 }
4900 }
4901 [(set_attr "conds" "clob,*")
4902 (set_attr "shift" "1")
4903 (set_attr "predicable" "no, yes")
4904 (set_attr "length" "8")
4905 (set_attr "type" "multiple")]
4906 )
4907
4908 (define_insn_and_split "*arm_neg_abssi2"
4909 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4910 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4911 (clobber (reg:CC CC_REGNUM))]
4912 "TARGET_ARM"
4913 "#"
4914 "&& reload_completed"
4915 [(const_int 0)]
4916 {
4917 /* if (which_alternative == 0) */
4918 if (REGNO (operands[0]) == REGNO (operands[1]))
4919 {
4920 /* Emit the pattern:
4921 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4922 */
4923 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4924 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4925 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4926 gen_rtx_GT (SImode,
4927 gen_rtx_REG (CCmode, CC_REGNUM),
4928 const0_rtx),
4929 gen_rtx_SET (operands[0],
4930 (gen_rtx_MINUS (SImode,
4931 const0_rtx,
4932 operands[1])))));
4933 }
4934 else
4935 {
4936 /* Emit the pattern:
4937 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4938 */
4939 emit_insn (gen_rtx_SET (operands[0],
4940 gen_rtx_XOR (SImode,
4941 gen_rtx_ASHIFTRT (SImode,
4942 operands[1],
4943 GEN_INT (31)),
4944 operands[1])));
4945 emit_insn (gen_rtx_SET (operands[0],
4946 gen_rtx_MINUS (SImode,
4947 gen_rtx_ASHIFTRT (SImode,
4948 operands[1],
4949 GEN_INT (31)),
4950 operands[0])));
4951 }
4952 DONE;
4953 }
4954 [(set_attr "conds" "clob,*")
4955 (set_attr "shift" "1")
4956 (set_attr "predicable" "no, yes")
4957 (set_attr "length" "8")
4958 (set_attr "type" "multiple")]
4959 )
4960
4961 (define_expand "abssf2"
4962 [(set (match_operand:SF 0 "s_register_operand" "")
4963 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4964 "TARGET_32BIT && TARGET_HARD_FLOAT"
4965 "")
4966
4967 (define_expand "absdf2"
4968 [(set (match_operand:DF 0 "s_register_operand" "")
4969 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4970 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4971 "")
4972
4973 (define_expand "sqrtsf2"
4974 [(set (match_operand:SF 0 "s_register_operand" "")
4975 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4976 "TARGET_32BIT && TARGET_HARD_FLOAT"
4977 "")
4978
4979 (define_expand "sqrtdf2"
4980 [(set (match_operand:DF 0 "s_register_operand" "")
4981 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4982 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4983 "")
4984
4985 (define_expand "one_cmpldi2"
4986 [(set (match_operand:DI 0 "s_register_operand" "")
4987 (not:DI (match_operand:DI 1 "s_register_operand" "")))]
4988 "TARGET_32BIT"
4989 "
4990 if (!TARGET_NEON && !TARGET_IWMMXT)
4991 {
4992 rtx low = simplify_gen_unary (NOT, SImode,
4993 gen_lowpart (SImode, operands[1]),
4994 SImode);
4995 rtx high = simplify_gen_unary (NOT, SImode,
4996 gen_highpart_mode (SImode, DImode,
4997 operands[1]),
4998 SImode);
4999
5000 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5001 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5002
5003 DONE;
5004 }
5005 /* Otherwise expand pattern as above. */
5006 "
5007 )
5008
5009 (define_insn_and_split "*one_cmpldi2_insn"
5010 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5011 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5012 "TARGET_32BIT"
5013 "@
5014 vmvn\t%P0, %P1
5015 #
5016 #
5017 vmvn\t%P0, %P1"
5018 "TARGET_32BIT && reload_completed
5019 && arm_general_register_operand (operands[0], DImode)"
5020 [(set (match_dup 0) (not:SI (match_dup 1)))
5021 (set (match_dup 2) (not:SI (match_dup 3)))]
5022 "
5023 {
5024 operands[2] = gen_highpart (SImode, operands[0]);
5025 operands[0] = gen_lowpart (SImode, operands[0]);
5026 operands[3] = gen_highpart (SImode, operands[1]);
5027 operands[1] = gen_lowpart (SImode, operands[1]);
5028 }"
5029 [(set_attr "length" "*,8,8,*")
5030 (set_attr "predicable" "no,yes,yes,no")
5031 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5032 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5033 )
5034
5035 (define_expand "one_cmplsi2"
5036 [(set (match_operand:SI 0 "s_register_operand" "")
5037 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5038 "TARGET_EITHER"
5039 ""
5040 )
5041
5042 (define_insn "*arm_one_cmplsi2"
5043 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5044 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5045 "TARGET_32BIT"
5046 "mvn%?\\t%0, %1"
5047 [(set_attr "predicable" "yes")
5048 (set_attr "predicable_short_it" "yes,no")
5049 (set_attr "arch" "t2,*")
5050 (set_attr "length" "4")
5051 (set_attr "type" "mvn_reg")]
5052 )
5053
5054 (define_insn "*notsi_compare0"
5055 [(set (reg:CC_NOOV CC_REGNUM)
5056 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5057 (const_int 0)))
5058 (set (match_operand:SI 0 "s_register_operand" "=r")
5059 (not:SI (match_dup 1)))]
5060 "TARGET_32BIT"
5061 "mvns%?\\t%0, %1"
5062 [(set_attr "conds" "set")
5063 (set_attr "type" "mvn_reg")]
5064 )
5065
5066 (define_insn "*notsi_compare0_scratch"
5067 [(set (reg:CC_NOOV CC_REGNUM)
5068 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5069 (const_int 0)))
5070 (clobber (match_scratch:SI 0 "=r"))]
5071 "TARGET_32BIT"
5072 "mvns%?\\t%0, %1"
5073 [(set_attr "conds" "set")
5074 (set_attr "type" "mvn_reg")]
5075 )
5076 \f
5077 ;; Fixed <--> Floating conversion insns
5078
5079 (define_expand "floatsihf2"
5080 [(set (match_operand:HF 0 "general_operand" "")
5081 (float:HF (match_operand:SI 1 "general_operand" "")))]
5082 "TARGET_EITHER"
5083 "
5084 {
5085 rtx op1 = gen_reg_rtx (SFmode);
5086 expand_float (op1, operands[1], 0);
5087 op1 = convert_to_mode (HFmode, op1, 0);
5088 emit_move_insn (operands[0], op1);
5089 DONE;
5090 }"
5091 )
5092
5093 (define_expand "floatdihf2"
5094 [(set (match_operand:HF 0 "general_operand" "")
5095 (float:HF (match_operand:DI 1 "general_operand" "")))]
5096 "TARGET_EITHER"
5097 "
5098 {
5099 rtx op1 = gen_reg_rtx (SFmode);
5100 expand_float (op1, operands[1], 0);
5101 op1 = convert_to_mode (HFmode, op1, 0);
5102 emit_move_insn (operands[0], op1);
5103 DONE;
5104 }"
5105 )
5106
5107 (define_expand "floatsisf2"
5108 [(set (match_operand:SF 0 "s_register_operand" "")
5109 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5110 "TARGET_32BIT && TARGET_HARD_FLOAT"
5111 "
5112 ")
5113
5114 (define_expand "floatsidf2"
5115 [(set (match_operand:DF 0 "s_register_operand" "")
5116 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5117 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5118 "
5119 ")
5120
5121 (define_expand "fix_trunchfsi2"
5122 [(set (match_operand:SI 0 "general_operand" "")
5123 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5124 "TARGET_EITHER"
5125 "
5126 {
5127 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5128 expand_fix (operands[0], op1, 0);
5129 DONE;
5130 }"
5131 )
5132
5133 (define_expand "fix_trunchfdi2"
5134 [(set (match_operand:DI 0 "general_operand" "")
5135 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5136 "TARGET_EITHER"
5137 "
5138 {
5139 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5140 expand_fix (operands[0], op1, 0);
5141 DONE;
5142 }"
5143 )
5144
5145 (define_expand "fix_truncsfsi2"
5146 [(set (match_operand:SI 0 "s_register_operand" "")
5147 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5148 "TARGET_32BIT && TARGET_HARD_FLOAT"
5149 "
5150 ")
5151
5152 (define_expand "fix_truncdfsi2"
5153 [(set (match_operand:SI 0 "s_register_operand" "")
5154 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5155 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5156 "
5157 ")
5158
5159 ;; Truncation insns
5160
5161 (define_expand "truncdfsf2"
5162 [(set (match_operand:SF 0 "s_register_operand" "")
5163 (float_truncate:SF
5164 (match_operand:DF 1 "s_register_operand" "")))]
5165 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5166 ""
5167 )
5168
5169 ;; DFmode to HFmode conversions on targets without a single-step hardware
5170 ;; instruction for it would have to go through SFmode. This is dangerous
5171 ;; as it introduces double rounding.
5172 ;;
5173 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5174 ;; a single-step instruction.
5175
5176 (define_expand "truncdfhf2"
5177 [(set (match_operand:HF 0 "s_register_operand" "")
5178 (float_truncate:HF
5179 (match_operand:DF 1 "s_register_operand" "")))]
5180 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5181 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5182 {
5183 /* We don't have a direct instruction for this, so we must be in
5184 an unsafe math mode, and going via SFmode. */
5185
5186 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5187 {
5188 rtx op1;
5189 op1 = convert_to_mode (SFmode, operands[1], 0);
5190 op1 = convert_to_mode (HFmode, op1, 0);
5191 emit_move_insn (operands[0], op1);
5192 DONE;
5193 }
5194 /* Otherwise, we will pick this up as a single instruction with
5195 no intermediary rounding. */
5196 }
5197 )
5198 \f
5199 ;; Zero and sign extension instructions.
5200
5201 (define_insn "zero_extend<mode>di2"
5202 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5203 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5204 "<qhs_zextenddi_cstr>")))]
5205 "TARGET_32BIT <qhs_zextenddi_cond>"
5206 "#"
5207 [(set_attr "length" "8,4,8,8")
5208 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5209 (set_attr "ce_count" "2")
5210 (set_attr "predicable" "yes")
5211 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5212 )
5213
5214 (define_insn "extend<mode>di2"
5215 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5216 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5217 "<qhs_extenddi_cstr>")))]
5218 "TARGET_32BIT <qhs_sextenddi_cond>"
5219 "#"
5220 [(set_attr "length" "8,4,8,8,8")
5221 (set_attr "ce_count" "2")
5222 (set_attr "shift" "1")
5223 (set_attr "predicable" "yes")
5224 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5225 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5226 )
5227
5228 ;; Splits for all extensions to DImode
5229 (define_split
5230 [(set (match_operand:DI 0 "s_register_operand" "")
5231 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5232 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5233 [(set (match_dup 0) (match_dup 1))]
5234 {
5235 rtx lo_part = gen_lowpart (SImode, operands[0]);
5236 machine_mode src_mode = GET_MODE (operands[1]);
5237
5238 if (REG_P (operands[0])
5239 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5240 emit_clobber (operands[0]);
5241 if (!REG_P (lo_part) || src_mode != SImode
5242 || !rtx_equal_p (lo_part, operands[1]))
5243 {
5244 if (src_mode == SImode)
5245 emit_move_insn (lo_part, operands[1]);
5246 else
5247 emit_insn (gen_rtx_SET (lo_part,
5248 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5249 operands[1] = lo_part;
5250 }
5251 operands[0] = gen_highpart (SImode, operands[0]);
5252 operands[1] = const0_rtx;
5253 })
5254
5255 (define_split
5256 [(set (match_operand:DI 0 "s_register_operand" "")
5257 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5258 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5259 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5260 {
5261 rtx lo_part = gen_lowpart (SImode, operands[0]);
5262 machine_mode src_mode = GET_MODE (operands[1]);
5263
5264 if (REG_P (operands[0])
5265 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5266 emit_clobber (operands[0]);
5267
5268 if (!REG_P (lo_part) || src_mode != SImode
5269 || !rtx_equal_p (lo_part, operands[1]))
5270 {
5271 if (src_mode == SImode)
5272 emit_move_insn (lo_part, operands[1]);
5273 else
5274 emit_insn (gen_rtx_SET (lo_part,
5275 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5276 operands[1] = lo_part;
5277 }
5278 operands[0] = gen_highpart (SImode, operands[0]);
5279 })
5280
5281 (define_expand "zero_extendhisi2"
5282 [(set (match_operand:SI 0 "s_register_operand" "")
5283 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5284 "TARGET_EITHER"
5285 {
5286 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5287 {
5288 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5289 DONE;
5290 }
5291 if (!arm_arch6 && !MEM_P (operands[1]))
5292 {
5293 rtx t = gen_lowpart (SImode, operands[1]);
5294 rtx tmp = gen_reg_rtx (SImode);
5295 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5296 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5297 DONE;
5298 }
5299 })
5300
5301 (define_split
5302 [(set (match_operand:SI 0 "s_register_operand" "")
5303 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5304 "!TARGET_THUMB2 && !arm_arch6"
5305 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5306 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5307 {
5308 operands[2] = gen_lowpart (SImode, operands[1]);
5309 })
5310
5311 (define_insn "*arm_zero_extendhisi2"
5312 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5313 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5314 "TARGET_ARM && arm_arch4 && !arm_arch6"
5315 "@
5316 #
5317 ldrh%?\\t%0, %1"
5318 [(set_attr "type" "alu_shift_reg,load_byte")
5319 (set_attr "predicable" "yes")]
5320 )
5321
5322 (define_insn "*arm_zero_extendhisi2_v6"
5323 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5324 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5325 "TARGET_ARM && arm_arch6"
5326 "@
5327 uxth%?\\t%0, %1
5328 ldrh%?\\t%0, %1"
5329 [(set_attr "predicable" "yes")
5330 (set_attr "type" "extend,load_byte")]
5331 )
5332
5333 (define_insn "*arm_zero_extendhisi2addsi"
5334 [(set (match_operand:SI 0 "s_register_operand" "=r")
5335 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5336 (match_operand:SI 2 "s_register_operand" "r")))]
5337 "TARGET_INT_SIMD"
5338 "uxtah%?\\t%0, %2, %1"
5339 [(set_attr "type" "alu_shift_reg")
5340 (set_attr "predicable" "yes")]
5341 )
5342
5343 (define_expand "zero_extendqisi2"
5344 [(set (match_operand:SI 0 "s_register_operand" "")
5345 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5346 "TARGET_EITHER"
5347 {
5348 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5349 {
5350 emit_insn (gen_andsi3 (operands[0],
5351 gen_lowpart (SImode, operands[1]),
5352 GEN_INT (255)));
5353 DONE;
5354 }
5355 if (!arm_arch6 && !MEM_P (operands[1]))
5356 {
5357 rtx t = gen_lowpart (SImode, operands[1]);
5358 rtx tmp = gen_reg_rtx (SImode);
5359 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5360 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5361 DONE;
5362 }
5363 })
5364
5365 (define_split
5366 [(set (match_operand:SI 0 "s_register_operand" "")
5367 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5368 "!arm_arch6"
5369 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5370 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5371 {
5372 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5373 if (TARGET_ARM)
5374 {
5375 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5376 DONE;
5377 }
5378 })
5379
5380 (define_insn "*arm_zero_extendqisi2"
5381 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5382 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5383 "TARGET_ARM && !arm_arch6"
5384 "@
5385 #
5386 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5387 [(set_attr "length" "8,4")
5388 (set_attr "type" "alu_shift_reg,load_byte")
5389 (set_attr "predicable" "yes")]
5390 )
5391
5392 (define_insn "*arm_zero_extendqisi2_v6"
5393 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5394 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5395 "TARGET_ARM && arm_arch6"
5396 "@
5397 uxtb%?\\t%0, %1
5398 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5399 [(set_attr "type" "extend,load_byte")
5400 (set_attr "predicable" "yes")]
5401 )
5402
5403 (define_insn "*arm_zero_extendqisi2addsi"
5404 [(set (match_operand:SI 0 "s_register_operand" "=r")
5405 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5406 (match_operand:SI 2 "s_register_operand" "r")))]
5407 "TARGET_INT_SIMD"
5408 "uxtab%?\\t%0, %2, %1"
5409 [(set_attr "predicable" "yes")
5410 (set_attr "type" "alu_shift_reg")]
5411 )
5412
5413 (define_split
5414 [(set (match_operand:SI 0 "s_register_operand" "")
5415 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5416 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5417 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5418 [(set (match_dup 2) (match_dup 1))
5419 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5420 ""
5421 )
5422
5423 (define_split
5424 [(set (match_operand:SI 0 "s_register_operand" "")
5425 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5426 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5427 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5428 [(set (match_dup 2) (match_dup 1))
5429 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5430 ""
5431 )
5432
5433
5434 (define_split
5435 [(set (match_operand:SI 0 "s_register_operand" "")
5436 (IOR_XOR:SI (and:SI (ashift:SI
5437 (match_operand:SI 1 "s_register_operand" "")
5438 (match_operand:SI 2 "const_int_operand" ""))
5439 (match_operand:SI 3 "const_int_operand" ""))
5440 (zero_extend:SI
5441 (match_operator 5 "subreg_lowpart_operator"
5442 [(match_operand:SI 4 "s_register_operand" "")]))))]
5443 "TARGET_32BIT
5444 && (UINTVAL (operands[3])
5445 == (GET_MODE_MASK (GET_MODE (operands[5]))
5446 & (GET_MODE_MASK (GET_MODE (operands[5]))
5447 << (INTVAL (operands[2])))))"
5448 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5449 (match_dup 4)))
5450 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5451 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5452 )
5453
5454 (define_insn "*compareqi_eq0"
5455 [(set (reg:CC_Z CC_REGNUM)
5456 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5457 (const_int 0)))]
5458 "TARGET_32BIT"
5459 "tst%?\\t%0, #255"
5460 [(set_attr "conds" "set")
5461 (set_attr "predicable" "yes")
5462 (set_attr "type" "logic_imm")]
5463 )
5464
5465 (define_expand "extendhisi2"
5466 [(set (match_operand:SI 0 "s_register_operand" "")
5467 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5468 "TARGET_EITHER"
5469 {
5470 if (TARGET_THUMB1)
5471 {
5472 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5473 DONE;
5474 }
5475 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5476 {
5477 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5478 DONE;
5479 }
5480
5481 if (!arm_arch6 && !MEM_P (operands[1]))
5482 {
5483 rtx t = gen_lowpart (SImode, operands[1]);
5484 rtx tmp = gen_reg_rtx (SImode);
5485 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5486 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5487 DONE;
5488 }
5489 })
5490
5491 (define_split
5492 [(parallel
5493 [(set (match_operand:SI 0 "register_operand" "")
5494 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5495 (clobber (match_scratch:SI 2 ""))])]
5496 "!arm_arch6"
5497 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5498 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5499 {
5500 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5501 })
5502
5503 ;; This pattern will only be used when ldsh is not available
5504 (define_expand "extendhisi2_mem"
5505 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5506 (set (match_dup 3)
5507 (zero_extend:SI (match_dup 7)))
5508 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5509 (set (match_operand:SI 0 "" "")
5510 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5511 "TARGET_ARM"
5512 "
5513 {
5514 rtx mem1, mem2;
5515 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5516
5517 mem1 = change_address (operands[1], QImode, addr);
5518 mem2 = change_address (operands[1], QImode,
5519 plus_constant (Pmode, addr, 1));
5520 operands[0] = gen_lowpart (SImode, operands[0]);
5521 operands[1] = mem1;
5522 operands[2] = gen_reg_rtx (SImode);
5523 operands[3] = gen_reg_rtx (SImode);
5524 operands[6] = gen_reg_rtx (SImode);
5525 operands[7] = mem2;
5526
5527 if (BYTES_BIG_ENDIAN)
5528 {
5529 operands[4] = operands[2];
5530 operands[5] = operands[3];
5531 }
5532 else
5533 {
5534 operands[4] = operands[3];
5535 operands[5] = operands[2];
5536 }
5537 }"
5538 )
5539
5540 (define_split
5541 [(set (match_operand:SI 0 "register_operand" "")
5542 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5543 "!arm_arch6"
5544 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5545 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5546 {
5547 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5548 })
5549
5550 (define_insn "*arm_extendhisi2"
5551 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5552 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5553 "TARGET_ARM && arm_arch4 && !arm_arch6"
5554 "@
5555 #
5556 ldrsh%?\\t%0, %1"
5557 [(set_attr "length" "8,4")
5558 (set_attr "type" "alu_shift_reg,load_byte")
5559 (set_attr "predicable" "yes")]
5560 )
5561
5562 ;; ??? Check Thumb-2 pool range
5563 (define_insn "*arm_extendhisi2_v6"
5564 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5565 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5566 "TARGET_32BIT && arm_arch6"
5567 "@
5568 sxth%?\\t%0, %1
5569 ldrsh%?\\t%0, %1"
5570 [(set_attr "type" "extend,load_byte")
5571 (set_attr "predicable" "yes")]
5572 )
5573
5574 (define_insn "*arm_extendhisi2addsi"
5575 [(set (match_operand:SI 0 "s_register_operand" "=r")
5576 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5577 (match_operand:SI 2 "s_register_operand" "r")))]
5578 "TARGET_INT_SIMD"
5579 "sxtah%?\\t%0, %2, %1"
5580 [(set_attr "type" "alu_shift_reg")]
5581 )
5582
5583 (define_expand "extendqihi2"
5584 [(set (match_dup 2)
5585 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5586 (const_int 24)))
5587 (set (match_operand:HI 0 "s_register_operand" "")
5588 (ashiftrt:SI (match_dup 2)
5589 (const_int 24)))]
5590 "TARGET_ARM"
5591 "
5592 {
5593 if (arm_arch4 && MEM_P (operands[1]))
5594 {
5595 emit_insn (gen_rtx_SET (operands[0],
5596 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5597 DONE;
5598 }
5599 if (!s_register_operand (operands[1], QImode))
5600 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5601 operands[0] = gen_lowpart (SImode, operands[0]);
5602 operands[1] = gen_lowpart (SImode, operands[1]);
5603 operands[2] = gen_reg_rtx (SImode);
5604 }"
5605 )
5606
5607 (define_insn "*arm_extendqihi_insn"
5608 [(set (match_operand:HI 0 "s_register_operand" "=r")
5609 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5610 "TARGET_ARM && arm_arch4"
5611 "ldrsb%?\\t%0, %1"
5612 [(set_attr "type" "load_byte")
5613 (set_attr "predicable" "yes")]
5614 )
5615
5616 (define_expand "extendqisi2"
5617 [(set (match_operand:SI 0 "s_register_operand" "")
5618 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5619 "TARGET_EITHER"
5620 {
5621 if (!arm_arch4 && MEM_P (operands[1]))
5622 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5623
5624 if (!arm_arch6 && !MEM_P (operands[1]))
5625 {
5626 rtx t = gen_lowpart (SImode, operands[1]);
5627 rtx tmp = gen_reg_rtx (SImode);
5628 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5629 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5630 DONE;
5631 }
5632 })
5633
5634 (define_split
5635 [(set (match_operand:SI 0 "register_operand" "")
5636 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5637 "!arm_arch6"
5638 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5639 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5640 {
5641 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5642 })
5643
5644 (define_insn "*arm_extendqisi"
5645 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5646 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5647 "TARGET_ARM && arm_arch4 && !arm_arch6"
5648 "@
5649 #
5650 ldrsb%?\\t%0, %1"
5651 [(set_attr "length" "8,4")
5652 (set_attr "type" "alu_shift_reg,load_byte")
5653 (set_attr "predicable" "yes")]
5654 )
5655
5656 (define_insn "*arm_extendqisi_v6"
5657 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5658 (sign_extend:SI
5659 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5660 "TARGET_ARM && arm_arch6"
5661 "@
5662 sxtb%?\\t%0, %1
5663 ldrsb%?\\t%0, %1"
5664 [(set_attr "type" "extend,load_byte")
5665 (set_attr "predicable" "yes")]
5666 )
5667
5668 (define_insn "*arm_extendqisi2addsi"
5669 [(set (match_operand:SI 0 "s_register_operand" "=r")
5670 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5671 (match_operand:SI 2 "s_register_operand" "r")))]
5672 "TARGET_INT_SIMD"
5673 "sxtab%?\\t%0, %2, %1"
5674 [(set_attr "type" "alu_shift_reg")
5675 (set_attr "predicable" "yes")]
5676 )
5677
5678 (define_expand "extendsfdf2"
5679 [(set (match_operand:DF 0 "s_register_operand" "")
5680 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5681 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5682 ""
5683 )
5684
5685 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5686 ;; must go through SFmode.
5687 ;;
5688 ;; This is always safe for an extend.
5689
5690 (define_expand "extendhfdf2"
5691 [(set (match_operand:DF 0 "s_register_operand" "")
5692 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5693 "TARGET_EITHER"
5694 {
5695 /* We don't have a direct instruction for this, so go via SFmode. */
5696 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5697 {
5698 rtx op1;
5699 op1 = convert_to_mode (SFmode, operands[1], 0);
5700 op1 = convert_to_mode (DFmode, op1, 0);
5701 emit_insn (gen_movdf (operands[0], op1));
5702 DONE;
5703 }
5704 /* Otherwise, we're done producing RTL and will pick up the correct
5705 pattern to do this with one rounding-step in a single instruction. */
5706 }
5707 )
5708 \f
5709 ;; Move insns (including loads and stores)
5710
5711 ;; XXX Just some ideas about movti.
5712 ;; I don't think these are a good idea on the arm, there just aren't enough
5713 ;; registers
5714 ;;(define_expand "loadti"
5715 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5716 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5717 ;; "" "")
5718
5719 ;;(define_expand "storeti"
5720 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5721 ;; (match_operand:TI 1 "s_register_operand" ""))]
5722 ;; "" "")
5723
5724 ;;(define_expand "movti"
5725 ;; [(set (match_operand:TI 0 "general_operand" "")
5726 ;; (match_operand:TI 1 "general_operand" ""))]
5727 ;; ""
5728 ;; "
5729 ;;{
5730 ;; rtx insn;
5731 ;;
5732 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5733 ;; operands[1] = copy_to_reg (operands[1]);
5734 ;; if (MEM_P (operands[0]))
5735 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5736 ;; else if (MEM_P (operands[1]))
5737 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5738 ;; else
5739 ;; FAIL;
5740 ;;
5741 ;; emit_insn (insn);
5742 ;; DONE;
5743 ;;}")
5744
5745 ;; Recognize garbage generated above.
5746
5747 ;;(define_insn ""
5748 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5749 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5750 ;; ""
5751 ;; "*
5752 ;; {
5753 ;; register mem = (which_alternative < 3);
5754 ;; register const char *template;
5755 ;;
5756 ;; operands[mem] = XEXP (operands[mem], 0);
5757 ;; switch (which_alternative)
5758 ;; {
5759 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5760 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5761 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5762 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5763 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5764 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5765 ;; }
5766 ;; output_asm_insn (template, operands);
5767 ;; return \"\";
5768 ;; }")
5769
5770 (define_expand "movdi"
5771 [(set (match_operand:DI 0 "general_operand" "")
5772 (match_operand:DI 1 "general_operand" ""))]
5773 "TARGET_EITHER"
5774 "
5775 if (can_create_pseudo_p ())
5776 {
5777 if (!REG_P (operands[0]))
5778 operands[1] = force_reg (DImode, operands[1]);
5779 }
5780 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5781 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5782 {
5783 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5784 when expanding function calls. */
5785 gcc_assert (can_create_pseudo_p ());
5786 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5787 {
5788 /* Perform load into legal reg pair first, then move. */
5789 rtx reg = gen_reg_rtx (DImode);
5790 emit_insn (gen_movdi (reg, operands[1]));
5791 operands[1] = reg;
5792 }
5793 emit_move_insn (gen_lowpart (SImode, operands[0]),
5794 gen_lowpart (SImode, operands[1]));
5795 emit_move_insn (gen_highpart (SImode, operands[0]),
5796 gen_highpart (SImode, operands[1]));
5797 DONE;
5798 }
5799 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5800 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5801 {
5802 /* Avoid STRD's from an odd-numbered register pair in ARM state
5803 when expanding function prologue. */
5804 gcc_assert (can_create_pseudo_p ());
5805 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5806 ? gen_reg_rtx (DImode)
5807 : operands[0];
5808 emit_move_insn (gen_lowpart (SImode, split_dest),
5809 gen_lowpart (SImode, operands[1]));
5810 emit_move_insn (gen_highpart (SImode, split_dest),
5811 gen_highpart (SImode, operands[1]));
5812 if (split_dest != operands[0])
5813 emit_insn (gen_movdi (operands[0], split_dest));
5814 DONE;
5815 }
5816 "
5817 )
5818
5819 (define_insn "*arm_movdi"
5820 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5821 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5822 "TARGET_32BIT
5823 && !(TARGET_HARD_FLOAT)
5824 && !TARGET_IWMMXT
5825 && ( register_operand (operands[0], DImode)
5826 || register_operand (operands[1], DImode))"
5827 "*
5828 switch (which_alternative)
5829 {
5830 case 0:
5831 case 1:
5832 case 2:
5833 return \"#\";
5834 case 3:
5835 /* Cannot load it directly, split to load it via MOV / MOVT. */
5836 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
5837 return \"#\";
5838 /* Fall through. */
5839 default:
5840 return output_move_double (operands, true, NULL);
5841 }
5842 "
5843 [(set_attr "length" "8,12,16,8,8")
5844 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5845 (set_attr "arm_pool_range" "*,*,*,1020,*")
5846 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5847 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5848 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5849 )
5850
5851 (define_split
5852 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5853 (match_operand:ANY64 1 "immediate_operand" ""))]
5854 "TARGET_32BIT
5855 && reload_completed
5856 && (arm_disable_literal_pool
5857 || (arm_const_double_inline_cost (operands[1])
5858 <= arm_max_const_double_inline_cost ()))"
5859 [(const_int 0)]
5860 "
5861 arm_split_constant (SET, SImode, curr_insn,
5862 INTVAL (gen_lowpart (SImode, operands[1])),
5863 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5864 arm_split_constant (SET, SImode, curr_insn,
5865 INTVAL (gen_highpart_mode (SImode,
5866 GET_MODE (operands[0]),
5867 operands[1])),
5868 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5869 DONE;
5870 "
5871 )
5872
5873 ; If optimizing for size, or if we have load delay slots, then
5874 ; we want to split the constant into two separate operations.
5875 ; In both cases this may split a trivial part into a single data op
5876 ; leaving a single complex constant to load. We can also get longer
5877 ; offsets in a LDR which means we get better chances of sharing the pool
5878 ; entries. Finally, we can normally do a better job of scheduling
5879 ; LDR instructions than we can with LDM.
5880 ; This pattern will only match if the one above did not.
5881 (define_split
5882 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5883 (match_operand:ANY64 1 "const_double_operand" ""))]
5884 "TARGET_ARM && reload_completed
5885 && arm_const_double_by_parts (operands[1])"
5886 [(set (match_dup 0) (match_dup 1))
5887 (set (match_dup 2) (match_dup 3))]
5888 "
5889 operands[2] = gen_highpart (SImode, operands[0]);
5890 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5891 operands[1]);
5892 operands[0] = gen_lowpart (SImode, operands[0]);
5893 operands[1] = gen_lowpart (SImode, operands[1]);
5894 "
5895 )
5896
5897 (define_split
5898 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5899 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5900 "TARGET_EITHER && reload_completed"
5901 [(set (match_dup 0) (match_dup 1))
5902 (set (match_dup 2) (match_dup 3))]
5903 "
5904 operands[2] = gen_highpart (SImode, operands[0]);
5905 operands[3] = gen_highpart (SImode, operands[1]);
5906 operands[0] = gen_lowpart (SImode, operands[0]);
5907 operands[1] = gen_lowpart (SImode, operands[1]);
5908
5909 /* Handle a partial overlap. */
5910 if (rtx_equal_p (operands[0], operands[3]))
5911 {
5912 rtx tmp0 = operands[0];
5913 rtx tmp1 = operands[1];
5914
5915 operands[0] = operands[2];
5916 operands[1] = operands[3];
5917 operands[2] = tmp0;
5918 operands[3] = tmp1;
5919 }
5920 "
5921 )
5922
5923 ;; We can't actually do base+index doubleword loads if the index and
5924 ;; destination overlap. Split here so that we at least have chance to
5925 ;; schedule.
5926 (define_split
5927 [(set (match_operand:DI 0 "s_register_operand" "")
5928 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5929 (match_operand:SI 2 "s_register_operand" ""))))]
5930 "TARGET_LDRD
5931 && reg_overlap_mentioned_p (operands[0], operands[1])
5932 && reg_overlap_mentioned_p (operands[0], operands[2])"
5933 [(set (match_dup 4)
5934 (plus:SI (match_dup 1)
5935 (match_dup 2)))
5936 (set (match_dup 0)
5937 (mem:DI (match_dup 4)))]
5938 "
5939 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5940 "
5941 )
5942
5943 (define_expand "movsi"
5944 [(set (match_operand:SI 0 "general_operand" "")
5945 (match_operand:SI 1 "general_operand" ""))]
5946 "TARGET_EITHER"
5947 "
5948 {
5949 rtx base, offset, tmp;
5950
5951 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5952 {
5953 /* Everything except mem = const or mem = mem can be done easily. */
5954 if (MEM_P (operands[0]))
5955 operands[1] = force_reg (SImode, operands[1]);
5956 if (arm_general_register_operand (operands[0], SImode)
5957 && CONST_INT_P (operands[1])
5958 && !(const_ok_for_arm (INTVAL (operands[1]))
5959 || const_ok_for_arm (~INTVAL (operands[1]))))
5960 {
5961 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5962 {
5963 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5964 DONE;
5965 }
5966 else
5967 {
5968 arm_split_constant (SET, SImode, NULL_RTX,
5969 INTVAL (operands[1]), operands[0], NULL_RTX,
5970 optimize && can_create_pseudo_p ());
5971 DONE;
5972 }
5973 }
5974 }
5975 else /* Target doesn't have MOVT... */
5976 {
5977 if (can_create_pseudo_p ())
5978 {
5979 if (!REG_P (operands[0]))
5980 operands[1] = force_reg (SImode, operands[1]);
5981 }
5982 }
5983
5984 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5985 {
5986 split_const (operands[1], &base, &offset);
5987 if (GET_CODE (base) == SYMBOL_REF
5988 && !offset_within_block_p (base, INTVAL (offset)))
5989 {
5990 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5991 emit_move_insn (tmp, base);
5992 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5993 DONE;
5994 }
5995 }
5996
5997 /* Recognize the case where operand[1] is a reference to thread-local
5998 data and load its address to a register. */
5999 if (arm_tls_referenced_p (operands[1]))
6000 {
6001 rtx tmp = operands[1];
6002 rtx addend = NULL;
6003
6004 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6005 {
6006 addend = XEXP (XEXP (tmp, 0), 1);
6007 tmp = XEXP (XEXP (tmp, 0), 0);
6008 }
6009
6010 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6011 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6012
6013 tmp = legitimize_tls_address (tmp,
6014 !can_create_pseudo_p () ? operands[0] : 0);
6015 if (addend)
6016 {
6017 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6018 tmp = force_operand (tmp, operands[0]);
6019 }
6020 operands[1] = tmp;
6021 }
6022 else if (flag_pic
6023 && (CONSTANT_P (operands[1])
6024 || symbol_mentioned_p (operands[1])
6025 || label_mentioned_p (operands[1])))
6026 operands[1] = legitimize_pic_address (operands[1], SImode,
6027 (!can_create_pseudo_p ()
6028 ? operands[0]
6029 : NULL_RTX), NULL_RTX,
6030 false /*compute_now*/);
6031 }
6032 "
6033 )
6034
6035 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6036 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6037 ;; so this does not matter.
6038 (define_insn "*arm_movt"
6039 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6040 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6041 (match_operand:SI 2 "general_operand" "i,i")))]
6042 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6043 "@
6044 movt%?\t%0, #:upper16:%c2
6045 movt\t%0, #:upper16:%c2"
6046 [(set_attr "arch" "32,v8mb")
6047 (set_attr "predicable" "yes")
6048 (set_attr "length" "4")
6049 (set_attr "type" "alu_sreg")]
6050 )
6051
6052 (define_insn "*arm_movsi_insn"
6053 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6054 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6055 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6056 && ( register_operand (operands[0], SImode)
6057 || register_operand (operands[1], SImode))"
6058 "@
6059 mov%?\\t%0, %1
6060 mov%?\\t%0, %1
6061 mvn%?\\t%0, #%B1
6062 movw%?\\t%0, %1
6063 ldr%?\\t%0, %1
6064 str%?\\t%1, %0"
6065 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6066 (set_attr "predicable" "yes")
6067 (set_attr "arch" "*,*,*,v6t2,*,*")
6068 (set_attr "pool_range" "*,*,*,*,4096,*")
6069 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6070 )
6071
6072 (define_split
6073 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6074 (match_operand:SI 1 "const_int_operand" ""))]
6075 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6076 && (!(const_ok_for_arm (INTVAL (operands[1]))
6077 || const_ok_for_arm (~INTVAL (operands[1]))))"
6078 [(clobber (const_int 0))]
6079 "
6080 arm_split_constant (SET, SImode, NULL_RTX,
6081 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6082 DONE;
6083 "
6084 )
6085
6086 ;; A normal way to do (symbol + offset) requires three instructions at least
6087 ;; (depends on how big the offset is) as below:
6088 ;; movw r0, #:lower16:g
6089 ;; movw r0, #:upper16:g
6090 ;; adds r0, #4
6091 ;;
6092 ;; A better way would be:
6093 ;; movw r0, #:lower16:g+4
6094 ;; movw r0, #:upper16:g+4
6095 ;;
6096 ;; The limitation of this way is that the length of offset should be a 16-bit
6097 ;; signed value, because current assembler only supports REL type relocation for
6098 ;; such case. If the more powerful RELA type is supported in future, we should
6099 ;; update this pattern to go with better way.
6100 (define_split
6101 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6102 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6103 (match_operand:SI 2 "const_int_operand" ""))))]
6104 "TARGET_THUMB
6105 && TARGET_HAVE_MOVT
6106 && arm_disable_literal_pool
6107 && reload_completed
6108 && GET_CODE (operands[1]) == SYMBOL_REF"
6109 [(clobber (const_int 0))]
6110 "
6111 int offset = INTVAL (operands[2]);
6112
6113 if (offset < -0x8000 || offset > 0x7fff)
6114 {
6115 arm_emit_movpair (operands[0], operands[1]);
6116 emit_insn (gen_rtx_SET (operands[0],
6117 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6118 }
6119 else
6120 {
6121 rtx op = gen_rtx_CONST (SImode,
6122 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6123 arm_emit_movpair (operands[0], op);
6124 }
6125 "
6126 )
6127
6128 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6129 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6130 ;; and lo_sum would be merged back into memory load at cprop. However,
6131 ;; if the default is to prefer movt/movw rather than a load from the constant
6132 ;; pool, the performance is better.
6133 (define_split
6134 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6135 (match_operand:SI 1 "general_operand" ""))]
6136 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6137 && !target_word_relocations
6138 && !arm_tls_referenced_p (operands[1])"
6139 [(clobber (const_int 0))]
6140 {
6141 arm_emit_movpair (operands[0], operands[1]);
6142 DONE;
6143 })
6144
6145 ;; When generating pic, we need to load the symbol offset into a register.
6146 ;; So that the optimizer does not confuse this with a normal symbol load
6147 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6148 ;; since that is the only type of relocation we can use.
6149
6150 ;; Wrap calculation of the whole PIC address in a single pattern for the
6151 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6152 ;; a PIC address involves two loads from memory, so we want to CSE it
6153 ;; as often as possible.
6154 ;; This pattern will be split into one of the pic_load_addr_* patterns
6155 ;; and a move after GCSE optimizations.
6156 ;;
6157 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6158 (define_expand "calculate_pic_address"
6159 [(set (match_operand:SI 0 "register_operand" "")
6160 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6161 (unspec:SI [(match_operand:SI 2 "" "")]
6162 UNSPEC_PIC_SYM))))]
6163 "flag_pic"
6164 )
6165
6166 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6167 (define_split
6168 [(set (match_operand:SI 0 "register_operand" "")
6169 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6170 (unspec:SI [(match_operand:SI 2 "" "")]
6171 UNSPEC_PIC_SYM))))]
6172 "flag_pic"
6173 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6174 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6175 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6176 )
6177
6178 ;; operand1 is the memory address to go into
6179 ;; pic_load_addr_32bit.
6180 ;; operand2 is the PIC label to be emitted
6181 ;; from pic_add_dot_plus_eight.
6182 ;; We do this to allow hoisting of the entire insn.
6183 (define_insn_and_split "pic_load_addr_unified"
6184 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6185 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6186 (match_operand:SI 2 "" "")]
6187 UNSPEC_PIC_UNIFIED))]
6188 "flag_pic"
6189 "#"
6190 "&& reload_completed"
6191 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6192 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6193 (match_dup 2)] UNSPEC_PIC_BASE))]
6194 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6195 [(set_attr "type" "load_4,load_4,load_4")
6196 (set_attr "pool_range" "4096,4094,1022")
6197 (set_attr "neg_pool_range" "4084,0,0")
6198 (set_attr "arch" "a,t2,t1")
6199 (set_attr "length" "8,6,4")]
6200 )
6201
6202 ;; The rather odd constraints on the following are to force reload to leave
6203 ;; the insn alone, and to force the minipool generation pass to then move
6204 ;; the GOT symbol to memory.
6205
6206 (define_insn "pic_load_addr_32bit"
6207 [(set (match_operand:SI 0 "s_register_operand" "=r")
6208 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6209 "TARGET_32BIT && flag_pic"
6210 "ldr%?\\t%0, %1"
6211 [(set_attr "type" "load_4")
6212 (set (attr "pool_range")
6213 (if_then_else (eq_attr "is_thumb" "no")
6214 (const_int 4096)
6215 (const_int 4094)))
6216 (set (attr "neg_pool_range")
6217 (if_then_else (eq_attr "is_thumb" "no")
6218 (const_int 4084)
6219 (const_int 0)))]
6220 )
6221
6222 (define_insn "pic_load_addr_thumb1"
6223 [(set (match_operand:SI 0 "s_register_operand" "=l")
6224 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6225 "TARGET_THUMB1 && flag_pic"
6226 "ldr\\t%0, %1"
6227 [(set_attr "type" "load_4")
6228 (set (attr "pool_range") (const_int 1018))]
6229 )
6230
6231 (define_insn "pic_add_dot_plus_four"
6232 [(set (match_operand:SI 0 "register_operand" "=r")
6233 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6234 (const_int 4)
6235 (match_operand 2 "" "")]
6236 UNSPEC_PIC_BASE))]
6237 "TARGET_THUMB"
6238 "*
6239 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6240 INTVAL (operands[2]));
6241 return \"add\\t%0, %|pc\";
6242 "
6243 [(set_attr "length" "2")
6244 (set_attr "type" "alu_sreg")]
6245 )
6246
6247 (define_insn "pic_add_dot_plus_eight"
6248 [(set (match_operand:SI 0 "register_operand" "=r")
6249 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6250 (const_int 8)
6251 (match_operand 2 "" "")]
6252 UNSPEC_PIC_BASE))]
6253 "TARGET_ARM"
6254 "*
6255 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6256 INTVAL (operands[2]));
6257 return \"add%?\\t%0, %|pc, %1\";
6258 "
6259 [(set_attr "predicable" "yes")
6260 (set_attr "type" "alu_sreg")]
6261 )
6262
6263 (define_insn "tls_load_dot_plus_eight"
6264 [(set (match_operand:SI 0 "register_operand" "=r")
6265 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6266 (const_int 8)
6267 (match_operand 2 "" "")]
6268 UNSPEC_PIC_BASE)))]
6269 "TARGET_ARM"
6270 "*
6271 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6272 INTVAL (operands[2]));
6273 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6274 "
6275 [(set_attr "predicable" "yes")
6276 (set_attr "type" "load_4")]
6277 )
6278
6279 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6280 ;; followed by a load. These sequences can be crunched down to
6281 ;; tls_load_dot_plus_eight by a peephole.
6282
6283 (define_peephole2
6284 [(set (match_operand:SI 0 "register_operand" "")
6285 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6286 (const_int 8)
6287 (match_operand 1 "" "")]
6288 UNSPEC_PIC_BASE))
6289 (set (match_operand:SI 2 "arm_general_register_operand" "")
6290 (mem:SI (match_dup 0)))]
6291 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6292 [(set (match_dup 2)
6293 (mem:SI (unspec:SI [(match_dup 3)
6294 (const_int 8)
6295 (match_dup 1)]
6296 UNSPEC_PIC_BASE)))]
6297 ""
6298 )
6299
6300 (define_insn "pic_offset_arm"
6301 [(set (match_operand:SI 0 "register_operand" "=r")
6302 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6303 (unspec:SI [(match_operand:SI 2 "" "X")]
6304 UNSPEC_PIC_OFFSET))))]
6305 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6306 "ldr%?\\t%0, [%1,%2]"
6307 [(set_attr "type" "load_4")]
6308 )
6309
6310 (define_expand "builtin_setjmp_receiver"
6311 [(label_ref (match_operand 0 "" ""))]
6312 "flag_pic"
6313 "
6314 {
6315 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6316 register. */
6317 if (arm_pic_register != INVALID_REGNUM)
6318 arm_load_pic_register (1UL << 3, NULL_RTX);
6319 DONE;
6320 }")
6321
6322 ;; If copying one reg to another we can set the condition codes according to
6323 ;; its value. Such a move is common after a return from subroutine and the
6324 ;; result is being tested against zero.
6325
6326 (define_insn "*movsi_compare0"
6327 [(set (reg:CC CC_REGNUM)
6328 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6329 (const_int 0)))
6330 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6331 (match_dup 1))]
6332 "TARGET_32BIT"
6333 "@
6334 cmp%?\\t%0, #0
6335 subs%?\\t%0, %1, #0"
6336 [(set_attr "conds" "set")
6337 (set_attr "type" "alus_imm,alus_imm")]
6338 )
6339
6340 ;; Subroutine to store a half word from a register into memory.
6341 ;; Operand 0 is the source register (HImode)
6342 ;; Operand 1 is the destination address in a register (SImode)
6343
6344 ;; In both this routine and the next, we must be careful not to spill
6345 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6346 ;; can generate unrecognizable rtl.
6347
6348 (define_expand "storehi"
6349 [;; store the low byte
6350 (set (match_operand 1 "" "") (match_dup 3))
6351 ;; extract the high byte
6352 (set (match_dup 2)
6353 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6354 ;; store the high byte
6355 (set (match_dup 4) (match_dup 5))]
6356 "TARGET_ARM"
6357 "
6358 {
6359 rtx op1 = operands[1];
6360 rtx addr = XEXP (op1, 0);
6361 enum rtx_code code = GET_CODE (addr);
6362
6363 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6364 || code == MINUS)
6365 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6366
6367 operands[4] = adjust_address (op1, QImode, 1);
6368 operands[1] = adjust_address (operands[1], QImode, 0);
6369 operands[3] = gen_lowpart (QImode, operands[0]);
6370 operands[0] = gen_lowpart (SImode, operands[0]);
6371 operands[2] = gen_reg_rtx (SImode);
6372 operands[5] = gen_lowpart (QImode, operands[2]);
6373 }"
6374 )
6375
6376 (define_expand "storehi_bigend"
6377 [(set (match_dup 4) (match_dup 3))
6378 (set (match_dup 2)
6379 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6380 (set (match_operand 1 "" "") (match_dup 5))]
6381 "TARGET_ARM"
6382 "
6383 {
6384 rtx op1 = operands[1];
6385 rtx addr = XEXP (op1, 0);
6386 enum rtx_code code = GET_CODE (addr);
6387
6388 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6389 || code == MINUS)
6390 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6391
6392 operands[4] = adjust_address (op1, QImode, 1);
6393 operands[1] = adjust_address (operands[1], QImode, 0);
6394 operands[3] = gen_lowpart (QImode, operands[0]);
6395 operands[0] = gen_lowpart (SImode, operands[0]);
6396 operands[2] = gen_reg_rtx (SImode);
6397 operands[5] = gen_lowpart (QImode, operands[2]);
6398 }"
6399 )
6400
6401 ;; Subroutine to store a half word integer constant into memory.
6402 (define_expand "storeinthi"
6403 [(set (match_operand 0 "" "")
6404 (match_operand 1 "" ""))
6405 (set (match_dup 3) (match_dup 2))]
6406 "TARGET_ARM"
6407 "
6408 {
6409 HOST_WIDE_INT value = INTVAL (operands[1]);
6410 rtx addr = XEXP (operands[0], 0);
6411 rtx op0 = operands[0];
6412 enum rtx_code code = GET_CODE (addr);
6413
6414 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6415 || code == MINUS)
6416 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6417
6418 operands[1] = gen_reg_rtx (SImode);
6419 if (BYTES_BIG_ENDIAN)
6420 {
6421 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6422 if ((value & 255) == ((value >> 8) & 255))
6423 operands[2] = operands[1];
6424 else
6425 {
6426 operands[2] = gen_reg_rtx (SImode);
6427 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6428 }
6429 }
6430 else
6431 {
6432 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6433 if ((value & 255) == ((value >> 8) & 255))
6434 operands[2] = operands[1];
6435 else
6436 {
6437 operands[2] = gen_reg_rtx (SImode);
6438 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6439 }
6440 }
6441
6442 operands[3] = adjust_address (op0, QImode, 1);
6443 operands[0] = adjust_address (operands[0], QImode, 0);
6444 operands[2] = gen_lowpart (QImode, operands[2]);
6445 operands[1] = gen_lowpart (QImode, operands[1]);
6446 }"
6447 )
6448
6449 (define_expand "storehi_single_op"
6450 [(set (match_operand:HI 0 "memory_operand" "")
6451 (match_operand:HI 1 "general_operand" ""))]
6452 "TARGET_32BIT && arm_arch4"
6453 "
6454 if (!s_register_operand (operands[1], HImode))
6455 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6456 "
6457 )
6458
6459 (define_expand "movhi"
6460 [(set (match_operand:HI 0 "general_operand" "")
6461 (match_operand:HI 1 "general_operand" ""))]
6462 "TARGET_EITHER"
6463 "
6464 if (TARGET_ARM)
6465 {
6466 if (can_create_pseudo_p ())
6467 {
6468 if (MEM_P (operands[0]))
6469 {
6470 if (arm_arch4)
6471 {
6472 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6473 DONE;
6474 }
6475 if (CONST_INT_P (operands[1]))
6476 emit_insn (gen_storeinthi (operands[0], operands[1]));
6477 else
6478 {
6479 if (MEM_P (operands[1]))
6480 operands[1] = force_reg (HImode, operands[1]);
6481 if (BYTES_BIG_ENDIAN)
6482 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6483 else
6484 emit_insn (gen_storehi (operands[1], operands[0]));
6485 }
6486 DONE;
6487 }
6488 /* Sign extend a constant, and keep it in an SImode reg. */
6489 else if (CONST_INT_P (operands[1]))
6490 {
6491 rtx reg = gen_reg_rtx (SImode);
6492 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6493
6494 /* If the constant is already valid, leave it alone. */
6495 if (!const_ok_for_arm (val))
6496 {
6497 /* If setting all the top bits will make the constant
6498 loadable in a single instruction, then set them.
6499 Otherwise, sign extend the number. */
6500
6501 if (const_ok_for_arm (~(val | ~0xffff)))
6502 val |= ~0xffff;
6503 else if (val & 0x8000)
6504 val |= ~0xffff;
6505 }
6506
6507 emit_insn (gen_movsi (reg, GEN_INT (val)));
6508 operands[1] = gen_lowpart (HImode, reg);
6509 }
6510 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6511 && MEM_P (operands[1]))
6512 {
6513 rtx reg = gen_reg_rtx (SImode);
6514
6515 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6516 operands[1] = gen_lowpart (HImode, reg);
6517 }
6518 else if (!arm_arch4)
6519 {
6520 if (MEM_P (operands[1]))
6521 {
6522 rtx base;
6523 rtx offset = const0_rtx;
6524 rtx reg = gen_reg_rtx (SImode);
6525
6526 if ((REG_P (base = XEXP (operands[1], 0))
6527 || (GET_CODE (base) == PLUS
6528 && (CONST_INT_P (offset = XEXP (base, 1)))
6529 && ((INTVAL(offset) & 1) != 1)
6530 && REG_P (base = XEXP (base, 0))))
6531 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6532 {
6533 rtx new_rtx;
6534
6535 new_rtx = widen_memory_access (operands[1], SImode,
6536 ((INTVAL (offset) & ~3)
6537 - INTVAL (offset)));
6538 emit_insn (gen_movsi (reg, new_rtx));
6539 if (((INTVAL (offset) & 2) != 0)
6540 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6541 {
6542 rtx reg2 = gen_reg_rtx (SImode);
6543
6544 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6545 reg = reg2;
6546 }
6547 }
6548 else
6549 emit_insn (gen_movhi_bytes (reg, operands[1]));
6550
6551 operands[1] = gen_lowpart (HImode, reg);
6552 }
6553 }
6554 }
6555 /* Handle loading a large integer during reload. */
6556 else if (CONST_INT_P (operands[1])
6557 && !const_ok_for_arm (INTVAL (operands[1]))
6558 && !const_ok_for_arm (~INTVAL (operands[1])))
6559 {
6560 /* Writing a constant to memory needs a scratch, which should
6561 be handled with SECONDARY_RELOADs. */
6562 gcc_assert (REG_P (operands[0]));
6563
6564 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6565 emit_insn (gen_movsi (operands[0], operands[1]));
6566 DONE;
6567 }
6568 }
6569 else if (TARGET_THUMB2)
6570 {
6571 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6572 if (can_create_pseudo_p ())
6573 {
6574 if (!REG_P (operands[0]))
6575 operands[1] = force_reg (HImode, operands[1]);
6576 /* Zero extend a constant, and keep it in an SImode reg. */
6577 else if (CONST_INT_P (operands[1]))
6578 {
6579 rtx reg = gen_reg_rtx (SImode);
6580 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6581
6582 emit_insn (gen_movsi (reg, GEN_INT (val)));
6583 operands[1] = gen_lowpart (HImode, reg);
6584 }
6585 }
6586 }
6587 else /* TARGET_THUMB1 */
6588 {
6589 if (can_create_pseudo_p ())
6590 {
6591 if (CONST_INT_P (operands[1]))
6592 {
6593 rtx reg = gen_reg_rtx (SImode);
6594
6595 emit_insn (gen_movsi (reg, operands[1]));
6596 operands[1] = gen_lowpart (HImode, reg);
6597 }
6598
6599 /* ??? We shouldn't really get invalid addresses here, but this can
6600 happen if we are passed a SP (never OK for HImode/QImode) or
6601 virtual register (also rejected as illegitimate for HImode/QImode)
6602 relative address. */
6603 /* ??? This should perhaps be fixed elsewhere, for instance, in
6604 fixup_stack_1, by checking for other kinds of invalid addresses,
6605 e.g. a bare reference to a virtual register. This may confuse the
6606 alpha though, which must handle this case differently. */
6607 if (MEM_P (operands[0])
6608 && !memory_address_p (GET_MODE (operands[0]),
6609 XEXP (operands[0], 0)))
6610 operands[0]
6611 = replace_equiv_address (operands[0],
6612 copy_to_reg (XEXP (operands[0], 0)));
6613
6614 if (MEM_P (operands[1])
6615 && !memory_address_p (GET_MODE (operands[1]),
6616 XEXP (operands[1], 0)))
6617 operands[1]
6618 = replace_equiv_address (operands[1],
6619 copy_to_reg (XEXP (operands[1], 0)));
6620
6621 if (MEM_P (operands[1]) && optimize > 0)
6622 {
6623 rtx reg = gen_reg_rtx (SImode);
6624
6625 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6626 operands[1] = gen_lowpart (HImode, reg);
6627 }
6628
6629 if (MEM_P (operands[0]))
6630 operands[1] = force_reg (HImode, operands[1]);
6631 }
6632 else if (CONST_INT_P (operands[1])
6633 && !satisfies_constraint_I (operands[1]))
6634 {
6635 /* Handle loading a large integer during reload. */
6636
6637 /* Writing a constant to memory needs a scratch, which should
6638 be handled with SECONDARY_RELOADs. */
6639 gcc_assert (REG_P (operands[0]));
6640
6641 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6642 emit_insn (gen_movsi (operands[0], operands[1]));
6643 DONE;
6644 }
6645 }
6646 "
6647 )
6648
6649 (define_expand "movhi_bytes"
6650 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6651 (set (match_dup 3)
6652 (zero_extend:SI (match_dup 6)))
6653 (set (match_operand:SI 0 "" "")
6654 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6655 "TARGET_ARM"
6656 "
6657 {
6658 rtx mem1, mem2;
6659 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6660
6661 mem1 = change_address (operands[1], QImode, addr);
6662 mem2 = change_address (operands[1], QImode,
6663 plus_constant (Pmode, addr, 1));
6664 operands[0] = gen_lowpart (SImode, operands[0]);
6665 operands[1] = mem1;
6666 operands[2] = gen_reg_rtx (SImode);
6667 operands[3] = gen_reg_rtx (SImode);
6668 operands[6] = mem2;
6669
6670 if (BYTES_BIG_ENDIAN)
6671 {
6672 operands[4] = operands[2];
6673 operands[5] = operands[3];
6674 }
6675 else
6676 {
6677 operands[4] = operands[3];
6678 operands[5] = operands[2];
6679 }
6680 }"
6681 )
6682
6683 (define_expand "movhi_bigend"
6684 [(set (match_dup 2)
6685 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6686 (const_int 16)))
6687 (set (match_dup 3)
6688 (ashiftrt:SI (match_dup 2) (const_int 16)))
6689 (set (match_operand:HI 0 "s_register_operand" "")
6690 (match_dup 4))]
6691 "TARGET_ARM"
6692 "
6693 operands[2] = gen_reg_rtx (SImode);
6694 operands[3] = gen_reg_rtx (SImode);
6695 operands[4] = gen_lowpart (HImode, operands[3]);
6696 "
6697 )
6698
6699 ;; Pattern to recognize insn generated default case above
6700 (define_insn "*movhi_insn_arch4"
6701 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6702 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6703 "TARGET_ARM
6704 && arm_arch4 && !TARGET_HARD_FLOAT
6705 && (register_operand (operands[0], HImode)
6706 || register_operand (operands[1], HImode))"
6707 "@
6708 mov%?\\t%0, %1\\t%@ movhi
6709 mvn%?\\t%0, #%B1\\t%@ movhi
6710 movw%?\\t%0, %L1\\t%@ movhi
6711 strh%?\\t%1, %0\\t%@ movhi
6712 ldrh%?\\t%0, %1\\t%@ movhi"
6713 [(set_attr "predicable" "yes")
6714 (set_attr "pool_range" "*,*,*,*,256")
6715 (set_attr "neg_pool_range" "*,*,*,*,244")
6716 (set_attr "arch" "*,*,v6t2,*,*")
6717 (set_attr_alternative "type"
6718 [(if_then_else (match_operand 1 "const_int_operand" "")
6719 (const_string "mov_imm" )
6720 (const_string "mov_reg"))
6721 (const_string "mvn_imm")
6722 (const_string "mov_imm")
6723 (const_string "store_4")
6724 (const_string "load_4")])]
6725 )
6726
6727 (define_insn "*movhi_bytes"
6728 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6729 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6730 "TARGET_ARM && !TARGET_HARD_FLOAT"
6731 "@
6732 mov%?\\t%0, %1\\t%@ movhi
6733 mov%?\\t%0, %1\\t%@ movhi
6734 mvn%?\\t%0, #%B1\\t%@ movhi"
6735 [(set_attr "predicable" "yes")
6736 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6737 )
6738
6739 ;; We use a DImode scratch because we may occasionally need an additional
6740 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6741 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6742 (define_expand "reload_outhi"
6743 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6744 (match_operand:HI 1 "s_register_operand" "r")
6745 (match_operand:DI 2 "s_register_operand" "=&l")])]
6746 "TARGET_EITHER"
6747 "if (TARGET_ARM)
6748 arm_reload_out_hi (operands);
6749 else
6750 thumb_reload_out_hi (operands);
6751 DONE;
6752 "
6753 )
6754
6755 (define_expand "reload_inhi"
6756 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6757 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6758 (match_operand:DI 2 "s_register_operand" "=&r")])]
6759 "TARGET_EITHER"
6760 "
6761 if (TARGET_ARM)
6762 arm_reload_in_hi (operands);
6763 else
6764 thumb_reload_out_hi (operands);
6765 DONE;
6766 ")
6767
6768 (define_expand "movqi"
6769 [(set (match_operand:QI 0 "general_operand" "")
6770 (match_operand:QI 1 "general_operand" ""))]
6771 "TARGET_EITHER"
6772 "
6773 /* Everything except mem = const or mem = mem can be done easily */
6774
6775 if (can_create_pseudo_p ())
6776 {
6777 if (CONST_INT_P (operands[1]))
6778 {
6779 rtx reg = gen_reg_rtx (SImode);
6780
6781 /* For thumb we want an unsigned immediate, then we are more likely
6782 to be able to use a movs insn. */
6783 if (TARGET_THUMB)
6784 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6785
6786 emit_insn (gen_movsi (reg, operands[1]));
6787 operands[1] = gen_lowpart (QImode, reg);
6788 }
6789
6790 if (TARGET_THUMB)
6791 {
6792 /* ??? We shouldn't really get invalid addresses here, but this can
6793 happen if we are passed a SP (never OK for HImode/QImode) or
6794 virtual register (also rejected as illegitimate for HImode/QImode)
6795 relative address. */
6796 /* ??? This should perhaps be fixed elsewhere, for instance, in
6797 fixup_stack_1, by checking for other kinds of invalid addresses,
6798 e.g. a bare reference to a virtual register. This may confuse the
6799 alpha though, which must handle this case differently. */
6800 if (MEM_P (operands[0])
6801 && !memory_address_p (GET_MODE (operands[0]),
6802 XEXP (operands[0], 0)))
6803 operands[0]
6804 = replace_equiv_address (operands[0],
6805 copy_to_reg (XEXP (operands[0], 0)));
6806 if (MEM_P (operands[1])
6807 && !memory_address_p (GET_MODE (operands[1]),
6808 XEXP (operands[1], 0)))
6809 operands[1]
6810 = replace_equiv_address (operands[1],
6811 copy_to_reg (XEXP (operands[1], 0)));
6812 }
6813
6814 if (MEM_P (operands[1]) && optimize > 0)
6815 {
6816 rtx reg = gen_reg_rtx (SImode);
6817
6818 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6819 operands[1] = gen_lowpart (QImode, reg);
6820 }
6821
6822 if (MEM_P (operands[0]))
6823 operands[1] = force_reg (QImode, operands[1]);
6824 }
6825 else if (TARGET_THUMB
6826 && CONST_INT_P (operands[1])
6827 && !satisfies_constraint_I (operands[1]))
6828 {
6829 /* Handle loading a large integer during reload. */
6830
6831 /* Writing a constant to memory needs a scratch, which should
6832 be handled with SECONDARY_RELOADs. */
6833 gcc_assert (REG_P (operands[0]));
6834
6835 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6836 emit_insn (gen_movsi (operands[0], operands[1]));
6837 DONE;
6838 }
6839 "
6840 )
6841
6842 (define_insn "*arm_movqi_insn"
6843 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6844 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6845 "TARGET_32BIT
6846 && ( register_operand (operands[0], QImode)
6847 || register_operand (operands[1], QImode))"
6848 "@
6849 mov%?\\t%0, %1
6850 mov%?\\t%0, %1
6851 mov%?\\t%0, %1
6852 mov%?\\t%0, %1
6853 mvn%?\\t%0, #%B1
6854 ldrb%?\\t%0, %1
6855 strb%?\\t%1, %0
6856 ldrb%?\\t%0, %1
6857 strb%?\\t%1, %0"
6858 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6859 (set_attr "predicable" "yes")
6860 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6861 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6862 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6863 )
6864
6865 ;; HFmode moves
6866 (define_expand "movhf"
6867 [(set (match_operand:HF 0 "general_operand" "")
6868 (match_operand:HF 1 "general_operand" ""))]
6869 "TARGET_EITHER"
6870 "
6871 if (TARGET_32BIT)
6872 {
6873 if (MEM_P (operands[0]))
6874 operands[1] = force_reg (HFmode, operands[1]);
6875 }
6876 else /* TARGET_THUMB1 */
6877 {
6878 if (can_create_pseudo_p ())
6879 {
6880 if (!REG_P (operands[0]))
6881 operands[1] = force_reg (HFmode, operands[1]);
6882 }
6883 }
6884 "
6885 )
6886
6887 (define_insn "*arm32_movhf"
6888 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6889 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6890 "TARGET_32BIT && !TARGET_HARD_FLOAT
6891 && ( s_register_operand (operands[0], HFmode)
6892 || s_register_operand (operands[1], HFmode))"
6893 "*
6894 switch (which_alternative)
6895 {
6896 case 0: /* ARM register from memory */
6897 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6898 case 1: /* memory from ARM register */
6899 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6900 case 2: /* ARM register from ARM register */
6901 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6902 case 3: /* ARM register from constant */
6903 {
6904 long bits;
6905 rtx ops[4];
6906
6907 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6908 HFmode);
6909 ops[0] = operands[0];
6910 ops[1] = GEN_INT (bits);
6911 ops[2] = GEN_INT (bits & 0xff00);
6912 ops[3] = GEN_INT (bits & 0x00ff);
6913
6914 if (arm_arch_thumb2)
6915 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6916 else
6917 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6918 return \"\";
6919 }
6920 default:
6921 gcc_unreachable ();
6922 }
6923 "
6924 [(set_attr "conds" "unconditional")
6925 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6926 (set_attr "length" "4,4,4,8")
6927 (set_attr "predicable" "yes")]
6928 )
6929
6930 (define_expand "movsf"
6931 [(set (match_operand:SF 0 "general_operand" "")
6932 (match_operand:SF 1 "general_operand" ""))]
6933 "TARGET_EITHER"
6934 "
6935 if (TARGET_32BIT)
6936 {
6937 if (MEM_P (operands[0]))
6938 operands[1] = force_reg (SFmode, operands[1]);
6939 }
6940 else /* TARGET_THUMB1 */
6941 {
6942 if (can_create_pseudo_p ())
6943 {
6944 if (!REG_P (operands[0]))
6945 operands[1] = force_reg (SFmode, operands[1]);
6946 }
6947 }
6948
6949 /* Cannot load it directly, generate a load with clobber so that it can be
6950 loaded via GPR with MOV / MOVT. */
6951 if (arm_disable_literal_pool
6952 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6953 && CONST_DOUBLE_P (operands[1])
6954 && TARGET_HARD_FLOAT
6955 && !vfp3_const_double_rtx (operands[1]))
6956 {
6957 rtx clobreg = gen_reg_rtx (SFmode);
6958 emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
6959 clobreg));
6960 DONE;
6961 }
6962 "
6963 )
6964
6965 ;; Transform a floating-point move of a constant into a core register into
6966 ;; an SImode operation.
6967 (define_split
6968 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6969 (match_operand:SF 1 "immediate_operand" ""))]
6970 "TARGET_EITHER
6971 && reload_completed
6972 && CONST_DOUBLE_P (operands[1])"
6973 [(set (match_dup 2) (match_dup 3))]
6974 "
6975 operands[2] = gen_lowpart (SImode, operands[0]);
6976 operands[3] = gen_lowpart (SImode, operands[1]);
6977 if (operands[2] == 0 || operands[3] == 0)
6978 FAIL;
6979 "
6980 )
6981
6982 (define_insn "*arm_movsf_soft_insn"
6983 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6984 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6985 "TARGET_32BIT
6986 && TARGET_SOFT_FLOAT
6987 && (!MEM_P (operands[0])
6988 || register_operand (operands[1], SFmode))"
6989 {
6990 switch (which_alternative)
6991 {
6992 case 0: return \"mov%?\\t%0, %1\";
6993 case 1:
6994 /* Cannot load it directly, split to load it via MOV / MOVT. */
6995 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
6996 return \"#\";
6997 return \"ldr%?\\t%0, %1\\t%@ float\";
6998 case 2: return \"str%?\\t%1, %0\\t%@ float\";
6999 default: gcc_unreachable ();
7000 }
7001 }
7002 [(set_attr "predicable" "yes")
7003 (set_attr "type" "mov_reg,load_4,store_4")
7004 (set_attr "arm_pool_range" "*,4096,*")
7005 (set_attr "thumb2_pool_range" "*,4094,*")
7006 (set_attr "arm_neg_pool_range" "*,4084,*")
7007 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7008 )
7009
7010 ;; Splitter for the above.
7011 (define_split
7012 [(set (match_operand:SF 0 "s_register_operand")
7013 (match_operand:SF 1 "const_double_operand"))]
7014 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7015 [(const_int 0)]
7016 {
7017 long buf;
7018 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
7019 rtx cst = gen_int_mode (buf, SImode);
7020 emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
7021 DONE;
7022 }
7023 )
7024
7025 (define_expand "movdf"
7026 [(set (match_operand:DF 0 "general_operand" "")
7027 (match_operand:DF 1 "general_operand" ""))]
7028 "TARGET_EITHER"
7029 "
7030 if (TARGET_32BIT)
7031 {
7032 if (MEM_P (operands[0]))
7033 operands[1] = force_reg (DFmode, operands[1]);
7034 }
7035 else /* TARGET_THUMB */
7036 {
7037 if (can_create_pseudo_p ())
7038 {
7039 if (!REG_P (operands[0]))
7040 operands[1] = force_reg (DFmode, operands[1]);
7041 }
7042 }
7043
7044 /* Cannot load it directly, generate a load with clobber so that it can be
7045 loaded via GPR with MOV / MOVT. */
7046 if (arm_disable_literal_pool
7047 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
7048 && CONSTANT_P (operands[1])
7049 && TARGET_HARD_FLOAT
7050 && !arm_const_double_rtx (operands[1])
7051 && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
7052 {
7053 rtx clobreg = gen_reg_rtx (DFmode);
7054 emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
7055 clobreg));
7056 DONE;
7057 }
7058 "
7059 )
7060
7061 ;; Reloading a df mode value stored in integer regs to memory can require a
7062 ;; scratch reg.
7063 (define_expand "reload_outdf"
7064 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7065 (match_operand:DF 1 "s_register_operand" "r")
7066 (match_operand:SI 2 "s_register_operand" "=&r")]
7067 "TARGET_THUMB2"
7068 "
7069 {
7070 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7071
7072 if (code == REG)
7073 operands[2] = XEXP (operands[0], 0);
7074 else if (code == POST_INC || code == PRE_DEC)
7075 {
7076 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7077 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7078 emit_insn (gen_movdi (operands[0], operands[1]));
7079 DONE;
7080 }
7081 else if (code == PRE_INC)
7082 {
7083 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7084
7085 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7086 operands[2] = reg;
7087 }
7088 else if (code == POST_DEC)
7089 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7090 else
7091 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7092 XEXP (XEXP (operands[0], 0), 1)));
7093
7094 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7095 operands[1]));
7096
7097 if (code == POST_DEC)
7098 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7099
7100 DONE;
7101 }"
7102 )
7103
7104 (define_insn "*movdf_soft_insn"
7105 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7106 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7107 "TARGET_32BIT && TARGET_SOFT_FLOAT
7108 && ( register_operand (operands[0], DFmode)
7109 || register_operand (operands[1], DFmode))"
7110 "*
7111 switch (which_alternative)
7112 {
7113 case 0:
7114 case 1:
7115 case 2:
7116 return \"#\";
7117 case 3:
7118 /* Cannot load it directly, split to load it via MOV / MOVT. */
7119 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7120 return \"#\";
7121 /* Fall through. */
7122 default:
7123 return output_move_double (operands, true, NULL);
7124 }
7125 "
7126 [(set_attr "length" "8,12,16,8,8")
7127 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7128 (set_attr "arm_pool_range" "*,*,*,1020,*")
7129 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7130 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7131 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7132 )
7133
7134 ;; Splitter for the above.
7135 (define_split
7136 [(set (match_operand:DF 0 "s_register_operand")
7137 (match_operand:DF 1 "const_double_operand"))]
7138 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7139 [(const_int 0)]
7140 {
7141 long buf[2];
7142 int order = BYTES_BIG_ENDIAN ? 1 : 0;
7143 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
7144 unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
7145 ival |= (zext_hwi (buf[1 - order], 32) << 32);
7146 rtx cst = gen_int_mode (ival, DImode);
7147 emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
7148 DONE;
7149 }
7150 )
7151 \f
7152
7153 ;; load- and store-multiple insns
7154 ;; The arm can load/store any set of registers, provided that they are in
7155 ;; ascending order, but these expanders assume a contiguous set.
7156
7157 (define_expand "load_multiple"
7158 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7159 (match_operand:SI 1 "" ""))
7160 (use (match_operand:SI 2 "" ""))])]
7161 "TARGET_32BIT"
7162 {
7163 HOST_WIDE_INT offset = 0;
7164
7165 /* Support only fixed point registers. */
7166 if (!CONST_INT_P (operands[2])
7167 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7168 || INTVAL (operands[2]) < 2
7169 || !MEM_P (operands[1])
7170 || !REG_P (operands[0])
7171 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7172 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7173 FAIL;
7174
7175 operands[3]
7176 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7177 INTVAL (operands[2]),
7178 force_reg (SImode, XEXP (operands[1], 0)),
7179 FALSE, operands[1], &offset);
7180 })
7181
7182 (define_expand "store_multiple"
7183 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7184 (match_operand:SI 1 "" ""))
7185 (use (match_operand:SI 2 "" ""))])]
7186 "TARGET_32BIT"
7187 {
7188 HOST_WIDE_INT offset = 0;
7189
7190 /* Support only fixed point registers. */
7191 if (!CONST_INT_P (operands[2])
7192 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7193 || INTVAL (operands[2]) < 2
7194 || !REG_P (operands[1])
7195 || !MEM_P (operands[0])
7196 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7197 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7198 FAIL;
7199
7200 operands[3]
7201 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7202 INTVAL (operands[2]),
7203 force_reg (SImode, XEXP (operands[0], 0)),
7204 FALSE, operands[0], &offset);
7205 })
7206
7207
7208 (define_expand "setmemsi"
7209 [(match_operand:BLK 0 "general_operand" "")
7210 (match_operand:SI 1 "const_int_operand" "")
7211 (match_operand:SI 2 "const_int_operand" "")
7212 (match_operand:SI 3 "const_int_operand" "")]
7213 "TARGET_32BIT"
7214 {
7215 if (arm_gen_setmem (operands))
7216 DONE;
7217
7218 FAIL;
7219 })
7220
7221
7222 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7223 ;; We could let this apply for blocks of less than this, but it clobbers so
7224 ;; many registers that there is then probably a better way.
7225
7226 (define_expand "movmemqi"
7227 [(match_operand:BLK 0 "general_operand" "")
7228 (match_operand:BLK 1 "general_operand" "")
7229 (match_operand:SI 2 "const_int_operand" "")
7230 (match_operand:SI 3 "const_int_operand" "")]
7231 ""
7232 "
7233 if (TARGET_32BIT)
7234 {
7235 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7236 && !optimize_function_for_size_p (cfun))
7237 {
7238 if (gen_movmem_ldrd_strd (operands))
7239 DONE;
7240 FAIL;
7241 }
7242
7243 if (arm_gen_movmemqi (operands))
7244 DONE;
7245 FAIL;
7246 }
7247 else /* TARGET_THUMB1 */
7248 {
7249 if ( INTVAL (operands[3]) != 4
7250 || INTVAL (operands[2]) > 48)
7251 FAIL;
7252
7253 thumb_expand_movmemqi (operands);
7254 DONE;
7255 }
7256 "
7257 )
7258 \f
7259
7260 ;; Compare & branch insns
7261 ;; The range calculations are based as follows:
7262 ;; For forward branches, the address calculation returns the address of
7263 ;; the next instruction. This is 2 beyond the branch instruction.
7264 ;; For backward branches, the address calculation returns the address of
7265 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7266 ;; instruction for the shortest sequence, and 4 before the branch instruction
7267 ;; if we have to jump around an unconditional branch.
7268 ;; To the basic branch range the PC offset must be added (this is +4).
7269 ;; So for forward branches we have
7270 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7271 ;; And for backward branches we have
7272 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7273 ;;
7274 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7275 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7276
7277 (define_expand "cbranchsi4"
7278 [(set (pc) (if_then_else
7279 (match_operator 0 "expandable_comparison_operator"
7280 [(match_operand:SI 1 "s_register_operand" "")
7281 (match_operand:SI 2 "nonmemory_operand" "")])
7282 (label_ref (match_operand 3 "" ""))
7283 (pc)))]
7284 "TARGET_EITHER"
7285 "
7286 if (!TARGET_THUMB1)
7287 {
7288 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7289 FAIL;
7290 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7291 operands[3]));
7292 DONE;
7293 }
7294 if (thumb1_cmpneg_operand (operands[2], SImode))
7295 {
7296 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7297 operands[3], operands[0]));
7298 DONE;
7299 }
7300 if (!thumb1_cmp_operand (operands[2], SImode))
7301 operands[2] = force_reg (SImode, operands[2]);
7302 ")
7303
7304 (define_expand "cbranchsf4"
7305 [(set (pc) (if_then_else
7306 (match_operator 0 "expandable_comparison_operator"
7307 [(match_operand:SF 1 "s_register_operand" "")
7308 (match_operand:SF 2 "vfp_compare_operand" "")])
7309 (label_ref (match_operand 3 "" ""))
7310 (pc)))]
7311 "TARGET_32BIT && TARGET_HARD_FLOAT"
7312 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7313 operands[3])); DONE;"
7314 )
7315
7316 (define_expand "cbranchdf4"
7317 [(set (pc) (if_then_else
7318 (match_operator 0 "expandable_comparison_operator"
7319 [(match_operand:DF 1 "s_register_operand" "")
7320 (match_operand:DF 2 "vfp_compare_operand" "")])
7321 (label_ref (match_operand 3 "" ""))
7322 (pc)))]
7323 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7324 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7325 operands[3])); DONE;"
7326 )
7327
7328 (define_expand "cbranchdi4"
7329 [(set (pc) (if_then_else
7330 (match_operator 0 "expandable_comparison_operator"
7331 [(match_operand:DI 1 "s_register_operand" "")
7332 (match_operand:DI 2 "cmpdi_operand" "")])
7333 (label_ref (match_operand 3 "" ""))
7334 (pc)))]
7335 "TARGET_32BIT"
7336 "{
7337 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7338 FAIL;
7339 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7340 operands[3]));
7341 DONE;
7342 }"
7343 )
7344
7345 ;; Comparison and test insns
7346
7347 (define_insn "*arm_cmpsi_insn"
7348 [(set (reg:CC CC_REGNUM)
7349 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7350 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7351 "TARGET_32BIT"
7352 "@
7353 cmp%?\\t%0, %1
7354 cmp%?\\t%0, %1
7355 cmp%?\\t%0, %1
7356 cmp%?\\t%0, %1
7357 cmn%?\\t%0, #%n1"
7358 [(set_attr "conds" "set")
7359 (set_attr "arch" "t2,t2,any,any,any")
7360 (set_attr "length" "2,2,4,4,4")
7361 (set_attr "predicable" "yes")
7362 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7363 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7364 )
7365
7366 (define_insn "*cmpsi_shiftsi"
7367 [(set (reg:CC CC_REGNUM)
7368 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7369 (match_operator:SI 3 "shift_operator"
7370 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7371 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7372 "TARGET_32BIT"
7373 "cmp\\t%0, %1%S3"
7374 [(set_attr "conds" "set")
7375 (set_attr "shift" "1")
7376 (set_attr "arch" "32,a,a")
7377 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7378
7379 (define_insn "*cmpsi_shiftsi_swp"
7380 [(set (reg:CC_SWP CC_REGNUM)
7381 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7382 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7383 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7384 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7385 "TARGET_32BIT"
7386 "cmp%?\\t%0, %1%S3"
7387 [(set_attr "conds" "set")
7388 (set_attr "shift" "1")
7389 (set_attr "arch" "32,a,a")
7390 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7391
7392 (define_insn "*arm_cmpsi_negshiftsi_si"
7393 [(set (reg:CC_Z CC_REGNUM)
7394 (compare:CC_Z
7395 (neg:SI (match_operator:SI 1 "shift_operator"
7396 [(match_operand:SI 2 "s_register_operand" "r")
7397 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7398 (match_operand:SI 0 "s_register_operand" "r")))]
7399 "TARGET_ARM"
7400 "cmn%?\\t%0, %2%S1"
7401 [(set_attr "conds" "set")
7402 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7403 (const_string "alus_shift_imm")
7404 (const_string "alus_shift_reg")))
7405 (set_attr "predicable" "yes")]
7406 )
7407
7408 ;; DImode comparisons. The generic code generates branches that
7409 ;; if-conversion cannot reduce to a conditional compare, so we do
7410 ;; that directly.
7411
7412 (define_insn_and_split "*arm_cmpdi_insn"
7413 [(set (reg:CC_NCV CC_REGNUM)
7414 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7415 (match_operand:DI 1 "arm_di_operand" "rDi")))
7416 (clobber (match_scratch:SI 2 "=r"))]
7417 "TARGET_32BIT"
7418 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7419 "&& reload_completed"
7420 [(set (reg:CC CC_REGNUM)
7421 (compare:CC (match_dup 0) (match_dup 1)))
7422 (parallel [(set (reg:CC CC_REGNUM)
7423 (compare:CC (match_dup 3) (match_dup 4)))
7424 (set (match_dup 2)
7425 (minus:SI (match_dup 5)
7426 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7427 {
7428 operands[3] = gen_highpart (SImode, operands[0]);
7429 operands[0] = gen_lowpart (SImode, operands[0]);
7430 if (CONST_INT_P (operands[1]))
7431 {
7432 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7433 DImode,
7434 operands[1])));
7435 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7436 }
7437 else
7438 {
7439 operands[4] = gen_highpart (SImode, operands[1]);
7440 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7441 }
7442 operands[1] = gen_lowpart (SImode, operands[1]);
7443 operands[2] = gen_lowpart (SImode, operands[2]);
7444 }
7445 [(set_attr "conds" "set")
7446 (set_attr "length" "8")
7447 (set_attr "type" "multiple")]
7448 )
7449
7450 (define_insn_and_split "*arm_cmpdi_unsigned"
7451 [(set (reg:CC_CZ CC_REGNUM)
7452 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7453 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7454
7455 "TARGET_32BIT"
7456 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7457 "&& reload_completed"
7458 [(set (reg:CC CC_REGNUM)
7459 (compare:CC (match_dup 2) (match_dup 3)))
7460 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7461 (set (reg:CC CC_REGNUM)
7462 (compare:CC (match_dup 0) (match_dup 1))))]
7463 {
7464 operands[2] = gen_highpart (SImode, operands[0]);
7465 operands[0] = gen_lowpart (SImode, operands[0]);
7466 if (CONST_INT_P (operands[1]))
7467 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7468 else
7469 operands[3] = gen_highpart (SImode, operands[1]);
7470 operands[1] = gen_lowpart (SImode, operands[1]);
7471 }
7472 [(set_attr "conds" "set")
7473 (set_attr "enabled_for_short_it" "yes,yes,no,*")
7474 (set_attr "arch" "t2,t2,t2,a")
7475 (set_attr "length" "6,6,10,8")
7476 (set_attr "type" "multiple")]
7477 )
7478
7479 (define_insn "*arm_cmpdi_zero"
7480 [(set (reg:CC_Z CC_REGNUM)
7481 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7482 (const_int 0)))
7483 (clobber (match_scratch:SI 1 "=r"))]
7484 "TARGET_32BIT"
7485 "orrs%?\\t%1, %Q0, %R0"
7486 [(set_attr "conds" "set")
7487 (set_attr "type" "logics_reg")]
7488 )
7489
7490 ; This insn allows redundant compares to be removed by cse, nothing should
7491 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7492 ; is deleted later on. The match_dup will match the mode here, so that
7493 ; mode changes of the condition codes aren't lost by this even though we don't
7494 ; specify what they are.
7495
7496 (define_insn "*deleted_compare"
7497 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7498 "TARGET_32BIT"
7499 "\\t%@ deleted compare"
7500 [(set_attr "conds" "set")
7501 (set_attr "length" "0")
7502 (set_attr "type" "no_insn")]
7503 )
7504
7505 \f
7506 ;; Conditional branch insns
7507
7508 (define_expand "cbranch_cc"
7509 [(set (pc)
7510 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7511 (match_operand 2 "" "")])
7512 (label_ref (match_operand 3 "" ""))
7513 (pc)))]
7514 "TARGET_32BIT"
7515 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7516 operands[1], operands[2], NULL_RTX);
7517 operands[2] = const0_rtx;"
7518 )
7519
7520 ;;
7521 ;; Patterns to match conditional branch insns.
7522 ;;
7523
7524 (define_insn "arm_cond_branch"
7525 [(set (pc)
7526 (if_then_else (match_operator 1 "arm_comparison_operator"
7527 [(match_operand 2 "cc_register" "") (const_int 0)])
7528 (label_ref (match_operand 0 "" ""))
7529 (pc)))]
7530 "TARGET_32BIT"
7531 "*
7532 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7533 {
7534 arm_ccfsm_state += 2;
7535 return \"\";
7536 }
7537 return \"b%d1\\t%l0\";
7538 "
7539 [(set_attr "conds" "use")
7540 (set_attr "type" "branch")
7541 (set (attr "length")
7542 (if_then_else
7543 (and (match_test "TARGET_THUMB2")
7544 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7545 (le (minus (match_dup 0) (pc)) (const_int 256))))
7546 (const_int 2)
7547 (const_int 4)))]
7548 )
7549
7550 (define_insn "*arm_cond_branch_reversed"
7551 [(set (pc)
7552 (if_then_else (match_operator 1 "arm_comparison_operator"
7553 [(match_operand 2 "cc_register" "") (const_int 0)])
7554 (pc)
7555 (label_ref (match_operand 0 "" ""))))]
7556 "TARGET_32BIT"
7557 "*
7558 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7559 {
7560 arm_ccfsm_state += 2;
7561 return \"\";
7562 }
7563 return \"b%D1\\t%l0\";
7564 "
7565 [(set_attr "conds" "use")
7566 (set_attr "type" "branch")
7567 (set (attr "length")
7568 (if_then_else
7569 (and (match_test "TARGET_THUMB2")
7570 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7571 (le (minus (match_dup 0) (pc)) (const_int 256))))
7572 (const_int 2)
7573 (const_int 4)))]
7574 )
7575
7576 \f
7577
7578 ; scc insns
7579
7580 (define_expand "cstore_cc"
7581 [(set (match_operand:SI 0 "s_register_operand" "")
7582 (match_operator:SI 1 "" [(match_operand 2 "" "")
7583 (match_operand 3 "" "")]))]
7584 "TARGET_32BIT"
7585 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7586 operands[2], operands[3], NULL_RTX);
7587 operands[3] = const0_rtx;"
7588 )
7589
7590 (define_insn_and_split "*mov_scc"
7591 [(set (match_operand:SI 0 "s_register_operand" "=r")
7592 (match_operator:SI 1 "arm_comparison_operator_mode"
7593 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7594 "TARGET_ARM"
7595 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7596 "TARGET_ARM"
7597 [(set (match_dup 0)
7598 (if_then_else:SI (match_dup 1)
7599 (const_int 1)
7600 (const_int 0)))]
7601 ""
7602 [(set_attr "conds" "use")
7603 (set_attr "length" "8")
7604 (set_attr "type" "multiple")]
7605 )
7606
7607 (define_insn_and_split "*mov_negscc"
7608 [(set (match_operand:SI 0 "s_register_operand" "=r")
7609 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7610 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7611 "TARGET_ARM"
7612 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7613 "TARGET_ARM"
7614 [(set (match_dup 0)
7615 (if_then_else:SI (match_dup 1)
7616 (match_dup 3)
7617 (const_int 0)))]
7618 {
7619 operands[3] = GEN_INT (~0);
7620 }
7621 [(set_attr "conds" "use")
7622 (set_attr "length" "8")
7623 (set_attr "type" "multiple")]
7624 )
7625
7626 (define_insn_and_split "*mov_notscc"
7627 [(set (match_operand:SI 0 "s_register_operand" "=r")
7628 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7629 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7630 "TARGET_ARM"
7631 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7632 "TARGET_ARM"
7633 [(set (match_dup 0)
7634 (if_then_else:SI (match_dup 1)
7635 (match_dup 3)
7636 (match_dup 4)))]
7637 {
7638 operands[3] = GEN_INT (~1);
7639 operands[4] = GEN_INT (~0);
7640 }
7641 [(set_attr "conds" "use")
7642 (set_attr "length" "8")
7643 (set_attr "type" "multiple")]
7644 )
7645
7646 (define_expand "cstoresi4"
7647 [(set (match_operand:SI 0 "s_register_operand" "")
7648 (match_operator:SI 1 "expandable_comparison_operator"
7649 [(match_operand:SI 2 "s_register_operand" "")
7650 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7651 "TARGET_32BIT || TARGET_THUMB1"
7652 "{
7653 rtx op3, scratch, scratch2;
7654
7655 if (!TARGET_THUMB1)
7656 {
7657 if (!arm_add_operand (operands[3], SImode))
7658 operands[3] = force_reg (SImode, operands[3]);
7659 emit_insn (gen_cstore_cc (operands[0], operands[1],
7660 operands[2], operands[3]));
7661 DONE;
7662 }
7663
7664 if (operands[3] == const0_rtx)
7665 {
7666 switch (GET_CODE (operands[1]))
7667 {
7668 case EQ:
7669 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7670 break;
7671
7672 case NE:
7673 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7674 break;
7675
7676 case LE:
7677 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7678 NULL_RTX, 0, OPTAB_WIDEN);
7679 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7680 NULL_RTX, 0, OPTAB_WIDEN);
7681 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7682 operands[0], 1, OPTAB_WIDEN);
7683 break;
7684
7685 case GE:
7686 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7687 NULL_RTX, 1);
7688 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7689 NULL_RTX, 1, OPTAB_WIDEN);
7690 break;
7691
7692 case GT:
7693 scratch = expand_binop (SImode, ashr_optab, operands[2],
7694 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7695 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7696 NULL_RTX, 0, OPTAB_WIDEN);
7697 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7698 0, OPTAB_WIDEN);
7699 break;
7700
7701 /* LT is handled by generic code. No need for unsigned with 0. */
7702 default:
7703 FAIL;
7704 }
7705 DONE;
7706 }
7707
7708 switch (GET_CODE (operands[1]))
7709 {
7710 case EQ:
7711 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7712 NULL_RTX, 0, OPTAB_WIDEN);
7713 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7714 break;
7715
7716 case NE:
7717 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7718 NULL_RTX, 0, OPTAB_WIDEN);
7719 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7720 break;
7721
7722 case LE:
7723 op3 = force_reg (SImode, operands[3]);
7724
7725 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7726 NULL_RTX, 1, OPTAB_WIDEN);
7727 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7728 NULL_RTX, 0, OPTAB_WIDEN);
7729 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7730 op3, operands[2]));
7731 break;
7732
7733 case GE:
7734 op3 = operands[3];
7735 if (!thumb1_cmp_operand (op3, SImode))
7736 op3 = force_reg (SImode, op3);
7737 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7738 NULL_RTX, 0, OPTAB_WIDEN);
7739 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7740 NULL_RTX, 1, OPTAB_WIDEN);
7741 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7742 operands[2], op3));
7743 break;
7744
7745 case LEU:
7746 op3 = force_reg (SImode, operands[3]);
7747 scratch = force_reg (SImode, const0_rtx);
7748 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7749 op3, operands[2]));
7750 break;
7751
7752 case GEU:
7753 op3 = operands[3];
7754 if (!thumb1_cmp_operand (op3, SImode))
7755 op3 = force_reg (SImode, op3);
7756 scratch = force_reg (SImode, const0_rtx);
7757 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7758 operands[2], op3));
7759 break;
7760
7761 case LTU:
7762 op3 = operands[3];
7763 if (!thumb1_cmp_operand (op3, SImode))
7764 op3 = force_reg (SImode, op3);
7765 scratch = gen_reg_rtx (SImode);
7766 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7767 break;
7768
7769 case GTU:
7770 op3 = force_reg (SImode, operands[3]);
7771 scratch = gen_reg_rtx (SImode);
7772 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7773 break;
7774
7775 /* No good sequences for GT, LT. */
7776 default:
7777 FAIL;
7778 }
7779 DONE;
7780 }")
7781
7782 (define_expand "cstorehf4"
7783 [(set (match_operand:SI 0 "s_register_operand")
7784 (match_operator:SI 1 "expandable_comparison_operator"
7785 [(match_operand:HF 2 "s_register_operand")
7786 (match_operand:HF 3 "vfp_compare_operand")]))]
7787 "TARGET_VFP_FP16INST"
7788 {
7789 if (!arm_validize_comparison (&operands[1],
7790 &operands[2],
7791 &operands[3]))
7792 FAIL;
7793
7794 emit_insn (gen_cstore_cc (operands[0], operands[1],
7795 operands[2], operands[3]));
7796 DONE;
7797 }
7798 )
7799
7800 (define_expand "cstoresf4"
7801 [(set (match_operand:SI 0 "s_register_operand" "")
7802 (match_operator:SI 1 "expandable_comparison_operator"
7803 [(match_operand:SF 2 "s_register_operand" "")
7804 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7805 "TARGET_32BIT && TARGET_HARD_FLOAT"
7806 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7807 operands[2], operands[3])); DONE;"
7808 )
7809
7810 (define_expand "cstoredf4"
7811 [(set (match_operand:SI 0 "s_register_operand" "")
7812 (match_operator:SI 1 "expandable_comparison_operator"
7813 [(match_operand:DF 2 "s_register_operand" "")
7814 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7815 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7816 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7817 operands[2], operands[3])); DONE;"
7818 )
7819
7820 (define_expand "cstoredi4"
7821 [(set (match_operand:SI 0 "s_register_operand" "")
7822 (match_operator:SI 1 "expandable_comparison_operator"
7823 [(match_operand:DI 2 "s_register_operand" "")
7824 (match_operand:DI 3 "cmpdi_operand" "")]))]
7825 "TARGET_32BIT"
7826 "{
7827 if (!arm_validize_comparison (&operands[1],
7828 &operands[2],
7829 &operands[3]))
7830 FAIL;
7831 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7832 operands[3]));
7833 DONE;
7834 }"
7835 )
7836
7837 \f
7838 ;; Conditional move insns
7839
7840 (define_expand "movsicc"
7841 [(set (match_operand:SI 0 "s_register_operand" "")
7842 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7843 (match_operand:SI 2 "arm_not_operand" "")
7844 (match_operand:SI 3 "arm_not_operand" "")))]
7845 "TARGET_32BIT"
7846 "
7847 {
7848 enum rtx_code code;
7849 rtx ccreg;
7850
7851 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7852 &XEXP (operands[1], 1)))
7853 FAIL;
7854
7855 code = GET_CODE (operands[1]);
7856 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7857 XEXP (operands[1], 1), NULL_RTX);
7858 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7859 }"
7860 )
7861
7862 (define_expand "movhfcc"
7863 [(set (match_operand:HF 0 "s_register_operand")
7864 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7865 (match_operand:HF 2 "s_register_operand")
7866 (match_operand:HF 3 "s_register_operand")))]
7867 "TARGET_VFP_FP16INST"
7868 "
7869 {
7870 enum rtx_code code = GET_CODE (operands[1]);
7871 rtx ccreg;
7872
7873 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7874 &XEXP (operands[1], 1)))
7875 FAIL;
7876
7877 code = GET_CODE (operands[1]);
7878 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7879 XEXP (operands[1], 1), NULL_RTX);
7880 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7881 }"
7882 )
7883
7884 (define_expand "movsfcc"
7885 [(set (match_operand:SF 0 "s_register_operand" "")
7886 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7887 (match_operand:SF 2 "s_register_operand" "")
7888 (match_operand:SF 3 "s_register_operand" "")))]
7889 "TARGET_32BIT && TARGET_HARD_FLOAT"
7890 "
7891 {
7892 enum rtx_code code = GET_CODE (operands[1]);
7893 rtx ccreg;
7894
7895 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7896 &XEXP (operands[1], 1)))
7897 FAIL;
7898
7899 code = GET_CODE (operands[1]);
7900 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7901 XEXP (operands[1], 1), NULL_RTX);
7902 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7903 }"
7904 )
7905
7906 (define_expand "movdfcc"
7907 [(set (match_operand:DF 0 "s_register_operand" "")
7908 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7909 (match_operand:DF 2 "s_register_operand" "")
7910 (match_operand:DF 3 "s_register_operand" "")))]
7911 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7912 "
7913 {
7914 enum rtx_code code = GET_CODE (operands[1]);
7915 rtx ccreg;
7916
7917 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7918 &XEXP (operands[1], 1)))
7919 FAIL;
7920 code = GET_CODE (operands[1]);
7921 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7922 XEXP (operands[1], 1), NULL_RTX);
7923 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7924 }"
7925 )
7926
7927 (define_insn "*cmov<mode>"
7928 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7929 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7930 [(match_operand 2 "cc_register" "") (const_int 0)])
7931 (match_operand:SDF 3 "s_register_operand"
7932 "<F_constraint>")
7933 (match_operand:SDF 4 "s_register_operand"
7934 "<F_constraint>")))]
7935 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7936 "*
7937 {
7938 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7939 switch (code)
7940 {
7941 case ARM_GE:
7942 case ARM_GT:
7943 case ARM_EQ:
7944 case ARM_VS:
7945 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7946 case ARM_LT:
7947 case ARM_LE:
7948 case ARM_NE:
7949 case ARM_VC:
7950 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7951 default:
7952 gcc_unreachable ();
7953 }
7954 return \"\";
7955 }"
7956 [(set_attr "conds" "use")
7957 (set_attr "type" "fcsel")]
7958 )
7959
7960 (define_insn "*cmovhf"
7961 [(set (match_operand:HF 0 "s_register_operand" "=t")
7962 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7963 [(match_operand 2 "cc_register" "") (const_int 0)])
7964 (match_operand:HF 3 "s_register_operand" "t")
7965 (match_operand:HF 4 "s_register_operand" "t")))]
7966 "TARGET_VFP_FP16INST"
7967 "*
7968 {
7969 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7970 switch (code)
7971 {
7972 case ARM_GE:
7973 case ARM_GT:
7974 case ARM_EQ:
7975 case ARM_VS:
7976 return \"vsel%d1.f16\\t%0, %3, %4\";
7977 case ARM_LT:
7978 case ARM_LE:
7979 case ARM_NE:
7980 case ARM_VC:
7981 return \"vsel%D1.f16\\t%0, %4, %3\";
7982 default:
7983 gcc_unreachable ();
7984 }
7985 return \"\";
7986 }"
7987 [(set_attr "conds" "use")
7988 (set_attr "type" "fcsel")]
7989 )
7990
7991 (define_insn_and_split "*movsicc_insn"
7992 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7993 (if_then_else:SI
7994 (match_operator 3 "arm_comparison_operator"
7995 [(match_operand 4 "cc_register" "") (const_int 0)])
7996 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7997 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7998 "TARGET_ARM"
7999 "@
8000 mov%D3\\t%0, %2
8001 mvn%D3\\t%0, #%B2
8002 mov%d3\\t%0, %1
8003 mvn%d3\\t%0, #%B1
8004 #
8005 #
8006 #
8007 #"
8008 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8009 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8010 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8011 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8012 "&& reload_completed"
8013 [(const_int 0)]
8014 {
8015 enum rtx_code rev_code;
8016 machine_mode mode;
8017 rtx rev_cond;
8018
8019 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8020 operands[3],
8021 gen_rtx_SET (operands[0], operands[1])));
8022
8023 rev_code = GET_CODE (operands[3]);
8024 mode = GET_MODE (operands[4]);
8025 if (mode == CCFPmode || mode == CCFPEmode)
8026 rev_code = reverse_condition_maybe_unordered (rev_code);
8027 else
8028 rev_code = reverse_condition (rev_code);
8029
8030 rev_cond = gen_rtx_fmt_ee (rev_code,
8031 VOIDmode,
8032 operands[4],
8033 const0_rtx);
8034 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8035 rev_cond,
8036 gen_rtx_SET (operands[0], operands[2])));
8037 DONE;
8038 }
8039 [(set_attr "length" "4,4,4,4,8,8,8,8")
8040 (set_attr "conds" "use")
8041 (set_attr_alternative "type"
8042 [(if_then_else (match_operand 2 "const_int_operand" "")
8043 (const_string "mov_imm")
8044 (const_string "mov_reg"))
8045 (const_string "mvn_imm")
8046 (if_then_else (match_operand 1 "const_int_operand" "")
8047 (const_string "mov_imm")
8048 (const_string "mov_reg"))
8049 (const_string "mvn_imm")
8050 (const_string "multiple")
8051 (const_string "multiple")
8052 (const_string "multiple")
8053 (const_string "multiple")])]
8054 )
8055
8056 (define_insn "*movsfcc_soft_insn"
8057 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8058 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8059 [(match_operand 4 "cc_register" "") (const_int 0)])
8060 (match_operand:SF 1 "s_register_operand" "0,r")
8061 (match_operand:SF 2 "s_register_operand" "r,0")))]
8062 "TARGET_ARM && TARGET_SOFT_FLOAT"
8063 "@
8064 mov%D3\\t%0, %2
8065 mov%d3\\t%0, %1"
8066 [(set_attr "conds" "use")
8067 (set_attr "type" "mov_reg")]
8068 )
8069
8070 \f
8071 ;; Jump and linkage insns
8072
8073 (define_expand "jump"
8074 [(set (pc)
8075 (label_ref (match_operand 0 "" "")))]
8076 "TARGET_EITHER"
8077 ""
8078 )
8079
8080 (define_insn "*arm_jump"
8081 [(set (pc)
8082 (label_ref (match_operand 0 "" "")))]
8083 "TARGET_32BIT"
8084 "*
8085 {
8086 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8087 {
8088 arm_ccfsm_state += 2;
8089 return \"\";
8090 }
8091 return \"b%?\\t%l0\";
8092 }
8093 "
8094 [(set_attr "predicable" "yes")
8095 (set (attr "length")
8096 (if_then_else
8097 (and (match_test "TARGET_THUMB2")
8098 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8099 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8100 (const_int 2)
8101 (const_int 4)))
8102 (set_attr "type" "branch")]
8103 )
8104
8105 (define_expand "call"
8106 [(parallel [(call (match_operand 0 "memory_operand" "")
8107 (match_operand 1 "general_operand" ""))
8108 (use (match_operand 2 "" ""))
8109 (clobber (reg:SI LR_REGNUM))])]
8110 "TARGET_EITHER"
8111 "
8112 {
8113 rtx callee, pat;
8114 tree addr = MEM_EXPR (operands[0]);
8115
8116 /* In an untyped call, we can get NULL for operand 2. */
8117 if (operands[2] == NULL_RTX)
8118 operands[2] = const0_rtx;
8119
8120 /* Decide if we should generate indirect calls by loading the
8121 32-bit address of the callee into a register before performing the
8122 branch and link. */
8123 callee = XEXP (operands[0], 0);
8124 if (GET_CODE (callee) == SYMBOL_REF
8125 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8126 : !REG_P (callee))
8127 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8128
8129 if (detect_cmse_nonsecure_call (addr))
8130 {
8131 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8132 operands[2]);
8133 emit_call_insn (pat);
8134 }
8135 else
8136 {
8137 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8138 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8139 }
8140 DONE;
8141 }"
8142 )
8143
8144 (define_expand "call_internal"
8145 [(parallel [(call (match_operand 0 "memory_operand" "")
8146 (match_operand 1 "general_operand" ""))
8147 (use (match_operand 2 "" ""))
8148 (clobber (reg:SI LR_REGNUM))])])
8149
8150 (define_expand "nonsecure_call_internal"
8151 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8152 UNSPEC_NONSECURE_MEM)
8153 (match_operand 1 "general_operand" ""))
8154 (use (match_operand 2 "" ""))
8155 (clobber (reg:SI LR_REGNUM))])]
8156 "use_cmse"
8157 "
8158 {
8159 rtx tmp;
8160 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8161 gen_rtx_REG (SImode, R4_REGNUM),
8162 SImode);
8163
8164 operands[0] = replace_equiv_address (operands[0], tmp);
8165 }")
8166
8167 (define_insn "*call_reg_armv5"
8168 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8169 (match_operand 1 "" ""))
8170 (use (match_operand 2 "" ""))
8171 (clobber (reg:SI LR_REGNUM))]
8172 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8173 "blx%?\\t%0"
8174 [(set_attr "type" "call")]
8175 )
8176
8177 (define_insn "*call_reg_arm"
8178 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8179 (match_operand 1 "" ""))
8180 (use (match_operand 2 "" ""))
8181 (clobber (reg:SI LR_REGNUM))]
8182 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8183 "*
8184 return output_call (operands);
8185 "
8186 ;; length is worst case, normally it is only two
8187 [(set_attr "length" "12")
8188 (set_attr "type" "call")]
8189 )
8190
8191
8192 (define_expand "call_value"
8193 [(parallel [(set (match_operand 0 "" "")
8194 (call (match_operand 1 "memory_operand" "")
8195 (match_operand 2 "general_operand" "")))
8196 (use (match_operand 3 "" ""))
8197 (clobber (reg:SI LR_REGNUM))])]
8198 "TARGET_EITHER"
8199 "
8200 {
8201 rtx pat, callee;
8202 tree addr = MEM_EXPR (operands[1]);
8203
8204 /* In an untyped call, we can get NULL for operand 2. */
8205 if (operands[3] == 0)
8206 operands[3] = const0_rtx;
8207
8208 /* Decide if we should generate indirect calls by loading the
8209 32-bit address of the callee into a register before performing the
8210 branch and link. */
8211 callee = XEXP (operands[1], 0);
8212 if (GET_CODE (callee) == SYMBOL_REF
8213 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8214 : !REG_P (callee))
8215 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8216
8217 if (detect_cmse_nonsecure_call (addr))
8218 {
8219 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8220 operands[2], operands[3]);
8221 emit_call_insn (pat);
8222 }
8223 else
8224 {
8225 pat = gen_call_value_internal (operands[0], operands[1],
8226 operands[2], operands[3]);
8227 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8228 }
8229 DONE;
8230 }"
8231 )
8232
8233 (define_expand "call_value_internal"
8234 [(parallel [(set (match_operand 0 "" "")
8235 (call (match_operand 1 "memory_operand" "")
8236 (match_operand 2 "general_operand" "")))
8237 (use (match_operand 3 "" ""))
8238 (clobber (reg:SI LR_REGNUM))])])
8239
8240 (define_expand "nonsecure_call_value_internal"
8241 [(parallel [(set (match_operand 0 "" "")
8242 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8243 UNSPEC_NONSECURE_MEM)
8244 (match_operand 2 "general_operand" "")))
8245 (use (match_operand 3 "" ""))
8246 (clobber (reg:SI LR_REGNUM))])]
8247 "use_cmse"
8248 "
8249 {
8250 rtx tmp;
8251 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8252 gen_rtx_REG (SImode, R4_REGNUM),
8253 SImode);
8254
8255 operands[1] = replace_equiv_address (operands[1], tmp);
8256 }")
8257
8258 (define_insn "*call_value_reg_armv5"
8259 [(set (match_operand 0 "" "")
8260 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8261 (match_operand 2 "" "")))
8262 (use (match_operand 3 "" ""))
8263 (clobber (reg:SI LR_REGNUM))]
8264 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8265 "blx%?\\t%1"
8266 [(set_attr "type" "call")]
8267 )
8268
8269 (define_insn "*call_value_reg_arm"
8270 [(set (match_operand 0 "" "")
8271 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8272 (match_operand 2 "" "")))
8273 (use (match_operand 3 "" ""))
8274 (clobber (reg:SI LR_REGNUM))]
8275 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8276 "*
8277 return output_call (&operands[1]);
8278 "
8279 [(set_attr "length" "12")
8280 (set_attr "type" "call")]
8281 )
8282
8283 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8284 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8285
8286 (define_insn "*call_symbol"
8287 [(call (mem:SI (match_operand:SI 0 "" ""))
8288 (match_operand 1 "" ""))
8289 (use (match_operand 2 "" ""))
8290 (clobber (reg:SI LR_REGNUM))]
8291 "TARGET_32BIT
8292 && !SIBLING_CALL_P (insn)
8293 && (GET_CODE (operands[0]) == SYMBOL_REF)
8294 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8295 "*
8296 {
8297 rtx op = operands[0];
8298
8299 /* Switch mode now when possible. */
8300 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8301 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8302 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8303
8304 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8305 }"
8306 [(set_attr "type" "call")]
8307 )
8308
8309 (define_insn "*call_value_symbol"
8310 [(set (match_operand 0 "" "")
8311 (call (mem:SI (match_operand:SI 1 "" ""))
8312 (match_operand:SI 2 "" "")))
8313 (use (match_operand 3 "" ""))
8314 (clobber (reg:SI LR_REGNUM))]
8315 "TARGET_32BIT
8316 && !SIBLING_CALL_P (insn)
8317 && (GET_CODE (operands[1]) == SYMBOL_REF)
8318 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8319 "*
8320 {
8321 rtx op = operands[1];
8322
8323 /* Switch mode now when possible. */
8324 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8325 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8326 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8327
8328 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8329 }"
8330 [(set_attr "type" "call")]
8331 )
8332
8333 (define_expand "sibcall_internal"
8334 [(parallel [(call (match_operand 0 "memory_operand" "")
8335 (match_operand 1 "general_operand" ""))
8336 (return)
8337 (use (match_operand 2 "" ""))])])
8338
8339 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8340 (define_expand "sibcall"
8341 [(parallel [(call (match_operand 0 "memory_operand" "")
8342 (match_operand 1 "general_operand" ""))
8343 (return)
8344 (use (match_operand 2 "" ""))])]
8345 "TARGET_32BIT"
8346 "
8347 {
8348 rtx pat;
8349
8350 if ((!REG_P (XEXP (operands[0], 0))
8351 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8352 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8353 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8354 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8355
8356 if (operands[2] == NULL_RTX)
8357 operands[2] = const0_rtx;
8358
8359 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8360 arm_emit_call_insn (pat, operands[0], true);
8361 DONE;
8362 }"
8363 )
8364
8365 (define_expand "sibcall_value_internal"
8366 [(parallel [(set (match_operand 0 "" "")
8367 (call (match_operand 1 "memory_operand" "")
8368 (match_operand 2 "general_operand" "")))
8369 (return)
8370 (use (match_operand 3 "" ""))])])
8371
8372 (define_expand "sibcall_value"
8373 [(parallel [(set (match_operand 0 "" "")
8374 (call (match_operand 1 "memory_operand" "")
8375 (match_operand 2 "general_operand" "")))
8376 (return)
8377 (use (match_operand 3 "" ""))])]
8378 "TARGET_32BIT"
8379 "
8380 {
8381 rtx pat;
8382
8383 if ((!REG_P (XEXP (operands[1], 0))
8384 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8385 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8386 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8387 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8388
8389 if (operands[3] == NULL_RTX)
8390 operands[3] = const0_rtx;
8391
8392 pat = gen_sibcall_value_internal (operands[0], operands[1],
8393 operands[2], operands[3]);
8394 arm_emit_call_insn (pat, operands[1], true);
8395 DONE;
8396 }"
8397 )
8398
8399 (define_insn "*sibcall_insn"
8400 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8401 (match_operand 1 "" ""))
8402 (return)
8403 (use (match_operand 2 "" ""))]
8404 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8405 "*
8406 if (which_alternative == 1)
8407 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8408 else
8409 {
8410 if (arm_arch5t || arm_arch4t)
8411 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8412 else
8413 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8414 }
8415 "
8416 [(set_attr "type" "call")]
8417 )
8418
8419 (define_insn "*sibcall_value_insn"
8420 [(set (match_operand 0 "" "")
8421 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8422 (match_operand 2 "" "")))
8423 (return)
8424 (use (match_operand 3 "" ""))]
8425 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8426 "*
8427 if (which_alternative == 1)
8428 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8429 else
8430 {
8431 if (arm_arch5t || arm_arch4t)
8432 return \"bx%?\\t%1\";
8433 else
8434 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8435 }
8436 "
8437 [(set_attr "type" "call")]
8438 )
8439
8440 (define_expand "<return_str>return"
8441 [(RETURNS)]
8442 "(TARGET_ARM || (TARGET_THUMB2
8443 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8444 && !IS_STACKALIGN (arm_current_func_type ())))
8445 <return_cond_false>"
8446 "
8447 {
8448 if (TARGET_THUMB2)
8449 {
8450 thumb2_expand_return (<return_simple_p>);
8451 DONE;
8452 }
8453 }
8454 "
8455 )
8456
8457 ;; Often the return insn will be the same as loading from memory, so set attr
8458 (define_insn "*arm_return"
8459 [(return)]
8460 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8461 "*
8462 {
8463 if (arm_ccfsm_state == 2)
8464 {
8465 arm_ccfsm_state += 2;
8466 return \"\";
8467 }
8468 return output_return_instruction (const_true_rtx, true, false, false);
8469 }"
8470 [(set_attr "type" "load_4")
8471 (set_attr "length" "12")
8472 (set_attr "predicable" "yes")]
8473 )
8474
8475 (define_insn "*cond_<return_str>return"
8476 [(set (pc)
8477 (if_then_else (match_operator 0 "arm_comparison_operator"
8478 [(match_operand 1 "cc_register" "") (const_int 0)])
8479 (RETURNS)
8480 (pc)))]
8481 "TARGET_ARM <return_cond_true>"
8482 "*
8483 {
8484 if (arm_ccfsm_state == 2)
8485 {
8486 arm_ccfsm_state += 2;
8487 return \"\";
8488 }
8489 return output_return_instruction (operands[0], true, false,
8490 <return_simple_p>);
8491 }"
8492 [(set_attr "conds" "use")
8493 (set_attr "length" "12")
8494 (set_attr "type" "load_4")]
8495 )
8496
8497 (define_insn "*cond_<return_str>return_inverted"
8498 [(set (pc)
8499 (if_then_else (match_operator 0 "arm_comparison_operator"
8500 [(match_operand 1 "cc_register" "") (const_int 0)])
8501 (pc)
8502 (RETURNS)))]
8503 "TARGET_ARM <return_cond_true>"
8504 "*
8505 {
8506 if (arm_ccfsm_state == 2)
8507 {
8508 arm_ccfsm_state += 2;
8509 return \"\";
8510 }
8511 return output_return_instruction (operands[0], true, true,
8512 <return_simple_p>);
8513 }"
8514 [(set_attr "conds" "use")
8515 (set_attr "length" "12")
8516 (set_attr "type" "load_4")]
8517 )
8518
8519 (define_insn "*arm_simple_return"
8520 [(simple_return)]
8521 "TARGET_ARM"
8522 "*
8523 {
8524 if (arm_ccfsm_state == 2)
8525 {
8526 arm_ccfsm_state += 2;
8527 return \"\";
8528 }
8529 return output_return_instruction (const_true_rtx, true, false, true);
8530 }"
8531 [(set_attr "type" "branch")
8532 (set_attr "length" "4")
8533 (set_attr "predicable" "yes")]
8534 )
8535
8536 ;; Generate a sequence of instructions to determine if the processor is
8537 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8538 ;; mask.
8539
8540 (define_expand "return_addr_mask"
8541 [(set (match_dup 1)
8542 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8543 (const_int 0)))
8544 (set (match_operand:SI 0 "s_register_operand" "")
8545 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8546 (const_int -1)
8547 (const_int 67108860)))] ; 0x03fffffc
8548 "TARGET_ARM"
8549 "
8550 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8551 ")
8552
8553 (define_insn "*check_arch2"
8554 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8555 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8556 (const_int 0)))]
8557 "TARGET_ARM"
8558 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8559 [(set_attr "length" "8")
8560 (set_attr "conds" "set")
8561 (set_attr "type" "multiple")]
8562 )
8563
8564 ;; Call subroutine returning any type.
8565
8566 (define_expand "untyped_call"
8567 [(parallel [(call (match_operand 0 "" "")
8568 (const_int 0))
8569 (match_operand 1 "" "")
8570 (match_operand 2 "" "")])]
8571 "TARGET_EITHER"
8572 "
8573 {
8574 int i;
8575 rtx par = gen_rtx_PARALLEL (VOIDmode,
8576 rtvec_alloc (XVECLEN (operands[2], 0)));
8577 rtx addr = gen_reg_rtx (Pmode);
8578 rtx mem;
8579 int size = 0;
8580
8581 emit_move_insn (addr, XEXP (operands[1], 0));
8582 mem = change_address (operands[1], BLKmode, addr);
8583
8584 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8585 {
8586 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8587
8588 /* Default code only uses r0 as a return value, but we could
8589 be using anything up to 4 registers. */
8590 if (REGNO (src) == R0_REGNUM)
8591 src = gen_rtx_REG (TImode, R0_REGNUM);
8592
8593 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8594 GEN_INT (size));
8595 size += GET_MODE_SIZE (GET_MODE (src));
8596 }
8597
8598 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8599
8600 size = 0;
8601
8602 for (i = 0; i < XVECLEN (par, 0); i++)
8603 {
8604 HOST_WIDE_INT offset = 0;
8605 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8606
8607 if (size != 0)
8608 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8609
8610 mem = change_address (mem, GET_MODE (reg), NULL);
8611 if (REGNO (reg) == R0_REGNUM)
8612 {
8613 /* On thumb we have to use a write-back instruction. */
8614 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8615 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8616 size = TARGET_ARM ? 16 : 0;
8617 }
8618 else
8619 {
8620 emit_move_insn (mem, reg);
8621 size = GET_MODE_SIZE (GET_MODE (reg));
8622 }
8623 }
8624
8625 /* The optimizer does not know that the call sets the function value
8626 registers we stored in the result block. We avoid problems by
8627 claiming that all hard registers are used and clobbered at this
8628 point. */
8629 emit_insn (gen_blockage ());
8630
8631 DONE;
8632 }"
8633 )
8634
8635 (define_expand "untyped_return"
8636 [(match_operand:BLK 0 "memory_operand" "")
8637 (match_operand 1 "" "")]
8638 "TARGET_EITHER"
8639 "
8640 {
8641 int i;
8642 rtx addr = gen_reg_rtx (Pmode);
8643 rtx mem;
8644 int size = 0;
8645
8646 emit_move_insn (addr, XEXP (operands[0], 0));
8647 mem = change_address (operands[0], BLKmode, addr);
8648
8649 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8650 {
8651 HOST_WIDE_INT offset = 0;
8652 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8653
8654 if (size != 0)
8655 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8656
8657 mem = change_address (mem, GET_MODE (reg), NULL);
8658 if (REGNO (reg) == R0_REGNUM)
8659 {
8660 /* On thumb we have to use a write-back instruction. */
8661 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8662 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8663 size = TARGET_ARM ? 16 : 0;
8664 }
8665 else
8666 {
8667 emit_move_insn (reg, mem);
8668 size = GET_MODE_SIZE (GET_MODE (reg));
8669 }
8670 }
8671
8672 /* Emit USE insns before the return. */
8673 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8674 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8675
8676 /* Construct the return. */
8677 expand_naked_return ();
8678
8679 DONE;
8680 }"
8681 )
8682
8683 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8684 ;; all of memory. This blocks insns from being moved across this point.
8685
8686 (define_insn "blockage"
8687 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8688 "TARGET_EITHER"
8689 ""
8690 [(set_attr "length" "0")
8691 (set_attr "type" "block")]
8692 )
8693
8694 ;; Since we hard code r0 here use the 'o' constraint to prevent
8695 ;; provoking undefined behaviour in the hardware with putting out
8696 ;; auto-increment operations with potentially r0 as the base register.
8697 (define_insn "probe_stack"
8698 [(set (match_operand:SI 0 "memory_operand" "=o")
8699 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8700 "TARGET_32BIT"
8701 "str%?\\tr0, %0"
8702 [(set_attr "type" "store_4")
8703 (set_attr "predicable" "yes")]
8704 )
8705
8706 (define_insn "probe_stack_range"
8707 [(set (match_operand:SI 0 "register_operand" "=r")
8708 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8709 (match_operand:SI 2 "register_operand" "r")]
8710 VUNSPEC_PROBE_STACK_RANGE))]
8711 "TARGET_32BIT"
8712 {
8713 return output_probe_stack_range (operands[0], operands[2]);
8714 }
8715 [(set_attr "type" "multiple")
8716 (set_attr "conds" "clob")]
8717 )
8718
8719 ;; Named patterns for stack smashing protection.
8720 (define_expand "stack_protect_combined_set"
8721 [(parallel
8722 [(set (match_operand:SI 0 "memory_operand" "")
8723 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8724 UNSPEC_SP_SET))
8725 (clobber (match_scratch:SI 2 ""))
8726 (clobber (match_scratch:SI 3 ""))])]
8727 ""
8728 ""
8729 )
8730
8731 ;; Use a separate insn from the above expand to be able to have the mem outside
8732 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8733 ;; try to reload the guard since we need to control how PIC access is done in
8734 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8735 ;; legitimize_pic_address ()).
8736 (define_insn_and_split "*stack_protect_combined_set_insn"
8737 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8738 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8739 UNSPEC_SP_SET))
8740 (clobber (match_scratch:SI 2 "=&l,&r"))
8741 (clobber (match_scratch:SI 3 "=&l,&r"))]
8742 ""
8743 "#"
8744 "reload_completed"
8745 [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))]
8746 UNSPEC_SP_SET))
8747 (clobber (match_dup 2))])]
8748 "
8749 {
8750 if (flag_pic)
8751 {
8752 /* Forces recomputing of GOT base now. */
8753 legitimize_pic_address (operands[1], SImode, operands[2], operands[3],
8754 true /*compute_now*/);
8755 }
8756 else
8757 {
8758 if (address_operand (operands[1], SImode))
8759 operands[2] = operands[1];
8760 else
8761 {
8762 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8763 emit_move_insn (operands[2], mem);
8764 }
8765 }
8766 }"
8767 [(set_attr "arch" "t1,32")]
8768 )
8769
8770 (define_insn "*stack_protect_set_insn"
8771 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8772 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))]
8773 UNSPEC_SP_SET))
8774 (clobber (match_dup 1))]
8775 ""
8776 "@
8777 ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1,#0
8778 ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1,#0"
8779 [(set_attr "length" "8,12")
8780 (set_attr "conds" "clob,nocond")
8781 (set_attr "type" "multiple")
8782 (set_attr "arch" "t1,32")]
8783 )
8784
8785 (define_expand "stack_protect_combined_test"
8786 [(parallel
8787 [(set (pc)
8788 (if_then_else
8789 (eq (match_operand:SI 0 "memory_operand" "")
8790 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8791 UNSPEC_SP_TEST))
8792 (label_ref (match_operand 2))
8793 (pc)))
8794 (clobber (match_scratch:SI 3 ""))
8795 (clobber (match_scratch:SI 4 ""))
8796 (clobber (reg:CC CC_REGNUM))])]
8797 ""
8798 ""
8799 )
8800
8801 ;; Use a separate insn from the above expand to be able to have the mem outside
8802 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8803 ;; try to reload the guard since we need to control how PIC access is done in
8804 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8805 ;; legitimize_pic_address ()).
8806 (define_insn_and_split "*stack_protect_combined_test_insn"
8807 [(set (pc)
8808 (if_then_else
8809 (eq (match_operand:SI 0 "memory_operand" "m,m")
8810 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8811 UNSPEC_SP_TEST))
8812 (label_ref (match_operand 2))
8813 (pc)))
8814 (clobber (match_scratch:SI 3 "=&l,&r"))
8815 (clobber (match_scratch:SI 4 "=&l,&r"))
8816 (clobber (reg:CC CC_REGNUM))]
8817 ""
8818 "#"
8819 "reload_completed"
8820 [(const_int 0)]
8821 {
8822 rtx eq;
8823
8824 if (flag_pic)
8825 {
8826 /* Forces recomputing of GOT base now. */
8827 legitimize_pic_address (operands[1], SImode, operands[3], operands[4],
8828 true /*compute_now*/);
8829 }
8830 else
8831 {
8832 if (address_operand (operands[1], SImode))
8833 operands[3] = operands[1];
8834 else
8835 {
8836 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8837 emit_move_insn (operands[3], mem);
8838 }
8839 }
8840 if (TARGET_32BIT)
8841 {
8842 emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0],
8843 operands[3]));
8844 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
8845 eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx);
8846 emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg));
8847 }
8848 else
8849 {
8850 emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0],
8851 operands[3]));
8852 eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
8853 emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx,
8854 operands[2]));
8855 }
8856 DONE;
8857 }
8858 [(set_attr "arch" "t1,32")]
8859 )
8860
8861 (define_insn "arm_stack_protect_test_insn"
8862 [(set (reg:CC_Z CC_REGNUM)
8863 (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m")
8864 (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))]
8865 UNSPEC_SP_TEST)
8866 (const_int 0)))
8867 (clobber (match_operand:SI 0 "register_operand" "=&l,&r"))
8868 (clobber (match_dup 2))]
8869 "TARGET_32BIT"
8870 "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0"
8871 [(set_attr "length" "8,12")
8872 (set_attr "conds" "set")
8873 (set_attr "type" "multiple")
8874 (set_attr "arch" "t,32")]
8875 )
8876
8877 (define_expand "casesi"
8878 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8879 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8880 (match_operand:SI 2 "const_int_operand" "") ; total range
8881 (match_operand:SI 3 "" "") ; table label
8882 (match_operand:SI 4 "" "")] ; Out of range label
8883 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8884 "
8885 {
8886 enum insn_code code;
8887 if (operands[1] != const0_rtx)
8888 {
8889 rtx reg = gen_reg_rtx (SImode);
8890
8891 emit_insn (gen_addsi3 (reg, operands[0],
8892 gen_int_mode (-INTVAL (operands[1]),
8893 SImode)));
8894 operands[0] = reg;
8895 }
8896
8897 if (TARGET_ARM)
8898 code = CODE_FOR_arm_casesi_internal;
8899 else if (TARGET_THUMB1)
8900 code = CODE_FOR_thumb1_casesi_internal_pic;
8901 else if (flag_pic)
8902 code = CODE_FOR_thumb2_casesi_internal_pic;
8903 else
8904 code = CODE_FOR_thumb2_casesi_internal;
8905
8906 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8907 operands[2] = force_reg (SImode, operands[2]);
8908
8909 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8910 operands[3], operands[4]));
8911 DONE;
8912 }"
8913 )
8914
8915 ;; The USE in this pattern is needed to tell flow analysis that this is
8916 ;; a CASESI insn. It has no other purpose.
8917 (define_insn "arm_casesi_internal"
8918 [(parallel [(set (pc)
8919 (if_then_else
8920 (leu (match_operand:SI 0 "s_register_operand" "r")
8921 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8922 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8923 (label_ref (match_operand 2 "" ""))))
8924 (label_ref (match_operand 3 "" ""))))
8925 (clobber (reg:CC CC_REGNUM))
8926 (use (label_ref (match_dup 2)))])]
8927 "TARGET_ARM"
8928 "*
8929 if (flag_pic)
8930 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8931 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8932 "
8933 [(set_attr "conds" "clob")
8934 (set_attr "length" "12")
8935 (set_attr "type" "multiple")]
8936 )
8937
8938 (define_expand "indirect_jump"
8939 [(set (pc)
8940 (match_operand:SI 0 "s_register_operand" ""))]
8941 "TARGET_EITHER"
8942 "
8943 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8944 address and use bx. */
8945 if (TARGET_THUMB2)
8946 {
8947 rtx tmp;
8948 tmp = gen_reg_rtx (SImode);
8949 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8950 operands[0] = tmp;
8951 }
8952 "
8953 )
8954
8955 ;; NB Never uses BX.
8956 (define_insn "*arm_indirect_jump"
8957 [(set (pc)
8958 (match_operand:SI 0 "s_register_operand" "r"))]
8959 "TARGET_ARM"
8960 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8961 [(set_attr "predicable" "yes")
8962 (set_attr "type" "branch")]
8963 )
8964
8965 (define_insn "*load_indirect_jump"
8966 [(set (pc)
8967 (match_operand:SI 0 "memory_operand" "m"))]
8968 "TARGET_ARM"
8969 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8970 [(set_attr "type" "load_4")
8971 (set_attr "pool_range" "4096")
8972 (set_attr "neg_pool_range" "4084")
8973 (set_attr "predicable" "yes")]
8974 )
8975
8976 \f
8977 ;; Misc insns
8978
8979 (define_insn "nop"
8980 [(const_int 0)]
8981 "TARGET_EITHER"
8982 "nop"
8983 [(set (attr "length")
8984 (if_then_else (eq_attr "is_thumb" "yes")
8985 (const_int 2)
8986 (const_int 4)))
8987 (set_attr "type" "mov_reg")]
8988 )
8989
8990 (define_insn "trap"
8991 [(trap_if (const_int 1) (const_int 0))]
8992 ""
8993 "*
8994 if (TARGET_ARM)
8995 return \".inst\\t0xe7f000f0\";
8996 else
8997 return \".inst\\t0xdeff\";
8998 "
8999 [(set (attr "length")
9000 (if_then_else (eq_attr "is_thumb" "yes")
9001 (const_int 2)
9002 (const_int 4)))
9003 (set_attr "type" "trap")
9004 (set_attr "conds" "unconditional")]
9005 )
9006
9007 \f
9008 ;; Patterns to allow combination of arithmetic, cond code and shifts
9009
9010 (define_insn "*<arith_shift_insn>_multsi"
9011 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9012 (SHIFTABLE_OPS:SI
9013 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
9014 (match_operand:SI 3 "power_of_two_operand" ""))
9015 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
9016 "TARGET_32BIT"
9017 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
9018 [(set_attr "predicable" "yes")
9019 (set_attr "shift" "2")
9020 (set_attr "arch" "a,t2")
9021 (set_attr "type" "alu_shift_imm")])
9022
9023 (define_insn "*<arith_shift_insn>_shiftsi"
9024 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9025 (SHIFTABLE_OPS:SI
9026 (match_operator:SI 2 "shift_nomul_operator"
9027 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9028 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
9029 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
9030 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
9031 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
9032 [(set_attr "predicable" "yes")
9033 (set_attr "shift" "3")
9034 (set_attr "arch" "a,t2,a")
9035 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9036
9037 (define_split
9038 [(set (match_operand:SI 0 "s_register_operand" "")
9039 (match_operator:SI 1 "shiftable_operator"
9040 [(match_operator:SI 2 "shiftable_operator"
9041 [(match_operator:SI 3 "shift_operator"
9042 [(match_operand:SI 4 "s_register_operand" "")
9043 (match_operand:SI 5 "reg_or_int_operand" "")])
9044 (match_operand:SI 6 "s_register_operand" "")])
9045 (match_operand:SI 7 "arm_rhs_operand" "")]))
9046 (clobber (match_operand:SI 8 "s_register_operand" ""))]
9047 "TARGET_32BIT"
9048 [(set (match_dup 8)
9049 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9050 (match_dup 6)]))
9051 (set (match_dup 0)
9052 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
9053 "")
9054
9055 (define_insn "*arith_shiftsi_compare0"
9056 [(set (reg:CC_NOOV CC_REGNUM)
9057 (compare:CC_NOOV
9058 (match_operator:SI 1 "shiftable_operator"
9059 [(match_operator:SI 3 "shift_operator"
9060 [(match_operand:SI 4 "s_register_operand" "r,r")
9061 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9062 (match_operand:SI 2 "s_register_operand" "r,r")])
9063 (const_int 0)))
9064 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9065 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9066 (match_dup 2)]))]
9067 "TARGET_32BIT"
9068 "%i1s%?\\t%0, %2, %4%S3"
9069 [(set_attr "conds" "set")
9070 (set_attr "shift" "4")
9071 (set_attr "arch" "32,a")
9072 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9073
9074 (define_insn "*arith_shiftsi_compare0_scratch"
9075 [(set (reg:CC_NOOV CC_REGNUM)
9076 (compare:CC_NOOV
9077 (match_operator:SI 1 "shiftable_operator"
9078 [(match_operator:SI 3 "shift_operator"
9079 [(match_operand:SI 4 "s_register_operand" "r,r")
9080 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9081 (match_operand:SI 2 "s_register_operand" "r,r")])
9082 (const_int 0)))
9083 (clobber (match_scratch:SI 0 "=r,r"))]
9084 "TARGET_32BIT"
9085 "%i1s%?\\t%0, %2, %4%S3"
9086 [(set_attr "conds" "set")
9087 (set_attr "shift" "4")
9088 (set_attr "arch" "32,a")
9089 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9090
9091 (define_insn "*sub_shiftsi"
9092 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9093 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9094 (match_operator:SI 2 "shift_operator"
9095 [(match_operand:SI 3 "s_register_operand" "r,r")
9096 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
9097 "TARGET_32BIT"
9098 "sub%?\\t%0, %1, %3%S2"
9099 [(set_attr "predicable" "yes")
9100 (set_attr "predicable_short_it" "no")
9101 (set_attr "shift" "3")
9102 (set_attr "arch" "32,a")
9103 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9104
9105 (define_insn "*sub_shiftsi_compare0"
9106 [(set (reg:CC_NOOV CC_REGNUM)
9107 (compare:CC_NOOV
9108 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9109 (match_operator:SI 2 "shift_operator"
9110 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9111 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9112 (const_int 0)))
9113 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9114 (minus:SI (match_dup 1)
9115 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
9116 "TARGET_32BIT"
9117 "subs%?\\t%0, %1, %3%S2"
9118 [(set_attr "conds" "set")
9119 (set_attr "shift" "3")
9120 (set_attr "arch" "32,a,a")
9121 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9122
9123 (define_insn "*sub_shiftsi_compare0_scratch"
9124 [(set (reg:CC_NOOV CC_REGNUM)
9125 (compare:CC_NOOV
9126 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9127 (match_operator:SI 2 "shift_operator"
9128 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9129 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9130 (const_int 0)))
9131 (clobber (match_scratch:SI 0 "=r,r,r"))]
9132 "TARGET_32BIT"
9133 "subs%?\\t%0, %1, %3%S2"
9134 [(set_attr "conds" "set")
9135 (set_attr "shift" "3")
9136 (set_attr "arch" "32,a,a")
9137 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9138 \f
9139
9140 (define_insn_and_split "*and_scc"
9141 [(set (match_operand:SI 0 "s_register_operand" "=r")
9142 (and:SI (match_operator:SI 1 "arm_comparison_operator"
9143 [(match_operand 2 "cc_register" "") (const_int 0)])
9144 (match_operand:SI 3 "s_register_operand" "r")))]
9145 "TARGET_ARM"
9146 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
9147 "&& reload_completed"
9148 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
9149 (cond_exec (match_dup 4) (set (match_dup 0)
9150 (and:SI (match_dup 3) (const_int 1))))]
9151 {
9152 machine_mode mode = GET_MODE (operands[2]);
9153 enum rtx_code rc = GET_CODE (operands[1]);
9154
9155 /* Note that operands[4] is the same as operands[1],
9156 but with VOIDmode as the result. */
9157 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9158 if (mode == CCFPmode || mode == CCFPEmode)
9159 rc = reverse_condition_maybe_unordered (rc);
9160 else
9161 rc = reverse_condition (rc);
9162 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9163 }
9164 [(set_attr "conds" "use")
9165 (set_attr "type" "multiple")
9166 (set_attr "length" "8")]
9167 )
9168
9169 (define_insn_and_split "*ior_scc"
9170 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9171 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
9172 [(match_operand 2 "cc_register" "") (const_int 0)])
9173 (match_operand:SI 3 "s_register_operand" "0,?r")))]
9174 "TARGET_ARM"
9175 "@
9176 orr%d1\\t%0, %3, #1
9177 #"
9178 "&& reload_completed
9179 && REGNO (operands [0]) != REGNO (operands[3])"
9180 ;; && which_alternative == 1
9181 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
9182 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
9183 (cond_exec (match_dup 4) (set (match_dup 0)
9184 (ior:SI (match_dup 3) (const_int 1))))]
9185 {
9186 machine_mode mode = GET_MODE (operands[2]);
9187 enum rtx_code rc = GET_CODE (operands[1]);
9188
9189 /* Note that operands[4] is the same as operands[1],
9190 but with VOIDmode as the result. */
9191 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9192 if (mode == CCFPmode || mode == CCFPEmode)
9193 rc = reverse_condition_maybe_unordered (rc);
9194 else
9195 rc = reverse_condition (rc);
9196 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9197 }
9198 [(set_attr "conds" "use")
9199 (set_attr "length" "4,8")
9200 (set_attr "type" "logic_imm,multiple")]
9201 )
9202
9203 ; A series of splitters for the compare_scc pattern below. Note that
9204 ; order is important.
9205 (define_split
9206 [(set (match_operand:SI 0 "s_register_operand" "")
9207 (lt:SI (match_operand:SI 1 "s_register_operand" "")
9208 (const_int 0)))
9209 (clobber (reg:CC CC_REGNUM))]
9210 "TARGET_32BIT && reload_completed"
9211 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9212
9213 (define_split
9214 [(set (match_operand:SI 0 "s_register_operand" "")
9215 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9216 (const_int 0)))
9217 (clobber (reg:CC CC_REGNUM))]
9218 "TARGET_32BIT && reload_completed"
9219 [(set (match_dup 0) (not:SI (match_dup 1)))
9220 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9221
9222 (define_split
9223 [(set (match_operand:SI 0 "s_register_operand" "")
9224 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9225 (const_int 0)))
9226 (clobber (reg:CC CC_REGNUM))]
9227 "arm_arch5t && TARGET_32BIT"
9228 [(set (match_dup 0) (clz:SI (match_dup 1)))
9229 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9230 )
9231
9232 (define_split
9233 [(set (match_operand:SI 0 "s_register_operand" "")
9234 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9235 (const_int 0)))
9236 (clobber (reg:CC CC_REGNUM))]
9237 "TARGET_32BIT && reload_completed"
9238 [(parallel
9239 [(set (reg:CC CC_REGNUM)
9240 (compare:CC (const_int 1) (match_dup 1)))
9241 (set (match_dup 0)
9242 (minus:SI (const_int 1) (match_dup 1)))])
9243 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9244 (set (match_dup 0) (const_int 0)))])
9245
9246 (define_split
9247 [(set (match_operand:SI 0 "s_register_operand" "")
9248 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9249 (match_operand:SI 2 "const_int_operand" "")))
9250 (clobber (reg:CC CC_REGNUM))]
9251 "TARGET_32BIT && reload_completed"
9252 [(parallel
9253 [(set (reg:CC CC_REGNUM)
9254 (compare:CC (match_dup 1) (match_dup 2)))
9255 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9256 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9257 (set (match_dup 0) (const_int 1)))]
9258 {
9259 operands[3] = GEN_INT (-INTVAL (operands[2]));
9260 })
9261
9262 (define_split
9263 [(set (match_operand:SI 0 "s_register_operand" "")
9264 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9265 (match_operand:SI 2 "arm_add_operand" "")))
9266 (clobber (reg:CC CC_REGNUM))]
9267 "TARGET_32BIT && reload_completed"
9268 [(parallel
9269 [(set (reg:CC_NOOV CC_REGNUM)
9270 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9271 (const_int 0)))
9272 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9273 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9274 (set (match_dup 0) (const_int 1)))])
9275
9276 (define_insn_and_split "*compare_scc"
9277 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9278 (match_operator:SI 1 "arm_comparison_operator"
9279 [(match_operand:SI 2 "s_register_operand" "r,r")
9280 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9281 (clobber (reg:CC CC_REGNUM))]
9282 "TARGET_32BIT"
9283 "#"
9284 "&& reload_completed"
9285 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9286 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9287 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9288 {
9289 rtx tmp1;
9290 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9291 operands[2], operands[3]);
9292 enum rtx_code rc = GET_CODE (operands[1]);
9293
9294 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9295
9296 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9297 if (mode == CCFPmode || mode == CCFPEmode)
9298 rc = reverse_condition_maybe_unordered (rc);
9299 else
9300 rc = reverse_condition (rc);
9301 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9302 }
9303 [(set_attr "type" "multiple")]
9304 )
9305
9306 ;; Attempt to improve the sequence generated by the compare_scc splitters
9307 ;; not to use conditional execution.
9308
9309 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9310 ;; clz Rd, reg1
9311 ;; lsr Rd, Rd, #5
9312 (define_peephole2
9313 [(set (reg:CC CC_REGNUM)
9314 (compare:CC (match_operand:SI 1 "register_operand" "")
9315 (const_int 0)))
9316 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9317 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9318 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9319 (set (match_dup 0) (const_int 1)))]
9320 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9321 [(set (match_dup 0) (clz:SI (match_dup 1)))
9322 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9323 )
9324
9325 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9326 ;; negs Rd, reg1
9327 ;; adc Rd, Rd, reg1
9328 (define_peephole2
9329 [(set (reg:CC CC_REGNUM)
9330 (compare:CC (match_operand:SI 1 "register_operand" "")
9331 (const_int 0)))
9332 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9333 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9334 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9335 (set (match_dup 0) (const_int 1)))
9336 (match_scratch:SI 2 "r")]
9337 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9338 [(parallel
9339 [(set (reg:CC CC_REGNUM)
9340 (compare:CC (const_int 0) (match_dup 1)))
9341 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9342 (set (match_dup 0)
9343 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9344 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9345 )
9346
9347 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9348 ;; sub Rd, Reg1, reg2
9349 ;; clz Rd, Rd
9350 ;; lsr Rd, Rd, #5
9351 (define_peephole2
9352 [(set (reg:CC CC_REGNUM)
9353 (compare:CC (match_operand:SI 1 "register_operand" "")
9354 (match_operand:SI 2 "arm_rhs_operand" "")))
9355 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9356 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9357 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9358 (set (match_dup 0) (const_int 1)))]
9359 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9360 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9361 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9362 (set (match_dup 0) (clz:SI (match_dup 0)))
9363 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9364 )
9365
9366
9367 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9368 ;; sub T1, Reg1, reg2
9369 ;; negs Rd, T1
9370 ;; adc Rd, Rd, T1
9371 (define_peephole2
9372 [(set (reg:CC CC_REGNUM)
9373 (compare:CC (match_operand:SI 1 "register_operand" "")
9374 (match_operand:SI 2 "arm_rhs_operand" "")))
9375 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9376 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9377 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9378 (set (match_dup 0) (const_int 1)))
9379 (match_scratch:SI 3 "r")]
9380 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9381 [(set (match_dup 3) (match_dup 4))
9382 (parallel
9383 [(set (reg:CC CC_REGNUM)
9384 (compare:CC (const_int 0) (match_dup 3)))
9385 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9386 (set (match_dup 0)
9387 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9388 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9389 "
9390 if (CONST_INT_P (operands[2]))
9391 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9392 else
9393 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9394 ")
9395
9396 (define_insn "*cond_move"
9397 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9398 (if_then_else:SI (match_operator 3 "equality_operator"
9399 [(match_operator 4 "arm_comparison_operator"
9400 [(match_operand 5 "cc_register" "") (const_int 0)])
9401 (const_int 0)])
9402 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9403 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9404 "TARGET_ARM"
9405 "*
9406 if (GET_CODE (operands[3]) == NE)
9407 {
9408 if (which_alternative != 1)
9409 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9410 if (which_alternative != 0)
9411 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9412 return \"\";
9413 }
9414 if (which_alternative != 0)
9415 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9416 if (which_alternative != 1)
9417 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9418 return \"\";
9419 "
9420 [(set_attr "conds" "use")
9421 (set_attr_alternative "type"
9422 [(if_then_else (match_operand 2 "const_int_operand" "")
9423 (const_string "mov_imm")
9424 (const_string "mov_reg"))
9425 (if_then_else (match_operand 1 "const_int_operand" "")
9426 (const_string "mov_imm")
9427 (const_string "mov_reg"))
9428 (const_string "multiple")])
9429 (set_attr "length" "4,4,8")]
9430 )
9431
9432 (define_insn "*cond_arith"
9433 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9434 (match_operator:SI 5 "shiftable_operator"
9435 [(match_operator:SI 4 "arm_comparison_operator"
9436 [(match_operand:SI 2 "s_register_operand" "r,r")
9437 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9438 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9439 (clobber (reg:CC CC_REGNUM))]
9440 "TARGET_ARM"
9441 "*
9442 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9443 return \"%i5\\t%0, %1, %2, lsr #31\";
9444
9445 output_asm_insn (\"cmp\\t%2, %3\", operands);
9446 if (GET_CODE (operands[5]) == AND)
9447 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9448 else if (GET_CODE (operands[5]) == MINUS)
9449 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9450 else if (which_alternative != 0)
9451 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9452 return \"%i5%d4\\t%0, %1, #1\";
9453 "
9454 [(set_attr "conds" "clob")
9455 (set_attr "length" "12")
9456 (set_attr "type" "multiple")]
9457 )
9458
9459 (define_insn "*cond_sub"
9460 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9461 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9462 (match_operator:SI 4 "arm_comparison_operator"
9463 [(match_operand:SI 2 "s_register_operand" "r,r")
9464 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9465 (clobber (reg:CC CC_REGNUM))]
9466 "TARGET_ARM"
9467 "*
9468 output_asm_insn (\"cmp\\t%2, %3\", operands);
9469 if (which_alternative != 0)
9470 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9471 return \"sub%d4\\t%0, %1, #1\";
9472 "
9473 [(set_attr "conds" "clob")
9474 (set_attr "length" "8,12")
9475 (set_attr "type" "multiple")]
9476 )
9477
9478 (define_insn "*cmp_ite0"
9479 [(set (match_operand 6 "dominant_cc_register" "")
9480 (compare
9481 (if_then_else:SI
9482 (match_operator 4 "arm_comparison_operator"
9483 [(match_operand:SI 0 "s_register_operand"
9484 "l,l,l,r,r,r,r,r,r")
9485 (match_operand:SI 1 "arm_add_operand"
9486 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9487 (match_operator:SI 5 "arm_comparison_operator"
9488 [(match_operand:SI 2 "s_register_operand"
9489 "l,r,r,l,l,r,r,r,r")
9490 (match_operand:SI 3 "arm_add_operand"
9491 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9492 (const_int 0))
9493 (const_int 0)))]
9494 "TARGET_32BIT"
9495 "*
9496 {
9497 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9498 {
9499 {\"cmp%d5\\t%0, %1\",
9500 \"cmp%d4\\t%2, %3\"},
9501 {\"cmn%d5\\t%0, #%n1\",
9502 \"cmp%d4\\t%2, %3\"},
9503 {\"cmp%d5\\t%0, %1\",
9504 \"cmn%d4\\t%2, #%n3\"},
9505 {\"cmn%d5\\t%0, #%n1\",
9506 \"cmn%d4\\t%2, #%n3\"}
9507 };
9508 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9509 {
9510 {\"cmp\\t%2, %3\",
9511 \"cmp\\t%0, %1\"},
9512 {\"cmp\\t%2, %3\",
9513 \"cmn\\t%0, #%n1\"},
9514 {\"cmn\\t%2, #%n3\",
9515 \"cmp\\t%0, %1\"},
9516 {\"cmn\\t%2, #%n3\",
9517 \"cmn\\t%0, #%n1\"}
9518 };
9519 static const char * const ite[2] =
9520 {
9521 \"it\\t%d5\",
9522 \"it\\t%d4\"
9523 };
9524 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9525 CMP_CMP, CMN_CMP, CMP_CMP,
9526 CMN_CMP, CMP_CMN, CMN_CMN};
9527 int swap =
9528 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9529
9530 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9531 if (TARGET_THUMB2) {
9532 output_asm_insn (ite[swap], operands);
9533 }
9534 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9535 return \"\";
9536 }"
9537 [(set_attr "conds" "set")
9538 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9539 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9540 (set_attr "type" "multiple")
9541 (set_attr_alternative "length"
9542 [(const_int 6)
9543 (const_int 8)
9544 (const_int 8)
9545 (const_int 8)
9546 (const_int 8)
9547 (if_then_else (eq_attr "is_thumb" "no")
9548 (const_int 8)
9549 (const_int 10))
9550 (if_then_else (eq_attr "is_thumb" "no")
9551 (const_int 8)
9552 (const_int 10))
9553 (if_then_else (eq_attr "is_thumb" "no")
9554 (const_int 8)
9555 (const_int 10))
9556 (if_then_else (eq_attr "is_thumb" "no")
9557 (const_int 8)
9558 (const_int 10))])]
9559 )
9560
9561 (define_insn "*cmp_ite1"
9562 [(set (match_operand 6 "dominant_cc_register" "")
9563 (compare
9564 (if_then_else:SI
9565 (match_operator 4 "arm_comparison_operator"
9566 [(match_operand:SI 0 "s_register_operand"
9567 "l,l,l,r,r,r,r,r,r")
9568 (match_operand:SI 1 "arm_add_operand"
9569 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9570 (match_operator:SI 5 "arm_comparison_operator"
9571 [(match_operand:SI 2 "s_register_operand"
9572 "l,r,r,l,l,r,r,r,r")
9573 (match_operand:SI 3 "arm_add_operand"
9574 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9575 (const_int 1))
9576 (const_int 0)))]
9577 "TARGET_32BIT"
9578 "*
9579 {
9580 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9581 {
9582 {\"cmp\\t%0, %1\",
9583 \"cmp\\t%2, %3\"},
9584 {\"cmn\\t%0, #%n1\",
9585 \"cmp\\t%2, %3\"},
9586 {\"cmp\\t%0, %1\",
9587 \"cmn\\t%2, #%n3\"},
9588 {\"cmn\\t%0, #%n1\",
9589 \"cmn\\t%2, #%n3\"}
9590 };
9591 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9592 {
9593 {\"cmp%d4\\t%2, %3\",
9594 \"cmp%D5\\t%0, %1\"},
9595 {\"cmp%d4\\t%2, %3\",
9596 \"cmn%D5\\t%0, #%n1\"},
9597 {\"cmn%d4\\t%2, #%n3\",
9598 \"cmp%D5\\t%0, %1\"},
9599 {\"cmn%d4\\t%2, #%n3\",
9600 \"cmn%D5\\t%0, #%n1\"}
9601 };
9602 static const char * const ite[2] =
9603 {
9604 \"it\\t%d4\",
9605 \"it\\t%D5\"
9606 };
9607 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9608 CMP_CMP, CMN_CMP, CMP_CMP,
9609 CMN_CMP, CMP_CMN, CMN_CMN};
9610 int swap =
9611 comparison_dominates_p (GET_CODE (operands[5]),
9612 reverse_condition (GET_CODE (operands[4])));
9613
9614 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9615 if (TARGET_THUMB2) {
9616 output_asm_insn (ite[swap], operands);
9617 }
9618 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9619 return \"\";
9620 }"
9621 [(set_attr "conds" "set")
9622 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9623 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9624 (set_attr_alternative "length"
9625 [(const_int 6)
9626 (const_int 8)
9627 (const_int 8)
9628 (const_int 8)
9629 (const_int 8)
9630 (if_then_else (eq_attr "is_thumb" "no")
9631 (const_int 8)
9632 (const_int 10))
9633 (if_then_else (eq_attr "is_thumb" "no")
9634 (const_int 8)
9635 (const_int 10))
9636 (if_then_else (eq_attr "is_thumb" "no")
9637 (const_int 8)
9638 (const_int 10))
9639 (if_then_else (eq_attr "is_thumb" "no")
9640 (const_int 8)
9641 (const_int 10))])
9642 (set_attr "type" "multiple")]
9643 )
9644
9645 (define_insn "*cmp_and"
9646 [(set (match_operand 6 "dominant_cc_register" "")
9647 (compare
9648 (and:SI
9649 (match_operator 4 "arm_comparison_operator"
9650 [(match_operand:SI 0 "s_register_operand"
9651 "l,l,l,r,r,r,r,r,r")
9652 (match_operand:SI 1 "arm_add_operand"
9653 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9654 (match_operator:SI 5 "arm_comparison_operator"
9655 [(match_operand:SI 2 "s_register_operand"
9656 "l,r,r,l,l,r,r,r,r")
9657 (match_operand:SI 3 "arm_add_operand"
9658 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9659 (const_int 0)))]
9660 "TARGET_32BIT"
9661 "*
9662 {
9663 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9664 {
9665 {\"cmp%d5\\t%0, %1\",
9666 \"cmp%d4\\t%2, %3\"},
9667 {\"cmn%d5\\t%0, #%n1\",
9668 \"cmp%d4\\t%2, %3\"},
9669 {\"cmp%d5\\t%0, %1\",
9670 \"cmn%d4\\t%2, #%n3\"},
9671 {\"cmn%d5\\t%0, #%n1\",
9672 \"cmn%d4\\t%2, #%n3\"}
9673 };
9674 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9675 {
9676 {\"cmp\\t%2, %3\",
9677 \"cmp\\t%0, %1\"},
9678 {\"cmp\\t%2, %3\",
9679 \"cmn\\t%0, #%n1\"},
9680 {\"cmn\\t%2, #%n3\",
9681 \"cmp\\t%0, %1\"},
9682 {\"cmn\\t%2, #%n3\",
9683 \"cmn\\t%0, #%n1\"}
9684 };
9685 static const char *const ite[2] =
9686 {
9687 \"it\\t%d5\",
9688 \"it\\t%d4\"
9689 };
9690 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9691 CMP_CMP, CMN_CMP, CMP_CMP,
9692 CMN_CMP, CMP_CMN, CMN_CMN};
9693 int swap =
9694 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9695
9696 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9697 if (TARGET_THUMB2) {
9698 output_asm_insn (ite[swap], operands);
9699 }
9700 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9701 return \"\";
9702 }"
9703 [(set_attr "conds" "set")
9704 (set_attr "predicable" "no")
9705 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9706 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9707 (set_attr_alternative "length"
9708 [(const_int 6)
9709 (const_int 8)
9710 (const_int 8)
9711 (const_int 8)
9712 (const_int 8)
9713 (if_then_else (eq_attr "is_thumb" "no")
9714 (const_int 8)
9715 (const_int 10))
9716 (if_then_else (eq_attr "is_thumb" "no")
9717 (const_int 8)
9718 (const_int 10))
9719 (if_then_else (eq_attr "is_thumb" "no")
9720 (const_int 8)
9721 (const_int 10))
9722 (if_then_else (eq_attr "is_thumb" "no")
9723 (const_int 8)
9724 (const_int 10))])
9725 (set_attr "type" "multiple")]
9726 )
9727
9728 (define_insn "*cmp_ior"
9729 [(set (match_operand 6 "dominant_cc_register" "")
9730 (compare
9731 (ior:SI
9732 (match_operator 4 "arm_comparison_operator"
9733 [(match_operand:SI 0 "s_register_operand"
9734 "l,l,l,r,r,r,r,r,r")
9735 (match_operand:SI 1 "arm_add_operand"
9736 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9737 (match_operator:SI 5 "arm_comparison_operator"
9738 [(match_operand:SI 2 "s_register_operand"
9739 "l,r,r,l,l,r,r,r,r")
9740 (match_operand:SI 3 "arm_add_operand"
9741 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9742 (const_int 0)))]
9743 "TARGET_32BIT"
9744 "*
9745 {
9746 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9747 {
9748 {\"cmp\\t%0, %1\",
9749 \"cmp\\t%2, %3\"},
9750 {\"cmn\\t%0, #%n1\",
9751 \"cmp\\t%2, %3\"},
9752 {\"cmp\\t%0, %1\",
9753 \"cmn\\t%2, #%n3\"},
9754 {\"cmn\\t%0, #%n1\",
9755 \"cmn\\t%2, #%n3\"}
9756 };
9757 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9758 {
9759 {\"cmp%D4\\t%2, %3\",
9760 \"cmp%D5\\t%0, %1\"},
9761 {\"cmp%D4\\t%2, %3\",
9762 \"cmn%D5\\t%0, #%n1\"},
9763 {\"cmn%D4\\t%2, #%n3\",
9764 \"cmp%D5\\t%0, %1\"},
9765 {\"cmn%D4\\t%2, #%n3\",
9766 \"cmn%D5\\t%0, #%n1\"}
9767 };
9768 static const char *const ite[2] =
9769 {
9770 \"it\\t%D4\",
9771 \"it\\t%D5\"
9772 };
9773 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9774 CMP_CMP, CMN_CMP, CMP_CMP,
9775 CMN_CMP, CMP_CMN, CMN_CMN};
9776 int swap =
9777 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9778
9779 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9780 if (TARGET_THUMB2) {
9781 output_asm_insn (ite[swap], operands);
9782 }
9783 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9784 return \"\";
9785 }
9786 "
9787 [(set_attr "conds" "set")
9788 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9789 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9790 (set_attr_alternative "length"
9791 [(const_int 6)
9792 (const_int 8)
9793 (const_int 8)
9794 (const_int 8)
9795 (const_int 8)
9796 (if_then_else (eq_attr "is_thumb" "no")
9797 (const_int 8)
9798 (const_int 10))
9799 (if_then_else (eq_attr "is_thumb" "no")
9800 (const_int 8)
9801 (const_int 10))
9802 (if_then_else (eq_attr "is_thumb" "no")
9803 (const_int 8)
9804 (const_int 10))
9805 (if_then_else (eq_attr "is_thumb" "no")
9806 (const_int 8)
9807 (const_int 10))])
9808 (set_attr "type" "multiple")]
9809 )
9810
9811 (define_insn_and_split "*ior_scc_scc"
9812 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9813 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9814 [(match_operand:SI 1 "s_register_operand" "l,r")
9815 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9816 (match_operator:SI 6 "arm_comparison_operator"
9817 [(match_operand:SI 4 "s_register_operand" "l,r")
9818 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9819 (clobber (reg:CC CC_REGNUM))]
9820 "TARGET_32BIT
9821 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9822 != CCmode)"
9823 "#"
9824 "TARGET_32BIT && reload_completed"
9825 [(set (match_dup 7)
9826 (compare
9827 (ior:SI
9828 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9829 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9830 (const_int 0)))
9831 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9832 "operands[7]
9833 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9834 DOM_CC_X_OR_Y),
9835 CC_REGNUM);"
9836 [(set_attr "conds" "clob")
9837 (set_attr "enabled_for_short_it" "yes,no")
9838 (set_attr "length" "16")
9839 (set_attr "type" "multiple")]
9840 )
9841
9842 ; If the above pattern is followed by a CMP insn, then the compare is
9843 ; redundant, since we can rework the conditional instruction that follows.
9844 (define_insn_and_split "*ior_scc_scc_cmp"
9845 [(set (match_operand 0 "dominant_cc_register" "")
9846 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9847 [(match_operand:SI 1 "s_register_operand" "l,r")
9848 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9849 (match_operator:SI 6 "arm_comparison_operator"
9850 [(match_operand:SI 4 "s_register_operand" "l,r")
9851 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9852 (const_int 0)))
9853 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9854 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9855 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9856 "TARGET_32BIT"
9857 "#"
9858 "TARGET_32BIT && reload_completed"
9859 [(set (match_dup 0)
9860 (compare
9861 (ior:SI
9862 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9863 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9864 (const_int 0)))
9865 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9866 ""
9867 [(set_attr "conds" "set")
9868 (set_attr "enabled_for_short_it" "yes,no")
9869 (set_attr "length" "16")
9870 (set_attr "type" "multiple")]
9871 )
9872
9873 (define_insn_and_split "*and_scc_scc"
9874 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9875 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9876 [(match_operand:SI 1 "s_register_operand" "l,r")
9877 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9878 (match_operator:SI 6 "arm_comparison_operator"
9879 [(match_operand:SI 4 "s_register_operand" "l,r")
9880 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9881 (clobber (reg:CC CC_REGNUM))]
9882 "TARGET_32BIT
9883 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9884 != CCmode)"
9885 "#"
9886 "TARGET_32BIT && reload_completed
9887 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9888 != CCmode)"
9889 [(set (match_dup 7)
9890 (compare
9891 (and:SI
9892 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9893 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9894 (const_int 0)))
9895 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9896 "operands[7]
9897 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9898 DOM_CC_X_AND_Y),
9899 CC_REGNUM);"
9900 [(set_attr "conds" "clob")
9901 (set_attr "enabled_for_short_it" "yes,no")
9902 (set_attr "length" "16")
9903 (set_attr "type" "multiple")]
9904 )
9905
9906 ; If the above pattern is followed by a CMP insn, then the compare is
9907 ; redundant, since we can rework the conditional instruction that follows.
9908 (define_insn_and_split "*and_scc_scc_cmp"
9909 [(set (match_operand 0 "dominant_cc_register" "")
9910 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9911 [(match_operand:SI 1 "s_register_operand" "l,r")
9912 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9913 (match_operator:SI 6 "arm_comparison_operator"
9914 [(match_operand:SI 4 "s_register_operand" "l,r")
9915 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9916 (const_int 0)))
9917 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9918 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9919 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9920 "TARGET_32BIT"
9921 "#"
9922 "TARGET_32BIT && reload_completed"
9923 [(set (match_dup 0)
9924 (compare
9925 (and:SI
9926 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9927 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9928 (const_int 0)))
9929 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9930 ""
9931 [(set_attr "conds" "set")
9932 (set_attr "enabled_for_short_it" "yes,no")
9933 (set_attr "length" "16")
9934 (set_attr "type" "multiple")]
9935 )
9936
9937 ;; If there is no dominance in the comparison, then we can still save an
9938 ;; instruction in the AND case, since we can know that the second compare
9939 ;; need only zero the value if false (if true, then the value is already
9940 ;; correct).
9941 (define_insn_and_split "*and_scc_scc_nodom"
9942 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9943 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9944 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9945 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9946 (match_operator:SI 6 "arm_comparison_operator"
9947 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9948 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9949 (clobber (reg:CC CC_REGNUM))]
9950 "TARGET_32BIT
9951 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9952 == CCmode)"
9953 "#"
9954 "TARGET_32BIT && reload_completed"
9955 [(parallel [(set (match_dup 0)
9956 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9957 (clobber (reg:CC CC_REGNUM))])
9958 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9959 (set (match_dup 0)
9960 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9961 (match_dup 0)
9962 (const_int 0)))]
9963 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9964 operands[4], operands[5]),
9965 CC_REGNUM);
9966 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9967 operands[5]);"
9968 [(set_attr "conds" "clob")
9969 (set_attr "length" "20")
9970 (set_attr "type" "multiple")]
9971 )
9972
9973 (define_split
9974 [(set (reg:CC_NOOV CC_REGNUM)
9975 (compare:CC_NOOV (ior:SI
9976 (and:SI (match_operand:SI 0 "s_register_operand" "")
9977 (const_int 1))
9978 (match_operator:SI 1 "arm_comparison_operator"
9979 [(match_operand:SI 2 "s_register_operand" "")
9980 (match_operand:SI 3 "arm_add_operand" "")]))
9981 (const_int 0)))
9982 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9983 "TARGET_ARM"
9984 [(set (match_dup 4)
9985 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9986 (match_dup 0)))
9987 (set (reg:CC_NOOV CC_REGNUM)
9988 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9989 (const_int 0)))]
9990 "")
9991
9992 (define_split
9993 [(set (reg:CC_NOOV CC_REGNUM)
9994 (compare:CC_NOOV (ior:SI
9995 (match_operator:SI 1 "arm_comparison_operator"
9996 [(match_operand:SI 2 "s_register_operand" "")
9997 (match_operand:SI 3 "arm_add_operand" "")])
9998 (and:SI (match_operand:SI 0 "s_register_operand" "")
9999 (const_int 1)))
10000 (const_int 0)))
10001 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10002 "TARGET_ARM"
10003 [(set (match_dup 4)
10004 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10005 (match_dup 0)))
10006 (set (reg:CC_NOOV CC_REGNUM)
10007 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10008 (const_int 0)))]
10009 "")
10010 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10011
10012 (define_insn_and_split "*negscc"
10013 [(set (match_operand:SI 0 "s_register_operand" "=r")
10014 (neg:SI (match_operator 3 "arm_comparison_operator"
10015 [(match_operand:SI 1 "s_register_operand" "r")
10016 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10017 (clobber (reg:CC CC_REGNUM))]
10018 "TARGET_ARM"
10019 "#"
10020 "&& reload_completed"
10021 [(const_int 0)]
10022 {
10023 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10024
10025 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10026 {
10027 /* Emit mov\\t%0, %1, asr #31 */
10028 emit_insn (gen_rtx_SET (operands[0],
10029 gen_rtx_ASHIFTRT (SImode,
10030 operands[1],
10031 GEN_INT (31))));
10032 DONE;
10033 }
10034 else if (GET_CODE (operands[3]) == NE)
10035 {
10036 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10037 if (CONST_INT_P (operands[2]))
10038 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10039 GEN_INT (- INTVAL (operands[2]))));
10040 else
10041 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10042
10043 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10044 gen_rtx_NE (SImode,
10045 cc_reg,
10046 const0_rtx),
10047 gen_rtx_SET (operands[0],
10048 GEN_INT (~0))));
10049 DONE;
10050 }
10051 else
10052 {
10053 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10054 emit_insn (gen_rtx_SET (cc_reg,
10055 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10056 enum rtx_code rc = GET_CODE (operands[3]);
10057
10058 rc = reverse_condition (rc);
10059 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10060 gen_rtx_fmt_ee (rc,
10061 VOIDmode,
10062 cc_reg,
10063 const0_rtx),
10064 gen_rtx_SET (operands[0], const0_rtx)));
10065 rc = GET_CODE (operands[3]);
10066 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10067 gen_rtx_fmt_ee (rc,
10068 VOIDmode,
10069 cc_reg,
10070 const0_rtx),
10071 gen_rtx_SET (operands[0],
10072 GEN_INT (~0))));
10073 DONE;
10074 }
10075 FAIL;
10076 }
10077 [(set_attr "conds" "clob")
10078 (set_attr "length" "12")
10079 (set_attr "type" "multiple")]
10080 )
10081
10082 (define_insn_and_split "movcond_addsi"
10083 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
10084 (if_then_else:SI
10085 (match_operator 5 "comparison_operator"
10086 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
10087 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
10088 (const_int 0)])
10089 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
10090 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
10091 (clobber (reg:CC CC_REGNUM))]
10092 "TARGET_32BIT"
10093 "#"
10094 "&& reload_completed"
10095 [(set (reg:CC_NOOV CC_REGNUM)
10096 (compare:CC_NOOV
10097 (plus:SI (match_dup 3)
10098 (match_dup 4))
10099 (const_int 0)))
10100 (set (match_dup 0) (match_dup 1))
10101 (cond_exec (match_dup 6)
10102 (set (match_dup 0) (match_dup 2)))]
10103 "
10104 {
10105 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
10106 operands[3], operands[4]);
10107 enum rtx_code rc = GET_CODE (operands[5]);
10108 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10109 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
10110 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
10111 rc = reverse_condition (rc);
10112 else
10113 std::swap (operands[1], operands[2]);
10114
10115 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10116 }
10117 "
10118 [(set_attr "conds" "clob")
10119 (set_attr "enabled_for_short_it" "no,yes,yes")
10120 (set_attr "type" "multiple")]
10121 )
10122
10123 (define_insn "movcond"
10124 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10125 (if_then_else:SI
10126 (match_operator 5 "arm_comparison_operator"
10127 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10128 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
10129 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10130 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
10131 (clobber (reg:CC CC_REGNUM))]
10132 "TARGET_ARM"
10133 "*
10134 if (GET_CODE (operands[5]) == LT
10135 && (operands[4] == const0_rtx))
10136 {
10137 if (which_alternative != 1 && REG_P (operands[1]))
10138 {
10139 if (operands[2] == const0_rtx)
10140 return \"and\\t%0, %1, %3, asr #31\";
10141 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
10142 }
10143 else if (which_alternative != 0 && REG_P (operands[2]))
10144 {
10145 if (operands[1] == const0_rtx)
10146 return \"bic\\t%0, %2, %3, asr #31\";
10147 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
10148 }
10149 /* The only case that falls through to here is when both ops 1 & 2
10150 are constants. */
10151 }
10152
10153 if (GET_CODE (operands[5]) == GE
10154 && (operands[4] == const0_rtx))
10155 {
10156 if (which_alternative != 1 && REG_P (operands[1]))
10157 {
10158 if (operands[2] == const0_rtx)
10159 return \"bic\\t%0, %1, %3, asr #31\";
10160 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
10161 }
10162 else if (which_alternative != 0 && REG_P (operands[2]))
10163 {
10164 if (operands[1] == const0_rtx)
10165 return \"and\\t%0, %2, %3, asr #31\";
10166 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
10167 }
10168 /* The only case that falls through to here is when both ops 1 & 2
10169 are constants. */
10170 }
10171 if (CONST_INT_P (operands[4])
10172 && !const_ok_for_arm (INTVAL (operands[4])))
10173 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
10174 else
10175 output_asm_insn (\"cmp\\t%3, %4\", operands);
10176 if (which_alternative != 0)
10177 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
10178 if (which_alternative != 1)
10179 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
10180 return \"\";
10181 "
10182 [(set_attr "conds" "clob")
10183 (set_attr "length" "8,8,12")
10184 (set_attr "type" "multiple")]
10185 )
10186
10187 ;; ??? The patterns below need checking for Thumb-2 usefulness.
10188
10189 (define_insn "*ifcompare_plus_move"
10190 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10191 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10192 [(match_operand:SI 4 "s_register_operand" "r,r")
10193 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10194 (plus:SI
10195 (match_operand:SI 2 "s_register_operand" "r,r")
10196 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10197 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10198 (clobber (reg:CC CC_REGNUM))]
10199 "TARGET_ARM"
10200 "#"
10201 [(set_attr "conds" "clob")
10202 (set_attr "length" "8,12")
10203 (set_attr "type" "multiple")]
10204 )
10205
10206 (define_insn "*if_plus_move"
10207 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10208 (if_then_else:SI
10209 (match_operator 4 "arm_comparison_operator"
10210 [(match_operand 5 "cc_register" "") (const_int 0)])
10211 (plus:SI
10212 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10213 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10214 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10215 "TARGET_ARM"
10216 "@
10217 add%d4\\t%0, %2, %3
10218 sub%d4\\t%0, %2, #%n3
10219 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10220 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10221 [(set_attr "conds" "use")
10222 (set_attr "length" "4,4,8,8")
10223 (set_attr_alternative "type"
10224 [(if_then_else (match_operand 3 "const_int_operand" "")
10225 (const_string "alu_imm" )
10226 (const_string "alu_sreg"))
10227 (const_string "alu_imm")
10228 (const_string "multiple")
10229 (const_string "multiple")])]
10230 )
10231
10232 (define_insn "*ifcompare_move_plus"
10233 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10234 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10235 [(match_operand:SI 4 "s_register_operand" "r,r")
10236 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10237 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10238 (plus:SI
10239 (match_operand:SI 2 "s_register_operand" "r,r")
10240 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10241 (clobber (reg:CC CC_REGNUM))]
10242 "TARGET_ARM"
10243 "#"
10244 [(set_attr "conds" "clob")
10245 (set_attr "length" "8,12")
10246 (set_attr "type" "multiple")]
10247 )
10248
10249 (define_insn "*if_move_plus"
10250 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10251 (if_then_else:SI
10252 (match_operator 4 "arm_comparison_operator"
10253 [(match_operand 5 "cc_register" "") (const_int 0)])
10254 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10255 (plus:SI
10256 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10257 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10258 "TARGET_ARM"
10259 "@
10260 add%D4\\t%0, %2, %3
10261 sub%D4\\t%0, %2, #%n3
10262 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10263 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10264 [(set_attr "conds" "use")
10265 (set_attr "length" "4,4,8,8")
10266 (set_attr_alternative "type"
10267 [(if_then_else (match_operand 3 "const_int_operand" "")
10268 (const_string "alu_imm" )
10269 (const_string "alu_sreg"))
10270 (const_string "alu_imm")
10271 (const_string "multiple")
10272 (const_string "multiple")])]
10273 )
10274
10275 (define_insn "*ifcompare_arith_arith"
10276 [(set (match_operand:SI 0 "s_register_operand" "=r")
10277 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10278 [(match_operand:SI 5 "s_register_operand" "r")
10279 (match_operand:SI 6 "arm_add_operand" "rIL")])
10280 (match_operator:SI 8 "shiftable_operator"
10281 [(match_operand:SI 1 "s_register_operand" "r")
10282 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10283 (match_operator:SI 7 "shiftable_operator"
10284 [(match_operand:SI 3 "s_register_operand" "r")
10285 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10286 (clobber (reg:CC CC_REGNUM))]
10287 "TARGET_ARM"
10288 "#"
10289 [(set_attr "conds" "clob")
10290 (set_attr "length" "12")
10291 (set_attr "type" "multiple")]
10292 )
10293
10294 (define_insn "*if_arith_arith"
10295 [(set (match_operand:SI 0 "s_register_operand" "=r")
10296 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10297 [(match_operand 8 "cc_register" "") (const_int 0)])
10298 (match_operator:SI 6 "shiftable_operator"
10299 [(match_operand:SI 1 "s_register_operand" "r")
10300 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10301 (match_operator:SI 7 "shiftable_operator"
10302 [(match_operand:SI 3 "s_register_operand" "r")
10303 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10304 "TARGET_ARM"
10305 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10306 [(set_attr "conds" "use")
10307 (set_attr "length" "8")
10308 (set_attr "type" "multiple")]
10309 )
10310
10311 (define_insn "*ifcompare_arith_move"
10312 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10313 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10314 [(match_operand:SI 2 "s_register_operand" "r,r")
10315 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10316 (match_operator:SI 7 "shiftable_operator"
10317 [(match_operand:SI 4 "s_register_operand" "r,r")
10318 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10319 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10320 (clobber (reg:CC CC_REGNUM))]
10321 "TARGET_ARM"
10322 "*
10323 /* If we have an operation where (op x 0) is the identity operation and
10324 the conditional operator is LT or GE and we are comparing against zero and
10325 everything is in registers then we can do this in two instructions. */
10326 if (operands[3] == const0_rtx
10327 && GET_CODE (operands[7]) != AND
10328 && REG_P (operands[5])
10329 && REG_P (operands[1])
10330 && REGNO (operands[1]) == REGNO (operands[4])
10331 && REGNO (operands[4]) != REGNO (operands[0]))
10332 {
10333 if (GET_CODE (operands[6]) == LT)
10334 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10335 else if (GET_CODE (operands[6]) == GE)
10336 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10337 }
10338 if (CONST_INT_P (operands[3])
10339 && !const_ok_for_arm (INTVAL (operands[3])))
10340 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10341 else
10342 output_asm_insn (\"cmp\\t%2, %3\", operands);
10343 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10344 if (which_alternative != 0)
10345 return \"mov%D6\\t%0, %1\";
10346 return \"\";
10347 "
10348 [(set_attr "conds" "clob")
10349 (set_attr "length" "8,12")
10350 (set_attr "type" "multiple")]
10351 )
10352
10353 (define_insn "*if_arith_move"
10354 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10355 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10356 [(match_operand 6 "cc_register" "") (const_int 0)])
10357 (match_operator:SI 5 "shiftable_operator"
10358 [(match_operand:SI 2 "s_register_operand" "r,r")
10359 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10360 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10361 "TARGET_ARM"
10362 "@
10363 %I5%d4\\t%0, %2, %3
10364 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10365 [(set_attr "conds" "use")
10366 (set_attr "length" "4,8")
10367 (set_attr_alternative "type"
10368 [(if_then_else (match_operand 3 "const_int_operand" "")
10369 (const_string "alu_shift_imm" )
10370 (const_string "alu_shift_reg"))
10371 (const_string "multiple")])]
10372 )
10373
10374 (define_insn "*ifcompare_move_arith"
10375 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10376 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10377 [(match_operand:SI 4 "s_register_operand" "r,r")
10378 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10379 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10380 (match_operator:SI 7 "shiftable_operator"
10381 [(match_operand:SI 2 "s_register_operand" "r,r")
10382 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10383 (clobber (reg:CC CC_REGNUM))]
10384 "TARGET_ARM"
10385 "*
10386 /* If we have an operation where (op x 0) is the identity operation and
10387 the conditional operator is LT or GE and we are comparing against zero and
10388 everything is in registers then we can do this in two instructions */
10389 if (operands[5] == const0_rtx
10390 && GET_CODE (operands[7]) != AND
10391 && REG_P (operands[3])
10392 && REG_P (operands[1])
10393 && REGNO (operands[1]) == REGNO (operands[2])
10394 && REGNO (operands[2]) != REGNO (operands[0]))
10395 {
10396 if (GET_CODE (operands[6]) == GE)
10397 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10398 else if (GET_CODE (operands[6]) == LT)
10399 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10400 }
10401
10402 if (CONST_INT_P (operands[5])
10403 && !const_ok_for_arm (INTVAL (operands[5])))
10404 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10405 else
10406 output_asm_insn (\"cmp\\t%4, %5\", operands);
10407
10408 if (which_alternative != 0)
10409 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10410 return \"%I7%D6\\t%0, %2, %3\";
10411 "
10412 [(set_attr "conds" "clob")
10413 (set_attr "length" "8,12")
10414 (set_attr "type" "multiple")]
10415 )
10416
10417 (define_insn "*if_move_arith"
10418 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10419 (if_then_else:SI
10420 (match_operator 4 "arm_comparison_operator"
10421 [(match_operand 6 "cc_register" "") (const_int 0)])
10422 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10423 (match_operator:SI 5 "shiftable_operator"
10424 [(match_operand:SI 2 "s_register_operand" "r,r")
10425 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10426 "TARGET_ARM"
10427 "@
10428 %I5%D4\\t%0, %2, %3
10429 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10430 [(set_attr "conds" "use")
10431 (set_attr "length" "4,8")
10432 (set_attr_alternative "type"
10433 [(if_then_else (match_operand 3 "const_int_operand" "")
10434 (const_string "alu_shift_imm" )
10435 (const_string "alu_shift_reg"))
10436 (const_string "multiple")])]
10437 )
10438
10439 (define_insn "*ifcompare_move_not"
10440 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10441 (if_then_else:SI
10442 (match_operator 5 "arm_comparison_operator"
10443 [(match_operand:SI 3 "s_register_operand" "r,r")
10444 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10445 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10446 (not:SI
10447 (match_operand:SI 2 "s_register_operand" "r,r"))))
10448 (clobber (reg:CC CC_REGNUM))]
10449 "TARGET_ARM"
10450 "#"
10451 [(set_attr "conds" "clob")
10452 (set_attr "length" "8,12")
10453 (set_attr "type" "multiple")]
10454 )
10455
10456 (define_insn "*if_move_not"
10457 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10458 (if_then_else:SI
10459 (match_operator 4 "arm_comparison_operator"
10460 [(match_operand 3 "cc_register" "") (const_int 0)])
10461 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10462 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10463 "TARGET_ARM"
10464 "@
10465 mvn%D4\\t%0, %2
10466 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10467 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10468 [(set_attr "conds" "use")
10469 (set_attr "type" "mvn_reg")
10470 (set_attr "length" "4,8,8")
10471 (set_attr "type" "mvn_reg,multiple,multiple")]
10472 )
10473
10474 (define_insn "*ifcompare_not_move"
10475 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10476 (if_then_else:SI
10477 (match_operator 5 "arm_comparison_operator"
10478 [(match_operand:SI 3 "s_register_operand" "r,r")
10479 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10480 (not:SI
10481 (match_operand:SI 2 "s_register_operand" "r,r"))
10482 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10483 (clobber (reg:CC CC_REGNUM))]
10484 "TARGET_ARM"
10485 "#"
10486 [(set_attr "conds" "clob")
10487 (set_attr "length" "8,12")
10488 (set_attr "type" "multiple")]
10489 )
10490
10491 (define_insn "*if_not_move"
10492 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10493 (if_then_else:SI
10494 (match_operator 4 "arm_comparison_operator"
10495 [(match_operand 3 "cc_register" "") (const_int 0)])
10496 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10497 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10498 "TARGET_ARM"
10499 "@
10500 mvn%d4\\t%0, %2
10501 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10502 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10503 [(set_attr "conds" "use")
10504 (set_attr "type" "mvn_reg,multiple,multiple")
10505 (set_attr "length" "4,8,8")]
10506 )
10507
10508 (define_insn "*ifcompare_shift_move"
10509 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10510 (if_then_else:SI
10511 (match_operator 6 "arm_comparison_operator"
10512 [(match_operand:SI 4 "s_register_operand" "r,r")
10513 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10514 (match_operator:SI 7 "shift_operator"
10515 [(match_operand:SI 2 "s_register_operand" "r,r")
10516 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10517 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10518 (clobber (reg:CC CC_REGNUM))]
10519 "TARGET_ARM"
10520 "#"
10521 [(set_attr "conds" "clob")
10522 (set_attr "length" "8,12")
10523 (set_attr "type" "multiple")]
10524 )
10525
10526 (define_insn "*if_shift_move"
10527 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10528 (if_then_else:SI
10529 (match_operator 5 "arm_comparison_operator"
10530 [(match_operand 6 "cc_register" "") (const_int 0)])
10531 (match_operator:SI 4 "shift_operator"
10532 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10533 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10534 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10535 "TARGET_ARM"
10536 "@
10537 mov%d5\\t%0, %2%S4
10538 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10539 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10540 [(set_attr "conds" "use")
10541 (set_attr "shift" "2")
10542 (set_attr "length" "4,8,8")
10543 (set_attr_alternative "type"
10544 [(if_then_else (match_operand 3 "const_int_operand" "")
10545 (const_string "mov_shift" )
10546 (const_string "mov_shift_reg"))
10547 (const_string "multiple")
10548 (const_string "multiple")])]
10549 )
10550
10551 (define_insn "*ifcompare_move_shift"
10552 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10553 (if_then_else:SI
10554 (match_operator 6 "arm_comparison_operator"
10555 [(match_operand:SI 4 "s_register_operand" "r,r")
10556 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10557 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10558 (match_operator:SI 7 "shift_operator"
10559 [(match_operand:SI 2 "s_register_operand" "r,r")
10560 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10561 (clobber (reg:CC CC_REGNUM))]
10562 "TARGET_ARM"
10563 "#"
10564 [(set_attr "conds" "clob")
10565 (set_attr "length" "8,12")
10566 (set_attr "type" "multiple")]
10567 )
10568
10569 (define_insn "*if_move_shift"
10570 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10571 (if_then_else:SI
10572 (match_operator 5 "arm_comparison_operator"
10573 [(match_operand 6 "cc_register" "") (const_int 0)])
10574 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10575 (match_operator:SI 4 "shift_operator"
10576 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10577 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10578 "TARGET_ARM"
10579 "@
10580 mov%D5\\t%0, %2%S4
10581 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10582 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10583 [(set_attr "conds" "use")
10584 (set_attr "shift" "2")
10585 (set_attr "length" "4,8,8")
10586 (set_attr_alternative "type"
10587 [(if_then_else (match_operand 3 "const_int_operand" "")
10588 (const_string "mov_shift" )
10589 (const_string "mov_shift_reg"))
10590 (const_string "multiple")
10591 (const_string "multiple")])]
10592 )
10593
10594 (define_insn "*ifcompare_shift_shift"
10595 [(set (match_operand:SI 0 "s_register_operand" "=r")
10596 (if_then_else:SI
10597 (match_operator 7 "arm_comparison_operator"
10598 [(match_operand:SI 5 "s_register_operand" "r")
10599 (match_operand:SI 6 "arm_add_operand" "rIL")])
10600 (match_operator:SI 8 "shift_operator"
10601 [(match_operand:SI 1 "s_register_operand" "r")
10602 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10603 (match_operator:SI 9 "shift_operator"
10604 [(match_operand:SI 3 "s_register_operand" "r")
10605 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10606 (clobber (reg:CC CC_REGNUM))]
10607 "TARGET_ARM"
10608 "#"
10609 [(set_attr "conds" "clob")
10610 (set_attr "length" "12")
10611 (set_attr "type" "multiple")]
10612 )
10613
10614 (define_insn "*if_shift_shift"
10615 [(set (match_operand:SI 0 "s_register_operand" "=r")
10616 (if_then_else:SI
10617 (match_operator 5 "arm_comparison_operator"
10618 [(match_operand 8 "cc_register" "") (const_int 0)])
10619 (match_operator:SI 6 "shift_operator"
10620 [(match_operand:SI 1 "s_register_operand" "r")
10621 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10622 (match_operator:SI 7 "shift_operator"
10623 [(match_operand:SI 3 "s_register_operand" "r")
10624 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10625 "TARGET_ARM"
10626 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10627 [(set_attr "conds" "use")
10628 (set_attr "shift" "1")
10629 (set_attr "length" "8")
10630 (set (attr "type") (if_then_else
10631 (and (match_operand 2 "const_int_operand" "")
10632 (match_operand 4 "const_int_operand" ""))
10633 (const_string "mov_shift")
10634 (const_string "mov_shift_reg")))]
10635 )
10636
10637 (define_insn "*ifcompare_not_arith"
10638 [(set (match_operand:SI 0 "s_register_operand" "=r")
10639 (if_then_else:SI
10640 (match_operator 6 "arm_comparison_operator"
10641 [(match_operand:SI 4 "s_register_operand" "r")
10642 (match_operand:SI 5 "arm_add_operand" "rIL")])
10643 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10644 (match_operator:SI 7 "shiftable_operator"
10645 [(match_operand:SI 2 "s_register_operand" "r")
10646 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10647 (clobber (reg:CC CC_REGNUM))]
10648 "TARGET_ARM"
10649 "#"
10650 [(set_attr "conds" "clob")
10651 (set_attr "length" "12")
10652 (set_attr "type" "multiple")]
10653 )
10654
10655 (define_insn "*if_not_arith"
10656 [(set (match_operand:SI 0 "s_register_operand" "=r")
10657 (if_then_else:SI
10658 (match_operator 5 "arm_comparison_operator"
10659 [(match_operand 4 "cc_register" "") (const_int 0)])
10660 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10661 (match_operator:SI 6 "shiftable_operator"
10662 [(match_operand:SI 2 "s_register_operand" "r")
10663 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10664 "TARGET_ARM"
10665 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10666 [(set_attr "conds" "use")
10667 (set_attr "type" "mvn_reg")
10668 (set_attr "length" "8")]
10669 )
10670
10671 (define_insn "*ifcompare_arith_not"
10672 [(set (match_operand:SI 0 "s_register_operand" "=r")
10673 (if_then_else:SI
10674 (match_operator 6 "arm_comparison_operator"
10675 [(match_operand:SI 4 "s_register_operand" "r")
10676 (match_operand:SI 5 "arm_add_operand" "rIL")])
10677 (match_operator:SI 7 "shiftable_operator"
10678 [(match_operand:SI 2 "s_register_operand" "r")
10679 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10680 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10681 (clobber (reg:CC CC_REGNUM))]
10682 "TARGET_ARM"
10683 "#"
10684 [(set_attr "conds" "clob")
10685 (set_attr "length" "12")
10686 (set_attr "type" "multiple")]
10687 )
10688
10689 (define_insn "*if_arith_not"
10690 [(set (match_operand:SI 0 "s_register_operand" "=r")
10691 (if_then_else:SI
10692 (match_operator 5 "arm_comparison_operator"
10693 [(match_operand 4 "cc_register" "") (const_int 0)])
10694 (match_operator:SI 6 "shiftable_operator"
10695 [(match_operand:SI 2 "s_register_operand" "r")
10696 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10697 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10698 "TARGET_ARM"
10699 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10700 [(set_attr "conds" "use")
10701 (set_attr "type" "multiple")
10702 (set_attr "length" "8")]
10703 )
10704
10705 (define_insn "*ifcompare_neg_move"
10706 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10707 (if_then_else:SI
10708 (match_operator 5 "arm_comparison_operator"
10709 [(match_operand:SI 3 "s_register_operand" "r,r")
10710 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10711 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10712 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10713 (clobber (reg:CC CC_REGNUM))]
10714 "TARGET_ARM"
10715 "#"
10716 [(set_attr "conds" "clob")
10717 (set_attr "length" "8,12")
10718 (set_attr "type" "multiple")]
10719 )
10720
10721 (define_insn_and_split "*if_neg_move"
10722 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10723 (if_then_else:SI
10724 (match_operator 4 "arm_comparison_operator"
10725 [(match_operand 3 "cc_register" "") (const_int 0)])
10726 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10727 (match_operand:SI 1 "s_register_operand" "0,0")))]
10728 "TARGET_32BIT"
10729 "#"
10730 "&& reload_completed"
10731 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10732 (set (match_dup 0) (neg:SI (match_dup 2))))]
10733 ""
10734 [(set_attr "conds" "use")
10735 (set_attr "length" "4")
10736 (set_attr "arch" "t2,32")
10737 (set_attr "enabled_for_short_it" "yes,no")
10738 (set_attr "type" "logic_shift_imm")]
10739 )
10740
10741 (define_insn "*ifcompare_move_neg"
10742 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10743 (if_then_else:SI
10744 (match_operator 5 "arm_comparison_operator"
10745 [(match_operand:SI 3 "s_register_operand" "r,r")
10746 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10747 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10748 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10749 (clobber (reg:CC CC_REGNUM))]
10750 "TARGET_ARM"
10751 "#"
10752 [(set_attr "conds" "clob")
10753 (set_attr "length" "8,12")
10754 (set_attr "type" "multiple")]
10755 )
10756
10757 (define_insn_and_split "*if_move_neg"
10758 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10759 (if_then_else:SI
10760 (match_operator 4 "arm_comparison_operator"
10761 [(match_operand 3 "cc_register" "") (const_int 0)])
10762 (match_operand:SI 1 "s_register_operand" "0,0")
10763 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10764 "TARGET_32BIT"
10765 "#"
10766 "&& reload_completed"
10767 [(cond_exec (match_dup 5)
10768 (set (match_dup 0) (neg:SI (match_dup 2))))]
10769 {
10770 machine_mode mode = GET_MODE (operands[3]);
10771 rtx_code rc = GET_CODE (operands[4]);
10772
10773 if (mode == CCFPmode || mode == CCFPEmode)
10774 rc = reverse_condition_maybe_unordered (rc);
10775 else
10776 rc = reverse_condition (rc);
10777
10778 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10779 }
10780 [(set_attr "conds" "use")
10781 (set_attr "length" "4")
10782 (set_attr "arch" "t2,32")
10783 (set_attr "enabled_for_short_it" "yes,no")
10784 (set_attr "type" "logic_shift_imm")]
10785 )
10786
10787 (define_insn "*arith_adjacentmem"
10788 [(set (match_operand:SI 0 "s_register_operand" "=r")
10789 (match_operator:SI 1 "shiftable_operator"
10790 [(match_operand:SI 2 "memory_operand" "m")
10791 (match_operand:SI 3 "memory_operand" "m")]))
10792 (clobber (match_scratch:SI 4 "=r"))]
10793 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10794 "*
10795 {
10796 rtx ldm[3];
10797 rtx arith[4];
10798 rtx base_reg;
10799 HOST_WIDE_INT val1 = 0, val2 = 0;
10800
10801 if (REGNO (operands[0]) > REGNO (operands[4]))
10802 {
10803 ldm[1] = operands[4];
10804 ldm[2] = operands[0];
10805 }
10806 else
10807 {
10808 ldm[1] = operands[0];
10809 ldm[2] = operands[4];
10810 }
10811
10812 base_reg = XEXP (operands[2], 0);
10813
10814 if (!REG_P (base_reg))
10815 {
10816 val1 = INTVAL (XEXP (base_reg, 1));
10817 base_reg = XEXP (base_reg, 0);
10818 }
10819
10820 if (!REG_P (XEXP (operands[3], 0)))
10821 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10822
10823 arith[0] = operands[0];
10824 arith[3] = operands[1];
10825
10826 if (val1 < val2)
10827 {
10828 arith[1] = ldm[1];
10829 arith[2] = ldm[2];
10830 }
10831 else
10832 {
10833 arith[1] = ldm[2];
10834 arith[2] = ldm[1];
10835 }
10836
10837 ldm[0] = base_reg;
10838 if (val1 !=0 && val2 != 0)
10839 {
10840 rtx ops[3];
10841
10842 if (val1 == 4 || val2 == 4)
10843 /* Other val must be 8, since we know they are adjacent and neither
10844 is zero. */
10845 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10846 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10847 {
10848 ldm[0] = ops[0] = operands[4];
10849 ops[1] = base_reg;
10850 ops[2] = GEN_INT (val1);
10851 output_add_immediate (ops);
10852 if (val1 < val2)
10853 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10854 else
10855 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10856 }
10857 else
10858 {
10859 /* Offset is out of range for a single add, so use two ldr. */
10860 ops[0] = ldm[1];
10861 ops[1] = base_reg;
10862 ops[2] = GEN_INT (val1);
10863 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10864 ops[0] = ldm[2];
10865 ops[2] = GEN_INT (val2);
10866 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10867 }
10868 }
10869 else if (val1 != 0)
10870 {
10871 if (val1 < val2)
10872 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10873 else
10874 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10875 }
10876 else
10877 {
10878 if (val1 < val2)
10879 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10880 else
10881 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10882 }
10883 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10884 return \"\";
10885 }"
10886 [(set_attr "length" "12")
10887 (set_attr "predicable" "yes")
10888 (set_attr "type" "load_4")]
10889 )
10890
10891 ; This pattern is never tried by combine, so do it as a peephole
10892
10893 (define_peephole2
10894 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10895 (match_operand:SI 1 "arm_general_register_operand" ""))
10896 (set (reg:CC CC_REGNUM)
10897 (compare:CC (match_dup 1) (const_int 0)))]
10898 "TARGET_ARM"
10899 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10900 (set (match_dup 0) (match_dup 1))])]
10901 ""
10902 )
10903
10904 (define_split
10905 [(set (match_operand:SI 0 "s_register_operand" "")
10906 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10907 (const_int 0))
10908 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10909 [(match_operand:SI 3 "s_register_operand" "")
10910 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10911 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10912 "TARGET_ARM"
10913 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10914 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10915 (match_dup 5)))]
10916 ""
10917 )
10918
10919 ;; This split can be used because CC_Z mode implies that the following
10920 ;; branch will be an equality, or an unsigned inequality, so the sign
10921 ;; extension is not needed.
10922
10923 (define_split
10924 [(set (reg:CC_Z CC_REGNUM)
10925 (compare:CC_Z
10926 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10927 (const_int 24))
10928 (match_operand 1 "const_int_operand" "")))
10929 (clobber (match_scratch:SI 2 ""))]
10930 "TARGET_ARM
10931 && ((UINTVAL (operands[1]))
10932 == ((UINTVAL (operands[1])) >> 24) << 24)"
10933 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10934 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10935 "
10936 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10937 "
10938 )
10939 ;; ??? Check the patterns above for Thumb-2 usefulness
10940
10941 (define_expand "prologue"
10942 [(clobber (const_int 0))]
10943 "TARGET_EITHER"
10944 "if (TARGET_32BIT)
10945 arm_expand_prologue ();
10946 else
10947 thumb1_expand_prologue ();
10948 DONE;
10949 "
10950 )
10951
10952 (define_expand "epilogue"
10953 [(clobber (const_int 0))]
10954 "TARGET_EITHER"
10955 "
10956 if (crtl->calls_eh_return)
10957 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10958 if (TARGET_THUMB1)
10959 {
10960 thumb1_expand_epilogue ();
10961 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10962 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10963 }
10964 else if (HAVE_return)
10965 {
10966 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10967 no need for explicit testing again. */
10968 emit_jump_insn (gen_return ());
10969 }
10970 else if (TARGET_32BIT)
10971 {
10972 arm_expand_epilogue (true);
10973 }
10974 DONE;
10975 "
10976 )
10977
10978 ;; Note - although unspec_volatile's USE all hard registers,
10979 ;; USEs are ignored after relaod has completed. Thus we need
10980 ;; to add an unspec of the link register to ensure that flow
10981 ;; does not think that it is unused by the sibcall branch that
10982 ;; will replace the standard function epilogue.
10983 (define_expand "sibcall_epilogue"
10984 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10985 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10986 "TARGET_32BIT"
10987 "
10988 arm_expand_epilogue (false);
10989 DONE;
10990 "
10991 )
10992
10993 (define_expand "eh_epilogue"
10994 [(use (match_operand:SI 0 "register_operand" ""))
10995 (use (match_operand:SI 1 "register_operand" ""))
10996 (use (match_operand:SI 2 "register_operand" ""))]
10997 "TARGET_EITHER"
10998 "
10999 {
11000 cfun->machine->eh_epilogue_sp_ofs = operands[1];
11001 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11002 {
11003 rtx ra = gen_rtx_REG (Pmode, 2);
11004
11005 emit_move_insn (ra, operands[2]);
11006 operands[2] = ra;
11007 }
11008 /* This is a hack -- we may have crystalized the function type too
11009 early. */
11010 cfun->machine->func_type = 0;
11011 }"
11012 )
11013
11014 ;; This split is only used during output to reduce the number of patterns
11015 ;; that need assembler instructions adding to them. We allowed the setting
11016 ;; of the conditions to be implicit during rtl generation so that
11017 ;; the conditional compare patterns would work. However this conflicts to
11018 ;; some extent with the conditional data operations, so we have to split them
11019 ;; up again here.
11020
11021 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
11022 ;; conditional execution sufficient?
11023
11024 (define_split
11025 [(set (match_operand:SI 0 "s_register_operand" "")
11026 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11027 [(match_operand 2 "" "") (match_operand 3 "" "")])
11028 (match_dup 0)
11029 (match_operand 4 "" "")))
11030 (clobber (reg:CC CC_REGNUM))]
11031 "TARGET_ARM && reload_completed"
11032 [(set (match_dup 5) (match_dup 6))
11033 (cond_exec (match_dup 7)
11034 (set (match_dup 0) (match_dup 4)))]
11035 "
11036 {
11037 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11038 operands[2], operands[3]);
11039 enum rtx_code rc = GET_CODE (operands[1]);
11040
11041 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11042 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11043 if (mode == CCFPmode || mode == CCFPEmode)
11044 rc = reverse_condition_maybe_unordered (rc);
11045 else
11046 rc = reverse_condition (rc);
11047
11048 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11049 }"
11050 )
11051
11052 (define_split
11053 [(set (match_operand:SI 0 "s_register_operand" "")
11054 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11055 [(match_operand 2 "" "") (match_operand 3 "" "")])
11056 (match_operand 4 "" "")
11057 (match_dup 0)))
11058 (clobber (reg:CC CC_REGNUM))]
11059 "TARGET_ARM && reload_completed"
11060 [(set (match_dup 5) (match_dup 6))
11061 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11062 (set (match_dup 0) (match_dup 4)))]
11063 "
11064 {
11065 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11066 operands[2], operands[3]);
11067
11068 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11069 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11070 }"
11071 )
11072
11073 (define_split
11074 [(set (match_operand:SI 0 "s_register_operand" "")
11075 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11076 [(match_operand 2 "" "") (match_operand 3 "" "")])
11077 (match_operand 4 "" "")
11078 (match_operand 5 "" "")))
11079 (clobber (reg:CC CC_REGNUM))]
11080 "TARGET_ARM && reload_completed"
11081 [(set (match_dup 6) (match_dup 7))
11082 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11083 (set (match_dup 0) (match_dup 4)))
11084 (cond_exec (match_dup 8)
11085 (set (match_dup 0) (match_dup 5)))]
11086 "
11087 {
11088 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11089 operands[2], operands[3]);
11090 enum rtx_code rc = GET_CODE (operands[1]);
11091
11092 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11093 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11094 if (mode == CCFPmode || mode == CCFPEmode)
11095 rc = reverse_condition_maybe_unordered (rc);
11096 else
11097 rc = reverse_condition (rc);
11098
11099 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11100 }"
11101 )
11102
11103 (define_split
11104 [(set (match_operand:SI 0 "s_register_operand" "")
11105 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11106 [(match_operand:SI 2 "s_register_operand" "")
11107 (match_operand:SI 3 "arm_add_operand" "")])
11108 (match_operand:SI 4 "arm_rhs_operand" "")
11109 (not:SI
11110 (match_operand:SI 5 "s_register_operand" ""))))
11111 (clobber (reg:CC CC_REGNUM))]
11112 "TARGET_ARM && reload_completed"
11113 [(set (match_dup 6) (match_dup 7))
11114 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11115 (set (match_dup 0) (match_dup 4)))
11116 (cond_exec (match_dup 8)
11117 (set (match_dup 0) (not:SI (match_dup 5))))]
11118 "
11119 {
11120 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11121 operands[2], operands[3]);
11122 enum rtx_code rc = GET_CODE (operands[1]);
11123
11124 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11125 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11126 if (mode == CCFPmode || mode == CCFPEmode)
11127 rc = reverse_condition_maybe_unordered (rc);
11128 else
11129 rc = reverse_condition (rc);
11130
11131 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11132 }"
11133 )
11134
11135 (define_insn "*cond_move_not"
11136 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11137 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11138 [(match_operand 3 "cc_register" "") (const_int 0)])
11139 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11140 (not:SI
11141 (match_operand:SI 2 "s_register_operand" "r,r"))))]
11142 "TARGET_ARM"
11143 "@
11144 mvn%D4\\t%0, %2
11145 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11146 [(set_attr "conds" "use")
11147 (set_attr "type" "mvn_reg,multiple")
11148 (set_attr "length" "4,8")]
11149 )
11150
11151 ;; The next two patterns occur when an AND operation is followed by a
11152 ;; scc insn sequence
11153
11154 (define_insn "*sign_extract_onebit"
11155 [(set (match_operand:SI 0 "s_register_operand" "=r")
11156 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11157 (const_int 1)
11158 (match_operand:SI 2 "const_int_operand" "n")))
11159 (clobber (reg:CC CC_REGNUM))]
11160 "TARGET_ARM"
11161 "*
11162 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11163 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
11164 return \"mvnne\\t%0, #0\";
11165 "
11166 [(set_attr "conds" "clob")
11167 (set_attr "length" "8")
11168 (set_attr "type" "multiple")]
11169 )
11170
11171 (define_insn "*not_signextract_onebit"
11172 [(set (match_operand:SI 0 "s_register_operand" "=r")
11173 (not:SI
11174 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11175 (const_int 1)
11176 (match_operand:SI 2 "const_int_operand" "n"))))
11177 (clobber (reg:CC CC_REGNUM))]
11178 "TARGET_ARM"
11179 "*
11180 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11181 output_asm_insn (\"tst\\t%1, %2\", operands);
11182 output_asm_insn (\"mvneq\\t%0, #0\", operands);
11183 return \"movne\\t%0, #0\";
11184 "
11185 [(set_attr "conds" "clob")
11186 (set_attr "length" "12")
11187 (set_attr "type" "multiple")]
11188 )
11189 ;; ??? The above patterns need auditing for Thumb-2
11190
11191 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
11192 ;; expressions. For simplicity, the first register is also in the unspec
11193 ;; part.
11194 ;; To avoid the usage of GNU extension, the length attribute is computed
11195 ;; in a C function arm_attr_length_push_multi.
11196 (define_insn "*push_multi"
11197 [(match_parallel 2 "multi_register_push"
11198 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11199 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11200 UNSPEC_PUSH_MULT))])]
11201 ""
11202 "*
11203 {
11204 int num_saves = XVECLEN (operands[2], 0);
11205
11206 /* For the StrongARM at least it is faster to
11207 use STR to store only a single register.
11208 In Thumb mode always use push, and the assembler will pick
11209 something appropriate. */
11210 if (num_saves == 1 && TARGET_ARM)
11211 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11212 else
11213 {
11214 int i;
11215 char pattern[100];
11216
11217 if (TARGET_32BIT)
11218 strcpy (pattern, \"push%?\\t{%1\");
11219 else
11220 strcpy (pattern, \"push\\t{%1\");
11221
11222 for (i = 1; i < num_saves; i++)
11223 {
11224 strcat (pattern, \", %|\");
11225 strcat (pattern,
11226 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11227 }
11228
11229 strcat (pattern, \"}\");
11230 output_asm_insn (pattern, operands);
11231 }
11232
11233 return \"\";
11234 }"
11235 [(set_attr "type" "store_16")
11236 (set (attr "length")
11237 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11238 )
11239
11240 (define_insn "stack_tie"
11241 [(set (mem:BLK (scratch))
11242 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11243 (match_operand:SI 1 "s_register_operand" "rk")]
11244 UNSPEC_PRLG_STK))]
11245 ""
11246 ""
11247 [(set_attr "length" "0")
11248 (set_attr "type" "block")]
11249 )
11250
11251 ;; Pop (as used in epilogue RTL)
11252 ;;
11253 (define_insn "*load_multiple_with_writeback"
11254 [(match_parallel 0 "load_multiple_operation"
11255 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11256 (plus:SI (match_dup 1)
11257 (match_operand:SI 2 "const_int_I_operand" "I")))
11258 (set (match_operand:SI 3 "s_register_operand" "=rk")
11259 (mem:SI (match_dup 1)))
11260 ])]
11261 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11262 "*
11263 {
11264 arm_output_multireg_pop (operands, /*return_pc=*/false,
11265 /*cond=*/const_true_rtx,
11266 /*reverse=*/false,
11267 /*update=*/true);
11268 return \"\";
11269 }
11270 "
11271 [(set_attr "type" "load_16")
11272 (set_attr "predicable" "yes")
11273 (set (attr "length")
11274 (symbol_ref "arm_attr_length_pop_multi (operands,
11275 /*return_pc=*/false,
11276 /*write_back_p=*/true)"))]
11277 )
11278
11279 ;; Pop with return (as used in epilogue RTL)
11280 ;;
11281 ;; This instruction is generated when the registers are popped at the end of
11282 ;; epilogue. Here, instead of popping the value into LR and then generating
11283 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11284 ;; with (return).
11285 (define_insn "*pop_multiple_with_writeback_and_return"
11286 [(match_parallel 0 "pop_multiple_return"
11287 [(return)
11288 (set (match_operand:SI 1 "s_register_operand" "+rk")
11289 (plus:SI (match_dup 1)
11290 (match_operand:SI 2 "const_int_I_operand" "I")))
11291 (set (match_operand:SI 3 "s_register_operand" "=rk")
11292 (mem:SI (match_dup 1)))
11293 ])]
11294 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11295 "*
11296 {
11297 arm_output_multireg_pop (operands, /*return_pc=*/true,
11298 /*cond=*/const_true_rtx,
11299 /*reverse=*/false,
11300 /*update=*/true);
11301 return \"\";
11302 }
11303 "
11304 [(set_attr "type" "load_16")
11305 (set_attr "predicable" "yes")
11306 (set (attr "length")
11307 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11308 /*write_back_p=*/true)"))]
11309 )
11310
11311 (define_insn "*pop_multiple_with_return"
11312 [(match_parallel 0 "pop_multiple_return"
11313 [(return)
11314 (set (match_operand:SI 2 "s_register_operand" "=rk")
11315 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11316 ])]
11317 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11318 "*
11319 {
11320 arm_output_multireg_pop (operands, /*return_pc=*/true,
11321 /*cond=*/const_true_rtx,
11322 /*reverse=*/false,
11323 /*update=*/false);
11324 return \"\";
11325 }
11326 "
11327 [(set_attr "type" "load_16")
11328 (set_attr "predicable" "yes")
11329 (set (attr "length")
11330 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11331 /*write_back_p=*/false)"))]
11332 )
11333
11334 ;; Load into PC and return
11335 (define_insn "*ldr_with_return"
11336 [(return)
11337 (set (reg:SI PC_REGNUM)
11338 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11339 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11340 "ldr%?\t%|pc, [%0], #4"
11341 [(set_attr "type" "load_4")
11342 (set_attr "predicable" "yes")]
11343 )
11344 ;; Pop for floating point registers (as used in epilogue RTL)
11345 (define_insn "*vfp_pop_multiple_with_writeback"
11346 [(match_parallel 0 "pop_multiple_fp"
11347 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11348 (plus:SI (match_dup 1)
11349 (match_operand:SI 2 "const_int_I_operand" "I")))
11350 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11351 (mem:DF (match_dup 1)))])]
11352 "TARGET_32BIT && TARGET_HARD_FLOAT"
11353 "*
11354 {
11355 int num_regs = XVECLEN (operands[0], 0);
11356 char pattern[100];
11357 rtx op_list[2];
11358 strcpy (pattern, \"vldm\\t\");
11359 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11360 strcat (pattern, \"!, {\");
11361 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11362 strcat (pattern, \"%P0\");
11363 if ((num_regs - 1) > 1)
11364 {
11365 strcat (pattern, \"-%P1\");
11366 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11367 }
11368
11369 strcat (pattern, \"}\");
11370 output_asm_insn (pattern, op_list);
11371 return \"\";
11372 }
11373 "
11374 [(set_attr "type" "load_16")
11375 (set_attr "conds" "unconditional")
11376 (set_attr "predicable" "no")]
11377 )
11378
11379 ;; Special patterns for dealing with the constant pool
11380
11381 (define_insn "align_4"
11382 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11383 "TARGET_EITHER"
11384 "*
11385 assemble_align (32);
11386 return \"\";
11387 "
11388 [(set_attr "type" "no_insn")]
11389 )
11390
11391 (define_insn "align_8"
11392 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11393 "TARGET_EITHER"
11394 "*
11395 assemble_align (64);
11396 return \"\";
11397 "
11398 [(set_attr "type" "no_insn")]
11399 )
11400
11401 (define_insn "consttable_end"
11402 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11403 "TARGET_EITHER"
11404 "*
11405 making_const_table = FALSE;
11406 return \"\";
11407 "
11408 [(set_attr "type" "no_insn")]
11409 )
11410
11411 (define_insn "consttable_1"
11412 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11413 "TARGET_EITHER"
11414 "*
11415 making_const_table = TRUE;
11416 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11417 assemble_zeros (3);
11418 return \"\";
11419 "
11420 [(set_attr "length" "4")
11421 (set_attr "type" "no_insn")]
11422 )
11423
11424 (define_insn "consttable_2"
11425 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11426 "TARGET_EITHER"
11427 "*
11428 {
11429 rtx x = operands[0];
11430 making_const_table = TRUE;
11431 switch (GET_MODE_CLASS (GET_MODE (x)))
11432 {
11433 case MODE_FLOAT:
11434 arm_emit_fp16_const (x);
11435 break;
11436 default:
11437 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11438 assemble_zeros (2);
11439 break;
11440 }
11441 return \"\";
11442 }"
11443 [(set_attr "length" "4")
11444 (set_attr "type" "no_insn")]
11445 )
11446
11447 (define_insn "consttable_4"
11448 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11449 "TARGET_EITHER"
11450 "*
11451 {
11452 rtx x = operands[0];
11453 making_const_table = TRUE;
11454 scalar_float_mode float_mode;
11455 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11456 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11457 else
11458 {
11459 /* XXX: Sometimes gcc does something really dumb and ends up with
11460 a HIGH in a constant pool entry, usually because it's trying to
11461 load into a VFP register. We know this will always be used in
11462 combination with a LO_SUM which ignores the high bits, so just
11463 strip off the HIGH. */
11464 if (GET_CODE (x) == HIGH)
11465 x = XEXP (x, 0);
11466 assemble_integer (x, 4, BITS_PER_WORD, 1);
11467 mark_symbol_refs_as_used (x);
11468 }
11469 return \"\";
11470 }"
11471 [(set_attr "length" "4")
11472 (set_attr "type" "no_insn")]
11473 )
11474
11475 (define_insn "consttable_8"
11476 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11477 "TARGET_EITHER"
11478 "*
11479 {
11480 making_const_table = TRUE;
11481 scalar_float_mode float_mode;
11482 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11483 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11484 float_mode, BITS_PER_WORD);
11485 else
11486 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11487 return \"\";
11488 }"
11489 [(set_attr "length" "8")
11490 (set_attr "type" "no_insn")]
11491 )
11492
11493 (define_insn "consttable_16"
11494 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11495 "TARGET_EITHER"
11496 "*
11497 {
11498 making_const_table = TRUE;
11499 scalar_float_mode float_mode;
11500 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11501 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11502 float_mode, BITS_PER_WORD);
11503 else
11504 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11505 return \"\";
11506 }"
11507 [(set_attr "length" "16")
11508 (set_attr "type" "no_insn")]
11509 )
11510
11511 ;; V5 Instructions,
11512
11513 (define_insn "clzsi2"
11514 [(set (match_operand:SI 0 "s_register_operand" "=r")
11515 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11516 "TARGET_32BIT && arm_arch5t"
11517 "clz%?\\t%0, %1"
11518 [(set_attr "predicable" "yes")
11519 (set_attr "type" "clz")])
11520
11521 (define_insn "rbitsi2"
11522 [(set (match_operand:SI 0 "s_register_operand" "=r")
11523 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11524 "TARGET_32BIT && arm_arch_thumb2"
11525 "rbit%?\\t%0, %1"
11526 [(set_attr "predicable" "yes")
11527 (set_attr "type" "clz")])
11528
11529 ;; Keep this as a CTZ expression until after reload and then split
11530 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11531 ;; to fold with any other expression.
11532
11533 (define_insn_and_split "ctzsi2"
11534 [(set (match_operand:SI 0 "s_register_operand" "=r")
11535 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11536 "TARGET_32BIT && arm_arch_thumb2"
11537 "#"
11538 "&& reload_completed"
11539 [(const_int 0)]
11540 "
11541 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11542 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11543 DONE;
11544 ")
11545
11546 ;; V5E instructions.
11547
11548 (define_insn "prefetch"
11549 [(prefetch (match_operand:SI 0 "address_operand" "p")
11550 (match_operand:SI 1 "" "")
11551 (match_operand:SI 2 "" ""))]
11552 "TARGET_32BIT && arm_arch5te"
11553 "pld\\t%a0"
11554 [(set_attr "type" "load_4")]
11555 )
11556
11557 ;; General predication pattern
11558
11559 (define_cond_exec
11560 [(match_operator 0 "arm_comparison_operator"
11561 [(match_operand 1 "cc_register" "")
11562 (const_int 0)])]
11563 "TARGET_32BIT
11564 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11565 ""
11566 [(set_attr "predicated" "yes")]
11567 )
11568
11569 (define_insn "force_register_use"
11570 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11571 ""
11572 "%@ %0 needed"
11573 [(set_attr "length" "0")
11574 (set_attr "type" "no_insn")]
11575 )
11576
11577
11578 ;; Patterns for exception handling
11579
11580 (define_expand "eh_return"
11581 [(use (match_operand 0 "general_operand" ""))]
11582 "TARGET_EITHER"
11583 "
11584 {
11585 if (TARGET_32BIT)
11586 emit_insn (gen_arm_eh_return (operands[0]));
11587 else
11588 emit_insn (gen_thumb_eh_return (operands[0]));
11589 DONE;
11590 }"
11591 )
11592
11593 ;; We can't expand this before we know where the link register is stored.
11594 (define_insn_and_split "arm_eh_return"
11595 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11596 VUNSPEC_EH_RETURN)
11597 (clobber (match_scratch:SI 1 "=&r"))]
11598 "TARGET_ARM"
11599 "#"
11600 "&& reload_completed"
11601 [(const_int 0)]
11602 "
11603 {
11604 arm_set_return_address (operands[0], operands[1]);
11605 DONE;
11606 }"
11607 )
11608
11609 \f
11610 ;; TLS support
11611
11612 (define_insn "load_tp_hard"
11613 [(set (match_operand:SI 0 "register_operand" "=r")
11614 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11615 "TARGET_HARD_TP"
11616 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11617 [(set_attr "predicable" "yes")
11618 (set_attr "type" "mrs")]
11619 )
11620
11621 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11622 (define_insn "load_tp_soft"
11623 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11624 (clobber (reg:SI LR_REGNUM))
11625 (clobber (reg:SI IP_REGNUM))
11626 (clobber (reg:CC CC_REGNUM))]
11627 "TARGET_SOFT_TP"
11628 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11629 [(set_attr "conds" "clob")
11630 (set_attr "type" "branch")]
11631 )
11632
11633 ;; tls descriptor call
11634 (define_insn "tlscall"
11635 [(set (reg:SI R0_REGNUM)
11636 (unspec:SI [(reg:SI R0_REGNUM)
11637 (match_operand:SI 0 "" "X")
11638 (match_operand 1 "" "")] UNSPEC_TLS))
11639 (clobber (reg:SI R1_REGNUM))
11640 (clobber (reg:SI LR_REGNUM))
11641 (clobber (reg:SI CC_REGNUM))]
11642 "TARGET_GNU2_TLS"
11643 {
11644 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11645 INTVAL (operands[1]));
11646 return "bl\\t%c0(tlscall)";
11647 }
11648 [(set_attr "conds" "clob")
11649 (set_attr "length" "4")
11650 (set_attr "type" "branch")]
11651 )
11652
11653 ;; For thread pointer builtin
11654 (define_expand "get_thread_pointersi"
11655 [(match_operand:SI 0 "s_register_operand" "=r")]
11656 ""
11657 "
11658 {
11659 arm_load_tp (operands[0]);
11660 DONE;
11661 }")
11662
11663 ;;
11664
11665 ;; We only care about the lower 16 bits of the constant
11666 ;; being inserted into the upper 16 bits of the register.
11667 (define_insn "*arm_movtas_ze"
11668 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11669 (const_int 16)
11670 (const_int 16))
11671 (match_operand:SI 1 "const_int_operand" ""))]
11672 "TARGET_HAVE_MOVT"
11673 "@
11674 movt%?\t%0, %L1
11675 movt\t%0, %L1"
11676 [(set_attr "arch" "32,v8mb")
11677 (set_attr "predicable" "yes")
11678 (set_attr "length" "4")
11679 (set_attr "type" "alu_sreg")]
11680 )
11681
11682 (define_insn "*arm_rev"
11683 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11684 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11685 "arm_arch6"
11686 "@
11687 rev\t%0, %1
11688 rev%?\t%0, %1
11689 rev%?\t%0, %1"
11690 [(set_attr "arch" "t1,t2,32")
11691 (set_attr "length" "2,2,4")
11692 (set_attr "predicable" "no,yes,yes")
11693 (set_attr "type" "rev")]
11694 )
11695
11696 (define_expand "arm_legacy_rev"
11697 [(set (match_operand:SI 2 "s_register_operand" "")
11698 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11699 (const_int 16))
11700 (match_dup 1)))
11701 (set (match_dup 2)
11702 (lshiftrt:SI (match_dup 2)
11703 (const_int 8)))
11704 (set (match_operand:SI 3 "s_register_operand" "")
11705 (rotatert:SI (match_dup 1)
11706 (const_int 8)))
11707 (set (match_dup 2)
11708 (and:SI (match_dup 2)
11709 (const_int -65281)))
11710 (set (match_operand:SI 0 "s_register_operand" "")
11711 (xor:SI (match_dup 3)
11712 (match_dup 2)))]
11713 "TARGET_32BIT"
11714 ""
11715 )
11716
11717 ;; Reuse temporaries to keep register pressure down.
11718 (define_expand "thumb_legacy_rev"
11719 [(set (match_operand:SI 2 "s_register_operand" "")
11720 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11721 (const_int 24)))
11722 (set (match_operand:SI 3 "s_register_operand" "")
11723 (lshiftrt:SI (match_dup 1)
11724 (const_int 24)))
11725 (set (match_dup 3)
11726 (ior:SI (match_dup 3)
11727 (match_dup 2)))
11728 (set (match_operand:SI 4 "s_register_operand" "")
11729 (const_int 16))
11730 (set (match_operand:SI 5 "s_register_operand" "")
11731 (rotatert:SI (match_dup 1)
11732 (match_dup 4)))
11733 (set (match_dup 2)
11734 (ashift:SI (match_dup 5)
11735 (const_int 24)))
11736 (set (match_dup 5)
11737 (lshiftrt:SI (match_dup 5)
11738 (const_int 24)))
11739 (set (match_dup 5)
11740 (ior:SI (match_dup 5)
11741 (match_dup 2)))
11742 (set (match_dup 5)
11743 (rotatert:SI (match_dup 5)
11744 (match_dup 4)))
11745 (set (match_operand:SI 0 "s_register_operand" "")
11746 (ior:SI (match_dup 5)
11747 (match_dup 3)))]
11748 "TARGET_THUMB"
11749 ""
11750 )
11751
11752 ;; ARM-specific expansion of signed mod by power of 2
11753 ;; using conditional negate.
11754 ;; For r0 % n where n is a power of 2 produce:
11755 ;; rsbs r1, r0, #0
11756 ;; and r0, r0, #(n - 1)
11757 ;; and r1, r1, #(n - 1)
11758 ;; rsbpl r0, r1, #0
11759
11760 (define_expand "modsi3"
11761 [(match_operand:SI 0 "register_operand" "")
11762 (match_operand:SI 1 "register_operand" "")
11763 (match_operand:SI 2 "const_int_operand" "")]
11764 "TARGET_32BIT"
11765 {
11766 HOST_WIDE_INT val = INTVAL (operands[2]);
11767
11768 if (val <= 0
11769 || exact_log2 (val) <= 0)
11770 FAIL;
11771
11772 rtx mask = GEN_INT (val - 1);
11773
11774 /* In the special case of x0 % 2 we can do the even shorter:
11775 cmp r0, #0
11776 and r0, r0, #1
11777 rsblt r0, r0, #0. */
11778
11779 if (val == 2)
11780 {
11781 rtx cc_reg = arm_gen_compare_reg (LT,
11782 operands[1], const0_rtx, NULL_RTX);
11783 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11784 rtx masked = gen_reg_rtx (SImode);
11785
11786 emit_insn (gen_andsi3 (masked, operands[1], mask));
11787 emit_move_insn (operands[0],
11788 gen_rtx_IF_THEN_ELSE (SImode, cond,
11789 gen_rtx_NEG (SImode,
11790 masked),
11791 masked));
11792 DONE;
11793 }
11794
11795 rtx neg_op = gen_reg_rtx (SImode);
11796 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11797 operands[1]));
11798
11799 /* Extract the condition register and mode. */
11800 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11801 rtx cc_reg = SET_DEST (cmp);
11802 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11803
11804 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11805
11806 rtx masked_neg = gen_reg_rtx (SImode);
11807 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11808
11809 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11810 during expand does not always work. Do an IF_THEN_ELSE instead. */
11811 emit_move_insn (operands[0],
11812 gen_rtx_IF_THEN_ELSE (SImode, cond,
11813 gen_rtx_NEG (SImode, masked_neg),
11814 operands[0]));
11815
11816
11817 DONE;
11818 }
11819 )
11820
11821 (define_expand "bswapsi2"
11822 [(set (match_operand:SI 0 "s_register_operand" "=r")
11823 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11824 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11825 "
11826 if (!arm_arch6)
11827 {
11828 rtx op2 = gen_reg_rtx (SImode);
11829 rtx op3 = gen_reg_rtx (SImode);
11830
11831 if (TARGET_THUMB)
11832 {
11833 rtx op4 = gen_reg_rtx (SImode);
11834 rtx op5 = gen_reg_rtx (SImode);
11835
11836 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11837 op2, op3, op4, op5));
11838 }
11839 else
11840 {
11841 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11842 op2, op3));
11843 }
11844
11845 DONE;
11846 }
11847 "
11848 )
11849
11850 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11851 ;; and unsigned variants, respectively. For rev16, expose
11852 ;; byte-swapping in the lower 16 bits only.
11853 (define_insn "*arm_revsh"
11854 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11855 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11856 "arm_arch6"
11857 "@
11858 revsh\t%0, %1
11859 revsh%?\t%0, %1
11860 revsh%?\t%0, %1"
11861 [(set_attr "arch" "t1,t2,32")
11862 (set_attr "length" "2,2,4")
11863 (set_attr "type" "rev")]
11864 )
11865
11866 (define_insn "*arm_rev16"
11867 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11868 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11869 "arm_arch6"
11870 "@
11871 rev16\t%0, %1
11872 rev16%?\t%0, %1
11873 rev16%?\t%0, %1"
11874 [(set_attr "arch" "t1,t2,32")
11875 (set_attr "length" "2,2,4")
11876 (set_attr "type" "rev")]
11877 )
11878
11879 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11880 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11881 ;; each valid permutation.
11882
11883 (define_insn "arm_rev16si2"
11884 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11885 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11886 (const_int 8))
11887 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11888 (and:SI (lshiftrt:SI (match_dup 1)
11889 (const_int 8))
11890 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11891 "arm_arch6
11892 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11893 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11894 "rev16\\t%0, %1"
11895 [(set_attr "arch" "t1,t2,32")
11896 (set_attr "length" "2,2,4")
11897 (set_attr "type" "rev")]
11898 )
11899
11900 (define_insn "arm_rev16si2_alt"
11901 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11902 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11903 (const_int 8))
11904 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11905 (and:SI (ashift:SI (match_dup 1)
11906 (const_int 8))
11907 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11908 "arm_arch6
11909 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11910 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11911 "rev16\\t%0, %1"
11912 [(set_attr "arch" "t1,t2,32")
11913 (set_attr "length" "2,2,4")
11914 (set_attr "type" "rev")]
11915 )
11916
11917 (define_expand "bswaphi2"
11918 [(set (match_operand:HI 0 "s_register_operand" "=r")
11919 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11920 "arm_arch6"
11921 ""
11922 )
11923
11924 ;; Patterns for LDRD/STRD in Thumb2 mode
11925
11926 (define_insn "*thumb2_ldrd"
11927 [(set (match_operand:SI 0 "s_register_operand" "=r")
11928 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11929 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11930 (set (match_operand:SI 3 "s_register_operand" "=r")
11931 (mem:SI (plus:SI (match_dup 1)
11932 (match_operand:SI 4 "const_int_operand" ""))))]
11933 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11934 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11935 && (operands_ok_ldrd_strd (operands[0], operands[3],
11936 operands[1], INTVAL (operands[2]),
11937 false, true))"
11938 "ldrd%?\t%0, %3, [%1, %2]"
11939 [(set_attr "type" "load_8")
11940 (set_attr "predicable" "yes")])
11941
11942 (define_insn "*thumb2_ldrd_base"
11943 [(set (match_operand:SI 0 "s_register_operand" "=r")
11944 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11945 (set (match_operand:SI 2 "s_register_operand" "=r")
11946 (mem:SI (plus:SI (match_dup 1)
11947 (const_int 4))))]
11948 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11949 && (operands_ok_ldrd_strd (operands[0], operands[2],
11950 operands[1], 0, false, true))"
11951 "ldrd%?\t%0, %2, [%1]"
11952 [(set_attr "type" "load_8")
11953 (set_attr "predicable" "yes")])
11954
11955 (define_insn "*thumb2_ldrd_base_neg"
11956 [(set (match_operand:SI 0 "s_register_operand" "=r")
11957 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11958 (const_int -4))))
11959 (set (match_operand:SI 2 "s_register_operand" "=r")
11960 (mem:SI (match_dup 1)))]
11961 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11962 && (operands_ok_ldrd_strd (operands[0], operands[2],
11963 operands[1], -4, false, true))"
11964 "ldrd%?\t%0, %2, [%1, #-4]"
11965 [(set_attr "type" "load_8")
11966 (set_attr "predicable" "yes")])
11967
11968 (define_insn "*thumb2_strd"
11969 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11970 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11971 (match_operand:SI 2 "s_register_operand" "r"))
11972 (set (mem:SI (plus:SI (match_dup 0)
11973 (match_operand:SI 3 "const_int_operand" "")))
11974 (match_operand:SI 4 "s_register_operand" "r"))]
11975 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11976 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11977 && (operands_ok_ldrd_strd (operands[2], operands[4],
11978 operands[0], INTVAL (operands[1]),
11979 false, false))"
11980 "strd%?\t%2, %4, [%0, %1]"
11981 [(set_attr "type" "store_8")
11982 (set_attr "predicable" "yes")])
11983
11984 (define_insn "*thumb2_strd_base"
11985 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11986 (match_operand:SI 1 "s_register_operand" "r"))
11987 (set (mem:SI (plus:SI (match_dup 0)
11988 (const_int 4)))
11989 (match_operand:SI 2 "s_register_operand" "r"))]
11990 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11991 && (operands_ok_ldrd_strd (operands[1], operands[2],
11992 operands[0], 0, false, false))"
11993 "strd%?\t%1, %2, [%0]"
11994 [(set_attr "type" "store_8")
11995 (set_attr "predicable" "yes")])
11996
11997 (define_insn "*thumb2_strd_base_neg"
11998 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11999 (const_int -4)))
12000 (match_operand:SI 1 "s_register_operand" "r"))
12001 (set (mem:SI (match_dup 0))
12002 (match_operand:SI 2 "s_register_operand" "r"))]
12003 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12004 && (operands_ok_ldrd_strd (operands[1], operands[2],
12005 operands[0], -4, false, false))"
12006 "strd%?\t%1, %2, [%0, #-4]"
12007 [(set_attr "type" "store_8")
12008 (set_attr "predicable" "yes")])
12009
12010 ;; ARMv8 CRC32 instructions.
12011 (define_insn "<crc_variant>"
12012 [(set (match_operand:SI 0 "s_register_operand" "=r")
12013 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
12014 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
12015 CRC))]
12016 "TARGET_CRC32"
12017 "<crc_variant>\\t%0, %1, %2"
12018 [(set_attr "type" "crc")
12019 (set_attr "conds" "unconditional")]
12020 )
12021
12022 ;; Load the load/store double peephole optimizations.
12023 (include "ldrdstrd.md")
12024
12025 ;; Load the load/store multiple patterns
12026 (include "ldmstm.md")
12027
12028 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12029 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12030 ;; The operands are validated through the load_multiple_operation
12031 ;; match_parallel predicate rather than through constraints so enable it only
12032 ;; after reload.
12033 (define_insn "*load_multiple"
12034 [(match_parallel 0 "load_multiple_operation"
12035 [(set (match_operand:SI 2 "s_register_operand" "=rk")
12036 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12037 ])]
12038 "TARGET_32BIT && reload_completed"
12039 "*
12040 {
12041 arm_output_multireg_pop (operands, /*return_pc=*/false,
12042 /*cond=*/const_true_rtx,
12043 /*reverse=*/false,
12044 /*update=*/false);
12045 return \"\";
12046 }
12047 "
12048 [(set_attr "predicable" "yes")]
12049 )
12050
12051 (define_expand "copysignsf3"
12052 [(match_operand:SF 0 "register_operand")
12053 (match_operand:SF 1 "register_operand")
12054 (match_operand:SF 2 "register_operand")]
12055 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12056 "{
12057 emit_move_insn (operands[0], operands[2]);
12058 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
12059 GEN_INT (31), GEN_INT (0),
12060 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
12061 DONE;
12062 }"
12063 )
12064
12065 (define_expand "copysigndf3"
12066 [(match_operand:DF 0 "register_operand")
12067 (match_operand:DF 1 "register_operand")
12068 (match_operand:DF 2 "register_operand")]
12069 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12070 "{
12071 rtx op0_low = gen_lowpart (SImode, operands[0]);
12072 rtx op0_high = gen_highpart (SImode, operands[0]);
12073 rtx op1_low = gen_lowpart (SImode, operands[1]);
12074 rtx op1_high = gen_highpart (SImode, operands[1]);
12075 rtx op2_high = gen_highpart (SImode, operands[2]);
12076
12077 rtx scratch1 = gen_reg_rtx (SImode);
12078 rtx scratch2 = gen_reg_rtx (SImode);
12079 emit_move_insn (scratch1, op2_high);
12080 emit_move_insn (scratch2, op1_high);
12081
12082 emit_insn(gen_rtx_SET(scratch1,
12083 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
12084 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
12085 emit_move_insn (op0_low, op1_low);
12086 emit_move_insn (op0_high, scratch2);
12087
12088 DONE;
12089 }"
12090 )
12091
12092 ;; movmisalign patterns for HImode and SImode.
12093 (define_expand "movmisalign<mode>"
12094 [(match_operand:HSI 0 "general_operand")
12095 (match_operand:HSI 1 "general_operand")]
12096 "unaligned_access"
12097 {
12098 /* This pattern is not permitted to fail during expansion: if both arguments
12099 are non-registers (e.g. memory := constant), force operand 1 into a
12100 register. */
12101 rtx (* gen_unaligned_load)(rtx, rtx);
12102 rtx tmp_dest = operands[0];
12103 if (!s_register_operand (operands[0], <MODE>mode)
12104 && !s_register_operand (operands[1], <MODE>mode))
12105 operands[1] = force_reg (<MODE>mode, operands[1]);
12106
12107 if (<MODE>mode == HImode)
12108 {
12109 gen_unaligned_load = gen_unaligned_loadhiu;
12110 tmp_dest = gen_reg_rtx (SImode);
12111 }
12112 else
12113 gen_unaligned_load = gen_unaligned_loadsi;
12114
12115 if (MEM_P (operands[1]))
12116 {
12117 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
12118 if (<MODE>mode == HImode)
12119 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
12120 }
12121 else
12122 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
12123
12124 DONE;
12125 })
12126
12127 (define_insn "<cdp>"
12128 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12129 (match_operand:SI 1 "immediate_operand" "n")
12130 (match_operand:SI 2 "immediate_operand" "n")
12131 (match_operand:SI 3 "immediate_operand" "n")
12132 (match_operand:SI 4 "immediate_operand" "n")
12133 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
12134 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
12135 {
12136 arm_const_bounds (operands[0], 0, 16);
12137 arm_const_bounds (operands[1], 0, 16);
12138 arm_const_bounds (operands[2], 0, (1 << 5));
12139 arm_const_bounds (operands[3], 0, (1 << 5));
12140 arm_const_bounds (operands[4], 0, (1 << 5));
12141 arm_const_bounds (operands[5], 0, 8);
12142 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
12143 }
12144 [(set_attr "length" "4")
12145 (set_attr "type" "coproc")])
12146
12147 (define_insn "*ldc"
12148 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12149 (match_operand:SI 1 "immediate_operand" "n")
12150 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
12151 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
12152 {
12153 arm_const_bounds (operands[0], 0, 16);
12154 arm_const_bounds (operands[1], 0, (1 << 5));
12155 return "<ldc>\\tp%c0, CR%c1, %2";
12156 }
12157 [(set_attr "length" "4")
12158 (set_attr "type" "coproc")])
12159
12160 (define_insn "*stc"
12161 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12162 (match_operand:SI 1 "immediate_operand" "n")
12163 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
12164 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
12165 {
12166 arm_const_bounds (operands[0], 0, 16);
12167 arm_const_bounds (operands[1], 0, (1 << 5));
12168 return "<stc>\\tp%c0, CR%c1, %2";
12169 }
12170 [(set_attr "length" "4")
12171 (set_attr "type" "coproc")])
12172
12173 (define_expand "<ldc>"
12174 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12175 (match_operand:SI 1 "immediate_operand")
12176 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
12177 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
12178
12179 (define_expand "<stc>"
12180 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12181 (match_operand:SI 1 "immediate_operand")
12182 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12183 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12184
12185 (define_insn "<mcr>"
12186 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12187 (match_operand:SI 1 "immediate_operand" "n")
12188 (match_operand:SI 2 "s_register_operand" "r")
12189 (match_operand:SI 3 "immediate_operand" "n")
12190 (match_operand:SI 4 "immediate_operand" "n")
12191 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12192 (use (match_dup 2))]
12193 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12194 {
12195 arm_const_bounds (operands[0], 0, 16);
12196 arm_const_bounds (operands[1], 0, 8);
12197 arm_const_bounds (operands[3], 0, (1 << 5));
12198 arm_const_bounds (operands[4], 0, (1 << 5));
12199 arm_const_bounds (operands[5], 0, 8);
12200 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12201 }
12202 [(set_attr "length" "4")
12203 (set_attr "type" "coproc")])
12204
12205 (define_insn "<mrc>"
12206 [(set (match_operand:SI 0 "s_register_operand" "=r")
12207 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12208 (match_operand:SI 2 "immediate_operand" "n")
12209 (match_operand:SI 3 "immediate_operand" "n")
12210 (match_operand:SI 4 "immediate_operand" "n")
12211 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12212 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12213 {
12214 arm_const_bounds (operands[1], 0, 16);
12215 arm_const_bounds (operands[2], 0, 8);
12216 arm_const_bounds (operands[3], 0, (1 << 5));
12217 arm_const_bounds (operands[4], 0, (1 << 5));
12218 arm_const_bounds (operands[5], 0, 8);
12219 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12220 }
12221 [(set_attr "length" "4")
12222 (set_attr "type" "coproc")])
12223
12224 (define_insn "<mcrr>"
12225 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12226 (match_operand:SI 1 "immediate_operand" "n")
12227 (match_operand:DI 2 "s_register_operand" "r")
12228 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12229 (use (match_dup 2))]
12230 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12231 {
12232 arm_const_bounds (operands[0], 0, 16);
12233 arm_const_bounds (operands[1], 0, 8);
12234 arm_const_bounds (operands[3], 0, (1 << 5));
12235 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12236 }
12237 [(set_attr "length" "4")
12238 (set_attr "type" "coproc")])
12239
12240 (define_insn "<mrrc>"
12241 [(set (match_operand:DI 0 "s_register_operand" "=r")
12242 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12243 (match_operand:SI 2 "immediate_operand" "n")
12244 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12245 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12246 {
12247 arm_const_bounds (operands[1], 0, 16);
12248 arm_const_bounds (operands[2], 0, 8);
12249 arm_const_bounds (operands[3], 0, (1 << 5));
12250 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12251 }
12252 [(set_attr "length" "4")
12253 (set_attr "type" "coproc")])
12254
12255 (define_expand "speculation_barrier"
12256 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12257 "TARGET_EITHER"
12258 "
12259 /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
12260 have a usable barrier (and probably don't need one in practice).
12261 But to be safe if such code is run on later architectures, call a
12262 helper function in libgcc that will do the thing for the active
12263 system. */
12264 if (!(arm_arch7 || arm_arch8))
12265 {
12266 arm_emit_speculation_barrier_function ();
12267 DONE;
12268 }
12269 "
12270 )
12271
12272 ;; Generate a hard speculation barrier when we have not enabled speculation
12273 ;; tracking.
12274 (define_insn "*speculation_barrier_insn"
12275 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12276 "arm_arch7 || arm_arch8"
12277 "isb\;dsb\\tsy"
12278 [(set_attr "type" "block")
12279 (set_attr "length" "8")]
12280 )
12281
12282 ;; Vector bits common to IWMMXT and Neon
12283 (include "vec-common.md")
12284 ;; Load the Intel Wireless Multimedia Extension patterns
12285 (include "iwmmxt.md")
12286 ;; Load the VFP co-processor patterns
12287 (include "vfp.md")
12288 ;; Thumb-1 patterns
12289 (include "thumb1.md")
12290 ;; Thumb-2 patterns
12291 (include "thumb2.md")
12292 ;; Neon patterns
12293 (include "neon.md")
12294 ;; Crypto patterns
12295 (include "crypto.md")
12296 ;; Synchronization Primitives
12297 (include "sync.md")
12298 ;; Fixed-point patterns
12299 (include "arm-fixed.md")