]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm.md
[ARM] Do no clobber r4 in Armv8-M nonsecure call
[thirdparty/gcc.git] / gcc / config / arm / arm.md
1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2017 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 can not 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,arm1020e,arm1026ejs,arm1136js,\
388 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389 cortexa9,cortexa12,cortexa15,cortexa17,\
390 cortexa53,cortexa57,cortexm4,cortexm7,\
391 exynosm1,marvell_pj4,xgene1")
392 (eq_attr "tune_cortexr4" "yes"))
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" "!arm1020e,arm1022e,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 && arm_arch3m"
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_arch3m && !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 && arm_arch3m"
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_arch3m && !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 && arm_arch3m"
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_arch3m && !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 && arm_arch3m"
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_arch3m && !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 && arm_arch3m"
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_arch3m && !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 && arm_arch3m"
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_arch3m && !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" "=l,r")
4464 (sign_extend:SI
4465 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4466 UNSPEC_UNALIGNED_LOAD)))]
4467 "unaligned_access"
4468 "ldrsh%?\t%0, %1\t@ unaligned"
4469 [(set_attr "arch" "t2,any")
4470 (set_attr "length" "2,4")
4471 (set_attr "predicable" "yes")
4472 (set_attr "predicable_short_it" "yes,no")
4473 (set_attr "type" "load_byte")])
4474
4475 (define_insn "unaligned_loadhiu"
4476 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4477 (zero_extend:SI
4478 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4479 UNSPEC_UNALIGNED_LOAD)))]
4480 "unaligned_access"
4481 "ldrh%?\t%0, %1\t@ unaligned"
4482 [(set_attr "arch" "t2,any")
4483 (set_attr "length" "2,4")
4484 (set_attr "predicable" "yes")
4485 (set_attr "predicable_short_it" "yes,no")
4486 (set_attr "type" "load_byte")])
4487
4488 (define_insn "unaligned_storesi"
4489 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4490 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4491 UNSPEC_UNALIGNED_STORE))]
4492 "unaligned_access"
4493 "str%?\t%1, %0\t@ unaligned"
4494 [(set_attr "arch" "t2,any")
4495 (set_attr "length" "2,4")
4496 (set_attr "predicable" "yes")
4497 (set_attr "predicable_short_it" "yes,no")
4498 (set_attr "type" "store_4")])
4499
4500 (define_insn "unaligned_storehi"
4501 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4502 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4503 UNSPEC_UNALIGNED_STORE))]
4504 "unaligned_access"
4505 "strh%?\t%1, %0\t@ unaligned"
4506 [(set_attr "arch" "t2,any")
4507 (set_attr "length" "2,4")
4508 (set_attr "predicable" "yes")
4509 (set_attr "predicable_short_it" "yes,no")
4510 (set_attr "type" "store_4")])
4511
4512
4513 (define_insn "*extv_reg"
4514 [(set (match_operand:SI 0 "s_register_operand" "=r")
4515 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4516 (match_operand:SI 2 "const_int_operand" "n")
4517 (match_operand:SI 3 "const_int_operand" "n")))]
4518 "arm_arch_thumb2
4519 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4520 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4521 "sbfx%?\t%0, %1, %3, %2"
4522 [(set_attr "length" "4")
4523 (set_attr "predicable" "yes")
4524 (set_attr "type" "bfm")]
4525 )
4526
4527 (define_insn "extzv_t2"
4528 [(set (match_operand:SI 0 "s_register_operand" "=r")
4529 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4530 (match_operand:SI 2 "const_int_operand" "n")
4531 (match_operand:SI 3 "const_int_operand" "n")))]
4532 "arm_arch_thumb2
4533 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4534 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4535 "ubfx%?\t%0, %1, %3, %2"
4536 [(set_attr "length" "4")
4537 (set_attr "predicable" "yes")
4538 (set_attr "type" "bfm")]
4539 )
4540
4541
4542 ;; Division instructions
4543 (define_insn "divsi3"
4544 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4545 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4546 (match_operand:SI 2 "s_register_operand" "r,r")))]
4547 "TARGET_IDIV"
4548 "@
4549 sdiv%?\t%0, %1, %2
4550 sdiv\t%0, %1, %2"
4551 [(set_attr "arch" "32,v8mb")
4552 (set_attr "predicable" "yes")
4553 (set_attr "type" "sdiv")]
4554 )
4555
4556 (define_insn "udivsi3"
4557 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4558 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4559 (match_operand:SI 2 "s_register_operand" "r,r")))]
4560 "TARGET_IDIV"
4561 "@
4562 udiv%?\t%0, %1, %2
4563 udiv\t%0, %1, %2"
4564 [(set_attr "arch" "32,v8mb")
4565 (set_attr "predicable" "yes")
4566 (set_attr "type" "udiv")]
4567 )
4568
4569 \f
4570 ;; Unary arithmetic insns
4571
4572 (define_expand "negvsi3"
4573 [(match_operand:SI 0 "register_operand")
4574 (match_operand:SI 1 "register_operand")
4575 (match_operand 2 "")]
4576 "TARGET_32BIT"
4577 {
4578 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4579 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4580
4581 DONE;
4582 })
4583
4584 (define_expand "negvdi3"
4585 [(match_operand:DI 0 "register_operand")
4586 (match_operand:DI 1 "register_operand")
4587 (match_operand 2 "")]
4588 "TARGET_ARM"
4589 {
4590 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4591 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4592
4593 DONE;
4594 })
4595
4596
4597 (define_insn_and_split "negdi2_compare"
4598 [(set (reg:CC CC_REGNUM)
4599 (compare:CC
4600 (const_int 0)
4601 (match_operand:DI 1 "register_operand" "0,r")))
4602 (set (match_operand:DI 0 "register_operand" "=r,&r")
4603 (minus:DI (const_int 0) (match_dup 1)))]
4604 "TARGET_ARM"
4605 "#"
4606 "&& reload_completed"
4607 [(parallel [(set (reg:CC CC_REGNUM)
4608 (compare:CC (const_int 0) (match_dup 1)))
4609 (set (match_dup 0) (minus:SI (const_int 0)
4610 (match_dup 1)))])
4611 (parallel [(set (reg:CC CC_REGNUM)
4612 (compare:CC (const_int 0) (match_dup 3)))
4613 (set (match_dup 2)
4614 (minus:SI
4615 (minus:SI (const_int 0) (match_dup 3))
4616 (ltu:SI (reg:CC_C CC_REGNUM)
4617 (const_int 0))))])]
4618 {
4619 operands[2] = gen_highpart (SImode, operands[0]);
4620 operands[0] = gen_lowpart (SImode, operands[0]);
4621 operands[3] = gen_highpart (SImode, operands[1]);
4622 operands[1] = gen_lowpart (SImode, operands[1]);
4623 }
4624 [(set_attr "conds" "set")
4625 (set_attr "length" "8")
4626 (set_attr "type" "multiple")]
4627 )
4628
4629 (define_expand "negdi2"
4630 [(parallel
4631 [(set (match_operand:DI 0 "s_register_operand" "")
4632 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4633 (clobber (reg:CC CC_REGNUM))])]
4634 "TARGET_EITHER"
4635 {
4636 if (TARGET_NEON)
4637 {
4638 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4639 DONE;
4640 }
4641 }
4642 )
4643
4644 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4645 ;; The first alternative allows the common case of a *full* overlap.
4646 (define_insn_and_split "*negdi2_insn"
4647 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4648 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4649 (clobber (reg:CC CC_REGNUM))]
4650 "TARGET_32BIT"
4651 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4652 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4653 "&& reload_completed"
4654 [(parallel [(set (reg:CC CC_REGNUM)
4655 (compare:CC (const_int 0) (match_dup 1)))
4656 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4657 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4658 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4659 {
4660 operands[2] = gen_highpart (SImode, operands[0]);
4661 operands[0] = gen_lowpart (SImode, operands[0]);
4662 operands[3] = gen_highpart (SImode, operands[1]);
4663 operands[1] = gen_lowpart (SImode, operands[1]);
4664 }
4665 [(set_attr "conds" "clob")
4666 (set_attr "length" "8")
4667 (set_attr "type" "multiple")]
4668 )
4669
4670 (define_insn "*negsi2_carryin_compare"
4671 [(set (reg:CC CC_REGNUM)
4672 (compare:CC (const_int 0)
4673 (match_operand:SI 1 "s_register_operand" "r")))
4674 (set (match_operand:SI 0 "s_register_operand" "=r")
4675 (minus:SI (minus:SI (const_int 0)
4676 (match_dup 1))
4677 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4678 "TARGET_ARM"
4679 "rscs\\t%0, %1, #0"
4680 [(set_attr "conds" "set")
4681 (set_attr "type" "alus_imm")]
4682 )
4683
4684 (define_expand "negsi2"
4685 [(set (match_operand:SI 0 "s_register_operand" "")
4686 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4687 "TARGET_EITHER"
4688 ""
4689 )
4690
4691 (define_insn "*arm_negsi2"
4692 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4693 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4694 "TARGET_32BIT"
4695 "rsb%?\\t%0, %1, #0"
4696 [(set_attr "predicable" "yes")
4697 (set_attr "predicable_short_it" "yes,no")
4698 (set_attr "arch" "t2,*")
4699 (set_attr "length" "4")
4700 (set_attr "type" "alu_sreg")]
4701 )
4702
4703 (define_expand "negsf2"
4704 [(set (match_operand:SF 0 "s_register_operand" "")
4705 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4706 "TARGET_32BIT && TARGET_HARD_FLOAT"
4707 ""
4708 )
4709
4710 (define_expand "negdf2"
4711 [(set (match_operand:DF 0 "s_register_operand" "")
4712 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4713 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4714 "")
4715
4716 (define_insn_and_split "*zextendsidi_negsi"
4717 [(set (match_operand:DI 0 "s_register_operand" "=r")
4718 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4719 "TARGET_32BIT"
4720 "#"
4721 ""
4722 [(set (match_dup 2)
4723 (neg:SI (match_dup 1)))
4724 (set (match_dup 3)
4725 (const_int 0))]
4726 {
4727 operands[2] = gen_lowpart (SImode, operands[0]);
4728 operands[3] = gen_highpart (SImode, operands[0]);
4729 }
4730 [(set_attr "length" "8")
4731 (set_attr "type" "multiple")]
4732 )
4733
4734 ;; Negate an extended 32-bit value.
4735 (define_insn_and_split "*negdi_extendsidi"
4736 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4737 (neg:DI (sign_extend:DI
4738 (match_operand:SI 1 "s_register_operand" "l,r"))))
4739 (clobber (reg:CC CC_REGNUM))]
4740 "TARGET_32BIT"
4741 "#"
4742 "&& reload_completed"
4743 [(const_int 0)]
4744 {
4745 rtx low = gen_lowpart (SImode, operands[0]);
4746 rtx high = gen_highpart (SImode, operands[0]);
4747
4748 if (reg_overlap_mentioned_p (low, operands[1]))
4749 {
4750 /* Input overlaps the low word of the output. Use:
4751 asr Rhi, Rin, #31
4752 rsbs Rlo, Rin, #0
4753 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4754 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4755
4756 emit_insn (gen_rtx_SET (high,
4757 gen_rtx_ASHIFTRT (SImode, operands[1],
4758 GEN_INT (31))));
4759
4760 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4761 if (TARGET_ARM)
4762 emit_insn (gen_rtx_SET (high,
4763 gen_rtx_MINUS (SImode,
4764 gen_rtx_MINUS (SImode,
4765 const0_rtx,
4766 high),
4767 gen_rtx_LTU (SImode,
4768 cc_reg,
4769 const0_rtx))));
4770 else
4771 {
4772 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4773 emit_insn (gen_rtx_SET (high,
4774 gen_rtx_MINUS (SImode,
4775 gen_rtx_MINUS (SImode,
4776 high,
4777 two_x),
4778 gen_rtx_LTU (SImode,
4779 cc_reg,
4780 const0_rtx))));
4781 }
4782 }
4783 else
4784 {
4785 /* No overlap, or overlap on high word. Use:
4786 rsb Rlo, Rin, #0
4787 bic Rhi, Rlo, Rin
4788 asr Rhi, Rhi, #31
4789 Flags not needed for this sequence. */
4790 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4791 emit_insn (gen_rtx_SET (high,
4792 gen_rtx_AND (SImode,
4793 gen_rtx_NOT (SImode, operands[1]),
4794 low)));
4795 emit_insn (gen_rtx_SET (high,
4796 gen_rtx_ASHIFTRT (SImode, high,
4797 GEN_INT (31))));
4798 }
4799 DONE;
4800 }
4801 [(set_attr "length" "12")
4802 (set_attr "arch" "t2,*")
4803 (set_attr "type" "multiple")]
4804 )
4805
4806 (define_insn_and_split "*negdi_zero_extendsidi"
4807 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4808 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4809 (clobber (reg:CC CC_REGNUM))]
4810 "TARGET_32BIT"
4811 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4812 ;; Don't care what register is input to sbc,
4813 ;; since we just need to propagate the carry.
4814 "&& reload_completed"
4815 [(parallel [(set (reg:CC CC_REGNUM)
4816 (compare:CC (const_int 0) (match_dup 1)))
4817 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4818 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4819 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4820 {
4821 operands[2] = gen_highpart (SImode, operands[0]);
4822 operands[0] = gen_lowpart (SImode, operands[0]);
4823 }
4824 [(set_attr "conds" "clob")
4825 (set_attr "length" "8")
4826 (set_attr "type" "multiple")] ;; length in thumb is 4
4827 )
4828
4829 ;; abssi2 doesn't really clobber the condition codes if a different register
4830 ;; is being set. To keep things simple, assume during rtl manipulations that
4831 ;; it does, but tell the final scan operator the truth. Similarly for
4832 ;; (neg (abs...))
4833
4834 (define_expand "abssi2"
4835 [(parallel
4836 [(set (match_operand:SI 0 "s_register_operand" "")
4837 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4838 (clobber (match_dup 2))])]
4839 "TARGET_EITHER"
4840 "
4841 if (TARGET_THUMB1)
4842 operands[2] = gen_rtx_SCRATCH (SImode);
4843 else
4844 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4845 ")
4846
4847 (define_insn_and_split "*arm_abssi2"
4848 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4849 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4850 (clobber (reg:CC CC_REGNUM))]
4851 "TARGET_ARM"
4852 "#"
4853 "&& reload_completed"
4854 [(const_int 0)]
4855 {
4856 /* if (which_alternative == 0) */
4857 if (REGNO(operands[0]) == REGNO(operands[1]))
4858 {
4859 /* Emit the pattern:
4860 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4861 [(set (reg:CC CC_REGNUM)
4862 (compare:CC (match_dup 0) (const_int 0)))
4863 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4864 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4865 */
4866 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4867 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4868 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4869 (gen_rtx_LT (SImode,
4870 gen_rtx_REG (CCmode, CC_REGNUM),
4871 const0_rtx)),
4872 (gen_rtx_SET (operands[0],
4873 (gen_rtx_MINUS (SImode,
4874 const0_rtx,
4875 operands[1]))))));
4876 DONE;
4877 }
4878 else
4879 {
4880 /* Emit the pattern:
4881 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4882 [(set (match_dup 0)
4883 (xor:SI (match_dup 1)
4884 (ashiftrt:SI (match_dup 1) (const_int 31))))
4885 (set (match_dup 0)
4886 (minus:SI (match_dup 0)
4887 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4888 */
4889 emit_insn (gen_rtx_SET (operands[0],
4890 gen_rtx_XOR (SImode,
4891 gen_rtx_ASHIFTRT (SImode,
4892 operands[1],
4893 GEN_INT (31)),
4894 operands[1])));
4895 emit_insn (gen_rtx_SET (operands[0],
4896 gen_rtx_MINUS (SImode,
4897 operands[0],
4898 gen_rtx_ASHIFTRT (SImode,
4899 operands[1],
4900 GEN_INT (31)))));
4901 DONE;
4902 }
4903 }
4904 [(set_attr "conds" "clob,*")
4905 (set_attr "shift" "1")
4906 (set_attr "predicable" "no, yes")
4907 (set_attr "length" "8")
4908 (set_attr "type" "multiple")]
4909 )
4910
4911 (define_insn_and_split "*arm_neg_abssi2"
4912 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4913 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4914 (clobber (reg:CC CC_REGNUM))]
4915 "TARGET_ARM"
4916 "#"
4917 "&& reload_completed"
4918 [(const_int 0)]
4919 {
4920 /* if (which_alternative == 0) */
4921 if (REGNO (operands[0]) == REGNO (operands[1]))
4922 {
4923 /* Emit the pattern:
4924 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4925 */
4926 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4927 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4928 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4929 gen_rtx_GT (SImode,
4930 gen_rtx_REG (CCmode, CC_REGNUM),
4931 const0_rtx),
4932 gen_rtx_SET (operands[0],
4933 (gen_rtx_MINUS (SImode,
4934 const0_rtx,
4935 operands[1])))));
4936 }
4937 else
4938 {
4939 /* Emit the pattern:
4940 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4941 */
4942 emit_insn (gen_rtx_SET (operands[0],
4943 gen_rtx_XOR (SImode,
4944 gen_rtx_ASHIFTRT (SImode,
4945 operands[1],
4946 GEN_INT (31)),
4947 operands[1])));
4948 emit_insn (gen_rtx_SET (operands[0],
4949 gen_rtx_MINUS (SImode,
4950 gen_rtx_ASHIFTRT (SImode,
4951 operands[1],
4952 GEN_INT (31)),
4953 operands[0])));
4954 }
4955 DONE;
4956 }
4957 [(set_attr "conds" "clob,*")
4958 (set_attr "shift" "1")
4959 (set_attr "predicable" "no, yes")
4960 (set_attr "length" "8")
4961 (set_attr "type" "multiple")]
4962 )
4963
4964 (define_expand "abssf2"
4965 [(set (match_operand:SF 0 "s_register_operand" "")
4966 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4967 "TARGET_32BIT && TARGET_HARD_FLOAT"
4968 "")
4969
4970 (define_expand "absdf2"
4971 [(set (match_operand:DF 0 "s_register_operand" "")
4972 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4973 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4974 "")
4975
4976 (define_expand "sqrtsf2"
4977 [(set (match_operand:SF 0 "s_register_operand" "")
4978 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4979 "TARGET_32BIT && TARGET_HARD_FLOAT"
4980 "")
4981
4982 (define_expand "sqrtdf2"
4983 [(set (match_operand:DF 0 "s_register_operand" "")
4984 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
4985 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4986 "")
4987
4988 (define_expand "one_cmpldi2"
4989 [(set (match_operand:DI 0 "s_register_operand" "")
4990 (not:DI (match_operand:DI 1 "s_register_operand" "")))]
4991 "TARGET_32BIT"
4992 "
4993 if (!TARGET_NEON && !TARGET_IWMMXT)
4994 {
4995 rtx low = simplify_gen_unary (NOT, SImode,
4996 gen_lowpart (SImode, operands[1]),
4997 SImode);
4998 rtx high = simplify_gen_unary (NOT, SImode,
4999 gen_highpart_mode (SImode, DImode,
5000 operands[1]),
5001 SImode);
5002
5003 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5004 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5005
5006 DONE;
5007 }
5008 /* Otherwise expand pattern as above. */
5009 "
5010 )
5011
5012 (define_insn_and_split "*one_cmpldi2_insn"
5013 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5014 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5015 "TARGET_32BIT"
5016 "@
5017 vmvn\t%P0, %P1
5018 #
5019 #
5020 vmvn\t%P0, %P1"
5021 "TARGET_32BIT && reload_completed
5022 && arm_general_register_operand (operands[0], DImode)"
5023 [(set (match_dup 0) (not:SI (match_dup 1)))
5024 (set (match_dup 2) (not:SI (match_dup 3)))]
5025 "
5026 {
5027 operands[2] = gen_highpart (SImode, operands[0]);
5028 operands[0] = gen_lowpart (SImode, operands[0]);
5029 operands[3] = gen_highpart (SImode, operands[1]);
5030 operands[1] = gen_lowpart (SImode, operands[1]);
5031 }"
5032 [(set_attr "length" "*,8,8,*")
5033 (set_attr "predicable" "no,yes,yes,no")
5034 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5035 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5036 )
5037
5038 (define_expand "one_cmplsi2"
5039 [(set (match_operand:SI 0 "s_register_operand" "")
5040 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5041 "TARGET_EITHER"
5042 ""
5043 )
5044
5045 (define_insn "*arm_one_cmplsi2"
5046 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5047 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5048 "TARGET_32BIT"
5049 "mvn%?\\t%0, %1"
5050 [(set_attr "predicable" "yes")
5051 (set_attr "predicable_short_it" "yes,no")
5052 (set_attr "arch" "t2,*")
5053 (set_attr "length" "4")
5054 (set_attr "type" "mvn_reg")]
5055 )
5056
5057 (define_insn "*notsi_compare0"
5058 [(set (reg:CC_NOOV CC_REGNUM)
5059 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5060 (const_int 0)))
5061 (set (match_operand:SI 0 "s_register_operand" "=r")
5062 (not:SI (match_dup 1)))]
5063 "TARGET_32BIT"
5064 "mvns%?\\t%0, %1"
5065 [(set_attr "conds" "set")
5066 (set_attr "type" "mvn_reg")]
5067 )
5068
5069 (define_insn "*notsi_compare0_scratch"
5070 [(set (reg:CC_NOOV CC_REGNUM)
5071 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5072 (const_int 0)))
5073 (clobber (match_scratch:SI 0 "=r"))]
5074 "TARGET_32BIT"
5075 "mvns%?\\t%0, %1"
5076 [(set_attr "conds" "set")
5077 (set_attr "type" "mvn_reg")]
5078 )
5079 \f
5080 ;; Fixed <--> Floating conversion insns
5081
5082 (define_expand "floatsihf2"
5083 [(set (match_operand:HF 0 "general_operand" "")
5084 (float:HF (match_operand:SI 1 "general_operand" "")))]
5085 "TARGET_EITHER"
5086 "
5087 {
5088 rtx op1 = gen_reg_rtx (SFmode);
5089 expand_float (op1, operands[1], 0);
5090 op1 = convert_to_mode (HFmode, op1, 0);
5091 emit_move_insn (operands[0], op1);
5092 DONE;
5093 }"
5094 )
5095
5096 (define_expand "floatdihf2"
5097 [(set (match_operand:HF 0 "general_operand" "")
5098 (float:HF (match_operand:DI 1 "general_operand" "")))]
5099 "TARGET_EITHER"
5100 "
5101 {
5102 rtx op1 = gen_reg_rtx (SFmode);
5103 expand_float (op1, operands[1], 0);
5104 op1 = convert_to_mode (HFmode, op1, 0);
5105 emit_move_insn (operands[0], op1);
5106 DONE;
5107 }"
5108 )
5109
5110 (define_expand "floatsisf2"
5111 [(set (match_operand:SF 0 "s_register_operand" "")
5112 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5113 "TARGET_32BIT && TARGET_HARD_FLOAT"
5114 "
5115 ")
5116
5117 (define_expand "floatsidf2"
5118 [(set (match_operand:DF 0 "s_register_operand" "")
5119 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5120 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5121 "
5122 ")
5123
5124 (define_expand "fix_trunchfsi2"
5125 [(set (match_operand:SI 0 "general_operand" "")
5126 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5127 "TARGET_EITHER"
5128 "
5129 {
5130 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5131 expand_fix (operands[0], op1, 0);
5132 DONE;
5133 }"
5134 )
5135
5136 (define_expand "fix_trunchfdi2"
5137 [(set (match_operand:DI 0 "general_operand" "")
5138 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5139 "TARGET_EITHER"
5140 "
5141 {
5142 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5143 expand_fix (operands[0], op1, 0);
5144 DONE;
5145 }"
5146 )
5147
5148 (define_expand "fix_truncsfsi2"
5149 [(set (match_operand:SI 0 "s_register_operand" "")
5150 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5151 "TARGET_32BIT && TARGET_HARD_FLOAT"
5152 "
5153 ")
5154
5155 (define_expand "fix_truncdfsi2"
5156 [(set (match_operand:SI 0 "s_register_operand" "")
5157 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5158 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5159 "
5160 ")
5161
5162 ;; Truncation insns
5163
5164 (define_expand "truncdfsf2"
5165 [(set (match_operand:SF 0 "s_register_operand" "")
5166 (float_truncate:SF
5167 (match_operand:DF 1 "s_register_operand" "")))]
5168 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5169 ""
5170 )
5171
5172 ;; DFmode to HFmode conversions on targets without a single-step hardware
5173 ;; instruction for it would have to go through SFmode. This is dangerous
5174 ;; as it introduces double rounding.
5175 ;;
5176 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5177 ;; a single-step instruction.
5178
5179 (define_expand "truncdfhf2"
5180 [(set (match_operand:HF 0 "s_register_operand" "")
5181 (float_truncate:HF
5182 (match_operand:DF 1 "s_register_operand" "")))]
5183 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5184 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5185 {
5186 /* We don't have a direct instruction for this, so we must be in
5187 an unsafe math mode, and going via SFmode. */
5188
5189 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5190 {
5191 rtx op1;
5192 op1 = convert_to_mode (SFmode, operands[1], 0);
5193 op1 = convert_to_mode (HFmode, op1, 0);
5194 emit_move_insn (operands[0], op1);
5195 DONE;
5196 }
5197 /* Otherwise, we will pick this up as a single instruction with
5198 no intermediary rounding. */
5199 }
5200 )
5201 \f
5202 ;; Zero and sign extension instructions.
5203
5204 (define_insn "zero_extend<mode>di2"
5205 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5206 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5207 "<qhs_zextenddi_cstr>")))]
5208 "TARGET_32BIT <qhs_zextenddi_cond>"
5209 "#"
5210 [(set_attr "length" "8,4,8,8")
5211 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5212 (set_attr "ce_count" "2")
5213 (set_attr "predicable" "yes")
5214 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5215 )
5216
5217 (define_insn "extend<mode>di2"
5218 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5219 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5220 "<qhs_extenddi_cstr>")))]
5221 "TARGET_32BIT <qhs_sextenddi_cond>"
5222 "#"
5223 [(set_attr "length" "8,4,8,8,8")
5224 (set_attr "ce_count" "2")
5225 (set_attr "shift" "1")
5226 (set_attr "predicable" "yes")
5227 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5228 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5229 )
5230
5231 ;; Splits for all extensions to DImode
5232 (define_split
5233 [(set (match_operand:DI 0 "s_register_operand" "")
5234 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5235 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5236 [(set (match_dup 0) (match_dup 1))]
5237 {
5238 rtx lo_part = gen_lowpart (SImode, operands[0]);
5239 machine_mode src_mode = GET_MODE (operands[1]);
5240
5241 if (REG_P (operands[0])
5242 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5243 emit_clobber (operands[0]);
5244 if (!REG_P (lo_part) || src_mode != SImode
5245 || !rtx_equal_p (lo_part, operands[1]))
5246 {
5247 if (src_mode == SImode)
5248 emit_move_insn (lo_part, operands[1]);
5249 else
5250 emit_insn (gen_rtx_SET (lo_part,
5251 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5252 operands[1] = lo_part;
5253 }
5254 operands[0] = gen_highpart (SImode, operands[0]);
5255 operands[1] = const0_rtx;
5256 })
5257
5258 (define_split
5259 [(set (match_operand:DI 0 "s_register_operand" "")
5260 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5261 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5262 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5263 {
5264 rtx lo_part = gen_lowpart (SImode, operands[0]);
5265 machine_mode src_mode = GET_MODE (operands[1]);
5266
5267 if (REG_P (operands[0])
5268 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5269 emit_clobber (operands[0]);
5270
5271 if (!REG_P (lo_part) || src_mode != SImode
5272 || !rtx_equal_p (lo_part, operands[1]))
5273 {
5274 if (src_mode == SImode)
5275 emit_move_insn (lo_part, operands[1]);
5276 else
5277 emit_insn (gen_rtx_SET (lo_part,
5278 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5279 operands[1] = lo_part;
5280 }
5281 operands[0] = gen_highpart (SImode, operands[0]);
5282 })
5283
5284 (define_expand "zero_extendhisi2"
5285 [(set (match_operand:SI 0 "s_register_operand" "")
5286 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5287 "TARGET_EITHER"
5288 {
5289 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5290 {
5291 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5292 DONE;
5293 }
5294 if (!arm_arch6 && !MEM_P (operands[1]))
5295 {
5296 rtx t = gen_lowpart (SImode, operands[1]);
5297 rtx tmp = gen_reg_rtx (SImode);
5298 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5299 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5300 DONE;
5301 }
5302 })
5303
5304 (define_split
5305 [(set (match_operand:SI 0 "s_register_operand" "")
5306 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5307 "!TARGET_THUMB2 && !arm_arch6"
5308 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5309 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5310 {
5311 operands[2] = gen_lowpart (SImode, operands[1]);
5312 })
5313
5314 (define_insn "*arm_zero_extendhisi2"
5315 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5316 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5317 "TARGET_ARM && arm_arch4 && !arm_arch6"
5318 "@
5319 #
5320 ldrh%?\\t%0, %1"
5321 [(set_attr "type" "alu_shift_reg,load_byte")
5322 (set_attr "predicable" "yes")]
5323 )
5324
5325 (define_insn "*arm_zero_extendhisi2_v6"
5326 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5327 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5328 "TARGET_ARM && arm_arch6"
5329 "@
5330 uxth%?\\t%0, %1
5331 ldrh%?\\t%0, %1"
5332 [(set_attr "predicable" "yes")
5333 (set_attr "type" "extend,load_byte")]
5334 )
5335
5336 (define_insn "*arm_zero_extendhisi2addsi"
5337 [(set (match_operand:SI 0 "s_register_operand" "=r")
5338 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5339 (match_operand:SI 2 "s_register_operand" "r")))]
5340 "TARGET_INT_SIMD"
5341 "uxtah%?\\t%0, %2, %1"
5342 [(set_attr "type" "alu_shift_reg")
5343 (set_attr "predicable" "yes")]
5344 )
5345
5346 (define_expand "zero_extendqisi2"
5347 [(set (match_operand:SI 0 "s_register_operand" "")
5348 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5349 "TARGET_EITHER"
5350 {
5351 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5352 {
5353 emit_insn (gen_andsi3 (operands[0],
5354 gen_lowpart (SImode, operands[1]),
5355 GEN_INT (255)));
5356 DONE;
5357 }
5358 if (!arm_arch6 && !MEM_P (operands[1]))
5359 {
5360 rtx t = gen_lowpart (SImode, operands[1]);
5361 rtx tmp = gen_reg_rtx (SImode);
5362 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5363 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5364 DONE;
5365 }
5366 })
5367
5368 (define_split
5369 [(set (match_operand:SI 0 "s_register_operand" "")
5370 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5371 "!arm_arch6"
5372 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5373 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5374 {
5375 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5376 if (TARGET_ARM)
5377 {
5378 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5379 DONE;
5380 }
5381 })
5382
5383 (define_insn "*arm_zero_extendqisi2"
5384 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5385 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5386 "TARGET_ARM && !arm_arch6"
5387 "@
5388 #
5389 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5390 [(set_attr "length" "8,4")
5391 (set_attr "type" "alu_shift_reg,load_byte")
5392 (set_attr "predicable" "yes")]
5393 )
5394
5395 (define_insn "*arm_zero_extendqisi2_v6"
5396 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5397 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5398 "TARGET_ARM && arm_arch6"
5399 "@
5400 uxtb%?\\t%0, %1
5401 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5402 [(set_attr "type" "extend,load_byte")
5403 (set_attr "predicable" "yes")]
5404 )
5405
5406 (define_insn "*arm_zero_extendqisi2addsi"
5407 [(set (match_operand:SI 0 "s_register_operand" "=r")
5408 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5409 (match_operand:SI 2 "s_register_operand" "r")))]
5410 "TARGET_INT_SIMD"
5411 "uxtab%?\\t%0, %2, %1"
5412 [(set_attr "predicable" "yes")
5413 (set_attr "type" "alu_shift_reg")]
5414 )
5415
5416 (define_split
5417 [(set (match_operand:SI 0 "s_register_operand" "")
5418 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5419 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5420 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5421 [(set (match_dup 2) (match_dup 1))
5422 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5423 ""
5424 )
5425
5426 (define_split
5427 [(set (match_operand:SI 0 "s_register_operand" "")
5428 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5429 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5430 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5431 [(set (match_dup 2) (match_dup 1))
5432 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5433 ""
5434 )
5435
5436
5437 (define_split
5438 [(set (match_operand:SI 0 "s_register_operand" "")
5439 (IOR_XOR:SI (and:SI (ashift:SI
5440 (match_operand:SI 1 "s_register_operand" "")
5441 (match_operand:SI 2 "const_int_operand" ""))
5442 (match_operand:SI 3 "const_int_operand" ""))
5443 (zero_extend:SI
5444 (match_operator 5 "subreg_lowpart_operator"
5445 [(match_operand:SI 4 "s_register_operand" "")]))))]
5446 "TARGET_32BIT
5447 && (UINTVAL (operands[3])
5448 == (GET_MODE_MASK (GET_MODE (operands[5]))
5449 & (GET_MODE_MASK (GET_MODE (operands[5]))
5450 << (INTVAL (operands[2])))))"
5451 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5452 (match_dup 4)))
5453 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5454 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5455 )
5456
5457 (define_insn "*compareqi_eq0"
5458 [(set (reg:CC_Z CC_REGNUM)
5459 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5460 (const_int 0)))]
5461 "TARGET_32BIT"
5462 "tst%?\\t%0, #255"
5463 [(set_attr "conds" "set")
5464 (set_attr "predicable" "yes")
5465 (set_attr "type" "logic_imm")]
5466 )
5467
5468 (define_expand "extendhisi2"
5469 [(set (match_operand:SI 0 "s_register_operand" "")
5470 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5471 "TARGET_EITHER"
5472 {
5473 if (TARGET_THUMB1)
5474 {
5475 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5476 DONE;
5477 }
5478 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5479 {
5480 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5481 DONE;
5482 }
5483
5484 if (!arm_arch6 && !MEM_P (operands[1]))
5485 {
5486 rtx t = gen_lowpart (SImode, operands[1]);
5487 rtx tmp = gen_reg_rtx (SImode);
5488 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5489 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5490 DONE;
5491 }
5492 })
5493
5494 (define_split
5495 [(parallel
5496 [(set (match_operand:SI 0 "register_operand" "")
5497 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5498 (clobber (match_scratch:SI 2 ""))])]
5499 "!arm_arch6"
5500 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5501 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5502 {
5503 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5504 })
5505
5506 ;; This pattern will only be used when ldsh is not available
5507 (define_expand "extendhisi2_mem"
5508 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5509 (set (match_dup 3)
5510 (zero_extend:SI (match_dup 7)))
5511 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5512 (set (match_operand:SI 0 "" "")
5513 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5514 "TARGET_ARM"
5515 "
5516 {
5517 rtx mem1, mem2;
5518 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5519
5520 mem1 = change_address (operands[1], QImode, addr);
5521 mem2 = change_address (operands[1], QImode,
5522 plus_constant (Pmode, addr, 1));
5523 operands[0] = gen_lowpart (SImode, operands[0]);
5524 operands[1] = mem1;
5525 operands[2] = gen_reg_rtx (SImode);
5526 operands[3] = gen_reg_rtx (SImode);
5527 operands[6] = gen_reg_rtx (SImode);
5528 operands[7] = mem2;
5529
5530 if (BYTES_BIG_ENDIAN)
5531 {
5532 operands[4] = operands[2];
5533 operands[5] = operands[3];
5534 }
5535 else
5536 {
5537 operands[4] = operands[3];
5538 operands[5] = operands[2];
5539 }
5540 }"
5541 )
5542
5543 (define_split
5544 [(set (match_operand:SI 0 "register_operand" "")
5545 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5546 "!arm_arch6"
5547 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5548 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5549 {
5550 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5551 })
5552
5553 (define_insn "*arm_extendhisi2"
5554 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5555 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5556 "TARGET_ARM && arm_arch4 && !arm_arch6"
5557 "@
5558 #
5559 ldrsh%?\\t%0, %1"
5560 [(set_attr "length" "8,4")
5561 (set_attr "type" "alu_shift_reg,load_byte")
5562 (set_attr "predicable" "yes")]
5563 )
5564
5565 ;; ??? Check Thumb-2 pool range
5566 (define_insn "*arm_extendhisi2_v6"
5567 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5568 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5569 "TARGET_32BIT && arm_arch6"
5570 "@
5571 sxth%?\\t%0, %1
5572 ldrsh%?\\t%0, %1"
5573 [(set_attr "type" "extend,load_byte")
5574 (set_attr "predicable" "yes")]
5575 )
5576
5577 (define_insn "*arm_extendhisi2addsi"
5578 [(set (match_operand:SI 0 "s_register_operand" "=r")
5579 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5580 (match_operand:SI 2 "s_register_operand" "r")))]
5581 "TARGET_INT_SIMD"
5582 "sxtah%?\\t%0, %2, %1"
5583 [(set_attr "type" "alu_shift_reg")]
5584 )
5585
5586 (define_expand "extendqihi2"
5587 [(set (match_dup 2)
5588 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5589 (const_int 24)))
5590 (set (match_operand:HI 0 "s_register_operand" "")
5591 (ashiftrt:SI (match_dup 2)
5592 (const_int 24)))]
5593 "TARGET_ARM"
5594 "
5595 {
5596 if (arm_arch4 && MEM_P (operands[1]))
5597 {
5598 emit_insn (gen_rtx_SET (operands[0],
5599 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5600 DONE;
5601 }
5602 if (!s_register_operand (operands[1], QImode))
5603 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5604 operands[0] = gen_lowpart (SImode, operands[0]);
5605 operands[1] = gen_lowpart (SImode, operands[1]);
5606 operands[2] = gen_reg_rtx (SImode);
5607 }"
5608 )
5609
5610 (define_insn "*arm_extendqihi_insn"
5611 [(set (match_operand:HI 0 "s_register_operand" "=r")
5612 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5613 "TARGET_ARM && arm_arch4"
5614 "ldrsb%?\\t%0, %1"
5615 [(set_attr "type" "load_byte")
5616 (set_attr "predicable" "yes")]
5617 )
5618
5619 (define_expand "extendqisi2"
5620 [(set (match_operand:SI 0 "s_register_operand" "")
5621 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5622 "TARGET_EITHER"
5623 {
5624 if (!arm_arch4 && MEM_P (operands[1]))
5625 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5626
5627 if (!arm_arch6 && !MEM_P (operands[1]))
5628 {
5629 rtx t = gen_lowpart (SImode, operands[1]);
5630 rtx tmp = gen_reg_rtx (SImode);
5631 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5632 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5633 DONE;
5634 }
5635 })
5636
5637 (define_split
5638 [(set (match_operand:SI 0 "register_operand" "")
5639 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5640 "!arm_arch6"
5641 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5642 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5643 {
5644 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5645 })
5646
5647 (define_insn "*arm_extendqisi"
5648 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5649 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5650 "TARGET_ARM && arm_arch4 && !arm_arch6"
5651 "@
5652 #
5653 ldrsb%?\\t%0, %1"
5654 [(set_attr "length" "8,4")
5655 (set_attr "type" "alu_shift_reg,load_byte")
5656 (set_attr "predicable" "yes")]
5657 )
5658
5659 (define_insn "*arm_extendqisi_v6"
5660 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5661 (sign_extend:SI
5662 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5663 "TARGET_ARM && arm_arch6"
5664 "@
5665 sxtb%?\\t%0, %1
5666 ldrsb%?\\t%0, %1"
5667 [(set_attr "type" "extend,load_byte")
5668 (set_attr "predicable" "yes")]
5669 )
5670
5671 (define_insn "*arm_extendqisi2addsi"
5672 [(set (match_operand:SI 0 "s_register_operand" "=r")
5673 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5674 (match_operand:SI 2 "s_register_operand" "r")))]
5675 "TARGET_INT_SIMD"
5676 "sxtab%?\\t%0, %2, %1"
5677 [(set_attr "type" "alu_shift_reg")
5678 (set_attr "predicable" "yes")]
5679 )
5680
5681 (define_expand "extendsfdf2"
5682 [(set (match_operand:DF 0 "s_register_operand" "")
5683 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5684 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5685 ""
5686 )
5687
5688 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5689 ;; must go through SFmode.
5690 ;;
5691 ;; This is always safe for an extend.
5692
5693 (define_expand "extendhfdf2"
5694 [(set (match_operand:DF 0 "s_register_operand" "")
5695 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5696 "TARGET_EITHER"
5697 {
5698 /* We don't have a direct instruction for this, so go via SFmode. */
5699 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5700 {
5701 rtx op1;
5702 op1 = convert_to_mode (SFmode, operands[1], 0);
5703 op1 = convert_to_mode (DFmode, op1, 0);
5704 emit_insn (gen_movdf (operands[0], op1));
5705 DONE;
5706 }
5707 /* Otherwise, we're done producing RTL and will pick up the correct
5708 pattern to do this with one rounding-step in a single instruction. */
5709 }
5710 )
5711 \f
5712 ;; Move insns (including loads and stores)
5713
5714 ;; XXX Just some ideas about movti.
5715 ;; I don't think these are a good idea on the arm, there just aren't enough
5716 ;; registers
5717 ;;(define_expand "loadti"
5718 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5719 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5720 ;; "" "")
5721
5722 ;;(define_expand "storeti"
5723 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5724 ;; (match_operand:TI 1 "s_register_operand" ""))]
5725 ;; "" "")
5726
5727 ;;(define_expand "movti"
5728 ;; [(set (match_operand:TI 0 "general_operand" "")
5729 ;; (match_operand:TI 1 "general_operand" ""))]
5730 ;; ""
5731 ;; "
5732 ;;{
5733 ;; rtx insn;
5734 ;;
5735 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5736 ;; operands[1] = copy_to_reg (operands[1]);
5737 ;; if (MEM_P (operands[0]))
5738 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5739 ;; else if (MEM_P (operands[1]))
5740 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5741 ;; else
5742 ;; FAIL;
5743 ;;
5744 ;; emit_insn (insn);
5745 ;; DONE;
5746 ;;}")
5747
5748 ;; Recognize garbage generated above.
5749
5750 ;;(define_insn ""
5751 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5752 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5753 ;; ""
5754 ;; "*
5755 ;; {
5756 ;; register mem = (which_alternative < 3);
5757 ;; register const char *template;
5758 ;;
5759 ;; operands[mem] = XEXP (operands[mem], 0);
5760 ;; switch (which_alternative)
5761 ;; {
5762 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5763 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5764 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5765 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5766 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5767 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5768 ;; }
5769 ;; output_asm_insn (template, operands);
5770 ;; return \"\";
5771 ;; }")
5772
5773 (define_expand "movdi"
5774 [(set (match_operand:DI 0 "general_operand" "")
5775 (match_operand:DI 1 "general_operand" ""))]
5776 "TARGET_EITHER"
5777 "
5778 if (can_create_pseudo_p ())
5779 {
5780 if (!REG_P (operands[0]))
5781 operands[1] = force_reg (DImode, operands[1]);
5782 }
5783 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5784 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5785 {
5786 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5787 when expanding function calls. */
5788 gcc_assert (can_create_pseudo_p ());
5789 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5790 {
5791 /* Perform load into legal reg pair first, then move. */
5792 rtx reg = gen_reg_rtx (DImode);
5793 emit_insn (gen_movdi (reg, operands[1]));
5794 operands[1] = reg;
5795 }
5796 emit_move_insn (gen_lowpart (SImode, operands[0]),
5797 gen_lowpart (SImode, operands[1]));
5798 emit_move_insn (gen_highpart (SImode, operands[0]),
5799 gen_highpart (SImode, operands[1]));
5800 DONE;
5801 }
5802 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5803 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5804 {
5805 /* Avoid STRD's from an odd-numbered register pair in ARM state
5806 when expanding function prologue. */
5807 gcc_assert (can_create_pseudo_p ());
5808 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5809 ? gen_reg_rtx (DImode)
5810 : operands[0];
5811 emit_move_insn (gen_lowpart (SImode, split_dest),
5812 gen_lowpart (SImode, operands[1]));
5813 emit_move_insn (gen_highpart (SImode, split_dest),
5814 gen_highpart (SImode, operands[1]));
5815 if (split_dest != operands[0])
5816 emit_insn (gen_movdi (operands[0], split_dest));
5817 DONE;
5818 }
5819 "
5820 )
5821
5822 (define_insn "*arm_movdi"
5823 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5824 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5825 "TARGET_32BIT
5826 && !(TARGET_HARD_FLOAT)
5827 && !TARGET_IWMMXT
5828 && ( register_operand (operands[0], DImode)
5829 || register_operand (operands[1], DImode))"
5830 "*
5831 switch (which_alternative)
5832 {
5833 case 0:
5834 case 1:
5835 case 2:
5836 return \"#\";
5837 default:
5838 return output_move_double (operands, true, NULL);
5839 }
5840 "
5841 [(set_attr "length" "8,12,16,8,8")
5842 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5843 (set_attr "arm_pool_range" "*,*,*,1020,*")
5844 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5845 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5846 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5847 )
5848
5849 (define_split
5850 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5851 (match_operand:ANY64 1 "immediate_operand" ""))]
5852 "TARGET_32BIT
5853 && reload_completed
5854 && (arm_disable_literal_pool
5855 || (arm_const_double_inline_cost (operands[1])
5856 <= arm_max_const_double_inline_cost ()))"
5857 [(const_int 0)]
5858 "
5859 arm_split_constant (SET, SImode, curr_insn,
5860 INTVAL (gen_lowpart (SImode, operands[1])),
5861 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5862 arm_split_constant (SET, SImode, curr_insn,
5863 INTVAL (gen_highpart_mode (SImode,
5864 GET_MODE (operands[0]),
5865 operands[1])),
5866 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5867 DONE;
5868 "
5869 )
5870
5871 ; If optimizing for size, or if we have load delay slots, then
5872 ; we want to split the constant into two separate operations.
5873 ; In both cases this may split a trivial part into a single data op
5874 ; leaving a single complex constant to load. We can also get longer
5875 ; offsets in a LDR which means we get better chances of sharing the pool
5876 ; entries. Finally, we can normally do a better job of scheduling
5877 ; LDR instructions than we can with LDM.
5878 ; This pattern will only match if the one above did not.
5879 (define_split
5880 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5881 (match_operand:ANY64 1 "const_double_operand" ""))]
5882 "TARGET_ARM && reload_completed
5883 && arm_const_double_by_parts (operands[1])"
5884 [(set (match_dup 0) (match_dup 1))
5885 (set (match_dup 2) (match_dup 3))]
5886 "
5887 operands[2] = gen_highpart (SImode, operands[0]);
5888 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5889 operands[1]);
5890 operands[0] = gen_lowpart (SImode, operands[0]);
5891 operands[1] = gen_lowpart (SImode, operands[1]);
5892 "
5893 )
5894
5895 (define_split
5896 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5897 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5898 "TARGET_EITHER && reload_completed"
5899 [(set (match_dup 0) (match_dup 1))
5900 (set (match_dup 2) (match_dup 3))]
5901 "
5902 operands[2] = gen_highpart (SImode, operands[0]);
5903 operands[3] = gen_highpart (SImode, operands[1]);
5904 operands[0] = gen_lowpart (SImode, operands[0]);
5905 operands[1] = gen_lowpart (SImode, operands[1]);
5906
5907 /* Handle a partial overlap. */
5908 if (rtx_equal_p (operands[0], operands[3]))
5909 {
5910 rtx tmp0 = operands[0];
5911 rtx tmp1 = operands[1];
5912
5913 operands[0] = operands[2];
5914 operands[1] = operands[3];
5915 operands[2] = tmp0;
5916 operands[3] = tmp1;
5917 }
5918 "
5919 )
5920
5921 ;; We can't actually do base+index doubleword loads if the index and
5922 ;; destination overlap. Split here so that we at least have chance to
5923 ;; schedule.
5924 (define_split
5925 [(set (match_operand:DI 0 "s_register_operand" "")
5926 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5927 (match_operand:SI 2 "s_register_operand" ""))))]
5928 "TARGET_LDRD
5929 && reg_overlap_mentioned_p (operands[0], operands[1])
5930 && reg_overlap_mentioned_p (operands[0], operands[2])"
5931 [(set (match_dup 4)
5932 (plus:SI (match_dup 1)
5933 (match_dup 2)))
5934 (set (match_dup 0)
5935 (mem:DI (match_dup 4)))]
5936 "
5937 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5938 "
5939 )
5940
5941 (define_expand "movsi"
5942 [(set (match_operand:SI 0 "general_operand" "")
5943 (match_operand:SI 1 "general_operand" ""))]
5944 "TARGET_EITHER"
5945 "
5946 {
5947 rtx base, offset, tmp;
5948
5949 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5950 {
5951 /* Everything except mem = const or mem = mem can be done easily. */
5952 if (MEM_P (operands[0]))
5953 operands[1] = force_reg (SImode, operands[1]);
5954 if (arm_general_register_operand (operands[0], SImode)
5955 && CONST_INT_P (operands[1])
5956 && !(const_ok_for_arm (INTVAL (operands[1]))
5957 || const_ok_for_arm (~INTVAL (operands[1]))))
5958 {
5959 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5960 {
5961 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5962 DONE;
5963 }
5964 else
5965 {
5966 arm_split_constant (SET, SImode, NULL_RTX,
5967 INTVAL (operands[1]), operands[0], NULL_RTX,
5968 optimize && can_create_pseudo_p ());
5969 DONE;
5970 }
5971 }
5972 }
5973 else /* Target doesn't have MOVT... */
5974 {
5975 if (can_create_pseudo_p ())
5976 {
5977 if (!REG_P (operands[0]))
5978 operands[1] = force_reg (SImode, operands[1]);
5979 }
5980 }
5981
5982 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5983 {
5984 split_const (operands[1], &base, &offset);
5985 if (GET_CODE (base) == SYMBOL_REF
5986 && !offset_within_block_p (base, INTVAL (offset)))
5987 {
5988 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5989 emit_move_insn (tmp, base);
5990 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5991 DONE;
5992 }
5993 }
5994
5995 /* Recognize the case where operand[1] is a reference to thread-local
5996 data and load its address to a register. */
5997 if (arm_tls_referenced_p (operands[1]))
5998 {
5999 rtx tmp = operands[1];
6000 rtx addend = NULL;
6001
6002 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6003 {
6004 addend = XEXP (XEXP (tmp, 0), 1);
6005 tmp = XEXP (XEXP (tmp, 0), 0);
6006 }
6007
6008 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6009 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6010
6011 tmp = legitimize_tls_address (tmp,
6012 !can_create_pseudo_p () ? operands[0] : 0);
6013 if (addend)
6014 {
6015 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6016 tmp = force_operand (tmp, operands[0]);
6017 }
6018 operands[1] = tmp;
6019 }
6020 else if (flag_pic
6021 && (CONSTANT_P (operands[1])
6022 || symbol_mentioned_p (operands[1])
6023 || label_mentioned_p (operands[1])))
6024 operands[1] = legitimize_pic_address (operands[1], SImode,
6025 (!can_create_pseudo_p ()
6026 ? operands[0]
6027 : 0));
6028 }
6029 "
6030 )
6031
6032 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6033 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6034 ;; so this does not matter.
6035 (define_insn "*arm_movt"
6036 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6037 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6038 (match_operand:SI 2 "general_operand" "i,i")))]
6039 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6040 "@
6041 movt%?\t%0, #:upper16:%c2
6042 movt\t%0, #:upper16:%c2"
6043 [(set_attr "arch" "32,v8mb")
6044 (set_attr "predicable" "yes")
6045 (set_attr "length" "4")
6046 (set_attr "type" "alu_sreg")]
6047 )
6048
6049 (define_insn "*arm_movsi_insn"
6050 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6051 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6052 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6053 && ( register_operand (operands[0], SImode)
6054 || register_operand (operands[1], SImode))"
6055 "@
6056 mov%?\\t%0, %1
6057 mov%?\\t%0, %1
6058 mvn%?\\t%0, #%B1
6059 movw%?\\t%0, %1
6060 ldr%?\\t%0, %1
6061 str%?\\t%1, %0"
6062 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6063 (set_attr "predicable" "yes")
6064 (set_attr "arch" "*,*,*,v6t2,*,*")
6065 (set_attr "pool_range" "*,*,*,*,4096,*")
6066 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6067 )
6068
6069 (define_split
6070 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6071 (match_operand:SI 1 "const_int_operand" ""))]
6072 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6073 && (!(const_ok_for_arm (INTVAL (operands[1]))
6074 || const_ok_for_arm (~INTVAL (operands[1]))))"
6075 [(clobber (const_int 0))]
6076 "
6077 arm_split_constant (SET, SImode, NULL_RTX,
6078 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6079 DONE;
6080 "
6081 )
6082
6083 ;; A normal way to do (symbol + offset) requires three instructions at least
6084 ;; (depends on how big the offset is) as below:
6085 ;; movw r0, #:lower16:g
6086 ;; movw r0, #:upper16:g
6087 ;; adds r0, #4
6088 ;;
6089 ;; A better way would be:
6090 ;; movw r0, #:lower16:g+4
6091 ;; movw r0, #:upper16:g+4
6092 ;;
6093 ;; The limitation of this way is that the length of offset should be a 16-bit
6094 ;; signed value, because current assembler only supports REL type relocation for
6095 ;; such case. If the more powerful RELA type is supported in future, we should
6096 ;; update this pattern to go with better way.
6097 (define_split
6098 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6099 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6100 (match_operand:SI 2 "const_int_operand" ""))))]
6101 "TARGET_THUMB
6102 && TARGET_HAVE_MOVT
6103 && arm_disable_literal_pool
6104 && reload_completed
6105 && GET_CODE (operands[1]) == SYMBOL_REF"
6106 [(clobber (const_int 0))]
6107 "
6108 int offset = INTVAL (operands[2]);
6109
6110 if (offset < -0x8000 || offset > 0x7fff)
6111 {
6112 arm_emit_movpair (operands[0], operands[1]);
6113 emit_insn (gen_rtx_SET (operands[0],
6114 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6115 }
6116 else
6117 {
6118 rtx op = gen_rtx_CONST (SImode,
6119 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6120 arm_emit_movpair (operands[0], op);
6121 }
6122 "
6123 )
6124
6125 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6126 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6127 ;; and lo_sum would be merged back into memory load at cprop. However,
6128 ;; if the default is to prefer movt/movw rather than a load from the constant
6129 ;; pool, the performance is better.
6130 (define_split
6131 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6132 (match_operand:SI 1 "general_operand" ""))]
6133 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6134 && !flag_pic && !target_word_relocations
6135 && !arm_tls_referenced_p (operands[1])"
6136 [(clobber (const_int 0))]
6137 {
6138 arm_emit_movpair (operands[0], operands[1]);
6139 DONE;
6140 })
6141
6142 ;; When generating pic, we need to load the symbol offset into a register.
6143 ;; So that the optimizer does not confuse this with a normal symbol load
6144 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6145 ;; since that is the only type of relocation we can use.
6146
6147 ;; Wrap calculation of the whole PIC address in a single pattern for the
6148 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6149 ;; a PIC address involves two loads from memory, so we want to CSE it
6150 ;; as often as possible.
6151 ;; This pattern will be split into one of the pic_load_addr_* patterns
6152 ;; and a move after GCSE optimizations.
6153 ;;
6154 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6155 (define_expand "calculate_pic_address"
6156 [(set (match_operand:SI 0 "register_operand" "")
6157 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6158 (unspec:SI [(match_operand:SI 2 "" "")]
6159 UNSPEC_PIC_SYM))))]
6160 "flag_pic"
6161 )
6162
6163 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6164 (define_split
6165 [(set (match_operand:SI 0 "register_operand" "")
6166 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6167 (unspec:SI [(match_operand:SI 2 "" "")]
6168 UNSPEC_PIC_SYM))))]
6169 "flag_pic"
6170 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6171 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6172 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6173 )
6174
6175 ;; operand1 is the memory address to go into
6176 ;; pic_load_addr_32bit.
6177 ;; operand2 is the PIC label to be emitted
6178 ;; from pic_add_dot_plus_eight.
6179 ;; We do this to allow hoisting of the entire insn.
6180 (define_insn_and_split "pic_load_addr_unified"
6181 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6182 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6183 (match_operand:SI 2 "" "")]
6184 UNSPEC_PIC_UNIFIED))]
6185 "flag_pic"
6186 "#"
6187 "&& reload_completed"
6188 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6189 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6190 (match_dup 2)] UNSPEC_PIC_BASE))]
6191 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6192 [(set_attr "type" "load_4,load_4,load_4")
6193 (set_attr "pool_range" "4096,4094,1022")
6194 (set_attr "neg_pool_range" "4084,0,0")
6195 (set_attr "arch" "a,t2,t1")
6196 (set_attr "length" "8,6,4")]
6197 )
6198
6199 ;; The rather odd constraints on the following are to force reload to leave
6200 ;; the insn alone, and to force the minipool generation pass to then move
6201 ;; the GOT symbol to memory.
6202
6203 (define_insn "pic_load_addr_32bit"
6204 [(set (match_operand:SI 0 "s_register_operand" "=r")
6205 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6206 "TARGET_32BIT && flag_pic"
6207 "ldr%?\\t%0, %1"
6208 [(set_attr "type" "load_4")
6209 (set (attr "pool_range")
6210 (if_then_else (eq_attr "is_thumb" "no")
6211 (const_int 4096)
6212 (const_int 4094)))
6213 (set (attr "neg_pool_range")
6214 (if_then_else (eq_attr "is_thumb" "no")
6215 (const_int 4084)
6216 (const_int 0)))]
6217 )
6218
6219 (define_insn "pic_load_addr_thumb1"
6220 [(set (match_operand:SI 0 "s_register_operand" "=l")
6221 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6222 "TARGET_THUMB1 && flag_pic"
6223 "ldr\\t%0, %1"
6224 [(set_attr "type" "load_4")
6225 (set (attr "pool_range") (const_int 1018))]
6226 )
6227
6228 (define_insn "pic_add_dot_plus_four"
6229 [(set (match_operand:SI 0 "register_operand" "=r")
6230 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6231 (const_int 4)
6232 (match_operand 2 "" "")]
6233 UNSPEC_PIC_BASE))]
6234 "TARGET_THUMB"
6235 "*
6236 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6237 INTVAL (operands[2]));
6238 return \"add\\t%0, %|pc\";
6239 "
6240 [(set_attr "length" "2")
6241 (set_attr "type" "alu_sreg")]
6242 )
6243
6244 (define_insn "pic_add_dot_plus_eight"
6245 [(set (match_operand:SI 0 "register_operand" "=r")
6246 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6247 (const_int 8)
6248 (match_operand 2 "" "")]
6249 UNSPEC_PIC_BASE))]
6250 "TARGET_ARM"
6251 "*
6252 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6253 INTVAL (operands[2]));
6254 return \"add%?\\t%0, %|pc, %1\";
6255 "
6256 [(set_attr "predicable" "yes")
6257 (set_attr "type" "alu_sreg")]
6258 )
6259
6260 (define_insn "tls_load_dot_plus_eight"
6261 [(set (match_operand:SI 0 "register_operand" "=r")
6262 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6263 (const_int 8)
6264 (match_operand 2 "" "")]
6265 UNSPEC_PIC_BASE)))]
6266 "TARGET_ARM"
6267 "*
6268 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6269 INTVAL (operands[2]));
6270 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6271 "
6272 [(set_attr "predicable" "yes")
6273 (set_attr "type" "load_4")]
6274 )
6275
6276 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6277 ;; followed by a load. These sequences can be crunched down to
6278 ;; tls_load_dot_plus_eight by a peephole.
6279
6280 (define_peephole2
6281 [(set (match_operand:SI 0 "register_operand" "")
6282 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6283 (const_int 8)
6284 (match_operand 1 "" "")]
6285 UNSPEC_PIC_BASE))
6286 (set (match_operand:SI 2 "arm_general_register_operand" "")
6287 (mem:SI (match_dup 0)))]
6288 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6289 [(set (match_dup 2)
6290 (mem:SI (unspec:SI [(match_dup 3)
6291 (const_int 8)
6292 (match_dup 1)]
6293 UNSPEC_PIC_BASE)))]
6294 ""
6295 )
6296
6297 (define_insn "pic_offset_arm"
6298 [(set (match_operand:SI 0 "register_operand" "=r")
6299 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6300 (unspec:SI [(match_operand:SI 2 "" "X")]
6301 UNSPEC_PIC_OFFSET))))]
6302 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6303 "ldr%?\\t%0, [%1,%2]"
6304 [(set_attr "type" "load_4")]
6305 )
6306
6307 (define_expand "builtin_setjmp_receiver"
6308 [(label_ref (match_operand 0 "" ""))]
6309 "flag_pic"
6310 "
6311 {
6312 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6313 register. */
6314 if (arm_pic_register != INVALID_REGNUM)
6315 arm_load_pic_register (1UL << 3);
6316 DONE;
6317 }")
6318
6319 ;; If copying one reg to another we can set the condition codes according to
6320 ;; its value. Such a move is common after a return from subroutine and the
6321 ;; result is being tested against zero.
6322
6323 (define_insn "*movsi_compare0"
6324 [(set (reg:CC CC_REGNUM)
6325 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6326 (const_int 0)))
6327 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6328 (match_dup 1))]
6329 "TARGET_32BIT"
6330 "@
6331 cmp%?\\t%0, #0
6332 subs%?\\t%0, %1, #0"
6333 [(set_attr "conds" "set")
6334 (set_attr "type" "alus_imm,alus_imm")]
6335 )
6336
6337 ;; Subroutine to store a half word from a register into memory.
6338 ;; Operand 0 is the source register (HImode)
6339 ;; Operand 1 is the destination address in a register (SImode)
6340
6341 ;; In both this routine and the next, we must be careful not to spill
6342 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6343 ;; can generate unrecognizable rtl.
6344
6345 (define_expand "storehi"
6346 [;; store the low byte
6347 (set (match_operand 1 "" "") (match_dup 3))
6348 ;; extract the high byte
6349 (set (match_dup 2)
6350 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6351 ;; store the high byte
6352 (set (match_dup 4) (match_dup 5))]
6353 "TARGET_ARM"
6354 "
6355 {
6356 rtx op1 = operands[1];
6357 rtx addr = XEXP (op1, 0);
6358 enum rtx_code code = GET_CODE (addr);
6359
6360 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6361 || code == MINUS)
6362 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6363
6364 operands[4] = adjust_address (op1, QImode, 1);
6365 operands[1] = adjust_address (operands[1], QImode, 0);
6366 operands[3] = gen_lowpart (QImode, operands[0]);
6367 operands[0] = gen_lowpart (SImode, operands[0]);
6368 operands[2] = gen_reg_rtx (SImode);
6369 operands[5] = gen_lowpart (QImode, operands[2]);
6370 }"
6371 )
6372
6373 (define_expand "storehi_bigend"
6374 [(set (match_dup 4) (match_dup 3))
6375 (set (match_dup 2)
6376 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6377 (set (match_operand 1 "" "") (match_dup 5))]
6378 "TARGET_ARM"
6379 "
6380 {
6381 rtx op1 = operands[1];
6382 rtx addr = XEXP (op1, 0);
6383 enum rtx_code code = GET_CODE (addr);
6384
6385 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6386 || code == MINUS)
6387 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6388
6389 operands[4] = adjust_address (op1, QImode, 1);
6390 operands[1] = adjust_address (operands[1], QImode, 0);
6391 operands[3] = gen_lowpart (QImode, operands[0]);
6392 operands[0] = gen_lowpart (SImode, operands[0]);
6393 operands[2] = gen_reg_rtx (SImode);
6394 operands[5] = gen_lowpart (QImode, operands[2]);
6395 }"
6396 )
6397
6398 ;; Subroutine to store a half word integer constant into memory.
6399 (define_expand "storeinthi"
6400 [(set (match_operand 0 "" "")
6401 (match_operand 1 "" ""))
6402 (set (match_dup 3) (match_dup 2))]
6403 "TARGET_ARM"
6404 "
6405 {
6406 HOST_WIDE_INT value = INTVAL (operands[1]);
6407 rtx addr = XEXP (operands[0], 0);
6408 rtx op0 = operands[0];
6409 enum rtx_code code = GET_CODE (addr);
6410
6411 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6412 || code == MINUS)
6413 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6414
6415 operands[1] = gen_reg_rtx (SImode);
6416 if (BYTES_BIG_ENDIAN)
6417 {
6418 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6419 if ((value & 255) == ((value >> 8) & 255))
6420 operands[2] = operands[1];
6421 else
6422 {
6423 operands[2] = gen_reg_rtx (SImode);
6424 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6425 }
6426 }
6427 else
6428 {
6429 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6430 if ((value & 255) == ((value >> 8) & 255))
6431 operands[2] = operands[1];
6432 else
6433 {
6434 operands[2] = gen_reg_rtx (SImode);
6435 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6436 }
6437 }
6438
6439 operands[3] = adjust_address (op0, QImode, 1);
6440 operands[0] = adjust_address (operands[0], QImode, 0);
6441 operands[2] = gen_lowpart (QImode, operands[2]);
6442 operands[1] = gen_lowpart (QImode, operands[1]);
6443 }"
6444 )
6445
6446 (define_expand "storehi_single_op"
6447 [(set (match_operand:HI 0 "memory_operand" "")
6448 (match_operand:HI 1 "general_operand" ""))]
6449 "TARGET_32BIT && arm_arch4"
6450 "
6451 if (!s_register_operand (operands[1], HImode))
6452 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6453 "
6454 )
6455
6456 (define_expand "movhi"
6457 [(set (match_operand:HI 0 "general_operand" "")
6458 (match_operand:HI 1 "general_operand" ""))]
6459 "TARGET_EITHER"
6460 "
6461 if (TARGET_ARM)
6462 {
6463 if (can_create_pseudo_p ())
6464 {
6465 if (MEM_P (operands[0]))
6466 {
6467 if (arm_arch4)
6468 {
6469 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6470 DONE;
6471 }
6472 if (CONST_INT_P (operands[1]))
6473 emit_insn (gen_storeinthi (operands[0], operands[1]));
6474 else
6475 {
6476 if (MEM_P (operands[1]))
6477 operands[1] = force_reg (HImode, operands[1]);
6478 if (BYTES_BIG_ENDIAN)
6479 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6480 else
6481 emit_insn (gen_storehi (operands[1], operands[0]));
6482 }
6483 DONE;
6484 }
6485 /* Sign extend a constant, and keep it in an SImode reg. */
6486 else if (CONST_INT_P (operands[1]))
6487 {
6488 rtx reg = gen_reg_rtx (SImode);
6489 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6490
6491 /* If the constant is already valid, leave it alone. */
6492 if (!const_ok_for_arm (val))
6493 {
6494 /* If setting all the top bits will make the constant
6495 loadable in a single instruction, then set them.
6496 Otherwise, sign extend the number. */
6497
6498 if (const_ok_for_arm (~(val | ~0xffff)))
6499 val |= ~0xffff;
6500 else if (val & 0x8000)
6501 val |= ~0xffff;
6502 }
6503
6504 emit_insn (gen_movsi (reg, GEN_INT (val)));
6505 operands[1] = gen_lowpart (HImode, reg);
6506 }
6507 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6508 && MEM_P (operands[1]))
6509 {
6510 rtx reg = gen_reg_rtx (SImode);
6511
6512 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6513 operands[1] = gen_lowpart (HImode, reg);
6514 }
6515 else if (!arm_arch4)
6516 {
6517 if (MEM_P (operands[1]))
6518 {
6519 rtx base;
6520 rtx offset = const0_rtx;
6521 rtx reg = gen_reg_rtx (SImode);
6522
6523 if ((REG_P (base = XEXP (operands[1], 0))
6524 || (GET_CODE (base) == PLUS
6525 && (CONST_INT_P (offset = XEXP (base, 1)))
6526 && ((INTVAL(offset) & 1) != 1)
6527 && REG_P (base = XEXP (base, 0))))
6528 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6529 {
6530 rtx new_rtx;
6531
6532 new_rtx = widen_memory_access (operands[1], SImode,
6533 ((INTVAL (offset) & ~3)
6534 - INTVAL (offset)));
6535 emit_insn (gen_movsi (reg, new_rtx));
6536 if (((INTVAL (offset) & 2) != 0)
6537 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6538 {
6539 rtx reg2 = gen_reg_rtx (SImode);
6540
6541 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6542 reg = reg2;
6543 }
6544 }
6545 else
6546 emit_insn (gen_movhi_bytes (reg, operands[1]));
6547
6548 operands[1] = gen_lowpart (HImode, reg);
6549 }
6550 }
6551 }
6552 /* Handle loading a large integer during reload. */
6553 else if (CONST_INT_P (operands[1])
6554 && !const_ok_for_arm (INTVAL (operands[1]))
6555 && !const_ok_for_arm (~INTVAL (operands[1])))
6556 {
6557 /* Writing a constant to memory needs a scratch, which should
6558 be handled with SECONDARY_RELOADs. */
6559 gcc_assert (REG_P (operands[0]));
6560
6561 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6562 emit_insn (gen_movsi (operands[0], operands[1]));
6563 DONE;
6564 }
6565 }
6566 else if (TARGET_THUMB2)
6567 {
6568 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6569 if (can_create_pseudo_p ())
6570 {
6571 if (!REG_P (operands[0]))
6572 operands[1] = force_reg (HImode, operands[1]);
6573 /* Zero extend a constant, and keep it in an SImode reg. */
6574 else if (CONST_INT_P (operands[1]))
6575 {
6576 rtx reg = gen_reg_rtx (SImode);
6577 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6578
6579 emit_insn (gen_movsi (reg, GEN_INT (val)));
6580 operands[1] = gen_lowpart (HImode, reg);
6581 }
6582 }
6583 }
6584 else /* TARGET_THUMB1 */
6585 {
6586 if (can_create_pseudo_p ())
6587 {
6588 if (CONST_INT_P (operands[1]))
6589 {
6590 rtx reg = gen_reg_rtx (SImode);
6591
6592 emit_insn (gen_movsi (reg, operands[1]));
6593 operands[1] = gen_lowpart (HImode, reg);
6594 }
6595
6596 /* ??? We shouldn't really get invalid addresses here, but this can
6597 happen if we are passed a SP (never OK for HImode/QImode) or
6598 virtual register (also rejected as illegitimate for HImode/QImode)
6599 relative address. */
6600 /* ??? This should perhaps be fixed elsewhere, for instance, in
6601 fixup_stack_1, by checking for other kinds of invalid addresses,
6602 e.g. a bare reference to a virtual register. This may confuse the
6603 alpha though, which must handle this case differently. */
6604 if (MEM_P (operands[0])
6605 && !memory_address_p (GET_MODE (operands[0]),
6606 XEXP (operands[0], 0)))
6607 operands[0]
6608 = replace_equiv_address (operands[0],
6609 copy_to_reg (XEXP (operands[0], 0)));
6610
6611 if (MEM_P (operands[1])
6612 && !memory_address_p (GET_MODE (operands[1]),
6613 XEXP (operands[1], 0)))
6614 operands[1]
6615 = replace_equiv_address (operands[1],
6616 copy_to_reg (XEXP (operands[1], 0)));
6617
6618 if (MEM_P (operands[1]) && optimize > 0)
6619 {
6620 rtx reg = gen_reg_rtx (SImode);
6621
6622 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6623 operands[1] = gen_lowpart (HImode, reg);
6624 }
6625
6626 if (MEM_P (operands[0]))
6627 operands[1] = force_reg (HImode, operands[1]);
6628 }
6629 else if (CONST_INT_P (operands[1])
6630 && !satisfies_constraint_I (operands[1]))
6631 {
6632 /* Handle loading a large integer during reload. */
6633
6634 /* Writing a constant to memory needs a scratch, which should
6635 be handled with SECONDARY_RELOADs. */
6636 gcc_assert (REG_P (operands[0]));
6637
6638 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6639 emit_insn (gen_movsi (operands[0], operands[1]));
6640 DONE;
6641 }
6642 }
6643 "
6644 )
6645
6646 (define_expand "movhi_bytes"
6647 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6648 (set (match_dup 3)
6649 (zero_extend:SI (match_dup 6)))
6650 (set (match_operand:SI 0 "" "")
6651 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6652 "TARGET_ARM"
6653 "
6654 {
6655 rtx mem1, mem2;
6656 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6657
6658 mem1 = change_address (operands[1], QImode, addr);
6659 mem2 = change_address (operands[1], QImode,
6660 plus_constant (Pmode, addr, 1));
6661 operands[0] = gen_lowpart (SImode, operands[0]);
6662 operands[1] = mem1;
6663 operands[2] = gen_reg_rtx (SImode);
6664 operands[3] = gen_reg_rtx (SImode);
6665 operands[6] = mem2;
6666
6667 if (BYTES_BIG_ENDIAN)
6668 {
6669 operands[4] = operands[2];
6670 operands[5] = operands[3];
6671 }
6672 else
6673 {
6674 operands[4] = operands[3];
6675 operands[5] = operands[2];
6676 }
6677 }"
6678 )
6679
6680 (define_expand "movhi_bigend"
6681 [(set (match_dup 2)
6682 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6683 (const_int 16)))
6684 (set (match_dup 3)
6685 (ashiftrt:SI (match_dup 2) (const_int 16)))
6686 (set (match_operand:HI 0 "s_register_operand" "")
6687 (match_dup 4))]
6688 "TARGET_ARM"
6689 "
6690 operands[2] = gen_reg_rtx (SImode);
6691 operands[3] = gen_reg_rtx (SImode);
6692 operands[4] = gen_lowpart (HImode, operands[3]);
6693 "
6694 )
6695
6696 ;; Pattern to recognize insn generated default case above
6697 (define_insn "*movhi_insn_arch4"
6698 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6699 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6700 "TARGET_ARM
6701 && arm_arch4 && !TARGET_HARD_FLOAT
6702 && (register_operand (operands[0], HImode)
6703 || register_operand (operands[1], HImode))"
6704 "@
6705 mov%?\\t%0, %1\\t%@ movhi
6706 mvn%?\\t%0, #%B1\\t%@ movhi
6707 movw%?\\t%0, %L1\\t%@ movhi
6708 strh%?\\t%1, %0\\t%@ movhi
6709 ldrh%?\\t%0, %1\\t%@ movhi"
6710 [(set_attr "predicable" "yes")
6711 (set_attr "pool_range" "*,*,*,*,256")
6712 (set_attr "neg_pool_range" "*,*,*,*,244")
6713 (set_attr "arch" "*,*,v6t2,*,*")
6714 (set_attr_alternative "type"
6715 [(if_then_else (match_operand 1 "const_int_operand" "")
6716 (const_string "mov_imm" )
6717 (const_string "mov_reg"))
6718 (const_string "mvn_imm")
6719 (const_string "mov_imm")
6720 (const_string "store_4")
6721 (const_string "load_4")])]
6722 )
6723
6724 (define_insn "*movhi_bytes"
6725 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6726 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6727 "TARGET_ARM && !TARGET_HARD_FLOAT"
6728 "@
6729 mov%?\\t%0, %1\\t%@ movhi
6730 mov%?\\t%0, %1\\t%@ movhi
6731 mvn%?\\t%0, #%B1\\t%@ movhi"
6732 [(set_attr "predicable" "yes")
6733 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6734 )
6735
6736 ;; We use a DImode scratch because we may occasionally need an additional
6737 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6738 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6739 (define_expand "reload_outhi"
6740 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6741 (match_operand:HI 1 "s_register_operand" "r")
6742 (match_operand:DI 2 "s_register_operand" "=&l")])]
6743 "TARGET_EITHER"
6744 "if (TARGET_ARM)
6745 arm_reload_out_hi (operands);
6746 else
6747 thumb_reload_out_hi (operands);
6748 DONE;
6749 "
6750 )
6751
6752 (define_expand "reload_inhi"
6753 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6754 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6755 (match_operand:DI 2 "s_register_operand" "=&r")])]
6756 "TARGET_EITHER"
6757 "
6758 if (TARGET_ARM)
6759 arm_reload_in_hi (operands);
6760 else
6761 thumb_reload_out_hi (operands);
6762 DONE;
6763 ")
6764
6765 (define_expand "movqi"
6766 [(set (match_operand:QI 0 "general_operand" "")
6767 (match_operand:QI 1 "general_operand" ""))]
6768 "TARGET_EITHER"
6769 "
6770 /* Everything except mem = const or mem = mem can be done easily */
6771
6772 if (can_create_pseudo_p ())
6773 {
6774 if (CONST_INT_P (operands[1]))
6775 {
6776 rtx reg = gen_reg_rtx (SImode);
6777
6778 /* For thumb we want an unsigned immediate, then we are more likely
6779 to be able to use a movs insn. */
6780 if (TARGET_THUMB)
6781 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6782
6783 emit_insn (gen_movsi (reg, operands[1]));
6784 operands[1] = gen_lowpart (QImode, reg);
6785 }
6786
6787 if (TARGET_THUMB)
6788 {
6789 /* ??? We shouldn't really get invalid addresses here, but this can
6790 happen if we are passed a SP (never OK for HImode/QImode) or
6791 virtual register (also rejected as illegitimate for HImode/QImode)
6792 relative address. */
6793 /* ??? This should perhaps be fixed elsewhere, for instance, in
6794 fixup_stack_1, by checking for other kinds of invalid addresses,
6795 e.g. a bare reference to a virtual register. This may confuse the
6796 alpha though, which must handle this case differently. */
6797 if (MEM_P (operands[0])
6798 && !memory_address_p (GET_MODE (operands[0]),
6799 XEXP (operands[0], 0)))
6800 operands[0]
6801 = replace_equiv_address (operands[0],
6802 copy_to_reg (XEXP (operands[0], 0)));
6803 if (MEM_P (operands[1])
6804 && !memory_address_p (GET_MODE (operands[1]),
6805 XEXP (operands[1], 0)))
6806 operands[1]
6807 = replace_equiv_address (operands[1],
6808 copy_to_reg (XEXP (operands[1], 0)));
6809 }
6810
6811 if (MEM_P (operands[1]) && optimize > 0)
6812 {
6813 rtx reg = gen_reg_rtx (SImode);
6814
6815 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6816 operands[1] = gen_lowpart (QImode, reg);
6817 }
6818
6819 if (MEM_P (operands[0]))
6820 operands[1] = force_reg (QImode, operands[1]);
6821 }
6822 else if (TARGET_THUMB
6823 && CONST_INT_P (operands[1])
6824 && !satisfies_constraint_I (operands[1]))
6825 {
6826 /* Handle loading a large integer during reload. */
6827
6828 /* Writing a constant to memory needs a scratch, which should
6829 be handled with SECONDARY_RELOADs. */
6830 gcc_assert (REG_P (operands[0]));
6831
6832 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6833 emit_insn (gen_movsi (operands[0], operands[1]));
6834 DONE;
6835 }
6836 "
6837 )
6838
6839 (define_insn "*arm_movqi_insn"
6840 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6841 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6842 "TARGET_32BIT
6843 && ( register_operand (operands[0], QImode)
6844 || register_operand (operands[1], QImode))"
6845 "@
6846 mov%?\\t%0, %1
6847 mov%?\\t%0, %1
6848 mov%?\\t%0, %1
6849 mov%?\\t%0, %1
6850 mvn%?\\t%0, #%B1
6851 ldrb%?\\t%0, %1
6852 strb%?\\t%1, %0
6853 ldrb%?\\t%0, %1
6854 strb%?\\t%1, %0"
6855 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6856 (set_attr "predicable" "yes")
6857 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6858 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6859 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6860 )
6861
6862 ;; HFmode moves
6863 (define_expand "movhf"
6864 [(set (match_operand:HF 0 "general_operand" "")
6865 (match_operand:HF 1 "general_operand" ""))]
6866 "TARGET_EITHER"
6867 "
6868 if (TARGET_32BIT)
6869 {
6870 if (MEM_P (operands[0]))
6871 operands[1] = force_reg (HFmode, operands[1]);
6872 }
6873 else /* TARGET_THUMB1 */
6874 {
6875 if (can_create_pseudo_p ())
6876 {
6877 if (!REG_P (operands[0]))
6878 operands[1] = force_reg (HFmode, operands[1]);
6879 }
6880 }
6881 "
6882 )
6883
6884 (define_insn "*arm32_movhf"
6885 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6886 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6887 "TARGET_32BIT && !TARGET_HARD_FLOAT
6888 && ( s_register_operand (operands[0], HFmode)
6889 || s_register_operand (operands[1], HFmode))"
6890 "*
6891 switch (which_alternative)
6892 {
6893 case 0: /* ARM register from memory */
6894 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6895 case 1: /* memory from ARM register */
6896 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6897 case 2: /* ARM register from ARM register */
6898 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6899 case 3: /* ARM register from constant */
6900 {
6901 long bits;
6902 rtx ops[4];
6903
6904 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6905 HFmode);
6906 ops[0] = operands[0];
6907 ops[1] = GEN_INT (bits);
6908 ops[2] = GEN_INT (bits & 0xff00);
6909 ops[3] = GEN_INT (bits & 0x00ff);
6910
6911 if (arm_arch_thumb2)
6912 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6913 else
6914 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6915 return \"\";
6916 }
6917 default:
6918 gcc_unreachable ();
6919 }
6920 "
6921 [(set_attr "conds" "unconditional")
6922 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6923 (set_attr "length" "4,4,4,8")
6924 (set_attr "predicable" "yes")]
6925 )
6926
6927 (define_expand "movsf"
6928 [(set (match_operand:SF 0 "general_operand" "")
6929 (match_operand:SF 1 "general_operand" ""))]
6930 "TARGET_EITHER"
6931 "
6932 if (TARGET_32BIT)
6933 {
6934 if (MEM_P (operands[0]))
6935 operands[1] = force_reg (SFmode, operands[1]);
6936 }
6937 else /* TARGET_THUMB1 */
6938 {
6939 if (can_create_pseudo_p ())
6940 {
6941 if (!REG_P (operands[0]))
6942 operands[1] = force_reg (SFmode, operands[1]);
6943 }
6944 }
6945 "
6946 )
6947
6948 ;; Transform a floating-point move of a constant into a core register into
6949 ;; an SImode operation.
6950 (define_split
6951 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6952 (match_operand:SF 1 "immediate_operand" ""))]
6953 "TARGET_EITHER
6954 && reload_completed
6955 && CONST_DOUBLE_P (operands[1])"
6956 [(set (match_dup 2) (match_dup 3))]
6957 "
6958 operands[2] = gen_lowpart (SImode, operands[0]);
6959 operands[3] = gen_lowpart (SImode, operands[1]);
6960 if (operands[2] == 0 || operands[3] == 0)
6961 FAIL;
6962 "
6963 )
6964
6965 (define_insn "*arm_movsf_soft_insn"
6966 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6967 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6968 "TARGET_32BIT
6969 && TARGET_SOFT_FLOAT
6970 && (!MEM_P (operands[0])
6971 || register_operand (operands[1], SFmode))"
6972 "@
6973 mov%?\\t%0, %1
6974 ldr%?\\t%0, %1\\t%@ float
6975 str%?\\t%1, %0\\t%@ float"
6976 [(set_attr "predicable" "yes")
6977 (set_attr "type" "mov_reg,load_4,store_4")
6978 (set_attr "arm_pool_range" "*,4096,*")
6979 (set_attr "thumb2_pool_range" "*,4094,*")
6980 (set_attr "arm_neg_pool_range" "*,4084,*")
6981 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6982 )
6983
6984 (define_expand "movdf"
6985 [(set (match_operand:DF 0 "general_operand" "")
6986 (match_operand:DF 1 "general_operand" ""))]
6987 "TARGET_EITHER"
6988 "
6989 if (TARGET_32BIT)
6990 {
6991 if (MEM_P (operands[0]))
6992 operands[1] = force_reg (DFmode, operands[1]);
6993 }
6994 else /* TARGET_THUMB */
6995 {
6996 if (can_create_pseudo_p ())
6997 {
6998 if (!REG_P (operands[0]))
6999 operands[1] = force_reg (DFmode, operands[1]);
7000 }
7001 }
7002 "
7003 )
7004
7005 ;; Reloading a df mode value stored in integer regs to memory can require a
7006 ;; scratch reg.
7007 (define_expand "reload_outdf"
7008 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7009 (match_operand:DF 1 "s_register_operand" "r")
7010 (match_operand:SI 2 "s_register_operand" "=&r")]
7011 "TARGET_THUMB2"
7012 "
7013 {
7014 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7015
7016 if (code == REG)
7017 operands[2] = XEXP (operands[0], 0);
7018 else if (code == POST_INC || code == PRE_DEC)
7019 {
7020 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7021 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7022 emit_insn (gen_movdi (operands[0], operands[1]));
7023 DONE;
7024 }
7025 else if (code == PRE_INC)
7026 {
7027 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7028
7029 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7030 operands[2] = reg;
7031 }
7032 else if (code == POST_DEC)
7033 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7034 else
7035 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7036 XEXP (XEXP (operands[0], 0), 1)));
7037
7038 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7039 operands[1]));
7040
7041 if (code == POST_DEC)
7042 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7043
7044 DONE;
7045 }"
7046 )
7047
7048 (define_insn "*movdf_soft_insn"
7049 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7050 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7051 "TARGET_32BIT && TARGET_SOFT_FLOAT
7052 && ( register_operand (operands[0], DFmode)
7053 || register_operand (operands[1], DFmode))"
7054 "*
7055 switch (which_alternative)
7056 {
7057 case 0:
7058 case 1:
7059 case 2:
7060 return \"#\";
7061 default:
7062 return output_move_double (operands, true, NULL);
7063 }
7064 "
7065 [(set_attr "length" "8,12,16,8,8")
7066 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7067 (set_attr "arm_pool_range" "*,*,*,1020,*")
7068 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7069 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7070 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7071 )
7072 \f
7073
7074 ;; load- and store-multiple insns
7075 ;; The arm can load/store any set of registers, provided that they are in
7076 ;; ascending order, but these expanders assume a contiguous set.
7077
7078 (define_expand "load_multiple"
7079 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7080 (match_operand:SI 1 "" ""))
7081 (use (match_operand:SI 2 "" ""))])]
7082 "TARGET_32BIT"
7083 {
7084 HOST_WIDE_INT offset = 0;
7085
7086 /* Support only fixed point registers. */
7087 if (!CONST_INT_P (operands[2])
7088 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7089 || INTVAL (operands[2]) < 2
7090 || !MEM_P (operands[1])
7091 || !REG_P (operands[0])
7092 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7093 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7094 FAIL;
7095
7096 operands[3]
7097 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7098 INTVAL (operands[2]),
7099 force_reg (SImode, XEXP (operands[1], 0)),
7100 FALSE, operands[1], &offset);
7101 })
7102
7103 (define_expand "store_multiple"
7104 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7105 (match_operand:SI 1 "" ""))
7106 (use (match_operand:SI 2 "" ""))])]
7107 "TARGET_32BIT"
7108 {
7109 HOST_WIDE_INT offset = 0;
7110
7111 /* Support only fixed point registers. */
7112 if (!CONST_INT_P (operands[2])
7113 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7114 || INTVAL (operands[2]) < 2
7115 || !REG_P (operands[1])
7116 || !MEM_P (operands[0])
7117 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7118 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7119 FAIL;
7120
7121 operands[3]
7122 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7123 INTVAL (operands[2]),
7124 force_reg (SImode, XEXP (operands[0], 0)),
7125 FALSE, operands[0], &offset);
7126 })
7127
7128
7129 (define_expand "setmemsi"
7130 [(match_operand:BLK 0 "general_operand" "")
7131 (match_operand:SI 1 "const_int_operand" "")
7132 (match_operand:SI 2 "const_int_operand" "")
7133 (match_operand:SI 3 "const_int_operand" "")]
7134 "TARGET_32BIT"
7135 {
7136 if (arm_gen_setmem (operands))
7137 DONE;
7138
7139 FAIL;
7140 })
7141
7142
7143 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7144 ;; We could let this apply for blocks of less than this, but it clobbers so
7145 ;; many registers that there is then probably a better way.
7146
7147 (define_expand "movmemqi"
7148 [(match_operand:BLK 0 "general_operand" "")
7149 (match_operand:BLK 1 "general_operand" "")
7150 (match_operand:SI 2 "const_int_operand" "")
7151 (match_operand:SI 3 "const_int_operand" "")]
7152 ""
7153 "
7154 if (TARGET_32BIT)
7155 {
7156 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7157 && !optimize_function_for_size_p (cfun))
7158 {
7159 if (gen_movmem_ldrd_strd (operands))
7160 DONE;
7161 FAIL;
7162 }
7163
7164 if (arm_gen_movmemqi (operands))
7165 DONE;
7166 FAIL;
7167 }
7168 else /* TARGET_THUMB1 */
7169 {
7170 if ( INTVAL (operands[3]) != 4
7171 || INTVAL (operands[2]) > 48)
7172 FAIL;
7173
7174 thumb_expand_movmemqi (operands);
7175 DONE;
7176 }
7177 "
7178 )
7179 \f
7180
7181 ;; Compare & branch insns
7182 ;; The range calculations are based as follows:
7183 ;; For forward branches, the address calculation returns the address of
7184 ;; the next instruction. This is 2 beyond the branch instruction.
7185 ;; For backward branches, the address calculation returns the address of
7186 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7187 ;; instruction for the shortest sequence, and 4 before the branch instruction
7188 ;; if we have to jump around an unconditional branch.
7189 ;; To the basic branch range the PC offset must be added (this is +4).
7190 ;; So for forward branches we have
7191 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7192 ;; And for backward branches we have
7193 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7194 ;;
7195 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7196 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7197
7198 (define_expand "cbranchsi4"
7199 [(set (pc) (if_then_else
7200 (match_operator 0 "expandable_comparison_operator"
7201 [(match_operand:SI 1 "s_register_operand" "")
7202 (match_operand:SI 2 "nonmemory_operand" "")])
7203 (label_ref (match_operand 3 "" ""))
7204 (pc)))]
7205 "TARGET_EITHER"
7206 "
7207 if (!TARGET_THUMB1)
7208 {
7209 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7210 FAIL;
7211 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7212 operands[3]));
7213 DONE;
7214 }
7215 if (thumb1_cmpneg_operand (operands[2], SImode))
7216 {
7217 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7218 operands[3], operands[0]));
7219 DONE;
7220 }
7221 if (!thumb1_cmp_operand (operands[2], SImode))
7222 operands[2] = force_reg (SImode, operands[2]);
7223 ")
7224
7225 (define_expand "cbranchsf4"
7226 [(set (pc) (if_then_else
7227 (match_operator 0 "expandable_comparison_operator"
7228 [(match_operand:SF 1 "s_register_operand" "")
7229 (match_operand:SF 2 "vfp_compare_operand" "")])
7230 (label_ref (match_operand 3 "" ""))
7231 (pc)))]
7232 "TARGET_32BIT && TARGET_HARD_FLOAT"
7233 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7234 operands[3])); DONE;"
7235 )
7236
7237 (define_expand "cbranchdf4"
7238 [(set (pc) (if_then_else
7239 (match_operator 0 "expandable_comparison_operator"
7240 [(match_operand:DF 1 "s_register_operand" "")
7241 (match_operand:DF 2 "vfp_compare_operand" "")])
7242 (label_ref (match_operand 3 "" ""))
7243 (pc)))]
7244 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7245 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7246 operands[3])); DONE;"
7247 )
7248
7249 (define_expand "cbranchdi4"
7250 [(set (pc) (if_then_else
7251 (match_operator 0 "expandable_comparison_operator"
7252 [(match_operand:DI 1 "s_register_operand" "")
7253 (match_operand:DI 2 "cmpdi_operand" "")])
7254 (label_ref (match_operand 3 "" ""))
7255 (pc)))]
7256 "TARGET_32BIT"
7257 "{
7258 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7259 FAIL;
7260 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7261 operands[3]));
7262 DONE;
7263 }"
7264 )
7265
7266 ;; Comparison and test insns
7267
7268 (define_insn "*arm_cmpsi_insn"
7269 [(set (reg:CC CC_REGNUM)
7270 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7271 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7272 "TARGET_32BIT"
7273 "@
7274 cmp%?\\t%0, %1
7275 cmp%?\\t%0, %1
7276 cmp%?\\t%0, %1
7277 cmp%?\\t%0, %1
7278 cmn%?\\t%0, #%n1"
7279 [(set_attr "conds" "set")
7280 (set_attr "arch" "t2,t2,any,any,any")
7281 (set_attr "length" "2,2,4,4,4")
7282 (set_attr "predicable" "yes")
7283 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7284 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7285 )
7286
7287 (define_insn "*cmpsi_shiftsi"
7288 [(set (reg:CC CC_REGNUM)
7289 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7290 (match_operator:SI 3 "shift_operator"
7291 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7292 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7293 "TARGET_32BIT"
7294 "cmp\\t%0, %1%S3"
7295 [(set_attr "conds" "set")
7296 (set_attr "shift" "1")
7297 (set_attr "arch" "32,a,a")
7298 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7299
7300 (define_insn "*cmpsi_shiftsi_swp"
7301 [(set (reg:CC_SWP CC_REGNUM)
7302 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7303 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7304 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7305 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7306 "TARGET_32BIT"
7307 "cmp%?\\t%0, %1%S3"
7308 [(set_attr "conds" "set")
7309 (set_attr "shift" "1")
7310 (set_attr "arch" "32,a,a")
7311 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7312
7313 (define_insn "*arm_cmpsi_negshiftsi_si"
7314 [(set (reg:CC_Z CC_REGNUM)
7315 (compare:CC_Z
7316 (neg:SI (match_operator:SI 1 "shift_operator"
7317 [(match_operand:SI 2 "s_register_operand" "r")
7318 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7319 (match_operand:SI 0 "s_register_operand" "r")))]
7320 "TARGET_ARM"
7321 "cmn%?\\t%0, %2%S1"
7322 [(set_attr "conds" "set")
7323 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7324 (const_string "alus_shift_imm")
7325 (const_string "alus_shift_reg")))
7326 (set_attr "predicable" "yes")]
7327 )
7328
7329 ;; DImode comparisons. The generic code generates branches that
7330 ;; if-conversion can not reduce to a conditional compare, so we do
7331 ;; that directly.
7332
7333 (define_insn_and_split "*arm_cmpdi_insn"
7334 [(set (reg:CC_NCV CC_REGNUM)
7335 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7336 (match_operand:DI 1 "arm_di_operand" "rDi")))
7337 (clobber (match_scratch:SI 2 "=r"))]
7338 "TARGET_32BIT"
7339 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7340 "&& reload_completed"
7341 [(set (reg:CC CC_REGNUM)
7342 (compare:CC (match_dup 0) (match_dup 1)))
7343 (parallel [(set (reg:CC CC_REGNUM)
7344 (compare:CC (match_dup 3) (match_dup 4)))
7345 (set (match_dup 2)
7346 (minus:SI (match_dup 5)
7347 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7348 {
7349 operands[3] = gen_highpart (SImode, operands[0]);
7350 operands[0] = gen_lowpart (SImode, operands[0]);
7351 if (CONST_INT_P (operands[1]))
7352 {
7353 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7354 DImode,
7355 operands[1])));
7356 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7357 }
7358 else
7359 {
7360 operands[4] = gen_highpart (SImode, operands[1]);
7361 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7362 }
7363 operands[1] = gen_lowpart (SImode, operands[1]);
7364 operands[2] = gen_lowpart (SImode, operands[2]);
7365 }
7366 [(set_attr "conds" "set")
7367 (set_attr "length" "8")
7368 (set_attr "type" "multiple")]
7369 )
7370
7371 (define_insn_and_split "*arm_cmpdi_unsigned"
7372 [(set (reg:CC_CZ CC_REGNUM)
7373 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7374 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7375
7376 "TARGET_32BIT"
7377 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7378 "&& reload_completed"
7379 [(set (reg:CC CC_REGNUM)
7380 (compare:CC (match_dup 2) (match_dup 3)))
7381 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7382 (set (reg:CC CC_REGNUM)
7383 (compare:CC (match_dup 0) (match_dup 1))))]
7384 {
7385 operands[2] = gen_highpart (SImode, operands[0]);
7386 operands[0] = gen_lowpart (SImode, operands[0]);
7387 if (CONST_INT_P (operands[1]))
7388 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7389 else
7390 operands[3] = gen_highpart (SImode, operands[1]);
7391 operands[1] = gen_lowpart (SImode, operands[1]);
7392 }
7393 [(set_attr "conds" "set")
7394 (set_attr "enabled_for_short_it" "yes,yes,no,*")
7395 (set_attr "arch" "t2,t2,t2,a")
7396 (set_attr "length" "6,6,10,8")
7397 (set_attr "type" "multiple")]
7398 )
7399
7400 (define_insn "*arm_cmpdi_zero"
7401 [(set (reg:CC_Z CC_REGNUM)
7402 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7403 (const_int 0)))
7404 (clobber (match_scratch:SI 1 "=r"))]
7405 "TARGET_32BIT"
7406 "orrs%?\\t%1, %Q0, %R0"
7407 [(set_attr "conds" "set")
7408 (set_attr "type" "logics_reg")]
7409 )
7410
7411 ; This insn allows redundant compares to be removed by cse, nothing should
7412 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7413 ; is deleted later on. The match_dup will match the mode here, so that
7414 ; mode changes of the condition codes aren't lost by this even though we don't
7415 ; specify what they are.
7416
7417 (define_insn "*deleted_compare"
7418 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7419 "TARGET_32BIT"
7420 "\\t%@ deleted compare"
7421 [(set_attr "conds" "set")
7422 (set_attr "length" "0")
7423 (set_attr "type" "no_insn")]
7424 )
7425
7426 \f
7427 ;; Conditional branch insns
7428
7429 (define_expand "cbranch_cc"
7430 [(set (pc)
7431 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7432 (match_operand 2 "" "")])
7433 (label_ref (match_operand 3 "" ""))
7434 (pc)))]
7435 "TARGET_32BIT"
7436 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7437 operands[1], operands[2], NULL_RTX);
7438 operands[2] = const0_rtx;"
7439 )
7440
7441 ;;
7442 ;; Patterns to match conditional branch insns.
7443 ;;
7444
7445 (define_insn "arm_cond_branch"
7446 [(set (pc)
7447 (if_then_else (match_operator 1 "arm_comparison_operator"
7448 [(match_operand 2 "cc_register" "") (const_int 0)])
7449 (label_ref (match_operand 0 "" ""))
7450 (pc)))]
7451 "TARGET_32BIT"
7452 "*
7453 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7454 {
7455 arm_ccfsm_state += 2;
7456 return \"\";
7457 }
7458 return \"b%d1\\t%l0\";
7459 "
7460 [(set_attr "conds" "use")
7461 (set_attr "type" "branch")
7462 (set (attr "length")
7463 (if_then_else
7464 (and (match_test "TARGET_THUMB2")
7465 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7466 (le (minus (match_dup 0) (pc)) (const_int 256))))
7467 (const_int 2)
7468 (const_int 4)))]
7469 )
7470
7471 (define_insn "*arm_cond_branch_reversed"
7472 [(set (pc)
7473 (if_then_else (match_operator 1 "arm_comparison_operator"
7474 [(match_operand 2 "cc_register" "") (const_int 0)])
7475 (pc)
7476 (label_ref (match_operand 0 "" ""))))]
7477 "TARGET_32BIT"
7478 "*
7479 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7480 {
7481 arm_ccfsm_state += 2;
7482 return \"\";
7483 }
7484 return \"b%D1\\t%l0\";
7485 "
7486 [(set_attr "conds" "use")
7487 (set_attr "type" "branch")
7488 (set (attr "length")
7489 (if_then_else
7490 (and (match_test "TARGET_THUMB2")
7491 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7492 (le (minus (match_dup 0) (pc)) (const_int 256))))
7493 (const_int 2)
7494 (const_int 4)))]
7495 )
7496
7497 \f
7498
7499 ; scc insns
7500
7501 (define_expand "cstore_cc"
7502 [(set (match_operand:SI 0 "s_register_operand" "")
7503 (match_operator:SI 1 "" [(match_operand 2 "" "")
7504 (match_operand 3 "" "")]))]
7505 "TARGET_32BIT"
7506 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7507 operands[2], operands[3], NULL_RTX);
7508 operands[3] = const0_rtx;"
7509 )
7510
7511 (define_insn_and_split "*mov_scc"
7512 [(set (match_operand:SI 0 "s_register_operand" "=r")
7513 (match_operator:SI 1 "arm_comparison_operator_mode"
7514 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7515 "TARGET_ARM"
7516 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7517 "TARGET_ARM"
7518 [(set (match_dup 0)
7519 (if_then_else:SI (match_dup 1)
7520 (const_int 1)
7521 (const_int 0)))]
7522 ""
7523 [(set_attr "conds" "use")
7524 (set_attr "length" "8")
7525 (set_attr "type" "multiple")]
7526 )
7527
7528 (define_insn_and_split "*mov_negscc"
7529 [(set (match_operand:SI 0 "s_register_operand" "=r")
7530 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7531 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7532 "TARGET_ARM"
7533 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7534 "TARGET_ARM"
7535 [(set (match_dup 0)
7536 (if_then_else:SI (match_dup 1)
7537 (match_dup 3)
7538 (const_int 0)))]
7539 {
7540 operands[3] = GEN_INT (~0);
7541 }
7542 [(set_attr "conds" "use")
7543 (set_attr "length" "8")
7544 (set_attr "type" "multiple")]
7545 )
7546
7547 (define_insn_and_split "*mov_notscc"
7548 [(set (match_operand:SI 0 "s_register_operand" "=r")
7549 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7550 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7551 "TARGET_ARM"
7552 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7553 "TARGET_ARM"
7554 [(set (match_dup 0)
7555 (if_then_else:SI (match_dup 1)
7556 (match_dup 3)
7557 (match_dup 4)))]
7558 {
7559 operands[3] = GEN_INT (~1);
7560 operands[4] = GEN_INT (~0);
7561 }
7562 [(set_attr "conds" "use")
7563 (set_attr "length" "8")
7564 (set_attr "type" "multiple")]
7565 )
7566
7567 (define_expand "cstoresi4"
7568 [(set (match_operand:SI 0 "s_register_operand" "")
7569 (match_operator:SI 1 "expandable_comparison_operator"
7570 [(match_operand:SI 2 "s_register_operand" "")
7571 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7572 "TARGET_32BIT || TARGET_THUMB1"
7573 "{
7574 rtx op3, scratch, scratch2;
7575
7576 if (!TARGET_THUMB1)
7577 {
7578 if (!arm_add_operand (operands[3], SImode))
7579 operands[3] = force_reg (SImode, operands[3]);
7580 emit_insn (gen_cstore_cc (operands[0], operands[1],
7581 operands[2], operands[3]));
7582 DONE;
7583 }
7584
7585 if (operands[3] == const0_rtx)
7586 {
7587 switch (GET_CODE (operands[1]))
7588 {
7589 case EQ:
7590 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7591 break;
7592
7593 case NE:
7594 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7595 break;
7596
7597 case LE:
7598 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7599 NULL_RTX, 0, OPTAB_WIDEN);
7600 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7601 NULL_RTX, 0, OPTAB_WIDEN);
7602 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7603 operands[0], 1, OPTAB_WIDEN);
7604 break;
7605
7606 case GE:
7607 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7608 NULL_RTX, 1);
7609 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7610 NULL_RTX, 1, OPTAB_WIDEN);
7611 break;
7612
7613 case GT:
7614 scratch = expand_binop (SImode, ashr_optab, operands[2],
7615 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7616 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7617 NULL_RTX, 0, OPTAB_WIDEN);
7618 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7619 0, OPTAB_WIDEN);
7620 break;
7621
7622 /* LT is handled by generic code. No need for unsigned with 0. */
7623 default:
7624 FAIL;
7625 }
7626 DONE;
7627 }
7628
7629 switch (GET_CODE (operands[1]))
7630 {
7631 case EQ:
7632 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7633 NULL_RTX, 0, OPTAB_WIDEN);
7634 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7635 break;
7636
7637 case NE:
7638 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7639 NULL_RTX, 0, OPTAB_WIDEN);
7640 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7641 break;
7642
7643 case LE:
7644 op3 = force_reg (SImode, operands[3]);
7645
7646 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7647 NULL_RTX, 1, OPTAB_WIDEN);
7648 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7649 NULL_RTX, 0, OPTAB_WIDEN);
7650 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7651 op3, operands[2]));
7652 break;
7653
7654 case GE:
7655 op3 = operands[3];
7656 if (!thumb1_cmp_operand (op3, SImode))
7657 op3 = force_reg (SImode, op3);
7658 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7659 NULL_RTX, 0, OPTAB_WIDEN);
7660 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7661 NULL_RTX, 1, OPTAB_WIDEN);
7662 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7663 operands[2], op3));
7664 break;
7665
7666 case LEU:
7667 op3 = force_reg (SImode, operands[3]);
7668 scratch = force_reg (SImode, const0_rtx);
7669 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7670 op3, operands[2]));
7671 break;
7672
7673 case GEU:
7674 op3 = operands[3];
7675 if (!thumb1_cmp_operand (op3, SImode))
7676 op3 = force_reg (SImode, op3);
7677 scratch = force_reg (SImode, const0_rtx);
7678 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7679 operands[2], op3));
7680 break;
7681
7682 case LTU:
7683 op3 = operands[3];
7684 if (!thumb1_cmp_operand (op3, SImode))
7685 op3 = force_reg (SImode, op3);
7686 scratch = gen_reg_rtx (SImode);
7687 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7688 break;
7689
7690 case GTU:
7691 op3 = force_reg (SImode, operands[3]);
7692 scratch = gen_reg_rtx (SImode);
7693 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7694 break;
7695
7696 /* No good sequences for GT, LT. */
7697 default:
7698 FAIL;
7699 }
7700 DONE;
7701 }")
7702
7703 (define_expand "cstorehf4"
7704 [(set (match_operand:SI 0 "s_register_operand")
7705 (match_operator:SI 1 "expandable_comparison_operator"
7706 [(match_operand:HF 2 "s_register_operand")
7707 (match_operand:HF 3 "vfp_compare_operand")]))]
7708 "TARGET_VFP_FP16INST"
7709 {
7710 if (!arm_validize_comparison (&operands[1],
7711 &operands[2],
7712 &operands[3]))
7713 FAIL;
7714
7715 emit_insn (gen_cstore_cc (operands[0], operands[1],
7716 operands[2], operands[3]));
7717 DONE;
7718 }
7719 )
7720
7721 (define_expand "cstoresf4"
7722 [(set (match_operand:SI 0 "s_register_operand" "")
7723 (match_operator:SI 1 "expandable_comparison_operator"
7724 [(match_operand:SF 2 "s_register_operand" "")
7725 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7726 "TARGET_32BIT && TARGET_HARD_FLOAT"
7727 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7728 operands[2], operands[3])); DONE;"
7729 )
7730
7731 (define_expand "cstoredf4"
7732 [(set (match_operand:SI 0 "s_register_operand" "")
7733 (match_operator:SI 1 "expandable_comparison_operator"
7734 [(match_operand:DF 2 "s_register_operand" "")
7735 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7736 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7737 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7738 operands[2], operands[3])); DONE;"
7739 )
7740
7741 (define_expand "cstoredi4"
7742 [(set (match_operand:SI 0 "s_register_operand" "")
7743 (match_operator:SI 1 "expandable_comparison_operator"
7744 [(match_operand:DI 2 "s_register_operand" "")
7745 (match_operand:DI 3 "cmpdi_operand" "")]))]
7746 "TARGET_32BIT"
7747 "{
7748 if (!arm_validize_comparison (&operands[1],
7749 &operands[2],
7750 &operands[3]))
7751 FAIL;
7752 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7753 operands[3]));
7754 DONE;
7755 }"
7756 )
7757
7758 \f
7759 ;; Conditional move insns
7760
7761 (define_expand "movsicc"
7762 [(set (match_operand:SI 0 "s_register_operand" "")
7763 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7764 (match_operand:SI 2 "arm_not_operand" "")
7765 (match_operand:SI 3 "arm_not_operand" "")))]
7766 "TARGET_32BIT"
7767 "
7768 {
7769 enum rtx_code code;
7770 rtx ccreg;
7771
7772 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7773 &XEXP (operands[1], 1)))
7774 FAIL;
7775
7776 code = GET_CODE (operands[1]);
7777 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7778 XEXP (operands[1], 1), NULL_RTX);
7779 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7780 }"
7781 )
7782
7783 (define_expand "movhfcc"
7784 [(set (match_operand:HF 0 "s_register_operand")
7785 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7786 (match_operand:HF 2 "s_register_operand")
7787 (match_operand:HF 3 "s_register_operand")))]
7788 "TARGET_VFP_FP16INST"
7789 "
7790 {
7791 enum rtx_code code = GET_CODE (operands[1]);
7792 rtx ccreg;
7793
7794 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7795 &XEXP (operands[1], 1)))
7796 FAIL;
7797
7798 code = GET_CODE (operands[1]);
7799 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7800 XEXP (operands[1], 1), NULL_RTX);
7801 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7802 }"
7803 )
7804
7805 (define_expand "movsfcc"
7806 [(set (match_operand:SF 0 "s_register_operand" "")
7807 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7808 (match_operand:SF 2 "s_register_operand" "")
7809 (match_operand:SF 3 "s_register_operand" "")))]
7810 "TARGET_32BIT && TARGET_HARD_FLOAT"
7811 "
7812 {
7813 enum rtx_code code = GET_CODE (operands[1]);
7814 rtx ccreg;
7815
7816 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7817 &XEXP (operands[1], 1)))
7818 FAIL;
7819
7820 code = GET_CODE (operands[1]);
7821 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7822 XEXP (operands[1], 1), NULL_RTX);
7823 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7824 }"
7825 )
7826
7827 (define_expand "movdfcc"
7828 [(set (match_operand:DF 0 "s_register_operand" "")
7829 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7830 (match_operand:DF 2 "s_register_operand" "")
7831 (match_operand:DF 3 "s_register_operand" "")))]
7832 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7833 "
7834 {
7835 enum rtx_code code = GET_CODE (operands[1]);
7836 rtx ccreg;
7837
7838 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7839 &XEXP (operands[1], 1)))
7840 FAIL;
7841 code = GET_CODE (operands[1]);
7842 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7843 XEXP (operands[1], 1), NULL_RTX);
7844 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7845 }"
7846 )
7847
7848 (define_insn "*cmov<mode>"
7849 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7850 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7851 [(match_operand 2 "cc_register" "") (const_int 0)])
7852 (match_operand:SDF 3 "s_register_operand"
7853 "<F_constraint>")
7854 (match_operand:SDF 4 "s_register_operand"
7855 "<F_constraint>")))]
7856 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7857 "*
7858 {
7859 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7860 switch (code)
7861 {
7862 case ARM_GE:
7863 case ARM_GT:
7864 case ARM_EQ:
7865 case ARM_VS:
7866 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7867 case ARM_LT:
7868 case ARM_LE:
7869 case ARM_NE:
7870 case ARM_VC:
7871 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7872 default:
7873 gcc_unreachable ();
7874 }
7875 return \"\";
7876 }"
7877 [(set_attr "conds" "use")
7878 (set_attr "type" "fcsel")]
7879 )
7880
7881 (define_insn "*cmovhf"
7882 [(set (match_operand:HF 0 "s_register_operand" "=t")
7883 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7884 [(match_operand 2 "cc_register" "") (const_int 0)])
7885 (match_operand:HF 3 "s_register_operand" "t")
7886 (match_operand:HF 4 "s_register_operand" "t")))]
7887 "TARGET_VFP_FP16INST"
7888 "*
7889 {
7890 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7891 switch (code)
7892 {
7893 case ARM_GE:
7894 case ARM_GT:
7895 case ARM_EQ:
7896 case ARM_VS:
7897 return \"vsel%d1.f16\\t%0, %3, %4\";
7898 case ARM_LT:
7899 case ARM_LE:
7900 case ARM_NE:
7901 case ARM_VC:
7902 return \"vsel%D1.f16\\t%0, %4, %3\";
7903 default:
7904 gcc_unreachable ();
7905 }
7906 return \"\";
7907 }"
7908 [(set_attr "conds" "use")
7909 (set_attr "type" "fcsel")]
7910 )
7911
7912 (define_insn_and_split "*movsicc_insn"
7913 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7914 (if_then_else:SI
7915 (match_operator 3 "arm_comparison_operator"
7916 [(match_operand 4 "cc_register" "") (const_int 0)])
7917 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7918 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7919 "TARGET_ARM"
7920 "@
7921 mov%D3\\t%0, %2
7922 mvn%D3\\t%0, #%B2
7923 mov%d3\\t%0, %1
7924 mvn%d3\\t%0, #%B1
7925 #
7926 #
7927 #
7928 #"
7929 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7930 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7931 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7932 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7933 "&& reload_completed"
7934 [(const_int 0)]
7935 {
7936 enum rtx_code rev_code;
7937 machine_mode mode;
7938 rtx rev_cond;
7939
7940 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7941 operands[3],
7942 gen_rtx_SET (operands[0], operands[1])));
7943
7944 rev_code = GET_CODE (operands[3]);
7945 mode = GET_MODE (operands[4]);
7946 if (mode == CCFPmode || mode == CCFPEmode)
7947 rev_code = reverse_condition_maybe_unordered (rev_code);
7948 else
7949 rev_code = reverse_condition (rev_code);
7950
7951 rev_cond = gen_rtx_fmt_ee (rev_code,
7952 VOIDmode,
7953 operands[4],
7954 const0_rtx);
7955 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7956 rev_cond,
7957 gen_rtx_SET (operands[0], operands[2])));
7958 DONE;
7959 }
7960 [(set_attr "length" "4,4,4,4,8,8,8,8")
7961 (set_attr "conds" "use")
7962 (set_attr_alternative "type"
7963 [(if_then_else (match_operand 2 "const_int_operand" "")
7964 (const_string "mov_imm")
7965 (const_string "mov_reg"))
7966 (const_string "mvn_imm")
7967 (if_then_else (match_operand 1 "const_int_operand" "")
7968 (const_string "mov_imm")
7969 (const_string "mov_reg"))
7970 (const_string "mvn_imm")
7971 (const_string "multiple")
7972 (const_string "multiple")
7973 (const_string "multiple")
7974 (const_string "multiple")])]
7975 )
7976
7977 (define_insn "*movsfcc_soft_insn"
7978 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7979 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7980 [(match_operand 4 "cc_register" "") (const_int 0)])
7981 (match_operand:SF 1 "s_register_operand" "0,r")
7982 (match_operand:SF 2 "s_register_operand" "r,0")))]
7983 "TARGET_ARM && TARGET_SOFT_FLOAT"
7984 "@
7985 mov%D3\\t%0, %2
7986 mov%d3\\t%0, %1"
7987 [(set_attr "conds" "use")
7988 (set_attr "type" "mov_reg")]
7989 )
7990
7991 \f
7992 ;; Jump and linkage insns
7993
7994 (define_expand "jump"
7995 [(set (pc)
7996 (label_ref (match_operand 0 "" "")))]
7997 "TARGET_EITHER"
7998 ""
7999 )
8000
8001 (define_insn "*arm_jump"
8002 [(set (pc)
8003 (label_ref (match_operand 0 "" "")))]
8004 "TARGET_32BIT"
8005 "*
8006 {
8007 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8008 {
8009 arm_ccfsm_state += 2;
8010 return \"\";
8011 }
8012 return \"b%?\\t%l0\";
8013 }
8014 "
8015 [(set_attr "predicable" "yes")
8016 (set (attr "length")
8017 (if_then_else
8018 (and (match_test "TARGET_THUMB2")
8019 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8020 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8021 (const_int 2)
8022 (const_int 4)))
8023 (set_attr "type" "branch")]
8024 )
8025
8026 (define_expand "call"
8027 [(parallel [(call (match_operand 0 "memory_operand" "")
8028 (match_operand 1 "general_operand" ""))
8029 (use (match_operand 2 "" ""))
8030 (clobber (reg:SI LR_REGNUM))])]
8031 "TARGET_EITHER"
8032 "
8033 {
8034 rtx callee, pat;
8035 tree addr = MEM_EXPR (operands[0]);
8036
8037 /* In an untyped call, we can get NULL for operand 2. */
8038 if (operands[2] == NULL_RTX)
8039 operands[2] = const0_rtx;
8040
8041 /* Decide if we should generate indirect calls by loading the
8042 32-bit address of the callee into a register before performing the
8043 branch and link. */
8044 callee = XEXP (operands[0], 0);
8045 if (GET_CODE (callee) == SYMBOL_REF
8046 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8047 : !REG_P (callee))
8048 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8049
8050 if (detect_cmse_nonsecure_call (addr))
8051 {
8052 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8053 operands[2]);
8054 emit_call_insn (pat);
8055 }
8056 else
8057 {
8058 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8059 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8060 }
8061 DONE;
8062 }"
8063 )
8064
8065 (define_expand "call_internal"
8066 [(parallel [(call (match_operand 0 "memory_operand" "")
8067 (match_operand 1 "general_operand" ""))
8068 (use (match_operand 2 "" ""))
8069 (clobber (reg:SI LR_REGNUM))])])
8070
8071 (define_expand "nonsecure_call_internal"
8072 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8073 UNSPEC_NONSECURE_MEM)
8074 (match_operand 1 "general_operand" ""))
8075 (use (match_operand 2 "" ""))
8076 (clobber (reg:SI LR_REGNUM))])]
8077 "use_cmse"
8078 "
8079 {
8080 rtx tmp;
8081 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8082 gen_rtx_REG (SImode, R4_REGNUM),
8083 SImode);
8084
8085 operands[0] = replace_equiv_address (operands[0], tmp);
8086 }")
8087
8088 (define_insn "*call_reg_armv5"
8089 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8090 (match_operand 1 "" ""))
8091 (use (match_operand 2 "" ""))
8092 (clobber (reg:SI LR_REGNUM))]
8093 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8094 "blx%?\\t%0"
8095 [(set_attr "type" "call")]
8096 )
8097
8098 (define_insn "*call_reg_arm"
8099 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8100 (match_operand 1 "" ""))
8101 (use (match_operand 2 "" ""))
8102 (clobber (reg:SI LR_REGNUM))]
8103 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8104 "*
8105 return output_call (operands);
8106 "
8107 ;; length is worst case, normally it is only two
8108 [(set_attr "length" "12")
8109 (set_attr "type" "call")]
8110 )
8111
8112
8113 (define_expand "call_value"
8114 [(parallel [(set (match_operand 0 "" "")
8115 (call (match_operand 1 "memory_operand" "")
8116 (match_operand 2 "general_operand" "")))
8117 (use (match_operand 3 "" ""))
8118 (clobber (reg:SI LR_REGNUM))])]
8119 "TARGET_EITHER"
8120 "
8121 {
8122 rtx pat, callee;
8123 tree addr = MEM_EXPR (operands[1]);
8124
8125 /* In an untyped call, we can get NULL for operand 2. */
8126 if (operands[3] == 0)
8127 operands[3] = const0_rtx;
8128
8129 /* Decide if we should generate indirect calls by loading the
8130 32-bit address of the callee into a register before performing the
8131 branch and link. */
8132 callee = XEXP (operands[1], 0);
8133 if (GET_CODE (callee) == SYMBOL_REF
8134 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8135 : !REG_P (callee))
8136 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8137
8138 if (detect_cmse_nonsecure_call (addr))
8139 {
8140 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8141 operands[2], operands[3]);
8142 emit_call_insn (pat);
8143 }
8144 else
8145 {
8146 pat = gen_call_value_internal (operands[0], operands[1],
8147 operands[2], operands[3]);
8148 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8149 }
8150 DONE;
8151 }"
8152 )
8153
8154 (define_expand "call_value_internal"
8155 [(parallel [(set (match_operand 0 "" "")
8156 (call (match_operand 1 "memory_operand" "")
8157 (match_operand 2 "general_operand" "")))
8158 (use (match_operand 3 "" ""))
8159 (clobber (reg:SI LR_REGNUM))])])
8160
8161 (define_expand "nonsecure_call_value_internal"
8162 [(parallel [(set (match_operand 0 "" "")
8163 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8164 UNSPEC_NONSECURE_MEM)
8165 (match_operand 2 "general_operand" "")))
8166 (use (match_operand 3 "" ""))
8167 (clobber (reg:SI LR_REGNUM))])]
8168 "use_cmse"
8169 "
8170 {
8171 rtx tmp;
8172 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8173 gen_rtx_REG (SImode, R4_REGNUM),
8174 SImode);
8175
8176 operands[1] = replace_equiv_address (operands[1], tmp);
8177 }")
8178
8179 (define_insn "*call_value_reg_armv5"
8180 [(set (match_operand 0 "" "")
8181 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8182 (match_operand 2 "" "")))
8183 (use (match_operand 3 "" ""))
8184 (clobber (reg:SI LR_REGNUM))]
8185 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8186 "blx%?\\t%1"
8187 [(set_attr "type" "call")]
8188 )
8189
8190 (define_insn "*call_value_reg_arm"
8191 [(set (match_operand 0 "" "")
8192 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8193 (match_operand 2 "" "")))
8194 (use (match_operand 3 "" ""))
8195 (clobber (reg:SI LR_REGNUM))]
8196 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8197 "*
8198 return output_call (&operands[1]);
8199 "
8200 [(set_attr "length" "12")
8201 (set_attr "type" "call")]
8202 )
8203
8204 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8205 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8206
8207 (define_insn "*call_symbol"
8208 [(call (mem:SI (match_operand:SI 0 "" ""))
8209 (match_operand 1 "" ""))
8210 (use (match_operand 2 "" ""))
8211 (clobber (reg:SI LR_REGNUM))]
8212 "TARGET_32BIT
8213 && !SIBLING_CALL_P (insn)
8214 && (GET_CODE (operands[0]) == SYMBOL_REF)
8215 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8216 "*
8217 {
8218 rtx op = operands[0];
8219
8220 /* Switch mode now when possible. */
8221 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8222 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8223 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8224
8225 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8226 }"
8227 [(set_attr "type" "call")]
8228 )
8229
8230 (define_insn "*call_value_symbol"
8231 [(set (match_operand 0 "" "")
8232 (call (mem:SI (match_operand:SI 1 "" ""))
8233 (match_operand:SI 2 "" "")))
8234 (use (match_operand 3 "" ""))
8235 (clobber (reg:SI LR_REGNUM))]
8236 "TARGET_32BIT
8237 && !SIBLING_CALL_P (insn)
8238 && (GET_CODE (operands[1]) == SYMBOL_REF)
8239 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8240 "*
8241 {
8242 rtx op = operands[1];
8243
8244 /* Switch mode now when possible. */
8245 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8246 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8247 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8248
8249 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8250 }"
8251 [(set_attr "type" "call")]
8252 )
8253
8254 (define_expand "sibcall_internal"
8255 [(parallel [(call (match_operand 0 "memory_operand" "")
8256 (match_operand 1 "general_operand" ""))
8257 (return)
8258 (use (match_operand 2 "" ""))])])
8259
8260 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8261 (define_expand "sibcall"
8262 [(parallel [(call (match_operand 0 "memory_operand" "")
8263 (match_operand 1 "general_operand" ""))
8264 (return)
8265 (use (match_operand 2 "" ""))])]
8266 "TARGET_32BIT"
8267 "
8268 {
8269 rtx pat;
8270
8271 if ((!REG_P (XEXP (operands[0], 0))
8272 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8273 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8274 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8275 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8276
8277 if (operands[2] == NULL_RTX)
8278 operands[2] = const0_rtx;
8279
8280 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8281 arm_emit_call_insn (pat, operands[0], true);
8282 DONE;
8283 }"
8284 )
8285
8286 (define_expand "sibcall_value_internal"
8287 [(parallel [(set (match_operand 0 "" "")
8288 (call (match_operand 1 "memory_operand" "")
8289 (match_operand 2 "general_operand" "")))
8290 (return)
8291 (use (match_operand 3 "" ""))])])
8292
8293 (define_expand "sibcall_value"
8294 [(parallel [(set (match_operand 0 "" "")
8295 (call (match_operand 1 "memory_operand" "")
8296 (match_operand 2 "general_operand" "")))
8297 (return)
8298 (use (match_operand 3 "" ""))])]
8299 "TARGET_32BIT"
8300 "
8301 {
8302 rtx pat;
8303
8304 if ((!REG_P (XEXP (operands[1], 0))
8305 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8306 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8307 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8308 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8309
8310 if (operands[3] == NULL_RTX)
8311 operands[3] = const0_rtx;
8312
8313 pat = gen_sibcall_value_internal (operands[0], operands[1],
8314 operands[2], operands[3]);
8315 arm_emit_call_insn (pat, operands[1], true);
8316 DONE;
8317 }"
8318 )
8319
8320 (define_insn "*sibcall_insn"
8321 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8322 (match_operand 1 "" ""))
8323 (return)
8324 (use (match_operand 2 "" ""))]
8325 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8326 "*
8327 if (which_alternative == 1)
8328 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8329 else
8330 {
8331 if (arm_arch5 || arm_arch4t)
8332 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8333 else
8334 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8335 }
8336 "
8337 [(set_attr "type" "call")]
8338 )
8339
8340 (define_insn "*sibcall_value_insn"
8341 [(set (match_operand 0 "" "")
8342 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8343 (match_operand 2 "" "")))
8344 (return)
8345 (use (match_operand 3 "" ""))]
8346 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8347 "*
8348 if (which_alternative == 1)
8349 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8350 else
8351 {
8352 if (arm_arch5 || arm_arch4t)
8353 return \"bx%?\\t%1\";
8354 else
8355 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8356 }
8357 "
8358 [(set_attr "type" "call")]
8359 )
8360
8361 (define_expand "<return_str>return"
8362 [(RETURNS)]
8363 "(TARGET_ARM || (TARGET_THUMB2
8364 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8365 && !IS_STACKALIGN (arm_current_func_type ())))
8366 <return_cond_false>"
8367 "
8368 {
8369 if (TARGET_THUMB2)
8370 {
8371 thumb2_expand_return (<return_simple_p>);
8372 DONE;
8373 }
8374 }
8375 "
8376 )
8377
8378 ;; Often the return insn will be the same as loading from memory, so set attr
8379 (define_insn "*arm_return"
8380 [(return)]
8381 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8382 "*
8383 {
8384 if (arm_ccfsm_state == 2)
8385 {
8386 arm_ccfsm_state += 2;
8387 return \"\";
8388 }
8389 return output_return_instruction (const_true_rtx, true, false, false);
8390 }"
8391 [(set_attr "type" "load_4")
8392 (set_attr "length" "12")
8393 (set_attr "predicable" "yes")]
8394 )
8395
8396 (define_insn "*cond_<return_str>return"
8397 [(set (pc)
8398 (if_then_else (match_operator 0 "arm_comparison_operator"
8399 [(match_operand 1 "cc_register" "") (const_int 0)])
8400 (RETURNS)
8401 (pc)))]
8402 "TARGET_ARM <return_cond_true>"
8403 "*
8404 {
8405 if (arm_ccfsm_state == 2)
8406 {
8407 arm_ccfsm_state += 2;
8408 return \"\";
8409 }
8410 return output_return_instruction (operands[0], true, false,
8411 <return_simple_p>);
8412 }"
8413 [(set_attr "conds" "use")
8414 (set_attr "length" "12")
8415 (set_attr "type" "load_4")]
8416 )
8417
8418 (define_insn "*cond_<return_str>return_inverted"
8419 [(set (pc)
8420 (if_then_else (match_operator 0 "arm_comparison_operator"
8421 [(match_operand 1 "cc_register" "") (const_int 0)])
8422 (pc)
8423 (RETURNS)))]
8424 "TARGET_ARM <return_cond_true>"
8425 "*
8426 {
8427 if (arm_ccfsm_state == 2)
8428 {
8429 arm_ccfsm_state += 2;
8430 return \"\";
8431 }
8432 return output_return_instruction (operands[0], true, true,
8433 <return_simple_p>);
8434 }"
8435 [(set_attr "conds" "use")
8436 (set_attr "length" "12")
8437 (set_attr "type" "load_4")]
8438 )
8439
8440 (define_insn "*arm_simple_return"
8441 [(simple_return)]
8442 "TARGET_ARM"
8443 "*
8444 {
8445 if (arm_ccfsm_state == 2)
8446 {
8447 arm_ccfsm_state += 2;
8448 return \"\";
8449 }
8450 return output_return_instruction (const_true_rtx, true, false, true);
8451 }"
8452 [(set_attr "type" "branch")
8453 (set_attr "length" "4")
8454 (set_attr "predicable" "yes")]
8455 )
8456
8457 ;; Generate a sequence of instructions to determine if the processor is
8458 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8459 ;; mask.
8460
8461 (define_expand "return_addr_mask"
8462 [(set (match_dup 1)
8463 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8464 (const_int 0)))
8465 (set (match_operand:SI 0 "s_register_operand" "")
8466 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8467 (const_int -1)
8468 (const_int 67108860)))] ; 0x03fffffc
8469 "TARGET_ARM"
8470 "
8471 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8472 ")
8473
8474 (define_insn "*check_arch2"
8475 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8476 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8477 (const_int 0)))]
8478 "TARGET_ARM"
8479 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8480 [(set_attr "length" "8")
8481 (set_attr "conds" "set")
8482 (set_attr "type" "multiple")]
8483 )
8484
8485 ;; Call subroutine returning any type.
8486
8487 (define_expand "untyped_call"
8488 [(parallel [(call (match_operand 0 "" "")
8489 (const_int 0))
8490 (match_operand 1 "" "")
8491 (match_operand 2 "" "")])]
8492 "TARGET_EITHER"
8493 "
8494 {
8495 int i;
8496 rtx par = gen_rtx_PARALLEL (VOIDmode,
8497 rtvec_alloc (XVECLEN (operands[2], 0)));
8498 rtx addr = gen_reg_rtx (Pmode);
8499 rtx mem;
8500 int size = 0;
8501
8502 emit_move_insn (addr, XEXP (operands[1], 0));
8503 mem = change_address (operands[1], BLKmode, addr);
8504
8505 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8506 {
8507 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8508
8509 /* Default code only uses r0 as a return value, but we could
8510 be using anything up to 4 registers. */
8511 if (REGNO (src) == R0_REGNUM)
8512 src = gen_rtx_REG (TImode, R0_REGNUM);
8513
8514 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8515 GEN_INT (size));
8516 size += GET_MODE_SIZE (GET_MODE (src));
8517 }
8518
8519 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8520
8521 size = 0;
8522
8523 for (i = 0; i < XVECLEN (par, 0); i++)
8524 {
8525 HOST_WIDE_INT offset = 0;
8526 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8527
8528 if (size != 0)
8529 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8530
8531 mem = change_address (mem, GET_MODE (reg), NULL);
8532 if (REGNO (reg) == R0_REGNUM)
8533 {
8534 /* On thumb we have to use a write-back instruction. */
8535 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8536 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8537 size = TARGET_ARM ? 16 : 0;
8538 }
8539 else
8540 {
8541 emit_move_insn (mem, reg);
8542 size = GET_MODE_SIZE (GET_MODE (reg));
8543 }
8544 }
8545
8546 /* The optimizer does not know that the call sets the function value
8547 registers we stored in the result block. We avoid problems by
8548 claiming that all hard registers are used and clobbered at this
8549 point. */
8550 emit_insn (gen_blockage ());
8551
8552 DONE;
8553 }"
8554 )
8555
8556 (define_expand "untyped_return"
8557 [(match_operand:BLK 0 "memory_operand" "")
8558 (match_operand 1 "" "")]
8559 "TARGET_EITHER"
8560 "
8561 {
8562 int i;
8563 rtx addr = gen_reg_rtx (Pmode);
8564 rtx mem;
8565 int size = 0;
8566
8567 emit_move_insn (addr, XEXP (operands[0], 0));
8568 mem = change_address (operands[0], BLKmode, addr);
8569
8570 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8571 {
8572 HOST_WIDE_INT offset = 0;
8573 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8574
8575 if (size != 0)
8576 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8577
8578 mem = change_address (mem, GET_MODE (reg), NULL);
8579 if (REGNO (reg) == R0_REGNUM)
8580 {
8581 /* On thumb we have to use a write-back instruction. */
8582 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8583 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8584 size = TARGET_ARM ? 16 : 0;
8585 }
8586 else
8587 {
8588 emit_move_insn (reg, mem);
8589 size = GET_MODE_SIZE (GET_MODE (reg));
8590 }
8591 }
8592
8593 /* Emit USE insns before the return. */
8594 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8595 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8596
8597 /* Construct the return. */
8598 expand_naked_return ();
8599
8600 DONE;
8601 }"
8602 )
8603
8604 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8605 ;; all of memory. This blocks insns from being moved across this point.
8606
8607 (define_insn "blockage"
8608 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8609 "TARGET_EITHER"
8610 ""
8611 [(set_attr "length" "0")
8612 (set_attr "type" "block")]
8613 )
8614
8615 (define_insn "probe_stack"
8616 [(set (match_operand:SI 0 "memory_operand" "=m")
8617 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8618 "TARGET_32BIT"
8619 "str%?\\tr0, %0"
8620 [(set_attr "type" "store_4")
8621 (set_attr "predicable" "yes")]
8622 )
8623
8624 (define_insn "probe_stack_range"
8625 [(set (match_operand:SI 0 "register_operand" "=r")
8626 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8627 (match_operand:SI 2 "register_operand" "r")]
8628 VUNSPEC_PROBE_STACK_RANGE))]
8629 "TARGET_32BIT"
8630 {
8631 return output_probe_stack_range (operands[0], operands[2]);
8632 }
8633 [(set_attr "type" "multiple")
8634 (set_attr "conds" "clob")]
8635 )
8636
8637 (define_expand "casesi"
8638 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8639 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8640 (match_operand:SI 2 "const_int_operand" "") ; total range
8641 (match_operand:SI 3 "" "") ; table label
8642 (match_operand:SI 4 "" "")] ; Out of range label
8643 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8644 "
8645 {
8646 enum insn_code code;
8647 if (operands[1] != const0_rtx)
8648 {
8649 rtx reg = gen_reg_rtx (SImode);
8650
8651 emit_insn (gen_addsi3 (reg, operands[0],
8652 gen_int_mode (-INTVAL (operands[1]),
8653 SImode)));
8654 operands[0] = reg;
8655 }
8656
8657 if (TARGET_ARM)
8658 code = CODE_FOR_arm_casesi_internal;
8659 else if (TARGET_THUMB1)
8660 code = CODE_FOR_thumb1_casesi_internal_pic;
8661 else if (flag_pic)
8662 code = CODE_FOR_thumb2_casesi_internal_pic;
8663 else
8664 code = CODE_FOR_thumb2_casesi_internal;
8665
8666 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8667 operands[2] = force_reg (SImode, operands[2]);
8668
8669 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8670 operands[3], operands[4]));
8671 DONE;
8672 }"
8673 )
8674
8675 ;; The USE in this pattern is needed to tell flow analysis that this is
8676 ;; a CASESI insn. It has no other purpose.
8677 (define_insn "arm_casesi_internal"
8678 [(parallel [(set (pc)
8679 (if_then_else
8680 (leu (match_operand:SI 0 "s_register_operand" "r")
8681 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8682 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8683 (label_ref (match_operand 2 "" ""))))
8684 (label_ref (match_operand 3 "" ""))))
8685 (clobber (reg:CC CC_REGNUM))
8686 (use (label_ref (match_dup 2)))])]
8687 "TARGET_ARM"
8688 "*
8689 if (flag_pic)
8690 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8691 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8692 "
8693 [(set_attr "conds" "clob")
8694 (set_attr "length" "12")
8695 (set_attr "type" "multiple")]
8696 )
8697
8698 (define_expand "indirect_jump"
8699 [(set (pc)
8700 (match_operand:SI 0 "s_register_operand" ""))]
8701 "TARGET_EITHER"
8702 "
8703 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8704 address and use bx. */
8705 if (TARGET_THUMB2)
8706 {
8707 rtx tmp;
8708 tmp = gen_reg_rtx (SImode);
8709 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8710 operands[0] = tmp;
8711 }
8712 "
8713 )
8714
8715 ;; NB Never uses BX.
8716 (define_insn "*arm_indirect_jump"
8717 [(set (pc)
8718 (match_operand:SI 0 "s_register_operand" "r"))]
8719 "TARGET_ARM"
8720 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8721 [(set_attr "predicable" "yes")
8722 (set_attr "type" "branch")]
8723 )
8724
8725 (define_insn "*load_indirect_jump"
8726 [(set (pc)
8727 (match_operand:SI 0 "memory_operand" "m"))]
8728 "TARGET_ARM"
8729 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8730 [(set_attr "type" "load_4")
8731 (set_attr "pool_range" "4096")
8732 (set_attr "neg_pool_range" "4084")
8733 (set_attr "predicable" "yes")]
8734 )
8735
8736 \f
8737 ;; Misc insns
8738
8739 (define_insn "nop"
8740 [(const_int 0)]
8741 "TARGET_EITHER"
8742 "nop"
8743 [(set (attr "length")
8744 (if_then_else (eq_attr "is_thumb" "yes")
8745 (const_int 2)
8746 (const_int 4)))
8747 (set_attr "type" "mov_reg")]
8748 )
8749
8750 (define_insn "trap"
8751 [(trap_if (const_int 1) (const_int 0))]
8752 ""
8753 "*
8754 if (TARGET_ARM)
8755 return \".inst\\t0xe7f000f0\";
8756 else
8757 return \".inst\\t0xdeff\";
8758 "
8759 [(set (attr "length")
8760 (if_then_else (eq_attr "is_thumb" "yes")
8761 (const_int 2)
8762 (const_int 4)))
8763 (set_attr "type" "trap")
8764 (set_attr "conds" "unconditional")]
8765 )
8766
8767 \f
8768 ;; Patterns to allow combination of arithmetic, cond code and shifts
8769
8770 (define_insn "*<arith_shift_insn>_multsi"
8771 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8772 (SHIFTABLE_OPS:SI
8773 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8774 (match_operand:SI 3 "power_of_two_operand" ""))
8775 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8776 "TARGET_32BIT"
8777 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8778 [(set_attr "predicable" "yes")
8779 (set_attr "shift" "2")
8780 (set_attr "arch" "a,t2")
8781 (set_attr "type" "alu_shift_imm")])
8782
8783 (define_insn "*<arith_shift_insn>_shiftsi"
8784 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8785 (SHIFTABLE_OPS:SI
8786 (match_operator:SI 2 "shift_nomul_operator"
8787 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8788 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8789 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8790 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8791 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8792 [(set_attr "predicable" "yes")
8793 (set_attr "shift" "3")
8794 (set_attr "arch" "a,t2,a")
8795 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8796
8797 (define_split
8798 [(set (match_operand:SI 0 "s_register_operand" "")
8799 (match_operator:SI 1 "shiftable_operator"
8800 [(match_operator:SI 2 "shiftable_operator"
8801 [(match_operator:SI 3 "shift_operator"
8802 [(match_operand:SI 4 "s_register_operand" "")
8803 (match_operand:SI 5 "reg_or_int_operand" "")])
8804 (match_operand:SI 6 "s_register_operand" "")])
8805 (match_operand:SI 7 "arm_rhs_operand" "")]))
8806 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8807 "TARGET_32BIT"
8808 [(set (match_dup 8)
8809 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8810 (match_dup 6)]))
8811 (set (match_dup 0)
8812 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8813 "")
8814
8815 (define_insn "*arith_shiftsi_compare0"
8816 [(set (reg:CC_NOOV CC_REGNUM)
8817 (compare:CC_NOOV
8818 (match_operator:SI 1 "shiftable_operator"
8819 [(match_operator:SI 3 "shift_operator"
8820 [(match_operand:SI 4 "s_register_operand" "r,r")
8821 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8822 (match_operand:SI 2 "s_register_operand" "r,r")])
8823 (const_int 0)))
8824 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8825 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8826 (match_dup 2)]))]
8827 "TARGET_32BIT"
8828 "%i1s%?\\t%0, %2, %4%S3"
8829 [(set_attr "conds" "set")
8830 (set_attr "shift" "4")
8831 (set_attr "arch" "32,a")
8832 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8833
8834 (define_insn "*arith_shiftsi_compare0_scratch"
8835 [(set (reg:CC_NOOV CC_REGNUM)
8836 (compare:CC_NOOV
8837 (match_operator:SI 1 "shiftable_operator"
8838 [(match_operator:SI 3 "shift_operator"
8839 [(match_operand:SI 4 "s_register_operand" "r,r")
8840 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8841 (match_operand:SI 2 "s_register_operand" "r,r")])
8842 (const_int 0)))
8843 (clobber (match_scratch:SI 0 "=r,r"))]
8844 "TARGET_32BIT"
8845 "%i1s%?\\t%0, %2, %4%S3"
8846 [(set_attr "conds" "set")
8847 (set_attr "shift" "4")
8848 (set_attr "arch" "32,a")
8849 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8850
8851 (define_insn "*sub_shiftsi"
8852 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8853 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8854 (match_operator:SI 2 "shift_operator"
8855 [(match_operand:SI 3 "s_register_operand" "r,r")
8856 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8857 "TARGET_32BIT"
8858 "sub%?\\t%0, %1, %3%S2"
8859 [(set_attr "predicable" "yes")
8860 (set_attr "predicable_short_it" "no")
8861 (set_attr "shift" "3")
8862 (set_attr "arch" "32,a")
8863 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8864
8865 (define_insn "*sub_shiftsi_compare0"
8866 [(set (reg:CC_NOOV CC_REGNUM)
8867 (compare:CC_NOOV
8868 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8869 (match_operator:SI 2 "shift_operator"
8870 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8871 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8872 (const_int 0)))
8873 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8874 (minus:SI (match_dup 1)
8875 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8876 "TARGET_32BIT"
8877 "subs%?\\t%0, %1, %3%S2"
8878 [(set_attr "conds" "set")
8879 (set_attr "shift" "3")
8880 (set_attr "arch" "32,a,a")
8881 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8882
8883 (define_insn "*sub_shiftsi_compare0_scratch"
8884 [(set (reg:CC_NOOV CC_REGNUM)
8885 (compare:CC_NOOV
8886 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8887 (match_operator:SI 2 "shift_operator"
8888 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8889 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8890 (const_int 0)))
8891 (clobber (match_scratch:SI 0 "=r,r,r"))]
8892 "TARGET_32BIT"
8893 "subs%?\\t%0, %1, %3%S2"
8894 [(set_attr "conds" "set")
8895 (set_attr "shift" "3")
8896 (set_attr "arch" "32,a,a")
8897 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8898 \f
8899
8900 (define_insn_and_split "*and_scc"
8901 [(set (match_operand:SI 0 "s_register_operand" "=r")
8902 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8903 [(match_operand 2 "cc_register" "") (const_int 0)])
8904 (match_operand:SI 3 "s_register_operand" "r")))]
8905 "TARGET_ARM"
8906 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8907 "&& reload_completed"
8908 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8909 (cond_exec (match_dup 4) (set (match_dup 0)
8910 (and:SI (match_dup 3) (const_int 1))))]
8911 {
8912 machine_mode mode = GET_MODE (operands[2]);
8913 enum rtx_code rc = GET_CODE (operands[1]);
8914
8915 /* Note that operands[4] is the same as operands[1],
8916 but with VOIDmode as the result. */
8917 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8918 if (mode == CCFPmode || mode == CCFPEmode)
8919 rc = reverse_condition_maybe_unordered (rc);
8920 else
8921 rc = reverse_condition (rc);
8922 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8923 }
8924 [(set_attr "conds" "use")
8925 (set_attr "type" "multiple")
8926 (set_attr "length" "8")]
8927 )
8928
8929 (define_insn_and_split "*ior_scc"
8930 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8931 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8932 [(match_operand 2 "cc_register" "") (const_int 0)])
8933 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8934 "TARGET_ARM"
8935 "@
8936 orr%d1\\t%0, %3, #1
8937 #"
8938 "&& reload_completed
8939 && REGNO (operands [0]) != REGNO (operands[3])"
8940 ;; && which_alternative == 1
8941 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8942 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8943 (cond_exec (match_dup 4) (set (match_dup 0)
8944 (ior:SI (match_dup 3) (const_int 1))))]
8945 {
8946 machine_mode mode = GET_MODE (operands[2]);
8947 enum rtx_code rc = GET_CODE (operands[1]);
8948
8949 /* Note that operands[4] is the same as operands[1],
8950 but with VOIDmode as the result. */
8951 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8952 if (mode == CCFPmode || mode == CCFPEmode)
8953 rc = reverse_condition_maybe_unordered (rc);
8954 else
8955 rc = reverse_condition (rc);
8956 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8957 }
8958 [(set_attr "conds" "use")
8959 (set_attr "length" "4,8")
8960 (set_attr "type" "logic_imm,multiple")]
8961 )
8962
8963 ; A series of splitters for the compare_scc pattern below. Note that
8964 ; order is important.
8965 (define_split
8966 [(set (match_operand:SI 0 "s_register_operand" "")
8967 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8968 (const_int 0)))
8969 (clobber (reg:CC CC_REGNUM))]
8970 "TARGET_32BIT && reload_completed"
8971 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8972
8973 (define_split
8974 [(set (match_operand:SI 0 "s_register_operand" "")
8975 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8976 (const_int 0)))
8977 (clobber (reg:CC CC_REGNUM))]
8978 "TARGET_32BIT && reload_completed"
8979 [(set (match_dup 0) (not:SI (match_dup 1)))
8980 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8981
8982 (define_split
8983 [(set (match_operand:SI 0 "s_register_operand" "")
8984 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8985 (const_int 0)))
8986 (clobber (reg:CC CC_REGNUM))]
8987 "arm_arch5 && TARGET_32BIT"
8988 [(set (match_dup 0) (clz:SI (match_dup 1)))
8989 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8990 )
8991
8992 (define_split
8993 [(set (match_operand:SI 0 "s_register_operand" "")
8994 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8995 (const_int 0)))
8996 (clobber (reg:CC CC_REGNUM))]
8997 "TARGET_32BIT && reload_completed"
8998 [(parallel
8999 [(set (reg:CC CC_REGNUM)
9000 (compare:CC (const_int 1) (match_dup 1)))
9001 (set (match_dup 0)
9002 (minus:SI (const_int 1) (match_dup 1)))])
9003 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9004 (set (match_dup 0) (const_int 0)))])
9005
9006 (define_split
9007 [(set (match_operand:SI 0 "s_register_operand" "")
9008 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9009 (match_operand:SI 2 "const_int_operand" "")))
9010 (clobber (reg:CC CC_REGNUM))]
9011 "TARGET_32BIT && reload_completed"
9012 [(parallel
9013 [(set (reg:CC CC_REGNUM)
9014 (compare:CC (match_dup 1) (match_dup 2)))
9015 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9016 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9017 (set (match_dup 0) (const_int 1)))]
9018 {
9019 operands[3] = GEN_INT (-INTVAL (operands[2]));
9020 })
9021
9022 (define_split
9023 [(set (match_operand:SI 0 "s_register_operand" "")
9024 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9025 (match_operand:SI 2 "arm_add_operand" "")))
9026 (clobber (reg:CC CC_REGNUM))]
9027 "TARGET_32BIT && reload_completed"
9028 [(parallel
9029 [(set (reg:CC_NOOV CC_REGNUM)
9030 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9031 (const_int 0)))
9032 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9033 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9034 (set (match_dup 0) (const_int 1)))])
9035
9036 (define_insn_and_split "*compare_scc"
9037 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9038 (match_operator:SI 1 "arm_comparison_operator"
9039 [(match_operand:SI 2 "s_register_operand" "r,r")
9040 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9041 (clobber (reg:CC CC_REGNUM))]
9042 "TARGET_32BIT"
9043 "#"
9044 "&& reload_completed"
9045 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9046 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9047 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9048 {
9049 rtx tmp1;
9050 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9051 operands[2], operands[3]);
9052 enum rtx_code rc = GET_CODE (operands[1]);
9053
9054 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9055
9056 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9057 if (mode == CCFPmode || mode == CCFPEmode)
9058 rc = reverse_condition_maybe_unordered (rc);
9059 else
9060 rc = reverse_condition (rc);
9061 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9062 }
9063 [(set_attr "type" "multiple")]
9064 )
9065
9066 ;; Attempt to improve the sequence generated by the compare_scc splitters
9067 ;; not to use conditional execution.
9068
9069 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9070 ;; clz Rd, reg1
9071 ;; lsr Rd, Rd, #5
9072 (define_peephole2
9073 [(set (reg:CC CC_REGNUM)
9074 (compare:CC (match_operand:SI 1 "register_operand" "")
9075 (const_int 0)))
9076 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9077 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9078 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9079 (set (match_dup 0) (const_int 1)))]
9080 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9081 [(set (match_dup 0) (clz:SI (match_dup 1)))
9082 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9083 )
9084
9085 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9086 ;; negs Rd, reg1
9087 ;; adc Rd, Rd, reg1
9088 (define_peephole2
9089 [(set (reg:CC CC_REGNUM)
9090 (compare:CC (match_operand:SI 1 "register_operand" "")
9091 (const_int 0)))
9092 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9093 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9094 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9095 (set (match_dup 0) (const_int 1)))
9096 (match_scratch:SI 2 "r")]
9097 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9098 [(parallel
9099 [(set (reg:CC CC_REGNUM)
9100 (compare:CC (const_int 0) (match_dup 1)))
9101 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9102 (set (match_dup 0)
9103 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9104 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9105 )
9106
9107 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9108 ;; sub Rd, Reg1, reg2
9109 ;; clz Rd, Rd
9110 ;; lsr Rd, Rd, #5
9111 (define_peephole2
9112 [(set (reg:CC CC_REGNUM)
9113 (compare:CC (match_operand:SI 1 "register_operand" "")
9114 (match_operand:SI 2 "arm_rhs_operand" "")))
9115 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9116 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9117 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9118 (set (match_dup 0) (const_int 1)))]
9119 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9120 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9121 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9122 (set (match_dup 0) (clz:SI (match_dup 0)))
9123 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9124 )
9125
9126
9127 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9128 ;; sub T1, Reg1, reg2
9129 ;; negs Rd, T1
9130 ;; adc Rd, Rd, T1
9131 (define_peephole2
9132 [(set (reg:CC CC_REGNUM)
9133 (compare:CC (match_operand:SI 1 "register_operand" "")
9134 (match_operand:SI 2 "arm_rhs_operand" "")))
9135 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9136 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9137 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9138 (set (match_dup 0) (const_int 1)))
9139 (match_scratch:SI 3 "r")]
9140 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9141 [(set (match_dup 3) (match_dup 4))
9142 (parallel
9143 [(set (reg:CC CC_REGNUM)
9144 (compare:CC (const_int 0) (match_dup 3)))
9145 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9146 (set (match_dup 0)
9147 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9148 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9149 "
9150 if (CONST_INT_P (operands[2]))
9151 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9152 else
9153 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9154 ")
9155
9156 (define_insn "*cond_move"
9157 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9158 (if_then_else:SI (match_operator 3 "equality_operator"
9159 [(match_operator 4 "arm_comparison_operator"
9160 [(match_operand 5 "cc_register" "") (const_int 0)])
9161 (const_int 0)])
9162 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9163 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9164 "TARGET_ARM"
9165 "*
9166 if (GET_CODE (operands[3]) == NE)
9167 {
9168 if (which_alternative != 1)
9169 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9170 if (which_alternative != 0)
9171 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9172 return \"\";
9173 }
9174 if (which_alternative != 0)
9175 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9176 if (which_alternative != 1)
9177 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9178 return \"\";
9179 "
9180 [(set_attr "conds" "use")
9181 (set_attr_alternative "type"
9182 [(if_then_else (match_operand 2 "const_int_operand" "")
9183 (const_string "mov_imm")
9184 (const_string "mov_reg"))
9185 (if_then_else (match_operand 1 "const_int_operand" "")
9186 (const_string "mov_imm")
9187 (const_string "mov_reg"))
9188 (const_string "multiple")])
9189 (set_attr "length" "4,4,8")]
9190 )
9191
9192 (define_insn "*cond_arith"
9193 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9194 (match_operator:SI 5 "shiftable_operator"
9195 [(match_operator:SI 4 "arm_comparison_operator"
9196 [(match_operand:SI 2 "s_register_operand" "r,r")
9197 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9198 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9199 (clobber (reg:CC CC_REGNUM))]
9200 "TARGET_ARM"
9201 "*
9202 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9203 return \"%i5\\t%0, %1, %2, lsr #31\";
9204
9205 output_asm_insn (\"cmp\\t%2, %3\", operands);
9206 if (GET_CODE (operands[5]) == AND)
9207 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9208 else if (GET_CODE (operands[5]) == MINUS)
9209 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9210 else if (which_alternative != 0)
9211 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9212 return \"%i5%d4\\t%0, %1, #1\";
9213 "
9214 [(set_attr "conds" "clob")
9215 (set_attr "length" "12")
9216 (set_attr "type" "multiple")]
9217 )
9218
9219 (define_insn "*cond_sub"
9220 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9221 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9222 (match_operator:SI 4 "arm_comparison_operator"
9223 [(match_operand:SI 2 "s_register_operand" "r,r")
9224 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9225 (clobber (reg:CC CC_REGNUM))]
9226 "TARGET_ARM"
9227 "*
9228 output_asm_insn (\"cmp\\t%2, %3\", operands);
9229 if (which_alternative != 0)
9230 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9231 return \"sub%d4\\t%0, %1, #1\";
9232 "
9233 [(set_attr "conds" "clob")
9234 (set_attr "length" "8,12")
9235 (set_attr "type" "multiple")]
9236 )
9237
9238 (define_insn "*cmp_ite0"
9239 [(set (match_operand 6 "dominant_cc_register" "")
9240 (compare
9241 (if_then_else:SI
9242 (match_operator 4 "arm_comparison_operator"
9243 [(match_operand:SI 0 "s_register_operand"
9244 "l,l,l,r,r,r,r,r,r")
9245 (match_operand:SI 1 "arm_add_operand"
9246 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9247 (match_operator:SI 5 "arm_comparison_operator"
9248 [(match_operand:SI 2 "s_register_operand"
9249 "l,r,r,l,l,r,r,r,r")
9250 (match_operand:SI 3 "arm_add_operand"
9251 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9252 (const_int 0))
9253 (const_int 0)))]
9254 "TARGET_32BIT"
9255 "*
9256 {
9257 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9258 {
9259 {\"cmp%d5\\t%0, %1\",
9260 \"cmp%d4\\t%2, %3\"},
9261 {\"cmn%d5\\t%0, #%n1\",
9262 \"cmp%d4\\t%2, %3\"},
9263 {\"cmp%d5\\t%0, %1\",
9264 \"cmn%d4\\t%2, #%n3\"},
9265 {\"cmn%d5\\t%0, #%n1\",
9266 \"cmn%d4\\t%2, #%n3\"}
9267 };
9268 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9269 {
9270 {\"cmp\\t%2, %3\",
9271 \"cmp\\t%0, %1\"},
9272 {\"cmp\\t%2, %3\",
9273 \"cmn\\t%0, #%n1\"},
9274 {\"cmn\\t%2, #%n3\",
9275 \"cmp\\t%0, %1\"},
9276 {\"cmn\\t%2, #%n3\",
9277 \"cmn\\t%0, #%n1\"}
9278 };
9279 static const char * const ite[2] =
9280 {
9281 \"it\\t%d5\",
9282 \"it\\t%d4\"
9283 };
9284 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9285 CMP_CMP, CMN_CMP, CMP_CMP,
9286 CMN_CMP, CMP_CMN, CMN_CMN};
9287 int swap =
9288 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9289
9290 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9291 if (TARGET_THUMB2) {
9292 output_asm_insn (ite[swap], operands);
9293 }
9294 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9295 return \"\";
9296 }"
9297 [(set_attr "conds" "set")
9298 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9299 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9300 (set_attr "type" "multiple")
9301 (set_attr_alternative "length"
9302 [(const_int 6)
9303 (const_int 8)
9304 (const_int 8)
9305 (const_int 8)
9306 (const_int 8)
9307 (if_then_else (eq_attr "is_thumb" "no")
9308 (const_int 8)
9309 (const_int 10))
9310 (if_then_else (eq_attr "is_thumb" "no")
9311 (const_int 8)
9312 (const_int 10))
9313 (if_then_else (eq_attr "is_thumb" "no")
9314 (const_int 8)
9315 (const_int 10))
9316 (if_then_else (eq_attr "is_thumb" "no")
9317 (const_int 8)
9318 (const_int 10))])]
9319 )
9320
9321 (define_insn "*cmp_ite1"
9322 [(set (match_operand 6 "dominant_cc_register" "")
9323 (compare
9324 (if_then_else:SI
9325 (match_operator 4 "arm_comparison_operator"
9326 [(match_operand:SI 0 "s_register_operand"
9327 "l,l,l,r,r,r,r,r,r")
9328 (match_operand:SI 1 "arm_add_operand"
9329 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9330 (match_operator:SI 5 "arm_comparison_operator"
9331 [(match_operand:SI 2 "s_register_operand"
9332 "l,r,r,l,l,r,r,r,r")
9333 (match_operand:SI 3 "arm_add_operand"
9334 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9335 (const_int 1))
9336 (const_int 0)))]
9337 "TARGET_32BIT"
9338 "*
9339 {
9340 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9341 {
9342 {\"cmp\\t%0, %1\",
9343 \"cmp\\t%2, %3\"},
9344 {\"cmn\\t%0, #%n1\",
9345 \"cmp\\t%2, %3\"},
9346 {\"cmp\\t%0, %1\",
9347 \"cmn\\t%2, #%n3\"},
9348 {\"cmn\\t%0, #%n1\",
9349 \"cmn\\t%2, #%n3\"}
9350 };
9351 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9352 {
9353 {\"cmp%d4\\t%2, %3\",
9354 \"cmp%D5\\t%0, %1\"},
9355 {\"cmp%d4\\t%2, %3\",
9356 \"cmn%D5\\t%0, #%n1\"},
9357 {\"cmn%d4\\t%2, #%n3\",
9358 \"cmp%D5\\t%0, %1\"},
9359 {\"cmn%d4\\t%2, #%n3\",
9360 \"cmn%D5\\t%0, #%n1\"}
9361 };
9362 static const char * const ite[2] =
9363 {
9364 \"it\\t%d4\",
9365 \"it\\t%D5\"
9366 };
9367 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9368 CMP_CMP, CMN_CMP, CMP_CMP,
9369 CMN_CMP, CMP_CMN, CMN_CMN};
9370 int swap =
9371 comparison_dominates_p (GET_CODE (operands[5]),
9372 reverse_condition (GET_CODE (operands[4])));
9373
9374 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9375 if (TARGET_THUMB2) {
9376 output_asm_insn (ite[swap], operands);
9377 }
9378 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9379 return \"\";
9380 }"
9381 [(set_attr "conds" "set")
9382 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9383 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9384 (set_attr_alternative "length"
9385 [(const_int 6)
9386 (const_int 8)
9387 (const_int 8)
9388 (const_int 8)
9389 (const_int 8)
9390 (if_then_else (eq_attr "is_thumb" "no")
9391 (const_int 8)
9392 (const_int 10))
9393 (if_then_else (eq_attr "is_thumb" "no")
9394 (const_int 8)
9395 (const_int 10))
9396 (if_then_else (eq_attr "is_thumb" "no")
9397 (const_int 8)
9398 (const_int 10))
9399 (if_then_else (eq_attr "is_thumb" "no")
9400 (const_int 8)
9401 (const_int 10))])
9402 (set_attr "type" "multiple")]
9403 )
9404
9405 (define_insn "*cmp_and"
9406 [(set (match_operand 6 "dominant_cc_register" "")
9407 (compare
9408 (and:SI
9409 (match_operator 4 "arm_comparison_operator"
9410 [(match_operand:SI 0 "s_register_operand"
9411 "l,l,l,r,r,r,r,r,r")
9412 (match_operand:SI 1 "arm_add_operand"
9413 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9414 (match_operator:SI 5 "arm_comparison_operator"
9415 [(match_operand:SI 2 "s_register_operand"
9416 "l,r,r,l,l,r,r,r,r")
9417 (match_operand:SI 3 "arm_add_operand"
9418 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9419 (const_int 0)))]
9420 "TARGET_32BIT"
9421 "*
9422 {
9423 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9424 {
9425 {\"cmp%d5\\t%0, %1\",
9426 \"cmp%d4\\t%2, %3\"},
9427 {\"cmn%d5\\t%0, #%n1\",
9428 \"cmp%d4\\t%2, %3\"},
9429 {\"cmp%d5\\t%0, %1\",
9430 \"cmn%d4\\t%2, #%n3\"},
9431 {\"cmn%d5\\t%0, #%n1\",
9432 \"cmn%d4\\t%2, #%n3\"}
9433 };
9434 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9435 {
9436 {\"cmp\\t%2, %3\",
9437 \"cmp\\t%0, %1\"},
9438 {\"cmp\\t%2, %3\",
9439 \"cmn\\t%0, #%n1\"},
9440 {\"cmn\\t%2, #%n3\",
9441 \"cmp\\t%0, %1\"},
9442 {\"cmn\\t%2, #%n3\",
9443 \"cmn\\t%0, #%n1\"}
9444 };
9445 static const char *const ite[2] =
9446 {
9447 \"it\\t%d5\",
9448 \"it\\t%d4\"
9449 };
9450 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9451 CMP_CMP, CMN_CMP, CMP_CMP,
9452 CMN_CMP, CMP_CMN, CMN_CMN};
9453 int swap =
9454 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9455
9456 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9457 if (TARGET_THUMB2) {
9458 output_asm_insn (ite[swap], operands);
9459 }
9460 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9461 return \"\";
9462 }"
9463 [(set_attr "conds" "set")
9464 (set_attr "predicable" "no")
9465 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9466 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9467 (set_attr_alternative "length"
9468 [(const_int 6)
9469 (const_int 8)
9470 (const_int 8)
9471 (const_int 8)
9472 (const_int 8)
9473 (if_then_else (eq_attr "is_thumb" "no")
9474 (const_int 8)
9475 (const_int 10))
9476 (if_then_else (eq_attr "is_thumb" "no")
9477 (const_int 8)
9478 (const_int 10))
9479 (if_then_else (eq_attr "is_thumb" "no")
9480 (const_int 8)
9481 (const_int 10))
9482 (if_then_else (eq_attr "is_thumb" "no")
9483 (const_int 8)
9484 (const_int 10))])
9485 (set_attr "type" "multiple")]
9486 )
9487
9488 (define_insn "*cmp_ior"
9489 [(set (match_operand 6 "dominant_cc_register" "")
9490 (compare
9491 (ior:SI
9492 (match_operator 4 "arm_comparison_operator"
9493 [(match_operand:SI 0 "s_register_operand"
9494 "l,l,l,r,r,r,r,r,r")
9495 (match_operand:SI 1 "arm_add_operand"
9496 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9497 (match_operator:SI 5 "arm_comparison_operator"
9498 [(match_operand:SI 2 "s_register_operand"
9499 "l,r,r,l,l,r,r,r,r")
9500 (match_operand:SI 3 "arm_add_operand"
9501 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9502 (const_int 0)))]
9503 "TARGET_32BIT"
9504 "*
9505 {
9506 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9507 {
9508 {\"cmp\\t%0, %1\",
9509 \"cmp\\t%2, %3\"},
9510 {\"cmn\\t%0, #%n1\",
9511 \"cmp\\t%2, %3\"},
9512 {\"cmp\\t%0, %1\",
9513 \"cmn\\t%2, #%n3\"},
9514 {\"cmn\\t%0, #%n1\",
9515 \"cmn\\t%2, #%n3\"}
9516 };
9517 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9518 {
9519 {\"cmp%D4\\t%2, %3\",
9520 \"cmp%D5\\t%0, %1\"},
9521 {\"cmp%D4\\t%2, %3\",
9522 \"cmn%D5\\t%0, #%n1\"},
9523 {\"cmn%D4\\t%2, #%n3\",
9524 \"cmp%D5\\t%0, %1\"},
9525 {\"cmn%D4\\t%2, #%n3\",
9526 \"cmn%D5\\t%0, #%n1\"}
9527 };
9528 static const char *const ite[2] =
9529 {
9530 \"it\\t%D4\",
9531 \"it\\t%D5\"
9532 };
9533 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9534 CMP_CMP, CMN_CMP, CMP_CMP,
9535 CMN_CMP, CMP_CMN, CMN_CMN};
9536 int swap =
9537 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9538
9539 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9540 if (TARGET_THUMB2) {
9541 output_asm_insn (ite[swap], operands);
9542 }
9543 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9544 return \"\";
9545 }
9546 "
9547 [(set_attr "conds" "set")
9548 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9549 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9550 (set_attr_alternative "length"
9551 [(const_int 6)
9552 (const_int 8)
9553 (const_int 8)
9554 (const_int 8)
9555 (const_int 8)
9556 (if_then_else (eq_attr "is_thumb" "no")
9557 (const_int 8)
9558 (const_int 10))
9559 (if_then_else (eq_attr "is_thumb" "no")
9560 (const_int 8)
9561 (const_int 10))
9562 (if_then_else (eq_attr "is_thumb" "no")
9563 (const_int 8)
9564 (const_int 10))
9565 (if_then_else (eq_attr "is_thumb" "no")
9566 (const_int 8)
9567 (const_int 10))])
9568 (set_attr "type" "multiple")]
9569 )
9570
9571 (define_insn_and_split "*ior_scc_scc"
9572 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9573 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9574 [(match_operand:SI 1 "s_register_operand" "l,r")
9575 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9576 (match_operator:SI 6 "arm_comparison_operator"
9577 [(match_operand:SI 4 "s_register_operand" "l,r")
9578 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9579 (clobber (reg:CC CC_REGNUM))]
9580 "TARGET_32BIT
9581 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9582 != CCmode)"
9583 "#"
9584 "TARGET_32BIT && reload_completed"
9585 [(set (match_dup 7)
9586 (compare
9587 (ior:SI
9588 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9589 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9590 (const_int 0)))
9591 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9592 "operands[7]
9593 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9594 DOM_CC_X_OR_Y),
9595 CC_REGNUM);"
9596 [(set_attr "conds" "clob")
9597 (set_attr "enabled_for_short_it" "yes,no")
9598 (set_attr "length" "16")
9599 (set_attr "type" "multiple")]
9600 )
9601
9602 ; If the above pattern is followed by a CMP insn, then the compare is
9603 ; redundant, since we can rework the conditional instruction that follows.
9604 (define_insn_and_split "*ior_scc_scc_cmp"
9605 [(set (match_operand 0 "dominant_cc_register" "")
9606 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9607 [(match_operand:SI 1 "s_register_operand" "l,r")
9608 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9609 (match_operator:SI 6 "arm_comparison_operator"
9610 [(match_operand:SI 4 "s_register_operand" "l,r")
9611 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9612 (const_int 0)))
9613 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9614 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9615 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9616 "TARGET_32BIT"
9617 "#"
9618 "TARGET_32BIT && reload_completed"
9619 [(set (match_dup 0)
9620 (compare
9621 (ior:SI
9622 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9623 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9624 (const_int 0)))
9625 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9626 ""
9627 [(set_attr "conds" "set")
9628 (set_attr "enabled_for_short_it" "yes,no")
9629 (set_attr "length" "16")
9630 (set_attr "type" "multiple")]
9631 )
9632
9633 (define_insn_and_split "*and_scc_scc"
9634 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9635 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9636 [(match_operand:SI 1 "s_register_operand" "l,r")
9637 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9638 (match_operator:SI 6 "arm_comparison_operator"
9639 [(match_operand:SI 4 "s_register_operand" "l,r")
9640 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9641 (clobber (reg:CC CC_REGNUM))]
9642 "TARGET_32BIT
9643 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9644 != CCmode)"
9645 "#"
9646 "TARGET_32BIT && reload_completed
9647 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9648 != CCmode)"
9649 [(set (match_dup 7)
9650 (compare
9651 (and:SI
9652 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9653 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9654 (const_int 0)))
9655 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9656 "operands[7]
9657 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9658 DOM_CC_X_AND_Y),
9659 CC_REGNUM);"
9660 [(set_attr "conds" "clob")
9661 (set_attr "enabled_for_short_it" "yes,no")
9662 (set_attr "length" "16")
9663 (set_attr "type" "multiple")]
9664 )
9665
9666 ; If the above pattern is followed by a CMP insn, then the compare is
9667 ; redundant, since we can rework the conditional instruction that follows.
9668 (define_insn_and_split "*and_scc_scc_cmp"
9669 [(set (match_operand 0 "dominant_cc_register" "")
9670 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9671 [(match_operand:SI 1 "s_register_operand" "l,r")
9672 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9673 (match_operator:SI 6 "arm_comparison_operator"
9674 [(match_operand:SI 4 "s_register_operand" "l,r")
9675 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9676 (const_int 0)))
9677 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9678 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9679 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9680 "TARGET_32BIT"
9681 "#"
9682 "TARGET_32BIT && reload_completed"
9683 [(set (match_dup 0)
9684 (compare
9685 (and:SI
9686 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9687 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9688 (const_int 0)))
9689 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9690 ""
9691 [(set_attr "conds" "set")
9692 (set_attr "enabled_for_short_it" "yes,no")
9693 (set_attr "length" "16")
9694 (set_attr "type" "multiple")]
9695 )
9696
9697 ;; If there is no dominance in the comparison, then we can still save an
9698 ;; instruction in the AND case, since we can know that the second compare
9699 ;; need only zero the value if false (if true, then the value is already
9700 ;; correct).
9701 (define_insn_and_split "*and_scc_scc_nodom"
9702 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9703 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9704 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9705 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9706 (match_operator:SI 6 "arm_comparison_operator"
9707 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9708 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9709 (clobber (reg:CC CC_REGNUM))]
9710 "TARGET_32BIT
9711 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9712 == CCmode)"
9713 "#"
9714 "TARGET_32BIT && reload_completed"
9715 [(parallel [(set (match_dup 0)
9716 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9717 (clobber (reg:CC CC_REGNUM))])
9718 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9719 (set (match_dup 0)
9720 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9721 (match_dup 0)
9722 (const_int 0)))]
9723 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9724 operands[4], operands[5]),
9725 CC_REGNUM);
9726 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9727 operands[5]);"
9728 [(set_attr "conds" "clob")
9729 (set_attr "length" "20")
9730 (set_attr "type" "multiple")]
9731 )
9732
9733 (define_split
9734 [(set (reg:CC_NOOV CC_REGNUM)
9735 (compare:CC_NOOV (ior:SI
9736 (and:SI (match_operand:SI 0 "s_register_operand" "")
9737 (const_int 1))
9738 (match_operator:SI 1 "arm_comparison_operator"
9739 [(match_operand:SI 2 "s_register_operand" "")
9740 (match_operand:SI 3 "arm_add_operand" "")]))
9741 (const_int 0)))
9742 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9743 "TARGET_ARM"
9744 [(set (match_dup 4)
9745 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9746 (match_dup 0)))
9747 (set (reg:CC_NOOV CC_REGNUM)
9748 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9749 (const_int 0)))]
9750 "")
9751
9752 (define_split
9753 [(set (reg:CC_NOOV CC_REGNUM)
9754 (compare:CC_NOOV (ior:SI
9755 (match_operator:SI 1 "arm_comparison_operator"
9756 [(match_operand:SI 2 "s_register_operand" "")
9757 (match_operand:SI 3 "arm_add_operand" "")])
9758 (and:SI (match_operand:SI 0 "s_register_operand" "")
9759 (const_int 1)))
9760 (const_int 0)))
9761 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9762 "TARGET_ARM"
9763 [(set (match_dup 4)
9764 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9765 (match_dup 0)))
9766 (set (reg:CC_NOOV CC_REGNUM)
9767 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9768 (const_int 0)))]
9769 "")
9770 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9771
9772 (define_insn_and_split "*negscc"
9773 [(set (match_operand:SI 0 "s_register_operand" "=r")
9774 (neg:SI (match_operator 3 "arm_comparison_operator"
9775 [(match_operand:SI 1 "s_register_operand" "r")
9776 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9777 (clobber (reg:CC CC_REGNUM))]
9778 "TARGET_ARM"
9779 "#"
9780 "&& reload_completed"
9781 [(const_int 0)]
9782 {
9783 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9784
9785 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9786 {
9787 /* Emit mov\\t%0, %1, asr #31 */
9788 emit_insn (gen_rtx_SET (operands[0],
9789 gen_rtx_ASHIFTRT (SImode,
9790 operands[1],
9791 GEN_INT (31))));
9792 DONE;
9793 }
9794 else if (GET_CODE (operands[3]) == NE)
9795 {
9796 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9797 if (CONST_INT_P (operands[2]))
9798 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9799 GEN_INT (- INTVAL (operands[2]))));
9800 else
9801 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9802
9803 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9804 gen_rtx_NE (SImode,
9805 cc_reg,
9806 const0_rtx),
9807 gen_rtx_SET (operands[0],
9808 GEN_INT (~0))));
9809 DONE;
9810 }
9811 else
9812 {
9813 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9814 emit_insn (gen_rtx_SET (cc_reg,
9815 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9816 enum rtx_code rc = GET_CODE (operands[3]);
9817
9818 rc = reverse_condition (rc);
9819 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9820 gen_rtx_fmt_ee (rc,
9821 VOIDmode,
9822 cc_reg,
9823 const0_rtx),
9824 gen_rtx_SET (operands[0], const0_rtx)));
9825 rc = GET_CODE (operands[3]);
9826 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9827 gen_rtx_fmt_ee (rc,
9828 VOIDmode,
9829 cc_reg,
9830 const0_rtx),
9831 gen_rtx_SET (operands[0],
9832 GEN_INT (~0))));
9833 DONE;
9834 }
9835 FAIL;
9836 }
9837 [(set_attr "conds" "clob")
9838 (set_attr "length" "12")
9839 (set_attr "type" "multiple")]
9840 )
9841
9842 (define_insn_and_split "movcond_addsi"
9843 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9844 (if_then_else:SI
9845 (match_operator 5 "comparison_operator"
9846 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9847 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9848 (const_int 0)])
9849 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9850 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9851 (clobber (reg:CC CC_REGNUM))]
9852 "TARGET_32BIT"
9853 "#"
9854 "&& reload_completed"
9855 [(set (reg:CC_NOOV CC_REGNUM)
9856 (compare:CC_NOOV
9857 (plus:SI (match_dup 3)
9858 (match_dup 4))
9859 (const_int 0)))
9860 (set (match_dup 0) (match_dup 1))
9861 (cond_exec (match_dup 6)
9862 (set (match_dup 0) (match_dup 2)))]
9863 "
9864 {
9865 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9866 operands[3], operands[4]);
9867 enum rtx_code rc = GET_CODE (operands[5]);
9868 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9869 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9870 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9871 rc = reverse_condition (rc);
9872 else
9873 std::swap (operands[1], operands[2]);
9874
9875 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9876 }
9877 "
9878 [(set_attr "conds" "clob")
9879 (set_attr "enabled_for_short_it" "no,yes,yes")
9880 (set_attr "type" "multiple")]
9881 )
9882
9883 (define_insn "movcond"
9884 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9885 (if_then_else:SI
9886 (match_operator 5 "arm_comparison_operator"
9887 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9888 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9889 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9890 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9891 (clobber (reg:CC CC_REGNUM))]
9892 "TARGET_ARM"
9893 "*
9894 if (GET_CODE (operands[5]) == LT
9895 && (operands[4] == const0_rtx))
9896 {
9897 if (which_alternative != 1 && REG_P (operands[1]))
9898 {
9899 if (operands[2] == const0_rtx)
9900 return \"and\\t%0, %1, %3, asr #31\";
9901 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9902 }
9903 else if (which_alternative != 0 && REG_P (operands[2]))
9904 {
9905 if (operands[1] == const0_rtx)
9906 return \"bic\\t%0, %2, %3, asr #31\";
9907 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9908 }
9909 /* The only case that falls through to here is when both ops 1 & 2
9910 are constants. */
9911 }
9912
9913 if (GET_CODE (operands[5]) == GE
9914 && (operands[4] == const0_rtx))
9915 {
9916 if (which_alternative != 1 && REG_P (operands[1]))
9917 {
9918 if (operands[2] == const0_rtx)
9919 return \"bic\\t%0, %1, %3, asr #31\";
9920 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9921 }
9922 else if (which_alternative != 0 && REG_P (operands[2]))
9923 {
9924 if (operands[1] == const0_rtx)
9925 return \"and\\t%0, %2, %3, asr #31\";
9926 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9927 }
9928 /* The only case that falls through to here is when both ops 1 & 2
9929 are constants. */
9930 }
9931 if (CONST_INT_P (operands[4])
9932 && !const_ok_for_arm (INTVAL (operands[4])))
9933 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9934 else
9935 output_asm_insn (\"cmp\\t%3, %4\", operands);
9936 if (which_alternative != 0)
9937 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9938 if (which_alternative != 1)
9939 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9940 return \"\";
9941 "
9942 [(set_attr "conds" "clob")
9943 (set_attr "length" "8,8,12")
9944 (set_attr "type" "multiple")]
9945 )
9946
9947 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9948
9949 (define_insn "*ifcompare_plus_move"
9950 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9951 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9952 [(match_operand:SI 4 "s_register_operand" "r,r")
9953 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9954 (plus:SI
9955 (match_operand:SI 2 "s_register_operand" "r,r")
9956 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9957 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9958 (clobber (reg:CC CC_REGNUM))]
9959 "TARGET_ARM"
9960 "#"
9961 [(set_attr "conds" "clob")
9962 (set_attr "length" "8,12")
9963 (set_attr "type" "multiple")]
9964 )
9965
9966 (define_insn "*if_plus_move"
9967 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9968 (if_then_else:SI
9969 (match_operator 4 "arm_comparison_operator"
9970 [(match_operand 5 "cc_register" "") (const_int 0)])
9971 (plus:SI
9972 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9973 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9974 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9975 "TARGET_ARM"
9976 "@
9977 add%d4\\t%0, %2, %3
9978 sub%d4\\t%0, %2, #%n3
9979 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9980 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9981 [(set_attr "conds" "use")
9982 (set_attr "length" "4,4,8,8")
9983 (set_attr_alternative "type"
9984 [(if_then_else (match_operand 3 "const_int_operand" "")
9985 (const_string "alu_imm" )
9986 (const_string "alu_sreg"))
9987 (const_string "alu_imm")
9988 (const_string "multiple")
9989 (const_string "multiple")])]
9990 )
9991
9992 (define_insn "*ifcompare_move_plus"
9993 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9994 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9995 [(match_operand:SI 4 "s_register_operand" "r,r")
9996 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9997 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9998 (plus:SI
9999 (match_operand:SI 2 "s_register_operand" "r,r")
10000 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10001 (clobber (reg:CC CC_REGNUM))]
10002 "TARGET_ARM"
10003 "#"
10004 [(set_attr "conds" "clob")
10005 (set_attr "length" "8,12")
10006 (set_attr "type" "multiple")]
10007 )
10008
10009 (define_insn "*if_move_plus"
10010 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10011 (if_then_else:SI
10012 (match_operator 4 "arm_comparison_operator"
10013 [(match_operand 5 "cc_register" "") (const_int 0)])
10014 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10015 (plus:SI
10016 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10017 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10018 "TARGET_ARM"
10019 "@
10020 add%D4\\t%0, %2, %3
10021 sub%D4\\t%0, %2, #%n3
10022 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10023 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10024 [(set_attr "conds" "use")
10025 (set_attr "length" "4,4,8,8")
10026 (set_attr_alternative "type"
10027 [(if_then_else (match_operand 3 "const_int_operand" "")
10028 (const_string "alu_imm" )
10029 (const_string "alu_sreg"))
10030 (const_string "alu_imm")
10031 (const_string "multiple")
10032 (const_string "multiple")])]
10033 )
10034
10035 (define_insn "*ifcompare_arith_arith"
10036 [(set (match_operand:SI 0 "s_register_operand" "=r")
10037 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10038 [(match_operand:SI 5 "s_register_operand" "r")
10039 (match_operand:SI 6 "arm_add_operand" "rIL")])
10040 (match_operator:SI 8 "shiftable_operator"
10041 [(match_operand:SI 1 "s_register_operand" "r")
10042 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10043 (match_operator:SI 7 "shiftable_operator"
10044 [(match_operand:SI 3 "s_register_operand" "r")
10045 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10046 (clobber (reg:CC CC_REGNUM))]
10047 "TARGET_ARM"
10048 "#"
10049 [(set_attr "conds" "clob")
10050 (set_attr "length" "12")
10051 (set_attr "type" "multiple")]
10052 )
10053
10054 (define_insn "*if_arith_arith"
10055 [(set (match_operand:SI 0 "s_register_operand" "=r")
10056 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10057 [(match_operand 8 "cc_register" "") (const_int 0)])
10058 (match_operator:SI 6 "shiftable_operator"
10059 [(match_operand:SI 1 "s_register_operand" "r")
10060 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10061 (match_operator:SI 7 "shiftable_operator"
10062 [(match_operand:SI 3 "s_register_operand" "r")
10063 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10064 "TARGET_ARM"
10065 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10066 [(set_attr "conds" "use")
10067 (set_attr "length" "8")
10068 (set_attr "type" "multiple")]
10069 )
10070
10071 (define_insn "*ifcompare_arith_move"
10072 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10073 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10074 [(match_operand:SI 2 "s_register_operand" "r,r")
10075 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10076 (match_operator:SI 7 "shiftable_operator"
10077 [(match_operand:SI 4 "s_register_operand" "r,r")
10078 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10079 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10080 (clobber (reg:CC CC_REGNUM))]
10081 "TARGET_ARM"
10082 "*
10083 /* If we have an operation where (op x 0) is the identity operation and
10084 the conditional operator is LT or GE and we are comparing against zero and
10085 everything is in registers then we can do this in two instructions. */
10086 if (operands[3] == const0_rtx
10087 && GET_CODE (operands[7]) != AND
10088 && REG_P (operands[5])
10089 && REG_P (operands[1])
10090 && REGNO (operands[1]) == REGNO (operands[4])
10091 && REGNO (operands[4]) != REGNO (operands[0]))
10092 {
10093 if (GET_CODE (operands[6]) == LT)
10094 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10095 else if (GET_CODE (operands[6]) == GE)
10096 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10097 }
10098 if (CONST_INT_P (operands[3])
10099 && !const_ok_for_arm (INTVAL (operands[3])))
10100 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10101 else
10102 output_asm_insn (\"cmp\\t%2, %3\", operands);
10103 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10104 if (which_alternative != 0)
10105 return \"mov%D6\\t%0, %1\";
10106 return \"\";
10107 "
10108 [(set_attr "conds" "clob")
10109 (set_attr "length" "8,12")
10110 (set_attr "type" "multiple")]
10111 )
10112
10113 (define_insn "*if_arith_move"
10114 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10115 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10116 [(match_operand 6 "cc_register" "") (const_int 0)])
10117 (match_operator:SI 5 "shiftable_operator"
10118 [(match_operand:SI 2 "s_register_operand" "r,r")
10119 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10120 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10121 "TARGET_ARM"
10122 "@
10123 %I5%d4\\t%0, %2, %3
10124 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10125 [(set_attr "conds" "use")
10126 (set_attr "length" "4,8")
10127 (set_attr_alternative "type"
10128 [(if_then_else (match_operand 3 "const_int_operand" "")
10129 (const_string "alu_shift_imm" )
10130 (const_string "alu_shift_reg"))
10131 (const_string "multiple")])]
10132 )
10133
10134 (define_insn "*ifcompare_move_arith"
10135 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10136 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10137 [(match_operand:SI 4 "s_register_operand" "r,r")
10138 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10139 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10140 (match_operator:SI 7 "shiftable_operator"
10141 [(match_operand:SI 2 "s_register_operand" "r,r")
10142 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10143 (clobber (reg:CC CC_REGNUM))]
10144 "TARGET_ARM"
10145 "*
10146 /* If we have an operation where (op x 0) is the identity operation and
10147 the conditional operator is LT or GE and we are comparing against zero and
10148 everything is in registers then we can do this in two instructions */
10149 if (operands[5] == const0_rtx
10150 && GET_CODE (operands[7]) != AND
10151 && REG_P (operands[3])
10152 && REG_P (operands[1])
10153 && REGNO (operands[1]) == REGNO (operands[2])
10154 && REGNO (operands[2]) != REGNO (operands[0]))
10155 {
10156 if (GET_CODE (operands[6]) == GE)
10157 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10158 else if (GET_CODE (operands[6]) == LT)
10159 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10160 }
10161
10162 if (CONST_INT_P (operands[5])
10163 && !const_ok_for_arm (INTVAL (operands[5])))
10164 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10165 else
10166 output_asm_insn (\"cmp\\t%4, %5\", operands);
10167
10168 if (which_alternative != 0)
10169 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10170 return \"%I7%D6\\t%0, %2, %3\";
10171 "
10172 [(set_attr "conds" "clob")
10173 (set_attr "length" "8,12")
10174 (set_attr "type" "multiple")]
10175 )
10176
10177 (define_insn "*if_move_arith"
10178 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10179 (if_then_else:SI
10180 (match_operator 4 "arm_comparison_operator"
10181 [(match_operand 6 "cc_register" "") (const_int 0)])
10182 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10183 (match_operator:SI 5 "shiftable_operator"
10184 [(match_operand:SI 2 "s_register_operand" "r,r")
10185 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10186 "TARGET_ARM"
10187 "@
10188 %I5%D4\\t%0, %2, %3
10189 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10190 [(set_attr "conds" "use")
10191 (set_attr "length" "4,8")
10192 (set_attr_alternative "type"
10193 [(if_then_else (match_operand 3 "const_int_operand" "")
10194 (const_string "alu_shift_imm" )
10195 (const_string "alu_shift_reg"))
10196 (const_string "multiple")])]
10197 )
10198
10199 (define_insn "*ifcompare_move_not"
10200 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10201 (if_then_else:SI
10202 (match_operator 5 "arm_comparison_operator"
10203 [(match_operand:SI 3 "s_register_operand" "r,r")
10204 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10205 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10206 (not:SI
10207 (match_operand:SI 2 "s_register_operand" "r,r"))))
10208 (clobber (reg:CC CC_REGNUM))]
10209 "TARGET_ARM"
10210 "#"
10211 [(set_attr "conds" "clob")
10212 (set_attr "length" "8,12")
10213 (set_attr "type" "multiple")]
10214 )
10215
10216 (define_insn "*if_move_not"
10217 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10218 (if_then_else:SI
10219 (match_operator 4 "arm_comparison_operator"
10220 [(match_operand 3 "cc_register" "") (const_int 0)])
10221 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10222 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10223 "TARGET_ARM"
10224 "@
10225 mvn%D4\\t%0, %2
10226 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10227 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10228 [(set_attr "conds" "use")
10229 (set_attr "type" "mvn_reg")
10230 (set_attr "length" "4,8,8")
10231 (set_attr "type" "mvn_reg,multiple,multiple")]
10232 )
10233
10234 (define_insn "*ifcompare_not_move"
10235 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10236 (if_then_else:SI
10237 (match_operator 5 "arm_comparison_operator"
10238 [(match_operand:SI 3 "s_register_operand" "r,r")
10239 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10240 (not:SI
10241 (match_operand:SI 2 "s_register_operand" "r,r"))
10242 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10243 (clobber (reg:CC CC_REGNUM))]
10244 "TARGET_ARM"
10245 "#"
10246 [(set_attr "conds" "clob")
10247 (set_attr "length" "8,12")
10248 (set_attr "type" "multiple")]
10249 )
10250
10251 (define_insn "*if_not_move"
10252 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10253 (if_then_else:SI
10254 (match_operator 4 "arm_comparison_operator"
10255 [(match_operand 3 "cc_register" "") (const_int 0)])
10256 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10257 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10258 "TARGET_ARM"
10259 "@
10260 mvn%d4\\t%0, %2
10261 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10262 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10263 [(set_attr "conds" "use")
10264 (set_attr "type" "mvn_reg,multiple,multiple")
10265 (set_attr "length" "4,8,8")]
10266 )
10267
10268 (define_insn "*ifcompare_shift_move"
10269 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10270 (if_then_else:SI
10271 (match_operator 6 "arm_comparison_operator"
10272 [(match_operand:SI 4 "s_register_operand" "r,r")
10273 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10274 (match_operator:SI 7 "shift_operator"
10275 [(match_operand:SI 2 "s_register_operand" "r,r")
10276 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10277 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10278 (clobber (reg:CC CC_REGNUM))]
10279 "TARGET_ARM"
10280 "#"
10281 [(set_attr "conds" "clob")
10282 (set_attr "length" "8,12")
10283 (set_attr "type" "multiple")]
10284 )
10285
10286 (define_insn "*if_shift_move"
10287 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10288 (if_then_else:SI
10289 (match_operator 5 "arm_comparison_operator"
10290 [(match_operand 6 "cc_register" "") (const_int 0)])
10291 (match_operator:SI 4 "shift_operator"
10292 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10293 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10294 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10295 "TARGET_ARM"
10296 "@
10297 mov%d5\\t%0, %2%S4
10298 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10299 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10300 [(set_attr "conds" "use")
10301 (set_attr "shift" "2")
10302 (set_attr "length" "4,8,8")
10303 (set_attr_alternative "type"
10304 [(if_then_else (match_operand 3 "const_int_operand" "")
10305 (const_string "mov_shift" )
10306 (const_string "mov_shift_reg"))
10307 (const_string "multiple")
10308 (const_string "multiple")])]
10309 )
10310
10311 (define_insn "*ifcompare_move_shift"
10312 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10313 (if_then_else:SI
10314 (match_operator 6 "arm_comparison_operator"
10315 [(match_operand:SI 4 "s_register_operand" "r,r")
10316 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10317 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10318 (match_operator:SI 7 "shift_operator"
10319 [(match_operand:SI 2 "s_register_operand" "r,r")
10320 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10321 (clobber (reg:CC CC_REGNUM))]
10322 "TARGET_ARM"
10323 "#"
10324 [(set_attr "conds" "clob")
10325 (set_attr "length" "8,12")
10326 (set_attr "type" "multiple")]
10327 )
10328
10329 (define_insn "*if_move_shift"
10330 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10331 (if_then_else:SI
10332 (match_operator 5 "arm_comparison_operator"
10333 [(match_operand 6 "cc_register" "") (const_int 0)])
10334 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10335 (match_operator:SI 4 "shift_operator"
10336 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10337 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10338 "TARGET_ARM"
10339 "@
10340 mov%D5\\t%0, %2%S4
10341 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10342 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10343 [(set_attr "conds" "use")
10344 (set_attr "shift" "2")
10345 (set_attr "length" "4,8,8")
10346 (set_attr_alternative "type"
10347 [(if_then_else (match_operand 3 "const_int_operand" "")
10348 (const_string "mov_shift" )
10349 (const_string "mov_shift_reg"))
10350 (const_string "multiple")
10351 (const_string "multiple")])]
10352 )
10353
10354 (define_insn "*ifcompare_shift_shift"
10355 [(set (match_operand:SI 0 "s_register_operand" "=r")
10356 (if_then_else:SI
10357 (match_operator 7 "arm_comparison_operator"
10358 [(match_operand:SI 5 "s_register_operand" "r")
10359 (match_operand:SI 6 "arm_add_operand" "rIL")])
10360 (match_operator:SI 8 "shift_operator"
10361 [(match_operand:SI 1 "s_register_operand" "r")
10362 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10363 (match_operator:SI 9 "shift_operator"
10364 [(match_operand:SI 3 "s_register_operand" "r")
10365 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10366 (clobber (reg:CC CC_REGNUM))]
10367 "TARGET_ARM"
10368 "#"
10369 [(set_attr "conds" "clob")
10370 (set_attr "length" "12")
10371 (set_attr "type" "multiple")]
10372 )
10373
10374 (define_insn "*if_shift_shift"
10375 [(set (match_operand:SI 0 "s_register_operand" "=r")
10376 (if_then_else:SI
10377 (match_operator 5 "arm_comparison_operator"
10378 [(match_operand 8 "cc_register" "") (const_int 0)])
10379 (match_operator:SI 6 "shift_operator"
10380 [(match_operand:SI 1 "s_register_operand" "r")
10381 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10382 (match_operator:SI 7 "shift_operator"
10383 [(match_operand:SI 3 "s_register_operand" "r")
10384 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10385 "TARGET_ARM"
10386 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10387 [(set_attr "conds" "use")
10388 (set_attr "shift" "1")
10389 (set_attr "length" "8")
10390 (set (attr "type") (if_then_else
10391 (and (match_operand 2 "const_int_operand" "")
10392 (match_operand 4 "const_int_operand" ""))
10393 (const_string "mov_shift")
10394 (const_string "mov_shift_reg")))]
10395 )
10396
10397 (define_insn "*ifcompare_not_arith"
10398 [(set (match_operand:SI 0 "s_register_operand" "=r")
10399 (if_then_else:SI
10400 (match_operator 6 "arm_comparison_operator"
10401 [(match_operand:SI 4 "s_register_operand" "r")
10402 (match_operand:SI 5 "arm_add_operand" "rIL")])
10403 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10404 (match_operator:SI 7 "shiftable_operator"
10405 [(match_operand:SI 2 "s_register_operand" "r")
10406 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10407 (clobber (reg:CC CC_REGNUM))]
10408 "TARGET_ARM"
10409 "#"
10410 [(set_attr "conds" "clob")
10411 (set_attr "length" "12")
10412 (set_attr "type" "multiple")]
10413 )
10414
10415 (define_insn "*if_not_arith"
10416 [(set (match_operand:SI 0 "s_register_operand" "=r")
10417 (if_then_else:SI
10418 (match_operator 5 "arm_comparison_operator"
10419 [(match_operand 4 "cc_register" "") (const_int 0)])
10420 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10421 (match_operator:SI 6 "shiftable_operator"
10422 [(match_operand:SI 2 "s_register_operand" "r")
10423 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10424 "TARGET_ARM"
10425 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10426 [(set_attr "conds" "use")
10427 (set_attr "type" "mvn_reg")
10428 (set_attr "length" "8")]
10429 )
10430
10431 (define_insn "*ifcompare_arith_not"
10432 [(set (match_operand:SI 0 "s_register_operand" "=r")
10433 (if_then_else:SI
10434 (match_operator 6 "arm_comparison_operator"
10435 [(match_operand:SI 4 "s_register_operand" "r")
10436 (match_operand:SI 5 "arm_add_operand" "rIL")])
10437 (match_operator:SI 7 "shiftable_operator"
10438 [(match_operand:SI 2 "s_register_operand" "r")
10439 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10440 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10441 (clobber (reg:CC CC_REGNUM))]
10442 "TARGET_ARM"
10443 "#"
10444 [(set_attr "conds" "clob")
10445 (set_attr "length" "12")
10446 (set_attr "type" "multiple")]
10447 )
10448
10449 (define_insn "*if_arith_not"
10450 [(set (match_operand:SI 0 "s_register_operand" "=r")
10451 (if_then_else:SI
10452 (match_operator 5 "arm_comparison_operator"
10453 [(match_operand 4 "cc_register" "") (const_int 0)])
10454 (match_operator:SI 6 "shiftable_operator"
10455 [(match_operand:SI 2 "s_register_operand" "r")
10456 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10457 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10458 "TARGET_ARM"
10459 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10460 [(set_attr "conds" "use")
10461 (set_attr "type" "multiple")
10462 (set_attr "length" "8")]
10463 )
10464
10465 (define_insn "*ifcompare_neg_move"
10466 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10467 (if_then_else:SI
10468 (match_operator 5 "arm_comparison_operator"
10469 [(match_operand:SI 3 "s_register_operand" "r,r")
10470 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10471 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10472 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10473 (clobber (reg:CC CC_REGNUM))]
10474 "TARGET_ARM"
10475 "#"
10476 [(set_attr "conds" "clob")
10477 (set_attr "length" "8,12")
10478 (set_attr "type" "multiple")]
10479 )
10480
10481 (define_insn_and_split "*if_neg_move"
10482 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10483 (if_then_else:SI
10484 (match_operator 4 "arm_comparison_operator"
10485 [(match_operand 3 "cc_register" "") (const_int 0)])
10486 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10487 (match_operand:SI 1 "s_register_operand" "0,0")))]
10488 "TARGET_32BIT"
10489 "#"
10490 "&& reload_completed"
10491 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10492 (set (match_dup 0) (neg:SI (match_dup 2))))]
10493 ""
10494 [(set_attr "conds" "use")
10495 (set_attr "length" "4")
10496 (set_attr "arch" "t2,32")
10497 (set_attr "enabled_for_short_it" "yes,no")
10498 (set_attr "type" "logic_shift_imm")]
10499 )
10500
10501 (define_insn "*ifcompare_move_neg"
10502 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10503 (if_then_else:SI
10504 (match_operator 5 "arm_comparison_operator"
10505 [(match_operand:SI 3 "s_register_operand" "r,r")
10506 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10507 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10508 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10509 (clobber (reg:CC CC_REGNUM))]
10510 "TARGET_ARM"
10511 "#"
10512 [(set_attr "conds" "clob")
10513 (set_attr "length" "8,12")
10514 (set_attr "type" "multiple")]
10515 )
10516
10517 (define_insn_and_split "*if_move_neg"
10518 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10519 (if_then_else:SI
10520 (match_operator 4 "arm_comparison_operator"
10521 [(match_operand 3 "cc_register" "") (const_int 0)])
10522 (match_operand:SI 1 "s_register_operand" "0,0")
10523 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10524 "TARGET_32BIT"
10525 "#"
10526 "&& reload_completed"
10527 [(cond_exec (match_dup 5)
10528 (set (match_dup 0) (neg:SI (match_dup 2))))]
10529 {
10530 machine_mode mode = GET_MODE (operands[3]);
10531 rtx_code rc = GET_CODE (operands[4]);
10532
10533 if (mode == CCFPmode || mode == CCFPEmode)
10534 rc = reverse_condition_maybe_unordered (rc);
10535 else
10536 rc = reverse_condition (rc);
10537
10538 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10539 }
10540 [(set_attr "conds" "use")
10541 (set_attr "length" "4")
10542 (set_attr "arch" "t2,32")
10543 (set_attr "enabled_for_short_it" "yes,no")
10544 (set_attr "type" "logic_shift_imm")]
10545 )
10546
10547 (define_insn "*arith_adjacentmem"
10548 [(set (match_operand:SI 0 "s_register_operand" "=r")
10549 (match_operator:SI 1 "shiftable_operator"
10550 [(match_operand:SI 2 "memory_operand" "m")
10551 (match_operand:SI 3 "memory_operand" "m")]))
10552 (clobber (match_scratch:SI 4 "=r"))]
10553 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10554 "*
10555 {
10556 rtx ldm[3];
10557 rtx arith[4];
10558 rtx base_reg;
10559 HOST_WIDE_INT val1 = 0, val2 = 0;
10560
10561 if (REGNO (operands[0]) > REGNO (operands[4]))
10562 {
10563 ldm[1] = operands[4];
10564 ldm[2] = operands[0];
10565 }
10566 else
10567 {
10568 ldm[1] = operands[0];
10569 ldm[2] = operands[4];
10570 }
10571
10572 base_reg = XEXP (operands[2], 0);
10573
10574 if (!REG_P (base_reg))
10575 {
10576 val1 = INTVAL (XEXP (base_reg, 1));
10577 base_reg = XEXP (base_reg, 0);
10578 }
10579
10580 if (!REG_P (XEXP (operands[3], 0)))
10581 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10582
10583 arith[0] = operands[0];
10584 arith[3] = operands[1];
10585
10586 if (val1 < val2)
10587 {
10588 arith[1] = ldm[1];
10589 arith[2] = ldm[2];
10590 }
10591 else
10592 {
10593 arith[1] = ldm[2];
10594 arith[2] = ldm[1];
10595 }
10596
10597 ldm[0] = base_reg;
10598 if (val1 !=0 && val2 != 0)
10599 {
10600 rtx ops[3];
10601
10602 if (val1 == 4 || val2 == 4)
10603 /* Other val must be 8, since we know they are adjacent and neither
10604 is zero. */
10605 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10606 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10607 {
10608 ldm[0] = ops[0] = operands[4];
10609 ops[1] = base_reg;
10610 ops[2] = GEN_INT (val1);
10611 output_add_immediate (ops);
10612 if (val1 < val2)
10613 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10614 else
10615 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10616 }
10617 else
10618 {
10619 /* Offset is out of range for a single add, so use two ldr. */
10620 ops[0] = ldm[1];
10621 ops[1] = base_reg;
10622 ops[2] = GEN_INT (val1);
10623 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10624 ops[0] = ldm[2];
10625 ops[2] = GEN_INT (val2);
10626 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10627 }
10628 }
10629 else if (val1 != 0)
10630 {
10631 if (val1 < val2)
10632 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10633 else
10634 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10635 }
10636 else
10637 {
10638 if (val1 < val2)
10639 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10640 else
10641 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10642 }
10643 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10644 return \"\";
10645 }"
10646 [(set_attr "length" "12")
10647 (set_attr "predicable" "yes")
10648 (set_attr "type" "load_4")]
10649 )
10650
10651 ; This pattern is never tried by combine, so do it as a peephole
10652
10653 (define_peephole2
10654 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10655 (match_operand:SI 1 "arm_general_register_operand" ""))
10656 (set (reg:CC CC_REGNUM)
10657 (compare:CC (match_dup 1) (const_int 0)))]
10658 "TARGET_ARM"
10659 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10660 (set (match_dup 0) (match_dup 1))])]
10661 ""
10662 )
10663
10664 (define_split
10665 [(set (match_operand:SI 0 "s_register_operand" "")
10666 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10667 (const_int 0))
10668 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10669 [(match_operand:SI 3 "s_register_operand" "")
10670 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10671 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10672 "TARGET_ARM"
10673 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10674 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10675 (match_dup 5)))]
10676 ""
10677 )
10678
10679 ;; This split can be used because CC_Z mode implies that the following
10680 ;; branch will be an equality, or an unsigned inequality, so the sign
10681 ;; extension is not needed.
10682
10683 (define_split
10684 [(set (reg:CC_Z CC_REGNUM)
10685 (compare:CC_Z
10686 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10687 (const_int 24))
10688 (match_operand 1 "const_int_operand" "")))
10689 (clobber (match_scratch:SI 2 ""))]
10690 "TARGET_ARM
10691 && ((UINTVAL (operands[1]))
10692 == ((UINTVAL (operands[1])) >> 24) << 24)"
10693 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10694 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10695 "
10696 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10697 "
10698 )
10699 ;; ??? Check the patterns above for Thumb-2 usefulness
10700
10701 (define_expand "prologue"
10702 [(clobber (const_int 0))]
10703 "TARGET_EITHER"
10704 "if (TARGET_32BIT)
10705 arm_expand_prologue ();
10706 else
10707 thumb1_expand_prologue ();
10708 DONE;
10709 "
10710 )
10711
10712 (define_expand "epilogue"
10713 [(clobber (const_int 0))]
10714 "TARGET_EITHER"
10715 "
10716 if (crtl->calls_eh_return)
10717 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10718 if (TARGET_THUMB1)
10719 {
10720 thumb1_expand_epilogue ();
10721 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10722 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10723 }
10724 else if (HAVE_return)
10725 {
10726 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10727 no need for explicit testing again. */
10728 emit_jump_insn (gen_return ());
10729 }
10730 else if (TARGET_32BIT)
10731 {
10732 arm_expand_epilogue (true);
10733 }
10734 DONE;
10735 "
10736 )
10737
10738 ;; Note - although unspec_volatile's USE all hard registers,
10739 ;; USEs are ignored after relaod has completed. Thus we need
10740 ;; to add an unspec of the link register to ensure that flow
10741 ;; does not think that it is unused by the sibcall branch that
10742 ;; will replace the standard function epilogue.
10743 (define_expand "sibcall_epilogue"
10744 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10745 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10746 "TARGET_32BIT"
10747 "
10748 arm_expand_epilogue (false);
10749 DONE;
10750 "
10751 )
10752
10753 (define_expand "eh_epilogue"
10754 [(use (match_operand:SI 0 "register_operand" ""))
10755 (use (match_operand:SI 1 "register_operand" ""))
10756 (use (match_operand:SI 2 "register_operand" ""))]
10757 "TARGET_EITHER"
10758 "
10759 {
10760 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10761 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10762 {
10763 rtx ra = gen_rtx_REG (Pmode, 2);
10764
10765 emit_move_insn (ra, operands[2]);
10766 operands[2] = ra;
10767 }
10768 /* This is a hack -- we may have crystalized the function type too
10769 early. */
10770 cfun->machine->func_type = 0;
10771 }"
10772 )
10773
10774 ;; This split is only used during output to reduce the number of patterns
10775 ;; that need assembler instructions adding to them. We allowed the setting
10776 ;; of the conditions to be implicit during rtl generation so that
10777 ;; the conditional compare patterns would work. However this conflicts to
10778 ;; some extent with the conditional data operations, so we have to split them
10779 ;; up again here.
10780
10781 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10782 ;; conditional execution sufficient?
10783
10784 (define_split
10785 [(set (match_operand:SI 0 "s_register_operand" "")
10786 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10787 [(match_operand 2 "" "") (match_operand 3 "" "")])
10788 (match_dup 0)
10789 (match_operand 4 "" "")))
10790 (clobber (reg:CC CC_REGNUM))]
10791 "TARGET_ARM && reload_completed"
10792 [(set (match_dup 5) (match_dup 6))
10793 (cond_exec (match_dup 7)
10794 (set (match_dup 0) (match_dup 4)))]
10795 "
10796 {
10797 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10798 operands[2], operands[3]);
10799 enum rtx_code rc = GET_CODE (operands[1]);
10800
10801 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10802 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10803 if (mode == CCFPmode || mode == CCFPEmode)
10804 rc = reverse_condition_maybe_unordered (rc);
10805 else
10806 rc = reverse_condition (rc);
10807
10808 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10809 }"
10810 )
10811
10812 (define_split
10813 [(set (match_operand:SI 0 "s_register_operand" "")
10814 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10815 [(match_operand 2 "" "") (match_operand 3 "" "")])
10816 (match_operand 4 "" "")
10817 (match_dup 0)))
10818 (clobber (reg:CC CC_REGNUM))]
10819 "TARGET_ARM && reload_completed"
10820 [(set (match_dup 5) (match_dup 6))
10821 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10822 (set (match_dup 0) (match_dup 4)))]
10823 "
10824 {
10825 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10826 operands[2], operands[3]);
10827
10828 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10829 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10830 }"
10831 )
10832
10833 (define_split
10834 [(set (match_operand:SI 0 "s_register_operand" "")
10835 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10836 [(match_operand 2 "" "") (match_operand 3 "" "")])
10837 (match_operand 4 "" "")
10838 (match_operand 5 "" "")))
10839 (clobber (reg:CC CC_REGNUM))]
10840 "TARGET_ARM && reload_completed"
10841 [(set (match_dup 6) (match_dup 7))
10842 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10843 (set (match_dup 0) (match_dup 4)))
10844 (cond_exec (match_dup 8)
10845 (set (match_dup 0) (match_dup 5)))]
10846 "
10847 {
10848 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10849 operands[2], operands[3]);
10850 enum rtx_code rc = GET_CODE (operands[1]);
10851
10852 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10853 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10854 if (mode == CCFPmode || mode == CCFPEmode)
10855 rc = reverse_condition_maybe_unordered (rc);
10856 else
10857 rc = reverse_condition (rc);
10858
10859 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10860 }"
10861 )
10862
10863 (define_split
10864 [(set (match_operand:SI 0 "s_register_operand" "")
10865 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10866 [(match_operand:SI 2 "s_register_operand" "")
10867 (match_operand:SI 3 "arm_add_operand" "")])
10868 (match_operand:SI 4 "arm_rhs_operand" "")
10869 (not:SI
10870 (match_operand:SI 5 "s_register_operand" ""))))
10871 (clobber (reg:CC CC_REGNUM))]
10872 "TARGET_ARM && reload_completed"
10873 [(set (match_dup 6) (match_dup 7))
10874 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10875 (set (match_dup 0) (match_dup 4)))
10876 (cond_exec (match_dup 8)
10877 (set (match_dup 0) (not:SI (match_dup 5))))]
10878 "
10879 {
10880 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10881 operands[2], operands[3]);
10882 enum rtx_code rc = GET_CODE (operands[1]);
10883
10884 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10885 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10886 if (mode == CCFPmode || mode == CCFPEmode)
10887 rc = reverse_condition_maybe_unordered (rc);
10888 else
10889 rc = reverse_condition (rc);
10890
10891 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10892 }"
10893 )
10894
10895 (define_insn "*cond_move_not"
10896 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10897 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10898 [(match_operand 3 "cc_register" "") (const_int 0)])
10899 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10900 (not:SI
10901 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10902 "TARGET_ARM"
10903 "@
10904 mvn%D4\\t%0, %2
10905 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10906 [(set_attr "conds" "use")
10907 (set_attr "type" "mvn_reg,multiple")
10908 (set_attr "length" "4,8")]
10909 )
10910
10911 ;; The next two patterns occur when an AND operation is followed by a
10912 ;; scc insn sequence
10913
10914 (define_insn "*sign_extract_onebit"
10915 [(set (match_operand:SI 0 "s_register_operand" "=r")
10916 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10917 (const_int 1)
10918 (match_operand:SI 2 "const_int_operand" "n")))
10919 (clobber (reg:CC CC_REGNUM))]
10920 "TARGET_ARM"
10921 "*
10922 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10923 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10924 return \"mvnne\\t%0, #0\";
10925 "
10926 [(set_attr "conds" "clob")
10927 (set_attr "length" "8")
10928 (set_attr "type" "multiple")]
10929 )
10930
10931 (define_insn "*not_signextract_onebit"
10932 [(set (match_operand:SI 0 "s_register_operand" "=r")
10933 (not:SI
10934 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10935 (const_int 1)
10936 (match_operand:SI 2 "const_int_operand" "n"))))
10937 (clobber (reg:CC CC_REGNUM))]
10938 "TARGET_ARM"
10939 "*
10940 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10941 output_asm_insn (\"tst\\t%1, %2\", operands);
10942 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10943 return \"movne\\t%0, #0\";
10944 "
10945 [(set_attr "conds" "clob")
10946 (set_attr "length" "12")
10947 (set_attr "type" "multiple")]
10948 )
10949 ;; ??? The above patterns need auditing for Thumb-2
10950
10951 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10952 ;; expressions. For simplicity, the first register is also in the unspec
10953 ;; part.
10954 ;; To avoid the usage of GNU extension, the length attribute is computed
10955 ;; in a C function arm_attr_length_push_multi.
10956 (define_insn "*push_multi"
10957 [(match_parallel 2 "multi_register_push"
10958 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10959 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10960 UNSPEC_PUSH_MULT))])]
10961 ""
10962 "*
10963 {
10964 int num_saves = XVECLEN (operands[2], 0);
10965
10966 /* For the StrongARM at least it is faster to
10967 use STR to store only a single register.
10968 In Thumb mode always use push, and the assembler will pick
10969 something appropriate. */
10970 if (num_saves == 1 && TARGET_ARM)
10971 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10972 else
10973 {
10974 int i;
10975 char pattern[100];
10976
10977 if (TARGET_32BIT)
10978 strcpy (pattern, \"push%?\\t{%1\");
10979 else
10980 strcpy (pattern, \"push\\t{%1\");
10981
10982 for (i = 1; i < num_saves; i++)
10983 {
10984 strcat (pattern, \", %|\");
10985 strcat (pattern,
10986 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10987 }
10988
10989 strcat (pattern, \"}\");
10990 output_asm_insn (pattern, operands);
10991 }
10992
10993 return \"\";
10994 }"
10995 [(set_attr "type" "store_16")
10996 (set (attr "length")
10997 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10998 )
10999
11000 (define_insn "stack_tie"
11001 [(set (mem:BLK (scratch))
11002 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11003 (match_operand:SI 1 "s_register_operand" "rk")]
11004 UNSPEC_PRLG_STK))]
11005 ""
11006 ""
11007 [(set_attr "length" "0")
11008 (set_attr "type" "block")]
11009 )
11010
11011 ;; Pop (as used in epilogue RTL)
11012 ;;
11013 (define_insn "*load_multiple_with_writeback"
11014 [(match_parallel 0 "load_multiple_operation"
11015 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11016 (plus:SI (match_dup 1)
11017 (match_operand:SI 2 "const_int_I_operand" "I")))
11018 (set (match_operand:SI 3 "s_register_operand" "=rk")
11019 (mem:SI (match_dup 1)))
11020 ])]
11021 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11022 "*
11023 {
11024 arm_output_multireg_pop (operands, /*return_pc=*/false,
11025 /*cond=*/const_true_rtx,
11026 /*reverse=*/false,
11027 /*update=*/true);
11028 return \"\";
11029 }
11030 "
11031 [(set_attr "type" "load_16")
11032 (set_attr "predicable" "yes")
11033 (set (attr "length")
11034 (symbol_ref "arm_attr_length_pop_multi (operands,
11035 /*return_pc=*/false,
11036 /*write_back_p=*/true)"))]
11037 )
11038
11039 ;; Pop with return (as used in epilogue RTL)
11040 ;;
11041 ;; This instruction is generated when the registers are popped at the end of
11042 ;; epilogue. Here, instead of popping the value into LR and then generating
11043 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11044 ;; with (return).
11045 (define_insn "*pop_multiple_with_writeback_and_return"
11046 [(match_parallel 0 "pop_multiple_return"
11047 [(return)
11048 (set (match_operand:SI 1 "s_register_operand" "+rk")
11049 (plus:SI (match_dup 1)
11050 (match_operand:SI 2 "const_int_I_operand" "I")))
11051 (set (match_operand:SI 3 "s_register_operand" "=rk")
11052 (mem:SI (match_dup 1)))
11053 ])]
11054 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11055 "*
11056 {
11057 arm_output_multireg_pop (operands, /*return_pc=*/true,
11058 /*cond=*/const_true_rtx,
11059 /*reverse=*/false,
11060 /*update=*/true);
11061 return \"\";
11062 }
11063 "
11064 [(set_attr "type" "load_16")
11065 (set_attr "predicable" "yes")
11066 (set (attr "length")
11067 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11068 /*write_back_p=*/true)"))]
11069 )
11070
11071 (define_insn "*pop_multiple_with_return"
11072 [(match_parallel 0 "pop_multiple_return"
11073 [(return)
11074 (set (match_operand:SI 2 "s_register_operand" "=rk")
11075 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11076 ])]
11077 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11078 "*
11079 {
11080 arm_output_multireg_pop (operands, /*return_pc=*/true,
11081 /*cond=*/const_true_rtx,
11082 /*reverse=*/false,
11083 /*update=*/false);
11084 return \"\";
11085 }
11086 "
11087 [(set_attr "type" "load_16")
11088 (set_attr "predicable" "yes")
11089 (set (attr "length")
11090 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11091 /*write_back_p=*/false)"))]
11092 )
11093
11094 ;; Load into PC and return
11095 (define_insn "*ldr_with_return"
11096 [(return)
11097 (set (reg:SI PC_REGNUM)
11098 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11099 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11100 "ldr%?\t%|pc, [%0], #4"
11101 [(set_attr "type" "load_4")
11102 (set_attr "predicable" "yes")]
11103 )
11104 ;; Pop for floating point registers (as used in epilogue RTL)
11105 (define_insn "*vfp_pop_multiple_with_writeback"
11106 [(match_parallel 0 "pop_multiple_fp"
11107 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11108 (plus:SI (match_dup 1)
11109 (match_operand:SI 2 "const_int_I_operand" "I")))
11110 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11111 (mem:DF (match_dup 1)))])]
11112 "TARGET_32BIT && TARGET_HARD_FLOAT"
11113 "*
11114 {
11115 int num_regs = XVECLEN (operands[0], 0);
11116 char pattern[100];
11117 rtx op_list[2];
11118 strcpy (pattern, \"vldm\\t\");
11119 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11120 strcat (pattern, \"!, {\");
11121 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11122 strcat (pattern, \"%P0\");
11123 if ((num_regs - 1) > 1)
11124 {
11125 strcat (pattern, \"-%P1\");
11126 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11127 }
11128
11129 strcat (pattern, \"}\");
11130 output_asm_insn (pattern, op_list);
11131 return \"\";
11132 }
11133 "
11134 [(set_attr "type" "load_16")
11135 (set_attr "conds" "unconditional")
11136 (set_attr "predicable" "no")]
11137 )
11138
11139 ;; Special patterns for dealing with the constant pool
11140
11141 (define_insn "align_4"
11142 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11143 "TARGET_EITHER"
11144 "*
11145 assemble_align (32);
11146 return \"\";
11147 "
11148 [(set_attr "type" "no_insn")]
11149 )
11150
11151 (define_insn "align_8"
11152 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11153 "TARGET_EITHER"
11154 "*
11155 assemble_align (64);
11156 return \"\";
11157 "
11158 [(set_attr "type" "no_insn")]
11159 )
11160
11161 (define_insn "consttable_end"
11162 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11163 "TARGET_EITHER"
11164 "*
11165 making_const_table = FALSE;
11166 return \"\";
11167 "
11168 [(set_attr "type" "no_insn")]
11169 )
11170
11171 (define_insn "consttable_1"
11172 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11173 "TARGET_EITHER"
11174 "*
11175 making_const_table = TRUE;
11176 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11177 assemble_zeros (3);
11178 return \"\";
11179 "
11180 [(set_attr "length" "4")
11181 (set_attr "type" "no_insn")]
11182 )
11183
11184 (define_insn "consttable_2"
11185 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11186 "TARGET_EITHER"
11187 "*
11188 {
11189 rtx x = operands[0];
11190 making_const_table = TRUE;
11191 switch (GET_MODE_CLASS (GET_MODE (x)))
11192 {
11193 case MODE_FLOAT:
11194 arm_emit_fp16_const (x);
11195 break;
11196 default:
11197 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11198 assemble_zeros (2);
11199 break;
11200 }
11201 return \"\";
11202 }"
11203 [(set_attr "length" "4")
11204 (set_attr "type" "no_insn")]
11205 )
11206
11207 (define_insn "consttable_4"
11208 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11209 "TARGET_EITHER"
11210 "*
11211 {
11212 rtx x = operands[0];
11213 making_const_table = TRUE;
11214 scalar_float_mode float_mode;
11215 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11216 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11217 else
11218 {
11219 /* XXX: Sometimes gcc does something really dumb and ends up with
11220 a HIGH in a constant pool entry, usually because it's trying to
11221 load into a VFP register. We know this will always be used in
11222 combination with a LO_SUM which ignores the high bits, so just
11223 strip off the HIGH. */
11224 if (GET_CODE (x) == HIGH)
11225 x = XEXP (x, 0);
11226 assemble_integer (x, 4, BITS_PER_WORD, 1);
11227 mark_symbol_refs_as_used (x);
11228 }
11229 return \"\";
11230 }"
11231 [(set_attr "length" "4")
11232 (set_attr "type" "no_insn")]
11233 )
11234
11235 (define_insn "consttable_8"
11236 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11237 "TARGET_EITHER"
11238 "*
11239 {
11240 making_const_table = TRUE;
11241 scalar_float_mode float_mode;
11242 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11243 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11244 float_mode, BITS_PER_WORD);
11245 else
11246 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11247 return \"\";
11248 }"
11249 [(set_attr "length" "8")
11250 (set_attr "type" "no_insn")]
11251 )
11252
11253 (define_insn "consttable_16"
11254 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11255 "TARGET_EITHER"
11256 "*
11257 {
11258 making_const_table = TRUE;
11259 scalar_float_mode float_mode;
11260 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11261 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11262 float_mode, BITS_PER_WORD);
11263 else
11264 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11265 return \"\";
11266 }"
11267 [(set_attr "length" "16")
11268 (set_attr "type" "no_insn")]
11269 )
11270
11271 ;; V5 Instructions,
11272
11273 (define_insn "clzsi2"
11274 [(set (match_operand:SI 0 "s_register_operand" "=r")
11275 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11276 "TARGET_32BIT && arm_arch5"
11277 "clz%?\\t%0, %1"
11278 [(set_attr "predicable" "yes")
11279 (set_attr "type" "clz")])
11280
11281 (define_insn "rbitsi2"
11282 [(set (match_operand:SI 0 "s_register_operand" "=r")
11283 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11284 "TARGET_32BIT && arm_arch_thumb2"
11285 "rbit%?\\t%0, %1"
11286 [(set_attr "predicable" "yes")
11287 (set_attr "type" "clz")])
11288
11289 ;; Keep this as a CTZ expression until after reload and then split
11290 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11291 ;; to fold with any other expression.
11292
11293 (define_insn_and_split "ctzsi2"
11294 [(set (match_operand:SI 0 "s_register_operand" "=r")
11295 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11296 "TARGET_32BIT && arm_arch_thumb2"
11297 "#"
11298 "&& reload_completed"
11299 [(const_int 0)]
11300 "
11301 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11302 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11303 DONE;
11304 ")
11305
11306 ;; V5E instructions.
11307
11308 (define_insn "prefetch"
11309 [(prefetch (match_operand:SI 0 "address_operand" "p")
11310 (match_operand:SI 1 "" "")
11311 (match_operand:SI 2 "" ""))]
11312 "TARGET_32BIT && arm_arch5e"
11313 "pld\\t%a0"
11314 [(set_attr "type" "load_4")]
11315 )
11316
11317 ;; General predication pattern
11318
11319 (define_cond_exec
11320 [(match_operator 0 "arm_comparison_operator"
11321 [(match_operand 1 "cc_register" "")
11322 (const_int 0)])]
11323 "TARGET_32BIT
11324 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11325 ""
11326 [(set_attr "predicated" "yes")]
11327 )
11328
11329 (define_insn "force_register_use"
11330 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11331 ""
11332 "%@ %0 needed"
11333 [(set_attr "length" "0")
11334 (set_attr "type" "no_insn")]
11335 )
11336
11337
11338 ;; Patterns for exception handling
11339
11340 (define_expand "eh_return"
11341 [(use (match_operand 0 "general_operand" ""))]
11342 "TARGET_EITHER"
11343 "
11344 {
11345 if (TARGET_32BIT)
11346 emit_insn (gen_arm_eh_return (operands[0]));
11347 else
11348 emit_insn (gen_thumb_eh_return (operands[0]));
11349 DONE;
11350 }"
11351 )
11352
11353 ;; We can't expand this before we know where the link register is stored.
11354 (define_insn_and_split "arm_eh_return"
11355 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11356 VUNSPEC_EH_RETURN)
11357 (clobber (match_scratch:SI 1 "=&r"))]
11358 "TARGET_ARM"
11359 "#"
11360 "&& reload_completed"
11361 [(const_int 0)]
11362 "
11363 {
11364 arm_set_return_address (operands[0], operands[1]);
11365 DONE;
11366 }"
11367 )
11368
11369 \f
11370 ;; TLS support
11371
11372 (define_insn "load_tp_hard"
11373 [(set (match_operand:SI 0 "register_operand" "=r")
11374 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11375 "TARGET_HARD_TP"
11376 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11377 [(set_attr "predicable" "yes")
11378 (set_attr "type" "mrs")]
11379 )
11380
11381 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11382 (define_insn "load_tp_soft"
11383 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11384 (clobber (reg:SI LR_REGNUM))
11385 (clobber (reg:SI IP_REGNUM))
11386 (clobber (reg:CC CC_REGNUM))]
11387 "TARGET_SOFT_TP"
11388 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11389 [(set_attr "conds" "clob")
11390 (set_attr "type" "branch")]
11391 )
11392
11393 ;; tls descriptor call
11394 (define_insn "tlscall"
11395 [(set (reg:SI R0_REGNUM)
11396 (unspec:SI [(reg:SI R0_REGNUM)
11397 (match_operand:SI 0 "" "X")
11398 (match_operand 1 "" "")] UNSPEC_TLS))
11399 (clobber (reg:SI R1_REGNUM))
11400 (clobber (reg:SI LR_REGNUM))
11401 (clobber (reg:SI CC_REGNUM))]
11402 "TARGET_GNU2_TLS"
11403 {
11404 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11405 INTVAL (operands[1]));
11406 return "bl\\t%c0(tlscall)";
11407 }
11408 [(set_attr "conds" "clob")
11409 (set_attr "length" "4")
11410 (set_attr "type" "branch")]
11411 )
11412
11413 ;; For thread pointer builtin
11414 (define_expand "get_thread_pointersi"
11415 [(match_operand:SI 0 "s_register_operand" "=r")]
11416 ""
11417 "
11418 {
11419 arm_load_tp (operands[0]);
11420 DONE;
11421 }")
11422
11423 ;;
11424
11425 ;; We only care about the lower 16 bits of the constant
11426 ;; being inserted into the upper 16 bits of the register.
11427 (define_insn "*arm_movtas_ze"
11428 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11429 (const_int 16)
11430 (const_int 16))
11431 (match_operand:SI 1 "const_int_operand" ""))]
11432 "TARGET_HAVE_MOVT"
11433 "@
11434 movt%?\t%0, %L1
11435 movt\t%0, %L1"
11436 [(set_attr "arch" "32,v8mb")
11437 (set_attr "predicable" "yes")
11438 (set_attr "length" "4")
11439 (set_attr "type" "alu_sreg")]
11440 )
11441
11442 (define_insn "*arm_rev"
11443 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11444 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11445 "arm_arch6"
11446 "@
11447 rev\t%0, %1
11448 rev%?\t%0, %1
11449 rev%?\t%0, %1"
11450 [(set_attr "arch" "t1,t2,32")
11451 (set_attr "length" "2,2,4")
11452 (set_attr "predicable" "no,yes,yes")
11453 (set_attr "type" "rev")]
11454 )
11455
11456 (define_expand "arm_legacy_rev"
11457 [(set (match_operand:SI 2 "s_register_operand" "")
11458 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11459 (const_int 16))
11460 (match_dup 1)))
11461 (set (match_dup 2)
11462 (lshiftrt:SI (match_dup 2)
11463 (const_int 8)))
11464 (set (match_operand:SI 3 "s_register_operand" "")
11465 (rotatert:SI (match_dup 1)
11466 (const_int 8)))
11467 (set (match_dup 2)
11468 (and:SI (match_dup 2)
11469 (const_int -65281)))
11470 (set (match_operand:SI 0 "s_register_operand" "")
11471 (xor:SI (match_dup 3)
11472 (match_dup 2)))]
11473 "TARGET_32BIT"
11474 ""
11475 )
11476
11477 ;; Reuse temporaries to keep register pressure down.
11478 (define_expand "thumb_legacy_rev"
11479 [(set (match_operand:SI 2 "s_register_operand" "")
11480 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11481 (const_int 24)))
11482 (set (match_operand:SI 3 "s_register_operand" "")
11483 (lshiftrt:SI (match_dup 1)
11484 (const_int 24)))
11485 (set (match_dup 3)
11486 (ior:SI (match_dup 3)
11487 (match_dup 2)))
11488 (set (match_operand:SI 4 "s_register_operand" "")
11489 (const_int 16))
11490 (set (match_operand:SI 5 "s_register_operand" "")
11491 (rotatert:SI (match_dup 1)
11492 (match_dup 4)))
11493 (set (match_dup 2)
11494 (ashift:SI (match_dup 5)
11495 (const_int 24)))
11496 (set (match_dup 5)
11497 (lshiftrt:SI (match_dup 5)
11498 (const_int 24)))
11499 (set (match_dup 5)
11500 (ior:SI (match_dup 5)
11501 (match_dup 2)))
11502 (set (match_dup 5)
11503 (rotatert:SI (match_dup 5)
11504 (match_dup 4)))
11505 (set (match_operand:SI 0 "s_register_operand" "")
11506 (ior:SI (match_dup 5)
11507 (match_dup 3)))]
11508 "TARGET_THUMB"
11509 ""
11510 )
11511
11512 ;; ARM-specific expansion of signed mod by power of 2
11513 ;; using conditional negate.
11514 ;; For r0 % n where n is a power of 2 produce:
11515 ;; rsbs r1, r0, #0
11516 ;; and r0, r0, #(n - 1)
11517 ;; and r1, r1, #(n - 1)
11518 ;; rsbpl r0, r1, #0
11519
11520 (define_expand "modsi3"
11521 [(match_operand:SI 0 "register_operand" "")
11522 (match_operand:SI 1 "register_operand" "")
11523 (match_operand:SI 2 "const_int_operand" "")]
11524 "TARGET_32BIT"
11525 {
11526 HOST_WIDE_INT val = INTVAL (operands[2]);
11527
11528 if (val <= 0
11529 || exact_log2 (val) <= 0)
11530 FAIL;
11531
11532 rtx mask = GEN_INT (val - 1);
11533
11534 /* In the special case of x0 % 2 we can do the even shorter:
11535 cmp r0, #0
11536 and r0, r0, #1
11537 rsblt r0, r0, #0. */
11538
11539 if (val == 2)
11540 {
11541 rtx cc_reg = arm_gen_compare_reg (LT,
11542 operands[1], const0_rtx, NULL_RTX);
11543 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11544 rtx masked = gen_reg_rtx (SImode);
11545
11546 emit_insn (gen_andsi3 (masked, operands[1], mask));
11547 emit_move_insn (operands[0],
11548 gen_rtx_IF_THEN_ELSE (SImode, cond,
11549 gen_rtx_NEG (SImode,
11550 masked),
11551 masked));
11552 DONE;
11553 }
11554
11555 rtx neg_op = gen_reg_rtx (SImode);
11556 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11557 operands[1]));
11558
11559 /* Extract the condition register and mode. */
11560 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11561 rtx cc_reg = SET_DEST (cmp);
11562 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11563
11564 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11565
11566 rtx masked_neg = gen_reg_rtx (SImode);
11567 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11568
11569 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11570 during expand does not always work. Do an IF_THEN_ELSE instead. */
11571 emit_move_insn (operands[0],
11572 gen_rtx_IF_THEN_ELSE (SImode, cond,
11573 gen_rtx_NEG (SImode, masked_neg),
11574 operands[0]));
11575
11576
11577 DONE;
11578 }
11579 )
11580
11581 (define_expand "bswapsi2"
11582 [(set (match_operand:SI 0 "s_register_operand" "=r")
11583 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11584 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11585 "
11586 if (!arm_arch6)
11587 {
11588 rtx op2 = gen_reg_rtx (SImode);
11589 rtx op3 = gen_reg_rtx (SImode);
11590
11591 if (TARGET_THUMB)
11592 {
11593 rtx op4 = gen_reg_rtx (SImode);
11594 rtx op5 = gen_reg_rtx (SImode);
11595
11596 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11597 op2, op3, op4, op5));
11598 }
11599 else
11600 {
11601 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11602 op2, op3));
11603 }
11604
11605 DONE;
11606 }
11607 "
11608 )
11609
11610 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11611 ;; and unsigned variants, respectively. For rev16, expose
11612 ;; byte-swapping in the lower 16 bits only.
11613 (define_insn "*arm_revsh"
11614 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11615 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11616 "arm_arch6"
11617 "@
11618 revsh\t%0, %1
11619 revsh%?\t%0, %1
11620 revsh%?\t%0, %1"
11621 [(set_attr "arch" "t1,t2,32")
11622 (set_attr "length" "2,2,4")
11623 (set_attr "type" "rev")]
11624 )
11625
11626 (define_insn "*arm_rev16"
11627 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11628 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11629 "arm_arch6"
11630 "@
11631 rev16\t%0, %1
11632 rev16%?\t%0, %1
11633 rev16%?\t%0, %1"
11634 [(set_attr "arch" "t1,t2,32")
11635 (set_attr "length" "2,2,4")
11636 (set_attr "type" "rev")]
11637 )
11638
11639 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11640 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11641 ;; each valid permutation.
11642
11643 (define_insn "arm_rev16si2"
11644 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11645 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11646 (const_int 8))
11647 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11648 (and:SI (lshiftrt:SI (match_dup 1)
11649 (const_int 8))
11650 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11651 "arm_arch6
11652 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11653 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11654 "rev16\\t%0, %1"
11655 [(set_attr "arch" "t1,t2,32")
11656 (set_attr "length" "2,2,4")
11657 (set_attr "type" "rev")]
11658 )
11659
11660 (define_insn "arm_rev16si2_alt"
11661 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11662 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11663 (const_int 8))
11664 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11665 (and:SI (ashift:SI (match_dup 1)
11666 (const_int 8))
11667 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11668 "arm_arch6
11669 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11670 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11671 "rev16\\t%0, %1"
11672 [(set_attr "arch" "t1,t2,32")
11673 (set_attr "length" "2,2,4")
11674 (set_attr "type" "rev")]
11675 )
11676
11677 (define_expand "bswaphi2"
11678 [(set (match_operand:HI 0 "s_register_operand" "=r")
11679 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11680 "arm_arch6"
11681 ""
11682 )
11683
11684 ;; Patterns for LDRD/STRD in Thumb2 mode
11685
11686 (define_insn "*thumb2_ldrd"
11687 [(set (match_operand:SI 0 "s_register_operand" "=r")
11688 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11689 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11690 (set (match_operand:SI 3 "s_register_operand" "=r")
11691 (mem:SI (plus:SI (match_dup 1)
11692 (match_operand:SI 4 "const_int_operand" ""))))]
11693 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11694 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11695 && (operands_ok_ldrd_strd (operands[0], operands[3],
11696 operands[1], INTVAL (operands[2]),
11697 false, true))"
11698 "ldrd%?\t%0, %3, [%1, %2]"
11699 [(set_attr "type" "load_8")
11700 (set_attr "predicable" "yes")])
11701
11702 (define_insn "*thumb2_ldrd_base"
11703 [(set (match_operand:SI 0 "s_register_operand" "=r")
11704 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11705 (set (match_operand:SI 2 "s_register_operand" "=r")
11706 (mem:SI (plus:SI (match_dup 1)
11707 (const_int 4))))]
11708 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11709 && (operands_ok_ldrd_strd (operands[0], operands[2],
11710 operands[1], 0, false, true))"
11711 "ldrd%?\t%0, %2, [%1]"
11712 [(set_attr "type" "load_8")
11713 (set_attr "predicable" "yes")])
11714
11715 (define_insn "*thumb2_ldrd_base_neg"
11716 [(set (match_operand:SI 0 "s_register_operand" "=r")
11717 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11718 (const_int -4))))
11719 (set (match_operand:SI 2 "s_register_operand" "=r")
11720 (mem:SI (match_dup 1)))]
11721 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11722 && (operands_ok_ldrd_strd (operands[0], operands[2],
11723 operands[1], -4, false, true))"
11724 "ldrd%?\t%0, %2, [%1, #-4]"
11725 [(set_attr "type" "load_8")
11726 (set_attr "predicable" "yes")])
11727
11728 (define_insn "*thumb2_strd"
11729 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11730 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11731 (match_operand:SI 2 "s_register_operand" "r"))
11732 (set (mem:SI (plus:SI (match_dup 0)
11733 (match_operand:SI 3 "const_int_operand" "")))
11734 (match_operand:SI 4 "s_register_operand" "r"))]
11735 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11736 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11737 && (operands_ok_ldrd_strd (operands[2], operands[4],
11738 operands[0], INTVAL (operands[1]),
11739 false, false))"
11740 "strd%?\t%2, %4, [%0, %1]"
11741 [(set_attr "type" "store_8")
11742 (set_attr "predicable" "yes")])
11743
11744 (define_insn "*thumb2_strd_base"
11745 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11746 (match_operand:SI 1 "s_register_operand" "r"))
11747 (set (mem:SI (plus:SI (match_dup 0)
11748 (const_int 4)))
11749 (match_operand:SI 2 "s_register_operand" "r"))]
11750 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11751 && (operands_ok_ldrd_strd (operands[1], operands[2],
11752 operands[0], 0, false, false))"
11753 "strd%?\t%1, %2, [%0]"
11754 [(set_attr "type" "store_8")
11755 (set_attr "predicable" "yes")])
11756
11757 (define_insn "*thumb2_strd_base_neg"
11758 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11759 (const_int -4)))
11760 (match_operand:SI 1 "s_register_operand" "r"))
11761 (set (mem:SI (match_dup 0))
11762 (match_operand:SI 2 "s_register_operand" "r"))]
11763 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11764 && (operands_ok_ldrd_strd (operands[1], operands[2],
11765 operands[0], -4, false, false))"
11766 "strd%?\t%1, %2, [%0, #-4]"
11767 [(set_attr "type" "store_8")
11768 (set_attr "predicable" "yes")])
11769
11770 ;; ARMv8 CRC32 instructions.
11771 (define_insn "<crc_variant>"
11772 [(set (match_operand:SI 0 "s_register_operand" "=r")
11773 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11774 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11775 CRC))]
11776 "TARGET_CRC32"
11777 "<crc_variant>\\t%0, %1, %2"
11778 [(set_attr "type" "crc")
11779 (set_attr "conds" "unconditional")]
11780 )
11781
11782 ;; Load the load/store double peephole optimizations.
11783 (include "ldrdstrd.md")
11784
11785 ;; Load the load/store multiple patterns
11786 (include "ldmstm.md")
11787
11788 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11789 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11790 ;; The operands are validated through the load_multiple_operation
11791 ;; match_parallel predicate rather than through constraints so enable it only
11792 ;; after reload.
11793 (define_insn "*load_multiple"
11794 [(match_parallel 0 "load_multiple_operation"
11795 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11796 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11797 ])]
11798 "TARGET_32BIT && reload_completed"
11799 "*
11800 {
11801 arm_output_multireg_pop (operands, /*return_pc=*/false,
11802 /*cond=*/const_true_rtx,
11803 /*reverse=*/false,
11804 /*update=*/false);
11805 return \"\";
11806 }
11807 "
11808 [(set_attr "predicable" "yes")]
11809 )
11810
11811 (define_expand "copysignsf3"
11812 [(match_operand:SF 0 "register_operand")
11813 (match_operand:SF 1 "register_operand")
11814 (match_operand:SF 2 "register_operand")]
11815 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11816 "{
11817 emit_move_insn (operands[0], operands[2]);
11818 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11819 GEN_INT (31), GEN_INT (0),
11820 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11821 DONE;
11822 }"
11823 )
11824
11825 (define_expand "copysigndf3"
11826 [(match_operand:DF 0 "register_operand")
11827 (match_operand:DF 1 "register_operand")
11828 (match_operand:DF 2 "register_operand")]
11829 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11830 "{
11831 rtx op0_low = gen_lowpart (SImode, operands[0]);
11832 rtx op0_high = gen_highpart (SImode, operands[0]);
11833 rtx op1_low = gen_lowpart (SImode, operands[1]);
11834 rtx op1_high = gen_highpart (SImode, operands[1]);
11835 rtx op2_high = gen_highpart (SImode, operands[2]);
11836
11837 rtx scratch1 = gen_reg_rtx (SImode);
11838 rtx scratch2 = gen_reg_rtx (SImode);
11839 emit_move_insn (scratch1, op2_high);
11840 emit_move_insn (scratch2, op1_high);
11841
11842 emit_insn(gen_rtx_SET(scratch1,
11843 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11844 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11845 emit_move_insn (op0_low, op1_low);
11846 emit_move_insn (op0_high, scratch2);
11847
11848 DONE;
11849 }"
11850 )
11851
11852 ;; movmisalign patterns for HImode and SImode.
11853 (define_expand "movmisalign<mode>"
11854 [(match_operand:HSI 0 "general_operand")
11855 (match_operand:HSI 1 "general_operand")]
11856 "unaligned_access"
11857 {
11858 /* This pattern is not permitted to fail during expansion: if both arguments
11859 are non-registers (e.g. memory := constant), force operand 1 into a
11860 register. */
11861 rtx (* gen_unaligned_load)(rtx, rtx);
11862 rtx tmp_dest = operands[0];
11863 if (!s_register_operand (operands[0], <MODE>mode)
11864 && !s_register_operand (operands[1], <MODE>mode))
11865 operands[1] = force_reg (<MODE>mode, operands[1]);
11866
11867 if (<MODE>mode == HImode)
11868 {
11869 gen_unaligned_load = gen_unaligned_loadhiu;
11870 tmp_dest = gen_reg_rtx (SImode);
11871 }
11872 else
11873 gen_unaligned_load = gen_unaligned_loadsi;
11874
11875 if (MEM_P (operands[1]))
11876 {
11877 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11878 if (<MODE>mode == HImode)
11879 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11880 }
11881 else
11882 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11883
11884 DONE;
11885 })
11886
11887 (define_insn "<cdp>"
11888 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11889 (match_operand:SI 1 "immediate_operand" "n")
11890 (match_operand:SI 2 "immediate_operand" "n")
11891 (match_operand:SI 3 "immediate_operand" "n")
11892 (match_operand:SI 4 "immediate_operand" "n")
11893 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11894 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11895 {
11896 arm_const_bounds (operands[0], 0, 16);
11897 arm_const_bounds (operands[1], 0, 16);
11898 arm_const_bounds (operands[2], 0, (1 << 5));
11899 arm_const_bounds (operands[3], 0, (1 << 5));
11900 arm_const_bounds (operands[4], 0, (1 << 5));
11901 arm_const_bounds (operands[5], 0, 8);
11902 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11903 }
11904 [(set_attr "length" "4")
11905 (set_attr "type" "coproc")])
11906
11907 (define_insn "*ldc"
11908 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11909 (match_operand:SI 1 "immediate_operand" "n")
11910 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11911 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11912 {
11913 arm_const_bounds (operands[0], 0, 16);
11914 arm_const_bounds (operands[1], 0, (1 << 5));
11915 return "<ldc>\\tp%c0, CR%c1, %2";
11916 }
11917 [(set_attr "length" "4")
11918 (set_attr "type" "coproc")])
11919
11920 (define_insn "*stc"
11921 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11922 (match_operand:SI 1 "immediate_operand" "n")
11923 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11924 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11925 {
11926 arm_const_bounds (operands[0], 0, 16);
11927 arm_const_bounds (operands[1], 0, (1 << 5));
11928 return "<stc>\\tp%c0, CR%c1, %2";
11929 }
11930 [(set_attr "length" "4")
11931 (set_attr "type" "coproc")])
11932
11933 (define_expand "<ldc>"
11934 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11935 (match_operand:SI 1 "immediate_operand")
11936 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11937 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11938
11939 (define_expand "<stc>"
11940 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11941 (match_operand:SI 1 "immediate_operand")
11942 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11943 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
11944
11945 (define_insn "<mcr>"
11946 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11947 (match_operand:SI 1 "immediate_operand" "n")
11948 (match_operand:SI 2 "s_register_operand" "r")
11949 (match_operand:SI 3 "immediate_operand" "n")
11950 (match_operand:SI 4 "immediate_operand" "n")
11951 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
11952 (use (match_dup 2))]
11953 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
11954 {
11955 arm_const_bounds (operands[0], 0, 16);
11956 arm_const_bounds (operands[1], 0, 8);
11957 arm_const_bounds (operands[3], 0, (1 << 5));
11958 arm_const_bounds (operands[4], 0, (1 << 5));
11959 arm_const_bounds (operands[5], 0, 8);
11960 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
11961 }
11962 [(set_attr "length" "4")
11963 (set_attr "type" "coproc")])
11964
11965 (define_insn "<mrc>"
11966 [(set (match_operand:SI 0 "s_register_operand" "=r")
11967 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
11968 (match_operand:SI 2 "immediate_operand" "n")
11969 (match_operand:SI 3 "immediate_operand" "n")
11970 (match_operand:SI 4 "immediate_operand" "n")
11971 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
11972 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
11973 {
11974 arm_const_bounds (operands[1], 0, 16);
11975 arm_const_bounds (operands[2], 0, 8);
11976 arm_const_bounds (operands[3], 0, (1 << 5));
11977 arm_const_bounds (operands[4], 0, (1 << 5));
11978 arm_const_bounds (operands[5], 0, 8);
11979 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
11980 }
11981 [(set_attr "length" "4")
11982 (set_attr "type" "coproc")])
11983
11984 (define_insn "<mcrr>"
11985 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11986 (match_operand:SI 1 "immediate_operand" "n")
11987 (match_operand:DI 2 "s_register_operand" "r")
11988 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
11989 (use (match_dup 2))]
11990 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
11991 {
11992 arm_const_bounds (operands[0], 0, 16);
11993 arm_const_bounds (operands[1], 0, 8);
11994 arm_const_bounds (operands[3], 0, (1 << 5));
11995 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
11996 }
11997 [(set_attr "length" "4")
11998 (set_attr "type" "coproc")])
11999
12000 (define_insn "<mrrc>"
12001 [(set (match_operand:DI 0 "s_register_operand" "=r")
12002 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12003 (match_operand:SI 2 "immediate_operand" "n")
12004 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12005 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12006 {
12007 arm_const_bounds (operands[1], 0, 16);
12008 arm_const_bounds (operands[2], 0, 8);
12009 arm_const_bounds (operands[3], 0, (1 << 5));
12010 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12011 }
12012 [(set_attr "length" "4")
12013 (set_attr "type" "coproc")])
12014
12015 ;; Vector bits common to IWMMXT and Neon
12016 (include "vec-common.md")
12017 ;; Load the Intel Wireless Multimedia Extension patterns
12018 (include "iwmmxt.md")
12019 ;; Load the VFP co-processor patterns
12020 (include "vfp.md")
12021 ;; Thumb-1 patterns
12022 (include "thumb1.md")
12023 ;; Thumb-2 patterns
12024 (include "thumb2.md")
12025 ;; Neon patterns
12026 (include "neon.md")
12027 ;; Crypto patterns
12028 (include "crypto.md")
12029 ;; Synchronization Primitives
12030 (include "sync.md")
12031 ;; Fixed-point patterns
12032 (include "arm-fixed.md")