]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm.md
[ARM] Implement support for ACLE Coprocessor CDP intrinsics
[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 (IP_REGNUM 12) ; Scratch register
34 (SP_REGNUM 13) ; Stack pointer
35 (LR_REGNUM 14) ; Return address register
36 (PC_REGNUM 15) ; Program counter
37 (LAST_ARM_REGNUM 15) ;
38 (CC_REGNUM 100) ; Condition code pseudo register
39 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
40 ]
41 )
42 ;; 3rd operand to select_dominance_cc_mode
43 (define_constants
44 [(DOM_CC_X_AND_Y 0)
45 (DOM_CC_NX_OR_Y 1)
46 (DOM_CC_X_OR_Y 2)
47 ]
48 )
49 ;; conditional compare combination
50 (define_constants
51 [(CMP_CMP 0)
52 (CMN_CMP 1)
53 (CMP_CMN 2)
54 (CMN_CMN 3)
55 (NUM_OF_COND_CMP 4)
56 ]
57 )
58
59 \f
60 ;;---------------------------------------------------------------------------
61 ;; Attributes
62
63 ;; Processor type. This is created automatically from arm-cores.def.
64 (include "arm-tune.md")
65
66 ;; Instruction classification types
67 (include "types.md")
68
69 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70 ; generating ARM code. This is used to control the length of some insn
71 ; patterns that share the same RTL in both ARM and Thumb code.
72 (define_attr "is_thumb" "yes,no"
73 (const (if_then_else (symbol_ref "TARGET_THUMB")
74 (const_string "yes") (const_string "no"))))
75
76 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
78
79 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
80 (define_attr "is_thumb1" "yes,no"
81 (const (if_then_else (symbol_ref "TARGET_THUMB1")
82 (const_string "yes") (const_string "no"))))
83
84 ; We use this attribute to disable alternatives that can produce 32-bit
85 ; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
86 ; that contain 32-bit instructions.
87 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
88
89 ; This attribute is used to disable a predicated alternative when we have
90 ; arm_restrict_it.
91 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
92
93 ;; Operand number of an input operand that is shifted. Zero if the
94 ;; given instruction does not shift one of its input operands.
95 (define_attr "shift" "" (const_int 0))
96
97 ;; [For compatibility with AArch64 in pipeline models]
98 ;; Attribute that specifies whether or not the instruction touches fp
99 ;; registers.
100 (define_attr "fp" "no,yes" (const_string "no"))
101
102 ; Floating Point Unit. If we only have floating point emulation, then there
103 ; is no point in scheduling the floating point insns. (Well, for best
104 ; performance we should try and group them together).
105 (define_attr "fpu" "none,vfp"
106 (const (symbol_ref "arm_fpu_attr")))
107
108 ; Predicated means that the insn form is conditionally executed based on a
109 ; predicate. We default to 'no' because no Thumb patterns match this rule
110 ; and not all ARM insns do.
111 (define_attr "predicated" "yes,no" (const_string "no"))
112
113 ; LENGTH of an instruction (in bytes)
114 (define_attr "length" ""
115 (const_int 4))
116
117 ; The architecture which supports the instruction (or alternative).
118 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
119 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
120 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
121 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
122 ; Baseline. This attribute is used to compute attribute "enabled",
123 ; use type "any" to enable an alternative in all cases.
124 (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"
125 (const_string "any"))
126
127 (define_attr "arch_enabled" "no,yes"
128 (cond [(eq_attr "arch" "any")
129 (const_string "yes")
130
131 (and (eq_attr "arch" "a")
132 (match_test "TARGET_ARM"))
133 (const_string "yes")
134
135 (and (eq_attr "arch" "t")
136 (match_test "TARGET_THUMB"))
137 (const_string "yes")
138
139 (and (eq_attr "arch" "t1")
140 (match_test "TARGET_THUMB1"))
141 (const_string "yes")
142
143 (and (eq_attr "arch" "t2")
144 (match_test "TARGET_THUMB2"))
145 (const_string "yes")
146
147 (and (eq_attr "arch" "32")
148 (match_test "TARGET_32BIT"))
149 (const_string "yes")
150
151 (and (eq_attr "arch" "v6")
152 (match_test "TARGET_32BIT && arm_arch6"))
153 (const_string "yes")
154
155 (and (eq_attr "arch" "nov6")
156 (match_test "TARGET_32BIT && !arm_arch6"))
157 (const_string "yes")
158
159 (and (eq_attr "arch" "v6t2")
160 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
161 (const_string "yes")
162
163 (and (eq_attr "arch" "v8mb")
164 (match_test "TARGET_THUMB1 && arm_arch8"))
165 (const_string "yes")
166
167 (and (eq_attr "arch" "avoid_neon_for_64bits")
168 (match_test "TARGET_NEON")
169 (not (match_test "TARGET_PREFER_NEON_64BITS")))
170 (const_string "yes")
171
172 (and (eq_attr "arch" "neon_for_64bits")
173 (match_test "TARGET_NEON")
174 (match_test "TARGET_PREFER_NEON_64BITS"))
175 (const_string "yes")
176
177 (and (eq_attr "arch" "iwmmxt2")
178 (match_test "TARGET_REALLY_IWMMXT2"))
179 (const_string "yes")
180
181 (and (eq_attr "arch" "armv6_or_vfpv3")
182 (match_test "arm_arch6 || TARGET_VFP3"))
183 (const_string "yes")
184
185 (and (eq_attr "arch" "neon")
186 (match_test "TARGET_NEON"))
187 (const_string "yes")
188 ]
189
190 (const_string "no")))
191
192 (define_attr "opt" "any,speed,size"
193 (const_string "any"))
194
195 (define_attr "opt_enabled" "no,yes"
196 (cond [(eq_attr "opt" "any")
197 (const_string "yes")
198
199 (and (eq_attr "opt" "speed")
200 (match_test "optimize_function_for_speed_p (cfun)"))
201 (const_string "yes")
202
203 (and (eq_attr "opt" "size")
204 (match_test "optimize_function_for_size_p (cfun)"))
205 (const_string "yes")]
206 (const_string "no")))
207
208 (define_attr "use_literal_pool" "no,yes"
209 (cond [(and (eq_attr "type" "f_loads,f_loadd")
210 (match_test "CONSTANT_P (operands[1])"))
211 (const_string "yes")]
212 (const_string "no")))
213
214 ; Enable all alternatives that are both arch_enabled and insn_enabled.
215 ; FIXME:: opt_enabled has been temporarily removed till the time we have
216 ; an attribute that allows the use of such alternatives.
217 ; This depends on caching of speed_p, size_p on a per
218 ; alternative basis. The problem is that the enabled attribute
219 ; cannot depend on any state that is not cached or is not constant
220 ; for a compilation unit. We probably need a generic "hot/cold"
221 ; alternative which if implemented can help with this. We disable this
222 ; until such a time as this is implemented and / or the improvements or
223 ; regressions with removing this attribute are double checked.
224 ; See ashldi3_neon and <shift>di3_neon in neon.md.
225
226 (define_attr "enabled" "no,yes"
227 (cond [(and (eq_attr "predicable_short_it" "no")
228 (and (eq_attr "predicated" "yes")
229 (match_test "arm_restrict_it")))
230 (const_string "no")
231
232 (and (eq_attr "enabled_for_depr_it" "no")
233 (match_test "arm_restrict_it"))
234 (const_string "no")
235
236 (and (eq_attr "use_literal_pool" "yes")
237 (match_test "arm_disable_literal_pool"))
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,load1")
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 "s_register_operand" "=&r,&r,&r,&r,&r")
465 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
466 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
467 (clobber (reg:CC CC_REGNUM))]
468 "TARGET_32BIT && !TARGET_NEON"
469 "#"
470 "TARGET_32BIT && reload_completed
471 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
472 [(parallel [(set (reg:CC_C CC_REGNUM)
473 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
474 (match_dup 1)))
475 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
476 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
477 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
478 "
479 {
480 operands[3] = gen_highpart (SImode, operands[0]);
481 operands[0] = gen_lowpart (SImode, operands[0]);
482 operands[4] = gen_highpart (SImode, operands[1]);
483 operands[1] = gen_lowpart (SImode, operands[1]);
484 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
485 operands[2] = gen_lowpart (SImode, operands[2]);
486 }"
487 [(set_attr "conds" "clob")
488 (set_attr "length" "8")
489 (set_attr "type" "multiple")]
490 )
491
492 (define_insn_and_split "*adddi_sesidi_di"
493 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
494 (plus:DI (sign_extend:DI
495 (match_operand:SI 2 "s_register_operand" "r,r"))
496 (match_operand:DI 1 "s_register_operand" "0,r")))
497 (clobber (reg:CC CC_REGNUM))]
498 "TARGET_32BIT"
499 "#"
500 "TARGET_32BIT && reload_completed"
501 [(parallel [(set (reg:CC_C CC_REGNUM)
502 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
503 (match_dup 1)))
504 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
505 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
506 (const_int 31))
507 (match_dup 4))
508 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
509 "
510 {
511 operands[3] = gen_highpart (SImode, operands[0]);
512 operands[0] = gen_lowpart (SImode, operands[0]);
513 operands[4] = gen_highpart (SImode, operands[1]);
514 operands[1] = gen_lowpart (SImode, operands[1]);
515 operands[2] = gen_lowpart (SImode, operands[2]);
516 }"
517 [(set_attr "conds" "clob")
518 (set_attr "length" "8")
519 (set_attr "type" "multiple")]
520 )
521
522 (define_insn_and_split "*adddi_zesidi_di"
523 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
524 (plus:DI (zero_extend:DI
525 (match_operand:SI 2 "s_register_operand" "r,r"))
526 (match_operand:DI 1 "s_register_operand" "0,r")))
527 (clobber (reg:CC CC_REGNUM))]
528 "TARGET_32BIT"
529 "#"
530 "TARGET_32BIT && reload_completed"
531 [(parallel [(set (reg:CC_C CC_REGNUM)
532 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
533 (match_dup 1)))
534 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
535 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
536 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
537 "
538 {
539 operands[3] = gen_highpart (SImode, operands[0]);
540 operands[0] = gen_lowpart (SImode, operands[0]);
541 operands[4] = gen_highpart (SImode, operands[1]);
542 operands[1] = gen_lowpart (SImode, operands[1]);
543 operands[2] = gen_lowpart (SImode, operands[2]);
544 }"
545 [(set_attr "conds" "clob")
546 (set_attr "length" "8")
547 (set_attr "type" "multiple")]
548 )
549
550 (define_expand "addv<mode>4"
551 [(match_operand:SIDI 0 "register_operand")
552 (match_operand:SIDI 1 "register_operand")
553 (match_operand:SIDI 2 "register_operand")
554 (match_operand 3 "")]
555 "TARGET_32BIT"
556 {
557 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
558 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
559
560 DONE;
561 })
562
563 (define_expand "uaddv<mode>4"
564 [(match_operand:SIDI 0 "register_operand")
565 (match_operand:SIDI 1 "register_operand")
566 (match_operand:SIDI 2 "register_operand")
567 (match_operand 3 "")]
568 "TARGET_32BIT"
569 {
570 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
571 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
572
573 DONE;
574 })
575
576 (define_expand "addsi3"
577 [(set (match_operand:SI 0 "s_register_operand" "")
578 (plus:SI (match_operand:SI 1 "s_register_operand" "")
579 (match_operand:SI 2 "reg_or_int_operand" "")))]
580 "TARGET_EITHER"
581 "
582 if (TARGET_32BIT && CONST_INT_P (operands[2]))
583 {
584 arm_split_constant (PLUS, SImode, NULL_RTX,
585 INTVAL (operands[2]), operands[0], operands[1],
586 optimize && can_create_pseudo_p ());
587 DONE;
588 }
589 "
590 )
591
592 ; If there is a scratch available, this will be faster than synthesizing the
593 ; addition.
594 (define_peephole2
595 [(match_scratch:SI 3 "r")
596 (set (match_operand:SI 0 "arm_general_register_operand" "")
597 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
598 (match_operand:SI 2 "const_int_operand" "")))]
599 "TARGET_32BIT &&
600 !(const_ok_for_arm (INTVAL (operands[2]))
601 || const_ok_for_arm (-INTVAL (operands[2])))
602 && const_ok_for_arm (~INTVAL (operands[2]))"
603 [(set (match_dup 3) (match_dup 2))
604 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
605 ""
606 )
607
608 ;; The r/r/k alternative is required when reloading the address
609 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
610 ;; put the duplicated register first, and not try the commutative version.
611 (define_insn_and_split "*arm_addsi3"
612 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
613 (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")
614 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
615 "TARGET_32BIT"
616 "@
617 add%?\\t%0, %0, %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, %1, %2
623 add%?\\t%0, %2, %1
624 add%?\\t%0, %1, %2
625 addw%?\\t%0, %1, %2
626 addw%?\\t%0, %1, %2
627 sub%?\\t%0, %1, #%n2
628 sub%?\\t%0, %1, #%n2
629 sub%?\\t%0, %1, #%n2
630 subw%?\\t%0, %1, #%n2
631 subw%?\\t%0, %1, #%n2
632 #"
633 "TARGET_32BIT
634 && CONST_INT_P (operands[2])
635 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
636 && (reload_completed || !arm_eliminable_register (operands[1]))"
637 [(clobber (const_int 0))]
638 "
639 arm_split_constant (PLUS, SImode, curr_insn,
640 INTVAL (operands[2]), operands[0],
641 operands[1], 0);
642 DONE;
643 "
644 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
645 (set_attr "predicable" "yes")
646 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
647 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
648 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
649 (const_string "alu_imm")
650 (const_string "alu_sreg")))
651 ]
652 )
653
654 (define_insn_and_split "adddi3_compareV"
655 [(set (reg:CC_V CC_REGNUM)
656 (ne:CC_V
657 (plus:TI
658 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
659 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
660 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
661 (set (match_operand:DI 0 "register_operand" "=&r")
662 (plus:DI (match_dup 1) (match_dup 2)))]
663 "TARGET_32BIT"
664 "#"
665 "&& reload_completed"
666 [(parallel [(set (reg:CC_C CC_REGNUM)
667 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
668 (match_dup 1)))
669 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
670 (parallel [(set (reg:CC_V CC_REGNUM)
671 (ne:CC_V
672 (plus:DI (plus:DI
673 (sign_extend:DI (match_dup 4))
674 (sign_extend:DI (match_dup 5)))
675 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
676 (plus:DI (sign_extend:DI
677 (plus:SI (match_dup 4) (match_dup 5)))
678 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
679 (set (match_dup 3) (plus:SI (plus:SI
680 (match_dup 4) (match_dup 5))
681 (ltu:SI (reg:CC_C CC_REGNUM)
682 (const_int 0))))])]
683 "
684 {
685 operands[3] = gen_highpart (SImode, operands[0]);
686 operands[0] = gen_lowpart (SImode, operands[0]);
687 operands[4] = gen_highpart (SImode, operands[1]);
688 operands[1] = gen_lowpart (SImode, operands[1]);
689 operands[5] = gen_highpart (SImode, operands[2]);
690 operands[2] = gen_lowpart (SImode, operands[2]);
691 }"
692 [(set_attr "conds" "set")
693 (set_attr "length" "8")
694 (set_attr "type" "multiple")]
695 )
696
697 (define_insn "addsi3_compareV"
698 [(set (reg:CC_V CC_REGNUM)
699 (ne:CC_V
700 (plus:DI
701 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
702 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
703 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
704 (set (match_operand:SI 0 "register_operand" "=r")
705 (plus:SI (match_dup 1) (match_dup 2)))]
706 "TARGET_32BIT"
707 "adds%?\\t%0, %1, %2"
708 [(set_attr "conds" "set")
709 (set_attr "type" "alus_sreg")]
710 )
711
712 (define_insn "*addsi3_compareV_upper"
713 [(set (reg:CC_V CC_REGNUM)
714 (ne:CC_V
715 (plus:DI
716 (plus:DI
717 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
718 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
719 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
720 (plus:DI (sign_extend:DI
721 (plus:SI (match_dup 1) (match_dup 2)))
722 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
723 (set (match_operand:SI 0 "register_operand" "=r")
724 (plus:SI
725 (plus:SI (match_dup 1) (match_dup 2))
726 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
727 "TARGET_32BIT"
728 "adcs%?\\t%0, %1, %2"
729 [(set_attr "conds" "set")
730 (set_attr "type" "adcs_reg")]
731 )
732
733 (define_insn_and_split "adddi3_compareC"
734 [(set (reg:CC_C CC_REGNUM)
735 (ne:CC_C
736 (plus:TI
737 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
738 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
739 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
740 (set (match_operand:DI 0 "register_operand" "=&r")
741 (plus:DI (match_dup 1) (match_dup 2)))]
742 "TARGET_32BIT"
743 "#"
744 "&& reload_completed"
745 [(parallel [(set (reg:CC_C CC_REGNUM)
746 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
747 (match_dup 1)))
748 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
749 (parallel [(set (reg:CC_C CC_REGNUM)
750 (ne:CC_C
751 (plus:DI (plus:DI
752 (zero_extend:DI (match_dup 4))
753 (zero_extend:DI (match_dup 5)))
754 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
755 (plus:DI (zero_extend:DI
756 (plus:SI (match_dup 4) (match_dup 5)))
757 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
758 (set (match_dup 3) (plus:SI
759 (plus:SI (match_dup 4) (match_dup 5))
760 (ltu:SI (reg:CC_C CC_REGNUM)
761 (const_int 0))))])]
762 "
763 {
764 operands[3] = gen_highpart (SImode, operands[0]);
765 operands[0] = gen_lowpart (SImode, operands[0]);
766 operands[4] = gen_highpart (SImode, operands[1]);
767 operands[5] = gen_highpart (SImode, operands[2]);
768 operands[1] = gen_lowpart (SImode, operands[1]);
769 operands[2] = gen_lowpart (SImode, operands[2]);
770 }"
771 [(set_attr "conds" "set")
772 (set_attr "length" "8")
773 (set_attr "type" "multiple")]
774 )
775
776 (define_insn "*addsi3_compareC_upper"
777 [(set (reg:CC_C CC_REGNUM)
778 (ne:CC_C
779 (plus:DI
780 (plus:DI
781 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
782 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
783 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
784 (plus:DI (zero_extend:DI
785 (plus:SI (match_dup 1) (match_dup 2)))
786 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
787 (set (match_operand:SI 0 "register_operand" "=r")
788 (plus:SI
789 (plus:SI (match_dup 1) (match_dup 2))
790 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
791 "TARGET_32BIT"
792 "adcs%?\\t%0, %1, %2"
793 [(set_attr "conds" "set")
794 (set_attr "type" "adcs_reg")]
795 )
796
797 (define_insn "addsi3_compareC"
798 [(set (reg:CC_C CC_REGNUM)
799 (ne:CC_C
800 (plus:DI
801 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
802 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
803 (zero_extend:DI
804 (plus:SI (match_dup 1) (match_dup 2)))))
805 (set (match_operand:SI 0 "register_operand" "=r")
806 (plus:SI (match_dup 1) (match_dup 2)))]
807 "TARGET_32BIT"
808 "adds%?\\t%0, %1, %2"
809 [(set_attr "conds" "set")
810 (set_attr "type" "alus_sreg")]
811 )
812
813 (define_insn "addsi3_compare0"
814 [(set (reg:CC_NOOV CC_REGNUM)
815 (compare:CC_NOOV
816 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
817 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
818 (const_int 0)))
819 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
820 (plus:SI (match_dup 1) (match_dup 2)))]
821 "TARGET_ARM"
822 "@
823 adds%?\\t%0, %1, %2
824 subs%?\\t%0, %1, #%n2
825 adds%?\\t%0, %1, %2"
826 [(set_attr "conds" "set")
827 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
828 )
829
830 (define_insn "*addsi3_compare0_scratch"
831 [(set (reg:CC_NOOV CC_REGNUM)
832 (compare:CC_NOOV
833 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
834 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
835 (const_int 0)))]
836 "TARGET_ARM"
837 "@
838 cmn%?\\t%0, %1
839 cmp%?\\t%0, #%n1
840 cmn%?\\t%0, %1"
841 [(set_attr "conds" "set")
842 (set_attr "predicable" "yes")
843 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
844 )
845
846 (define_insn "*compare_negsi_si"
847 [(set (reg:CC_Z CC_REGNUM)
848 (compare:CC_Z
849 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
850 (match_operand:SI 1 "s_register_operand" "l,r")))]
851 "TARGET_32BIT"
852 "cmn%?\\t%1, %0"
853 [(set_attr "conds" "set")
854 (set_attr "predicable" "yes")
855 (set_attr "arch" "t2,*")
856 (set_attr "length" "2,4")
857 (set_attr "predicable_short_it" "yes,no")
858 (set_attr "type" "alus_sreg")]
859 )
860
861 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
862 ;; addend is a constant.
863 (define_insn "cmpsi2_addneg"
864 [(set (reg:CC CC_REGNUM)
865 (compare:CC
866 (match_operand:SI 1 "s_register_operand" "r,r")
867 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
868 (set (match_operand:SI 0 "s_register_operand" "=r,r")
869 (plus:SI (match_dup 1)
870 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
871 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
872 "@
873 adds%?\\t%0, %1, %3
874 subs%?\\t%0, %1, #%n3"
875 [(set_attr "conds" "set")
876 (set_attr "type" "alus_sreg")]
877 )
878
879 ;; Convert the sequence
880 ;; sub rd, rn, #1
881 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
882 ;; bne dest
883 ;; into
884 ;; subs rd, rn, #1
885 ;; bcs dest ((unsigned)rn >= 1)
886 ;; similarly for the beq variant using bcc.
887 ;; This is a common looping idiom (while (n--))
888 (define_peephole2
889 [(set (match_operand:SI 0 "arm_general_register_operand" "")
890 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
891 (const_int -1)))
892 (set (match_operand 2 "cc_register" "")
893 (compare (match_dup 0) (const_int -1)))
894 (set (pc)
895 (if_then_else (match_operator 3 "equality_operator"
896 [(match_dup 2) (const_int 0)])
897 (match_operand 4 "" "")
898 (match_operand 5 "" "")))]
899 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
900 [(parallel[
901 (set (match_dup 2)
902 (compare:CC
903 (match_dup 1) (const_int 1)))
904 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
905 (set (pc)
906 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
907 (match_dup 4)
908 (match_dup 5)))]
909 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
910 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
911 ? GEU : LTU),
912 VOIDmode,
913 operands[2], const0_rtx);"
914 )
915
916 ;; The next four insns work because they compare the result with one of
917 ;; the operands, and we know that the use of the condition code is
918 ;; either GEU or LTU, so we can use the carry flag from the addition
919 ;; instead of doing the compare a second time.
920 (define_insn "*addsi3_compare_op1"
921 [(set (reg:CC_C CC_REGNUM)
922 (compare:CC_C
923 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
924 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
925 (match_dup 1)))
926 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
927 (plus:SI (match_dup 1) (match_dup 2)))]
928 "TARGET_32BIT"
929 "@
930 adds%?\\t%0, %1, %2
931 subs%?\\t%0, %1, #%n2
932 adds%?\\t%0, %1, %2"
933 [(set_attr "conds" "set")
934 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
935 )
936
937 (define_insn "*addsi3_compare_op2"
938 [(set (reg:CC_C CC_REGNUM)
939 (compare:CC_C
940 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
941 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
942 (match_dup 2)))
943 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
944 (plus:SI (match_dup 1) (match_dup 2)))]
945 "TARGET_32BIT"
946 "@
947 adds%?\\t%0, %1, %2
948 subs%?\\t%0, %1, #%n2
949 adds%?\\t%0, %1, %2"
950 [(set_attr "conds" "set")
951 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
952 )
953
954 (define_insn "*compare_addsi2_op0"
955 [(set (reg:CC_C CC_REGNUM)
956 (compare:CC_C
957 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
958 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
959 (match_dup 0)))]
960 "TARGET_32BIT"
961 "@
962 cmp%?\\t%0, #%n1
963 cmn%?\\t%0, %1
964 cmn%?\\t%0, %1
965 cmp%?\\t%0, #%n1
966 cmn%?\\t%0, %1"
967 [(set_attr "conds" "set")
968 (set_attr "predicable" "yes")
969 (set_attr "arch" "t2,t2,*,*,*")
970 (set_attr "predicable_short_it" "yes,yes,no,no,no")
971 (set_attr "length" "2,2,4,4,4")
972 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
973 )
974
975 (define_insn "*compare_addsi2_op1"
976 [(set (reg:CC_C CC_REGNUM)
977 (compare:CC_C
978 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
979 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
980 (match_dup 1)))]
981 "TARGET_32BIT"
982 "@
983 cmp%?\\t%0, #%n1
984 cmn%?\\t%0, %1
985 cmn%?\\t%0, %1
986 cmp%?\\t%0, #%n1
987 cmn%?\\t%0, %1"
988 [(set_attr "conds" "set")
989 (set_attr "predicable" "yes")
990 (set_attr "arch" "t2,t2,*,*,*")
991 (set_attr "predicable_short_it" "yes,yes,no,no,no")
992 (set_attr "length" "2,2,4,4,4")
993 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
994 )
995
996 (define_insn "*addsi3_carryin_<optab>"
997 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
998 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
999 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
1000 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1001 "TARGET_32BIT"
1002 "@
1003 adc%?\\t%0, %1, %2
1004 adc%?\\t%0, %1, %2
1005 sbc%?\\t%0, %1, #%B2"
1006 [(set_attr "conds" "use")
1007 (set_attr "predicable" "yes")
1008 (set_attr "arch" "t2,*,*")
1009 (set_attr "length" "4")
1010 (set_attr "predicable_short_it" "yes,no,no")
1011 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1012 )
1013
1014 (define_insn "*addsi3_carryin_alt2_<optab>"
1015 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1016 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1017 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1018 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1019 "TARGET_32BIT"
1020 "@
1021 adc%?\\t%0, %1, %2
1022 adc%?\\t%0, %1, %2
1023 sbc%?\\t%0, %1, #%B2"
1024 [(set_attr "conds" "use")
1025 (set_attr "predicable" "yes")
1026 (set_attr "arch" "t2,*,*")
1027 (set_attr "length" "4")
1028 (set_attr "predicable_short_it" "yes,no,no")
1029 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1030 )
1031
1032 (define_insn "*addsi3_carryin_shift_<optab>"
1033 [(set (match_operand:SI 0 "s_register_operand" "=r")
1034 (plus:SI (plus:SI
1035 (match_operator:SI 2 "shift_operator"
1036 [(match_operand:SI 3 "s_register_operand" "r")
1037 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1038 (match_operand:SI 1 "s_register_operand" "r"))
1039 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1040 "TARGET_32BIT"
1041 "adc%?\\t%0, %1, %3%S2"
1042 [(set_attr "conds" "use")
1043 (set_attr "predicable" "yes")
1044 (set_attr "predicable_short_it" "no")
1045 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1046 (const_string "alu_shift_imm")
1047 (const_string "alu_shift_reg")))]
1048 )
1049
1050 (define_insn "*addsi3_carryin_clobercc_<optab>"
1051 [(set (match_operand:SI 0 "s_register_operand" "=r")
1052 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1053 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1054 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1055 (clobber (reg:CC CC_REGNUM))]
1056 "TARGET_32BIT"
1057 "adcs%?\\t%0, %1, %2"
1058 [(set_attr "conds" "set")
1059 (set_attr "type" "adcs_reg")]
1060 )
1061
1062 (define_expand "subv<mode>4"
1063 [(match_operand:SIDI 0 "register_operand")
1064 (match_operand:SIDI 1 "register_operand")
1065 (match_operand:SIDI 2 "register_operand")
1066 (match_operand 3 "")]
1067 "TARGET_32BIT"
1068 {
1069 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1070 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1071
1072 DONE;
1073 })
1074
1075 (define_expand "usubv<mode>4"
1076 [(match_operand:SIDI 0 "register_operand")
1077 (match_operand:SIDI 1 "register_operand")
1078 (match_operand:SIDI 2 "register_operand")
1079 (match_operand 3 "")]
1080 "TARGET_32BIT"
1081 {
1082 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1083 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1084
1085 DONE;
1086 })
1087
1088 (define_insn_and_split "subdi3_compare1"
1089 [(set (reg:CC CC_REGNUM)
1090 (compare:CC
1091 (match_operand:DI 1 "register_operand" "r")
1092 (match_operand:DI 2 "register_operand" "r")))
1093 (set (match_operand:DI 0 "register_operand" "=&r")
1094 (minus:DI (match_dup 1) (match_dup 2)))]
1095 "TARGET_32BIT"
1096 "#"
1097 "&& reload_completed"
1098 [(parallel [(set (reg:CC CC_REGNUM)
1099 (compare:CC (match_dup 1) (match_dup 2)))
1100 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1101 (parallel [(set (reg:CC CC_REGNUM)
1102 (compare:CC (match_dup 4) (match_dup 5)))
1103 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1104 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1105 {
1106 operands[3] = gen_highpart (SImode, operands[0]);
1107 operands[0] = gen_lowpart (SImode, operands[0]);
1108 operands[4] = gen_highpart (SImode, operands[1]);
1109 operands[1] = gen_lowpart (SImode, operands[1]);
1110 operands[5] = gen_highpart (SImode, operands[2]);
1111 operands[2] = gen_lowpart (SImode, operands[2]);
1112 }
1113 [(set_attr "conds" "set")
1114 (set_attr "length" "8")
1115 (set_attr "type" "multiple")]
1116 )
1117
1118 (define_insn "subsi3_compare1"
1119 [(set (reg:CC CC_REGNUM)
1120 (compare:CC
1121 (match_operand:SI 1 "register_operand" "r")
1122 (match_operand:SI 2 "register_operand" "r")))
1123 (set (match_operand:SI 0 "register_operand" "=r")
1124 (minus:SI (match_dup 1) (match_dup 2)))]
1125 "TARGET_32BIT"
1126 "subs%?\\t%0, %1, %2"
1127 [(set_attr "conds" "set")
1128 (set_attr "type" "alus_sreg")]
1129 )
1130
1131 (define_insn "*subsi3_carryin"
1132 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1133 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1134 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1135 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1136 "TARGET_32BIT"
1137 "@
1138 sbc%?\\t%0, %1, %2
1139 rsc%?\\t%0, %2, %1
1140 sbc%?\\t%0, %2, %2, lsl #1"
1141 [(set_attr "conds" "use")
1142 (set_attr "arch" "*,a,t2")
1143 (set_attr "predicable" "yes")
1144 (set_attr "predicable_short_it" "no")
1145 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1146 )
1147
1148 (define_insn "*subsi3_carryin_const"
1149 [(set (match_operand:SI 0 "s_register_operand" "=r")
1150 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1151 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1152 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1153 "TARGET_32BIT"
1154 "sbc\\t%0, %1, #%B2"
1155 [(set_attr "conds" "use")
1156 (set_attr "type" "adc_imm")]
1157 )
1158
1159 (define_insn "*subsi3_carryin_compare"
1160 [(set (reg:CC CC_REGNUM)
1161 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1162 (match_operand:SI 2 "s_register_operand" "r")))
1163 (set (match_operand:SI 0 "s_register_operand" "=r")
1164 (minus:SI (minus:SI (match_dup 1)
1165 (match_dup 2))
1166 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1167 "TARGET_32BIT"
1168 "sbcs\\t%0, %1, %2"
1169 [(set_attr "conds" "set")
1170 (set_attr "type" "adcs_reg")]
1171 )
1172
1173 (define_insn "*subsi3_carryin_compare_const"
1174 [(set (reg:CC CC_REGNUM)
1175 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1176 (match_operand:SI 2 "arm_not_operand" "K")))
1177 (set (match_operand:SI 0 "s_register_operand" "=r")
1178 (minus:SI (plus:SI (match_dup 1)
1179 (match_dup 2))
1180 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1181 "TARGET_32BIT"
1182 "sbcs\\t%0, %1, #%B2"
1183 [(set_attr "conds" "set")
1184 (set_attr "type" "adcs_imm")]
1185 )
1186
1187 (define_insn "*subsi3_carryin_shift"
1188 [(set (match_operand:SI 0 "s_register_operand" "=r")
1189 (minus:SI (minus:SI
1190 (match_operand:SI 1 "s_register_operand" "r")
1191 (match_operator:SI 2 "shift_operator"
1192 [(match_operand:SI 3 "s_register_operand" "r")
1193 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1194 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1195 "TARGET_32BIT"
1196 "sbc%?\\t%0, %1, %3%S2"
1197 [(set_attr "conds" "use")
1198 (set_attr "predicable" "yes")
1199 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1200 (const_string "alu_shift_imm")
1201 (const_string "alu_shift_reg")))]
1202 )
1203
1204 (define_insn "*rsbsi3_carryin_shift"
1205 [(set (match_operand:SI 0 "s_register_operand" "=r")
1206 (minus:SI (minus:SI
1207 (match_operator:SI 2 "shift_operator"
1208 [(match_operand:SI 3 "s_register_operand" "r")
1209 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1210 (match_operand:SI 1 "s_register_operand" "r"))
1211 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1212 "TARGET_ARM"
1213 "rsc%?\\t%0, %1, %3%S2"
1214 [(set_attr "conds" "use")
1215 (set_attr "predicable" "yes")
1216 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1217 (const_string "alu_shift_imm")
1218 (const_string "alu_shift_reg")))]
1219 )
1220
1221 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1222 (define_split
1223 [(set (match_operand:SI 0 "s_register_operand" "")
1224 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1225 (match_operand:SI 2 "s_register_operand" ""))
1226 (const_int -1)))
1227 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1228 "TARGET_32BIT"
1229 [(set (match_dup 3) (match_dup 1))
1230 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1231 "
1232 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1233 ")
1234
1235 (define_expand "addsf3"
1236 [(set (match_operand:SF 0 "s_register_operand" "")
1237 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1238 (match_operand:SF 2 "s_register_operand" "")))]
1239 "TARGET_32BIT && TARGET_HARD_FLOAT"
1240 "
1241 ")
1242
1243 (define_expand "adddf3"
1244 [(set (match_operand:DF 0 "s_register_operand" "")
1245 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1246 (match_operand:DF 2 "s_register_operand" "")))]
1247 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1248 "
1249 ")
1250
1251 (define_expand "subdi3"
1252 [(parallel
1253 [(set (match_operand:DI 0 "s_register_operand" "")
1254 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1255 (match_operand:DI 2 "s_register_operand" "")))
1256 (clobber (reg:CC CC_REGNUM))])]
1257 "TARGET_EITHER"
1258 "
1259 if (TARGET_THUMB1)
1260 {
1261 if (!REG_P (operands[1]))
1262 operands[1] = force_reg (DImode, operands[1]);
1263 if (!REG_P (operands[2]))
1264 operands[2] = force_reg (DImode, operands[2]);
1265 }
1266 "
1267 )
1268
1269 (define_insn_and_split "*arm_subdi3"
1270 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1271 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1272 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1273 (clobber (reg:CC CC_REGNUM))]
1274 "TARGET_32BIT && !TARGET_NEON"
1275 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1276 "&& reload_completed"
1277 [(parallel [(set (reg:CC CC_REGNUM)
1278 (compare:CC (match_dup 1) (match_dup 2)))
1279 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1280 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1281 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1282 {
1283 operands[3] = gen_highpart (SImode, operands[0]);
1284 operands[0] = gen_lowpart (SImode, operands[0]);
1285 operands[4] = gen_highpart (SImode, operands[1]);
1286 operands[1] = gen_lowpart (SImode, operands[1]);
1287 operands[5] = gen_highpart (SImode, operands[2]);
1288 operands[2] = gen_lowpart (SImode, operands[2]);
1289 }
1290 [(set_attr "conds" "clob")
1291 (set_attr "length" "8")
1292 (set_attr "type" "multiple")]
1293 )
1294
1295 (define_insn_and_split "*subdi_di_zesidi"
1296 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1297 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1298 (zero_extend:DI
1299 (match_operand:SI 2 "s_register_operand" "r,r"))))
1300 (clobber (reg:CC CC_REGNUM))]
1301 "TARGET_32BIT"
1302 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1303 "&& reload_completed"
1304 [(parallel [(set (reg:CC CC_REGNUM)
1305 (compare:CC (match_dup 1) (match_dup 2)))
1306 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1307 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1308 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1309 {
1310 operands[3] = gen_highpart (SImode, operands[0]);
1311 operands[0] = gen_lowpart (SImode, operands[0]);
1312 operands[4] = gen_highpart (SImode, operands[1]);
1313 operands[1] = gen_lowpart (SImode, operands[1]);
1314 operands[5] = GEN_INT (~0);
1315 }
1316 [(set_attr "conds" "clob")
1317 (set_attr "length" "8")
1318 (set_attr "type" "multiple")]
1319 )
1320
1321 (define_insn_and_split "*subdi_di_sesidi"
1322 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1323 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1324 (sign_extend:DI
1325 (match_operand:SI 2 "s_register_operand" "r,r"))))
1326 (clobber (reg:CC CC_REGNUM))]
1327 "TARGET_32BIT"
1328 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1329 "&& reload_completed"
1330 [(parallel [(set (reg:CC CC_REGNUM)
1331 (compare:CC (match_dup 1) (match_dup 2)))
1332 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1333 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1334 (ashiftrt:SI (match_dup 2)
1335 (const_int 31)))
1336 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1337 {
1338 operands[3] = gen_highpart (SImode, operands[0]);
1339 operands[0] = gen_lowpart (SImode, operands[0]);
1340 operands[4] = gen_highpart (SImode, operands[1]);
1341 operands[1] = gen_lowpart (SImode, operands[1]);
1342 }
1343 [(set_attr "conds" "clob")
1344 (set_attr "length" "8")
1345 (set_attr "type" "multiple")]
1346 )
1347
1348 (define_insn_and_split "*subdi_zesidi_di"
1349 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1350 (minus:DI (zero_extend:DI
1351 (match_operand:SI 2 "s_register_operand" "r,r"))
1352 (match_operand:DI 1 "s_register_operand" "0,r")))
1353 (clobber (reg:CC CC_REGNUM))]
1354 "TARGET_ARM"
1355 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1356 ; is equivalent to:
1357 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1358 "&& reload_completed"
1359 [(parallel [(set (reg:CC CC_REGNUM)
1360 (compare:CC (match_dup 2) (match_dup 1)))
1361 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1362 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1363 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1364 {
1365 operands[3] = gen_highpart (SImode, operands[0]);
1366 operands[0] = gen_lowpart (SImode, operands[0]);
1367 operands[4] = gen_highpart (SImode, operands[1]);
1368 operands[1] = gen_lowpart (SImode, operands[1]);
1369 }
1370 [(set_attr "conds" "clob")
1371 (set_attr "length" "8")
1372 (set_attr "type" "multiple")]
1373 )
1374
1375 (define_insn_and_split "*subdi_sesidi_di"
1376 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1377 (minus:DI (sign_extend:DI
1378 (match_operand:SI 2 "s_register_operand" "r,r"))
1379 (match_operand:DI 1 "s_register_operand" "0,r")))
1380 (clobber (reg:CC CC_REGNUM))]
1381 "TARGET_ARM"
1382 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1383 ; is equivalent to:
1384 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1385 "&& reload_completed"
1386 [(parallel [(set (reg:CC CC_REGNUM)
1387 (compare:CC (match_dup 2) (match_dup 1)))
1388 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1389 (set (match_dup 3) (minus:SI (minus:SI
1390 (ashiftrt:SI (match_dup 2)
1391 (const_int 31))
1392 (match_dup 4))
1393 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1394 {
1395 operands[3] = gen_highpart (SImode, operands[0]);
1396 operands[0] = gen_lowpart (SImode, operands[0]);
1397 operands[4] = gen_highpart (SImode, operands[1]);
1398 operands[1] = gen_lowpart (SImode, operands[1]);
1399 }
1400 [(set_attr "conds" "clob")
1401 (set_attr "length" "8")
1402 (set_attr "type" "multiple")]
1403 )
1404
1405 (define_insn_and_split "*subdi_zesidi_zesidi"
1406 [(set (match_operand:DI 0 "s_register_operand" "=r")
1407 (minus:DI (zero_extend:DI
1408 (match_operand:SI 1 "s_register_operand" "r"))
1409 (zero_extend:DI
1410 (match_operand:SI 2 "s_register_operand" "r"))))
1411 (clobber (reg:CC CC_REGNUM))]
1412 "TARGET_32BIT"
1413 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1414 "&& reload_completed"
1415 [(parallel [(set (reg:CC CC_REGNUM)
1416 (compare:CC (match_dup 1) (match_dup 2)))
1417 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1418 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1419 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1420 {
1421 operands[3] = gen_highpart (SImode, operands[0]);
1422 operands[0] = gen_lowpart (SImode, operands[0]);
1423 }
1424 [(set_attr "conds" "clob")
1425 (set_attr "length" "8")
1426 (set_attr "type" "multiple")]
1427 )
1428
1429 (define_expand "subsi3"
1430 [(set (match_operand:SI 0 "s_register_operand" "")
1431 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1432 (match_operand:SI 2 "s_register_operand" "")))]
1433 "TARGET_EITHER"
1434 "
1435 if (CONST_INT_P (operands[1]))
1436 {
1437 if (TARGET_32BIT)
1438 {
1439 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1440 operands[1] = force_reg (SImode, operands[1]);
1441 else
1442 {
1443 arm_split_constant (MINUS, SImode, NULL_RTX,
1444 INTVAL (operands[1]), operands[0],
1445 operands[2],
1446 optimize && can_create_pseudo_p ());
1447 DONE;
1448 }
1449 }
1450 else /* TARGET_THUMB1 */
1451 operands[1] = force_reg (SImode, operands[1]);
1452 }
1453 "
1454 )
1455
1456 ; ??? Check Thumb-2 split length
1457 (define_insn_and_split "*arm_subsi3_insn"
1458 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1459 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1460 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1461 "TARGET_32BIT"
1462 "@
1463 sub%?\\t%0, %1, %2
1464 sub%?\\t%0, %2
1465 sub%?\\t%0, %1, %2
1466 rsb%?\\t%0, %2, %1
1467 rsb%?\\t%0, %2, %1
1468 sub%?\\t%0, %1, %2
1469 sub%?\\t%0, %1, %2
1470 sub%?\\t%0, %1, %2
1471 #"
1472 "&& (CONST_INT_P (operands[1])
1473 && !const_ok_for_arm (INTVAL (operands[1])))"
1474 [(clobber (const_int 0))]
1475 "
1476 arm_split_constant (MINUS, SImode, curr_insn,
1477 INTVAL (operands[1]), operands[0], operands[2], 0);
1478 DONE;
1479 "
1480 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1481 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1482 (set_attr "predicable" "yes")
1483 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1484 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1485 )
1486
1487 (define_peephole2
1488 [(match_scratch:SI 3 "r")
1489 (set (match_operand:SI 0 "arm_general_register_operand" "")
1490 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1491 (match_operand:SI 2 "arm_general_register_operand" "")))]
1492 "TARGET_32BIT
1493 && !const_ok_for_arm (INTVAL (operands[1]))
1494 && const_ok_for_arm (~INTVAL (operands[1]))"
1495 [(set (match_dup 3) (match_dup 1))
1496 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1497 ""
1498 )
1499
1500 (define_insn "subsi3_compare0"
1501 [(set (reg:CC_NOOV CC_REGNUM)
1502 (compare:CC_NOOV
1503 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1504 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1505 (const_int 0)))
1506 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1507 (minus:SI (match_dup 1) (match_dup 2)))]
1508 "TARGET_32BIT"
1509 "@
1510 subs%?\\t%0, %1, %2
1511 subs%?\\t%0, %1, %2
1512 rsbs%?\\t%0, %2, %1"
1513 [(set_attr "conds" "set")
1514 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1515 )
1516
1517 (define_insn "subsi3_compare"
1518 [(set (reg:CC CC_REGNUM)
1519 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1520 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1521 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1522 (minus:SI (match_dup 1) (match_dup 2)))]
1523 "TARGET_32BIT"
1524 "@
1525 subs%?\\t%0, %1, %2
1526 subs%?\\t%0, %1, %2
1527 rsbs%?\\t%0, %2, %1"
1528 [(set_attr "conds" "set")
1529 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1530 )
1531
1532 (define_expand "subsf3"
1533 [(set (match_operand:SF 0 "s_register_operand" "")
1534 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1535 (match_operand:SF 2 "s_register_operand" "")))]
1536 "TARGET_32BIT && TARGET_HARD_FLOAT"
1537 "
1538 ")
1539
1540 (define_expand "subdf3"
1541 [(set (match_operand:DF 0 "s_register_operand" "")
1542 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1543 (match_operand:DF 2 "s_register_operand" "")))]
1544 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1545 "
1546 ")
1547
1548 \f
1549 ;; Multiplication insns
1550
1551 (define_expand "mulhi3"
1552 [(set (match_operand:HI 0 "s_register_operand" "")
1553 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1554 (match_operand:HI 2 "s_register_operand" "")))]
1555 "TARGET_DSP_MULTIPLY"
1556 "
1557 {
1558 rtx result = gen_reg_rtx (SImode);
1559 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1560 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1561 DONE;
1562 }"
1563 )
1564
1565 (define_expand "mulsi3"
1566 [(set (match_operand:SI 0 "s_register_operand" "")
1567 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1568 (match_operand:SI 1 "s_register_operand" "")))]
1569 "TARGET_EITHER"
1570 ""
1571 )
1572
1573 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1574 (define_insn "*arm_mulsi3"
1575 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1576 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1577 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1578 "TARGET_32BIT && !arm_arch6"
1579 "mul%?\\t%0, %2, %1"
1580 [(set_attr "type" "mul")
1581 (set_attr "predicable" "yes")]
1582 )
1583
1584 (define_insn "*arm_mulsi3_v6"
1585 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1586 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1587 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1588 "TARGET_32BIT && arm_arch6"
1589 "mul%?\\t%0, %1, %2"
1590 [(set_attr "type" "mul")
1591 (set_attr "predicable" "yes")
1592 (set_attr "arch" "t2,t2,*")
1593 (set_attr "length" "4")
1594 (set_attr "predicable_short_it" "yes,yes,no")]
1595 )
1596
1597 (define_insn "*mulsi3_compare0"
1598 [(set (reg:CC_NOOV CC_REGNUM)
1599 (compare:CC_NOOV (mult:SI
1600 (match_operand:SI 2 "s_register_operand" "r,r")
1601 (match_operand:SI 1 "s_register_operand" "%0,r"))
1602 (const_int 0)))
1603 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1604 (mult:SI (match_dup 2) (match_dup 1)))]
1605 "TARGET_ARM && !arm_arch6"
1606 "muls%?\\t%0, %2, %1"
1607 [(set_attr "conds" "set")
1608 (set_attr "type" "muls")]
1609 )
1610
1611 (define_insn "*mulsi3_compare0_v6"
1612 [(set (reg:CC_NOOV CC_REGNUM)
1613 (compare:CC_NOOV (mult:SI
1614 (match_operand:SI 2 "s_register_operand" "r")
1615 (match_operand:SI 1 "s_register_operand" "r"))
1616 (const_int 0)))
1617 (set (match_operand:SI 0 "s_register_operand" "=r")
1618 (mult:SI (match_dup 2) (match_dup 1)))]
1619 "TARGET_ARM && arm_arch6 && optimize_size"
1620 "muls%?\\t%0, %2, %1"
1621 [(set_attr "conds" "set")
1622 (set_attr "type" "muls")]
1623 )
1624
1625 (define_insn "*mulsi_compare0_scratch"
1626 [(set (reg:CC_NOOV CC_REGNUM)
1627 (compare:CC_NOOV (mult:SI
1628 (match_operand:SI 2 "s_register_operand" "r,r")
1629 (match_operand:SI 1 "s_register_operand" "%0,r"))
1630 (const_int 0)))
1631 (clobber (match_scratch:SI 0 "=&r,&r"))]
1632 "TARGET_ARM && !arm_arch6"
1633 "muls%?\\t%0, %2, %1"
1634 [(set_attr "conds" "set")
1635 (set_attr "type" "muls")]
1636 )
1637
1638 (define_insn "*mulsi_compare0_scratch_v6"
1639 [(set (reg:CC_NOOV CC_REGNUM)
1640 (compare:CC_NOOV (mult:SI
1641 (match_operand:SI 2 "s_register_operand" "r")
1642 (match_operand:SI 1 "s_register_operand" "r"))
1643 (const_int 0)))
1644 (clobber (match_scratch:SI 0 "=r"))]
1645 "TARGET_ARM && arm_arch6 && optimize_size"
1646 "muls%?\\t%0, %2, %1"
1647 [(set_attr "conds" "set")
1648 (set_attr "type" "muls")]
1649 )
1650
1651 ;; Unnamed templates to match MLA instruction.
1652
1653 (define_insn "*mulsi3addsi"
1654 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1655 (plus:SI
1656 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1657 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1658 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1659 "TARGET_32BIT && !arm_arch6"
1660 "mla%?\\t%0, %2, %1, %3"
1661 [(set_attr "type" "mla")
1662 (set_attr "predicable" "yes")]
1663 )
1664
1665 (define_insn "*mulsi3addsi_v6"
1666 [(set (match_operand:SI 0 "s_register_operand" "=r")
1667 (plus:SI
1668 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1669 (match_operand:SI 1 "s_register_operand" "r"))
1670 (match_operand:SI 3 "s_register_operand" "r")))]
1671 "TARGET_32BIT && arm_arch6"
1672 "mla%?\\t%0, %2, %1, %3"
1673 [(set_attr "type" "mla")
1674 (set_attr "predicable" "yes")
1675 (set_attr "predicable_short_it" "no")]
1676 )
1677
1678 (define_insn "*mulsi3addsi_compare0"
1679 [(set (reg:CC_NOOV CC_REGNUM)
1680 (compare:CC_NOOV
1681 (plus:SI (mult:SI
1682 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1683 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1684 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1685 (const_int 0)))
1686 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1687 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1688 (match_dup 3)))]
1689 "TARGET_ARM && arm_arch6"
1690 "mlas%?\\t%0, %2, %1, %3"
1691 [(set_attr "conds" "set")
1692 (set_attr "type" "mlas")]
1693 )
1694
1695 (define_insn "*mulsi3addsi_compare0_v6"
1696 [(set (reg:CC_NOOV CC_REGNUM)
1697 (compare:CC_NOOV
1698 (plus:SI (mult:SI
1699 (match_operand:SI 2 "s_register_operand" "r")
1700 (match_operand:SI 1 "s_register_operand" "r"))
1701 (match_operand:SI 3 "s_register_operand" "r"))
1702 (const_int 0)))
1703 (set (match_operand:SI 0 "s_register_operand" "=r")
1704 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1705 (match_dup 3)))]
1706 "TARGET_ARM && arm_arch6 && optimize_size"
1707 "mlas%?\\t%0, %2, %1, %3"
1708 [(set_attr "conds" "set")
1709 (set_attr "type" "mlas")]
1710 )
1711
1712 (define_insn "*mulsi3addsi_compare0_scratch"
1713 [(set (reg:CC_NOOV CC_REGNUM)
1714 (compare:CC_NOOV
1715 (plus:SI (mult:SI
1716 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1717 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1718 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1719 (const_int 0)))
1720 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1721 "TARGET_ARM && !arm_arch6"
1722 "mlas%?\\t%0, %2, %1, %3"
1723 [(set_attr "conds" "set")
1724 (set_attr "type" "mlas")]
1725 )
1726
1727 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1728 [(set (reg:CC_NOOV CC_REGNUM)
1729 (compare:CC_NOOV
1730 (plus:SI (mult:SI
1731 (match_operand:SI 2 "s_register_operand" "r")
1732 (match_operand:SI 1 "s_register_operand" "r"))
1733 (match_operand:SI 3 "s_register_operand" "r"))
1734 (const_int 0)))
1735 (clobber (match_scratch:SI 0 "=r"))]
1736 "TARGET_ARM && arm_arch6 && optimize_size"
1737 "mlas%?\\t%0, %2, %1, %3"
1738 [(set_attr "conds" "set")
1739 (set_attr "type" "mlas")]
1740 )
1741
1742 (define_insn "*mulsi3subsi"
1743 [(set (match_operand:SI 0 "s_register_operand" "=r")
1744 (minus:SI
1745 (match_operand:SI 3 "s_register_operand" "r")
1746 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1747 (match_operand:SI 1 "s_register_operand" "r"))))]
1748 "TARGET_32BIT && arm_arch_thumb2"
1749 "mls%?\\t%0, %2, %1, %3"
1750 [(set_attr "type" "mla")
1751 (set_attr "predicable" "yes")
1752 (set_attr "predicable_short_it" "no")]
1753 )
1754
1755 (define_expand "maddsidi4"
1756 [(set (match_operand:DI 0 "s_register_operand" "")
1757 (plus:DI
1758 (mult:DI
1759 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1760 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1761 (match_operand:DI 3 "s_register_operand" "")))]
1762 "TARGET_32BIT && arm_arch3m"
1763 "")
1764
1765 (define_insn "*mulsidi3adddi"
1766 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1767 (plus:DI
1768 (mult:DI
1769 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1770 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1771 (match_operand:DI 1 "s_register_operand" "0")))]
1772 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1773 "smlal%?\\t%Q0, %R0, %3, %2"
1774 [(set_attr "type" "smlal")
1775 (set_attr "predicable" "yes")]
1776 )
1777
1778 (define_insn "*mulsidi3adddi_v6"
1779 [(set (match_operand:DI 0 "s_register_operand" "=r")
1780 (plus:DI
1781 (mult:DI
1782 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1783 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1784 (match_operand:DI 1 "s_register_operand" "0")))]
1785 "TARGET_32BIT && arm_arch6"
1786 "smlal%?\\t%Q0, %R0, %3, %2"
1787 [(set_attr "type" "smlal")
1788 (set_attr "predicable" "yes")
1789 (set_attr "predicable_short_it" "no")]
1790 )
1791
1792 ;; 32x32->64 widening multiply.
1793 ;; As with mulsi3, the only difference between the v3-5 and v6+
1794 ;; versions of these patterns is the requirement that the output not
1795 ;; overlap the inputs, but that still means we have to have a named
1796 ;; expander and two different starred insns.
1797
1798 (define_expand "mulsidi3"
1799 [(set (match_operand:DI 0 "s_register_operand" "")
1800 (mult:DI
1801 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1802 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1803 "TARGET_32BIT && arm_arch3m"
1804 ""
1805 )
1806
1807 (define_insn "*mulsidi3_nov6"
1808 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1809 (mult:DI
1810 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1811 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1812 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1813 "smull%?\\t%Q0, %R0, %1, %2"
1814 [(set_attr "type" "smull")
1815 (set_attr "predicable" "yes")]
1816 )
1817
1818 (define_insn "*mulsidi3_v6"
1819 [(set (match_operand:DI 0 "s_register_operand" "=r")
1820 (mult:DI
1821 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1822 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1823 "TARGET_32BIT && arm_arch6"
1824 "smull%?\\t%Q0, %R0, %1, %2"
1825 [(set_attr "type" "smull")
1826 (set_attr "predicable" "yes")
1827 (set_attr "predicable_short_it" "no")]
1828 )
1829
1830 (define_expand "umulsidi3"
1831 [(set (match_operand:DI 0 "s_register_operand" "")
1832 (mult:DI
1833 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1834 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1835 "TARGET_32BIT && arm_arch3m"
1836 ""
1837 )
1838
1839 (define_insn "*umulsidi3_nov6"
1840 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1841 (mult:DI
1842 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1843 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1844 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1845 "umull%?\\t%Q0, %R0, %1, %2"
1846 [(set_attr "type" "umull")
1847 (set_attr "predicable" "yes")]
1848 )
1849
1850 (define_insn "*umulsidi3_v6"
1851 [(set (match_operand:DI 0 "s_register_operand" "=r")
1852 (mult:DI
1853 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1854 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1855 "TARGET_32BIT && arm_arch6"
1856 "umull%?\\t%Q0, %R0, %1, %2"
1857 [(set_attr "type" "umull")
1858 (set_attr "predicable" "yes")
1859 (set_attr "predicable_short_it" "no")]
1860 )
1861
1862 (define_expand "umaddsidi4"
1863 [(set (match_operand:DI 0 "s_register_operand" "")
1864 (plus:DI
1865 (mult:DI
1866 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1867 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1868 (match_operand:DI 3 "s_register_operand" "")))]
1869 "TARGET_32BIT && arm_arch3m"
1870 "")
1871
1872 (define_insn "*umulsidi3adddi"
1873 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1874 (plus:DI
1875 (mult:DI
1876 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1877 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1878 (match_operand:DI 1 "s_register_operand" "0")))]
1879 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1880 "umlal%?\\t%Q0, %R0, %3, %2"
1881 [(set_attr "type" "umlal")
1882 (set_attr "predicable" "yes")]
1883 )
1884
1885 (define_insn "*umulsidi3adddi_v6"
1886 [(set (match_operand:DI 0 "s_register_operand" "=r")
1887 (plus:DI
1888 (mult:DI
1889 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1890 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1891 (match_operand:DI 1 "s_register_operand" "0")))]
1892 "TARGET_32BIT && arm_arch6"
1893 "umlal%?\\t%Q0, %R0, %3, %2"
1894 [(set_attr "type" "umlal")
1895 (set_attr "predicable" "yes")
1896 (set_attr "predicable_short_it" "no")]
1897 )
1898
1899 (define_expand "smulsi3_highpart"
1900 [(parallel
1901 [(set (match_operand:SI 0 "s_register_operand" "")
1902 (truncate:SI
1903 (lshiftrt:DI
1904 (mult:DI
1905 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1906 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1907 (const_int 32))))
1908 (clobber (match_scratch:SI 3 ""))])]
1909 "TARGET_32BIT && arm_arch3m"
1910 ""
1911 )
1912
1913 (define_insn "*smulsi3_highpart_nov6"
1914 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1915 (truncate:SI
1916 (lshiftrt:DI
1917 (mult:DI
1918 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1919 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1920 (const_int 32))))
1921 (clobber (match_scratch:SI 3 "=&r,&r"))]
1922 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1923 "smull%?\\t%3, %0, %2, %1"
1924 [(set_attr "type" "smull")
1925 (set_attr "predicable" "yes")]
1926 )
1927
1928 (define_insn "*smulsi3_highpart_v6"
1929 [(set (match_operand:SI 0 "s_register_operand" "=r")
1930 (truncate:SI
1931 (lshiftrt:DI
1932 (mult:DI
1933 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1934 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1935 (const_int 32))))
1936 (clobber (match_scratch:SI 3 "=r"))]
1937 "TARGET_32BIT && arm_arch6"
1938 "smull%?\\t%3, %0, %2, %1"
1939 [(set_attr "type" "smull")
1940 (set_attr "predicable" "yes")
1941 (set_attr "predicable_short_it" "no")]
1942 )
1943
1944 (define_expand "umulsi3_highpart"
1945 [(parallel
1946 [(set (match_operand:SI 0 "s_register_operand" "")
1947 (truncate:SI
1948 (lshiftrt:DI
1949 (mult:DI
1950 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1951 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1952 (const_int 32))))
1953 (clobber (match_scratch:SI 3 ""))])]
1954 "TARGET_32BIT && arm_arch3m"
1955 ""
1956 )
1957
1958 (define_insn "*umulsi3_highpart_nov6"
1959 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1960 (truncate:SI
1961 (lshiftrt:DI
1962 (mult:DI
1963 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1964 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1965 (const_int 32))))
1966 (clobber (match_scratch:SI 3 "=&r,&r"))]
1967 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1968 "umull%?\\t%3, %0, %2, %1"
1969 [(set_attr "type" "umull")
1970 (set_attr "predicable" "yes")]
1971 )
1972
1973 (define_insn "*umulsi3_highpart_v6"
1974 [(set (match_operand:SI 0 "s_register_operand" "=r")
1975 (truncate:SI
1976 (lshiftrt:DI
1977 (mult:DI
1978 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1979 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1980 (const_int 32))))
1981 (clobber (match_scratch:SI 3 "=r"))]
1982 "TARGET_32BIT && arm_arch6"
1983 "umull%?\\t%3, %0, %2, %1"
1984 [(set_attr "type" "umull")
1985 (set_attr "predicable" "yes")
1986 (set_attr "predicable_short_it" "no")]
1987 )
1988
1989 (define_insn "mulhisi3"
1990 [(set (match_operand:SI 0 "s_register_operand" "=r")
1991 (mult:SI (sign_extend:SI
1992 (match_operand:HI 1 "s_register_operand" "%r"))
1993 (sign_extend:SI
1994 (match_operand:HI 2 "s_register_operand" "r"))))]
1995 "TARGET_DSP_MULTIPLY"
1996 "smulbb%?\\t%0, %1, %2"
1997 [(set_attr "type" "smulxy")
1998 (set_attr "predicable" "yes")]
1999 )
2000
2001 (define_insn "*mulhisi3tb"
2002 [(set (match_operand:SI 0 "s_register_operand" "=r")
2003 (mult:SI (ashiftrt:SI
2004 (match_operand:SI 1 "s_register_operand" "r")
2005 (const_int 16))
2006 (sign_extend:SI
2007 (match_operand:HI 2 "s_register_operand" "r"))))]
2008 "TARGET_DSP_MULTIPLY"
2009 "smultb%?\\t%0, %1, %2"
2010 [(set_attr "type" "smulxy")
2011 (set_attr "predicable" "yes")
2012 (set_attr "predicable_short_it" "no")]
2013 )
2014
2015 (define_insn "*mulhisi3bt"
2016 [(set (match_operand:SI 0 "s_register_operand" "=r")
2017 (mult:SI (sign_extend:SI
2018 (match_operand:HI 1 "s_register_operand" "r"))
2019 (ashiftrt:SI
2020 (match_operand:SI 2 "s_register_operand" "r")
2021 (const_int 16))))]
2022 "TARGET_DSP_MULTIPLY"
2023 "smulbt%?\\t%0, %1, %2"
2024 [(set_attr "type" "smulxy")
2025 (set_attr "predicable" "yes")
2026 (set_attr "predicable_short_it" "no")]
2027 )
2028
2029 (define_insn "*mulhisi3tt"
2030 [(set (match_operand:SI 0 "s_register_operand" "=r")
2031 (mult:SI (ashiftrt:SI
2032 (match_operand:SI 1 "s_register_operand" "r")
2033 (const_int 16))
2034 (ashiftrt:SI
2035 (match_operand:SI 2 "s_register_operand" "r")
2036 (const_int 16))))]
2037 "TARGET_DSP_MULTIPLY"
2038 "smultt%?\\t%0, %1, %2"
2039 [(set_attr "type" "smulxy")
2040 (set_attr "predicable" "yes")
2041 (set_attr "predicable_short_it" "no")]
2042 )
2043
2044 (define_insn "maddhisi4"
2045 [(set (match_operand:SI 0 "s_register_operand" "=r")
2046 (plus:SI (mult:SI (sign_extend:SI
2047 (match_operand:HI 1 "s_register_operand" "r"))
2048 (sign_extend:SI
2049 (match_operand:HI 2 "s_register_operand" "r")))
2050 (match_operand:SI 3 "s_register_operand" "r")))]
2051 "TARGET_DSP_MULTIPLY"
2052 "smlabb%?\\t%0, %1, %2, %3"
2053 [(set_attr "type" "smlaxy")
2054 (set_attr "predicable" "yes")
2055 (set_attr "predicable_short_it" "no")]
2056 )
2057
2058 ;; Note: there is no maddhisi4ibt because this one is canonical form
2059 (define_insn "*maddhisi4tb"
2060 [(set (match_operand:SI 0 "s_register_operand" "=r")
2061 (plus:SI (mult:SI (ashiftrt:SI
2062 (match_operand:SI 1 "s_register_operand" "r")
2063 (const_int 16))
2064 (sign_extend:SI
2065 (match_operand:HI 2 "s_register_operand" "r")))
2066 (match_operand:SI 3 "s_register_operand" "r")))]
2067 "TARGET_DSP_MULTIPLY"
2068 "smlatb%?\\t%0, %1, %2, %3"
2069 [(set_attr "type" "smlaxy")
2070 (set_attr "predicable" "yes")
2071 (set_attr "predicable_short_it" "no")]
2072 )
2073
2074 (define_insn "*maddhisi4tt"
2075 [(set (match_operand:SI 0 "s_register_operand" "=r")
2076 (plus:SI (mult:SI (ashiftrt:SI
2077 (match_operand:SI 1 "s_register_operand" "r")
2078 (const_int 16))
2079 (ashiftrt:SI
2080 (match_operand:SI 2 "s_register_operand" "r")
2081 (const_int 16)))
2082 (match_operand:SI 3 "s_register_operand" "r")))]
2083 "TARGET_DSP_MULTIPLY"
2084 "smlatt%?\\t%0, %1, %2, %3"
2085 [(set_attr "type" "smlaxy")
2086 (set_attr "predicable" "yes")
2087 (set_attr "predicable_short_it" "no")]
2088 )
2089
2090 (define_insn "maddhidi4"
2091 [(set (match_operand:DI 0 "s_register_operand" "=r")
2092 (plus:DI
2093 (mult:DI (sign_extend:DI
2094 (match_operand:HI 1 "s_register_operand" "r"))
2095 (sign_extend:DI
2096 (match_operand:HI 2 "s_register_operand" "r")))
2097 (match_operand:DI 3 "s_register_operand" "0")))]
2098 "TARGET_DSP_MULTIPLY"
2099 "smlalbb%?\\t%Q0, %R0, %1, %2"
2100 [(set_attr "type" "smlalxy")
2101 (set_attr "predicable" "yes")
2102 (set_attr "predicable_short_it" "no")])
2103
2104 ;; Note: there is no maddhidi4ibt because this one is canonical form
2105 (define_insn "*maddhidi4tb"
2106 [(set (match_operand:DI 0 "s_register_operand" "=r")
2107 (plus:DI
2108 (mult:DI (sign_extend:DI
2109 (ashiftrt:SI
2110 (match_operand:SI 1 "s_register_operand" "r")
2111 (const_int 16)))
2112 (sign_extend:DI
2113 (match_operand:HI 2 "s_register_operand" "r")))
2114 (match_operand:DI 3 "s_register_operand" "0")))]
2115 "TARGET_DSP_MULTIPLY"
2116 "smlaltb%?\\t%Q0, %R0, %1, %2"
2117 [(set_attr "type" "smlalxy")
2118 (set_attr "predicable" "yes")
2119 (set_attr "predicable_short_it" "no")])
2120
2121 (define_insn "*maddhidi4tt"
2122 [(set (match_operand:DI 0 "s_register_operand" "=r")
2123 (plus:DI
2124 (mult:DI (sign_extend:DI
2125 (ashiftrt:SI
2126 (match_operand:SI 1 "s_register_operand" "r")
2127 (const_int 16)))
2128 (sign_extend:DI
2129 (ashiftrt:SI
2130 (match_operand:SI 2 "s_register_operand" "r")
2131 (const_int 16))))
2132 (match_operand:DI 3 "s_register_operand" "0")))]
2133 "TARGET_DSP_MULTIPLY"
2134 "smlaltt%?\\t%Q0, %R0, %1, %2"
2135 [(set_attr "type" "smlalxy")
2136 (set_attr "predicable" "yes")
2137 (set_attr "predicable_short_it" "no")])
2138
2139 (define_expand "mulsf3"
2140 [(set (match_operand:SF 0 "s_register_operand" "")
2141 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2142 (match_operand:SF 2 "s_register_operand" "")))]
2143 "TARGET_32BIT && TARGET_HARD_FLOAT"
2144 "
2145 ")
2146
2147 (define_expand "muldf3"
2148 [(set (match_operand:DF 0 "s_register_operand" "")
2149 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2150 (match_operand:DF 2 "s_register_operand" "")))]
2151 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2152 "
2153 ")
2154 \f
2155 ;; Division insns
2156
2157 (define_expand "divsf3"
2158 [(set (match_operand:SF 0 "s_register_operand" "")
2159 (div:SF (match_operand:SF 1 "s_register_operand" "")
2160 (match_operand:SF 2 "s_register_operand" "")))]
2161 "TARGET_32BIT && TARGET_HARD_FLOAT"
2162 "")
2163
2164 (define_expand "divdf3"
2165 [(set (match_operand:DF 0 "s_register_operand" "")
2166 (div:DF (match_operand:DF 1 "s_register_operand" "")
2167 (match_operand:DF 2 "s_register_operand" "")))]
2168 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2169 "")
2170 \f
2171 ;; Boolean and,ior,xor insns
2172
2173 ;; Split up double word logical operations
2174
2175 ;; Split up simple DImode logical operations. Simply perform the logical
2176 ;; operation on the upper and lower halves of the registers.
2177 (define_split
2178 [(set (match_operand:DI 0 "s_register_operand" "")
2179 (match_operator:DI 6 "logical_binary_operator"
2180 [(match_operand:DI 1 "s_register_operand" "")
2181 (match_operand:DI 2 "s_register_operand" "")]))]
2182 "TARGET_32BIT && reload_completed
2183 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2184 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2185 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2186 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2187 "
2188 {
2189 operands[3] = gen_highpart (SImode, operands[0]);
2190 operands[0] = gen_lowpart (SImode, operands[0]);
2191 operands[4] = gen_highpart (SImode, operands[1]);
2192 operands[1] = gen_lowpart (SImode, operands[1]);
2193 operands[5] = gen_highpart (SImode, operands[2]);
2194 operands[2] = gen_lowpart (SImode, operands[2]);
2195 }"
2196 )
2197
2198 (define_split
2199 [(set (match_operand:DI 0 "s_register_operand" "")
2200 (match_operator:DI 6 "logical_binary_operator"
2201 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2202 (match_operand:DI 1 "s_register_operand" "")]))]
2203 "TARGET_32BIT && reload_completed"
2204 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2205 (set (match_dup 3) (match_op_dup:SI 6
2206 [(ashiftrt:SI (match_dup 2) (const_int 31))
2207 (match_dup 4)]))]
2208 "
2209 {
2210 operands[3] = gen_highpart (SImode, operands[0]);
2211 operands[0] = gen_lowpart (SImode, operands[0]);
2212 operands[4] = gen_highpart (SImode, operands[1]);
2213 operands[1] = gen_lowpart (SImode, operands[1]);
2214 operands[5] = gen_highpart (SImode, operands[2]);
2215 operands[2] = gen_lowpart (SImode, operands[2]);
2216 }"
2217 )
2218
2219 ;; The zero extend of operand 2 means we can just copy the high part of
2220 ;; operand1 into operand0.
2221 (define_split
2222 [(set (match_operand:DI 0 "s_register_operand" "")
2223 (ior:DI
2224 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2225 (match_operand:DI 1 "s_register_operand" "")))]
2226 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2227 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2228 (set (match_dup 3) (match_dup 4))]
2229 "
2230 {
2231 operands[4] = gen_highpart (SImode, operands[1]);
2232 operands[3] = gen_highpart (SImode, operands[0]);
2233 operands[0] = gen_lowpart (SImode, operands[0]);
2234 operands[1] = gen_lowpart (SImode, operands[1]);
2235 }"
2236 )
2237
2238 ;; The zero extend of operand 2 means we can just copy the high part of
2239 ;; operand1 into operand0.
2240 (define_split
2241 [(set (match_operand:DI 0 "s_register_operand" "")
2242 (xor:DI
2243 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2244 (match_operand:DI 1 "s_register_operand" "")))]
2245 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2246 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2247 (set (match_dup 3) (match_dup 4))]
2248 "
2249 {
2250 operands[4] = gen_highpart (SImode, operands[1]);
2251 operands[3] = gen_highpart (SImode, operands[0]);
2252 operands[0] = gen_lowpart (SImode, operands[0]);
2253 operands[1] = gen_lowpart (SImode, operands[1]);
2254 }"
2255 )
2256
2257 (define_expand "anddi3"
2258 [(set (match_operand:DI 0 "s_register_operand" "")
2259 (and:DI (match_operand:DI 1 "s_register_operand" "")
2260 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2261 "TARGET_32BIT"
2262 ""
2263 )
2264
2265 (define_insn_and_split "*anddi3_insn"
2266 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2267 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2268 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2269 "TARGET_32BIT && !TARGET_IWMMXT"
2270 {
2271 switch (which_alternative)
2272 {
2273 case 0: /* fall through */
2274 case 6: return "vand\t%P0, %P1, %P2";
2275 case 1: /* fall through */
2276 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2277 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2278 case 2:
2279 case 3:
2280 case 4:
2281 case 5: /* fall through */
2282 return "#";
2283 default: gcc_unreachable ();
2284 }
2285 }
2286 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2287 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2288 [(set (match_dup 3) (match_dup 4))
2289 (set (match_dup 5) (match_dup 6))]
2290 "
2291 {
2292 operands[3] = gen_lowpart (SImode, operands[0]);
2293 operands[5] = gen_highpart (SImode, operands[0]);
2294
2295 operands[4] = simplify_gen_binary (AND, SImode,
2296 gen_lowpart (SImode, operands[1]),
2297 gen_lowpart (SImode, operands[2]));
2298 operands[6] = simplify_gen_binary (AND, SImode,
2299 gen_highpart (SImode, operands[1]),
2300 gen_highpart_mode (SImode, DImode, operands[2]));
2301
2302 }"
2303 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2304 multiple,multiple,neon_logic,neon_logic")
2305 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2306 avoid_neon_for_64bits,avoid_neon_for_64bits")
2307 (set_attr "length" "*,*,8,8,8,8,*,*")
2308 ]
2309 )
2310
2311 (define_insn_and_split "*anddi_zesidi_di"
2312 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2313 (and:DI (zero_extend:DI
2314 (match_operand:SI 2 "s_register_operand" "r,r"))
2315 (match_operand:DI 1 "s_register_operand" "0,r")))]
2316 "TARGET_32BIT"
2317 "#"
2318 "TARGET_32BIT && reload_completed"
2319 ; The zero extend of operand 2 clears the high word of the output
2320 ; operand.
2321 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2322 (set (match_dup 3) (const_int 0))]
2323 "
2324 {
2325 operands[3] = gen_highpart (SImode, operands[0]);
2326 operands[0] = gen_lowpart (SImode, operands[0]);
2327 operands[1] = gen_lowpart (SImode, operands[1]);
2328 }"
2329 [(set_attr "length" "8")
2330 (set_attr "type" "multiple")]
2331 )
2332
2333 (define_insn "*anddi_sesdi_di"
2334 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2335 (and:DI (sign_extend:DI
2336 (match_operand:SI 2 "s_register_operand" "r,r"))
2337 (match_operand:DI 1 "s_register_operand" "0,r")))]
2338 "TARGET_32BIT"
2339 "#"
2340 [(set_attr "length" "8")
2341 (set_attr "type" "multiple")]
2342 )
2343
2344 (define_expand "andsi3"
2345 [(set (match_operand:SI 0 "s_register_operand" "")
2346 (and:SI (match_operand:SI 1 "s_register_operand" "")
2347 (match_operand:SI 2 "reg_or_int_operand" "")))]
2348 "TARGET_EITHER"
2349 "
2350 if (TARGET_32BIT)
2351 {
2352 if (CONST_INT_P (operands[2]))
2353 {
2354 if (INTVAL (operands[2]) == 255 && arm_arch6)
2355 {
2356 operands[1] = convert_to_mode (QImode, operands[1], 1);
2357 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2358 operands[1]));
2359 DONE;
2360 }
2361 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2362 operands[2] = force_reg (SImode, operands[2]);
2363 else
2364 {
2365 arm_split_constant (AND, SImode, NULL_RTX,
2366 INTVAL (operands[2]), operands[0],
2367 operands[1],
2368 optimize && can_create_pseudo_p ());
2369
2370 DONE;
2371 }
2372 }
2373 }
2374 else /* TARGET_THUMB1 */
2375 {
2376 if (!CONST_INT_P (operands[2]))
2377 {
2378 rtx tmp = force_reg (SImode, operands[2]);
2379 if (rtx_equal_p (operands[0], operands[1]))
2380 operands[2] = tmp;
2381 else
2382 {
2383 operands[2] = operands[1];
2384 operands[1] = tmp;
2385 }
2386 }
2387 else
2388 {
2389 int i;
2390
2391 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2392 {
2393 operands[2] = force_reg (SImode,
2394 GEN_INT (~INTVAL (operands[2])));
2395
2396 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2397
2398 DONE;
2399 }
2400
2401 for (i = 9; i <= 31; i++)
2402 {
2403 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2404 {
2405 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2406 const0_rtx));
2407 DONE;
2408 }
2409 else if ((HOST_WIDE_INT_1 << i) - 1
2410 == ~INTVAL (operands[2]))
2411 {
2412 rtx shift = GEN_INT (i);
2413 rtx reg = gen_reg_rtx (SImode);
2414
2415 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2416 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2417
2418 DONE;
2419 }
2420 }
2421
2422 operands[2] = force_reg (SImode, operands[2]);
2423 }
2424 }
2425 "
2426 )
2427
2428 ; ??? Check split length for Thumb-2
2429 (define_insn_and_split "*arm_andsi3_insn"
2430 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2431 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2432 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2433 "TARGET_32BIT"
2434 "@
2435 and%?\\t%0, %1, %2
2436 and%?\\t%0, %1, %2
2437 bic%?\\t%0, %1, #%B2
2438 and%?\\t%0, %1, %2
2439 #"
2440 "TARGET_32BIT
2441 && CONST_INT_P (operands[2])
2442 && !(const_ok_for_arm (INTVAL (operands[2]))
2443 || const_ok_for_arm (~INTVAL (operands[2])))"
2444 [(clobber (const_int 0))]
2445 "
2446 arm_split_constant (AND, SImode, curr_insn,
2447 INTVAL (operands[2]), operands[0], operands[1], 0);
2448 DONE;
2449 "
2450 [(set_attr "length" "4,4,4,4,16")
2451 (set_attr "predicable" "yes")
2452 (set_attr "predicable_short_it" "no,yes,no,no,no")
2453 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2454 )
2455
2456 (define_insn "*andsi3_compare0"
2457 [(set (reg:CC_NOOV CC_REGNUM)
2458 (compare:CC_NOOV
2459 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2460 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2461 (const_int 0)))
2462 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2463 (and:SI (match_dup 1) (match_dup 2)))]
2464 "TARGET_32BIT"
2465 "@
2466 ands%?\\t%0, %1, %2
2467 bics%?\\t%0, %1, #%B2
2468 ands%?\\t%0, %1, %2"
2469 [(set_attr "conds" "set")
2470 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2471 )
2472
2473 (define_insn "*andsi3_compare0_scratch"
2474 [(set (reg:CC_NOOV CC_REGNUM)
2475 (compare:CC_NOOV
2476 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2477 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2478 (const_int 0)))
2479 (clobber (match_scratch:SI 2 "=X,r,X"))]
2480 "TARGET_32BIT"
2481 "@
2482 tst%?\\t%0, %1
2483 bics%?\\t%2, %0, #%B1
2484 tst%?\\t%0, %1"
2485 [(set_attr "conds" "set")
2486 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2487 )
2488
2489 (define_insn "*zeroextractsi_compare0_scratch"
2490 [(set (reg:CC_NOOV CC_REGNUM)
2491 (compare:CC_NOOV (zero_extract:SI
2492 (match_operand:SI 0 "s_register_operand" "r")
2493 (match_operand 1 "const_int_operand" "n")
2494 (match_operand 2 "const_int_operand" "n"))
2495 (const_int 0)))]
2496 "TARGET_32BIT
2497 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2498 && INTVAL (operands[1]) > 0
2499 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2500 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2501 "*
2502 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2503 << INTVAL (operands[2]));
2504 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2505 return \"\";
2506 "
2507 [(set_attr "conds" "set")
2508 (set_attr "predicable" "yes")
2509 (set_attr "predicable_short_it" "no")
2510 (set_attr "type" "logics_imm")]
2511 )
2512
2513 (define_insn_and_split "*ne_zeroextractsi"
2514 [(set (match_operand:SI 0 "s_register_operand" "=r")
2515 (ne:SI (zero_extract:SI
2516 (match_operand:SI 1 "s_register_operand" "r")
2517 (match_operand:SI 2 "const_int_operand" "n")
2518 (match_operand:SI 3 "const_int_operand" "n"))
2519 (const_int 0)))
2520 (clobber (reg:CC CC_REGNUM))]
2521 "TARGET_32BIT
2522 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2523 && INTVAL (operands[2]) > 0
2524 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2525 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2526 "#"
2527 "TARGET_32BIT
2528 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2529 && INTVAL (operands[2]) > 0
2530 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2531 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2532 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2533 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2534 (const_int 0)))
2535 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2536 (set (match_dup 0)
2537 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2538 (match_dup 0) (const_int 1)))]
2539 "
2540 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2541 << INTVAL (operands[3]));
2542 "
2543 [(set_attr "conds" "clob")
2544 (set (attr "length")
2545 (if_then_else (eq_attr "is_thumb" "yes")
2546 (const_int 12)
2547 (const_int 8)))
2548 (set_attr "type" "multiple")]
2549 )
2550
2551 (define_insn_and_split "*ne_zeroextractsi_shifted"
2552 [(set (match_operand:SI 0 "s_register_operand" "=r")
2553 (ne:SI (zero_extract:SI
2554 (match_operand:SI 1 "s_register_operand" "r")
2555 (match_operand:SI 2 "const_int_operand" "n")
2556 (const_int 0))
2557 (const_int 0)))
2558 (clobber (reg:CC CC_REGNUM))]
2559 "TARGET_ARM"
2560 "#"
2561 "TARGET_ARM"
2562 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2563 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2564 (const_int 0)))
2565 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2566 (set (match_dup 0)
2567 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2568 (match_dup 0) (const_int 1)))]
2569 "
2570 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2571 "
2572 [(set_attr "conds" "clob")
2573 (set_attr "length" "8")
2574 (set_attr "type" "multiple")]
2575 )
2576
2577 (define_insn_and_split "*ite_ne_zeroextractsi"
2578 [(set (match_operand:SI 0 "s_register_operand" "=r")
2579 (if_then_else:SI (ne (zero_extract:SI
2580 (match_operand:SI 1 "s_register_operand" "r")
2581 (match_operand:SI 2 "const_int_operand" "n")
2582 (match_operand:SI 3 "const_int_operand" "n"))
2583 (const_int 0))
2584 (match_operand:SI 4 "arm_not_operand" "rIK")
2585 (const_int 0)))
2586 (clobber (reg:CC CC_REGNUM))]
2587 "TARGET_ARM
2588 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2589 && INTVAL (operands[2]) > 0
2590 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2591 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2592 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2593 "#"
2594 "TARGET_ARM
2595 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2596 && INTVAL (operands[2]) > 0
2597 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2598 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2599 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2600 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2601 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2602 (const_int 0)))
2603 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2604 (set (match_dup 0)
2605 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2606 (match_dup 0) (match_dup 4)))]
2607 "
2608 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2609 << INTVAL (operands[3]));
2610 "
2611 [(set_attr "conds" "clob")
2612 (set_attr "length" "8")
2613 (set_attr "type" "multiple")]
2614 )
2615
2616 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2617 [(set (match_operand:SI 0 "s_register_operand" "=r")
2618 (if_then_else:SI (ne (zero_extract:SI
2619 (match_operand:SI 1 "s_register_operand" "r")
2620 (match_operand:SI 2 "const_int_operand" "n")
2621 (const_int 0))
2622 (const_int 0))
2623 (match_operand:SI 3 "arm_not_operand" "rIK")
2624 (const_int 0)))
2625 (clobber (reg:CC CC_REGNUM))]
2626 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2627 "#"
2628 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2629 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2630 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2631 (const_int 0)))
2632 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2633 (set (match_dup 0)
2634 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2635 (match_dup 0) (match_dup 3)))]
2636 "
2637 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2638 "
2639 [(set_attr "conds" "clob")
2640 (set_attr "length" "8")
2641 (set_attr "type" "multiple")]
2642 )
2643
2644 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2645 (define_split
2646 [(set (match_operand:SI 0 "s_register_operand" "")
2647 (match_operator:SI 1 "shiftable_operator"
2648 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2649 (match_operand:SI 3 "const_int_operand" "")
2650 (match_operand:SI 4 "const_int_operand" ""))
2651 (match_operand:SI 5 "s_register_operand" "")]))
2652 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2653 "TARGET_ARM"
2654 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2655 (set (match_dup 0)
2656 (match_op_dup 1
2657 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2658 (match_dup 5)]))]
2659 "{
2660 HOST_WIDE_INT temp = INTVAL (operands[3]);
2661
2662 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2663 operands[4] = GEN_INT (32 - temp);
2664 }"
2665 )
2666
2667 (define_split
2668 [(set (match_operand:SI 0 "s_register_operand" "")
2669 (match_operator:SI 1 "shiftable_operator"
2670 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2671 (match_operand:SI 3 "const_int_operand" "")
2672 (match_operand:SI 4 "const_int_operand" ""))
2673 (match_operand:SI 5 "s_register_operand" "")]))
2674 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2675 "TARGET_ARM"
2676 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2677 (set (match_dup 0)
2678 (match_op_dup 1
2679 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2680 (match_dup 5)]))]
2681 "{
2682 HOST_WIDE_INT temp = INTVAL (operands[3]);
2683
2684 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2685 operands[4] = GEN_INT (32 - temp);
2686 }"
2687 )
2688
2689 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2690 ;;; represented by the bitfield, then this will produce incorrect results.
2691 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2692 ;;; which have a real bit-field insert instruction, the truncation happens
2693 ;;; in the bit-field insert instruction itself. Since arm does not have a
2694 ;;; bit-field insert instruction, we would have to emit code here to truncate
2695 ;;; the value before we insert. This loses some of the advantage of having
2696 ;;; this insv pattern, so this pattern needs to be reevalutated.
2697
2698 (define_expand "insv"
2699 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2700 (match_operand 1 "general_operand" "")
2701 (match_operand 2 "general_operand" ""))
2702 (match_operand 3 "reg_or_int_operand" ""))]
2703 "TARGET_ARM || arm_arch_thumb2"
2704 "
2705 {
2706 int start_bit = INTVAL (operands[2]);
2707 int width = INTVAL (operands[1]);
2708 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2709 rtx target, subtarget;
2710
2711 if (arm_arch_thumb2)
2712 {
2713 if (unaligned_access && MEM_P (operands[0])
2714 && s_register_operand (operands[3], GET_MODE (operands[3]))
2715 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2716 {
2717 rtx base_addr;
2718
2719 if (BYTES_BIG_ENDIAN)
2720 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2721 - start_bit;
2722
2723 if (width == 32)
2724 {
2725 base_addr = adjust_address (operands[0], SImode,
2726 start_bit / BITS_PER_UNIT);
2727 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2728 }
2729 else
2730 {
2731 rtx tmp = gen_reg_rtx (HImode);
2732
2733 base_addr = adjust_address (operands[0], HImode,
2734 start_bit / BITS_PER_UNIT);
2735 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2736 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2737 }
2738 DONE;
2739 }
2740 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2741 {
2742 bool use_bfi = TRUE;
2743
2744 if (CONST_INT_P (operands[3]))
2745 {
2746 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2747
2748 if (val == 0)
2749 {
2750 emit_insn (gen_insv_zero (operands[0], operands[1],
2751 operands[2]));
2752 DONE;
2753 }
2754
2755 /* See if the set can be done with a single orr instruction. */
2756 if (val == mask && const_ok_for_arm (val << start_bit))
2757 use_bfi = FALSE;
2758 }
2759
2760 if (use_bfi)
2761 {
2762 if (!REG_P (operands[3]))
2763 operands[3] = force_reg (SImode, operands[3]);
2764
2765 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2766 operands[3]));
2767 DONE;
2768 }
2769 }
2770 else
2771 FAIL;
2772 }
2773
2774 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2775 FAIL;
2776
2777 target = copy_rtx (operands[0]);
2778 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2779 subreg as the final target. */
2780 if (GET_CODE (target) == SUBREG)
2781 {
2782 subtarget = gen_reg_rtx (SImode);
2783 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2784 < GET_MODE_SIZE (SImode))
2785 target = SUBREG_REG (target);
2786 }
2787 else
2788 subtarget = target;
2789
2790 if (CONST_INT_P (operands[3]))
2791 {
2792 /* Since we are inserting a known constant, we may be able to
2793 reduce the number of bits that we have to clear so that
2794 the mask becomes simple. */
2795 /* ??? This code does not check to see if the new mask is actually
2796 simpler. It may not be. */
2797 rtx op1 = gen_reg_rtx (SImode);
2798 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2799 start of this pattern. */
2800 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2801 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2802
2803 emit_insn (gen_andsi3 (op1, operands[0],
2804 gen_int_mode (~mask2, SImode)));
2805 emit_insn (gen_iorsi3 (subtarget, op1,
2806 gen_int_mode (op3_value << start_bit, SImode)));
2807 }
2808 else if (start_bit == 0
2809 && !(const_ok_for_arm (mask)
2810 || const_ok_for_arm (~mask)))
2811 {
2812 /* A Trick, since we are setting the bottom bits in the word,
2813 we can shift operand[3] up, operand[0] down, OR them together
2814 and rotate the result back again. This takes 3 insns, and
2815 the third might be mergeable into another op. */
2816 /* The shift up copes with the possibility that operand[3] is
2817 wider than the bitfield. */
2818 rtx op0 = gen_reg_rtx (SImode);
2819 rtx op1 = gen_reg_rtx (SImode);
2820
2821 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2822 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2823 emit_insn (gen_iorsi3 (op1, op1, op0));
2824 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2825 }
2826 else if ((width + start_bit == 32)
2827 && !(const_ok_for_arm (mask)
2828 || const_ok_for_arm (~mask)))
2829 {
2830 /* Similar trick, but slightly less efficient. */
2831
2832 rtx op0 = gen_reg_rtx (SImode);
2833 rtx op1 = gen_reg_rtx (SImode);
2834
2835 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2836 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2837 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2838 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2839 }
2840 else
2841 {
2842 rtx op0 = gen_int_mode (mask, SImode);
2843 rtx op1 = gen_reg_rtx (SImode);
2844 rtx op2 = gen_reg_rtx (SImode);
2845
2846 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2847 {
2848 rtx tmp = gen_reg_rtx (SImode);
2849
2850 emit_insn (gen_movsi (tmp, op0));
2851 op0 = tmp;
2852 }
2853
2854 /* Mask out any bits in operand[3] that are not needed. */
2855 emit_insn (gen_andsi3 (op1, operands[3], op0));
2856
2857 if (CONST_INT_P (op0)
2858 && (const_ok_for_arm (mask << start_bit)
2859 || const_ok_for_arm (~(mask << start_bit))))
2860 {
2861 op0 = gen_int_mode (~(mask << start_bit), SImode);
2862 emit_insn (gen_andsi3 (op2, operands[0], op0));
2863 }
2864 else
2865 {
2866 if (CONST_INT_P (op0))
2867 {
2868 rtx tmp = gen_reg_rtx (SImode);
2869
2870 emit_insn (gen_movsi (tmp, op0));
2871 op0 = tmp;
2872 }
2873
2874 if (start_bit != 0)
2875 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2876
2877 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2878 }
2879
2880 if (start_bit != 0)
2881 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2882
2883 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2884 }
2885
2886 if (subtarget != target)
2887 {
2888 /* If TARGET is still a SUBREG, then it must be wider than a word,
2889 so we must be careful only to set the subword we were asked to. */
2890 if (GET_CODE (target) == SUBREG)
2891 emit_move_insn (target, subtarget);
2892 else
2893 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2894 }
2895
2896 DONE;
2897 }"
2898 )
2899
2900 (define_insn "insv_zero"
2901 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2902 (match_operand:SI 1 "const_int_M_operand" "M")
2903 (match_operand:SI 2 "const_int_M_operand" "M"))
2904 (const_int 0))]
2905 "arm_arch_thumb2"
2906 "bfc%?\t%0, %2, %1"
2907 [(set_attr "length" "4")
2908 (set_attr "predicable" "yes")
2909 (set_attr "predicable_short_it" "no")
2910 (set_attr "type" "bfm")]
2911 )
2912
2913 (define_insn "insv_t2"
2914 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2915 (match_operand:SI 1 "const_int_M_operand" "M")
2916 (match_operand:SI 2 "const_int_M_operand" "M"))
2917 (match_operand:SI 3 "s_register_operand" "r"))]
2918 "arm_arch_thumb2"
2919 "bfi%?\t%0, %3, %2, %1"
2920 [(set_attr "length" "4")
2921 (set_attr "predicable" "yes")
2922 (set_attr "predicable_short_it" "no")
2923 (set_attr "type" "bfm")]
2924 )
2925
2926 ; constants for op 2 will never be given to these patterns.
2927 (define_insn_and_split "*anddi_notdi_di"
2928 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2929 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2930 (match_operand:DI 2 "s_register_operand" "r,0")))]
2931 "TARGET_32BIT"
2932 "#"
2933 "TARGET_32BIT && reload_completed
2934 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2935 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2936 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2937 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2938 "
2939 {
2940 operands[3] = gen_highpart (SImode, operands[0]);
2941 operands[0] = gen_lowpart (SImode, operands[0]);
2942 operands[4] = gen_highpart (SImode, operands[1]);
2943 operands[1] = gen_lowpart (SImode, operands[1]);
2944 operands[5] = gen_highpart (SImode, operands[2]);
2945 operands[2] = gen_lowpart (SImode, operands[2]);
2946 }"
2947 [(set_attr "length" "8")
2948 (set_attr "predicable" "yes")
2949 (set_attr "type" "multiple")]
2950 )
2951
2952 (define_insn_and_split "*anddi_notzesidi_di"
2953 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2954 (and:DI (not:DI (zero_extend:DI
2955 (match_operand:SI 2 "s_register_operand" "r,r")))
2956 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2957 "TARGET_32BIT"
2958 "@
2959 bic%?\\t%Q0, %Q1, %2
2960 #"
2961 ; (not (zero_extend ...)) allows us to just copy the high word from
2962 ; operand1 to operand0.
2963 "TARGET_32BIT
2964 && reload_completed
2965 && operands[0] != operands[1]"
2966 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2967 (set (match_dup 3) (match_dup 4))]
2968 "
2969 {
2970 operands[3] = gen_highpart (SImode, operands[0]);
2971 operands[0] = gen_lowpart (SImode, operands[0]);
2972 operands[4] = gen_highpart (SImode, operands[1]);
2973 operands[1] = gen_lowpart (SImode, operands[1]);
2974 }"
2975 [(set_attr "length" "4,8")
2976 (set_attr "predicable" "yes")
2977 (set_attr "predicable_short_it" "no")
2978 (set_attr "type" "multiple")]
2979 )
2980
2981 (define_insn_and_split "*anddi_notdi_zesidi"
2982 [(set (match_operand:DI 0 "s_register_operand" "=r")
2983 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2984 (zero_extend:DI
2985 (match_operand:SI 1 "s_register_operand" "r"))))]
2986 "TARGET_32BIT"
2987 "#"
2988 "TARGET_32BIT && reload_completed"
2989 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2990 (set (match_dup 3) (const_int 0))]
2991 "
2992 {
2993 operands[3] = gen_highpart (SImode, operands[0]);
2994 operands[0] = gen_lowpart (SImode, operands[0]);
2995 operands[2] = gen_lowpart (SImode, operands[2]);
2996 }"
2997 [(set_attr "length" "8")
2998 (set_attr "predicable" "yes")
2999 (set_attr "predicable_short_it" "no")
3000 (set_attr "type" "multiple")]
3001 )
3002
3003 (define_insn_and_split "*anddi_notsesidi_di"
3004 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3005 (and:DI (not:DI (sign_extend:DI
3006 (match_operand:SI 2 "s_register_operand" "r,r")))
3007 (match_operand:DI 1 "s_register_operand" "0,r")))]
3008 "TARGET_32BIT"
3009 "#"
3010 "TARGET_32BIT && reload_completed"
3011 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3012 (set (match_dup 3) (and:SI (not:SI
3013 (ashiftrt:SI (match_dup 2) (const_int 31)))
3014 (match_dup 4)))]
3015 "
3016 {
3017 operands[3] = gen_highpart (SImode, operands[0]);
3018 operands[0] = gen_lowpart (SImode, operands[0]);
3019 operands[4] = gen_highpart (SImode, operands[1]);
3020 operands[1] = gen_lowpart (SImode, operands[1]);
3021 }"
3022 [(set_attr "length" "8")
3023 (set_attr "predicable" "yes")
3024 (set_attr "predicable_short_it" "no")
3025 (set_attr "type" "multiple")]
3026 )
3027
3028 (define_insn "andsi_notsi_si"
3029 [(set (match_operand:SI 0 "s_register_operand" "=r")
3030 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3031 (match_operand:SI 1 "s_register_operand" "r")))]
3032 "TARGET_32BIT"
3033 "bic%?\\t%0, %1, %2"
3034 [(set_attr "predicable" "yes")
3035 (set_attr "predicable_short_it" "no")
3036 (set_attr "type" "logic_reg")]
3037 )
3038
3039 (define_insn "andsi_not_shiftsi_si"
3040 [(set (match_operand:SI 0 "s_register_operand" "=r")
3041 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3042 [(match_operand:SI 2 "s_register_operand" "r")
3043 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3044 (match_operand:SI 1 "s_register_operand" "r")))]
3045 "TARGET_ARM"
3046 "bic%?\\t%0, %1, %2%S4"
3047 [(set_attr "predicable" "yes")
3048 (set_attr "shift" "2")
3049 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3050 (const_string "logic_shift_imm")
3051 (const_string "logic_shift_reg")))]
3052 )
3053
3054 ;; Shifted bics pattern used to set up CC status register and not reusing
3055 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3056 ;; does not support shift by register.
3057 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3058 [(set (reg:CC_NOOV CC_REGNUM)
3059 (compare:CC_NOOV
3060 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3061 [(match_operand:SI 1 "s_register_operand" "r")
3062 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3063 (match_operand:SI 3 "s_register_operand" "r"))
3064 (const_int 0)))
3065 (clobber (match_scratch:SI 4 "=r"))]
3066 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3067 "bics%?\\t%4, %3, %1%S0"
3068 [(set_attr "predicable" "yes")
3069 (set_attr "predicable_short_it" "no")
3070 (set_attr "conds" "set")
3071 (set_attr "shift" "1")
3072 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3073 (const_string "logic_shift_imm")
3074 (const_string "logic_shift_reg")))]
3075 )
3076
3077 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3078 ;; getting reused later.
3079 (define_insn "andsi_not_shiftsi_si_scc"
3080 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3081 (compare:CC_NOOV
3082 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3083 [(match_operand:SI 1 "s_register_operand" "r")
3084 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3085 (match_operand:SI 3 "s_register_operand" "r"))
3086 (const_int 0)))
3087 (set (match_operand:SI 4 "s_register_operand" "=r")
3088 (and:SI (not:SI (match_op_dup 0
3089 [(match_dup 1)
3090 (match_dup 2)]))
3091 (match_dup 3)))])]
3092 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3093 "bics%?\\t%4, %3, %1%S0"
3094 [(set_attr "predicable" "yes")
3095 (set_attr "predicable_short_it" "no")
3096 (set_attr "conds" "set")
3097 (set_attr "shift" "1")
3098 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3099 (const_string "logic_shift_imm")
3100 (const_string "logic_shift_reg")))]
3101 )
3102
3103 (define_insn "*andsi_notsi_si_compare0"
3104 [(set (reg:CC_NOOV CC_REGNUM)
3105 (compare:CC_NOOV
3106 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3107 (match_operand:SI 1 "s_register_operand" "r"))
3108 (const_int 0)))
3109 (set (match_operand:SI 0 "s_register_operand" "=r")
3110 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3111 "TARGET_32BIT"
3112 "bics\\t%0, %1, %2"
3113 [(set_attr "conds" "set")
3114 (set_attr "type" "logics_shift_reg")]
3115 )
3116
3117 (define_insn "*andsi_notsi_si_compare0_scratch"
3118 [(set (reg:CC_NOOV CC_REGNUM)
3119 (compare:CC_NOOV
3120 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3121 (match_operand:SI 1 "s_register_operand" "r"))
3122 (const_int 0)))
3123 (clobber (match_scratch:SI 0 "=r"))]
3124 "TARGET_32BIT"
3125 "bics\\t%0, %1, %2"
3126 [(set_attr "conds" "set")
3127 (set_attr "type" "logics_shift_reg")]
3128 )
3129
3130 (define_expand "iordi3"
3131 [(set (match_operand:DI 0 "s_register_operand" "")
3132 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3133 (match_operand:DI 2 "neon_logic_op2" "")))]
3134 "TARGET_32BIT"
3135 ""
3136 )
3137
3138 (define_insn_and_split "*iordi3_insn"
3139 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3140 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3141 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3142 "TARGET_32BIT && !TARGET_IWMMXT"
3143 {
3144 switch (which_alternative)
3145 {
3146 case 0: /* fall through */
3147 case 6: return "vorr\t%P0, %P1, %P2";
3148 case 1: /* fall through */
3149 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3150 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3151 case 2:
3152 case 3:
3153 case 4:
3154 case 5:
3155 return "#";
3156 default: gcc_unreachable ();
3157 }
3158 }
3159 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3160 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3161 [(set (match_dup 3) (match_dup 4))
3162 (set (match_dup 5) (match_dup 6))]
3163 "
3164 {
3165 operands[3] = gen_lowpart (SImode, operands[0]);
3166 operands[5] = gen_highpart (SImode, operands[0]);
3167
3168 operands[4] = simplify_gen_binary (IOR, SImode,
3169 gen_lowpart (SImode, operands[1]),
3170 gen_lowpart (SImode, operands[2]));
3171 operands[6] = simplify_gen_binary (IOR, SImode,
3172 gen_highpart (SImode, operands[1]),
3173 gen_highpart_mode (SImode, DImode, operands[2]));
3174
3175 }"
3176 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3177 multiple,neon_logic,neon_logic")
3178 (set_attr "length" "*,*,8,8,8,8,*,*")
3179 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3180 )
3181
3182 (define_insn "*iordi_zesidi_di"
3183 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3184 (ior:DI (zero_extend:DI
3185 (match_operand:SI 2 "s_register_operand" "r,r"))
3186 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3187 "TARGET_32BIT"
3188 "@
3189 orr%?\\t%Q0, %Q1, %2
3190 #"
3191 [(set_attr "length" "4,8")
3192 (set_attr "predicable" "yes")
3193 (set_attr "predicable_short_it" "no")
3194 (set_attr "type" "logic_reg,multiple")]
3195 )
3196
3197 (define_insn "*iordi_sesidi_di"
3198 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3199 (ior:DI (sign_extend:DI
3200 (match_operand:SI 2 "s_register_operand" "r,r"))
3201 (match_operand:DI 1 "s_register_operand" "0,r")))]
3202 "TARGET_32BIT"
3203 "#"
3204 [(set_attr "length" "8")
3205 (set_attr "predicable" "yes")
3206 (set_attr "type" "multiple")]
3207 )
3208
3209 (define_expand "iorsi3"
3210 [(set (match_operand:SI 0 "s_register_operand" "")
3211 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3212 (match_operand:SI 2 "reg_or_int_operand" "")))]
3213 "TARGET_EITHER"
3214 "
3215 if (CONST_INT_P (operands[2]))
3216 {
3217 if (TARGET_32BIT)
3218 {
3219 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3220 operands[2] = force_reg (SImode, operands[2]);
3221 else
3222 {
3223 arm_split_constant (IOR, SImode, NULL_RTX,
3224 INTVAL (operands[2]), operands[0],
3225 operands[1],
3226 optimize && can_create_pseudo_p ());
3227 DONE;
3228 }
3229 }
3230 else /* TARGET_THUMB1 */
3231 {
3232 rtx tmp = force_reg (SImode, operands[2]);
3233 if (rtx_equal_p (operands[0], operands[1]))
3234 operands[2] = tmp;
3235 else
3236 {
3237 operands[2] = operands[1];
3238 operands[1] = tmp;
3239 }
3240 }
3241 }
3242 "
3243 )
3244
3245 (define_insn_and_split "*iorsi3_insn"
3246 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3247 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3248 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3249 "TARGET_32BIT"
3250 "@
3251 orr%?\\t%0, %1, %2
3252 orr%?\\t%0, %1, %2
3253 orn%?\\t%0, %1, #%B2
3254 orr%?\\t%0, %1, %2
3255 #"
3256 "TARGET_32BIT
3257 && CONST_INT_P (operands[2])
3258 && !(const_ok_for_arm (INTVAL (operands[2]))
3259 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3260 [(clobber (const_int 0))]
3261 {
3262 arm_split_constant (IOR, SImode, curr_insn,
3263 INTVAL (operands[2]), operands[0], operands[1], 0);
3264 DONE;
3265 }
3266 [(set_attr "length" "4,4,4,4,16")
3267 (set_attr "arch" "32,t2,t2,32,32")
3268 (set_attr "predicable" "yes")
3269 (set_attr "predicable_short_it" "no,yes,no,no,no")
3270 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3271 )
3272
3273 (define_peephole2
3274 [(match_scratch:SI 3 "r")
3275 (set (match_operand:SI 0 "arm_general_register_operand" "")
3276 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3277 (match_operand:SI 2 "const_int_operand" "")))]
3278 "TARGET_ARM
3279 && !const_ok_for_arm (INTVAL (operands[2]))
3280 && const_ok_for_arm (~INTVAL (operands[2]))"
3281 [(set (match_dup 3) (match_dup 2))
3282 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3283 ""
3284 )
3285
3286 (define_insn "*iorsi3_compare0"
3287 [(set (reg:CC_NOOV CC_REGNUM)
3288 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3289 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3290 (const_int 0)))
3291 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3292 (ior:SI (match_dup 1) (match_dup 2)))]
3293 "TARGET_32BIT"
3294 "orrs%?\\t%0, %1, %2"
3295 [(set_attr "conds" "set")
3296 (set_attr "type" "logics_imm,logics_reg")]
3297 )
3298
3299 (define_insn "*iorsi3_compare0_scratch"
3300 [(set (reg:CC_NOOV CC_REGNUM)
3301 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3302 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3303 (const_int 0)))
3304 (clobber (match_scratch:SI 0 "=r,r"))]
3305 "TARGET_32BIT"
3306 "orrs%?\\t%0, %1, %2"
3307 [(set_attr "conds" "set")
3308 (set_attr "type" "logics_imm,logics_reg")]
3309 )
3310
3311 (define_expand "xordi3"
3312 [(set (match_operand:DI 0 "s_register_operand" "")
3313 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3314 (match_operand:DI 2 "arm_xordi_operand" "")))]
3315 "TARGET_32BIT"
3316 ""
3317 )
3318
3319 (define_insn_and_split "*xordi3_insn"
3320 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3321 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3322 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3323 "TARGET_32BIT && !TARGET_IWMMXT"
3324 {
3325 switch (which_alternative)
3326 {
3327 case 1:
3328 case 2:
3329 case 3:
3330 case 4: /* fall through */
3331 return "#";
3332 case 0: /* fall through */
3333 case 5: return "veor\t%P0, %P1, %P2";
3334 default: gcc_unreachable ();
3335 }
3336 }
3337 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3338 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3339 [(set (match_dup 3) (match_dup 4))
3340 (set (match_dup 5) (match_dup 6))]
3341 "
3342 {
3343 operands[3] = gen_lowpart (SImode, operands[0]);
3344 operands[5] = gen_highpart (SImode, operands[0]);
3345
3346 operands[4] = simplify_gen_binary (XOR, SImode,
3347 gen_lowpart (SImode, operands[1]),
3348 gen_lowpart (SImode, operands[2]));
3349 operands[6] = simplify_gen_binary (XOR, SImode,
3350 gen_highpart (SImode, operands[1]),
3351 gen_highpart_mode (SImode, DImode, operands[2]));
3352
3353 }"
3354 [(set_attr "length" "*,8,8,8,8,*")
3355 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3356 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3357 )
3358
3359 (define_insn "*xordi_zesidi_di"
3360 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3361 (xor:DI (zero_extend:DI
3362 (match_operand:SI 2 "s_register_operand" "r,r"))
3363 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3364 "TARGET_32BIT"
3365 "@
3366 eor%?\\t%Q0, %Q1, %2
3367 #"
3368 [(set_attr "length" "4,8")
3369 (set_attr "predicable" "yes")
3370 (set_attr "predicable_short_it" "no")
3371 (set_attr "type" "logic_reg")]
3372 )
3373
3374 (define_insn "*xordi_sesidi_di"
3375 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3376 (xor:DI (sign_extend:DI
3377 (match_operand:SI 2 "s_register_operand" "r,r"))
3378 (match_operand:DI 1 "s_register_operand" "0,r")))]
3379 "TARGET_32BIT"
3380 "#"
3381 [(set_attr "length" "8")
3382 (set_attr "predicable" "yes")
3383 (set_attr "type" "multiple")]
3384 )
3385
3386 (define_expand "xorsi3"
3387 [(set (match_operand:SI 0 "s_register_operand" "")
3388 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3389 (match_operand:SI 2 "reg_or_int_operand" "")))]
3390 "TARGET_EITHER"
3391 "if (CONST_INT_P (operands[2]))
3392 {
3393 if (TARGET_32BIT)
3394 {
3395 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3396 operands[2] = force_reg (SImode, operands[2]);
3397 else
3398 {
3399 arm_split_constant (XOR, SImode, NULL_RTX,
3400 INTVAL (operands[2]), operands[0],
3401 operands[1],
3402 optimize && can_create_pseudo_p ());
3403 DONE;
3404 }
3405 }
3406 else /* TARGET_THUMB1 */
3407 {
3408 rtx tmp = force_reg (SImode, operands[2]);
3409 if (rtx_equal_p (operands[0], operands[1]))
3410 operands[2] = tmp;
3411 else
3412 {
3413 operands[2] = operands[1];
3414 operands[1] = tmp;
3415 }
3416 }
3417 }"
3418 )
3419
3420 (define_insn_and_split "*arm_xorsi3"
3421 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3422 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3423 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3424 "TARGET_32BIT"
3425 "@
3426 eor%?\\t%0, %1, %2
3427 eor%?\\t%0, %1, %2
3428 eor%?\\t%0, %1, %2
3429 #"
3430 "TARGET_32BIT
3431 && CONST_INT_P (operands[2])
3432 && !const_ok_for_arm (INTVAL (operands[2]))"
3433 [(clobber (const_int 0))]
3434 {
3435 arm_split_constant (XOR, SImode, curr_insn,
3436 INTVAL (operands[2]), operands[0], operands[1], 0);
3437 DONE;
3438 }
3439 [(set_attr "length" "4,4,4,16")
3440 (set_attr "predicable" "yes")
3441 (set_attr "predicable_short_it" "no,yes,no,no")
3442 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3443 )
3444
3445 (define_insn "*xorsi3_compare0"
3446 [(set (reg:CC_NOOV CC_REGNUM)
3447 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3448 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3449 (const_int 0)))
3450 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3451 (xor:SI (match_dup 1) (match_dup 2)))]
3452 "TARGET_32BIT"
3453 "eors%?\\t%0, %1, %2"
3454 [(set_attr "conds" "set")
3455 (set_attr "type" "logics_imm,logics_reg")]
3456 )
3457
3458 (define_insn "*xorsi3_compare0_scratch"
3459 [(set (reg:CC_NOOV CC_REGNUM)
3460 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3461 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3462 (const_int 0)))]
3463 "TARGET_32BIT"
3464 "teq%?\\t%0, %1"
3465 [(set_attr "conds" "set")
3466 (set_attr "type" "logics_imm,logics_reg")]
3467 )
3468
3469 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3470 ; (NOT D) we can sometimes merge the final NOT into one of the following
3471 ; insns.
3472
3473 (define_split
3474 [(set (match_operand:SI 0 "s_register_operand" "")
3475 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3476 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3477 (match_operand:SI 3 "arm_rhs_operand" "")))
3478 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3479 "TARGET_32BIT"
3480 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3481 (not:SI (match_dup 3))))
3482 (set (match_dup 0) (not:SI (match_dup 4)))]
3483 ""
3484 )
3485
3486 (define_insn_and_split "*andsi_iorsi3_notsi"
3487 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3488 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3489 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3490 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3491 "TARGET_32BIT"
3492 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3493 "&& reload_completed"
3494 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3495 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3496 {
3497 /* If operands[3] is a constant make sure to fold the NOT into it
3498 to avoid creating a NOT of a CONST_INT. */
3499 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3500 if (CONST_INT_P (not_rtx))
3501 {
3502 operands[4] = operands[0];
3503 operands[5] = not_rtx;
3504 }
3505 else
3506 {
3507 operands[5] = operands[0];
3508 operands[4] = not_rtx;
3509 }
3510 }
3511 [(set_attr "length" "8")
3512 (set_attr "ce_count" "2")
3513 (set_attr "predicable" "yes")
3514 (set_attr "predicable_short_it" "no")
3515 (set_attr "type" "multiple")]
3516 )
3517
3518 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3519 ; insns are available?
3520 (define_split
3521 [(set (match_operand:SI 0 "s_register_operand" "")
3522 (match_operator:SI 1 "logical_binary_operator"
3523 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3524 (match_operand:SI 3 "const_int_operand" "")
3525 (match_operand:SI 4 "const_int_operand" ""))
3526 (match_operator:SI 9 "logical_binary_operator"
3527 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3528 (match_operand:SI 6 "const_int_operand" ""))
3529 (match_operand:SI 7 "s_register_operand" "")])]))
3530 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3531 "TARGET_32BIT
3532 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3533 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3534 [(set (match_dup 8)
3535 (match_op_dup 1
3536 [(ashift:SI (match_dup 2) (match_dup 4))
3537 (match_dup 5)]))
3538 (set (match_dup 0)
3539 (match_op_dup 1
3540 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3541 (match_dup 7)]))]
3542 "
3543 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3544 ")
3545
3546 (define_split
3547 [(set (match_operand:SI 0 "s_register_operand" "")
3548 (match_operator:SI 1 "logical_binary_operator"
3549 [(match_operator:SI 9 "logical_binary_operator"
3550 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3551 (match_operand:SI 6 "const_int_operand" ""))
3552 (match_operand:SI 7 "s_register_operand" "")])
3553 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3554 (match_operand:SI 3 "const_int_operand" "")
3555 (match_operand:SI 4 "const_int_operand" ""))]))
3556 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3557 "TARGET_32BIT
3558 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3559 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3560 [(set (match_dup 8)
3561 (match_op_dup 1
3562 [(ashift:SI (match_dup 2) (match_dup 4))
3563 (match_dup 5)]))
3564 (set (match_dup 0)
3565 (match_op_dup 1
3566 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3567 (match_dup 7)]))]
3568 "
3569 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3570 ")
3571
3572 (define_split
3573 [(set (match_operand:SI 0 "s_register_operand" "")
3574 (match_operator:SI 1 "logical_binary_operator"
3575 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3576 (match_operand:SI 3 "const_int_operand" "")
3577 (match_operand:SI 4 "const_int_operand" ""))
3578 (match_operator:SI 9 "logical_binary_operator"
3579 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3580 (match_operand:SI 6 "const_int_operand" ""))
3581 (match_operand:SI 7 "s_register_operand" "")])]))
3582 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3583 "TARGET_32BIT
3584 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3585 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3586 [(set (match_dup 8)
3587 (match_op_dup 1
3588 [(ashift:SI (match_dup 2) (match_dup 4))
3589 (match_dup 5)]))
3590 (set (match_dup 0)
3591 (match_op_dup 1
3592 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3593 (match_dup 7)]))]
3594 "
3595 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3596 ")
3597
3598 (define_split
3599 [(set (match_operand:SI 0 "s_register_operand" "")
3600 (match_operator:SI 1 "logical_binary_operator"
3601 [(match_operator:SI 9 "logical_binary_operator"
3602 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3603 (match_operand:SI 6 "const_int_operand" ""))
3604 (match_operand:SI 7 "s_register_operand" "")])
3605 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3606 (match_operand:SI 3 "const_int_operand" "")
3607 (match_operand:SI 4 "const_int_operand" ""))]))
3608 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3609 "TARGET_32BIT
3610 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3611 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3612 [(set (match_dup 8)
3613 (match_op_dup 1
3614 [(ashift:SI (match_dup 2) (match_dup 4))
3615 (match_dup 5)]))
3616 (set (match_dup 0)
3617 (match_op_dup 1
3618 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3619 (match_dup 7)]))]
3620 "
3621 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3622 ")
3623 \f
3624
3625 ;; Minimum and maximum insns
3626
3627 (define_expand "smaxsi3"
3628 [(parallel [
3629 (set (match_operand:SI 0 "s_register_operand" "")
3630 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3631 (match_operand:SI 2 "arm_rhs_operand" "")))
3632 (clobber (reg:CC CC_REGNUM))])]
3633 "TARGET_32BIT"
3634 "
3635 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3636 {
3637 /* No need for a clobber of the condition code register here. */
3638 emit_insn (gen_rtx_SET (operands[0],
3639 gen_rtx_SMAX (SImode, operands[1],
3640 operands[2])));
3641 DONE;
3642 }
3643 ")
3644
3645 (define_insn "*smax_0"
3646 [(set (match_operand:SI 0 "s_register_operand" "=r")
3647 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3648 (const_int 0)))]
3649 "TARGET_32BIT"
3650 "bic%?\\t%0, %1, %1, asr #31"
3651 [(set_attr "predicable" "yes")
3652 (set_attr "predicable_short_it" "no")
3653 (set_attr "type" "logic_shift_reg")]
3654 )
3655
3656 (define_insn "*smax_m1"
3657 [(set (match_operand:SI 0 "s_register_operand" "=r")
3658 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3659 (const_int -1)))]
3660 "TARGET_32BIT"
3661 "orr%?\\t%0, %1, %1, asr #31"
3662 [(set_attr "predicable" "yes")
3663 (set_attr "predicable_short_it" "no")
3664 (set_attr "type" "logic_shift_reg")]
3665 )
3666
3667 (define_insn_and_split "*arm_smax_insn"
3668 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3669 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3670 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3671 (clobber (reg:CC CC_REGNUM))]
3672 "TARGET_ARM"
3673 "#"
3674 ; cmp\\t%1, %2\;movlt\\t%0, %2
3675 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3676 "TARGET_ARM"
3677 [(set (reg:CC CC_REGNUM)
3678 (compare:CC (match_dup 1) (match_dup 2)))
3679 (set (match_dup 0)
3680 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3681 (match_dup 1)
3682 (match_dup 2)))]
3683 ""
3684 [(set_attr "conds" "clob")
3685 (set_attr "length" "8,12")
3686 (set_attr "type" "multiple")]
3687 )
3688
3689 (define_expand "sminsi3"
3690 [(parallel [
3691 (set (match_operand:SI 0 "s_register_operand" "")
3692 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3693 (match_operand:SI 2 "arm_rhs_operand" "")))
3694 (clobber (reg:CC CC_REGNUM))])]
3695 "TARGET_32BIT"
3696 "
3697 if (operands[2] == const0_rtx)
3698 {
3699 /* No need for a clobber of the condition code register here. */
3700 emit_insn (gen_rtx_SET (operands[0],
3701 gen_rtx_SMIN (SImode, operands[1],
3702 operands[2])));
3703 DONE;
3704 }
3705 ")
3706
3707 (define_insn "*smin_0"
3708 [(set (match_operand:SI 0 "s_register_operand" "=r")
3709 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3710 (const_int 0)))]
3711 "TARGET_32BIT"
3712 "and%?\\t%0, %1, %1, asr #31"
3713 [(set_attr "predicable" "yes")
3714 (set_attr "predicable_short_it" "no")
3715 (set_attr "type" "logic_shift_reg")]
3716 )
3717
3718 (define_insn_and_split "*arm_smin_insn"
3719 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3720 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3721 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3722 (clobber (reg:CC CC_REGNUM))]
3723 "TARGET_ARM"
3724 "#"
3725 ; cmp\\t%1, %2\;movge\\t%0, %2
3726 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3727 "TARGET_ARM"
3728 [(set (reg:CC CC_REGNUM)
3729 (compare:CC (match_dup 1) (match_dup 2)))
3730 (set (match_dup 0)
3731 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3732 (match_dup 1)
3733 (match_dup 2)))]
3734 ""
3735 [(set_attr "conds" "clob")
3736 (set_attr "length" "8,12")
3737 (set_attr "type" "multiple,multiple")]
3738 )
3739
3740 (define_expand "umaxsi3"
3741 [(parallel [
3742 (set (match_operand:SI 0 "s_register_operand" "")
3743 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3744 (match_operand:SI 2 "arm_rhs_operand" "")))
3745 (clobber (reg:CC CC_REGNUM))])]
3746 "TARGET_32BIT"
3747 ""
3748 )
3749
3750 (define_insn_and_split "*arm_umaxsi3"
3751 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3752 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3753 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3754 (clobber (reg:CC CC_REGNUM))]
3755 "TARGET_ARM"
3756 "#"
3757 ; cmp\\t%1, %2\;movcc\\t%0, %2
3758 ; cmp\\t%1, %2\;movcs\\t%0, %1
3759 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3760 "TARGET_ARM"
3761 [(set (reg:CC CC_REGNUM)
3762 (compare:CC (match_dup 1) (match_dup 2)))
3763 (set (match_dup 0)
3764 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3765 (match_dup 1)
3766 (match_dup 2)))]
3767 ""
3768 [(set_attr "conds" "clob")
3769 (set_attr "length" "8,8,12")
3770 (set_attr "type" "store1")]
3771 )
3772
3773 (define_expand "uminsi3"
3774 [(parallel [
3775 (set (match_operand:SI 0 "s_register_operand" "")
3776 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3777 (match_operand:SI 2 "arm_rhs_operand" "")))
3778 (clobber (reg:CC CC_REGNUM))])]
3779 "TARGET_32BIT"
3780 ""
3781 )
3782
3783 (define_insn_and_split "*arm_uminsi3"
3784 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3785 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3786 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3787 (clobber (reg:CC CC_REGNUM))]
3788 "TARGET_ARM"
3789 "#"
3790 ; cmp\\t%1, %2\;movcs\\t%0, %2
3791 ; cmp\\t%1, %2\;movcc\\t%0, %1
3792 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3793 "TARGET_ARM"
3794 [(set (reg:CC CC_REGNUM)
3795 (compare:CC (match_dup 1) (match_dup 2)))
3796 (set (match_dup 0)
3797 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3798 (match_dup 1)
3799 (match_dup 2)))]
3800 ""
3801 [(set_attr "conds" "clob")
3802 (set_attr "length" "8,8,12")
3803 (set_attr "type" "store1")]
3804 )
3805
3806 (define_insn "*store_minmaxsi"
3807 [(set (match_operand:SI 0 "memory_operand" "=m")
3808 (match_operator:SI 3 "minmax_operator"
3809 [(match_operand:SI 1 "s_register_operand" "r")
3810 (match_operand:SI 2 "s_register_operand" "r")]))
3811 (clobber (reg:CC CC_REGNUM))]
3812 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3813 "*
3814 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3815 operands[1], operands[2]);
3816 output_asm_insn (\"cmp\\t%1, %2\", operands);
3817 if (TARGET_THUMB2)
3818 output_asm_insn (\"ite\t%d3\", operands);
3819 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3820 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3821 return \"\";
3822 "
3823 [(set_attr "conds" "clob")
3824 (set (attr "length")
3825 (if_then_else (eq_attr "is_thumb" "yes")
3826 (const_int 14)
3827 (const_int 12)))
3828 (set_attr "type" "store1")]
3829 )
3830
3831 ; Reject the frame pointer in operand[1], since reloading this after
3832 ; it has been eliminated can cause carnage.
3833 (define_insn "*minmax_arithsi"
3834 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3835 (match_operator:SI 4 "shiftable_operator"
3836 [(match_operator:SI 5 "minmax_operator"
3837 [(match_operand:SI 2 "s_register_operand" "r,r")
3838 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3839 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3840 (clobber (reg:CC CC_REGNUM))]
3841 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3842 "*
3843 {
3844 enum rtx_code code = GET_CODE (operands[4]);
3845 bool need_else;
3846
3847 if (which_alternative != 0 || operands[3] != const0_rtx
3848 || (code != PLUS && code != IOR && code != XOR))
3849 need_else = true;
3850 else
3851 need_else = false;
3852
3853 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3854 operands[2], operands[3]);
3855 output_asm_insn (\"cmp\\t%2, %3\", operands);
3856 if (TARGET_THUMB2)
3857 {
3858 if (need_else)
3859 output_asm_insn (\"ite\\t%d5\", operands);
3860 else
3861 output_asm_insn (\"it\\t%d5\", operands);
3862 }
3863 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3864 if (need_else)
3865 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3866 return \"\";
3867 }"
3868 [(set_attr "conds" "clob")
3869 (set (attr "length")
3870 (if_then_else (eq_attr "is_thumb" "yes")
3871 (const_int 14)
3872 (const_int 12)))
3873 (set_attr "type" "multiple")]
3874 )
3875
3876 ; Reject the frame pointer in operand[1], since reloading this after
3877 ; it has been eliminated can cause carnage.
3878 (define_insn_and_split "*minmax_arithsi_non_canon"
3879 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3880 (minus:SI
3881 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3882 (match_operator:SI 4 "minmax_operator"
3883 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3884 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3885 (clobber (reg:CC CC_REGNUM))]
3886 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3887 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3888 "#"
3889 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3890 [(set (reg:CC CC_REGNUM)
3891 (compare:CC (match_dup 2) (match_dup 3)))
3892
3893 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3894 (set (match_dup 0)
3895 (minus:SI (match_dup 1)
3896 (match_dup 2))))
3897 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3898 (set (match_dup 0)
3899 (match_dup 6)))]
3900 {
3901 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3902 operands[2], operands[3]);
3903 enum rtx_code rc = minmax_code (operands[4]);
3904 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3905 operands[2], operands[3]);
3906
3907 if (mode == CCFPmode || mode == CCFPEmode)
3908 rc = reverse_condition_maybe_unordered (rc);
3909 else
3910 rc = reverse_condition (rc);
3911 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3912 if (CONST_INT_P (operands[3]))
3913 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3914 else
3915 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3916 }
3917 [(set_attr "conds" "clob")
3918 (set (attr "length")
3919 (if_then_else (eq_attr "is_thumb" "yes")
3920 (const_int 14)
3921 (const_int 12)))
3922 (set_attr "type" "multiple")]
3923 )
3924
3925 (define_code_iterator SAT [smin smax])
3926 (define_code_iterator SATrev [smin smax])
3927 (define_code_attr SATlo [(smin "1") (smax "2")])
3928 (define_code_attr SAThi [(smin "2") (smax "1")])
3929
3930 (define_insn "*satsi_<SAT:code>"
3931 [(set (match_operand:SI 0 "s_register_operand" "=r")
3932 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3933 (match_operand:SI 1 "const_int_operand" "i"))
3934 (match_operand:SI 2 "const_int_operand" "i")))]
3935 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3936 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3937 {
3938 int mask;
3939 bool signed_sat;
3940 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3941 &mask, &signed_sat))
3942 gcc_unreachable ();
3943
3944 operands[1] = GEN_INT (mask);
3945 if (signed_sat)
3946 return "ssat%?\t%0, %1, %3";
3947 else
3948 return "usat%?\t%0, %1, %3";
3949 }
3950 [(set_attr "predicable" "yes")
3951 (set_attr "predicable_short_it" "no")
3952 (set_attr "type" "alus_imm")]
3953 )
3954
3955 (define_insn "*satsi_<SAT:code>_shift"
3956 [(set (match_operand:SI 0 "s_register_operand" "=r")
3957 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3958 [(match_operand:SI 4 "s_register_operand" "r")
3959 (match_operand:SI 5 "const_int_operand" "i")])
3960 (match_operand:SI 1 "const_int_operand" "i"))
3961 (match_operand:SI 2 "const_int_operand" "i")))]
3962 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3963 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3964 {
3965 int mask;
3966 bool signed_sat;
3967 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3968 &mask, &signed_sat))
3969 gcc_unreachable ();
3970
3971 operands[1] = GEN_INT (mask);
3972 if (signed_sat)
3973 return "ssat%?\t%0, %1, %4%S3";
3974 else
3975 return "usat%?\t%0, %1, %4%S3";
3976 }
3977 [(set_attr "predicable" "yes")
3978 (set_attr "predicable_short_it" "no")
3979 (set_attr "shift" "3")
3980 (set_attr "type" "logic_shift_reg")])
3981 \f
3982 ;; Shift and rotation insns
3983
3984 (define_expand "ashldi3"
3985 [(set (match_operand:DI 0 "s_register_operand" "")
3986 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3987 (match_operand:SI 2 "general_operand" "")))]
3988 "TARGET_32BIT"
3989 "
3990 if (TARGET_NEON)
3991 {
3992 /* Delay the decision whether to use NEON or core-regs until
3993 register allocation. */
3994 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3995 DONE;
3996 }
3997 else
3998 {
3999 /* Only the NEON case can handle in-memory shift counts. */
4000 if (!reg_or_int_operand (operands[2], SImode))
4001 operands[2] = force_reg (SImode, operands[2]);
4002 }
4003
4004 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4005 ; /* No special preparation statements; expand pattern as above. */
4006 else
4007 {
4008 rtx scratch1, scratch2;
4009
4010 if (operands[2] == CONST1_RTX (SImode))
4011 {
4012 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
4013 DONE;
4014 }
4015
4016 /* Ideally we should use iwmmxt here if we could know that operands[1]
4017 ends up already living in an iwmmxt register. Otherwise it's
4018 cheaper to have the alternate code being generated than moving
4019 values to iwmmxt regs and back. */
4020
4021 /* Expand operation using core-registers.
4022 'FAIL' would achieve the same thing, but this is a bit smarter. */
4023 scratch1 = gen_reg_rtx (SImode);
4024 scratch2 = gen_reg_rtx (SImode);
4025 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4026 operands[2], scratch1, scratch2);
4027 DONE;
4028 }
4029 "
4030 )
4031
4032 (define_insn "arm_ashldi3_1bit"
4033 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4034 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4035 (const_int 1)))
4036 (clobber (reg:CC CC_REGNUM))]
4037 "TARGET_32BIT"
4038 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4039 [(set_attr "conds" "clob")
4040 (set_attr "length" "8")
4041 (set_attr "type" "multiple")]
4042 )
4043
4044 (define_expand "ashlsi3"
4045 [(set (match_operand:SI 0 "s_register_operand" "")
4046 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4047 (match_operand:SI 2 "arm_rhs_operand" "")))]
4048 "TARGET_EITHER"
4049 "
4050 if (CONST_INT_P (operands[2])
4051 && (UINTVAL (operands[2])) > 31)
4052 {
4053 emit_insn (gen_movsi (operands[0], const0_rtx));
4054 DONE;
4055 }
4056 "
4057 )
4058
4059 (define_expand "ashrdi3"
4060 [(set (match_operand:DI 0 "s_register_operand" "")
4061 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4062 (match_operand:SI 2 "reg_or_int_operand" "")))]
4063 "TARGET_32BIT"
4064 "
4065 if (TARGET_NEON)
4066 {
4067 /* Delay the decision whether to use NEON or core-regs until
4068 register allocation. */
4069 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4070 DONE;
4071 }
4072
4073 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4074 ; /* No special preparation statements; expand pattern as above. */
4075 else
4076 {
4077 rtx scratch1, scratch2;
4078
4079 if (operands[2] == CONST1_RTX (SImode))
4080 {
4081 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4082 DONE;
4083 }
4084
4085 /* Ideally we should use iwmmxt here if we could know that operands[1]
4086 ends up already living in an iwmmxt register. Otherwise it's
4087 cheaper to have the alternate code being generated than moving
4088 values to iwmmxt regs and back. */
4089
4090 /* Expand operation using core-registers.
4091 'FAIL' would achieve the same thing, but this is a bit smarter. */
4092 scratch1 = gen_reg_rtx (SImode);
4093 scratch2 = gen_reg_rtx (SImode);
4094 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4095 operands[2], scratch1, scratch2);
4096 DONE;
4097 }
4098 "
4099 )
4100
4101 (define_insn "arm_ashrdi3_1bit"
4102 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4103 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4104 (const_int 1)))
4105 (clobber (reg:CC CC_REGNUM))]
4106 "TARGET_32BIT"
4107 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4108 [(set_attr "conds" "clob")
4109 (set_attr "length" "8")
4110 (set_attr "type" "multiple")]
4111 )
4112
4113 (define_expand "ashrsi3"
4114 [(set (match_operand:SI 0 "s_register_operand" "")
4115 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4116 (match_operand:SI 2 "arm_rhs_operand" "")))]
4117 "TARGET_EITHER"
4118 "
4119 if (CONST_INT_P (operands[2])
4120 && UINTVAL (operands[2]) > 31)
4121 operands[2] = GEN_INT (31);
4122 "
4123 )
4124
4125 (define_expand "lshrdi3"
4126 [(set (match_operand:DI 0 "s_register_operand" "")
4127 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4128 (match_operand:SI 2 "reg_or_int_operand" "")))]
4129 "TARGET_32BIT"
4130 "
4131 if (TARGET_NEON)
4132 {
4133 /* Delay the decision whether to use NEON or core-regs until
4134 register allocation. */
4135 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4136 DONE;
4137 }
4138
4139 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4140 ; /* No special preparation statements; expand pattern as above. */
4141 else
4142 {
4143 rtx scratch1, scratch2;
4144
4145 if (operands[2] == CONST1_RTX (SImode))
4146 {
4147 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4148 DONE;
4149 }
4150
4151 /* Ideally we should use iwmmxt here if we could know that operands[1]
4152 ends up already living in an iwmmxt register. Otherwise it's
4153 cheaper to have the alternate code being generated than moving
4154 values to iwmmxt regs and back. */
4155
4156 /* Expand operation using core-registers.
4157 'FAIL' would achieve the same thing, but this is a bit smarter. */
4158 scratch1 = gen_reg_rtx (SImode);
4159 scratch2 = gen_reg_rtx (SImode);
4160 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4161 operands[2], scratch1, scratch2);
4162 DONE;
4163 }
4164 "
4165 )
4166
4167 (define_insn "arm_lshrdi3_1bit"
4168 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4169 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4170 (const_int 1)))
4171 (clobber (reg:CC CC_REGNUM))]
4172 "TARGET_32BIT"
4173 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4174 [(set_attr "conds" "clob")
4175 (set_attr "length" "8")
4176 (set_attr "type" "multiple")]
4177 )
4178
4179 (define_expand "lshrsi3"
4180 [(set (match_operand:SI 0 "s_register_operand" "")
4181 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4182 (match_operand:SI 2 "arm_rhs_operand" "")))]
4183 "TARGET_EITHER"
4184 "
4185 if (CONST_INT_P (operands[2])
4186 && (UINTVAL (operands[2])) > 31)
4187 {
4188 emit_insn (gen_movsi (operands[0], const0_rtx));
4189 DONE;
4190 }
4191 "
4192 )
4193
4194 (define_expand "rotlsi3"
4195 [(set (match_operand:SI 0 "s_register_operand" "")
4196 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4197 (match_operand:SI 2 "reg_or_int_operand" "")))]
4198 "TARGET_32BIT"
4199 "
4200 if (CONST_INT_P (operands[2]))
4201 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4202 else
4203 {
4204 rtx reg = gen_reg_rtx (SImode);
4205 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4206 operands[2] = reg;
4207 }
4208 "
4209 )
4210
4211 (define_expand "rotrsi3"
4212 [(set (match_operand:SI 0 "s_register_operand" "")
4213 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4214 (match_operand:SI 2 "arm_rhs_operand" "")))]
4215 "TARGET_EITHER"
4216 "
4217 if (TARGET_32BIT)
4218 {
4219 if (CONST_INT_P (operands[2])
4220 && UINTVAL (operands[2]) > 31)
4221 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4222 }
4223 else /* TARGET_THUMB1 */
4224 {
4225 if (CONST_INT_P (operands [2]))
4226 operands [2] = force_reg (SImode, operands[2]);
4227 }
4228 "
4229 )
4230
4231 (define_insn "*arm_shiftsi3"
4232 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4233 (match_operator:SI 3 "shift_operator"
4234 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4235 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4236 "TARGET_32BIT"
4237 "* return arm_output_shift(operands, 0);"
4238 [(set_attr "predicable" "yes")
4239 (set_attr "arch" "t2,t2,*,*")
4240 (set_attr "predicable_short_it" "yes,yes,no,no")
4241 (set_attr "length" "4")
4242 (set_attr "shift" "1")
4243 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4244 )
4245
4246 (define_insn "*shiftsi3_compare0"
4247 [(set (reg:CC_NOOV CC_REGNUM)
4248 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4249 [(match_operand:SI 1 "s_register_operand" "r,r")
4250 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4251 (const_int 0)))
4252 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4253 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4254 "TARGET_32BIT"
4255 "* return arm_output_shift(operands, 1);"
4256 [(set_attr "conds" "set")
4257 (set_attr "shift" "1")
4258 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4259 )
4260
4261 (define_insn "*shiftsi3_compare0_scratch"
4262 [(set (reg:CC_NOOV CC_REGNUM)
4263 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4264 [(match_operand:SI 1 "s_register_operand" "r,r")
4265 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4266 (const_int 0)))
4267 (clobber (match_scratch:SI 0 "=r,r"))]
4268 "TARGET_32BIT"
4269 "* return arm_output_shift(operands, 1);"
4270 [(set_attr "conds" "set")
4271 (set_attr "shift" "1")
4272 (set_attr "type" "shift_imm,shift_reg")]
4273 )
4274
4275 (define_insn "*not_shiftsi"
4276 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4277 (not:SI (match_operator:SI 3 "shift_operator"
4278 [(match_operand:SI 1 "s_register_operand" "r,r")
4279 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4280 "TARGET_32BIT"
4281 "mvn%?\\t%0, %1%S3"
4282 [(set_attr "predicable" "yes")
4283 (set_attr "predicable_short_it" "no")
4284 (set_attr "shift" "1")
4285 (set_attr "arch" "32,a")
4286 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4287
4288 (define_insn "*not_shiftsi_compare0"
4289 [(set (reg:CC_NOOV CC_REGNUM)
4290 (compare:CC_NOOV
4291 (not:SI (match_operator:SI 3 "shift_operator"
4292 [(match_operand:SI 1 "s_register_operand" "r,r")
4293 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4294 (const_int 0)))
4295 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4296 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4297 "TARGET_32BIT"
4298 "mvns%?\\t%0, %1%S3"
4299 [(set_attr "conds" "set")
4300 (set_attr "shift" "1")
4301 (set_attr "arch" "32,a")
4302 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4303
4304 (define_insn "*not_shiftsi_compare0_scratch"
4305 [(set (reg:CC_NOOV CC_REGNUM)
4306 (compare:CC_NOOV
4307 (not:SI (match_operator:SI 3 "shift_operator"
4308 [(match_operand:SI 1 "s_register_operand" "r,r")
4309 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4310 (const_int 0)))
4311 (clobber (match_scratch:SI 0 "=r,r"))]
4312 "TARGET_32BIT"
4313 "mvns%?\\t%0, %1%S3"
4314 [(set_attr "conds" "set")
4315 (set_attr "shift" "1")
4316 (set_attr "arch" "32,a")
4317 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4318
4319 ;; We don't really have extzv, but defining this using shifts helps
4320 ;; to reduce register pressure later on.
4321
4322 (define_expand "extzv"
4323 [(set (match_operand 0 "s_register_operand" "")
4324 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4325 (match_operand 2 "const_int_operand" "")
4326 (match_operand 3 "const_int_operand" "")))]
4327 "TARGET_THUMB1 || arm_arch_thumb2"
4328 "
4329 {
4330 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4331 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4332
4333 if (arm_arch_thumb2)
4334 {
4335 HOST_WIDE_INT width = INTVAL (operands[2]);
4336 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4337
4338 if (unaligned_access && MEM_P (operands[1])
4339 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4340 {
4341 rtx base_addr;
4342
4343 if (BYTES_BIG_ENDIAN)
4344 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4345 - bitpos;
4346
4347 if (width == 32)
4348 {
4349 base_addr = adjust_address (operands[1], SImode,
4350 bitpos / BITS_PER_UNIT);
4351 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4352 }
4353 else
4354 {
4355 rtx dest = operands[0];
4356 rtx tmp = gen_reg_rtx (SImode);
4357
4358 /* We may get a paradoxical subreg here. Strip it off. */
4359 if (GET_CODE (dest) == SUBREG
4360 && GET_MODE (dest) == SImode
4361 && GET_MODE (SUBREG_REG (dest)) == HImode)
4362 dest = SUBREG_REG (dest);
4363
4364 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4365 FAIL;
4366
4367 base_addr = adjust_address (operands[1], HImode,
4368 bitpos / BITS_PER_UNIT);
4369 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4370 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4371 }
4372 DONE;
4373 }
4374 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4375 {
4376 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4377 operands[3]));
4378 DONE;
4379 }
4380 else
4381 FAIL;
4382 }
4383
4384 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4385 FAIL;
4386
4387 operands[3] = GEN_INT (rshift);
4388
4389 if (lshift == 0)
4390 {
4391 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4392 DONE;
4393 }
4394
4395 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4396 operands[3], gen_reg_rtx (SImode)));
4397 DONE;
4398 }"
4399 )
4400
4401 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4402
4403 (define_expand "extzv_t1"
4404 [(set (match_operand:SI 4 "s_register_operand" "")
4405 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4406 (match_operand:SI 2 "const_int_operand" "")))
4407 (set (match_operand:SI 0 "s_register_operand" "")
4408 (lshiftrt:SI (match_dup 4)
4409 (match_operand:SI 3 "const_int_operand" "")))]
4410 "TARGET_THUMB1"
4411 "")
4412
4413 (define_expand "extv"
4414 [(set (match_operand 0 "s_register_operand" "")
4415 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4416 (match_operand 2 "const_int_operand" "")
4417 (match_operand 3 "const_int_operand" "")))]
4418 "arm_arch_thumb2"
4419 {
4420 HOST_WIDE_INT width = INTVAL (operands[2]);
4421 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4422
4423 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4424 && (bitpos % BITS_PER_UNIT) == 0)
4425 {
4426 rtx base_addr;
4427
4428 if (BYTES_BIG_ENDIAN)
4429 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4430
4431 if (width == 32)
4432 {
4433 base_addr = adjust_address (operands[1], SImode,
4434 bitpos / BITS_PER_UNIT);
4435 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4436 }
4437 else
4438 {
4439 rtx dest = operands[0];
4440 rtx tmp = gen_reg_rtx (SImode);
4441
4442 /* We may get a paradoxical subreg here. Strip it off. */
4443 if (GET_CODE (dest) == SUBREG
4444 && GET_MODE (dest) == SImode
4445 && GET_MODE (SUBREG_REG (dest)) == HImode)
4446 dest = SUBREG_REG (dest);
4447
4448 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4449 FAIL;
4450
4451 base_addr = adjust_address (operands[1], HImode,
4452 bitpos / BITS_PER_UNIT);
4453 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4454 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4455 }
4456
4457 DONE;
4458 }
4459 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4460 FAIL;
4461 else if (GET_MODE (operands[0]) == SImode
4462 && GET_MODE (operands[1]) == SImode)
4463 {
4464 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4465 operands[3]));
4466 DONE;
4467 }
4468
4469 FAIL;
4470 })
4471
4472 ; Helper to expand register forms of extv with the proper modes.
4473
4474 (define_expand "extv_regsi"
4475 [(set (match_operand:SI 0 "s_register_operand" "")
4476 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4477 (match_operand 2 "const_int_operand" "")
4478 (match_operand 3 "const_int_operand" "")))]
4479 ""
4480 {
4481 })
4482
4483 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4484
4485 (define_insn "unaligned_loadsi"
4486 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4487 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4488 UNSPEC_UNALIGNED_LOAD))]
4489 "unaligned_access"
4490 "ldr%?\t%0, %1\t@ unaligned"
4491 [(set_attr "arch" "t2,any")
4492 (set_attr "length" "2,4")
4493 (set_attr "predicable" "yes")
4494 (set_attr "predicable_short_it" "yes,no")
4495 (set_attr "type" "load1")])
4496
4497 (define_insn "unaligned_loadhis"
4498 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4499 (sign_extend:SI
4500 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4501 UNSPEC_UNALIGNED_LOAD)))]
4502 "unaligned_access"
4503 "ldrsh%?\t%0, %1\t@ unaligned"
4504 [(set_attr "arch" "t2,any")
4505 (set_attr "length" "2,4")
4506 (set_attr "predicable" "yes")
4507 (set_attr "predicable_short_it" "yes,no")
4508 (set_attr "type" "load_byte")])
4509
4510 (define_insn "unaligned_loadhiu"
4511 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4512 (zero_extend:SI
4513 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4514 UNSPEC_UNALIGNED_LOAD)))]
4515 "unaligned_access"
4516 "ldrh%?\t%0, %1\t@ unaligned"
4517 [(set_attr "arch" "t2,any")
4518 (set_attr "length" "2,4")
4519 (set_attr "predicable" "yes")
4520 (set_attr "predicable_short_it" "yes,no")
4521 (set_attr "type" "load_byte")])
4522
4523 (define_insn "unaligned_storesi"
4524 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4525 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4526 UNSPEC_UNALIGNED_STORE))]
4527 "unaligned_access"
4528 "str%?\t%1, %0\t@ unaligned"
4529 [(set_attr "arch" "t2,any")
4530 (set_attr "length" "2,4")
4531 (set_attr "predicable" "yes")
4532 (set_attr "predicable_short_it" "yes,no")
4533 (set_attr "type" "store1")])
4534
4535 (define_insn "unaligned_storehi"
4536 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4537 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4538 UNSPEC_UNALIGNED_STORE))]
4539 "unaligned_access"
4540 "strh%?\t%1, %0\t@ unaligned"
4541 [(set_attr "arch" "t2,any")
4542 (set_attr "length" "2,4")
4543 (set_attr "predicable" "yes")
4544 (set_attr "predicable_short_it" "yes,no")
4545 (set_attr "type" "store1")])
4546
4547
4548 (define_insn "*extv_reg"
4549 [(set (match_operand:SI 0 "s_register_operand" "=r")
4550 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4551 (match_operand:SI 2 "const_int_operand" "n")
4552 (match_operand:SI 3 "const_int_operand" "n")))]
4553 "arm_arch_thumb2
4554 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4555 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4556 "sbfx%?\t%0, %1, %3, %2"
4557 [(set_attr "length" "4")
4558 (set_attr "predicable" "yes")
4559 (set_attr "predicable_short_it" "no")
4560 (set_attr "type" "bfm")]
4561 )
4562
4563 (define_insn "extzv_t2"
4564 [(set (match_operand:SI 0 "s_register_operand" "=r")
4565 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4566 (match_operand:SI 2 "const_int_operand" "n")
4567 (match_operand:SI 3 "const_int_operand" "n")))]
4568 "arm_arch_thumb2
4569 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4570 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4571 "ubfx%?\t%0, %1, %3, %2"
4572 [(set_attr "length" "4")
4573 (set_attr "predicable" "yes")
4574 (set_attr "predicable_short_it" "no")
4575 (set_attr "type" "bfm")]
4576 )
4577
4578
4579 ;; Division instructions
4580 (define_insn "divsi3"
4581 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4582 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4583 (match_operand:SI 2 "s_register_operand" "r,r")))]
4584 "TARGET_IDIV"
4585 "@
4586 sdiv%?\t%0, %1, %2
4587 sdiv\t%0, %1, %2"
4588 [(set_attr "arch" "32,v8mb")
4589 (set_attr "predicable" "yes")
4590 (set_attr "predicable_short_it" "no")
4591 (set_attr "type" "sdiv")]
4592 )
4593
4594 (define_insn "udivsi3"
4595 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4596 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4597 (match_operand:SI 2 "s_register_operand" "r,r")))]
4598 "TARGET_IDIV"
4599 "@
4600 udiv%?\t%0, %1, %2
4601 udiv\t%0, %1, %2"
4602 [(set_attr "arch" "32,v8mb")
4603 (set_attr "predicable" "yes")
4604 (set_attr "predicable_short_it" "no")
4605 (set_attr "type" "udiv")]
4606 )
4607
4608 \f
4609 ;; Unary arithmetic insns
4610
4611 (define_expand "negvsi3"
4612 [(match_operand:SI 0 "register_operand")
4613 (match_operand:SI 1 "register_operand")
4614 (match_operand 2 "")]
4615 "TARGET_32BIT"
4616 {
4617 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4618 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4619
4620 DONE;
4621 })
4622
4623 (define_expand "negvdi3"
4624 [(match_operand:DI 0 "register_operand")
4625 (match_operand:DI 1 "register_operand")
4626 (match_operand 2 "")]
4627 "TARGET_ARM"
4628 {
4629 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4630 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4631
4632 DONE;
4633 })
4634
4635
4636 (define_insn_and_split "negdi2_compare"
4637 [(set (reg:CC CC_REGNUM)
4638 (compare:CC
4639 (const_int 0)
4640 (match_operand:DI 1 "register_operand" "0,r")))
4641 (set (match_operand:DI 0 "register_operand" "=r,&r")
4642 (minus:DI (const_int 0) (match_dup 1)))]
4643 "TARGET_ARM"
4644 "#"
4645 "&& reload_completed"
4646 [(parallel [(set (reg:CC CC_REGNUM)
4647 (compare:CC (const_int 0) (match_dup 1)))
4648 (set (match_dup 0) (minus:SI (const_int 0)
4649 (match_dup 1)))])
4650 (parallel [(set (reg:CC CC_REGNUM)
4651 (compare:CC (const_int 0) (match_dup 3)))
4652 (set (match_dup 2)
4653 (minus:SI
4654 (minus:SI (const_int 0) (match_dup 3))
4655 (ltu:SI (reg:CC_C CC_REGNUM)
4656 (const_int 0))))])]
4657 {
4658 operands[2] = gen_highpart (SImode, operands[0]);
4659 operands[0] = gen_lowpart (SImode, operands[0]);
4660 operands[3] = gen_highpart (SImode, operands[1]);
4661 operands[1] = gen_lowpart (SImode, operands[1]);
4662 }
4663 [(set_attr "conds" "set")
4664 (set_attr "length" "8")
4665 (set_attr "type" "multiple")]
4666 )
4667
4668 (define_expand "negdi2"
4669 [(parallel
4670 [(set (match_operand:DI 0 "s_register_operand" "")
4671 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4672 (clobber (reg:CC CC_REGNUM))])]
4673 "TARGET_EITHER"
4674 {
4675 if (TARGET_NEON)
4676 {
4677 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4678 DONE;
4679 }
4680 }
4681 )
4682
4683 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4684 ;; The first alternative allows the common case of a *full* overlap.
4685 (define_insn_and_split "*negdi2_insn"
4686 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4687 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4688 (clobber (reg:CC CC_REGNUM))]
4689 "TARGET_32BIT"
4690 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4691 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4692 "&& reload_completed"
4693 [(parallel [(set (reg:CC CC_REGNUM)
4694 (compare:CC (const_int 0) (match_dup 1)))
4695 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4696 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4697 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4698 {
4699 operands[2] = gen_highpart (SImode, operands[0]);
4700 operands[0] = gen_lowpart (SImode, operands[0]);
4701 operands[3] = gen_highpart (SImode, operands[1]);
4702 operands[1] = gen_lowpart (SImode, operands[1]);
4703 }
4704 [(set_attr "conds" "clob")
4705 (set_attr "length" "8")
4706 (set_attr "type" "multiple")]
4707 )
4708
4709 (define_insn "*negsi2_carryin_compare"
4710 [(set (reg:CC CC_REGNUM)
4711 (compare:CC (const_int 0)
4712 (match_operand:SI 1 "s_register_operand" "r")))
4713 (set (match_operand:SI 0 "s_register_operand" "=r")
4714 (minus:SI (minus:SI (const_int 0)
4715 (match_dup 1))
4716 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4717 "TARGET_ARM"
4718 "rscs\\t%0, %1, #0"
4719 [(set_attr "conds" "set")
4720 (set_attr "type" "alus_imm")]
4721 )
4722
4723 (define_expand "negsi2"
4724 [(set (match_operand:SI 0 "s_register_operand" "")
4725 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4726 "TARGET_EITHER"
4727 ""
4728 )
4729
4730 (define_insn "*arm_negsi2"
4731 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4732 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4733 "TARGET_32BIT"
4734 "rsb%?\\t%0, %1, #0"
4735 [(set_attr "predicable" "yes")
4736 (set_attr "predicable_short_it" "yes,no")
4737 (set_attr "arch" "t2,*")
4738 (set_attr "length" "4")
4739 (set_attr "type" "alu_sreg")]
4740 )
4741
4742 (define_expand "negsf2"
4743 [(set (match_operand:SF 0 "s_register_operand" "")
4744 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4745 "TARGET_32BIT && TARGET_HARD_FLOAT"
4746 ""
4747 )
4748
4749 (define_expand "negdf2"
4750 [(set (match_operand:DF 0 "s_register_operand" "")
4751 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4752 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4753 "")
4754
4755 (define_insn_and_split "*zextendsidi_negsi"
4756 [(set (match_operand:DI 0 "s_register_operand" "=r")
4757 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4758 "TARGET_32BIT"
4759 "#"
4760 ""
4761 [(set (match_dup 2)
4762 (neg:SI (match_dup 1)))
4763 (set (match_dup 3)
4764 (const_int 0))]
4765 {
4766 operands[2] = gen_lowpart (SImode, operands[0]);
4767 operands[3] = gen_highpart (SImode, operands[0]);
4768 }
4769 [(set_attr "length" "8")
4770 (set_attr "type" "multiple")]
4771 )
4772
4773 ;; Negate an extended 32-bit value.
4774 (define_insn_and_split "*negdi_extendsidi"
4775 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4776 (neg:DI (sign_extend:DI
4777 (match_operand:SI 1 "s_register_operand" "l,r"))))
4778 (clobber (reg:CC CC_REGNUM))]
4779 "TARGET_32BIT"
4780 "#"
4781 "&& reload_completed"
4782 [(const_int 0)]
4783 {
4784 rtx low = gen_lowpart (SImode, operands[0]);
4785 rtx high = gen_highpart (SImode, operands[0]);
4786
4787 if (reg_overlap_mentioned_p (low, operands[1]))
4788 {
4789 /* Input overlaps the low word of the output. Use:
4790 asr Rhi, Rin, #31
4791 rsbs Rlo, Rin, #0
4792 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4793 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4794
4795 emit_insn (gen_rtx_SET (high,
4796 gen_rtx_ASHIFTRT (SImode, operands[1],
4797 GEN_INT (31))));
4798
4799 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4800 if (TARGET_ARM)
4801 emit_insn (gen_rtx_SET (high,
4802 gen_rtx_MINUS (SImode,
4803 gen_rtx_MINUS (SImode,
4804 const0_rtx,
4805 high),
4806 gen_rtx_LTU (SImode,
4807 cc_reg,
4808 const0_rtx))));
4809 else
4810 {
4811 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4812 emit_insn (gen_rtx_SET (high,
4813 gen_rtx_MINUS (SImode,
4814 gen_rtx_MINUS (SImode,
4815 high,
4816 two_x),
4817 gen_rtx_LTU (SImode,
4818 cc_reg,
4819 const0_rtx))));
4820 }
4821 }
4822 else
4823 {
4824 /* No overlap, or overlap on high word. Use:
4825 rsb Rlo, Rin, #0
4826 bic Rhi, Rlo, Rin
4827 asr Rhi, Rhi, #31
4828 Flags not needed for this sequence. */
4829 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4830 emit_insn (gen_rtx_SET (high,
4831 gen_rtx_AND (SImode,
4832 gen_rtx_NOT (SImode, operands[1]),
4833 low)));
4834 emit_insn (gen_rtx_SET (high,
4835 gen_rtx_ASHIFTRT (SImode, high,
4836 GEN_INT (31))));
4837 }
4838 DONE;
4839 }
4840 [(set_attr "length" "12")
4841 (set_attr "arch" "t2,*")
4842 (set_attr "type" "multiple")]
4843 )
4844
4845 (define_insn_and_split "*negdi_zero_extendsidi"
4846 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4847 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4848 (clobber (reg:CC CC_REGNUM))]
4849 "TARGET_32BIT"
4850 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4851 ;; Don't care what register is input to sbc,
4852 ;; since we just need to propagate the carry.
4853 "&& reload_completed"
4854 [(parallel [(set (reg:CC CC_REGNUM)
4855 (compare:CC (const_int 0) (match_dup 1)))
4856 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4857 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4858 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4859 {
4860 operands[2] = gen_highpart (SImode, operands[0]);
4861 operands[0] = gen_lowpart (SImode, operands[0]);
4862 }
4863 [(set_attr "conds" "clob")
4864 (set_attr "length" "8")
4865 (set_attr "type" "multiple")] ;; length in thumb is 4
4866 )
4867
4868 ;; abssi2 doesn't really clobber the condition codes if a different register
4869 ;; is being set. To keep things simple, assume during rtl manipulations that
4870 ;; it does, but tell the final scan operator the truth. Similarly for
4871 ;; (neg (abs...))
4872
4873 (define_expand "abssi2"
4874 [(parallel
4875 [(set (match_operand:SI 0 "s_register_operand" "")
4876 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4877 (clobber (match_dup 2))])]
4878 "TARGET_EITHER"
4879 "
4880 if (TARGET_THUMB1)
4881 operands[2] = gen_rtx_SCRATCH (SImode);
4882 else
4883 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4884 ")
4885
4886 (define_insn_and_split "*arm_abssi2"
4887 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4888 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4889 (clobber (reg:CC CC_REGNUM))]
4890 "TARGET_ARM"
4891 "#"
4892 "&& reload_completed"
4893 [(const_int 0)]
4894 {
4895 /* if (which_alternative == 0) */
4896 if (REGNO(operands[0]) == REGNO(operands[1]))
4897 {
4898 /* Emit the pattern:
4899 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4900 [(set (reg:CC CC_REGNUM)
4901 (compare:CC (match_dup 0) (const_int 0)))
4902 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4903 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4904 */
4905 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4906 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4907 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4908 (gen_rtx_LT (SImode,
4909 gen_rtx_REG (CCmode, CC_REGNUM),
4910 const0_rtx)),
4911 (gen_rtx_SET (operands[0],
4912 (gen_rtx_MINUS (SImode,
4913 const0_rtx,
4914 operands[1]))))));
4915 DONE;
4916 }
4917 else
4918 {
4919 /* Emit the pattern:
4920 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4921 [(set (match_dup 0)
4922 (xor:SI (match_dup 1)
4923 (ashiftrt:SI (match_dup 1) (const_int 31))))
4924 (set (match_dup 0)
4925 (minus:SI (match_dup 0)
4926 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4927 */
4928 emit_insn (gen_rtx_SET (operands[0],
4929 gen_rtx_XOR (SImode,
4930 gen_rtx_ASHIFTRT (SImode,
4931 operands[1],
4932 GEN_INT (31)),
4933 operands[1])));
4934 emit_insn (gen_rtx_SET (operands[0],
4935 gen_rtx_MINUS (SImode,
4936 operands[0],
4937 gen_rtx_ASHIFTRT (SImode,
4938 operands[1],
4939 GEN_INT (31)))));
4940 DONE;
4941 }
4942 }
4943 [(set_attr "conds" "clob,*")
4944 (set_attr "shift" "1")
4945 (set_attr "predicable" "no, yes")
4946 (set_attr "length" "8")
4947 (set_attr "type" "multiple")]
4948 )
4949
4950 (define_insn_and_split "*arm_neg_abssi2"
4951 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4952 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4953 (clobber (reg:CC CC_REGNUM))]
4954 "TARGET_ARM"
4955 "#"
4956 "&& reload_completed"
4957 [(const_int 0)]
4958 {
4959 /* if (which_alternative == 0) */
4960 if (REGNO (operands[0]) == REGNO (operands[1]))
4961 {
4962 /* Emit the pattern:
4963 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4964 */
4965 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4966 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4967 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4968 gen_rtx_GT (SImode,
4969 gen_rtx_REG (CCmode, CC_REGNUM),
4970 const0_rtx),
4971 gen_rtx_SET (operands[0],
4972 (gen_rtx_MINUS (SImode,
4973 const0_rtx,
4974 operands[1])))));
4975 }
4976 else
4977 {
4978 /* Emit the pattern:
4979 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4980 */
4981 emit_insn (gen_rtx_SET (operands[0],
4982 gen_rtx_XOR (SImode,
4983 gen_rtx_ASHIFTRT (SImode,
4984 operands[1],
4985 GEN_INT (31)),
4986 operands[1])));
4987 emit_insn (gen_rtx_SET (operands[0],
4988 gen_rtx_MINUS (SImode,
4989 gen_rtx_ASHIFTRT (SImode,
4990 operands[1],
4991 GEN_INT (31)),
4992 operands[0])));
4993 }
4994 DONE;
4995 }
4996 [(set_attr "conds" "clob,*")
4997 (set_attr "shift" "1")
4998 (set_attr "predicable" "no, yes")
4999 (set_attr "length" "8")
5000 (set_attr "type" "multiple")]
5001 )
5002
5003 (define_expand "abssf2"
5004 [(set (match_operand:SF 0 "s_register_operand" "")
5005 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5006 "TARGET_32BIT && TARGET_HARD_FLOAT"
5007 "")
5008
5009 (define_expand "absdf2"
5010 [(set (match_operand:DF 0 "s_register_operand" "")
5011 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5012 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5013 "")
5014
5015 (define_expand "sqrtsf2"
5016 [(set (match_operand:SF 0 "s_register_operand" "")
5017 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5018 "TARGET_32BIT && TARGET_HARD_FLOAT"
5019 "")
5020
5021 (define_expand "sqrtdf2"
5022 [(set (match_operand:DF 0 "s_register_operand" "")
5023 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5024 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5025 "")
5026
5027 (define_insn_and_split "one_cmpldi2"
5028 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5029 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5030 "TARGET_32BIT"
5031 "@
5032 vmvn\t%P0, %P1
5033 #
5034 #
5035 vmvn\t%P0, %P1"
5036 "TARGET_32BIT && reload_completed
5037 && arm_general_register_operand (operands[0], DImode)"
5038 [(set (match_dup 0) (not:SI (match_dup 1)))
5039 (set (match_dup 2) (not:SI (match_dup 3)))]
5040 "
5041 {
5042 operands[2] = gen_highpart (SImode, operands[0]);
5043 operands[0] = gen_lowpart (SImode, operands[0]);
5044 operands[3] = gen_highpart (SImode, operands[1]);
5045 operands[1] = gen_lowpart (SImode, operands[1]);
5046 }"
5047 [(set_attr "length" "*,8,8,*")
5048 (set_attr "predicable" "no,yes,yes,no")
5049 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5050 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5051 )
5052
5053 (define_expand "one_cmplsi2"
5054 [(set (match_operand:SI 0 "s_register_operand" "")
5055 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5056 "TARGET_EITHER"
5057 ""
5058 )
5059
5060 (define_insn "*arm_one_cmplsi2"
5061 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5062 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5063 "TARGET_32BIT"
5064 "mvn%?\\t%0, %1"
5065 [(set_attr "predicable" "yes")
5066 (set_attr "predicable_short_it" "yes,no")
5067 (set_attr "arch" "t2,*")
5068 (set_attr "length" "4")
5069 (set_attr "type" "mvn_reg")]
5070 )
5071
5072 (define_insn "*notsi_compare0"
5073 [(set (reg:CC_NOOV CC_REGNUM)
5074 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5075 (const_int 0)))
5076 (set (match_operand:SI 0 "s_register_operand" "=r")
5077 (not:SI (match_dup 1)))]
5078 "TARGET_32BIT"
5079 "mvns%?\\t%0, %1"
5080 [(set_attr "conds" "set")
5081 (set_attr "type" "mvn_reg")]
5082 )
5083
5084 (define_insn "*notsi_compare0_scratch"
5085 [(set (reg:CC_NOOV CC_REGNUM)
5086 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5087 (const_int 0)))
5088 (clobber (match_scratch:SI 0 "=r"))]
5089 "TARGET_32BIT"
5090 "mvns%?\\t%0, %1"
5091 [(set_attr "conds" "set")
5092 (set_attr "type" "mvn_reg")]
5093 )
5094 \f
5095 ;; Fixed <--> Floating conversion insns
5096
5097 (define_expand "floatsihf2"
5098 [(set (match_operand:HF 0 "general_operand" "")
5099 (float:HF (match_operand:SI 1 "general_operand" "")))]
5100 "TARGET_EITHER"
5101 "
5102 {
5103 rtx op1 = gen_reg_rtx (SFmode);
5104 expand_float (op1, operands[1], 0);
5105 op1 = convert_to_mode (HFmode, op1, 0);
5106 emit_move_insn (operands[0], op1);
5107 DONE;
5108 }"
5109 )
5110
5111 (define_expand "floatdihf2"
5112 [(set (match_operand:HF 0 "general_operand" "")
5113 (float:HF (match_operand:DI 1 "general_operand" "")))]
5114 "TARGET_EITHER"
5115 "
5116 {
5117 rtx op1 = gen_reg_rtx (SFmode);
5118 expand_float (op1, operands[1], 0);
5119 op1 = convert_to_mode (HFmode, op1, 0);
5120 emit_move_insn (operands[0], op1);
5121 DONE;
5122 }"
5123 )
5124
5125 (define_expand "floatsisf2"
5126 [(set (match_operand:SF 0 "s_register_operand" "")
5127 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5128 "TARGET_32BIT && TARGET_HARD_FLOAT"
5129 "
5130 ")
5131
5132 (define_expand "floatsidf2"
5133 [(set (match_operand:DF 0 "s_register_operand" "")
5134 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5135 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5136 "
5137 ")
5138
5139 (define_expand "fix_trunchfsi2"
5140 [(set (match_operand:SI 0 "general_operand" "")
5141 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5142 "TARGET_EITHER"
5143 "
5144 {
5145 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5146 expand_fix (operands[0], op1, 0);
5147 DONE;
5148 }"
5149 )
5150
5151 (define_expand "fix_trunchfdi2"
5152 [(set (match_operand:DI 0 "general_operand" "")
5153 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5154 "TARGET_EITHER"
5155 "
5156 {
5157 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5158 expand_fix (operands[0], op1, 0);
5159 DONE;
5160 }"
5161 )
5162
5163 (define_expand "fix_truncsfsi2"
5164 [(set (match_operand:SI 0 "s_register_operand" "")
5165 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5166 "TARGET_32BIT && TARGET_HARD_FLOAT"
5167 "
5168 ")
5169
5170 (define_expand "fix_truncdfsi2"
5171 [(set (match_operand:SI 0 "s_register_operand" "")
5172 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5173 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5174 "
5175 ")
5176
5177 ;; Truncation insns
5178
5179 (define_expand "truncdfsf2"
5180 [(set (match_operand:SF 0 "s_register_operand" "")
5181 (float_truncate:SF
5182 (match_operand:DF 1 "s_register_operand" "")))]
5183 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5184 ""
5185 )
5186
5187 ;; DFmode to HFmode conversions on targets without a single-step hardware
5188 ;; instruction for it would have to go through SFmode. This is dangerous
5189 ;; as it introduces double rounding.
5190 ;;
5191 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5192 ;; a single-step instruction.
5193
5194 (define_expand "truncdfhf2"
5195 [(set (match_operand:HF 0 "s_register_operand" "")
5196 (float_truncate:HF
5197 (match_operand:DF 1 "s_register_operand" "")))]
5198 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5199 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5200 {
5201 /* We don't have a direct instruction for this, so we must be in
5202 an unsafe math mode, and going via SFmode. */
5203
5204 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5205 {
5206 rtx op1;
5207 op1 = convert_to_mode (SFmode, operands[1], 0);
5208 op1 = convert_to_mode (HFmode, op1, 0);
5209 emit_move_insn (operands[0], op1);
5210 DONE;
5211 }
5212 /* Otherwise, we will pick this up as a single instruction with
5213 no intermediary rounding. */
5214 }
5215 )
5216 \f
5217 ;; Zero and sign extension instructions.
5218
5219 (define_insn "zero_extend<mode>di2"
5220 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5221 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5222 "<qhs_zextenddi_cstr>")))]
5223 "TARGET_32BIT <qhs_zextenddi_cond>"
5224 "#"
5225 [(set_attr "length" "8,4,8,8")
5226 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5227 (set_attr "ce_count" "2")
5228 (set_attr "predicable" "yes")
5229 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5230 )
5231
5232 (define_insn "extend<mode>di2"
5233 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5234 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5235 "<qhs_extenddi_cstr>")))]
5236 "TARGET_32BIT <qhs_sextenddi_cond>"
5237 "#"
5238 [(set_attr "length" "8,4,8,8,8")
5239 (set_attr "ce_count" "2")
5240 (set_attr "shift" "1")
5241 (set_attr "predicable" "yes")
5242 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5243 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5244 )
5245
5246 ;; Splits for all extensions to DImode
5247 (define_split
5248 [(set (match_operand:DI 0 "s_register_operand" "")
5249 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5250 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5251 [(set (match_dup 0) (match_dup 1))]
5252 {
5253 rtx lo_part = gen_lowpart (SImode, operands[0]);
5254 machine_mode src_mode = GET_MODE (operands[1]);
5255
5256 if (REG_P (operands[0])
5257 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5258 emit_clobber (operands[0]);
5259 if (!REG_P (lo_part) || src_mode != SImode
5260 || !rtx_equal_p (lo_part, operands[1]))
5261 {
5262 if (src_mode == SImode)
5263 emit_move_insn (lo_part, operands[1]);
5264 else
5265 emit_insn (gen_rtx_SET (lo_part,
5266 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5267 operands[1] = lo_part;
5268 }
5269 operands[0] = gen_highpart (SImode, operands[0]);
5270 operands[1] = const0_rtx;
5271 })
5272
5273 (define_split
5274 [(set (match_operand:DI 0 "s_register_operand" "")
5275 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5276 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5277 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5278 {
5279 rtx lo_part = gen_lowpart (SImode, operands[0]);
5280 machine_mode src_mode = GET_MODE (operands[1]);
5281
5282 if (REG_P (operands[0])
5283 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5284 emit_clobber (operands[0]);
5285
5286 if (!REG_P (lo_part) || src_mode != SImode
5287 || !rtx_equal_p (lo_part, operands[1]))
5288 {
5289 if (src_mode == SImode)
5290 emit_move_insn (lo_part, operands[1]);
5291 else
5292 emit_insn (gen_rtx_SET (lo_part,
5293 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5294 operands[1] = lo_part;
5295 }
5296 operands[0] = gen_highpart (SImode, operands[0]);
5297 })
5298
5299 (define_expand "zero_extendhisi2"
5300 [(set (match_operand:SI 0 "s_register_operand" "")
5301 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5302 "TARGET_EITHER"
5303 {
5304 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5305 {
5306 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5307 DONE;
5308 }
5309 if (!arm_arch6 && !MEM_P (operands[1]))
5310 {
5311 rtx t = gen_lowpart (SImode, operands[1]);
5312 rtx tmp = gen_reg_rtx (SImode);
5313 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5314 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5315 DONE;
5316 }
5317 })
5318
5319 (define_split
5320 [(set (match_operand:SI 0 "s_register_operand" "")
5321 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5322 "!TARGET_THUMB2 && !arm_arch6"
5323 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5324 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5325 {
5326 operands[2] = gen_lowpart (SImode, operands[1]);
5327 })
5328
5329 (define_insn "*arm_zero_extendhisi2"
5330 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5331 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5332 "TARGET_ARM && arm_arch4 && !arm_arch6"
5333 "@
5334 #
5335 ldrh%?\\t%0, %1"
5336 [(set_attr "type" "alu_shift_reg,load_byte")
5337 (set_attr "predicable" "yes")]
5338 )
5339
5340 (define_insn "*arm_zero_extendhisi2_v6"
5341 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5342 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5343 "TARGET_ARM && arm_arch6"
5344 "@
5345 uxth%?\\t%0, %1
5346 ldrh%?\\t%0, %1"
5347 [(set_attr "predicable" "yes")
5348 (set_attr "type" "extend,load_byte")]
5349 )
5350
5351 (define_insn "*arm_zero_extendhisi2addsi"
5352 [(set (match_operand:SI 0 "s_register_operand" "=r")
5353 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5354 (match_operand:SI 2 "s_register_operand" "r")))]
5355 "TARGET_INT_SIMD"
5356 "uxtah%?\\t%0, %2, %1"
5357 [(set_attr "type" "alu_shift_reg")
5358 (set_attr "predicable" "yes")
5359 (set_attr "predicable_short_it" "no")]
5360 )
5361
5362 (define_expand "zero_extendqisi2"
5363 [(set (match_operand:SI 0 "s_register_operand" "")
5364 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5365 "TARGET_EITHER"
5366 {
5367 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5368 {
5369 emit_insn (gen_andsi3 (operands[0],
5370 gen_lowpart (SImode, operands[1]),
5371 GEN_INT (255)));
5372 DONE;
5373 }
5374 if (!arm_arch6 && !MEM_P (operands[1]))
5375 {
5376 rtx t = gen_lowpart (SImode, operands[1]);
5377 rtx tmp = gen_reg_rtx (SImode);
5378 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5379 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5380 DONE;
5381 }
5382 })
5383
5384 (define_split
5385 [(set (match_operand:SI 0 "s_register_operand" "")
5386 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5387 "!arm_arch6"
5388 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5389 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5390 {
5391 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5392 if (TARGET_ARM)
5393 {
5394 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5395 DONE;
5396 }
5397 })
5398
5399 (define_insn "*arm_zero_extendqisi2"
5400 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5401 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5402 "TARGET_ARM && !arm_arch6"
5403 "@
5404 #
5405 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5406 [(set_attr "length" "8,4")
5407 (set_attr "type" "alu_shift_reg,load_byte")
5408 (set_attr "predicable" "yes")]
5409 )
5410
5411 (define_insn "*arm_zero_extendqisi2_v6"
5412 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5413 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5414 "TARGET_ARM && arm_arch6"
5415 "@
5416 uxtb%?\\t%0, %1
5417 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5418 [(set_attr "type" "extend,load_byte")
5419 (set_attr "predicable" "yes")]
5420 )
5421
5422 (define_insn "*arm_zero_extendqisi2addsi"
5423 [(set (match_operand:SI 0 "s_register_operand" "=r")
5424 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5425 (match_operand:SI 2 "s_register_operand" "r")))]
5426 "TARGET_INT_SIMD"
5427 "uxtab%?\\t%0, %2, %1"
5428 [(set_attr "predicable" "yes")
5429 (set_attr "predicable_short_it" "no")
5430 (set_attr "type" "alu_shift_reg")]
5431 )
5432
5433 (define_split
5434 [(set (match_operand:SI 0 "s_register_operand" "")
5435 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5436 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5437 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5438 [(set (match_dup 2) (match_dup 1))
5439 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5440 ""
5441 )
5442
5443 (define_split
5444 [(set (match_operand:SI 0 "s_register_operand" "")
5445 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5446 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5447 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5448 [(set (match_dup 2) (match_dup 1))
5449 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5450 ""
5451 )
5452
5453
5454 (define_split
5455 [(set (match_operand:SI 0 "s_register_operand" "")
5456 (IOR_XOR:SI (and:SI (ashift:SI
5457 (match_operand:SI 1 "s_register_operand" "")
5458 (match_operand:SI 2 "const_int_operand" ""))
5459 (match_operand:SI 3 "const_int_operand" ""))
5460 (zero_extend:SI
5461 (match_operator 5 "subreg_lowpart_operator"
5462 [(match_operand:SI 4 "s_register_operand" "")]))))]
5463 "TARGET_32BIT
5464 && (UINTVAL (operands[3])
5465 == (GET_MODE_MASK (GET_MODE (operands[5]))
5466 & (GET_MODE_MASK (GET_MODE (operands[5]))
5467 << (INTVAL (operands[2])))))"
5468 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5469 (match_dup 4)))
5470 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5471 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5472 )
5473
5474 (define_insn "*compareqi_eq0"
5475 [(set (reg:CC_Z CC_REGNUM)
5476 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5477 (const_int 0)))]
5478 "TARGET_32BIT"
5479 "tst%?\\t%0, #255"
5480 [(set_attr "conds" "set")
5481 (set_attr "predicable" "yes")
5482 (set_attr "predicable_short_it" "no")
5483 (set_attr "type" "logic_imm")]
5484 )
5485
5486 (define_expand "extendhisi2"
5487 [(set (match_operand:SI 0 "s_register_operand" "")
5488 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5489 "TARGET_EITHER"
5490 {
5491 if (TARGET_THUMB1)
5492 {
5493 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5494 DONE;
5495 }
5496 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5497 {
5498 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5499 DONE;
5500 }
5501
5502 if (!arm_arch6 && !MEM_P (operands[1]))
5503 {
5504 rtx t = gen_lowpart (SImode, operands[1]);
5505 rtx tmp = gen_reg_rtx (SImode);
5506 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5507 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5508 DONE;
5509 }
5510 })
5511
5512 (define_split
5513 [(parallel
5514 [(set (match_operand:SI 0 "register_operand" "")
5515 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5516 (clobber (match_scratch:SI 2 ""))])]
5517 "!arm_arch6"
5518 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5519 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5520 {
5521 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5522 })
5523
5524 ;; This pattern will only be used when ldsh is not available
5525 (define_expand "extendhisi2_mem"
5526 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5527 (set (match_dup 3)
5528 (zero_extend:SI (match_dup 7)))
5529 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5530 (set (match_operand:SI 0 "" "")
5531 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5532 "TARGET_ARM"
5533 "
5534 {
5535 rtx mem1, mem2;
5536 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5537
5538 mem1 = change_address (operands[1], QImode, addr);
5539 mem2 = change_address (operands[1], QImode,
5540 plus_constant (Pmode, addr, 1));
5541 operands[0] = gen_lowpart (SImode, operands[0]);
5542 operands[1] = mem1;
5543 operands[2] = gen_reg_rtx (SImode);
5544 operands[3] = gen_reg_rtx (SImode);
5545 operands[6] = gen_reg_rtx (SImode);
5546 operands[7] = mem2;
5547
5548 if (BYTES_BIG_ENDIAN)
5549 {
5550 operands[4] = operands[2];
5551 operands[5] = operands[3];
5552 }
5553 else
5554 {
5555 operands[4] = operands[3];
5556 operands[5] = operands[2];
5557 }
5558 }"
5559 )
5560
5561 (define_split
5562 [(set (match_operand:SI 0 "register_operand" "")
5563 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5564 "!arm_arch6"
5565 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5566 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5567 {
5568 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5569 })
5570
5571 (define_insn "*arm_extendhisi2"
5572 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5573 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5574 "TARGET_ARM && arm_arch4 && !arm_arch6"
5575 "@
5576 #
5577 ldrsh%?\\t%0, %1"
5578 [(set_attr "length" "8,4")
5579 (set_attr "type" "alu_shift_reg,load_byte")
5580 (set_attr "predicable" "yes")]
5581 )
5582
5583 ;; ??? Check Thumb-2 pool range
5584 (define_insn "*arm_extendhisi2_v6"
5585 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5586 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5587 "TARGET_32BIT && arm_arch6"
5588 "@
5589 sxth%?\\t%0, %1
5590 ldrsh%?\\t%0, %1"
5591 [(set_attr "type" "extend,load_byte")
5592 (set_attr "predicable" "yes")
5593 (set_attr "predicable_short_it" "no")]
5594 )
5595
5596 (define_insn "*arm_extendhisi2addsi"
5597 [(set (match_operand:SI 0 "s_register_operand" "=r")
5598 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5599 (match_operand:SI 2 "s_register_operand" "r")))]
5600 "TARGET_INT_SIMD"
5601 "sxtah%?\\t%0, %2, %1"
5602 [(set_attr "type" "alu_shift_reg")]
5603 )
5604
5605 (define_expand "extendqihi2"
5606 [(set (match_dup 2)
5607 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5608 (const_int 24)))
5609 (set (match_operand:HI 0 "s_register_operand" "")
5610 (ashiftrt:SI (match_dup 2)
5611 (const_int 24)))]
5612 "TARGET_ARM"
5613 "
5614 {
5615 if (arm_arch4 && MEM_P (operands[1]))
5616 {
5617 emit_insn (gen_rtx_SET (operands[0],
5618 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5619 DONE;
5620 }
5621 if (!s_register_operand (operands[1], QImode))
5622 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5623 operands[0] = gen_lowpart (SImode, operands[0]);
5624 operands[1] = gen_lowpart (SImode, operands[1]);
5625 operands[2] = gen_reg_rtx (SImode);
5626 }"
5627 )
5628
5629 (define_insn "*arm_extendqihi_insn"
5630 [(set (match_operand:HI 0 "s_register_operand" "=r")
5631 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5632 "TARGET_ARM && arm_arch4"
5633 "ldrsb%?\\t%0, %1"
5634 [(set_attr "type" "load_byte")
5635 (set_attr "predicable" "yes")]
5636 )
5637
5638 (define_expand "extendqisi2"
5639 [(set (match_operand:SI 0 "s_register_operand" "")
5640 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5641 "TARGET_EITHER"
5642 {
5643 if (!arm_arch4 && MEM_P (operands[1]))
5644 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5645
5646 if (!arm_arch6 && !MEM_P (operands[1]))
5647 {
5648 rtx t = gen_lowpart (SImode, operands[1]);
5649 rtx tmp = gen_reg_rtx (SImode);
5650 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5651 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5652 DONE;
5653 }
5654 })
5655
5656 (define_split
5657 [(set (match_operand:SI 0 "register_operand" "")
5658 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5659 "!arm_arch6"
5660 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5661 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5662 {
5663 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5664 })
5665
5666 (define_insn "*arm_extendqisi"
5667 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5668 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5669 "TARGET_ARM && arm_arch4 && !arm_arch6"
5670 "@
5671 #
5672 ldrsb%?\\t%0, %1"
5673 [(set_attr "length" "8,4")
5674 (set_attr "type" "alu_shift_reg,load_byte")
5675 (set_attr "predicable" "yes")]
5676 )
5677
5678 (define_insn "*arm_extendqisi_v6"
5679 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5680 (sign_extend:SI
5681 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5682 "TARGET_ARM && arm_arch6"
5683 "@
5684 sxtb%?\\t%0, %1
5685 ldrsb%?\\t%0, %1"
5686 [(set_attr "type" "extend,load_byte")
5687 (set_attr "predicable" "yes")]
5688 )
5689
5690 (define_insn "*arm_extendqisi2addsi"
5691 [(set (match_operand:SI 0 "s_register_operand" "=r")
5692 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5693 (match_operand:SI 2 "s_register_operand" "r")))]
5694 "TARGET_INT_SIMD"
5695 "sxtab%?\\t%0, %2, %1"
5696 [(set_attr "type" "alu_shift_reg")
5697 (set_attr "predicable" "yes")
5698 (set_attr "predicable_short_it" "no")]
5699 )
5700
5701 (define_expand "extendsfdf2"
5702 [(set (match_operand:DF 0 "s_register_operand" "")
5703 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5704 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5705 ""
5706 )
5707
5708 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5709 ;; must go through SFmode.
5710 ;;
5711 ;; This is always safe for an extend.
5712
5713 (define_expand "extendhfdf2"
5714 [(set (match_operand:DF 0 "s_register_operand" "")
5715 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5716 "TARGET_EITHER"
5717 {
5718 /* We don't have a direct instruction for this, so go via SFmode. */
5719 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5720 {
5721 rtx op1;
5722 op1 = convert_to_mode (SFmode, operands[1], 0);
5723 op1 = convert_to_mode (DFmode, op1, 0);
5724 emit_insn (gen_movdf (operands[0], op1));
5725 DONE;
5726 }
5727 /* Otherwise, we're done producing RTL and will pick up the correct
5728 pattern to do this with one rounding-step in a single instruction. */
5729 }
5730 )
5731 \f
5732 ;; Move insns (including loads and stores)
5733
5734 ;; XXX Just some ideas about movti.
5735 ;; I don't think these are a good idea on the arm, there just aren't enough
5736 ;; registers
5737 ;;(define_expand "loadti"
5738 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5739 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5740 ;; "" "")
5741
5742 ;;(define_expand "storeti"
5743 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5744 ;; (match_operand:TI 1 "s_register_operand" ""))]
5745 ;; "" "")
5746
5747 ;;(define_expand "movti"
5748 ;; [(set (match_operand:TI 0 "general_operand" "")
5749 ;; (match_operand:TI 1 "general_operand" ""))]
5750 ;; ""
5751 ;; "
5752 ;;{
5753 ;; rtx insn;
5754 ;;
5755 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5756 ;; operands[1] = copy_to_reg (operands[1]);
5757 ;; if (MEM_P (operands[0]))
5758 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5759 ;; else if (MEM_P (operands[1]))
5760 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5761 ;; else
5762 ;; FAIL;
5763 ;;
5764 ;; emit_insn (insn);
5765 ;; DONE;
5766 ;;}")
5767
5768 ;; Recognize garbage generated above.
5769
5770 ;;(define_insn ""
5771 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5772 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5773 ;; ""
5774 ;; "*
5775 ;; {
5776 ;; register mem = (which_alternative < 3);
5777 ;; register const char *template;
5778 ;;
5779 ;; operands[mem] = XEXP (operands[mem], 0);
5780 ;; switch (which_alternative)
5781 ;; {
5782 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5783 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5784 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5785 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5786 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5787 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5788 ;; }
5789 ;; output_asm_insn (template, operands);
5790 ;; return \"\";
5791 ;; }")
5792
5793 (define_expand "movdi"
5794 [(set (match_operand:DI 0 "general_operand" "")
5795 (match_operand:DI 1 "general_operand" ""))]
5796 "TARGET_EITHER"
5797 "
5798 if (can_create_pseudo_p ())
5799 {
5800 if (!REG_P (operands[0]))
5801 operands[1] = force_reg (DImode, operands[1]);
5802 }
5803 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5804 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5805 {
5806 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5807 when expanding function calls. */
5808 gcc_assert (can_create_pseudo_p ());
5809 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5810 {
5811 /* Perform load into legal reg pair first, then move. */
5812 rtx reg = gen_reg_rtx (DImode);
5813 emit_insn (gen_movdi (reg, operands[1]));
5814 operands[1] = reg;
5815 }
5816 emit_move_insn (gen_lowpart (SImode, operands[0]),
5817 gen_lowpart (SImode, operands[1]));
5818 emit_move_insn (gen_highpart (SImode, operands[0]),
5819 gen_highpart (SImode, operands[1]));
5820 DONE;
5821 }
5822 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5823 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5824 {
5825 /* Avoid STRD's from an odd-numbered register pair in ARM state
5826 when expanding function prologue. */
5827 gcc_assert (can_create_pseudo_p ());
5828 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5829 ? gen_reg_rtx (DImode)
5830 : operands[0];
5831 emit_move_insn (gen_lowpart (SImode, split_dest),
5832 gen_lowpart (SImode, operands[1]));
5833 emit_move_insn (gen_highpart (SImode, split_dest),
5834 gen_highpart (SImode, operands[1]));
5835 if (split_dest != operands[0])
5836 emit_insn (gen_movdi (operands[0], split_dest));
5837 DONE;
5838 }
5839 "
5840 )
5841
5842 (define_insn "*arm_movdi"
5843 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5844 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5845 "TARGET_32BIT
5846 && !(TARGET_HARD_FLOAT)
5847 && !TARGET_IWMMXT
5848 && ( register_operand (operands[0], DImode)
5849 || register_operand (operands[1], DImode))"
5850 "*
5851 switch (which_alternative)
5852 {
5853 case 0:
5854 case 1:
5855 case 2:
5856 return \"#\";
5857 default:
5858 return output_move_double (operands, true, NULL);
5859 }
5860 "
5861 [(set_attr "length" "8,12,16,8,8")
5862 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5863 (set_attr "arm_pool_range" "*,*,*,1020,*")
5864 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5865 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5866 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5867 )
5868
5869 (define_split
5870 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5871 (match_operand:ANY64 1 "immediate_operand" ""))]
5872 "TARGET_32BIT
5873 && reload_completed
5874 && (arm_const_double_inline_cost (operands[1])
5875 <= arm_max_const_double_inline_cost ())"
5876 [(const_int 0)]
5877 "
5878 arm_split_constant (SET, SImode, curr_insn,
5879 INTVAL (gen_lowpart (SImode, operands[1])),
5880 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5881 arm_split_constant (SET, SImode, curr_insn,
5882 INTVAL (gen_highpart_mode (SImode,
5883 GET_MODE (operands[0]),
5884 operands[1])),
5885 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5886 DONE;
5887 "
5888 )
5889
5890 ; If optimizing for size, or if we have load delay slots, then
5891 ; we want to split the constant into two separate operations.
5892 ; In both cases this may split a trivial part into a single data op
5893 ; leaving a single complex constant to load. We can also get longer
5894 ; offsets in a LDR which means we get better chances of sharing the pool
5895 ; entries. Finally, we can normally do a better job of scheduling
5896 ; LDR instructions than we can with LDM.
5897 ; This pattern will only match if the one above did not.
5898 (define_split
5899 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5900 (match_operand:ANY64 1 "const_double_operand" ""))]
5901 "TARGET_ARM && reload_completed
5902 && arm_const_double_by_parts (operands[1])"
5903 [(set (match_dup 0) (match_dup 1))
5904 (set (match_dup 2) (match_dup 3))]
5905 "
5906 operands[2] = gen_highpart (SImode, operands[0]);
5907 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5908 operands[1]);
5909 operands[0] = gen_lowpart (SImode, operands[0]);
5910 operands[1] = gen_lowpart (SImode, operands[1]);
5911 "
5912 )
5913
5914 (define_split
5915 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5916 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5917 "TARGET_EITHER && reload_completed"
5918 [(set (match_dup 0) (match_dup 1))
5919 (set (match_dup 2) (match_dup 3))]
5920 "
5921 operands[2] = gen_highpart (SImode, operands[0]);
5922 operands[3] = gen_highpart (SImode, operands[1]);
5923 operands[0] = gen_lowpart (SImode, operands[0]);
5924 operands[1] = gen_lowpart (SImode, operands[1]);
5925
5926 /* Handle a partial overlap. */
5927 if (rtx_equal_p (operands[0], operands[3]))
5928 {
5929 rtx tmp0 = operands[0];
5930 rtx tmp1 = operands[1];
5931
5932 operands[0] = operands[2];
5933 operands[1] = operands[3];
5934 operands[2] = tmp0;
5935 operands[3] = tmp1;
5936 }
5937 "
5938 )
5939
5940 ;; We can't actually do base+index doubleword loads if the index and
5941 ;; destination overlap. Split here so that we at least have chance to
5942 ;; schedule.
5943 (define_split
5944 [(set (match_operand:DI 0 "s_register_operand" "")
5945 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5946 (match_operand:SI 2 "s_register_operand" ""))))]
5947 "TARGET_LDRD
5948 && reg_overlap_mentioned_p (operands[0], operands[1])
5949 && reg_overlap_mentioned_p (operands[0], operands[2])"
5950 [(set (match_dup 4)
5951 (plus:SI (match_dup 1)
5952 (match_dup 2)))
5953 (set (match_dup 0)
5954 (mem:DI (match_dup 4)))]
5955 "
5956 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5957 "
5958 )
5959
5960 (define_expand "movsi"
5961 [(set (match_operand:SI 0 "general_operand" "")
5962 (match_operand:SI 1 "general_operand" ""))]
5963 "TARGET_EITHER"
5964 "
5965 {
5966 rtx base, offset, tmp;
5967
5968 if (TARGET_32BIT)
5969 {
5970 /* Everything except mem = const or mem = mem can be done easily. */
5971 if (MEM_P (operands[0]))
5972 operands[1] = force_reg (SImode, operands[1]);
5973 if (arm_general_register_operand (operands[0], SImode)
5974 && CONST_INT_P (operands[1])
5975 && !(const_ok_for_arm (INTVAL (operands[1]))
5976 || const_ok_for_arm (~INTVAL (operands[1]))))
5977 {
5978 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5979 {
5980 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5981 DONE;
5982 }
5983 else
5984 {
5985 arm_split_constant (SET, SImode, NULL_RTX,
5986 INTVAL (operands[1]), operands[0], NULL_RTX,
5987 optimize && can_create_pseudo_p ());
5988 DONE;
5989 }
5990 }
5991 }
5992 else /* TARGET_THUMB1... */
5993 {
5994 if (can_create_pseudo_p ())
5995 {
5996 if (!REG_P (operands[0]))
5997 operands[1] = force_reg (SImode, operands[1]);
5998 }
5999 }
6000
6001 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6002 {
6003 split_const (operands[1], &base, &offset);
6004 if (GET_CODE (base) == SYMBOL_REF
6005 && !offset_within_block_p (base, INTVAL (offset)))
6006 {
6007 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6008 emit_move_insn (tmp, base);
6009 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6010 DONE;
6011 }
6012 }
6013
6014 /* Recognize the case where operand[1] is a reference to thread-local
6015 data and load its address to a register. */
6016 if (arm_tls_referenced_p (operands[1]))
6017 {
6018 rtx tmp = operands[1];
6019 rtx addend = NULL;
6020
6021 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6022 {
6023 addend = XEXP (XEXP (tmp, 0), 1);
6024 tmp = XEXP (XEXP (tmp, 0), 0);
6025 }
6026
6027 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6028 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6029
6030 tmp = legitimize_tls_address (tmp,
6031 !can_create_pseudo_p () ? operands[0] : 0);
6032 if (addend)
6033 {
6034 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6035 tmp = force_operand (tmp, operands[0]);
6036 }
6037 operands[1] = tmp;
6038 }
6039 else if (flag_pic
6040 && (CONSTANT_P (operands[1])
6041 || symbol_mentioned_p (operands[1])
6042 || label_mentioned_p (operands[1])))
6043 operands[1] = legitimize_pic_address (operands[1], SImode,
6044 (!can_create_pseudo_p ()
6045 ? operands[0]
6046 : 0));
6047 }
6048 "
6049 )
6050
6051 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6052 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6053 ;; so this does not matter.
6054 (define_insn "*arm_movt"
6055 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6056 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6057 (match_operand:SI 2 "general_operand" "i,i")))]
6058 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6059 "@
6060 movt%?\t%0, #:upper16:%c2
6061 movt\t%0, #:upper16:%c2"
6062 [(set_attr "arch" "32,v8mb")
6063 (set_attr "predicable" "yes")
6064 (set_attr "predicable_short_it" "no")
6065 (set_attr "length" "4")
6066 (set_attr "type" "alu_sreg")]
6067 )
6068
6069 (define_insn "*arm_movsi_insn"
6070 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6071 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6072 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6073 && ( register_operand (operands[0], SImode)
6074 || register_operand (operands[1], SImode))"
6075 "@
6076 mov%?\\t%0, %1
6077 mov%?\\t%0, %1
6078 mvn%?\\t%0, #%B1
6079 movw%?\\t%0, %1
6080 ldr%?\\t%0, %1
6081 str%?\\t%1, %0"
6082 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6083 (set_attr "predicable" "yes")
6084 (set_attr "arch" "*,*,*,v6t2,*,*")
6085 (set_attr "pool_range" "*,*,*,*,4096,*")
6086 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6087 )
6088
6089 (define_split
6090 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6091 (match_operand:SI 1 "const_int_operand" ""))]
6092 "TARGET_32BIT
6093 && (!(const_ok_for_arm (INTVAL (operands[1]))
6094 || const_ok_for_arm (~INTVAL (operands[1]))))"
6095 [(clobber (const_int 0))]
6096 "
6097 arm_split_constant (SET, SImode, NULL_RTX,
6098 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6099 DONE;
6100 "
6101 )
6102
6103 ;; A normal way to do (symbol + offset) requires three instructions at least
6104 ;; (depends on how big the offset is) as below:
6105 ;; movw r0, #:lower16:g
6106 ;; movw r0, #:upper16:g
6107 ;; adds r0, #4
6108 ;;
6109 ;; A better way would be:
6110 ;; movw r0, #:lower16:g+4
6111 ;; movw r0, #:upper16:g+4
6112 ;;
6113 ;; The limitation of this way is that the length of offset should be a 16-bit
6114 ;; signed value, because current assembler only supports REL type relocation for
6115 ;; such case. If the more powerful RELA type is supported in future, we should
6116 ;; update this pattern to go with better way.
6117 (define_split
6118 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6119 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6120 (match_operand:SI 2 "const_int_operand" ""))))]
6121 "TARGET_THUMB
6122 && TARGET_HAVE_MOVT
6123 && arm_disable_literal_pool
6124 && reload_completed
6125 && GET_CODE (operands[1]) == SYMBOL_REF"
6126 [(clobber (const_int 0))]
6127 "
6128 int offset = INTVAL (operands[2]);
6129
6130 if (offset < -0x8000 || offset > 0x7fff)
6131 {
6132 arm_emit_movpair (operands[0], operands[1]);
6133 emit_insn (gen_rtx_SET (operands[0],
6134 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6135 }
6136 else
6137 {
6138 rtx op = gen_rtx_CONST (SImode,
6139 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6140 arm_emit_movpair (operands[0], op);
6141 }
6142 "
6143 )
6144
6145 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6146 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6147 ;; and lo_sum would be merged back into memory load at cprop. However,
6148 ;; if the default is to prefer movt/movw rather than a load from the constant
6149 ;; pool, the performance is better.
6150 (define_split
6151 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6152 (match_operand:SI 1 "general_operand" ""))]
6153 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6154 && !flag_pic && !target_word_relocations
6155 && !arm_tls_referenced_p (operands[1])"
6156 [(clobber (const_int 0))]
6157 {
6158 arm_emit_movpair (operands[0], operands[1]);
6159 DONE;
6160 })
6161
6162 ;; When generating pic, we need to load the symbol offset into a register.
6163 ;; So that the optimizer does not confuse this with a normal symbol load
6164 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6165 ;; since that is the only type of relocation we can use.
6166
6167 ;; Wrap calculation of the whole PIC address in a single pattern for the
6168 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6169 ;; a PIC address involves two loads from memory, so we want to CSE it
6170 ;; as often as possible.
6171 ;; This pattern will be split into one of the pic_load_addr_* patterns
6172 ;; and a move after GCSE optimizations.
6173 ;;
6174 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6175 (define_expand "calculate_pic_address"
6176 [(set (match_operand:SI 0 "register_operand" "")
6177 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6178 (unspec:SI [(match_operand:SI 2 "" "")]
6179 UNSPEC_PIC_SYM))))]
6180 "flag_pic"
6181 )
6182
6183 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6184 (define_split
6185 [(set (match_operand:SI 0 "register_operand" "")
6186 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6187 (unspec:SI [(match_operand:SI 2 "" "")]
6188 UNSPEC_PIC_SYM))))]
6189 "flag_pic"
6190 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6191 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6192 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6193 )
6194
6195 ;; operand1 is the memory address to go into
6196 ;; pic_load_addr_32bit.
6197 ;; operand2 is the PIC label to be emitted
6198 ;; from pic_add_dot_plus_eight.
6199 ;; We do this to allow hoisting of the entire insn.
6200 (define_insn_and_split "pic_load_addr_unified"
6201 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6202 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6203 (match_operand:SI 2 "" "")]
6204 UNSPEC_PIC_UNIFIED))]
6205 "flag_pic"
6206 "#"
6207 "&& reload_completed"
6208 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6209 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6210 (match_dup 2)] UNSPEC_PIC_BASE))]
6211 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6212 [(set_attr "type" "load1,load1,load1")
6213 (set_attr "pool_range" "4096,4094,1022")
6214 (set_attr "neg_pool_range" "4084,0,0")
6215 (set_attr "arch" "a,t2,t1")
6216 (set_attr "length" "8,6,4")]
6217 )
6218
6219 ;; The rather odd constraints on the following are to force reload to leave
6220 ;; the insn alone, and to force the minipool generation pass to then move
6221 ;; the GOT symbol to memory.
6222
6223 (define_insn "pic_load_addr_32bit"
6224 [(set (match_operand:SI 0 "s_register_operand" "=r")
6225 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6226 "TARGET_32BIT && flag_pic"
6227 "ldr%?\\t%0, %1"
6228 [(set_attr "type" "load1")
6229 (set (attr "pool_range")
6230 (if_then_else (eq_attr "is_thumb" "no")
6231 (const_int 4096)
6232 (const_int 4094)))
6233 (set (attr "neg_pool_range")
6234 (if_then_else (eq_attr "is_thumb" "no")
6235 (const_int 4084)
6236 (const_int 0)))]
6237 )
6238
6239 (define_insn "pic_load_addr_thumb1"
6240 [(set (match_operand:SI 0 "s_register_operand" "=l")
6241 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6242 "TARGET_THUMB1 && flag_pic"
6243 "ldr\\t%0, %1"
6244 [(set_attr "type" "load1")
6245 (set (attr "pool_range") (const_int 1018))]
6246 )
6247
6248 (define_insn "pic_add_dot_plus_four"
6249 [(set (match_operand:SI 0 "register_operand" "=r")
6250 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6251 (const_int 4)
6252 (match_operand 2 "" "")]
6253 UNSPEC_PIC_BASE))]
6254 "TARGET_THUMB"
6255 "*
6256 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6257 INTVAL (operands[2]));
6258 return \"add\\t%0, %|pc\";
6259 "
6260 [(set_attr "length" "2")
6261 (set_attr "type" "alu_sreg")]
6262 )
6263
6264 (define_insn "pic_add_dot_plus_eight"
6265 [(set (match_operand:SI 0 "register_operand" "=r")
6266 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6267 (const_int 8)
6268 (match_operand 2 "" "")]
6269 UNSPEC_PIC_BASE))]
6270 "TARGET_ARM"
6271 "*
6272 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6273 INTVAL (operands[2]));
6274 return \"add%?\\t%0, %|pc, %1\";
6275 "
6276 [(set_attr "predicable" "yes")
6277 (set_attr "type" "alu_sreg")]
6278 )
6279
6280 (define_insn "tls_load_dot_plus_eight"
6281 [(set (match_operand:SI 0 "register_operand" "=r")
6282 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6283 (const_int 8)
6284 (match_operand 2 "" "")]
6285 UNSPEC_PIC_BASE)))]
6286 "TARGET_ARM"
6287 "*
6288 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6289 INTVAL (operands[2]));
6290 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6291 "
6292 [(set_attr "predicable" "yes")
6293 (set_attr "type" "load1")]
6294 )
6295
6296 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6297 ;; followed by a load. These sequences can be crunched down to
6298 ;; tls_load_dot_plus_eight by a peephole.
6299
6300 (define_peephole2
6301 [(set (match_operand:SI 0 "register_operand" "")
6302 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6303 (const_int 8)
6304 (match_operand 1 "" "")]
6305 UNSPEC_PIC_BASE))
6306 (set (match_operand:SI 2 "arm_general_register_operand" "")
6307 (mem:SI (match_dup 0)))]
6308 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6309 [(set (match_dup 2)
6310 (mem:SI (unspec:SI [(match_dup 3)
6311 (const_int 8)
6312 (match_dup 1)]
6313 UNSPEC_PIC_BASE)))]
6314 ""
6315 )
6316
6317 (define_insn "pic_offset_arm"
6318 [(set (match_operand:SI 0 "register_operand" "=r")
6319 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6320 (unspec:SI [(match_operand:SI 2 "" "X")]
6321 UNSPEC_PIC_OFFSET))))]
6322 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6323 "ldr%?\\t%0, [%1,%2]"
6324 [(set_attr "type" "load1")]
6325 )
6326
6327 (define_expand "builtin_setjmp_receiver"
6328 [(label_ref (match_operand 0 "" ""))]
6329 "flag_pic"
6330 "
6331 {
6332 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6333 register. */
6334 if (arm_pic_register != INVALID_REGNUM)
6335 arm_load_pic_register (1UL << 3);
6336 DONE;
6337 }")
6338
6339 ;; If copying one reg to another we can set the condition codes according to
6340 ;; its value. Such a move is common after a return from subroutine and the
6341 ;; result is being tested against zero.
6342
6343 (define_insn "*movsi_compare0"
6344 [(set (reg:CC CC_REGNUM)
6345 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6346 (const_int 0)))
6347 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6348 (match_dup 1))]
6349 "TARGET_32BIT"
6350 "@
6351 cmp%?\\t%0, #0
6352 subs%?\\t%0, %1, #0"
6353 [(set_attr "conds" "set")
6354 (set_attr "type" "alus_imm,alus_imm")]
6355 )
6356
6357 ;; Subroutine to store a half word from a register into memory.
6358 ;; Operand 0 is the source register (HImode)
6359 ;; Operand 1 is the destination address in a register (SImode)
6360
6361 ;; In both this routine and the next, we must be careful not to spill
6362 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6363 ;; can generate unrecognizable rtl.
6364
6365 (define_expand "storehi"
6366 [;; store the low byte
6367 (set (match_operand 1 "" "") (match_dup 3))
6368 ;; extract the high byte
6369 (set (match_dup 2)
6370 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6371 ;; store the high byte
6372 (set (match_dup 4) (match_dup 5))]
6373 "TARGET_ARM"
6374 "
6375 {
6376 rtx op1 = operands[1];
6377 rtx addr = XEXP (op1, 0);
6378 enum rtx_code code = GET_CODE (addr);
6379
6380 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6381 || code == MINUS)
6382 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6383
6384 operands[4] = adjust_address (op1, QImode, 1);
6385 operands[1] = adjust_address (operands[1], QImode, 0);
6386 operands[3] = gen_lowpart (QImode, operands[0]);
6387 operands[0] = gen_lowpart (SImode, operands[0]);
6388 operands[2] = gen_reg_rtx (SImode);
6389 operands[5] = gen_lowpart (QImode, operands[2]);
6390 }"
6391 )
6392
6393 (define_expand "storehi_bigend"
6394 [(set (match_dup 4) (match_dup 3))
6395 (set (match_dup 2)
6396 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6397 (set (match_operand 1 "" "") (match_dup 5))]
6398 "TARGET_ARM"
6399 "
6400 {
6401 rtx op1 = operands[1];
6402 rtx addr = XEXP (op1, 0);
6403 enum rtx_code code = GET_CODE (addr);
6404
6405 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6406 || code == MINUS)
6407 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6408
6409 operands[4] = adjust_address (op1, QImode, 1);
6410 operands[1] = adjust_address (operands[1], QImode, 0);
6411 operands[3] = gen_lowpart (QImode, operands[0]);
6412 operands[0] = gen_lowpart (SImode, operands[0]);
6413 operands[2] = gen_reg_rtx (SImode);
6414 operands[5] = gen_lowpart (QImode, operands[2]);
6415 }"
6416 )
6417
6418 ;; Subroutine to store a half word integer constant into memory.
6419 (define_expand "storeinthi"
6420 [(set (match_operand 0 "" "")
6421 (match_operand 1 "" ""))
6422 (set (match_dup 3) (match_dup 2))]
6423 "TARGET_ARM"
6424 "
6425 {
6426 HOST_WIDE_INT value = INTVAL (operands[1]);
6427 rtx addr = XEXP (operands[0], 0);
6428 rtx op0 = operands[0];
6429 enum rtx_code code = GET_CODE (addr);
6430
6431 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6432 || code == MINUS)
6433 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6434
6435 operands[1] = gen_reg_rtx (SImode);
6436 if (BYTES_BIG_ENDIAN)
6437 {
6438 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6439 if ((value & 255) == ((value >> 8) & 255))
6440 operands[2] = operands[1];
6441 else
6442 {
6443 operands[2] = gen_reg_rtx (SImode);
6444 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6445 }
6446 }
6447 else
6448 {
6449 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6450 if ((value & 255) == ((value >> 8) & 255))
6451 operands[2] = operands[1];
6452 else
6453 {
6454 operands[2] = gen_reg_rtx (SImode);
6455 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6456 }
6457 }
6458
6459 operands[3] = adjust_address (op0, QImode, 1);
6460 operands[0] = adjust_address (operands[0], QImode, 0);
6461 operands[2] = gen_lowpart (QImode, operands[2]);
6462 operands[1] = gen_lowpart (QImode, operands[1]);
6463 }"
6464 )
6465
6466 (define_expand "storehi_single_op"
6467 [(set (match_operand:HI 0 "memory_operand" "")
6468 (match_operand:HI 1 "general_operand" ""))]
6469 "TARGET_32BIT && arm_arch4"
6470 "
6471 if (!s_register_operand (operands[1], HImode))
6472 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6473 "
6474 )
6475
6476 (define_expand "movhi"
6477 [(set (match_operand:HI 0 "general_operand" "")
6478 (match_operand:HI 1 "general_operand" ""))]
6479 "TARGET_EITHER"
6480 "
6481 if (TARGET_ARM)
6482 {
6483 if (can_create_pseudo_p ())
6484 {
6485 if (MEM_P (operands[0]))
6486 {
6487 if (arm_arch4)
6488 {
6489 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6490 DONE;
6491 }
6492 if (CONST_INT_P (operands[1]))
6493 emit_insn (gen_storeinthi (operands[0], operands[1]));
6494 else
6495 {
6496 if (MEM_P (operands[1]))
6497 operands[1] = force_reg (HImode, operands[1]);
6498 if (BYTES_BIG_ENDIAN)
6499 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6500 else
6501 emit_insn (gen_storehi (operands[1], operands[0]));
6502 }
6503 DONE;
6504 }
6505 /* Sign extend a constant, and keep it in an SImode reg. */
6506 else if (CONST_INT_P (operands[1]))
6507 {
6508 rtx reg = gen_reg_rtx (SImode);
6509 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6510
6511 /* If the constant is already valid, leave it alone. */
6512 if (!const_ok_for_arm (val))
6513 {
6514 /* If setting all the top bits will make the constant
6515 loadable in a single instruction, then set them.
6516 Otherwise, sign extend the number. */
6517
6518 if (const_ok_for_arm (~(val | ~0xffff)))
6519 val |= ~0xffff;
6520 else if (val & 0x8000)
6521 val |= ~0xffff;
6522 }
6523
6524 emit_insn (gen_movsi (reg, GEN_INT (val)));
6525 operands[1] = gen_lowpart (HImode, reg);
6526 }
6527 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6528 && MEM_P (operands[1]))
6529 {
6530 rtx reg = gen_reg_rtx (SImode);
6531
6532 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6533 operands[1] = gen_lowpart (HImode, reg);
6534 }
6535 else if (!arm_arch4)
6536 {
6537 if (MEM_P (operands[1]))
6538 {
6539 rtx base;
6540 rtx offset = const0_rtx;
6541 rtx reg = gen_reg_rtx (SImode);
6542
6543 if ((REG_P (base = XEXP (operands[1], 0))
6544 || (GET_CODE (base) == PLUS
6545 && (CONST_INT_P (offset = XEXP (base, 1)))
6546 && ((INTVAL(offset) & 1) != 1)
6547 && REG_P (base = XEXP (base, 0))))
6548 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6549 {
6550 rtx new_rtx;
6551
6552 new_rtx = widen_memory_access (operands[1], SImode,
6553 ((INTVAL (offset) & ~3)
6554 - INTVAL (offset)));
6555 emit_insn (gen_movsi (reg, new_rtx));
6556 if (((INTVAL (offset) & 2) != 0)
6557 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6558 {
6559 rtx reg2 = gen_reg_rtx (SImode);
6560
6561 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6562 reg = reg2;
6563 }
6564 }
6565 else
6566 emit_insn (gen_movhi_bytes (reg, operands[1]));
6567
6568 operands[1] = gen_lowpart (HImode, reg);
6569 }
6570 }
6571 }
6572 /* Handle loading a large integer during reload. */
6573 else if (CONST_INT_P (operands[1])
6574 && !const_ok_for_arm (INTVAL (operands[1]))
6575 && !const_ok_for_arm (~INTVAL (operands[1])))
6576 {
6577 /* Writing a constant to memory needs a scratch, which should
6578 be handled with SECONDARY_RELOADs. */
6579 gcc_assert (REG_P (operands[0]));
6580
6581 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6582 emit_insn (gen_movsi (operands[0], operands[1]));
6583 DONE;
6584 }
6585 }
6586 else if (TARGET_THUMB2)
6587 {
6588 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6589 if (can_create_pseudo_p ())
6590 {
6591 if (!REG_P (operands[0]))
6592 operands[1] = force_reg (HImode, operands[1]);
6593 /* Zero extend a constant, and keep it in an SImode reg. */
6594 else if (CONST_INT_P (operands[1]))
6595 {
6596 rtx reg = gen_reg_rtx (SImode);
6597 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6598
6599 emit_insn (gen_movsi (reg, GEN_INT (val)));
6600 operands[1] = gen_lowpart (HImode, reg);
6601 }
6602 }
6603 }
6604 else /* TARGET_THUMB1 */
6605 {
6606 if (can_create_pseudo_p ())
6607 {
6608 if (CONST_INT_P (operands[1]))
6609 {
6610 rtx reg = gen_reg_rtx (SImode);
6611
6612 emit_insn (gen_movsi (reg, operands[1]));
6613 operands[1] = gen_lowpart (HImode, reg);
6614 }
6615
6616 /* ??? We shouldn't really get invalid addresses here, but this can
6617 happen if we are passed a SP (never OK for HImode/QImode) or
6618 virtual register (also rejected as illegitimate for HImode/QImode)
6619 relative address. */
6620 /* ??? This should perhaps be fixed elsewhere, for instance, in
6621 fixup_stack_1, by checking for other kinds of invalid addresses,
6622 e.g. a bare reference to a virtual register. This may confuse the
6623 alpha though, which must handle this case differently. */
6624 if (MEM_P (operands[0])
6625 && !memory_address_p (GET_MODE (operands[0]),
6626 XEXP (operands[0], 0)))
6627 operands[0]
6628 = replace_equiv_address (operands[0],
6629 copy_to_reg (XEXP (operands[0], 0)));
6630
6631 if (MEM_P (operands[1])
6632 && !memory_address_p (GET_MODE (operands[1]),
6633 XEXP (operands[1], 0)))
6634 operands[1]
6635 = replace_equiv_address (operands[1],
6636 copy_to_reg (XEXP (operands[1], 0)));
6637
6638 if (MEM_P (operands[1]) && optimize > 0)
6639 {
6640 rtx reg = gen_reg_rtx (SImode);
6641
6642 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6643 operands[1] = gen_lowpart (HImode, reg);
6644 }
6645
6646 if (MEM_P (operands[0]))
6647 operands[1] = force_reg (HImode, operands[1]);
6648 }
6649 else if (CONST_INT_P (operands[1])
6650 && !satisfies_constraint_I (operands[1]))
6651 {
6652 /* Handle loading a large integer during reload. */
6653
6654 /* Writing a constant to memory needs a scratch, which should
6655 be handled with SECONDARY_RELOADs. */
6656 gcc_assert (REG_P (operands[0]));
6657
6658 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6659 emit_insn (gen_movsi (operands[0], operands[1]));
6660 DONE;
6661 }
6662 }
6663 "
6664 )
6665
6666 (define_expand "movhi_bytes"
6667 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6668 (set (match_dup 3)
6669 (zero_extend:SI (match_dup 6)))
6670 (set (match_operand:SI 0 "" "")
6671 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6672 "TARGET_ARM"
6673 "
6674 {
6675 rtx mem1, mem2;
6676 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6677
6678 mem1 = change_address (operands[1], QImode, addr);
6679 mem2 = change_address (operands[1], QImode,
6680 plus_constant (Pmode, addr, 1));
6681 operands[0] = gen_lowpart (SImode, operands[0]);
6682 operands[1] = mem1;
6683 operands[2] = gen_reg_rtx (SImode);
6684 operands[3] = gen_reg_rtx (SImode);
6685 operands[6] = mem2;
6686
6687 if (BYTES_BIG_ENDIAN)
6688 {
6689 operands[4] = operands[2];
6690 operands[5] = operands[3];
6691 }
6692 else
6693 {
6694 operands[4] = operands[3];
6695 operands[5] = operands[2];
6696 }
6697 }"
6698 )
6699
6700 (define_expand "movhi_bigend"
6701 [(set (match_dup 2)
6702 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6703 (const_int 16)))
6704 (set (match_dup 3)
6705 (ashiftrt:SI (match_dup 2) (const_int 16)))
6706 (set (match_operand:HI 0 "s_register_operand" "")
6707 (match_dup 4))]
6708 "TARGET_ARM"
6709 "
6710 operands[2] = gen_reg_rtx (SImode);
6711 operands[3] = gen_reg_rtx (SImode);
6712 operands[4] = gen_lowpart (HImode, operands[3]);
6713 "
6714 )
6715
6716 ;; Pattern to recognize insn generated default case above
6717 (define_insn "*movhi_insn_arch4"
6718 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6719 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6720 "TARGET_ARM
6721 && arm_arch4 && !TARGET_HARD_FLOAT
6722 && (register_operand (operands[0], HImode)
6723 || register_operand (operands[1], HImode))"
6724 "@
6725 mov%?\\t%0, %1\\t%@ movhi
6726 mvn%?\\t%0, #%B1\\t%@ movhi
6727 movw%?\\t%0, %L1\\t%@ movhi
6728 strh%?\\t%1, %0\\t%@ movhi
6729 ldrh%?\\t%0, %1\\t%@ movhi"
6730 [(set_attr "predicable" "yes")
6731 (set_attr "pool_range" "*,*,*,*,256")
6732 (set_attr "neg_pool_range" "*,*,*,*,244")
6733 (set_attr "arch" "*,*,v6t2,*,*")
6734 (set_attr_alternative "type"
6735 [(if_then_else (match_operand 1 "const_int_operand" "")
6736 (const_string "mov_imm" )
6737 (const_string "mov_reg"))
6738 (const_string "mvn_imm")
6739 (const_string "mov_imm")
6740 (const_string "store1")
6741 (const_string "load1")])]
6742 )
6743
6744 (define_insn "*movhi_bytes"
6745 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6746 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6747 "TARGET_ARM && !TARGET_HARD_FLOAT"
6748 "@
6749 mov%?\\t%0, %1\\t%@ movhi
6750 mov%?\\t%0, %1\\t%@ movhi
6751 mvn%?\\t%0, #%B1\\t%@ movhi"
6752 [(set_attr "predicable" "yes")
6753 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6754 )
6755
6756 ;; We use a DImode scratch because we may occasionally need an additional
6757 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6758 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6759 (define_expand "reload_outhi"
6760 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6761 (match_operand:HI 1 "s_register_operand" "r")
6762 (match_operand:DI 2 "s_register_operand" "=&l")])]
6763 "TARGET_EITHER"
6764 "if (TARGET_ARM)
6765 arm_reload_out_hi (operands);
6766 else
6767 thumb_reload_out_hi (operands);
6768 DONE;
6769 "
6770 )
6771
6772 (define_expand "reload_inhi"
6773 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6774 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6775 (match_operand:DI 2 "s_register_operand" "=&r")])]
6776 "TARGET_EITHER"
6777 "
6778 if (TARGET_ARM)
6779 arm_reload_in_hi (operands);
6780 else
6781 thumb_reload_out_hi (operands);
6782 DONE;
6783 ")
6784
6785 (define_expand "movqi"
6786 [(set (match_operand:QI 0 "general_operand" "")
6787 (match_operand:QI 1 "general_operand" ""))]
6788 "TARGET_EITHER"
6789 "
6790 /* Everything except mem = const or mem = mem can be done easily */
6791
6792 if (can_create_pseudo_p ())
6793 {
6794 if (CONST_INT_P (operands[1]))
6795 {
6796 rtx reg = gen_reg_rtx (SImode);
6797
6798 /* For thumb we want an unsigned immediate, then we are more likely
6799 to be able to use a movs insn. */
6800 if (TARGET_THUMB)
6801 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6802
6803 emit_insn (gen_movsi (reg, operands[1]));
6804 operands[1] = gen_lowpart (QImode, reg);
6805 }
6806
6807 if (TARGET_THUMB)
6808 {
6809 /* ??? We shouldn't really get invalid addresses here, but this can
6810 happen if we are passed a SP (never OK for HImode/QImode) or
6811 virtual register (also rejected as illegitimate for HImode/QImode)
6812 relative address. */
6813 /* ??? This should perhaps be fixed elsewhere, for instance, in
6814 fixup_stack_1, by checking for other kinds of invalid addresses,
6815 e.g. a bare reference to a virtual register. This may confuse the
6816 alpha though, which must handle this case differently. */
6817 if (MEM_P (operands[0])
6818 && !memory_address_p (GET_MODE (operands[0]),
6819 XEXP (operands[0], 0)))
6820 operands[0]
6821 = replace_equiv_address (operands[0],
6822 copy_to_reg (XEXP (operands[0], 0)));
6823 if (MEM_P (operands[1])
6824 && !memory_address_p (GET_MODE (operands[1]),
6825 XEXP (operands[1], 0)))
6826 operands[1]
6827 = replace_equiv_address (operands[1],
6828 copy_to_reg (XEXP (operands[1], 0)));
6829 }
6830
6831 if (MEM_P (operands[1]) && optimize > 0)
6832 {
6833 rtx reg = gen_reg_rtx (SImode);
6834
6835 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6836 operands[1] = gen_lowpart (QImode, reg);
6837 }
6838
6839 if (MEM_P (operands[0]))
6840 operands[1] = force_reg (QImode, operands[1]);
6841 }
6842 else if (TARGET_THUMB
6843 && CONST_INT_P (operands[1])
6844 && !satisfies_constraint_I (operands[1]))
6845 {
6846 /* Handle loading a large integer during reload. */
6847
6848 /* Writing a constant to memory needs a scratch, which should
6849 be handled with SECONDARY_RELOADs. */
6850 gcc_assert (REG_P (operands[0]));
6851
6852 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6853 emit_insn (gen_movsi (operands[0], operands[1]));
6854 DONE;
6855 }
6856 "
6857 )
6858
6859 (define_insn "*arm_movqi_insn"
6860 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6861 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6862 "TARGET_32BIT
6863 && ( register_operand (operands[0], QImode)
6864 || register_operand (operands[1], QImode))"
6865 "@
6866 mov%?\\t%0, %1
6867 mov%?\\t%0, %1
6868 mov%?\\t%0, %1
6869 mov%?\\t%0, %1
6870 mvn%?\\t%0, #%B1
6871 ldrb%?\\t%0, %1
6872 strb%?\\t%1, %0
6873 ldrb%?\\t%0, %1
6874 strb%?\\t%1, %0"
6875 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6876 (set_attr "predicable" "yes")
6877 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6878 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6879 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6880 )
6881
6882 ;; HFmode moves
6883 (define_expand "movhf"
6884 [(set (match_operand:HF 0 "general_operand" "")
6885 (match_operand:HF 1 "general_operand" ""))]
6886 "TARGET_EITHER"
6887 "
6888 if (TARGET_32BIT)
6889 {
6890 if (MEM_P (operands[0]))
6891 operands[1] = force_reg (HFmode, operands[1]);
6892 }
6893 else /* TARGET_THUMB1 */
6894 {
6895 if (can_create_pseudo_p ())
6896 {
6897 if (!REG_P (operands[0]))
6898 operands[1] = force_reg (HFmode, operands[1]);
6899 }
6900 }
6901 "
6902 )
6903
6904 (define_insn "*arm32_movhf"
6905 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6906 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6907 "TARGET_32BIT && !TARGET_HARD_FLOAT
6908 && ( s_register_operand (operands[0], HFmode)
6909 || s_register_operand (operands[1], HFmode))"
6910 "*
6911 switch (which_alternative)
6912 {
6913 case 0: /* ARM register from memory */
6914 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6915 case 1: /* memory from ARM register */
6916 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6917 case 2: /* ARM register from ARM register */
6918 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6919 case 3: /* ARM register from constant */
6920 {
6921 long bits;
6922 rtx ops[4];
6923
6924 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6925 HFmode);
6926 ops[0] = operands[0];
6927 ops[1] = GEN_INT (bits);
6928 ops[2] = GEN_INT (bits & 0xff00);
6929 ops[3] = GEN_INT (bits & 0x00ff);
6930
6931 if (arm_arch_thumb2)
6932 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6933 else
6934 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6935 return \"\";
6936 }
6937 default:
6938 gcc_unreachable ();
6939 }
6940 "
6941 [(set_attr "conds" "unconditional")
6942 (set_attr "type" "load1,store1,mov_reg,multiple")
6943 (set_attr "length" "4,4,4,8")
6944 (set_attr "predicable" "yes")
6945 (set_attr "predicable_short_it" "no")]
6946 )
6947
6948 (define_expand "movsf"
6949 [(set (match_operand:SF 0 "general_operand" "")
6950 (match_operand:SF 1 "general_operand" ""))]
6951 "TARGET_EITHER"
6952 "
6953 if (TARGET_32BIT)
6954 {
6955 if (MEM_P (operands[0]))
6956 operands[1] = force_reg (SFmode, operands[1]);
6957 }
6958 else /* TARGET_THUMB1 */
6959 {
6960 if (can_create_pseudo_p ())
6961 {
6962 if (!REG_P (operands[0]))
6963 operands[1] = force_reg (SFmode, operands[1]);
6964 }
6965 }
6966 "
6967 )
6968
6969 ;; Transform a floating-point move of a constant into a core register into
6970 ;; an SImode operation.
6971 (define_split
6972 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6973 (match_operand:SF 1 "immediate_operand" ""))]
6974 "TARGET_EITHER
6975 && reload_completed
6976 && CONST_DOUBLE_P (operands[1])"
6977 [(set (match_dup 2) (match_dup 3))]
6978 "
6979 operands[2] = gen_lowpart (SImode, operands[0]);
6980 operands[3] = gen_lowpart (SImode, operands[1]);
6981 if (operands[2] == 0 || operands[3] == 0)
6982 FAIL;
6983 "
6984 )
6985
6986 (define_insn "*arm_movsf_soft_insn"
6987 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6988 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6989 "TARGET_32BIT
6990 && TARGET_SOFT_FLOAT
6991 && (!MEM_P (operands[0])
6992 || register_operand (operands[1], SFmode))"
6993 "@
6994 mov%?\\t%0, %1
6995 ldr%?\\t%0, %1\\t%@ float
6996 str%?\\t%1, %0\\t%@ float"
6997 [(set_attr "predicable" "yes")
6998 (set_attr "predicable_short_it" "no")
6999 (set_attr "type" "mov_reg,load1,store1")
7000 (set_attr "arm_pool_range" "*,4096,*")
7001 (set_attr "thumb2_pool_range" "*,4094,*")
7002 (set_attr "arm_neg_pool_range" "*,4084,*")
7003 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7004 )
7005
7006 (define_expand "movdf"
7007 [(set (match_operand:DF 0 "general_operand" "")
7008 (match_operand:DF 1 "general_operand" ""))]
7009 "TARGET_EITHER"
7010 "
7011 if (TARGET_32BIT)
7012 {
7013 if (MEM_P (operands[0]))
7014 operands[1] = force_reg (DFmode, operands[1]);
7015 }
7016 else /* TARGET_THUMB */
7017 {
7018 if (can_create_pseudo_p ())
7019 {
7020 if (!REG_P (operands[0]))
7021 operands[1] = force_reg (DFmode, operands[1]);
7022 }
7023 }
7024 "
7025 )
7026
7027 ;; Reloading a df mode value stored in integer regs to memory can require a
7028 ;; scratch reg.
7029 (define_expand "reload_outdf"
7030 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7031 (match_operand:DF 1 "s_register_operand" "r")
7032 (match_operand:SI 2 "s_register_operand" "=&r")]
7033 "TARGET_THUMB2"
7034 "
7035 {
7036 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7037
7038 if (code == REG)
7039 operands[2] = XEXP (operands[0], 0);
7040 else if (code == POST_INC || code == PRE_DEC)
7041 {
7042 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7043 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7044 emit_insn (gen_movdi (operands[0], operands[1]));
7045 DONE;
7046 }
7047 else if (code == PRE_INC)
7048 {
7049 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7050
7051 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7052 operands[2] = reg;
7053 }
7054 else if (code == POST_DEC)
7055 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7056 else
7057 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7058 XEXP (XEXP (operands[0], 0), 1)));
7059
7060 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7061 operands[1]));
7062
7063 if (code == POST_DEC)
7064 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7065
7066 DONE;
7067 }"
7068 )
7069
7070 (define_insn "*movdf_soft_insn"
7071 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7072 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7073 "TARGET_32BIT && TARGET_SOFT_FLOAT
7074 && ( register_operand (operands[0], DFmode)
7075 || register_operand (operands[1], DFmode))"
7076 "*
7077 switch (which_alternative)
7078 {
7079 case 0:
7080 case 1:
7081 case 2:
7082 return \"#\";
7083 default:
7084 return output_move_double (operands, true, NULL);
7085 }
7086 "
7087 [(set_attr "length" "8,12,16,8,8")
7088 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7089 (set_attr "arm_pool_range" "*,*,*,1020,*")
7090 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7091 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7092 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7093 )
7094 \f
7095
7096 ;; load- and store-multiple insns
7097 ;; The arm can load/store any set of registers, provided that they are in
7098 ;; ascending order, but these expanders assume a contiguous set.
7099
7100 (define_expand "load_multiple"
7101 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7102 (match_operand:SI 1 "" ""))
7103 (use (match_operand:SI 2 "" ""))])]
7104 "TARGET_32BIT"
7105 {
7106 HOST_WIDE_INT offset = 0;
7107
7108 /* Support only fixed point registers. */
7109 if (!CONST_INT_P (operands[2])
7110 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7111 || INTVAL (operands[2]) < 2
7112 || !MEM_P (operands[1])
7113 || !REG_P (operands[0])
7114 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7115 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7116 FAIL;
7117
7118 operands[3]
7119 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7120 INTVAL (operands[2]),
7121 force_reg (SImode, XEXP (operands[1], 0)),
7122 FALSE, operands[1], &offset);
7123 })
7124
7125 (define_expand "store_multiple"
7126 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7127 (match_operand:SI 1 "" ""))
7128 (use (match_operand:SI 2 "" ""))])]
7129 "TARGET_32BIT"
7130 {
7131 HOST_WIDE_INT offset = 0;
7132
7133 /* Support only fixed point registers. */
7134 if (!CONST_INT_P (operands[2])
7135 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7136 || INTVAL (operands[2]) < 2
7137 || !REG_P (operands[1])
7138 || !MEM_P (operands[0])
7139 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7140 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7141 FAIL;
7142
7143 operands[3]
7144 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7145 INTVAL (operands[2]),
7146 force_reg (SImode, XEXP (operands[0], 0)),
7147 FALSE, operands[0], &offset);
7148 })
7149
7150
7151 (define_expand "setmemsi"
7152 [(match_operand:BLK 0 "general_operand" "")
7153 (match_operand:SI 1 "const_int_operand" "")
7154 (match_operand:SI 2 "const_int_operand" "")
7155 (match_operand:SI 3 "const_int_operand" "")]
7156 "TARGET_32BIT"
7157 {
7158 if (arm_gen_setmem (operands))
7159 DONE;
7160
7161 FAIL;
7162 })
7163
7164
7165 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7166 ;; We could let this apply for blocks of less than this, but it clobbers so
7167 ;; many registers that there is then probably a better way.
7168
7169 (define_expand "movmemqi"
7170 [(match_operand:BLK 0 "general_operand" "")
7171 (match_operand:BLK 1 "general_operand" "")
7172 (match_operand:SI 2 "const_int_operand" "")
7173 (match_operand:SI 3 "const_int_operand" "")]
7174 ""
7175 "
7176 if (TARGET_32BIT)
7177 {
7178 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7179 && !optimize_function_for_size_p (cfun))
7180 {
7181 if (gen_movmem_ldrd_strd (operands))
7182 DONE;
7183 FAIL;
7184 }
7185
7186 if (arm_gen_movmemqi (operands))
7187 DONE;
7188 FAIL;
7189 }
7190 else /* TARGET_THUMB1 */
7191 {
7192 if ( INTVAL (operands[3]) != 4
7193 || INTVAL (operands[2]) > 48)
7194 FAIL;
7195
7196 thumb_expand_movmemqi (operands);
7197 DONE;
7198 }
7199 "
7200 )
7201 \f
7202
7203 ;; Compare & branch insns
7204 ;; The range calculations are based as follows:
7205 ;; For forward branches, the address calculation returns the address of
7206 ;; the next instruction. This is 2 beyond the branch instruction.
7207 ;; For backward branches, the address calculation returns the address of
7208 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7209 ;; instruction for the shortest sequence, and 4 before the branch instruction
7210 ;; if we have to jump around an unconditional branch.
7211 ;; To the basic branch range the PC offset must be added (this is +4).
7212 ;; So for forward branches we have
7213 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7214 ;; And for backward branches we have
7215 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7216 ;;
7217 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7218 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7219
7220 (define_expand "cbranchsi4"
7221 [(set (pc) (if_then_else
7222 (match_operator 0 "expandable_comparison_operator"
7223 [(match_operand:SI 1 "s_register_operand" "")
7224 (match_operand:SI 2 "nonmemory_operand" "")])
7225 (label_ref (match_operand 3 "" ""))
7226 (pc)))]
7227 "TARGET_EITHER"
7228 "
7229 if (!TARGET_THUMB1)
7230 {
7231 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7232 FAIL;
7233 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7234 operands[3]));
7235 DONE;
7236 }
7237 if (thumb1_cmpneg_operand (operands[2], SImode))
7238 {
7239 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7240 operands[3], operands[0]));
7241 DONE;
7242 }
7243 if (!thumb1_cmp_operand (operands[2], SImode))
7244 operands[2] = force_reg (SImode, operands[2]);
7245 ")
7246
7247 (define_expand "cbranchsf4"
7248 [(set (pc) (if_then_else
7249 (match_operator 0 "expandable_comparison_operator"
7250 [(match_operand:SF 1 "s_register_operand" "")
7251 (match_operand:SF 2 "vfp_compare_operand" "")])
7252 (label_ref (match_operand 3 "" ""))
7253 (pc)))]
7254 "TARGET_32BIT && TARGET_HARD_FLOAT"
7255 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7256 operands[3])); DONE;"
7257 )
7258
7259 (define_expand "cbranchdf4"
7260 [(set (pc) (if_then_else
7261 (match_operator 0 "expandable_comparison_operator"
7262 [(match_operand:DF 1 "s_register_operand" "")
7263 (match_operand:DF 2 "vfp_compare_operand" "")])
7264 (label_ref (match_operand 3 "" ""))
7265 (pc)))]
7266 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7267 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7268 operands[3])); DONE;"
7269 )
7270
7271 (define_expand "cbranchdi4"
7272 [(set (pc) (if_then_else
7273 (match_operator 0 "expandable_comparison_operator"
7274 [(match_operand:DI 1 "s_register_operand" "")
7275 (match_operand:DI 2 "cmpdi_operand" "")])
7276 (label_ref (match_operand 3 "" ""))
7277 (pc)))]
7278 "TARGET_32BIT"
7279 "{
7280 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7281 FAIL;
7282 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7283 operands[3]));
7284 DONE;
7285 }"
7286 )
7287
7288 ;; Comparison and test insns
7289
7290 (define_insn "*arm_cmpsi_insn"
7291 [(set (reg:CC CC_REGNUM)
7292 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7293 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7294 "TARGET_32BIT"
7295 "@
7296 cmp%?\\t%0, %1
7297 cmp%?\\t%0, %1
7298 cmp%?\\t%0, %1
7299 cmp%?\\t%0, %1
7300 cmn%?\\t%0, #%n1"
7301 [(set_attr "conds" "set")
7302 (set_attr "arch" "t2,t2,any,any,any")
7303 (set_attr "length" "2,2,4,4,4")
7304 (set_attr "predicable" "yes")
7305 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7306 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7307 )
7308
7309 (define_insn "*cmpsi_shiftsi"
7310 [(set (reg:CC CC_REGNUM)
7311 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7312 (match_operator:SI 3 "shift_operator"
7313 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7314 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7315 "TARGET_32BIT"
7316 "cmp\\t%0, %1%S3"
7317 [(set_attr "conds" "set")
7318 (set_attr "shift" "1")
7319 (set_attr "arch" "32,a,a")
7320 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7321
7322 (define_insn "*cmpsi_shiftsi_swp"
7323 [(set (reg:CC_SWP CC_REGNUM)
7324 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7325 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7326 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7327 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7328 "TARGET_32BIT"
7329 "cmp%?\\t%0, %1%S3"
7330 [(set_attr "conds" "set")
7331 (set_attr "shift" "1")
7332 (set_attr "arch" "32,a,a")
7333 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7334
7335 (define_insn "*arm_cmpsi_negshiftsi_si"
7336 [(set (reg:CC_Z CC_REGNUM)
7337 (compare:CC_Z
7338 (neg:SI (match_operator:SI 1 "shift_operator"
7339 [(match_operand:SI 2 "s_register_operand" "r")
7340 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7341 (match_operand:SI 0 "s_register_operand" "r")))]
7342 "TARGET_ARM"
7343 "cmn%?\\t%0, %2%S1"
7344 [(set_attr "conds" "set")
7345 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7346 (const_string "alus_shift_imm")
7347 (const_string "alus_shift_reg")))
7348 (set_attr "predicable" "yes")]
7349 )
7350
7351 ;; DImode comparisons. The generic code generates branches that
7352 ;; if-conversion can not reduce to a conditional compare, so we do
7353 ;; that directly.
7354
7355 (define_insn_and_split "*arm_cmpdi_insn"
7356 [(set (reg:CC_NCV CC_REGNUM)
7357 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7358 (match_operand:DI 1 "arm_di_operand" "rDi")))
7359 (clobber (match_scratch:SI 2 "=r"))]
7360 "TARGET_32BIT"
7361 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7362 "&& reload_completed"
7363 [(set (reg:CC CC_REGNUM)
7364 (compare:CC (match_dup 0) (match_dup 1)))
7365 (parallel [(set (reg:CC CC_REGNUM)
7366 (compare:CC (match_dup 3) (match_dup 4)))
7367 (set (match_dup 2)
7368 (minus:SI (match_dup 5)
7369 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7370 {
7371 operands[3] = gen_highpart (SImode, operands[0]);
7372 operands[0] = gen_lowpart (SImode, operands[0]);
7373 if (CONST_INT_P (operands[1]))
7374 {
7375 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7376 DImode,
7377 operands[1])));
7378 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7379 }
7380 else
7381 {
7382 operands[4] = gen_highpart (SImode, operands[1]);
7383 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7384 }
7385 operands[1] = gen_lowpart (SImode, operands[1]);
7386 operands[2] = gen_lowpart (SImode, operands[2]);
7387 }
7388 [(set_attr "conds" "set")
7389 (set_attr "length" "8")
7390 (set_attr "type" "multiple")]
7391 )
7392
7393 (define_insn_and_split "*arm_cmpdi_unsigned"
7394 [(set (reg:CC_CZ CC_REGNUM)
7395 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7396 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7397
7398 "TARGET_32BIT"
7399 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7400 "&& reload_completed"
7401 [(set (reg:CC CC_REGNUM)
7402 (compare:CC (match_dup 2) (match_dup 3)))
7403 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7404 (set (reg:CC CC_REGNUM)
7405 (compare:CC (match_dup 0) (match_dup 1))))]
7406 {
7407 operands[2] = gen_highpart (SImode, operands[0]);
7408 operands[0] = gen_lowpart (SImode, operands[0]);
7409 if (CONST_INT_P (operands[1]))
7410 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7411 else
7412 operands[3] = gen_highpart (SImode, operands[1]);
7413 operands[1] = gen_lowpart (SImode, operands[1]);
7414 }
7415 [(set_attr "conds" "set")
7416 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7417 (set_attr "arch" "t2,t2,t2,a")
7418 (set_attr "length" "6,6,10,8")
7419 (set_attr "type" "multiple")]
7420 )
7421
7422 (define_insn "*arm_cmpdi_zero"
7423 [(set (reg:CC_Z CC_REGNUM)
7424 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7425 (const_int 0)))
7426 (clobber (match_scratch:SI 1 "=r"))]
7427 "TARGET_32BIT"
7428 "orrs%?\\t%1, %Q0, %R0"
7429 [(set_attr "conds" "set")
7430 (set_attr "type" "logics_reg")]
7431 )
7432
7433 ; This insn allows redundant compares to be removed by cse, nothing should
7434 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7435 ; is deleted later on. The match_dup will match the mode here, so that
7436 ; mode changes of the condition codes aren't lost by this even though we don't
7437 ; specify what they are.
7438
7439 (define_insn "*deleted_compare"
7440 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7441 "TARGET_32BIT"
7442 "\\t%@ deleted compare"
7443 [(set_attr "conds" "set")
7444 (set_attr "length" "0")
7445 (set_attr "type" "no_insn")]
7446 )
7447
7448 \f
7449 ;; Conditional branch insns
7450
7451 (define_expand "cbranch_cc"
7452 [(set (pc)
7453 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7454 (match_operand 2 "" "")])
7455 (label_ref (match_operand 3 "" ""))
7456 (pc)))]
7457 "TARGET_32BIT"
7458 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7459 operands[1], operands[2], NULL_RTX);
7460 operands[2] = const0_rtx;"
7461 )
7462
7463 ;;
7464 ;; Patterns to match conditional branch insns.
7465 ;;
7466
7467 (define_insn "arm_cond_branch"
7468 [(set (pc)
7469 (if_then_else (match_operator 1 "arm_comparison_operator"
7470 [(match_operand 2 "cc_register" "") (const_int 0)])
7471 (label_ref (match_operand 0 "" ""))
7472 (pc)))]
7473 "TARGET_32BIT"
7474 "*
7475 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7476 {
7477 arm_ccfsm_state += 2;
7478 return \"\";
7479 }
7480 return \"b%d1\\t%l0\";
7481 "
7482 [(set_attr "conds" "use")
7483 (set_attr "type" "branch")
7484 (set (attr "length")
7485 (if_then_else
7486 (and (match_test "TARGET_THUMB2")
7487 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7488 (le (minus (match_dup 0) (pc)) (const_int 256))))
7489 (const_int 2)
7490 (const_int 4)))]
7491 )
7492
7493 (define_insn "*arm_cond_branch_reversed"
7494 [(set (pc)
7495 (if_then_else (match_operator 1 "arm_comparison_operator"
7496 [(match_operand 2 "cc_register" "") (const_int 0)])
7497 (pc)
7498 (label_ref (match_operand 0 "" ""))))]
7499 "TARGET_32BIT"
7500 "*
7501 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7502 {
7503 arm_ccfsm_state += 2;
7504 return \"\";
7505 }
7506 return \"b%D1\\t%l0\";
7507 "
7508 [(set_attr "conds" "use")
7509 (set_attr "type" "branch")
7510 (set (attr "length")
7511 (if_then_else
7512 (and (match_test "TARGET_THUMB2")
7513 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7514 (le (minus (match_dup 0) (pc)) (const_int 256))))
7515 (const_int 2)
7516 (const_int 4)))]
7517 )
7518
7519 \f
7520
7521 ; scc insns
7522
7523 (define_expand "cstore_cc"
7524 [(set (match_operand:SI 0 "s_register_operand" "")
7525 (match_operator:SI 1 "" [(match_operand 2 "" "")
7526 (match_operand 3 "" "")]))]
7527 "TARGET_32BIT"
7528 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7529 operands[2], operands[3], NULL_RTX);
7530 operands[3] = const0_rtx;"
7531 )
7532
7533 (define_insn_and_split "*mov_scc"
7534 [(set (match_operand:SI 0 "s_register_operand" "=r")
7535 (match_operator:SI 1 "arm_comparison_operator_mode"
7536 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7537 "TARGET_ARM"
7538 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7539 "TARGET_ARM"
7540 [(set (match_dup 0)
7541 (if_then_else:SI (match_dup 1)
7542 (const_int 1)
7543 (const_int 0)))]
7544 ""
7545 [(set_attr "conds" "use")
7546 (set_attr "length" "8")
7547 (set_attr "type" "multiple")]
7548 )
7549
7550 (define_insn_and_split "*mov_negscc"
7551 [(set (match_operand:SI 0 "s_register_operand" "=r")
7552 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7553 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7554 "TARGET_ARM"
7555 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7556 "TARGET_ARM"
7557 [(set (match_dup 0)
7558 (if_then_else:SI (match_dup 1)
7559 (match_dup 3)
7560 (const_int 0)))]
7561 {
7562 operands[3] = GEN_INT (~0);
7563 }
7564 [(set_attr "conds" "use")
7565 (set_attr "length" "8")
7566 (set_attr "type" "multiple")]
7567 )
7568
7569 (define_insn_and_split "*mov_notscc"
7570 [(set (match_operand:SI 0 "s_register_operand" "=r")
7571 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7572 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7573 "TARGET_ARM"
7574 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7575 "TARGET_ARM"
7576 [(set (match_dup 0)
7577 (if_then_else:SI (match_dup 1)
7578 (match_dup 3)
7579 (match_dup 4)))]
7580 {
7581 operands[3] = GEN_INT (~1);
7582 operands[4] = GEN_INT (~0);
7583 }
7584 [(set_attr "conds" "use")
7585 (set_attr "length" "8")
7586 (set_attr "type" "multiple")]
7587 )
7588
7589 (define_expand "cstoresi4"
7590 [(set (match_operand:SI 0 "s_register_operand" "")
7591 (match_operator:SI 1 "expandable_comparison_operator"
7592 [(match_operand:SI 2 "s_register_operand" "")
7593 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7594 "TARGET_32BIT || TARGET_THUMB1"
7595 "{
7596 rtx op3, scratch, scratch2;
7597
7598 if (!TARGET_THUMB1)
7599 {
7600 if (!arm_add_operand (operands[3], SImode))
7601 operands[3] = force_reg (SImode, operands[3]);
7602 emit_insn (gen_cstore_cc (operands[0], operands[1],
7603 operands[2], operands[3]));
7604 DONE;
7605 }
7606
7607 if (operands[3] == const0_rtx)
7608 {
7609 switch (GET_CODE (operands[1]))
7610 {
7611 case EQ:
7612 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7613 break;
7614
7615 case NE:
7616 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7617 break;
7618
7619 case LE:
7620 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7621 NULL_RTX, 0, OPTAB_WIDEN);
7622 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7623 NULL_RTX, 0, OPTAB_WIDEN);
7624 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7625 operands[0], 1, OPTAB_WIDEN);
7626 break;
7627
7628 case GE:
7629 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7630 NULL_RTX, 1);
7631 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7632 NULL_RTX, 1, OPTAB_WIDEN);
7633 break;
7634
7635 case GT:
7636 scratch = expand_binop (SImode, ashr_optab, operands[2],
7637 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7638 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7639 NULL_RTX, 0, OPTAB_WIDEN);
7640 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7641 0, OPTAB_WIDEN);
7642 break;
7643
7644 /* LT is handled by generic code. No need for unsigned with 0. */
7645 default:
7646 FAIL;
7647 }
7648 DONE;
7649 }
7650
7651 switch (GET_CODE (operands[1]))
7652 {
7653 case EQ:
7654 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7655 NULL_RTX, 0, OPTAB_WIDEN);
7656 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7657 break;
7658
7659 case NE:
7660 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7661 NULL_RTX, 0, OPTAB_WIDEN);
7662 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7663 break;
7664
7665 case LE:
7666 op3 = force_reg (SImode, operands[3]);
7667
7668 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7669 NULL_RTX, 1, OPTAB_WIDEN);
7670 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7671 NULL_RTX, 0, OPTAB_WIDEN);
7672 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7673 op3, operands[2]));
7674 break;
7675
7676 case GE:
7677 op3 = operands[3];
7678 if (!thumb1_cmp_operand (op3, SImode))
7679 op3 = force_reg (SImode, op3);
7680 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7681 NULL_RTX, 0, OPTAB_WIDEN);
7682 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7683 NULL_RTX, 1, OPTAB_WIDEN);
7684 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7685 operands[2], op3));
7686 break;
7687
7688 case LEU:
7689 op3 = force_reg (SImode, operands[3]);
7690 scratch = force_reg (SImode, const0_rtx);
7691 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7692 op3, operands[2]));
7693 break;
7694
7695 case GEU:
7696 op3 = operands[3];
7697 if (!thumb1_cmp_operand (op3, SImode))
7698 op3 = force_reg (SImode, op3);
7699 scratch = force_reg (SImode, const0_rtx);
7700 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7701 operands[2], op3));
7702 break;
7703
7704 case LTU:
7705 op3 = operands[3];
7706 if (!thumb1_cmp_operand (op3, SImode))
7707 op3 = force_reg (SImode, op3);
7708 scratch = gen_reg_rtx (SImode);
7709 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7710 break;
7711
7712 case GTU:
7713 op3 = force_reg (SImode, operands[3]);
7714 scratch = gen_reg_rtx (SImode);
7715 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7716 break;
7717
7718 /* No good sequences for GT, LT. */
7719 default:
7720 FAIL;
7721 }
7722 DONE;
7723 }")
7724
7725 (define_expand "cstorehf4"
7726 [(set (match_operand:SI 0 "s_register_operand")
7727 (match_operator:SI 1 "expandable_comparison_operator"
7728 [(match_operand:HF 2 "s_register_operand")
7729 (match_operand:HF 3 "vfp_compare_operand")]))]
7730 "TARGET_VFP_FP16INST"
7731 {
7732 if (!arm_validize_comparison (&operands[1],
7733 &operands[2],
7734 &operands[3]))
7735 FAIL;
7736
7737 emit_insn (gen_cstore_cc (operands[0], operands[1],
7738 operands[2], operands[3]));
7739 DONE;
7740 }
7741 )
7742
7743 (define_expand "cstoresf4"
7744 [(set (match_operand:SI 0 "s_register_operand" "")
7745 (match_operator:SI 1 "expandable_comparison_operator"
7746 [(match_operand:SF 2 "s_register_operand" "")
7747 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7748 "TARGET_32BIT && TARGET_HARD_FLOAT"
7749 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7750 operands[2], operands[3])); DONE;"
7751 )
7752
7753 (define_expand "cstoredf4"
7754 [(set (match_operand:SI 0 "s_register_operand" "")
7755 (match_operator:SI 1 "expandable_comparison_operator"
7756 [(match_operand:DF 2 "s_register_operand" "")
7757 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7758 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7759 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7760 operands[2], operands[3])); DONE;"
7761 )
7762
7763 (define_expand "cstoredi4"
7764 [(set (match_operand:SI 0 "s_register_operand" "")
7765 (match_operator:SI 1 "expandable_comparison_operator"
7766 [(match_operand:DI 2 "s_register_operand" "")
7767 (match_operand:DI 3 "cmpdi_operand" "")]))]
7768 "TARGET_32BIT"
7769 "{
7770 if (!arm_validize_comparison (&operands[1],
7771 &operands[2],
7772 &operands[3]))
7773 FAIL;
7774 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7775 operands[3]));
7776 DONE;
7777 }"
7778 )
7779
7780 \f
7781 ;; Conditional move insns
7782
7783 (define_expand "movsicc"
7784 [(set (match_operand:SI 0 "s_register_operand" "")
7785 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7786 (match_operand:SI 2 "arm_not_operand" "")
7787 (match_operand:SI 3 "arm_not_operand" "")))]
7788 "TARGET_32BIT"
7789 "
7790 {
7791 enum rtx_code code;
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 "movhfcc"
7806 [(set (match_operand:HF 0 "s_register_operand")
7807 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7808 (match_operand:HF 2 "s_register_operand")
7809 (match_operand:HF 3 "s_register_operand")))]
7810 "TARGET_VFP_FP16INST"
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 "movsfcc"
7828 [(set (match_operand:SF 0 "s_register_operand" "")
7829 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7830 (match_operand:SF 2 "s_register_operand" "")
7831 (match_operand:SF 3 "s_register_operand" "")))]
7832 "TARGET_32BIT && TARGET_HARD_FLOAT"
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
7842 code = GET_CODE (operands[1]);
7843 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7844 XEXP (operands[1], 1), NULL_RTX);
7845 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7846 }"
7847 )
7848
7849 (define_expand "movdfcc"
7850 [(set (match_operand:DF 0 "s_register_operand" "")
7851 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7852 (match_operand:DF 2 "s_register_operand" "")
7853 (match_operand:DF 3 "s_register_operand" "")))]
7854 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7855 "
7856 {
7857 enum rtx_code code = GET_CODE (operands[1]);
7858 rtx ccreg;
7859
7860 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7861 &XEXP (operands[1], 1)))
7862 FAIL;
7863 code = GET_CODE (operands[1]);
7864 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7865 XEXP (operands[1], 1), NULL_RTX);
7866 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7867 }"
7868 )
7869
7870 (define_insn "*cmov<mode>"
7871 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7872 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7873 [(match_operand 2 "cc_register" "") (const_int 0)])
7874 (match_operand:SDF 3 "s_register_operand"
7875 "<F_constraint>")
7876 (match_operand:SDF 4 "s_register_operand"
7877 "<F_constraint>")))]
7878 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7879 "*
7880 {
7881 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7882 switch (code)
7883 {
7884 case ARM_GE:
7885 case ARM_GT:
7886 case ARM_EQ:
7887 case ARM_VS:
7888 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7889 case ARM_LT:
7890 case ARM_LE:
7891 case ARM_NE:
7892 case ARM_VC:
7893 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7894 default:
7895 gcc_unreachable ();
7896 }
7897 return \"\";
7898 }"
7899 [(set_attr "conds" "use")
7900 (set_attr "type" "fcsel")]
7901 )
7902
7903 (define_insn "*cmovhf"
7904 [(set (match_operand:HF 0 "s_register_operand" "=t")
7905 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7906 [(match_operand 2 "cc_register" "") (const_int 0)])
7907 (match_operand:HF 3 "s_register_operand" "t")
7908 (match_operand:HF 4 "s_register_operand" "t")))]
7909 "TARGET_VFP_FP16INST"
7910 "*
7911 {
7912 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7913 switch (code)
7914 {
7915 case ARM_GE:
7916 case ARM_GT:
7917 case ARM_EQ:
7918 case ARM_VS:
7919 return \"vsel%d1.f16\\t%0, %3, %4\";
7920 case ARM_LT:
7921 case ARM_LE:
7922 case ARM_NE:
7923 case ARM_VC:
7924 return \"vsel%D1.f16\\t%0, %4, %3\";
7925 default:
7926 gcc_unreachable ();
7927 }
7928 return \"\";
7929 }"
7930 [(set_attr "conds" "use")
7931 (set_attr "type" "fcsel")]
7932 )
7933
7934 (define_insn_and_split "*movsicc_insn"
7935 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7936 (if_then_else:SI
7937 (match_operator 3 "arm_comparison_operator"
7938 [(match_operand 4 "cc_register" "") (const_int 0)])
7939 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7940 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7941 "TARGET_ARM"
7942 "@
7943 mov%D3\\t%0, %2
7944 mvn%D3\\t%0, #%B2
7945 mov%d3\\t%0, %1
7946 mvn%d3\\t%0, #%B1
7947 #
7948 #
7949 #
7950 #"
7951 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7952 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7953 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7954 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7955 "&& reload_completed"
7956 [(const_int 0)]
7957 {
7958 enum rtx_code rev_code;
7959 machine_mode mode;
7960 rtx rev_cond;
7961
7962 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7963 operands[3],
7964 gen_rtx_SET (operands[0], operands[1])));
7965
7966 rev_code = GET_CODE (operands[3]);
7967 mode = GET_MODE (operands[4]);
7968 if (mode == CCFPmode || mode == CCFPEmode)
7969 rev_code = reverse_condition_maybe_unordered (rev_code);
7970 else
7971 rev_code = reverse_condition (rev_code);
7972
7973 rev_cond = gen_rtx_fmt_ee (rev_code,
7974 VOIDmode,
7975 operands[4],
7976 const0_rtx);
7977 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7978 rev_cond,
7979 gen_rtx_SET (operands[0], operands[2])));
7980 DONE;
7981 }
7982 [(set_attr "length" "4,4,4,4,8,8,8,8")
7983 (set_attr "conds" "use")
7984 (set_attr_alternative "type"
7985 [(if_then_else (match_operand 2 "const_int_operand" "")
7986 (const_string "mov_imm")
7987 (const_string "mov_reg"))
7988 (const_string "mvn_imm")
7989 (if_then_else (match_operand 1 "const_int_operand" "")
7990 (const_string "mov_imm")
7991 (const_string "mov_reg"))
7992 (const_string "mvn_imm")
7993 (const_string "multiple")
7994 (const_string "multiple")
7995 (const_string "multiple")
7996 (const_string "multiple")])]
7997 )
7998
7999 (define_insn "*movsfcc_soft_insn"
8000 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8001 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8002 [(match_operand 4 "cc_register" "") (const_int 0)])
8003 (match_operand:SF 1 "s_register_operand" "0,r")
8004 (match_operand:SF 2 "s_register_operand" "r,0")))]
8005 "TARGET_ARM && TARGET_SOFT_FLOAT"
8006 "@
8007 mov%D3\\t%0, %2
8008 mov%d3\\t%0, %1"
8009 [(set_attr "conds" "use")
8010 (set_attr "type" "mov_reg")]
8011 )
8012
8013 \f
8014 ;; Jump and linkage insns
8015
8016 (define_expand "jump"
8017 [(set (pc)
8018 (label_ref (match_operand 0 "" "")))]
8019 "TARGET_EITHER"
8020 ""
8021 )
8022
8023 (define_insn "*arm_jump"
8024 [(set (pc)
8025 (label_ref (match_operand 0 "" "")))]
8026 "TARGET_32BIT"
8027 "*
8028 {
8029 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8030 {
8031 arm_ccfsm_state += 2;
8032 return \"\";
8033 }
8034 return \"b%?\\t%l0\";
8035 }
8036 "
8037 [(set_attr "predicable" "yes")
8038 (set (attr "length")
8039 (if_then_else
8040 (and (match_test "TARGET_THUMB2")
8041 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8042 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8043 (const_int 2)
8044 (const_int 4)))
8045 (set_attr "type" "branch")]
8046 )
8047
8048 (define_expand "call"
8049 [(parallel [(call (match_operand 0 "memory_operand" "")
8050 (match_operand 1 "general_operand" ""))
8051 (use (match_operand 2 "" ""))
8052 (clobber (reg:SI LR_REGNUM))])]
8053 "TARGET_EITHER"
8054 "
8055 {
8056 rtx callee, pat;
8057 tree addr = MEM_EXPR (operands[0]);
8058
8059 /* In an untyped call, we can get NULL for operand 2. */
8060 if (operands[2] == NULL_RTX)
8061 operands[2] = const0_rtx;
8062
8063 /* Decide if we should generate indirect calls by loading the
8064 32-bit address of the callee into a register before performing the
8065 branch and link. */
8066 callee = XEXP (operands[0], 0);
8067 if (GET_CODE (callee) == SYMBOL_REF
8068 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8069 : !REG_P (callee))
8070 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8071
8072 if (detect_cmse_nonsecure_call (addr))
8073 {
8074 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8075 operands[2]);
8076 emit_call_insn (pat);
8077 }
8078 else
8079 {
8080 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8081 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8082 }
8083 DONE;
8084 }"
8085 )
8086
8087 (define_expand "call_internal"
8088 [(parallel [(call (match_operand 0 "memory_operand" "")
8089 (match_operand 1 "general_operand" ""))
8090 (use (match_operand 2 "" ""))
8091 (clobber (reg:SI LR_REGNUM))])])
8092
8093 (define_expand "nonsecure_call_internal"
8094 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8095 UNSPEC_NONSECURE_MEM)
8096 (match_operand 1 "general_operand" ""))
8097 (use (match_operand 2 "" ""))
8098 (clobber (reg:SI LR_REGNUM))
8099 (clobber (reg:SI 4))])]
8100 "use_cmse"
8101 "
8102 {
8103 rtx tmp;
8104 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8105 gen_rtx_REG (SImode, 4),
8106 SImode);
8107
8108 operands[0] = replace_equiv_address (operands[0], tmp);
8109 }")
8110
8111 (define_insn "*call_reg_armv5"
8112 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8113 (match_operand 1 "" ""))
8114 (use (match_operand 2 "" ""))
8115 (clobber (reg:SI LR_REGNUM))]
8116 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8117 "blx%?\\t%0"
8118 [(set_attr "type" "call")]
8119 )
8120
8121 (define_insn "*call_reg_arm"
8122 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8123 (match_operand 1 "" ""))
8124 (use (match_operand 2 "" ""))
8125 (clobber (reg:SI LR_REGNUM))]
8126 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8127 "*
8128 return output_call (operands);
8129 "
8130 ;; length is worst case, normally it is only two
8131 [(set_attr "length" "12")
8132 (set_attr "type" "call")]
8133 )
8134
8135
8136 (define_expand "call_value"
8137 [(parallel [(set (match_operand 0 "" "")
8138 (call (match_operand 1 "memory_operand" "")
8139 (match_operand 2 "general_operand" "")))
8140 (use (match_operand 3 "" ""))
8141 (clobber (reg:SI LR_REGNUM))])]
8142 "TARGET_EITHER"
8143 "
8144 {
8145 rtx pat, callee;
8146 tree addr = MEM_EXPR (operands[1]);
8147
8148 /* In an untyped call, we can get NULL for operand 2. */
8149 if (operands[3] == 0)
8150 operands[3] = const0_rtx;
8151
8152 /* Decide if we should generate indirect calls by loading the
8153 32-bit address of the callee into a register before performing the
8154 branch and link. */
8155 callee = XEXP (operands[1], 0);
8156 if (GET_CODE (callee) == SYMBOL_REF
8157 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8158 : !REG_P (callee))
8159 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8160
8161 if (detect_cmse_nonsecure_call (addr))
8162 {
8163 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8164 operands[2], operands[3]);
8165 emit_call_insn (pat);
8166 }
8167 else
8168 {
8169 pat = gen_call_value_internal (operands[0], operands[1],
8170 operands[2], operands[3]);
8171 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8172 }
8173 DONE;
8174 }"
8175 )
8176
8177 (define_expand "call_value_internal"
8178 [(parallel [(set (match_operand 0 "" "")
8179 (call (match_operand 1 "memory_operand" "")
8180 (match_operand 2 "general_operand" "")))
8181 (use (match_operand 3 "" ""))
8182 (clobber (reg:SI LR_REGNUM))])])
8183
8184 (define_expand "nonsecure_call_value_internal"
8185 [(parallel [(set (match_operand 0 "" "")
8186 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8187 UNSPEC_NONSECURE_MEM)
8188 (match_operand 2 "general_operand" "")))
8189 (use (match_operand 3 "" ""))
8190 (clobber (reg:SI LR_REGNUM))
8191 (clobber (reg:SI 4))])]
8192 "use_cmse"
8193 "
8194 {
8195 rtx tmp;
8196 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8197 gen_rtx_REG (SImode, 4),
8198 SImode);
8199
8200 operands[1] = replace_equiv_address (operands[1], tmp);
8201 }")
8202
8203 (define_insn "*call_value_reg_armv5"
8204 [(set (match_operand 0 "" "")
8205 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8206 (match_operand 2 "" "")))
8207 (use (match_operand 3 "" ""))
8208 (clobber (reg:SI LR_REGNUM))]
8209 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8210 "blx%?\\t%1"
8211 [(set_attr "type" "call")]
8212 )
8213
8214 (define_insn "*call_value_reg_arm"
8215 [(set (match_operand 0 "" "")
8216 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8217 (match_operand 2 "" "")))
8218 (use (match_operand 3 "" ""))
8219 (clobber (reg:SI LR_REGNUM))]
8220 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8221 "*
8222 return output_call (&operands[1]);
8223 "
8224 [(set_attr "length" "12")
8225 (set_attr "type" "call")]
8226 )
8227
8228 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8229 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8230
8231 (define_insn "*call_symbol"
8232 [(call (mem:SI (match_operand:SI 0 "" ""))
8233 (match_operand 1 "" ""))
8234 (use (match_operand 2 "" ""))
8235 (clobber (reg:SI LR_REGNUM))]
8236 "TARGET_32BIT
8237 && !SIBLING_CALL_P (insn)
8238 && (GET_CODE (operands[0]) == SYMBOL_REF)
8239 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8240 "*
8241 {
8242 rtx op = operands[0];
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%a0(PLT)\" : \"blx%?\\t(%a0)\";
8248
8249 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8250 }"
8251 [(set_attr "type" "call")]
8252 )
8253
8254 (define_insn "*call_value_symbol"
8255 [(set (match_operand 0 "" "")
8256 (call (mem:SI (match_operand:SI 1 "" ""))
8257 (match_operand:SI 2 "" "")))
8258 (use (match_operand 3 "" ""))
8259 (clobber (reg:SI LR_REGNUM))]
8260 "TARGET_32BIT
8261 && !SIBLING_CALL_P (insn)
8262 && (GET_CODE (operands[1]) == SYMBOL_REF)
8263 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8264 "*
8265 {
8266 rtx op = operands[1];
8267
8268 /* Switch mode now when possible. */
8269 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8270 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8271 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8272
8273 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8274 }"
8275 [(set_attr "type" "call")]
8276 )
8277
8278 (define_expand "sibcall_internal"
8279 [(parallel [(call (match_operand 0 "memory_operand" "")
8280 (match_operand 1 "general_operand" ""))
8281 (return)
8282 (use (match_operand 2 "" ""))])])
8283
8284 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8285 (define_expand "sibcall"
8286 [(parallel [(call (match_operand 0 "memory_operand" "")
8287 (match_operand 1 "general_operand" ""))
8288 (return)
8289 (use (match_operand 2 "" ""))])]
8290 "TARGET_32BIT"
8291 "
8292 {
8293 rtx pat;
8294
8295 if ((!REG_P (XEXP (operands[0], 0))
8296 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8297 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8298 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8299 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8300
8301 if (operands[2] == NULL_RTX)
8302 operands[2] = const0_rtx;
8303
8304 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8305 arm_emit_call_insn (pat, operands[0], true);
8306 DONE;
8307 }"
8308 )
8309
8310 (define_expand "sibcall_value_internal"
8311 [(parallel [(set (match_operand 0 "" "")
8312 (call (match_operand 1 "memory_operand" "")
8313 (match_operand 2 "general_operand" "")))
8314 (return)
8315 (use (match_operand 3 "" ""))])])
8316
8317 (define_expand "sibcall_value"
8318 [(parallel [(set (match_operand 0 "" "")
8319 (call (match_operand 1 "memory_operand" "")
8320 (match_operand 2 "general_operand" "")))
8321 (return)
8322 (use (match_operand 3 "" ""))])]
8323 "TARGET_32BIT"
8324 "
8325 {
8326 rtx pat;
8327
8328 if ((!REG_P (XEXP (operands[1], 0))
8329 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8330 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8331 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8332 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8333
8334 if (operands[3] == NULL_RTX)
8335 operands[3] = const0_rtx;
8336
8337 pat = gen_sibcall_value_internal (operands[0], operands[1],
8338 operands[2], operands[3]);
8339 arm_emit_call_insn (pat, operands[1], true);
8340 DONE;
8341 }"
8342 )
8343
8344 (define_insn "*sibcall_insn"
8345 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8346 (match_operand 1 "" ""))
8347 (return)
8348 (use (match_operand 2 "" ""))]
8349 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8350 "*
8351 if (which_alternative == 1)
8352 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8353 else
8354 {
8355 if (arm_arch5 || arm_arch4t)
8356 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8357 else
8358 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8359 }
8360 "
8361 [(set_attr "type" "call")]
8362 )
8363
8364 (define_insn "*sibcall_value_insn"
8365 [(set (match_operand 0 "" "")
8366 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8367 (match_operand 2 "" "")))
8368 (return)
8369 (use (match_operand 3 "" ""))]
8370 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8371 "*
8372 if (which_alternative == 1)
8373 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8374 else
8375 {
8376 if (arm_arch5 || arm_arch4t)
8377 return \"bx%?\\t%1\";
8378 else
8379 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8380 }
8381 "
8382 [(set_attr "type" "call")]
8383 )
8384
8385 (define_expand "<return_str>return"
8386 [(RETURNS)]
8387 "(TARGET_ARM || (TARGET_THUMB2
8388 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8389 && !IS_STACKALIGN (arm_current_func_type ())))
8390 <return_cond_false>"
8391 "
8392 {
8393 if (TARGET_THUMB2)
8394 {
8395 thumb2_expand_return (<return_simple_p>);
8396 DONE;
8397 }
8398 }
8399 "
8400 )
8401
8402 ;; Often the return insn will be the same as loading from memory, so set attr
8403 (define_insn "*arm_return"
8404 [(return)]
8405 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8406 "*
8407 {
8408 if (arm_ccfsm_state == 2)
8409 {
8410 arm_ccfsm_state += 2;
8411 return \"\";
8412 }
8413 return output_return_instruction (const_true_rtx, true, false, false);
8414 }"
8415 [(set_attr "type" "load1")
8416 (set_attr "length" "12")
8417 (set_attr "predicable" "yes")]
8418 )
8419
8420 (define_insn "*cond_<return_str>return"
8421 [(set (pc)
8422 (if_then_else (match_operator 0 "arm_comparison_operator"
8423 [(match_operand 1 "cc_register" "") (const_int 0)])
8424 (RETURNS)
8425 (pc)))]
8426 "TARGET_ARM <return_cond_true>"
8427 "*
8428 {
8429 if (arm_ccfsm_state == 2)
8430 {
8431 arm_ccfsm_state += 2;
8432 return \"\";
8433 }
8434 return output_return_instruction (operands[0], true, false,
8435 <return_simple_p>);
8436 }"
8437 [(set_attr "conds" "use")
8438 (set_attr "length" "12")
8439 (set_attr "type" "load1")]
8440 )
8441
8442 (define_insn "*cond_<return_str>return_inverted"
8443 [(set (pc)
8444 (if_then_else (match_operator 0 "arm_comparison_operator"
8445 [(match_operand 1 "cc_register" "") (const_int 0)])
8446 (pc)
8447 (RETURNS)))]
8448 "TARGET_ARM <return_cond_true>"
8449 "*
8450 {
8451 if (arm_ccfsm_state == 2)
8452 {
8453 arm_ccfsm_state += 2;
8454 return \"\";
8455 }
8456 return output_return_instruction (operands[0], true, true,
8457 <return_simple_p>);
8458 }"
8459 [(set_attr "conds" "use")
8460 (set_attr "length" "12")
8461 (set_attr "type" "load1")]
8462 )
8463
8464 (define_insn "*arm_simple_return"
8465 [(simple_return)]
8466 "TARGET_ARM"
8467 "*
8468 {
8469 if (arm_ccfsm_state == 2)
8470 {
8471 arm_ccfsm_state += 2;
8472 return \"\";
8473 }
8474 return output_return_instruction (const_true_rtx, true, false, true);
8475 }"
8476 [(set_attr "type" "branch")
8477 (set_attr "length" "4")
8478 (set_attr "predicable" "yes")]
8479 )
8480
8481 ;; Generate a sequence of instructions to determine if the processor is
8482 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8483 ;; mask.
8484
8485 (define_expand "return_addr_mask"
8486 [(set (match_dup 1)
8487 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8488 (const_int 0)))
8489 (set (match_operand:SI 0 "s_register_operand" "")
8490 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8491 (const_int -1)
8492 (const_int 67108860)))] ; 0x03fffffc
8493 "TARGET_ARM"
8494 "
8495 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8496 ")
8497
8498 (define_insn "*check_arch2"
8499 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8500 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8501 (const_int 0)))]
8502 "TARGET_ARM"
8503 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8504 [(set_attr "length" "8")
8505 (set_attr "conds" "set")
8506 (set_attr "type" "multiple")]
8507 )
8508
8509 ;; Call subroutine returning any type.
8510
8511 (define_expand "untyped_call"
8512 [(parallel [(call (match_operand 0 "" "")
8513 (const_int 0))
8514 (match_operand 1 "" "")
8515 (match_operand 2 "" "")])]
8516 "TARGET_EITHER"
8517 "
8518 {
8519 int i;
8520 rtx par = gen_rtx_PARALLEL (VOIDmode,
8521 rtvec_alloc (XVECLEN (operands[2], 0)));
8522 rtx addr = gen_reg_rtx (Pmode);
8523 rtx mem;
8524 int size = 0;
8525
8526 emit_move_insn (addr, XEXP (operands[1], 0));
8527 mem = change_address (operands[1], BLKmode, addr);
8528
8529 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8530 {
8531 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8532
8533 /* Default code only uses r0 as a return value, but we could
8534 be using anything up to 4 registers. */
8535 if (REGNO (src) == R0_REGNUM)
8536 src = gen_rtx_REG (TImode, R0_REGNUM);
8537
8538 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8539 GEN_INT (size));
8540 size += GET_MODE_SIZE (GET_MODE (src));
8541 }
8542
8543 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8544
8545 size = 0;
8546
8547 for (i = 0; i < XVECLEN (par, 0); i++)
8548 {
8549 HOST_WIDE_INT offset = 0;
8550 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8551
8552 if (size != 0)
8553 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8554
8555 mem = change_address (mem, GET_MODE (reg), NULL);
8556 if (REGNO (reg) == R0_REGNUM)
8557 {
8558 /* On thumb we have to use a write-back instruction. */
8559 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8560 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8561 size = TARGET_ARM ? 16 : 0;
8562 }
8563 else
8564 {
8565 emit_move_insn (mem, reg);
8566 size = GET_MODE_SIZE (GET_MODE (reg));
8567 }
8568 }
8569
8570 /* The optimizer does not know that the call sets the function value
8571 registers we stored in the result block. We avoid problems by
8572 claiming that all hard registers are used and clobbered at this
8573 point. */
8574 emit_insn (gen_blockage ());
8575
8576 DONE;
8577 }"
8578 )
8579
8580 (define_expand "untyped_return"
8581 [(match_operand:BLK 0 "memory_operand" "")
8582 (match_operand 1 "" "")]
8583 "TARGET_EITHER"
8584 "
8585 {
8586 int i;
8587 rtx addr = gen_reg_rtx (Pmode);
8588 rtx mem;
8589 int size = 0;
8590
8591 emit_move_insn (addr, XEXP (operands[0], 0));
8592 mem = change_address (operands[0], BLKmode, addr);
8593
8594 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8595 {
8596 HOST_WIDE_INT offset = 0;
8597 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8598
8599 if (size != 0)
8600 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8601
8602 mem = change_address (mem, GET_MODE (reg), NULL);
8603 if (REGNO (reg) == R0_REGNUM)
8604 {
8605 /* On thumb we have to use a write-back instruction. */
8606 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8607 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8608 size = TARGET_ARM ? 16 : 0;
8609 }
8610 else
8611 {
8612 emit_move_insn (reg, mem);
8613 size = GET_MODE_SIZE (GET_MODE (reg));
8614 }
8615 }
8616
8617 /* Emit USE insns before the return. */
8618 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8619 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8620
8621 /* Construct the return. */
8622 expand_naked_return ();
8623
8624 DONE;
8625 }"
8626 )
8627
8628 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8629 ;; all of memory. This blocks insns from being moved across this point.
8630
8631 (define_insn "blockage"
8632 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8633 "TARGET_EITHER"
8634 ""
8635 [(set_attr "length" "0")
8636 (set_attr "type" "block")]
8637 )
8638
8639 (define_insn "probe_stack"
8640 [(set (match_operand:SI 0 "memory_operand" "=m")
8641 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8642 "TARGET_32BIT"
8643 "str%?\\tr0, %0"
8644 [(set_attr "type" "store1")
8645 (set_attr "predicable" "yes")]
8646 )
8647
8648 (define_insn "probe_stack_range"
8649 [(set (match_operand:SI 0 "register_operand" "=r")
8650 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8651 (match_operand:SI 2 "register_operand" "r")]
8652 VUNSPEC_PROBE_STACK_RANGE))]
8653 "TARGET_32BIT"
8654 {
8655 return output_probe_stack_range (operands[0], operands[2]);
8656 }
8657 [(set_attr "type" "multiple")
8658 (set_attr "conds" "clob")]
8659 )
8660
8661 (define_expand "casesi"
8662 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8663 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8664 (match_operand:SI 2 "const_int_operand" "") ; total range
8665 (match_operand:SI 3 "" "") ; table label
8666 (match_operand:SI 4 "" "")] ; Out of range label
8667 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8668 "
8669 {
8670 enum insn_code code;
8671 if (operands[1] != const0_rtx)
8672 {
8673 rtx reg = gen_reg_rtx (SImode);
8674
8675 emit_insn (gen_addsi3 (reg, operands[0],
8676 gen_int_mode (-INTVAL (operands[1]),
8677 SImode)));
8678 operands[0] = reg;
8679 }
8680
8681 if (TARGET_ARM)
8682 code = CODE_FOR_arm_casesi_internal;
8683 else if (TARGET_THUMB1)
8684 code = CODE_FOR_thumb1_casesi_internal_pic;
8685 else if (flag_pic)
8686 code = CODE_FOR_thumb2_casesi_internal_pic;
8687 else
8688 code = CODE_FOR_thumb2_casesi_internal;
8689
8690 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8691 operands[2] = force_reg (SImode, operands[2]);
8692
8693 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8694 operands[3], operands[4]));
8695 DONE;
8696 }"
8697 )
8698
8699 ;; The USE in this pattern is needed to tell flow analysis that this is
8700 ;; a CASESI insn. It has no other purpose.
8701 (define_insn "arm_casesi_internal"
8702 [(parallel [(set (pc)
8703 (if_then_else
8704 (leu (match_operand:SI 0 "s_register_operand" "r")
8705 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8706 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8707 (label_ref (match_operand 2 "" ""))))
8708 (label_ref (match_operand 3 "" ""))))
8709 (clobber (reg:CC CC_REGNUM))
8710 (use (label_ref (match_dup 2)))])]
8711 "TARGET_ARM"
8712 "*
8713 if (flag_pic)
8714 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8715 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8716 "
8717 [(set_attr "conds" "clob")
8718 (set_attr "length" "12")
8719 (set_attr "type" "multiple")]
8720 )
8721
8722 (define_expand "indirect_jump"
8723 [(set (pc)
8724 (match_operand:SI 0 "s_register_operand" ""))]
8725 "TARGET_EITHER"
8726 "
8727 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8728 address and use bx. */
8729 if (TARGET_THUMB2)
8730 {
8731 rtx tmp;
8732 tmp = gen_reg_rtx (SImode);
8733 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8734 operands[0] = tmp;
8735 }
8736 "
8737 )
8738
8739 ;; NB Never uses BX.
8740 (define_insn "*arm_indirect_jump"
8741 [(set (pc)
8742 (match_operand:SI 0 "s_register_operand" "r"))]
8743 "TARGET_ARM"
8744 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8745 [(set_attr "predicable" "yes")
8746 (set_attr "type" "branch")]
8747 )
8748
8749 (define_insn "*load_indirect_jump"
8750 [(set (pc)
8751 (match_operand:SI 0 "memory_operand" "m"))]
8752 "TARGET_ARM"
8753 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8754 [(set_attr "type" "load1")
8755 (set_attr "pool_range" "4096")
8756 (set_attr "neg_pool_range" "4084")
8757 (set_attr "predicable" "yes")]
8758 )
8759
8760 \f
8761 ;; Misc insns
8762
8763 (define_insn "nop"
8764 [(const_int 0)]
8765 "TARGET_EITHER"
8766 "nop"
8767 [(set (attr "length")
8768 (if_then_else (eq_attr "is_thumb" "yes")
8769 (const_int 2)
8770 (const_int 4)))
8771 (set_attr "type" "mov_reg")]
8772 )
8773
8774 (define_insn "trap"
8775 [(trap_if (const_int 1) (const_int 0))]
8776 ""
8777 "*
8778 if (TARGET_ARM)
8779 return \".inst\\t0xe7f000f0\";
8780 else
8781 return \".inst\\t0xdeff\";
8782 "
8783 [(set (attr "length")
8784 (if_then_else (eq_attr "is_thumb" "yes")
8785 (const_int 2)
8786 (const_int 4)))
8787 (set_attr "type" "trap")
8788 (set_attr "conds" "unconditional")]
8789 )
8790
8791 \f
8792 ;; Patterns to allow combination of arithmetic, cond code and shifts
8793
8794 (define_insn "*<arith_shift_insn>_multsi"
8795 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8796 (SHIFTABLE_OPS:SI
8797 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8798 (match_operand:SI 3 "power_of_two_operand" ""))
8799 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8800 "TARGET_32BIT"
8801 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8802 [(set_attr "predicable" "yes")
8803 (set_attr "predicable_short_it" "no")
8804 (set_attr "shift" "2")
8805 (set_attr "arch" "a,t2")
8806 (set_attr "type" "alu_shift_imm")])
8807
8808 (define_insn "*<arith_shift_insn>_shiftsi"
8809 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8810 (SHIFTABLE_OPS:SI
8811 (match_operator:SI 2 "shift_nomul_operator"
8812 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8813 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8814 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8815 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8816 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8817 [(set_attr "predicable" "yes")
8818 (set_attr "predicable_short_it" "no")
8819 (set_attr "shift" "3")
8820 (set_attr "arch" "a,t2,a")
8821 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8822
8823 (define_split
8824 [(set (match_operand:SI 0 "s_register_operand" "")
8825 (match_operator:SI 1 "shiftable_operator"
8826 [(match_operator:SI 2 "shiftable_operator"
8827 [(match_operator:SI 3 "shift_operator"
8828 [(match_operand:SI 4 "s_register_operand" "")
8829 (match_operand:SI 5 "reg_or_int_operand" "")])
8830 (match_operand:SI 6 "s_register_operand" "")])
8831 (match_operand:SI 7 "arm_rhs_operand" "")]))
8832 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8833 "TARGET_32BIT"
8834 [(set (match_dup 8)
8835 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8836 (match_dup 6)]))
8837 (set (match_dup 0)
8838 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8839 "")
8840
8841 (define_insn "*arith_shiftsi_compare0"
8842 [(set (reg:CC_NOOV CC_REGNUM)
8843 (compare:CC_NOOV
8844 (match_operator:SI 1 "shiftable_operator"
8845 [(match_operator:SI 3 "shift_operator"
8846 [(match_operand:SI 4 "s_register_operand" "r,r")
8847 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8848 (match_operand:SI 2 "s_register_operand" "r,r")])
8849 (const_int 0)))
8850 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8851 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8852 (match_dup 2)]))]
8853 "TARGET_32BIT"
8854 "%i1s%?\\t%0, %2, %4%S3"
8855 [(set_attr "conds" "set")
8856 (set_attr "shift" "4")
8857 (set_attr "arch" "32,a")
8858 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8859
8860 (define_insn "*arith_shiftsi_compare0_scratch"
8861 [(set (reg:CC_NOOV CC_REGNUM)
8862 (compare:CC_NOOV
8863 (match_operator:SI 1 "shiftable_operator"
8864 [(match_operator:SI 3 "shift_operator"
8865 [(match_operand:SI 4 "s_register_operand" "r,r")
8866 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8867 (match_operand:SI 2 "s_register_operand" "r,r")])
8868 (const_int 0)))
8869 (clobber (match_scratch:SI 0 "=r,r"))]
8870 "TARGET_32BIT"
8871 "%i1s%?\\t%0, %2, %4%S3"
8872 [(set_attr "conds" "set")
8873 (set_attr "shift" "4")
8874 (set_attr "arch" "32,a")
8875 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8876
8877 (define_insn "*sub_shiftsi"
8878 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8879 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8880 (match_operator:SI 2 "shift_operator"
8881 [(match_operand:SI 3 "s_register_operand" "r,r")
8882 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8883 "TARGET_32BIT"
8884 "sub%?\\t%0, %1, %3%S2"
8885 [(set_attr "predicable" "yes")
8886 (set_attr "shift" "3")
8887 (set_attr "arch" "32,a")
8888 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8889
8890 (define_insn "*sub_shiftsi_compare0"
8891 [(set (reg:CC_NOOV CC_REGNUM)
8892 (compare:CC_NOOV
8893 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8894 (match_operator:SI 2 "shift_operator"
8895 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8896 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8897 (const_int 0)))
8898 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8899 (minus:SI (match_dup 1)
8900 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8901 "TARGET_32BIT"
8902 "subs%?\\t%0, %1, %3%S2"
8903 [(set_attr "conds" "set")
8904 (set_attr "shift" "3")
8905 (set_attr "arch" "32,a,a")
8906 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8907
8908 (define_insn "*sub_shiftsi_compare0_scratch"
8909 [(set (reg:CC_NOOV CC_REGNUM)
8910 (compare:CC_NOOV
8911 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8912 (match_operator:SI 2 "shift_operator"
8913 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8914 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8915 (const_int 0)))
8916 (clobber (match_scratch:SI 0 "=r,r,r"))]
8917 "TARGET_32BIT"
8918 "subs%?\\t%0, %1, %3%S2"
8919 [(set_attr "conds" "set")
8920 (set_attr "shift" "3")
8921 (set_attr "arch" "32,a,a")
8922 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8923 \f
8924
8925 (define_insn_and_split "*and_scc"
8926 [(set (match_operand:SI 0 "s_register_operand" "=r")
8927 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8928 [(match_operand 2 "cc_register" "") (const_int 0)])
8929 (match_operand:SI 3 "s_register_operand" "r")))]
8930 "TARGET_ARM"
8931 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8932 "&& reload_completed"
8933 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8934 (cond_exec (match_dup 4) (set (match_dup 0)
8935 (and:SI (match_dup 3) (const_int 1))))]
8936 {
8937 machine_mode mode = GET_MODE (operands[2]);
8938 enum rtx_code rc = GET_CODE (operands[1]);
8939
8940 /* Note that operands[4] is the same as operands[1],
8941 but with VOIDmode as the result. */
8942 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8943 if (mode == CCFPmode || mode == CCFPEmode)
8944 rc = reverse_condition_maybe_unordered (rc);
8945 else
8946 rc = reverse_condition (rc);
8947 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8948 }
8949 [(set_attr "conds" "use")
8950 (set_attr "type" "multiple")
8951 (set_attr "length" "8")]
8952 )
8953
8954 (define_insn_and_split "*ior_scc"
8955 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8956 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8957 [(match_operand 2 "cc_register" "") (const_int 0)])
8958 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8959 "TARGET_ARM"
8960 "@
8961 orr%d1\\t%0, %3, #1
8962 #"
8963 "&& reload_completed
8964 && REGNO (operands [0]) != REGNO (operands[3])"
8965 ;; && which_alternative == 1
8966 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8967 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8968 (cond_exec (match_dup 4) (set (match_dup 0)
8969 (ior:SI (match_dup 3) (const_int 1))))]
8970 {
8971 machine_mode mode = GET_MODE (operands[2]);
8972 enum rtx_code rc = GET_CODE (operands[1]);
8973
8974 /* Note that operands[4] is the same as operands[1],
8975 but with VOIDmode as the result. */
8976 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8977 if (mode == CCFPmode || mode == CCFPEmode)
8978 rc = reverse_condition_maybe_unordered (rc);
8979 else
8980 rc = reverse_condition (rc);
8981 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8982 }
8983 [(set_attr "conds" "use")
8984 (set_attr "length" "4,8")
8985 (set_attr "type" "logic_imm,multiple")]
8986 )
8987
8988 ; A series of splitters for the compare_scc pattern below. Note that
8989 ; order is important.
8990 (define_split
8991 [(set (match_operand:SI 0 "s_register_operand" "")
8992 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8993 (const_int 0)))
8994 (clobber (reg:CC CC_REGNUM))]
8995 "TARGET_32BIT && reload_completed"
8996 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8997
8998 (define_split
8999 [(set (match_operand:SI 0 "s_register_operand" "")
9000 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9001 (const_int 0)))
9002 (clobber (reg:CC CC_REGNUM))]
9003 "TARGET_32BIT && reload_completed"
9004 [(set (match_dup 0) (not:SI (match_dup 1)))
9005 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9006
9007 (define_split
9008 [(set (match_operand:SI 0 "s_register_operand" "")
9009 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9010 (const_int 0)))
9011 (clobber (reg:CC CC_REGNUM))]
9012 "arm_arch5 && TARGET_32BIT"
9013 [(set (match_dup 0) (clz:SI (match_dup 1)))
9014 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9015 )
9016
9017 (define_split
9018 [(set (match_operand:SI 0 "s_register_operand" "")
9019 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9020 (const_int 0)))
9021 (clobber (reg:CC CC_REGNUM))]
9022 "TARGET_32BIT && reload_completed"
9023 [(parallel
9024 [(set (reg:CC CC_REGNUM)
9025 (compare:CC (const_int 1) (match_dup 1)))
9026 (set (match_dup 0)
9027 (minus:SI (const_int 1) (match_dup 1)))])
9028 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9029 (set (match_dup 0) (const_int 0)))])
9030
9031 (define_split
9032 [(set (match_operand:SI 0 "s_register_operand" "")
9033 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9034 (match_operand:SI 2 "const_int_operand" "")))
9035 (clobber (reg:CC CC_REGNUM))]
9036 "TARGET_32BIT && reload_completed"
9037 [(parallel
9038 [(set (reg:CC CC_REGNUM)
9039 (compare:CC (match_dup 1) (match_dup 2)))
9040 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9041 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9042 (set (match_dup 0) (const_int 1)))]
9043 {
9044 operands[3] = GEN_INT (-INTVAL (operands[2]));
9045 })
9046
9047 (define_split
9048 [(set (match_operand:SI 0 "s_register_operand" "")
9049 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9050 (match_operand:SI 2 "arm_add_operand" "")))
9051 (clobber (reg:CC CC_REGNUM))]
9052 "TARGET_32BIT && reload_completed"
9053 [(parallel
9054 [(set (reg:CC_NOOV CC_REGNUM)
9055 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9056 (const_int 0)))
9057 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9058 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9059 (set (match_dup 0) (const_int 1)))])
9060
9061 (define_insn_and_split "*compare_scc"
9062 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9063 (match_operator:SI 1 "arm_comparison_operator"
9064 [(match_operand:SI 2 "s_register_operand" "r,r")
9065 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9066 (clobber (reg:CC CC_REGNUM))]
9067 "TARGET_32BIT"
9068 "#"
9069 "&& reload_completed"
9070 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9071 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9072 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9073 {
9074 rtx tmp1;
9075 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9076 operands[2], operands[3]);
9077 enum rtx_code rc = GET_CODE (operands[1]);
9078
9079 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9080
9081 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9082 if (mode == CCFPmode || mode == CCFPEmode)
9083 rc = reverse_condition_maybe_unordered (rc);
9084 else
9085 rc = reverse_condition (rc);
9086 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9087 }
9088 [(set_attr "type" "multiple")]
9089 )
9090
9091 ;; Attempt to improve the sequence generated by the compare_scc splitters
9092 ;; not to use conditional execution.
9093
9094 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9095 ;; clz Rd, reg1
9096 ;; lsr Rd, Rd, #5
9097 (define_peephole2
9098 [(set (reg:CC CC_REGNUM)
9099 (compare:CC (match_operand:SI 1 "register_operand" "")
9100 (const_int 0)))
9101 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9102 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9103 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9104 (set (match_dup 0) (const_int 1)))]
9105 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9106 [(set (match_dup 0) (clz:SI (match_dup 1)))
9107 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9108 )
9109
9110 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9111 ;; negs Rd, reg1
9112 ;; adc Rd, Rd, reg1
9113 (define_peephole2
9114 [(set (reg:CC CC_REGNUM)
9115 (compare:CC (match_operand:SI 1 "register_operand" "")
9116 (const_int 0)))
9117 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9118 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9119 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9120 (set (match_dup 0) (const_int 1)))
9121 (match_scratch:SI 2 "r")]
9122 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9123 [(parallel
9124 [(set (reg:CC CC_REGNUM)
9125 (compare:CC (const_int 0) (match_dup 1)))
9126 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9127 (set (match_dup 0)
9128 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9129 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9130 )
9131
9132 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9133 ;; sub Rd, Reg1, reg2
9134 ;; clz Rd, Rd
9135 ;; lsr Rd, Rd, #5
9136 (define_peephole2
9137 [(set (reg:CC CC_REGNUM)
9138 (compare:CC (match_operand:SI 1 "register_operand" "")
9139 (match_operand:SI 2 "arm_rhs_operand" "")))
9140 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9141 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9142 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9143 (set (match_dup 0) (const_int 1)))]
9144 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9145 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9146 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9147 (set (match_dup 0) (clz:SI (match_dup 0)))
9148 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9149 )
9150
9151
9152 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9153 ;; sub T1, Reg1, reg2
9154 ;; negs Rd, T1
9155 ;; adc Rd, Rd, T1
9156 (define_peephole2
9157 [(set (reg:CC CC_REGNUM)
9158 (compare:CC (match_operand:SI 1 "register_operand" "")
9159 (match_operand:SI 2 "arm_rhs_operand" "")))
9160 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9161 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9162 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9163 (set (match_dup 0) (const_int 1)))
9164 (match_scratch:SI 3 "r")]
9165 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9166 [(set (match_dup 3) (match_dup 4))
9167 (parallel
9168 [(set (reg:CC CC_REGNUM)
9169 (compare:CC (const_int 0) (match_dup 3)))
9170 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9171 (set (match_dup 0)
9172 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9173 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9174 "
9175 if (CONST_INT_P (operands[2]))
9176 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9177 else
9178 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9179 ")
9180
9181 (define_insn "*cond_move"
9182 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9183 (if_then_else:SI (match_operator 3 "equality_operator"
9184 [(match_operator 4 "arm_comparison_operator"
9185 [(match_operand 5 "cc_register" "") (const_int 0)])
9186 (const_int 0)])
9187 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9188 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9189 "TARGET_ARM"
9190 "*
9191 if (GET_CODE (operands[3]) == NE)
9192 {
9193 if (which_alternative != 1)
9194 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9195 if (which_alternative != 0)
9196 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9197 return \"\";
9198 }
9199 if (which_alternative != 0)
9200 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9201 if (which_alternative != 1)
9202 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9203 return \"\";
9204 "
9205 [(set_attr "conds" "use")
9206 (set_attr_alternative "type"
9207 [(if_then_else (match_operand 2 "const_int_operand" "")
9208 (const_string "mov_imm")
9209 (const_string "mov_reg"))
9210 (if_then_else (match_operand 1 "const_int_operand" "")
9211 (const_string "mov_imm")
9212 (const_string "mov_reg"))
9213 (const_string "multiple")])
9214 (set_attr "length" "4,4,8")]
9215 )
9216
9217 (define_insn "*cond_arith"
9218 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9219 (match_operator:SI 5 "shiftable_operator"
9220 [(match_operator:SI 4 "arm_comparison_operator"
9221 [(match_operand:SI 2 "s_register_operand" "r,r")
9222 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9223 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9224 (clobber (reg:CC CC_REGNUM))]
9225 "TARGET_ARM"
9226 "*
9227 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9228 return \"%i5\\t%0, %1, %2, lsr #31\";
9229
9230 output_asm_insn (\"cmp\\t%2, %3\", operands);
9231 if (GET_CODE (operands[5]) == AND)
9232 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9233 else if (GET_CODE (operands[5]) == MINUS)
9234 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9235 else if (which_alternative != 0)
9236 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9237 return \"%i5%d4\\t%0, %1, #1\";
9238 "
9239 [(set_attr "conds" "clob")
9240 (set_attr "length" "12")
9241 (set_attr "type" "multiple")]
9242 )
9243
9244 (define_insn "*cond_sub"
9245 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9246 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9247 (match_operator:SI 4 "arm_comparison_operator"
9248 [(match_operand:SI 2 "s_register_operand" "r,r")
9249 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9250 (clobber (reg:CC CC_REGNUM))]
9251 "TARGET_ARM"
9252 "*
9253 output_asm_insn (\"cmp\\t%2, %3\", operands);
9254 if (which_alternative != 0)
9255 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9256 return \"sub%d4\\t%0, %1, #1\";
9257 "
9258 [(set_attr "conds" "clob")
9259 (set_attr "length" "8,12")
9260 (set_attr "type" "multiple")]
9261 )
9262
9263 (define_insn "*cmp_ite0"
9264 [(set (match_operand 6 "dominant_cc_register" "")
9265 (compare
9266 (if_then_else:SI
9267 (match_operator 4 "arm_comparison_operator"
9268 [(match_operand:SI 0 "s_register_operand"
9269 "l,l,l,r,r,r,r,r,r")
9270 (match_operand:SI 1 "arm_add_operand"
9271 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9272 (match_operator:SI 5 "arm_comparison_operator"
9273 [(match_operand:SI 2 "s_register_operand"
9274 "l,r,r,l,l,r,r,r,r")
9275 (match_operand:SI 3 "arm_add_operand"
9276 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9277 (const_int 0))
9278 (const_int 0)))]
9279 "TARGET_32BIT"
9280 "*
9281 {
9282 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9283 {
9284 {\"cmp%d5\\t%0, %1\",
9285 \"cmp%d4\\t%2, %3\"},
9286 {\"cmn%d5\\t%0, #%n1\",
9287 \"cmp%d4\\t%2, %3\"},
9288 {\"cmp%d5\\t%0, %1\",
9289 \"cmn%d4\\t%2, #%n3\"},
9290 {\"cmn%d5\\t%0, #%n1\",
9291 \"cmn%d4\\t%2, #%n3\"}
9292 };
9293 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9294 {
9295 {\"cmp\\t%2, %3\",
9296 \"cmp\\t%0, %1\"},
9297 {\"cmp\\t%2, %3\",
9298 \"cmn\\t%0, #%n1\"},
9299 {\"cmn\\t%2, #%n3\",
9300 \"cmp\\t%0, %1\"},
9301 {\"cmn\\t%2, #%n3\",
9302 \"cmn\\t%0, #%n1\"}
9303 };
9304 static const char * const ite[2] =
9305 {
9306 \"it\\t%d5\",
9307 \"it\\t%d4\"
9308 };
9309 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9310 CMP_CMP, CMN_CMP, CMP_CMP,
9311 CMN_CMP, CMP_CMN, CMN_CMN};
9312 int swap =
9313 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9314
9315 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9316 if (TARGET_THUMB2) {
9317 output_asm_insn (ite[swap], operands);
9318 }
9319 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9320 return \"\";
9321 }"
9322 [(set_attr "conds" "set")
9323 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9324 (set_attr "type" "multiple")
9325 (set_attr_alternative "length"
9326 [(const_int 6)
9327 (const_int 8)
9328 (const_int 8)
9329 (const_int 8)
9330 (const_int 8)
9331 (if_then_else (eq_attr "is_thumb" "no")
9332 (const_int 8)
9333 (const_int 10))
9334 (if_then_else (eq_attr "is_thumb" "no")
9335 (const_int 8)
9336 (const_int 10))
9337 (if_then_else (eq_attr "is_thumb" "no")
9338 (const_int 8)
9339 (const_int 10))
9340 (if_then_else (eq_attr "is_thumb" "no")
9341 (const_int 8)
9342 (const_int 10))])]
9343 )
9344
9345 (define_insn "*cmp_ite1"
9346 [(set (match_operand 6 "dominant_cc_register" "")
9347 (compare
9348 (if_then_else:SI
9349 (match_operator 4 "arm_comparison_operator"
9350 [(match_operand:SI 0 "s_register_operand"
9351 "l,l,l,r,r,r,r,r,r")
9352 (match_operand:SI 1 "arm_add_operand"
9353 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9354 (match_operator:SI 5 "arm_comparison_operator"
9355 [(match_operand:SI 2 "s_register_operand"
9356 "l,r,r,l,l,r,r,r,r")
9357 (match_operand:SI 3 "arm_add_operand"
9358 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9359 (const_int 1))
9360 (const_int 0)))]
9361 "TARGET_32BIT"
9362 "*
9363 {
9364 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9365 {
9366 {\"cmp\\t%0, %1\",
9367 \"cmp\\t%2, %3\"},
9368 {\"cmn\\t%0, #%n1\",
9369 \"cmp\\t%2, %3\"},
9370 {\"cmp\\t%0, %1\",
9371 \"cmn\\t%2, #%n3\"},
9372 {\"cmn\\t%0, #%n1\",
9373 \"cmn\\t%2, #%n3\"}
9374 };
9375 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9376 {
9377 {\"cmp%d4\\t%2, %3\",
9378 \"cmp%D5\\t%0, %1\"},
9379 {\"cmp%d4\\t%2, %3\",
9380 \"cmn%D5\\t%0, #%n1\"},
9381 {\"cmn%d4\\t%2, #%n3\",
9382 \"cmp%D5\\t%0, %1\"},
9383 {\"cmn%d4\\t%2, #%n3\",
9384 \"cmn%D5\\t%0, #%n1\"}
9385 };
9386 static const char * const ite[2] =
9387 {
9388 \"it\\t%d4\",
9389 \"it\\t%D5\"
9390 };
9391 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9392 CMP_CMP, CMN_CMP, CMP_CMP,
9393 CMN_CMP, CMP_CMN, CMN_CMN};
9394 int swap =
9395 comparison_dominates_p (GET_CODE (operands[5]),
9396 reverse_condition (GET_CODE (operands[4])));
9397
9398 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9399 if (TARGET_THUMB2) {
9400 output_asm_insn (ite[swap], operands);
9401 }
9402 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9403 return \"\";
9404 }"
9405 [(set_attr "conds" "set")
9406 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9407 (set_attr_alternative "length"
9408 [(const_int 6)
9409 (const_int 8)
9410 (const_int 8)
9411 (const_int 8)
9412 (const_int 8)
9413 (if_then_else (eq_attr "is_thumb" "no")
9414 (const_int 8)
9415 (const_int 10))
9416 (if_then_else (eq_attr "is_thumb" "no")
9417 (const_int 8)
9418 (const_int 10))
9419 (if_then_else (eq_attr "is_thumb" "no")
9420 (const_int 8)
9421 (const_int 10))
9422 (if_then_else (eq_attr "is_thumb" "no")
9423 (const_int 8)
9424 (const_int 10))])
9425 (set_attr "type" "multiple")]
9426 )
9427
9428 (define_insn "*cmp_and"
9429 [(set (match_operand 6 "dominant_cc_register" "")
9430 (compare
9431 (and:SI
9432 (match_operator 4 "arm_comparison_operator"
9433 [(match_operand:SI 0 "s_register_operand"
9434 "l,l,l,r,r,r,r,r,r")
9435 (match_operand:SI 1 "arm_add_operand"
9436 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9437 (match_operator:SI 5 "arm_comparison_operator"
9438 [(match_operand:SI 2 "s_register_operand"
9439 "l,r,r,l,l,r,r,r,r")
9440 (match_operand:SI 3 "arm_add_operand"
9441 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9442 (const_int 0)))]
9443 "TARGET_32BIT"
9444 "*
9445 {
9446 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9447 {
9448 {\"cmp%d5\\t%0, %1\",
9449 \"cmp%d4\\t%2, %3\"},
9450 {\"cmn%d5\\t%0, #%n1\",
9451 \"cmp%d4\\t%2, %3\"},
9452 {\"cmp%d5\\t%0, %1\",
9453 \"cmn%d4\\t%2, #%n3\"},
9454 {\"cmn%d5\\t%0, #%n1\",
9455 \"cmn%d4\\t%2, #%n3\"}
9456 };
9457 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9458 {
9459 {\"cmp\\t%2, %3\",
9460 \"cmp\\t%0, %1\"},
9461 {\"cmp\\t%2, %3\",
9462 \"cmn\\t%0, #%n1\"},
9463 {\"cmn\\t%2, #%n3\",
9464 \"cmp\\t%0, %1\"},
9465 {\"cmn\\t%2, #%n3\",
9466 \"cmn\\t%0, #%n1\"}
9467 };
9468 static const char *const ite[2] =
9469 {
9470 \"it\\t%d5\",
9471 \"it\\t%d4\"
9472 };
9473 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9474 CMP_CMP, CMN_CMP, CMP_CMP,
9475 CMN_CMP, CMP_CMN, CMN_CMN};
9476 int swap =
9477 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9478
9479 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9480 if (TARGET_THUMB2) {
9481 output_asm_insn (ite[swap], operands);
9482 }
9483 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9484 return \"\";
9485 }"
9486 [(set_attr "conds" "set")
9487 (set_attr "predicable" "no")
9488 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9489 (set_attr_alternative "length"
9490 [(const_int 6)
9491 (const_int 8)
9492 (const_int 8)
9493 (const_int 8)
9494 (const_int 8)
9495 (if_then_else (eq_attr "is_thumb" "no")
9496 (const_int 8)
9497 (const_int 10))
9498 (if_then_else (eq_attr "is_thumb" "no")
9499 (const_int 8)
9500 (const_int 10))
9501 (if_then_else (eq_attr "is_thumb" "no")
9502 (const_int 8)
9503 (const_int 10))
9504 (if_then_else (eq_attr "is_thumb" "no")
9505 (const_int 8)
9506 (const_int 10))])
9507 (set_attr "type" "multiple")]
9508 )
9509
9510 (define_insn "*cmp_ior"
9511 [(set (match_operand 6 "dominant_cc_register" "")
9512 (compare
9513 (ior:SI
9514 (match_operator 4 "arm_comparison_operator"
9515 [(match_operand:SI 0 "s_register_operand"
9516 "l,l,l,r,r,r,r,r,r")
9517 (match_operand:SI 1 "arm_add_operand"
9518 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9519 (match_operator:SI 5 "arm_comparison_operator"
9520 [(match_operand:SI 2 "s_register_operand"
9521 "l,r,r,l,l,r,r,r,r")
9522 (match_operand:SI 3 "arm_add_operand"
9523 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9524 (const_int 0)))]
9525 "TARGET_32BIT"
9526 "*
9527 {
9528 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9529 {
9530 {\"cmp\\t%0, %1\",
9531 \"cmp\\t%2, %3\"},
9532 {\"cmn\\t%0, #%n1\",
9533 \"cmp\\t%2, %3\"},
9534 {\"cmp\\t%0, %1\",
9535 \"cmn\\t%2, #%n3\"},
9536 {\"cmn\\t%0, #%n1\",
9537 \"cmn\\t%2, #%n3\"}
9538 };
9539 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9540 {
9541 {\"cmp%D4\\t%2, %3\",
9542 \"cmp%D5\\t%0, %1\"},
9543 {\"cmp%D4\\t%2, %3\",
9544 \"cmn%D5\\t%0, #%n1\"},
9545 {\"cmn%D4\\t%2, #%n3\",
9546 \"cmp%D5\\t%0, %1\"},
9547 {\"cmn%D4\\t%2, #%n3\",
9548 \"cmn%D5\\t%0, #%n1\"}
9549 };
9550 static const char *const ite[2] =
9551 {
9552 \"it\\t%D4\",
9553 \"it\\t%D5\"
9554 };
9555 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9556 CMP_CMP, CMN_CMP, CMP_CMP,
9557 CMN_CMP, CMP_CMN, CMN_CMN};
9558 int swap =
9559 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9560
9561 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9562 if (TARGET_THUMB2) {
9563 output_asm_insn (ite[swap], operands);
9564 }
9565 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9566 return \"\";
9567 }
9568 "
9569 [(set_attr "conds" "set")
9570 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9571 (set_attr_alternative "length"
9572 [(const_int 6)
9573 (const_int 8)
9574 (const_int 8)
9575 (const_int 8)
9576 (const_int 8)
9577 (if_then_else (eq_attr "is_thumb" "no")
9578 (const_int 8)
9579 (const_int 10))
9580 (if_then_else (eq_attr "is_thumb" "no")
9581 (const_int 8)
9582 (const_int 10))
9583 (if_then_else (eq_attr "is_thumb" "no")
9584 (const_int 8)
9585 (const_int 10))
9586 (if_then_else (eq_attr "is_thumb" "no")
9587 (const_int 8)
9588 (const_int 10))])
9589 (set_attr "type" "multiple")]
9590 )
9591
9592 (define_insn_and_split "*ior_scc_scc"
9593 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9594 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9595 [(match_operand:SI 1 "s_register_operand" "r")
9596 (match_operand:SI 2 "arm_add_operand" "rIL")])
9597 (match_operator:SI 6 "arm_comparison_operator"
9598 [(match_operand:SI 4 "s_register_operand" "r")
9599 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9600 (clobber (reg:CC CC_REGNUM))]
9601 "TARGET_32BIT
9602 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9603 != CCmode)"
9604 "#"
9605 "TARGET_32BIT && reload_completed"
9606 [(set (match_dup 7)
9607 (compare
9608 (ior:SI
9609 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9610 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9611 (const_int 0)))
9612 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9613 "operands[7]
9614 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9615 DOM_CC_X_OR_Y),
9616 CC_REGNUM);"
9617 [(set_attr "conds" "clob")
9618 (set_attr "length" "16")
9619 (set_attr "type" "multiple")]
9620 )
9621
9622 ; If the above pattern is followed by a CMP insn, then the compare is
9623 ; redundant, since we can rework the conditional instruction that follows.
9624 (define_insn_and_split "*ior_scc_scc_cmp"
9625 [(set (match_operand 0 "dominant_cc_register" "")
9626 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9627 [(match_operand:SI 1 "s_register_operand" "r")
9628 (match_operand:SI 2 "arm_add_operand" "rIL")])
9629 (match_operator:SI 6 "arm_comparison_operator"
9630 [(match_operand:SI 4 "s_register_operand" "r")
9631 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9632 (const_int 0)))
9633 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9634 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9635 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9636 "TARGET_32BIT"
9637 "#"
9638 "TARGET_32BIT && reload_completed"
9639 [(set (match_dup 0)
9640 (compare
9641 (ior:SI
9642 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9643 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9644 (const_int 0)))
9645 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9646 ""
9647 [(set_attr "conds" "set")
9648 (set_attr "length" "16")
9649 (set_attr "type" "multiple")]
9650 )
9651
9652 (define_insn_and_split "*and_scc_scc"
9653 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9654 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9655 [(match_operand:SI 1 "s_register_operand" "r")
9656 (match_operand:SI 2 "arm_add_operand" "rIL")])
9657 (match_operator:SI 6 "arm_comparison_operator"
9658 [(match_operand:SI 4 "s_register_operand" "r")
9659 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9660 (clobber (reg:CC CC_REGNUM))]
9661 "TARGET_32BIT
9662 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9663 != CCmode)"
9664 "#"
9665 "TARGET_32BIT && reload_completed
9666 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9667 != CCmode)"
9668 [(set (match_dup 7)
9669 (compare
9670 (and:SI
9671 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9672 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9673 (const_int 0)))
9674 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9675 "operands[7]
9676 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9677 DOM_CC_X_AND_Y),
9678 CC_REGNUM);"
9679 [(set_attr "conds" "clob")
9680 (set_attr "length" "16")
9681 (set_attr "type" "multiple")]
9682 )
9683
9684 ; If the above pattern is followed by a CMP insn, then the compare is
9685 ; redundant, since we can rework the conditional instruction that follows.
9686 (define_insn_and_split "*and_scc_scc_cmp"
9687 [(set (match_operand 0 "dominant_cc_register" "")
9688 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9689 [(match_operand:SI 1 "s_register_operand" "r")
9690 (match_operand:SI 2 "arm_add_operand" "rIL")])
9691 (match_operator:SI 6 "arm_comparison_operator"
9692 [(match_operand:SI 4 "s_register_operand" "r")
9693 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9694 (const_int 0)))
9695 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9696 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9697 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9698 "TARGET_32BIT"
9699 "#"
9700 "TARGET_32BIT && reload_completed"
9701 [(set (match_dup 0)
9702 (compare
9703 (and:SI
9704 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9705 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9706 (const_int 0)))
9707 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9708 ""
9709 [(set_attr "conds" "set")
9710 (set_attr "length" "16")
9711 (set_attr "type" "multiple")]
9712 )
9713
9714 ;; If there is no dominance in the comparison, then we can still save an
9715 ;; instruction in the AND case, since we can know that the second compare
9716 ;; need only zero the value if false (if true, then the value is already
9717 ;; correct).
9718 (define_insn_and_split "*and_scc_scc_nodom"
9719 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9720 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9721 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9722 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9723 (match_operator:SI 6 "arm_comparison_operator"
9724 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9725 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9726 (clobber (reg:CC CC_REGNUM))]
9727 "TARGET_32BIT
9728 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9729 == CCmode)"
9730 "#"
9731 "TARGET_32BIT && reload_completed"
9732 [(parallel [(set (match_dup 0)
9733 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9734 (clobber (reg:CC CC_REGNUM))])
9735 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9736 (set (match_dup 0)
9737 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9738 (match_dup 0)
9739 (const_int 0)))]
9740 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9741 operands[4], operands[5]),
9742 CC_REGNUM);
9743 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9744 operands[5]);"
9745 [(set_attr "conds" "clob")
9746 (set_attr "length" "20")
9747 (set_attr "type" "multiple")]
9748 )
9749
9750 (define_split
9751 [(set (reg:CC_NOOV CC_REGNUM)
9752 (compare:CC_NOOV (ior:SI
9753 (and:SI (match_operand:SI 0 "s_register_operand" "")
9754 (const_int 1))
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 (const_int 0)))
9759 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9760 "TARGET_ARM"
9761 [(set (match_dup 4)
9762 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9763 (match_dup 0)))
9764 (set (reg:CC_NOOV CC_REGNUM)
9765 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9766 (const_int 0)))]
9767 "")
9768
9769 (define_split
9770 [(set (reg:CC_NOOV CC_REGNUM)
9771 (compare:CC_NOOV (ior:SI
9772 (match_operator:SI 1 "arm_comparison_operator"
9773 [(match_operand:SI 2 "s_register_operand" "")
9774 (match_operand:SI 3 "arm_add_operand" "")])
9775 (and:SI (match_operand:SI 0 "s_register_operand" "")
9776 (const_int 1)))
9777 (const_int 0)))
9778 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9779 "TARGET_ARM"
9780 [(set (match_dup 4)
9781 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9782 (match_dup 0)))
9783 (set (reg:CC_NOOV CC_REGNUM)
9784 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9785 (const_int 0)))]
9786 "")
9787 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9788
9789 (define_insn_and_split "*negscc"
9790 [(set (match_operand:SI 0 "s_register_operand" "=r")
9791 (neg:SI (match_operator 3 "arm_comparison_operator"
9792 [(match_operand:SI 1 "s_register_operand" "r")
9793 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9794 (clobber (reg:CC CC_REGNUM))]
9795 "TARGET_ARM"
9796 "#"
9797 "&& reload_completed"
9798 [(const_int 0)]
9799 {
9800 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9801
9802 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9803 {
9804 /* Emit mov\\t%0, %1, asr #31 */
9805 emit_insn (gen_rtx_SET (operands[0],
9806 gen_rtx_ASHIFTRT (SImode,
9807 operands[1],
9808 GEN_INT (31))));
9809 DONE;
9810 }
9811 else if (GET_CODE (operands[3]) == NE)
9812 {
9813 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9814 if (CONST_INT_P (operands[2]))
9815 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9816 GEN_INT (- INTVAL (operands[2]))));
9817 else
9818 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9819
9820 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9821 gen_rtx_NE (SImode,
9822 cc_reg,
9823 const0_rtx),
9824 gen_rtx_SET (operands[0],
9825 GEN_INT (~0))));
9826 DONE;
9827 }
9828 else
9829 {
9830 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9831 emit_insn (gen_rtx_SET (cc_reg,
9832 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9833 enum rtx_code rc = GET_CODE (operands[3]);
9834
9835 rc = reverse_condition (rc);
9836 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9837 gen_rtx_fmt_ee (rc,
9838 VOIDmode,
9839 cc_reg,
9840 const0_rtx),
9841 gen_rtx_SET (operands[0], const0_rtx)));
9842 rc = GET_CODE (operands[3]);
9843 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9844 gen_rtx_fmt_ee (rc,
9845 VOIDmode,
9846 cc_reg,
9847 const0_rtx),
9848 gen_rtx_SET (operands[0],
9849 GEN_INT (~0))));
9850 DONE;
9851 }
9852 FAIL;
9853 }
9854 [(set_attr "conds" "clob")
9855 (set_attr "length" "12")
9856 (set_attr "type" "multiple")]
9857 )
9858
9859 (define_insn_and_split "movcond_addsi"
9860 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9861 (if_then_else:SI
9862 (match_operator 5 "comparison_operator"
9863 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9864 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9865 (const_int 0)])
9866 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9867 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9868 (clobber (reg:CC CC_REGNUM))]
9869 "TARGET_32BIT"
9870 "#"
9871 "&& reload_completed"
9872 [(set (reg:CC_NOOV CC_REGNUM)
9873 (compare:CC_NOOV
9874 (plus:SI (match_dup 3)
9875 (match_dup 4))
9876 (const_int 0)))
9877 (set (match_dup 0) (match_dup 1))
9878 (cond_exec (match_dup 6)
9879 (set (match_dup 0) (match_dup 2)))]
9880 "
9881 {
9882 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9883 operands[3], operands[4]);
9884 enum rtx_code rc = GET_CODE (operands[5]);
9885 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9886 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9887 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9888 rc = reverse_condition (rc);
9889 else
9890 std::swap (operands[1], operands[2]);
9891
9892 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9893 }
9894 "
9895 [(set_attr "conds" "clob")
9896 (set_attr "enabled_for_depr_it" "no,yes,yes")
9897 (set_attr "type" "multiple")]
9898 )
9899
9900 (define_insn "movcond"
9901 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9902 (if_then_else:SI
9903 (match_operator 5 "arm_comparison_operator"
9904 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9905 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9906 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9907 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9908 (clobber (reg:CC CC_REGNUM))]
9909 "TARGET_ARM"
9910 "*
9911 if (GET_CODE (operands[5]) == LT
9912 && (operands[4] == const0_rtx))
9913 {
9914 if (which_alternative != 1 && REG_P (operands[1]))
9915 {
9916 if (operands[2] == const0_rtx)
9917 return \"and\\t%0, %1, %3, asr #31\";
9918 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9919 }
9920 else if (which_alternative != 0 && REG_P (operands[2]))
9921 {
9922 if (operands[1] == const0_rtx)
9923 return \"bic\\t%0, %2, %3, asr #31\";
9924 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9925 }
9926 /* The only case that falls through to here is when both ops 1 & 2
9927 are constants. */
9928 }
9929
9930 if (GET_CODE (operands[5]) == GE
9931 && (operands[4] == const0_rtx))
9932 {
9933 if (which_alternative != 1 && REG_P (operands[1]))
9934 {
9935 if (operands[2] == const0_rtx)
9936 return \"bic\\t%0, %1, %3, asr #31\";
9937 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9938 }
9939 else if (which_alternative != 0 && REG_P (operands[2]))
9940 {
9941 if (operands[1] == const0_rtx)
9942 return \"and\\t%0, %2, %3, asr #31\";
9943 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9944 }
9945 /* The only case that falls through to here is when both ops 1 & 2
9946 are constants. */
9947 }
9948 if (CONST_INT_P (operands[4])
9949 && !const_ok_for_arm (INTVAL (operands[4])))
9950 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9951 else
9952 output_asm_insn (\"cmp\\t%3, %4\", operands);
9953 if (which_alternative != 0)
9954 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9955 if (which_alternative != 1)
9956 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9957 return \"\";
9958 "
9959 [(set_attr "conds" "clob")
9960 (set_attr "length" "8,8,12")
9961 (set_attr "type" "multiple")]
9962 )
9963
9964 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9965
9966 (define_insn "*ifcompare_plus_move"
9967 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9968 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9969 [(match_operand:SI 4 "s_register_operand" "r,r")
9970 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9971 (plus:SI
9972 (match_operand:SI 2 "s_register_operand" "r,r")
9973 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9974 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9975 (clobber (reg:CC CC_REGNUM))]
9976 "TARGET_ARM"
9977 "#"
9978 [(set_attr "conds" "clob")
9979 (set_attr "length" "8,12")
9980 (set_attr "type" "multiple")]
9981 )
9982
9983 (define_insn "*if_plus_move"
9984 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9985 (if_then_else:SI
9986 (match_operator 4 "arm_comparison_operator"
9987 [(match_operand 5 "cc_register" "") (const_int 0)])
9988 (plus:SI
9989 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9990 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9991 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9992 "TARGET_ARM"
9993 "@
9994 add%d4\\t%0, %2, %3
9995 sub%d4\\t%0, %2, #%n3
9996 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9997 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9998 [(set_attr "conds" "use")
9999 (set_attr "length" "4,4,8,8")
10000 (set_attr_alternative "type"
10001 [(if_then_else (match_operand 3 "const_int_operand" "")
10002 (const_string "alu_imm" )
10003 (const_string "alu_sreg"))
10004 (const_string "alu_imm")
10005 (const_string "multiple")
10006 (const_string "multiple")])]
10007 )
10008
10009 (define_insn "*ifcompare_move_plus"
10010 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10011 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10012 [(match_operand:SI 4 "s_register_operand" "r,r")
10013 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10014 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10015 (plus:SI
10016 (match_operand:SI 2 "s_register_operand" "r,r")
10017 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10018 (clobber (reg:CC CC_REGNUM))]
10019 "TARGET_ARM"
10020 "#"
10021 [(set_attr "conds" "clob")
10022 (set_attr "length" "8,12")
10023 (set_attr "type" "multiple")]
10024 )
10025
10026 (define_insn "*if_move_plus"
10027 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10028 (if_then_else:SI
10029 (match_operator 4 "arm_comparison_operator"
10030 [(match_operand 5 "cc_register" "") (const_int 0)])
10031 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10032 (plus:SI
10033 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10034 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10035 "TARGET_ARM"
10036 "@
10037 add%D4\\t%0, %2, %3
10038 sub%D4\\t%0, %2, #%n3
10039 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10040 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10041 [(set_attr "conds" "use")
10042 (set_attr "length" "4,4,8,8")
10043 (set_attr_alternative "type"
10044 [(if_then_else (match_operand 3 "const_int_operand" "")
10045 (const_string "alu_imm" )
10046 (const_string "alu_sreg"))
10047 (const_string "alu_imm")
10048 (const_string "multiple")
10049 (const_string "multiple")])]
10050 )
10051
10052 (define_insn "*ifcompare_arith_arith"
10053 [(set (match_operand:SI 0 "s_register_operand" "=r")
10054 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10055 [(match_operand:SI 5 "s_register_operand" "r")
10056 (match_operand:SI 6 "arm_add_operand" "rIL")])
10057 (match_operator:SI 8 "shiftable_operator"
10058 [(match_operand:SI 1 "s_register_operand" "r")
10059 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10060 (match_operator:SI 7 "shiftable_operator"
10061 [(match_operand:SI 3 "s_register_operand" "r")
10062 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10063 (clobber (reg:CC CC_REGNUM))]
10064 "TARGET_ARM"
10065 "#"
10066 [(set_attr "conds" "clob")
10067 (set_attr "length" "12")
10068 (set_attr "type" "multiple")]
10069 )
10070
10071 (define_insn "*if_arith_arith"
10072 [(set (match_operand:SI 0 "s_register_operand" "=r")
10073 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10074 [(match_operand 8 "cc_register" "") (const_int 0)])
10075 (match_operator:SI 6 "shiftable_operator"
10076 [(match_operand:SI 1 "s_register_operand" "r")
10077 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10078 (match_operator:SI 7 "shiftable_operator"
10079 [(match_operand:SI 3 "s_register_operand" "r")
10080 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10081 "TARGET_ARM"
10082 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10083 [(set_attr "conds" "use")
10084 (set_attr "length" "8")
10085 (set_attr "type" "multiple")]
10086 )
10087
10088 (define_insn "*ifcompare_arith_move"
10089 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10090 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10091 [(match_operand:SI 2 "s_register_operand" "r,r")
10092 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10093 (match_operator:SI 7 "shiftable_operator"
10094 [(match_operand:SI 4 "s_register_operand" "r,r")
10095 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10096 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10097 (clobber (reg:CC CC_REGNUM))]
10098 "TARGET_ARM"
10099 "*
10100 /* If we have an operation where (op x 0) is the identity operation and
10101 the conditional operator is LT or GE and we are comparing against zero and
10102 everything is in registers then we can do this in two instructions. */
10103 if (operands[3] == const0_rtx
10104 && GET_CODE (operands[7]) != AND
10105 && REG_P (operands[5])
10106 && REG_P (operands[1])
10107 && REGNO (operands[1]) == REGNO (operands[4])
10108 && REGNO (operands[4]) != REGNO (operands[0]))
10109 {
10110 if (GET_CODE (operands[6]) == LT)
10111 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10112 else if (GET_CODE (operands[6]) == GE)
10113 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10114 }
10115 if (CONST_INT_P (operands[3])
10116 && !const_ok_for_arm (INTVAL (operands[3])))
10117 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10118 else
10119 output_asm_insn (\"cmp\\t%2, %3\", operands);
10120 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10121 if (which_alternative != 0)
10122 return \"mov%D6\\t%0, %1\";
10123 return \"\";
10124 "
10125 [(set_attr "conds" "clob")
10126 (set_attr "length" "8,12")
10127 (set_attr "type" "multiple")]
10128 )
10129
10130 (define_insn "*if_arith_move"
10131 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10132 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10133 [(match_operand 6 "cc_register" "") (const_int 0)])
10134 (match_operator:SI 5 "shiftable_operator"
10135 [(match_operand:SI 2 "s_register_operand" "r,r")
10136 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10137 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10138 "TARGET_ARM"
10139 "@
10140 %I5%d4\\t%0, %2, %3
10141 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10142 [(set_attr "conds" "use")
10143 (set_attr "length" "4,8")
10144 (set_attr_alternative "type"
10145 [(if_then_else (match_operand 3 "const_int_operand" "")
10146 (const_string "alu_shift_imm" )
10147 (const_string "alu_shift_reg"))
10148 (const_string "multiple")])]
10149 )
10150
10151 (define_insn "*ifcompare_move_arith"
10152 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10153 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10154 [(match_operand:SI 4 "s_register_operand" "r,r")
10155 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10156 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10157 (match_operator:SI 7 "shiftable_operator"
10158 [(match_operand:SI 2 "s_register_operand" "r,r")
10159 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10160 (clobber (reg:CC CC_REGNUM))]
10161 "TARGET_ARM"
10162 "*
10163 /* If we have an operation where (op x 0) is the identity operation and
10164 the conditional operator is LT or GE and we are comparing against zero and
10165 everything is in registers then we can do this in two instructions */
10166 if (operands[5] == const0_rtx
10167 && GET_CODE (operands[7]) != AND
10168 && REG_P (operands[3])
10169 && REG_P (operands[1])
10170 && REGNO (operands[1]) == REGNO (operands[2])
10171 && REGNO (operands[2]) != REGNO (operands[0]))
10172 {
10173 if (GET_CODE (operands[6]) == GE)
10174 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10175 else if (GET_CODE (operands[6]) == LT)
10176 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10177 }
10178
10179 if (CONST_INT_P (operands[5])
10180 && !const_ok_for_arm (INTVAL (operands[5])))
10181 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10182 else
10183 output_asm_insn (\"cmp\\t%4, %5\", operands);
10184
10185 if (which_alternative != 0)
10186 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10187 return \"%I7%D6\\t%0, %2, %3\";
10188 "
10189 [(set_attr "conds" "clob")
10190 (set_attr "length" "8,12")
10191 (set_attr "type" "multiple")]
10192 )
10193
10194 (define_insn "*if_move_arith"
10195 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10196 (if_then_else:SI
10197 (match_operator 4 "arm_comparison_operator"
10198 [(match_operand 6 "cc_register" "") (const_int 0)])
10199 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10200 (match_operator:SI 5 "shiftable_operator"
10201 [(match_operand:SI 2 "s_register_operand" "r,r")
10202 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10203 "TARGET_ARM"
10204 "@
10205 %I5%D4\\t%0, %2, %3
10206 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10207 [(set_attr "conds" "use")
10208 (set_attr "length" "4,8")
10209 (set_attr_alternative "type"
10210 [(if_then_else (match_operand 3 "const_int_operand" "")
10211 (const_string "alu_shift_imm" )
10212 (const_string "alu_shift_reg"))
10213 (const_string "multiple")])]
10214 )
10215
10216 (define_insn "*ifcompare_move_not"
10217 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10218 (if_then_else:SI
10219 (match_operator 5 "arm_comparison_operator"
10220 [(match_operand:SI 3 "s_register_operand" "r,r")
10221 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10222 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10223 (not:SI
10224 (match_operand:SI 2 "s_register_operand" "r,r"))))
10225 (clobber (reg:CC CC_REGNUM))]
10226 "TARGET_ARM"
10227 "#"
10228 [(set_attr "conds" "clob")
10229 (set_attr "length" "8,12")
10230 (set_attr "type" "multiple")]
10231 )
10232
10233 (define_insn "*if_move_not"
10234 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10235 (if_then_else:SI
10236 (match_operator 4 "arm_comparison_operator"
10237 [(match_operand 3 "cc_register" "") (const_int 0)])
10238 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10239 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10240 "TARGET_ARM"
10241 "@
10242 mvn%D4\\t%0, %2
10243 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10244 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10245 [(set_attr "conds" "use")
10246 (set_attr "type" "mvn_reg")
10247 (set_attr "length" "4,8,8")
10248 (set_attr "type" "mvn_reg,multiple,multiple")]
10249 )
10250
10251 (define_insn "*ifcompare_not_move"
10252 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10253 (if_then_else:SI
10254 (match_operator 5 "arm_comparison_operator"
10255 [(match_operand:SI 3 "s_register_operand" "r,r")
10256 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10257 (not:SI
10258 (match_operand:SI 2 "s_register_operand" "r,r"))
10259 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10260 (clobber (reg:CC CC_REGNUM))]
10261 "TARGET_ARM"
10262 "#"
10263 [(set_attr "conds" "clob")
10264 (set_attr "length" "8,12")
10265 (set_attr "type" "multiple")]
10266 )
10267
10268 (define_insn "*if_not_move"
10269 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10270 (if_then_else:SI
10271 (match_operator 4 "arm_comparison_operator"
10272 [(match_operand 3 "cc_register" "") (const_int 0)])
10273 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10274 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10275 "TARGET_ARM"
10276 "@
10277 mvn%d4\\t%0, %2
10278 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10279 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10280 [(set_attr "conds" "use")
10281 (set_attr "type" "mvn_reg,multiple,multiple")
10282 (set_attr "length" "4,8,8")]
10283 )
10284
10285 (define_insn "*ifcompare_shift_move"
10286 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10287 (if_then_else:SI
10288 (match_operator 6 "arm_comparison_operator"
10289 [(match_operand:SI 4 "s_register_operand" "r,r")
10290 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10291 (match_operator:SI 7 "shift_operator"
10292 [(match_operand:SI 2 "s_register_operand" "r,r")
10293 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10294 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10295 (clobber (reg:CC CC_REGNUM))]
10296 "TARGET_ARM"
10297 "#"
10298 [(set_attr "conds" "clob")
10299 (set_attr "length" "8,12")
10300 (set_attr "type" "multiple")]
10301 )
10302
10303 (define_insn "*if_shift_move"
10304 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10305 (if_then_else:SI
10306 (match_operator 5 "arm_comparison_operator"
10307 [(match_operand 6 "cc_register" "") (const_int 0)])
10308 (match_operator:SI 4 "shift_operator"
10309 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10310 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10311 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10312 "TARGET_ARM"
10313 "@
10314 mov%d5\\t%0, %2%S4
10315 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10316 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10317 [(set_attr "conds" "use")
10318 (set_attr "shift" "2")
10319 (set_attr "length" "4,8,8")
10320 (set_attr_alternative "type"
10321 [(if_then_else (match_operand 3 "const_int_operand" "")
10322 (const_string "mov_shift" )
10323 (const_string "mov_shift_reg"))
10324 (const_string "multiple")
10325 (const_string "multiple")])]
10326 )
10327
10328 (define_insn "*ifcompare_move_shift"
10329 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10330 (if_then_else:SI
10331 (match_operator 6 "arm_comparison_operator"
10332 [(match_operand:SI 4 "s_register_operand" "r,r")
10333 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10334 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10335 (match_operator:SI 7 "shift_operator"
10336 [(match_operand:SI 2 "s_register_operand" "r,r")
10337 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10338 (clobber (reg:CC CC_REGNUM))]
10339 "TARGET_ARM"
10340 "#"
10341 [(set_attr "conds" "clob")
10342 (set_attr "length" "8,12")
10343 (set_attr "type" "multiple")]
10344 )
10345
10346 (define_insn "*if_move_shift"
10347 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10348 (if_then_else:SI
10349 (match_operator 5 "arm_comparison_operator"
10350 [(match_operand 6 "cc_register" "") (const_int 0)])
10351 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10352 (match_operator:SI 4 "shift_operator"
10353 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10354 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10355 "TARGET_ARM"
10356 "@
10357 mov%D5\\t%0, %2%S4
10358 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10359 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10360 [(set_attr "conds" "use")
10361 (set_attr "shift" "2")
10362 (set_attr "length" "4,8,8")
10363 (set_attr_alternative "type"
10364 [(if_then_else (match_operand 3 "const_int_operand" "")
10365 (const_string "mov_shift" )
10366 (const_string "mov_shift_reg"))
10367 (const_string "multiple")
10368 (const_string "multiple")])]
10369 )
10370
10371 (define_insn "*ifcompare_shift_shift"
10372 [(set (match_operand:SI 0 "s_register_operand" "=r")
10373 (if_then_else:SI
10374 (match_operator 7 "arm_comparison_operator"
10375 [(match_operand:SI 5 "s_register_operand" "r")
10376 (match_operand:SI 6 "arm_add_operand" "rIL")])
10377 (match_operator:SI 8 "shift_operator"
10378 [(match_operand:SI 1 "s_register_operand" "r")
10379 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10380 (match_operator:SI 9 "shift_operator"
10381 [(match_operand:SI 3 "s_register_operand" "r")
10382 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10383 (clobber (reg:CC CC_REGNUM))]
10384 "TARGET_ARM"
10385 "#"
10386 [(set_attr "conds" "clob")
10387 (set_attr "length" "12")
10388 (set_attr "type" "multiple")]
10389 )
10390
10391 (define_insn "*if_shift_shift"
10392 [(set (match_operand:SI 0 "s_register_operand" "=r")
10393 (if_then_else:SI
10394 (match_operator 5 "arm_comparison_operator"
10395 [(match_operand 8 "cc_register" "") (const_int 0)])
10396 (match_operator:SI 6 "shift_operator"
10397 [(match_operand:SI 1 "s_register_operand" "r")
10398 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10399 (match_operator:SI 7 "shift_operator"
10400 [(match_operand:SI 3 "s_register_operand" "r")
10401 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10402 "TARGET_ARM"
10403 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10404 [(set_attr "conds" "use")
10405 (set_attr "shift" "1")
10406 (set_attr "length" "8")
10407 (set (attr "type") (if_then_else
10408 (and (match_operand 2 "const_int_operand" "")
10409 (match_operand 4 "const_int_operand" ""))
10410 (const_string "mov_shift")
10411 (const_string "mov_shift_reg")))]
10412 )
10413
10414 (define_insn "*ifcompare_not_arith"
10415 [(set (match_operand:SI 0 "s_register_operand" "=r")
10416 (if_then_else:SI
10417 (match_operator 6 "arm_comparison_operator"
10418 [(match_operand:SI 4 "s_register_operand" "r")
10419 (match_operand:SI 5 "arm_add_operand" "rIL")])
10420 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10421 (match_operator:SI 7 "shiftable_operator"
10422 [(match_operand:SI 2 "s_register_operand" "r")
10423 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10424 (clobber (reg:CC CC_REGNUM))]
10425 "TARGET_ARM"
10426 "#"
10427 [(set_attr "conds" "clob")
10428 (set_attr "length" "12")
10429 (set_attr "type" "multiple")]
10430 )
10431
10432 (define_insn "*if_not_arith"
10433 [(set (match_operand:SI 0 "s_register_operand" "=r")
10434 (if_then_else:SI
10435 (match_operator 5 "arm_comparison_operator"
10436 [(match_operand 4 "cc_register" "") (const_int 0)])
10437 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10438 (match_operator:SI 6 "shiftable_operator"
10439 [(match_operand:SI 2 "s_register_operand" "r")
10440 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10441 "TARGET_ARM"
10442 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10443 [(set_attr "conds" "use")
10444 (set_attr "type" "mvn_reg")
10445 (set_attr "length" "8")]
10446 )
10447
10448 (define_insn "*ifcompare_arith_not"
10449 [(set (match_operand:SI 0 "s_register_operand" "=r")
10450 (if_then_else:SI
10451 (match_operator 6 "arm_comparison_operator"
10452 [(match_operand:SI 4 "s_register_operand" "r")
10453 (match_operand:SI 5 "arm_add_operand" "rIL")])
10454 (match_operator:SI 7 "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 (clobber (reg:CC CC_REGNUM))]
10459 "TARGET_ARM"
10460 "#"
10461 [(set_attr "conds" "clob")
10462 (set_attr "length" "12")
10463 (set_attr "type" "multiple")]
10464 )
10465
10466 (define_insn "*if_arith_not"
10467 [(set (match_operand:SI 0 "s_register_operand" "=r")
10468 (if_then_else:SI
10469 (match_operator 5 "arm_comparison_operator"
10470 [(match_operand 4 "cc_register" "") (const_int 0)])
10471 (match_operator:SI 6 "shiftable_operator"
10472 [(match_operand:SI 2 "s_register_operand" "r")
10473 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10474 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10475 "TARGET_ARM"
10476 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10477 [(set_attr "conds" "use")
10478 (set_attr "type" "multiple")
10479 (set_attr "length" "8")]
10480 )
10481
10482 (define_insn "*ifcompare_neg_move"
10483 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10484 (if_then_else:SI
10485 (match_operator 5 "arm_comparison_operator"
10486 [(match_operand:SI 3 "s_register_operand" "r,r")
10487 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10488 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10489 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10490 (clobber (reg:CC CC_REGNUM))]
10491 "TARGET_ARM"
10492 "#"
10493 [(set_attr "conds" "clob")
10494 (set_attr "length" "8,12")
10495 (set_attr "type" "multiple")]
10496 )
10497
10498 (define_insn_and_split "*if_neg_move"
10499 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10500 (if_then_else:SI
10501 (match_operator 4 "arm_comparison_operator"
10502 [(match_operand 3 "cc_register" "") (const_int 0)])
10503 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10504 (match_operand:SI 1 "s_register_operand" "0,0")))]
10505 "TARGET_32BIT"
10506 "#"
10507 "&& reload_completed"
10508 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10509 (set (match_dup 0) (neg:SI (match_dup 2))))]
10510 ""
10511 [(set_attr "conds" "use")
10512 (set_attr "length" "4")
10513 (set_attr "arch" "t2,32")
10514 (set_attr "enabled_for_depr_it" "yes,no")
10515 (set_attr "type" "logic_shift_imm")]
10516 )
10517
10518 (define_insn "*ifcompare_move_neg"
10519 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10520 (if_then_else:SI
10521 (match_operator 5 "arm_comparison_operator"
10522 [(match_operand:SI 3 "s_register_operand" "r,r")
10523 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10524 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10525 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10526 (clobber (reg:CC CC_REGNUM))]
10527 "TARGET_ARM"
10528 "#"
10529 [(set_attr "conds" "clob")
10530 (set_attr "length" "8,12")
10531 (set_attr "type" "multiple")]
10532 )
10533
10534 (define_insn_and_split "*if_move_neg"
10535 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10536 (if_then_else:SI
10537 (match_operator 4 "arm_comparison_operator"
10538 [(match_operand 3 "cc_register" "") (const_int 0)])
10539 (match_operand:SI 1 "s_register_operand" "0,0")
10540 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10541 "TARGET_32BIT"
10542 "#"
10543 "&& reload_completed"
10544 [(cond_exec (match_dup 5)
10545 (set (match_dup 0) (neg:SI (match_dup 2))))]
10546 {
10547 machine_mode mode = GET_MODE (operands[3]);
10548 rtx_code rc = GET_CODE (operands[4]);
10549
10550 if (mode == CCFPmode || mode == CCFPEmode)
10551 rc = reverse_condition_maybe_unordered (rc);
10552 else
10553 rc = reverse_condition (rc);
10554
10555 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10556 }
10557 [(set_attr "conds" "use")
10558 (set_attr "length" "4")
10559 (set_attr "arch" "t2,32")
10560 (set_attr "enabled_for_depr_it" "yes,no")
10561 (set_attr "type" "logic_shift_imm")]
10562 )
10563
10564 (define_insn "*arith_adjacentmem"
10565 [(set (match_operand:SI 0 "s_register_operand" "=r")
10566 (match_operator:SI 1 "shiftable_operator"
10567 [(match_operand:SI 2 "memory_operand" "m")
10568 (match_operand:SI 3 "memory_operand" "m")]))
10569 (clobber (match_scratch:SI 4 "=r"))]
10570 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10571 "*
10572 {
10573 rtx ldm[3];
10574 rtx arith[4];
10575 rtx base_reg;
10576 HOST_WIDE_INT val1 = 0, val2 = 0;
10577
10578 if (REGNO (operands[0]) > REGNO (operands[4]))
10579 {
10580 ldm[1] = operands[4];
10581 ldm[2] = operands[0];
10582 }
10583 else
10584 {
10585 ldm[1] = operands[0];
10586 ldm[2] = operands[4];
10587 }
10588
10589 base_reg = XEXP (operands[2], 0);
10590
10591 if (!REG_P (base_reg))
10592 {
10593 val1 = INTVAL (XEXP (base_reg, 1));
10594 base_reg = XEXP (base_reg, 0);
10595 }
10596
10597 if (!REG_P (XEXP (operands[3], 0)))
10598 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10599
10600 arith[0] = operands[0];
10601 arith[3] = operands[1];
10602
10603 if (val1 < val2)
10604 {
10605 arith[1] = ldm[1];
10606 arith[2] = ldm[2];
10607 }
10608 else
10609 {
10610 arith[1] = ldm[2];
10611 arith[2] = ldm[1];
10612 }
10613
10614 ldm[0] = base_reg;
10615 if (val1 !=0 && val2 != 0)
10616 {
10617 rtx ops[3];
10618
10619 if (val1 == 4 || val2 == 4)
10620 /* Other val must be 8, since we know they are adjacent and neither
10621 is zero. */
10622 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10623 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10624 {
10625 ldm[0] = ops[0] = operands[4];
10626 ops[1] = base_reg;
10627 ops[2] = GEN_INT (val1);
10628 output_add_immediate (ops);
10629 if (val1 < val2)
10630 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10631 else
10632 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10633 }
10634 else
10635 {
10636 /* Offset is out of range for a single add, so use two ldr. */
10637 ops[0] = ldm[1];
10638 ops[1] = base_reg;
10639 ops[2] = GEN_INT (val1);
10640 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10641 ops[0] = ldm[2];
10642 ops[2] = GEN_INT (val2);
10643 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10644 }
10645 }
10646 else if (val1 != 0)
10647 {
10648 if (val1 < val2)
10649 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10650 else
10651 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10652 }
10653 else
10654 {
10655 if (val1 < val2)
10656 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10657 else
10658 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10659 }
10660 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10661 return \"\";
10662 }"
10663 [(set_attr "length" "12")
10664 (set_attr "predicable" "yes")
10665 (set_attr "type" "load1")]
10666 )
10667
10668 ; This pattern is never tried by combine, so do it as a peephole
10669
10670 (define_peephole2
10671 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10672 (match_operand:SI 1 "arm_general_register_operand" ""))
10673 (set (reg:CC CC_REGNUM)
10674 (compare:CC (match_dup 1) (const_int 0)))]
10675 "TARGET_ARM"
10676 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10677 (set (match_dup 0) (match_dup 1))])]
10678 ""
10679 )
10680
10681 (define_split
10682 [(set (match_operand:SI 0 "s_register_operand" "")
10683 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10684 (const_int 0))
10685 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10686 [(match_operand:SI 3 "s_register_operand" "")
10687 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10688 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10689 "TARGET_ARM"
10690 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10691 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10692 (match_dup 5)))]
10693 ""
10694 )
10695
10696 ;; This split can be used because CC_Z mode implies that the following
10697 ;; branch will be an equality, or an unsigned inequality, so the sign
10698 ;; extension is not needed.
10699
10700 (define_split
10701 [(set (reg:CC_Z CC_REGNUM)
10702 (compare:CC_Z
10703 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10704 (const_int 24))
10705 (match_operand 1 "const_int_operand" "")))
10706 (clobber (match_scratch:SI 2 ""))]
10707 "TARGET_ARM
10708 && ((UINTVAL (operands[1]))
10709 == ((UINTVAL (operands[1])) >> 24) << 24)"
10710 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10711 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10712 "
10713 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10714 "
10715 )
10716 ;; ??? Check the patterns above for Thumb-2 usefulness
10717
10718 (define_expand "prologue"
10719 [(clobber (const_int 0))]
10720 "TARGET_EITHER"
10721 "if (TARGET_32BIT)
10722 arm_expand_prologue ();
10723 else
10724 thumb1_expand_prologue ();
10725 DONE;
10726 "
10727 )
10728
10729 (define_expand "epilogue"
10730 [(clobber (const_int 0))]
10731 "TARGET_EITHER"
10732 "
10733 if (crtl->calls_eh_return)
10734 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10735 if (TARGET_THUMB1)
10736 {
10737 thumb1_expand_epilogue ();
10738 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10739 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10740 }
10741 else if (HAVE_return)
10742 {
10743 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10744 no need for explicit testing again. */
10745 emit_jump_insn (gen_return ());
10746 }
10747 else if (TARGET_32BIT)
10748 {
10749 arm_expand_epilogue (true);
10750 }
10751 DONE;
10752 "
10753 )
10754
10755 ;; Note - although unspec_volatile's USE all hard registers,
10756 ;; USEs are ignored after relaod has completed. Thus we need
10757 ;; to add an unspec of the link register to ensure that flow
10758 ;; does not think that it is unused by the sibcall branch that
10759 ;; will replace the standard function epilogue.
10760 (define_expand "sibcall_epilogue"
10761 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10762 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10763 "TARGET_32BIT"
10764 "
10765 arm_expand_epilogue (false);
10766 DONE;
10767 "
10768 )
10769
10770 (define_expand "eh_epilogue"
10771 [(use (match_operand:SI 0 "register_operand" ""))
10772 (use (match_operand:SI 1 "register_operand" ""))
10773 (use (match_operand:SI 2 "register_operand" ""))]
10774 "TARGET_EITHER"
10775 "
10776 {
10777 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10778 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10779 {
10780 rtx ra = gen_rtx_REG (Pmode, 2);
10781
10782 emit_move_insn (ra, operands[2]);
10783 operands[2] = ra;
10784 }
10785 /* This is a hack -- we may have crystalized the function type too
10786 early. */
10787 cfun->machine->func_type = 0;
10788 }"
10789 )
10790
10791 ;; This split is only used during output to reduce the number of patterns
10792 ;; that need assembler instructions adding to them. We allowed the setting
10793 ;; of the conditions to be implicit during rtl generation so that
10794 ;; the conditional compare patterns would work. However this conflicts to
10795 ;; some extent with the conditional data operations, so we have to split them
10796 ;; up again here.
10797
10798 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10799 ;; conditional execution sufficient?
10800
10801 (define_split
10802 [(set (match_operand:SI 0 "s_register_operand" "")
10803 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10804 [(match_operand 2 "" "") (match_operand 3 "" "")])
10805 (match_dup 0)
10806 (match_operand 4 "" "")))
10807 (clobber (reg:CC CC_REGNUM))]
10808 "TARGET_ARM && reload_completed"
10809 [(set (match_dup 5) (match_dup 6))
10810 (cond_exec (match_dup 7)
10811 (set (match_dup 0) (match_dup 4)))]
10812 "
10813 {
10814 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10815 operands[2], operands[3]);
10816 enum rtx_code rc = GET_CODE (operands[1]);
10817
10818 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10819 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10820 if (mode == CCFPmode || mode == CCFPEmode)
10821 rc = reverse_condition_maybe_unordered (rc);
10822 else
10823 rc = reverse_condition (rc);
10824
10825 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10826 }"
10827 )
10828
10829 (define_split
10830 [(set (match_operand:SI 0 "s_register_operand" "")
10831 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10832 [(match_operand 2 "" "") (match_operand 3 "" "")])
10833 (match_operand 4 "" "")
10834 (match_dup 0)))
10835 (clobber (reg:CC CC_REGNUM))]
10836 "TARGET_ARM && reload_completed"
10837 [(set (match_dup 5) (match_dup 6))
10838 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10839 (set (match_dup 0) (match_dup 4)))]
10840 "
10841 {
10842 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10843 operands[2], operands[3]);
10844
10845 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10846 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10847 }"
10848 )
10849
10850 (define_split
10851 [(set (match_operand:SI 0 "s_register_operand" "")
10852 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10853 [(match_operand 2 "" "") (match_operand 3 "" "")])
10854 (match_operand 4 "" "")
10855 (match_operand 5 "" "")))
10856 (clobber (reg:CC CC_REGNUM))]
10857 "TARGET_ARM && reload_completed"
10858 [(set (match_dup 6) (match_dup 7))
10859 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10860 (set (match_dup 0) (match_dup 4)))
10861 (cond_exec (match_dup 8)
10862 (set (match_dup 0) (match_dup 5)))]
10863 "
10864 {
10865 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10866 operands[2], operands[3]);
10867 enum rtx_code rc = GET_CODE (operands[1]);
10868
10869 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10870 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10871 if (mode == CCFPmode || mode == CCFPEmode)
10872 rc = reverse_condition_maybe_unordered (rc);
10873 else
10874 rc = reverse_condition (rc);
10875
10876 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10877 }"
10878 )
10879
10880 (define_split
10881 [(set (match_operand:SI 0 "s_register_operand" "")
10882 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10883 [(match_operand:SI 2 "s_register_operand" "")
10884 (match_operand:SI 3 "arm_add_operand" "")])
10885 (match_operand:SI 4 "arm_rhs_operand" "")
10886 (not:SI
10887 (match_operand:SI 5 "s_register_operand" ""))))
10888 (clobber (reg:CC CC_REGNUM))]
10889 "TARGET_ARM && reload_completed"
10890 [(set (match_dup 6) (match_dup 7))
10891 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10892 (set (match_dup 0) (match_dup 4)))
10893 (cond_exec (match_dup 8)
10894 (set (match_dup 0) (not:SI (match_dup 5))))]
10895 "
10896 {
10897 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10898 operands[2], operands[3]);
10899 enum rtx_code rc = GET_CODE (operands[1]);
10900
10901 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10902 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10903 if (mode == CCFPmode || mode == CCFPEmode)
10904 rc = reverse_condition_maybe_unordered (rc);
10905 else
10906 rc = reverse_condition (rc);
10907
10908 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10909 }"
10910 )
10911
10912 (define_insn "*cond_move_not"
10913 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10914 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10915 [(match_operand 3 "cc_register" "") (const_int 0)])
10916 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10917 (not:SI
10918 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10919 "TARGET_ARM"
10920 "@
10921 mvn%D4\\t%0, %2
10922 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10923 [(set_attr "conds" "use")
10924 (set_attr "type" "mvn_reg,multiple")
10925 (set_attr "length" "4,8")]
10926 )
10927
10928 ;; The next two patterns occur when an AND operation is followed by a
10929 ;; scc insn sequence
10930
10931 (define_insn "*sign_extract_onebit"
10932 [(set (match_operand:SI 0 "s_register_operand" "=r")
10933 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10934 (const_int 1)
10935 (match_operand:SI 2 "const_int_operand" "n")))
10936 (clobber (reg:CC CC_REGNUM))]
10937 "TARGET_ARM"
10938 "*
10939 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10940 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10941 return \"mvnne\\t%0, #0\";
10942 "
10943 [(set_attr "conds" "clob")
10944 (set_attr "length" "8")
10945 (set_attr "type" "multiple")]
10946 )
10947
10948 (define_insn "*not_signextract_onebit"
10949 [(set (match_operand:SI 0 "s_register_operand" "=r")
10950 (not:SI
10951 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10952 (const_int 1)
10953 (match_operand:SI 2 "const_int_operand" "n"))))
10954 (clobber (reg:CC CC_REGNUM))]
10955 "TARGET_ARM"
10956 "*
10957 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10958 output_asm_insn (\"tst\\t%1, %2\", operands);
10959 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10960 return \"movne\\t%0, #0\";
10961 "
10962 [(set_attr "conds" "clob")
10963 (set_attr "length" "12")
10964 (set_attr "type" "multiple")]
10965 )
10966 ;; ??? The above patterns need auditing for Thumb-2
10967
10968 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10969 ;; expressions. For simplicity, the first register is also in the unspec
10970 ;; part.
10971 ;; To avoid the usage of GNU extension, the length attribute is computed
10972 ;; in a C function arm_attr_length_push_multi.
10973 (define_insn "*push_multi"
10974 [(match_parallel 2 "multi_register_push"
10975 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10976 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10977 UNSPEC_PUSH_MULT))])]
10978 ""
10979 "*
10980 {
10981 int num_saves = XVECLEN (operands[2], 0);
10982
10983 /* For the StrongARM at least it is faster to
10984 use STR to store only a single register.
10985 In Thumb mode always use push, and the assembler will pick
10986 something appropriate. */
10987 if (num_saves == 1 && TARGET_ARM)
10988 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10989 else
10990 {
10991 int i;
10992 char pattern[100];
10993
10994 if (TARGET_32BIT)
10995 strcpy (pattern, \"push%?\\t{%1\");
10996 else
10997 strcpy (pattern, \"push\\t{%1\");
10998
10999 for (i = 1; i < num_saves; i++)
11000 {
11001 strcat (pattern, \", %|\");
11002 strcat (pattern,
11003 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11004 }
11005
11006 strcat (pattern, \"}\");
11007 output_asm_insn (pattern, operands);
11008 }
11009
11010 return \"\";
11011 }"
11012 [(set_attr "type" "store4")
11013 (set (attr "length")
11014 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11015 )
11016
11017 (define_insn "stack_tie"
11018 [(set (mem:BLK (scratch))
11019 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11020 (match_operand:SI 1 "s_register_operand" "rk")]
11021 UNSPEC_PRLG_STK))]
11022 ""
11023 ""
11024 [(set_attr "length" "0")
11025 (set_attr "type" "block")]
11026 )
11027
11028 ;; Pop (as used in epilogue RTL)
11029 ;;
11030 (define_insn "*load_multiple_with_writeback"
11031 [(match_parallel 0 "load_multiple_operation"
11032 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11033 (plus:SI (match_dup 1)
11034 (match_operand:SI 2 "const_int_I_operand" "I")))
11035 (set (match_operand:SI 3 "s_register_operand" "=rk")
11036 (mem:SI (match_dup 1)))
11037 ])]
11038 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11039 "*
11040 {
11041 arm_output_multireg_pop (operands, /*return_pc=*/false,
11042 /*cond=*/const_true_rtx,
11043 /*reverse=*/false,
11044 /*update=*/true);
11045 return \"\";
11046 }
11047 "
11048 [(set_attr "type" "load4")
11049 (set_attr "predicable" "yes")
11050 (set (attr "length")
11051 (symbol_ref "arm_attr_length_pop_multi (operands,
11052 /*return_pc=*/false,
11053 /*write_back_p=*/true)"))]
11054 )
11055
11056 ;; Pop with return (as used in epilogue RTL)
11057 ;;
11058 ;; This instruction is generated when the registers are popped at the end of
11059 ;; epilogue. Here, instead of popping the value into LR and then generating
11060 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11061 ;; with (return).
11062 (define_insn "*pop_multiple_with_writeback_and_return"
11063 [(match_parallel 0 "pop_multiple_return"
11064 [(return)
11065 (set (match_operand:SI 1 "s_register_operand" "+rk")
11066 (plus:SI (match_dup 1)
11067 (match_operand:SI 2 "const_int_I_operand" "I")))
11068 (set (match_operand:SI 3 "s_register_operand" "=rk")
11069 (mem:SI (match_dup 1)))
11070 ])]
11071 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11072 "*
11073 {
11074 arm_output_multireg_pop (operands, /*return_pc=*/true,
11075 /*cond=*/const_true_rtx,
11076 /*reverse=*/false,
11077 /*update=*/true);
11078 return \"\";
11079 }
11080 "
11081 [(set_attr "type" "load4")
11082 (set_attr "predicable" "yes")
11083 (set (attr "length")
11084 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11085 /*write_back_p=*/true)"))]
11086 )
11087
11088 (define_insn "*pop_multiple_with_return"
11089 [(match_parallel 0 "pop_multiple_return"
11090 [(return)
11091 (set (match_operand:SI 2 "s_register_operand" "=rk")
11092 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11093 ])]
11094 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11095 "*
11096 {
11097 arm_output_multireg_pop (operands, /*return_pc=*/true,
11098 /*cond=*/const_true_rtx,
11099 /*reverse=*/false,
11100 /*update=*/false);
11101 return \"\";
11102 }
11103 "
11104 [(set_attr "type" "load4")
11105 (set_attr "predicable" "yes")
11106 (set (attr "length")
11107 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11108 /*write_back_p=*/false)"))]
11109 )
11110
11111 ;; Load into PC and return
11112 (define_insn "*ldr_with_return"
11113 [(return)
11114 (set (reg:SI PC_REGNUM)
11115 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11116 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11117 "ldr%?\t%|pc, [%0], #4"
11118 [(set_attr "type" "load1")
11119 (set_attr "predicable" "yes")]
11120 )
11121 ;; Pop for floating point registers (as used in epilogue RTL)
11122 (define_insn "*vfp_pop_multiple_with_writeback"
11123 [(match_parallel 0 "pop_multiple_fp"
11124 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11125 (plus:SI (match_dup 1)
11126 (match_operand:SI 2 "const_int_I_operand" "I")))
11127 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11128 (mem:DF (match_dup 1)))])]
11129 "TARGET_32BIT && TARGET_HARD_FLOAT"
11130 "*
11131 {
11132 int num_regs = XVECLEN (operands[0], 0);
11133 char pattern[100];
11134 rtx op_list[2];
11135 strcpy (pattern, \"vldm\\t\");
11136 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11137 strcat (pattern, \"!, {\");
11138 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11139 strcat (pattern, \"%P0\");
11140 if ((num_regs - 1) > 1)
11141 {
11142 strcat (pattern, \"-%P1\");
11143 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11144 }
11145
11146 strcat (pattern, \"}\");
11147 output_asm_insn (pattern, op_list);
11148 return \"\";
11149 }
11150 "
11151 [(set_attr "type" "load4")
11152 (set_attr "conds" "unconditional")
11153 (set_attr "predicable" "no")]
11154 )
11155
11156 ;; Special patterns for dealing with the constant pool
11157
11158 (define_insn "align_4"
11159 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11160 "TARGET_EITHER"
11161 "*
11162 assemble_align (32);
11163 return \"\";
11164 "
11165 [(set_attr "type" "no_insn")]
11166 )
11167
11168 (define_insn "align_8"
11169 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11170 "TARGET_EITHER"
11171 "*
11172 assemble_align (64);
11173 return \"\";
11174 "
11175 [(set_attr "type" "no_insn")]
11176 )
11177
11178 (define_insn "consttable_end"
11179 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11180 "TARGET_EITHER"
11181 "*
11182 making_const_table = FALSE;
11183 return \"\";
11184 "
11185 [(set_attr "type" "no_insn")]
11186 )
11187
11188 (define_insn "consttable_1"
11189 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11190 "TARGET_EITHER"
11191 "*
11192 making_const_table = TRUE;
11193 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11194 assemble_zeros (3);
11195 return \"\";
11196 "
11197 [(set_attr "length" "4")
11198 (set_attr "type" "no_insn")]
11199 )
11200
11201 (define_insn "consttable_2"
11202 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11203 "TARGET_EITHER"
11204 "*
11205 {
11206 rtx x = operands[0];
11207 making_const_table = TRUE;
11208 switch (GET_MODE_CLASS (GET_MODE (x)))
11209 {
11210 case MODE_FLOAT:
11211 arm_emit_fp16_const (x);
11212 break;
11213 default:
11214 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11215 assemble_zeros (2);
11216 break;
11217 }
11218 return \"\";
11219 }"
11220 [(set_attr "length" "4")
11221 (set_attr "type" "no_insn")]
11222 )
11223
11224 (define_insn "consttable_4"
11225 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11226 "TARGET_EITHER"
11227 "*
11228 {
11229 rtx x = operands[0];
11230 making_const_table = TRUE;
11231 switch (GET_MODE_CLASS (GET_MODE (x)))
11232 {
11233 case MODE_FLOAT:
11234 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
11235 BITS_PER_WORD);
11236 break;
11237 default:
11238 /* XXX: Sometimes gcc does something really dumb and ends up with
11239 a HIGH in a constant pool entry, usually because it's trying to
11240 load into a VFP register. We know this will always be used in
11241 combination with a LO_SUM which ignores the high bits, so just
11242 strip off the HIGH. */
11243 if (GET_CODE (x) == HIGH)
11244 x = XEXP (x, 0);
11245 assemble_integer (x, 4, BITS_PER_WORD, 1);
11246 mark_symbol_refs_as_used (x);
11247 break;
11248 }
11249 return \"\";
11250 }"
11251 [(set_attr "length" "4")
11252 (set_attr "type" "no_insn")]
11253 )
11254
11255 (define_insn "consttable_8"
11256 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11257 "TARGET_EITHER"
11258 "*
11259 {
11260 making_const_table = TRUE;
11261 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11262 {
11263 case MODE_FLOAT:
11264 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11265 GET_MODE (operands[0]), BITS_PER_WORD);
11266 break;
11267 default:
11268 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11269 break;
11270 }
11271 return \"\";
11272 }"
11273 [(set_attr "length" "8")
11274 (set_attr "type" "no_insn")]
11275 )
11276
11277 (define_insn "consttable_16"
11278 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11279 "TARGET_EITHER"
11280 "*
11281 {
11282 making_const_table = TRUE;
11283 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11284 {
11285 case MODE_FLOAT:
11286 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11287 GET_MODE (operands[0]), BITS_PER_WORD);
11288 break;
11289 default:
11290 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11291 break;
11292 }
11293 return \"\";
11294 }"
11295 [(set_attr "length" "16")
11296 (set_attr "type" "no_insn")]
11297 )
11298
11299 ;; V5 Instructions,
11300
11301 (define_insn "clzsi2"
11302 [(set (match_operand:SI 0 "s_register_operand" "=r")
11303 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11304 "TARGET_32BIT && arm_arch5"
11305 "clz%?\\t%0, %1"
11306 [(set_attr "predicable" "yes")
11307 (set_attr "predicable_short_it" "no")
11308 (set_attr "type" "clz")])
11309
11310 (define_insn "rbitsi2"
11311 [(set (match_operand:SI 0 "s_register_operand" "=r")
11312 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11313 "TARGET_32BIT && arm_arch_thumb2"
11314 "rbit%?\\t%0, %1"
11315 [(set_attr "predicable" "yes")
11316 (set_attr "predicable_short_it" "no")
11317 (set_attr "type" "clz")])
11318
11319 ;; Keep this as a CTZ expression until after reload and then split
11320 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11321 ;; to fold with any other expression.
11322
11323 (define_insn_and_split "ctzsi2"
11324 [(set (match_operand:SI 0 "s_register_operand" "=r")
11325 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11326 "TARGET_32BIT && arm_arch_thumb2"
11327 "#"
11328 "&& reload_completed"
11329 [(const_int 0)]
11330 "
11331 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11332 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11333 DONE;
11334 ")
11335
11336 ;; V5E instructions.
11337
11338 (define_insn "prefetch"
11339 [(prefetch (match_operand:SI 0 "address_operand" "p")
11340 (match_operand:SI 1 "" "")
11341 (match_operand:SI 2 "" ""))]
11342 "TARGET_32BIT && arm_arch5e"
11343 "pld\\t%a0"
11344 [(set_attr "type" "load1")]
11345 )
11346
11347 ;; General predication pattern
11348
11349 (define_cond_exec
11350 [(match_operator 0 "arm_comparison_operator"
11351 [(match_operand 1 "cc_register" "")
11352 (const_int 0)])]
11353 "TARGET_32BIT
11354 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11355 ""
11356 [(set_attr "predicated" "yes")]
11357 )
11358
11359 (define_insn "force_register_use"
11360 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11361 ""
11362 "%@ %0 needed"
11363 [(set_attr "length" "0")
11364 (set_attr "type" "no_insn")]
11365 )
11366
11367
11368 ;; Patterns for exception handling
11369
11370 (define_expand "eh_return"
11371 [(use (match_operand 0 "general_operand" ""))]
11372 "TARGET_EITHER"
11373 "
11374 {
11375 if (TARGET_32BIT)
11376 emit_insn (gen_arm_eh_return (operands[0]));
11377 else
11378 emit_insn (gen_thumb_eh_return (operands[0]));
11379 DONE;
11380 }"
11381 )
11382
11383 ;; We can't expand this before we know where the link register is stored.
11384 (define_insn_and_split "arm_eh_return"
11385 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11386 VUNSPEC_EH_RETURN)
11387 (clobber (match_scratch:SI 1 "=&r"))]
11388 "TARGET_ARM"
11389 "#"
11390 "&& reload_completed"
11391 [(const_int 0)]
11392 "
11393 {
11394 arm_set_return_address (operands[0], operands[1]);
11395 DONE;
11396 }"
11397 )
11398
11399 \f
11400 ;; TLS support
11401
11402 (define_insn "load_tp_hard"
11403 [(set (match_operand:SI 0 "register_operand" "=r")
11404 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11405 "TARGET_HARD_TP"
11406 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11407 [(set_attr "predicable" "yes")
11408 (set_attr "type" "mrs")]
11409 )
11410
11411 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11412 (define_insn "load_tp_soft"
11413 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11414 (clobber (reg:SI LR_REGNUM))
11415 (clobber (reg:SI IP_REGNUM))
11416 (clobber (reg:CC CC_REGNUM))]
11417 "TARGET_SOFT_TP"
11418 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11419 [(set_attr "conds" "clob")
11420 (set_attr "type" "branch")]
11421 )
11422
11423 ;; tls descriptor call
11424 (define_insn "tlscall"
11425 [(set (reg:SI R0_REGNUM)
11426 (unspec:SI [(reg:SI R0_REGNUM)
11427 (match_operand:SI 0 "" "X")
11428 (match_operand 1 "" "")] UNSPEC_TLS))
11429 (clobber (reg:SI R1_REGNUM))
11430 (clobber (reg:SI LR_REGNUM))
11431 (clobber (reg:SI CC_REGNUM))]
11432 "TARGET_GNU2_TLS"
11433 {
11434 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11435 INTVAL (operands[1]));
11436 return "bl\\t%c0(tlscall)";
11437 }
11438 [(set_attr "conds" "clob")
11439 (set_attr "length" "4")
11440 (set_attr "type" "branch")]
11441 )
11442
11443 ;; For thread pointer builtin
11444 (define_expand "get_thread_pointersi"
11445 [(match_operand:SI 0 "s_register_operand" "=r")]
11446 ""
11447 "
11448 {
11449 arm_load_tp (operands[0]);
11450 DONE;
11451 }")
11452
11453 ;;
11454
11455 ;; We only care about the lower 16 bits of the constant
11456 ;; being inserted into the upper 16 bits of the register.
11457 (define_insn "*arm_movtas_ze"
11458 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11459 (const_int 16)
11460 (const_int 16))
11461 (match_operand:SI 1 "const_int_operand" ""))]
11462 "TARGET_HAVE_MOVT"
11463 "@
11464 movt%?\t%0, %L1
11465 movt\t%0, %L1"
11466 [(set_attr "arch" "32,v8mb")
11467 (set_attr "predicable" "yes")
11468 (set_attr "predicable_short_it" "no")
11469 (set_attr "length" "4")
11470 (set_attr "type" "alu_sreg")]
11471 )
11472
11473 (define_insn "*arm_rev"
11474 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11475 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11476 "arm_arch6"
11477 "@
11478 rev\t%0, %1
11479 rev%?\t%0, %1
11480 rev%?\t%0, %1"
11481 [(set_attr "arch" "t1,t2,32")
11482 (set_attr "length" "2,2,4")
11483 (set_attr "predicable" "no,yes,yes")
11484 (set_attr "predicable_short_it" "no")
11485 (set_attr "type" "rev")]
11486 )
11487
11488 (define_expand "arm_legacy_rev"
11489 [(set (match_operand:SI 2 "s_register_operand" "")
11490 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11491 (const_int 16))
11492 (match_dup 1)))
11493 (set (match_dup 2)
11494 (lshiftrt:SI (match_dup 2)
11495 (const_int 8)))
11496 (set (match_operand:SI 3 "s_register_operand" "")
11497 (rotatert:SI (match_dup 1)
11498 (const_int 8)))
11499 (set (match_dup 2)
11500 (and:SI (match_dup 2)
11501 (const_int -65281)))
11502 (set (match_operand:SI 0 "s_register_operand" "")
11503 (xor:SI (match_dup 3)
11504 (match_dup 2)))]
11505 "TARGET_32BIT"
11506 ""
11507 )
11508
11509 ;; Reuse temporaries to keep register pressure down.
11510 (define_expand "thumb_legacy_rev"
11511 [(set (match_operand:SI 2 "s_register_operand" "")
11512 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11513 (const_int 24)))
11514 (set (match_operand:SI 3 "s_register_operand" "")
11515 (lshiftrt:SI (match_dup 1)
11516 (const_int 24)))
11517 (set (match_dup 3)
11518 (ior:SI (match_dup 3)
11519 (match_dup 2)))
11520 (set (match_operand:SI 4 "s_register_operand" "")
11521 (const_int 16))
11522 (set (match_operand:SI 5 "s_register_operand" "")
11523 (rotatert:SI (match_dup 1)
11524 (match_dup 4)))
11525 (set (match_dup 2)
11526 (ashift:SI (match_dup 5)
11527 (const_int 24)))
11528 (set (match_dup 5)
11529 (lshiftrt:SI (match_dup 5)
11530 (const_int 24)))
11531 (set (match_dup 5)
11532 (ior:SI (match_dup 5)
11533 (match_dup 2)))
11534 (set (match_dup 5)
11535 (rotatert:SI (match_dup 5)
11536 (match_dup 4)))
11537 (set (match_operand:SI 0 "s_register_operand" "")
11538 (ior:SI (match_dup 5)
11539 (match_dup 3)))]
11540 "TARGET_THUMB"
11541 ""
11542 )
11543
11544 ;; ARM-specific expansion of signed mod by power of 2
11545 ;; using conditional negate.
11546 ;; For r0 % n where n is a power of 2 produce:
11547 ;; rsbs r1, r0, #0
11548 ;; and r0, r0, #(n - 1)
11549 ;; and r1, r1, #(n - 1)
11550 ;; rsbpl r0, r1, #0
11551
11552 (define_expand "modsi3"
11553 [(match_operand:SI 0 "register_operand" "")
11554 (match_operand:SI 1 "register_operand" "")
11555 (match_operand:SI 2 "const_int_operand" "")]
11556 "TARGET_32BIT"
11557 {
11558 HOST_WIDE_INT val = INTVAL (operands[2]);
11559
11560 if (val <= 0
11561 || exact_log2 (val) <= 0)
11562 FAIL;
11563
11564 rtx mask = GEN_INT (val - 1);
11565
11566 /* In the special case of x0 % 2 we can do the even shorter:
11567 cmp r0, #0
11568 and r0, r0, #1
11569 rsblt r0, r0, #0. */
11570
11571 if (val == 2)
11572 {
11573 rtx cc_reg = arm_gen_compare_reg (LT,
11574 operands[1], const0_rtx, NULL_RTX);
11575 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11576 rtx masked = gen_reg_rtx (SImode);
11577
11578 emit_insn (gen_andsi3 (masked, operands[1], mask));
11579 emit_move_insn (operands[0],
11580 gen_rtx_IF_THEN_ELSE (SImode, cond,
11581 gen_rtx_NEG (SImode,
11582 masked),
11583 masked));
11584 DONE;
11585 }
11586
11587 rtx neg_op = gen_reg_rtx (SImode);
11588 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11589 operands[1]));
11590
11591 /* Extract the condition register and mode. */
11592 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11593 rtx cc_reg = SET_DEST (cmp);
11594 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11595
11596 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11597
11598 rtx masked_neg = gen_reg_rtx (SImode);
11599 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11600
11601 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11602 during expand does not always work. Do an IF_THEN_ELSE instead. */
11603 emit_move_insn (operands[0],
11604 gen_rtx_IF_THEN_ELSE (SImode, cond,
11605 gen_rtx_NEG (SImode, masked_neg),
11606 operands[0]));
11607
11608
11609 DONE;
11610 }
11611 )
11612
11613 (define_expand "bswapsi2"
11614 [(set (match_operand:SI 0 "s_register_operand" "=r")
11615 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11616 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11617 "
11618 if (!arm_arch6)
11619 {
11620 rtx op2 = gen_reg_rtx (SImode);
11621 rtx op3 = gen_reg_rtx (SImode);
11622
11623 if (TARGET_THUMB)
11624 {
11625 rtx op4 = gen_reg_rtx (SImode);
11626 rtx op5 = gen_reg_rtx (SImode);
11627
11628 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11629 op2, op3, op4, op5));
11630 }
11631 else
11632 {
11633 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11634 op2, op3));
11635 }
11636
11637 DONE;
11638 }
11639 "
11640 )
11641
11642 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11643 ;; and unsigned variants, respectively. For rev16, expose
11644 ;; byte-swapping in the lower 16 bits only.
11645 (define_insn "*arm_revsh"
11646 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11647 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11648 "arm_arch6"
11649 "@
11650 revsh\t%0, %1
11651 revsh%?\t%0, %1
11652 revsh%?\t%0, %1"
11653 [(set_attr "arch" "t1,t2,32")
11654 (set_attr "length" "2,2,4")
11655 (set_attr "type" "rev")]
11656 )
11657
11658 (define_insn "*arm_rev16"
11659 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11660 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11661 "arm_arch6"
11662 "@
11663 rev16\t%0, %1
11664 rev16%?\t%0, %1
11665 rev16%?\t%0, %1"
11666 [(set_attr "arch" "t1,t2,32")
11667 (set_attr "length" "2,2,4")
11668 (set_attr "type" "rev")]
11669 )
11670
11671 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11672 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11673 ;; each valid permutation.
11674
11675 (define_insn "arm_rev16si2"
11676 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11677 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11678 (const_int 8))
11679 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11680 (and:SI (lshiftrt:SI (match_dup 1)
11681 (const_int 8))
11682 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11683 "arm_arch6
11684 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11685 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11686 "rev16\\t%0, %1"
11687 [(set_attr "arch" "t1,t2,32")
11688 (set_attr "length" "2,2,4")
11689 (set_attr "type" "rev")]
11690 )
11691
11692 (define_insn "arm_rev16si2_alt"
11693 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11694 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11695 (const_int 8))
11696 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11697 (and:SI (ashift:SI (match_dup 1)
11698 (const_int 8))
11699 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11700 "arm_arch6
11701 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11702 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11703 "rev16\\t%0, %1"
11704 [(set_attr "arch" "t1,t2,32")
11705 (set_attr "length" "2,2,4")
11706 (set_attr "type" "rev")]
11707 )
11708
11709 (define_expand "bswaphi2"
11710 [(set (match_operand:HI 0 "s_register_operand" "=r")
11711 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11712 "arm_arch6"
11713 ""
11714 )
11715
11716 ;; Patterns for LDRD/STRD in Thumb2 mode
11717
11718 (define_insn "*thumb2_ldrd"
11719 [(set (match_operand:SI 0 "s_register_operand" "=r")
11720 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11721 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11722 (set (match_operand:SI 3 "s_register_operand" "=r")
11723 (mem:SI (plus:SI (match_dup 1)
11724 (match_operand:SI 4 "const_int_operand" ""))))]
11725 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11726 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11727 && (operands_ok_ldrd_strd (operands[0], operands[3],
11728 operands[1], INTVAL (operands[2]),
11729 false, true))"
11730 "ldrd%?\t%0, %3, [%1, %2]"
11731 [(set_attr "type" "load2")
11732 (set_attr "predicable" "yes")
11733 (set_attr "predicable_short_it" "no")])
11734
11735 (define_insn "*thumb2_ldrd_base"
11736 [(set (match_operand:SI 0 "s_register_operand" "=r")
11737 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11738 (set (match_operand:SI 2 "s_register_operand" "=r")
11739 (mem:SI (plus:SI (match_dup 1)
11740 (const_int 4))))]
11741 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11742 && (operands_ok_ldrd_strd (operands[0], operands[2],
11743 operands[1], 0, false, true))"
11744 "ldrd%?\t%0, %2, [%1]"
11745 [(set_attr "type" "load2")
11746 (set_attr "predicable" "yes")
11747 (set_attr "predicable_short_it" "no")])
11748
11749 (define_insn "*thumb2_ldrd_base_neg"
11750 [(set (match_operand:SI 0 "s_register_operand" "=r")
11751 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11752 (const_int -4))))
11753 (set (match_operand:SI 2 "s_register_operand" "=r")
11754 (mem:SI (match_dup 1)))]
11755 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11756 && (operands_ok_ldrd_strd (operands[0], operands[2],
11757 operands[1], -4, false, true))"
11758 "ldrd%?\t%0, %2, [%1, #-4]"
11759 [(set_attr "type" "load2")
11760 (set_attr "predicable" "yes")
11761 (set_attr "predicable_short_it" "no")])
11762
11763 (define_insn "*thumb2_strd"
11764 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11765 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11766 (match_operand:SI 2 "s_register_operand" "r"))
11767 (set (mem:SI (plus:SI (match_dup 0)
11768 (match_operand:SI 3 "const_int_operand" "")))
11769 (match_operand:SI 4 "s_register_operand" "r"))]
11770 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11771 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11772 && (operands_ok_ldrd_strd (operands[2], operands[4],
11773 operands[0], INTVAL (operands[1]),
11774 false, false))"
11775 "strd%?\t%2, %4, [%0, %1]"
11776 [(set_attr "type" "store2")
11777 (set_attr "predicable" "yes")
11778 (set_attr "predicable_short_it" "no")])
11779
11780 (define_insn "*thumb2_strd_base"
11781 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11782 (match_operand:SI 1 "s_register_operand" "r"))
11783 (set (mem:SI (plus:SI (match_dup 0)
11784 (const_int 4)))
11785 (match_operand:SI 2 "s_register_operand" "r"))]
11786 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11787 && (operands_ok_ldrd_strd (operands[1], operands[2],
11788 operands[0], 0, false, false))"
11789 "strd%?\t%1, %2, [%0]"
11790 [(set_attr "type" "store2")
11791 (set_attr "predicable" "yes")
11792 (set_attr "predicable_short_it" "no")])
11793
11794 (define_insn "*thumb2_strd_base_neg"
11795 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11796 (const_int -4)))
11797 (match_operand:SI 1 "s_register_operand" "r"))
11798 (set (mem:SI (match_dup 0))
11799 (match_operand:SI 2 "s_register_operand" "r"))]
11800 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11801 && (operands_ok_ldrd_strd (operands[1], operands[2],
11802 operands[0], -4, false, false))"
11803 "strd%?\t%1, %2, [%0, #-4]"
11804 [(set_attr "type" "store2")
11805 (set_attr "predicable" "yes")
11806 (set_attr "predicable_short_it" "no")])
11807
11808 ;; ARMv8 CRC32 instructions.
11809 (define_insn "<crc_variant>"
11810 [(set (match_operand:SI 0 "s_register_operand" "=r")
11811 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11812 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11813 CRC))]
11814 "TARGET_CRC32"
11815 "<crc_variant>\\t%0, %1, %2"
11816 [(set_attr "type" "crc")
11817 (set_attr "conds" "unconditional")]
11818 )
11819
11820 ;; Load the load/store double peephole optimizations.
11821 (include "ldrdstrd.md")
11822
11823 ;; Load the load/store multiple patterns
11824 (include "ldmstm.md")
11825
11826 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11827 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11828 (define_insn "*load_multiple"
11829 [(match_parallel 0 "load_multiple_operation"
11830 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11831 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11832 ])]
11833 "TARGET_32BIT"
11834 "*
11835 {
11836 arm_output_multireg_pop (operands, /*return_pc=*/false,
11837 /*cond=*/const_true_rtx,
11838 /*reverse=*/false,
11839 /*update=*/false);
11840 return \"\";
11841 }
11842 "
11843 [(set_attr "predicable" "yes")]
11844 )
11845
11846 (define_expand "copysignsf3"
11847 [(match_operand:SF 0 "register_operand")
11848 (match_operand:SF 1 "register_operand")
11849 (match_operand:SF 2 "register_operand")]
11850 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11851 "{
11852 emit_move_insn (operands[0], operands[2]);
11853 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11854 GEN_INT (31), GEN_INT (0),
11855 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11856 DONE;
11857 }"
11858 )
11859
11860 (define_expand "copysigndf3"
11861 [(match_operand:DF 0 "register_operand")
11862 (match_operand:DF 1 "register_operand")
11863 (match_operand:DF 2 "register_operand")]
11864 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11865 "{
11866 rtx op0_low = gen_lowpart (SImode, operands[0]);
11867 rtx op0_high = gen_highpart (SImode, operands[0]);
11868 rtx op1_low = gen_lowpart (SImode, operands[1]);
11869 rtx op1_high = gen_highpart (SImode, operands[1]);
11870 rtx op2_high = gen_highpart (SImode, operands[2]);
11871
11872 rtx scratch1 = gen_reg_rtx (SImode);
11873 rtx scratch2 = gen_reg_rtx (SImode);
11874 emit_move_insn (scratch1, op2_high);
11875 emit_move_insn (scratch2, op1_high);
11876
11877 emit_insn(gen_rtx_SET(scratch1,
11878 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11879 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11880 emit_move_insn (op0_low, op1_low);
11881 emit_move_insn (op0_high, scratch2);
11882
11883 DONE;
11884 }"
11885 )
11886
11887 ;; movmisalign patterns for HImode and SImode.
11888 (define_expand "movmisalign<mode>"
11889 [(match_operand:HSI 0 "general_operand")
11890 (match_operand:HSI 1 "general_operand")]
11891 "unaligned_access"
11892 {
11893 /* This pattern is not permitted to fail during expansion: if both arguments
11894 are non-registers (e.g. memory := constant), force operand 1 into a
11895 register. */
11896 rtx (* gen_unaligned_load)(rtx, rtx);
11897 rtx tmp_dest = operands[0];
11898 if (!s_register_operand (operands[0], <MODE>mode)
11899 && !s_register_operand (operands[1], <MODE>mode))
11900 operands[1] = force_reg (<MODE>mode, operands[1]);
11901
11902 if (<MODE>mode == HImode)
11903 {
11904 gen_unaligned_load = gen_unaligned_loadhiu;
11905 tmp_dest = gen_reg_rtx (SImode);
11906 }
11907 else
11908 gen_unaligned_load = gen_unaligned_loadsi;
11909
11910 if (MEM_P (operands[1]))
11911 {
11912 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11913 if (<MODE>mode == HImode)
11914 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11915 }
11916 else
11917 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11918
11919 DONE;
11920 })
11921
11922 (define_insn "<cdp>"
11923 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11924 (match_operand:SI 1 "immediate_operand" "n")
11925 (match_operand:SI 2 "immediate_operand" "n")
11926 (match_operand:SI 3 "immediate_operand" "n")
11927 (match_operand:SI 4 "immediate_operand" "n")
11928 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11929 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11930 {
11931 arm_const_bounds (operands[0], 0, 16);
11932 arm_const_bounds (operands[1], 0, 16);
11933 arm_const_bounds (operands[2], 0, (1 << 5));
11934 arm_const_bounds (operands[3], 0, (1 << 5));
11935 arm_const_bounds (operands[4], 0, (1 << 5));
11936 arm_const_bounds (operands[5], 0, 8);
11937 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11938 }
11939 [(set_attr "length" "4")
11940 (set_attr "type" "coproc")])
11941
11942 ;; Vector bits common to IWMMXT and Neon
11943 (include "vec-common.md")
11944 ;; Load the Intel Wireless Multimedia Extension patterns
11945 (include "iwmmxt.md")
11946 ;; Load the VFP co-processor patterns
11947 (include "vfp.md")
11948 ;; Thumb-1 patterns
11949 (include "thumb1.md")
11950 ;; Thumb-2 patterns
11951 (include "thumb2.md")
11952 ;; Neon patterns
11953 (include "neon.md")
11954 ;; Crypto patterns
11955 (include "crypto.md")
11956 ;; Synchronization Primitives
11957 (include "sync.md")
11958 ;; Fixed-point patterns
11959 (include "arm-fixed.md")