]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm.md
PR target/89434
[thirdparty/gcc.git] / gcc / config / arm / arm.md
1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2019 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
13
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 \f
26 ;;---------------------------------------------------------------------------
27 ;; Constants
28
29 ;; Register numbers -- All machine registers should be defined here
30 (define_constants
31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (R4_REGNUM 4) ; Fifth CORE register
34 (IP_REGNUM 12) ; Scratch register
35 (SP_REGNUM 13) ; Stack pointer
36 (LR_REGNUM 14) ; Return address register
37 (PC_REGNUM 15) ; Program counter
38 (LAST_ARM_REGNUM 15) ;
39 (CC_REGNUM 100) ; Condition code pseudo register
40 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
41 ]
42 )
43 ;; 3rd operand to select_dominance_cc_mode
44 (define_constants
45 [(DOM_CC_X_AND_Y 0)
46 (DOM_CC_NX_OR_Y 1)
47 (DOM_CC_X_OR_Y 2)
48 ]
49 )
50 ;; conditional compare combination
51 (define_constants
52 [(CMP_CMP 0)
53 (CMN_CMP 1)
54 (CMP_CMN 2)
55 (CMN_CMN 3)
56 (NUM_OF_COND_CMP 4)
57 ]
58 )
59
60 \f
61 ;;---------------------------------------------------------------------------
62 ;; Attributes
63
64 ;; Processor type. This is created automatically from arm-cores.def.
65 (include "arm-tune.md")
66
67 ;; Instruction classification types
68 (include "types.md")
69
70 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
71 ; generating ARM code. This is used to control the length of some insn
72 ; patterns that share the same RTL in both ARM and Thumb code.
73 (define_attr "is_thumb" "yes,no"
74 (const (if_then_else (symbol_ref "TARGET_THUMB")
75 (const_string "yes") (const_string "no"))))
76
77 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
78 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
79
80 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
81 (define_attr "is_thumb1" "yes,no"
82 (const (if_then_else (symbol_ref "TARGET_THUMB1")
83 (const_string "yes") (const_string "no"))))
84
85 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
86 ; The arm_restrict_it flag enables the "short IT" feature which
87 ; restricts IT blocks to a single 16-bit instruction.
88 ; This attribute should only be used on 16-bit Thumb-2 instructions
89 ; which may be predicated (the "predicable" attribute must be set).
90 (define_attr "predicable_short_it" "no,yes" (const_string "no"))
91
92 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
93 ; This attribute should only be used on instructions which may emit
94 ; an IT block in their expansion which is not a short IT.
95 (define_attr "enabled_for_short_it" "no,yes" (const_string "yes"))
96
97 ;; Operand number of an input operand that is shifted. Zero if the
98 ;; given instruction does not shift one of its input operands.
99 (define_attr "shift" "" (const_int 0))
100
101 ;; [For compatibility with AArch64 in pipeline models]
102 ;; Attribute that specifies whether or not the instruction touches fp
103 ;; registers.
104 (define_attr "fp" "no,yes" (const_string "no"))
105
106 ; Floating Point Unit. If we only have floating point emulation, then there
107 ; is no point in scheduling the floating point insns. (Well, for best
108 ; performance we should try and group them together).
109 (define_attr "fpu" "none,vfp"
110 (const (symbol_ref "arm_fpu_attr")))
111
112 ; Predicated means that the insn form is conditionally executed based on a
113 ; predicate. We default to 'no' because no Thumb patterns match this rule
114 ; and not all ARM insns do.
115 (define_attr "predicated" "yes,no" (const_string "no"))
116
117 ; LENGTH of an instruction (in bytes)
118 (define_attr "length" ""
119 (const_int 4))
120
121 ; The architecture which supports the instruction (or alternative).
122 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
123 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
124 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
125 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
126 ; Baseline. This attribute is used to compute attribute "enabled",
127 ; use type "any" to enable an alternative in all cases.
128 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
129 (const_string "any"))
130
131 (define_attr "arch_enabled" "no,yes"
132 (cond [(eq_attr "arch" "any")
133 (const_string "yes")
134
135 (and (eq_attr "arch" "a")
136 (match_test "TARGET_ARM"))
137 (const_string "yes")
138
139 (and (eq_attr "arch" "t")
140 (match_test "TARGET_THUMB"))
141 (const_string "yes")
142
143 (and (eq_attr "arch" "t1")
144 (match_test "TARGET_THUMB1"))
145 (const_string "yes")
146
147 (and (eq_attr "arch" "t2")
148 (match_test "TARGET_THUMB2"))
149 (const_string "yes")
150
151 (and (eq_attr "arch" "32")
152 (match_test "TARGET_32BIT"))
153 (const_string "yes")
154
155 (and (eq_attr "arch" "v6")
156 (match_test "TARGET_32BIT && arm_arch6"))
157 (const_string "yes")
158
159 (and (eq_attr "arch" "nov6")
160 (match_test "TARGET_32BIT && !arm_arch6"))
161 (const_string "yes")
162
163 (and (eq_attr "arch" "v6t2")
164 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
165 (const_string "yes")
166
167 (and (eq_attr "arch" "v8mb")
168 (match_test "TARGET_THUMB1 && arm_arch8"))
169 (const_string "yes")
170
171 (and (eq_attr "arch" "avoid_neon_for_64bits")
172 (match_test "TARGET_NEON")
173 (not (match_test "TARGET_PREFER_NEON_64BITS")))
174 (const_string "yes")
175
176 (and (eq_attr "arch" "neon_for_64bits")
177 (match_test "TARGET_NEON")
178 (match_test "TARGET_PREFER_NEON_64BITS"))
179 (const_string "yes")
180
181 (and (eq_attr "arch" "iwmmxt2")
182 (match_test "TARGET_REALLY_IWMMXT2"))
183 (const_string "yes")
184
185 (and (eq_attr "arch" "armv6_or_vfpv3")
186 (match_test "arm_arch6 || TARGET_VFP3"))
187 (const_string "yes")
188
189 (and (eq_attr "arch" "neon")
190 (match_test "TARGET_NEON"))
191 (const_string "yes")
192 ]
193
194 (const_string "no")))
195
196 (define_attr "opt" "any,speed,size"
197 (const_string "any"))
198
199 (define_attr "opt_enabled" "no,yes"
200 (cond [(eq_attr "opt" "any")
201 (const_string "yes")
202
203 (and (eq_attr "opt" "speed")
204 (match_test "optimize_function_for_speed_p (cfun)"))
205 (const_string "yes")
206
207 (and (eq_attr "opt" "size")
208 (match_test "optimize_function_for_size_p (cfun)"))
209 (const_string "yes")]
210 (const_string "no")))
211
212 (define_attr "use_literal_pool" "no,yes"
213 (cond [(and (eq_attr "type" "f_loads,f_loadd")
214 (match_test "CONSTANT_P (operands[1])"))
215 (const_string "yes")]
216 (const_string "no")))
217
218 ; Enable all alternatives that are both arch_enabled and insn_enabled.
219 ; FIXME:: opt_enabled has been temporarily removed till the time we have
220 ; an attribute that allows the use of such alternatives.
221 ; This depends on caching of speed_p, size_p on a per
222 ; alternative basis. The problem is that the enabled attribute
223 ; cannot depend on any state that is not cached or is not constant
224 ; for a compilation unit. We probably need a generic "hot/cold"
225 ; alternative which if implemented can help with this. We disable this
226 ; until such a time as this is implemented and / or the improvements or
227 ; regressions with removing this attribute are double checked.
228 ; See ashldi3_neon and <shift>di3_neon in neon.md.
229
230 (define_attr "enabled" "no,yes"
231 (cond [(and (eq_attr "predicable_short_it" "no")
232 (and (eq_attr "predicated" "yes")
233 (match_test "arm_restrict_it")))
234 (const_string "no")
235
236 (and (eq_attr "enabled_for_short_it" "no")
237 (match_test "arm_restrict_it"))
238 (const_string "no")
239
240 (eq_attr "arch_enabled" "no")
241 (const_string "no")]
242 (const_string "yes")))
243
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed. If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address. It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
256
257 (define_attr "pool_range" ""
258 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259 (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262 (attr "arm_neg_pool_range")))
263
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268 [(set_attr "conds" "clob")
269 (set_attr "length" "4")
270 (set_attr "pool_range" "250")])
271
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
275
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions. It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
279 ;
280 ; USE means that the condition codes are used by the insn in the process of
281 ; outputting code, this means (at present) that we can't use the insn in
282 ; inlined branches
283 ;
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ; well defined manner.
286 ;
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ; they are altered at all
289 ;
290 ; UNCONDITIONAL means the instruction cannot be conditionally executed and
291 ; that the instruction does not use or alter the condition codes.
292 ;
293 ; NOCOND means that the instruction does not use or alter the condition
294 ; codes but can be converted into a conditionally exectuted instruction.
295
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
297 (if_then_else
298 (ior (eq_attr "is_thumb1" "yes")
299 (eq_attr "type" "call"))
300 (const_string "clob")
301 (if_then_else (eq_attr "is_neon_type" "no")
302 (const_string "nocond")
303 (const_string "unconditional"))))
304
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by
307 ; gen...). We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
310
311 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
312 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
316
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor. Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320 (if_then_else (eq_attr "type"
321 "block,call,load_4")
322 (const_string "yes")
323 (const_string "no")))
324
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328 (if_then_else (eq_attr "type"
329 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345 (const_string "single")
346 (const_string "multi")))
347
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label. Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
351
352
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
356
357 ;;---------------------------------------------------------------------------
358 ;; Unspecs
359
360 (include "unspecs.md")
361
362 ;;---------------------------------------------------------------------------
363 ;; Mode iterators
364
365 (include "iterators.md")
366
367 ;;---------------------------------------------------------------------------
368 ;; Predicates
369
370 (include "predicates.md")
371 (include "constraints.md")
372
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
375
376 (define_attr "tune_cortexr4" "yes,no"
377 (const (if_then_else
378 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
379 (const_string "yes")
380 (const_string "no"))))
381
382 ;; True if the generic scheduling description should be used.
383
384 (define_attr "generic_sched" "yes,no"
385 (const (if_then_else
386 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387 arm926ejs,arm10e,arm1026ejs,arm1136js,\
388 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389 cortexa9,cortexa12,cortexa15,cortexa17,\
390 cortexa53,cortexa57,cortexm4,cortexm7,\
391 exynosm1,marvell_pj4,xgene1")
392 (eq_attr "tune_cortexr4" "yes"))
393 (const_string "no")
394 (const_string "yes"))))
395
396 (define_attr "generic_vfp" "yes,no"
397 (const (if_then_else
398 (and (eq_attr "fpu" "vfp")
399 (eq_attr "tune" "!arm10e,cortexa5,cortexa7,\
400 cortexa8,cortexa9,cortexa53,cortexm4,\
401 cortexm7,marvell_pj4,xgene1")
402 (eq_attr "tune_cortexr4" "no"))
403 (const_string "yes")
404 (const_string "no"))))
405
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
412 (include "fa526.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
431 (include "vfp11.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
434
435 \f
436 ;;---------------------------------------------------------------------------
437 ;; Insn patterns
438 ;;
439 ;; Addition insns.
440
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
444
445 (define_expand "adddi3"
446 [(parallel
447 [(set (match_operand:DI 0 "s_register_operand" "")
448 (plus:DI (match_operand:DI 1 "s_register_operand" "")
449 (match_operand:DI 2 "arm_adddi_operand" "")))
450 (clobber (reg:CC CC_REGNUM))])]
451 "TARGET_EITHER"
452 "
453 if (TARGET_THUMB1)
454 {
455 if (!REG_P (operands[1]))
456 operands[1] = force_reg (DImode, operands[1]);
457 if (!REG_P (operands[2]))
458 operands[2] = force_reg (DImode, operands[2]);
459 }
460 "
461 )
462
463 (define_insn_and_split "*arm_adddi3"
464 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r,&r,&r")
465 (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r")
466 (match_operand:DI 2 "arm_general_adddi_operand" "r, 0, r, Dd, Dd")))
467 (clobber (reg:CC CC_REGNUM))]
468 "TARGET_32BIT && !TARGET_NEON"
469 "#"
470 "TARGET_32BIT && ((!TARGET_NEON && !TARGET_IWMMXT) || reload_completed)"
471 [(parallel [(set (reg:CC_C CC_REGNUM)
472 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
473 (match_dup 1)))
474 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
475 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
476 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
477 "
478 {
479 operands[3] = gen_highpart (SImode, operands[0]);
480 operands[0] = gen_lowpart (SImode, operands[0]);
481 operands[4] = gen_highpart (SImode, operands[1]);
482 operands[1] = gen_lowpart (SImode, operands[1]);
483 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
484 operands[2] = gen_lowpart (SImode, operands[2]);
485 }"
486 [(set_attr "conds" "clob")
487 (set_attr "length" "8")
488 (set_attr "type" "multiple")]
489 )
490
491 (define_insn_and_split "*adddi_sesidi_di"
492 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
493 (plus:DI (sign_extend:DI
494 (match_operand:SI 2 "s_register_operand" "r,r"))
495 (match_operand:DI 1 "s_register_operand" "0,r")))
496 (clobber (reg:CC CC_REGNUM))]
497 "TARGET_32BIT"
498 "#"
499 "TARGET_32BIT && reload_completed"
500 [(parallel [(set (reg:CC_C CC_REGNUM)
501 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
502 (match_dup 1)))
503 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
504 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
505 (const_int 31))
506 (match_dup 4))
507 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
508 "
509 {
510 operands[3] = gen_highpart (SImode, operands[0]);
511 operands[0] = gen_lowpart (SImode, operands[0]);
512 operands[4] = gen_highpart (SImode, operands[1]);
513 operands[1] = gen_lowpart (SImode, operands[1]);
514 operands[2] = gen_lowpart (SImode, operands[2]);
515 }"
516 [(set_attr "conds" "clob")
517 (set_attr "length" "8")
518 (set_attr "type" "multiple")]
519 )
520
521 (define_insn_and_split "*adddi_zesidi_di"
522 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
523 (plus:DI (zero_extend:DI
524 (match_operand:SI 2 "s_register_operand" "r,r"))
525 (match_operand:DI 1 "s_register_operand" "0,r")))
526 (clobber (reg:CC CC_REGNUM))]
527 "TARGET_32BIT"
528 "#"
529 "TARGET_32BIT && reload_completed"
530 [(parallel [(set (reg:CC_C CC_REGNUM)
531 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
532 (match_dup 1)))
533 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
534 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
535 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
536 "
537 {
538 operands[3] = gen_highpart (SImode, operands[0]);
539 operands[0] = gen_lowpart (SImode, operands[0]);
540 operands[4] = gen_highpart (SImode, operands[1]);
541 operands[1] = gen_lowpart (SImode, operands[1]);
542 operands[2] = gen_lowpart (SImode, operands[2]);
543 }"
544 [(set_attr "conds" "clob")
545 (set_attr "length" "8")
546 (set_attr "type" "multiple")]
547 )
548
549 (define_expand "addv<mode>4"
550 [(match_operand:SIDI 0 "register_operand")
551 (match_operand:SIDI 1 "register_operand")
552 (match_operand:SIDI 2 "register_operand")
553 (match_operand 3 "")]
554 "TARGET_32BIT"
555 {
556 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
557 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
558
559 DONE;
560 })
561
562 (define_expand "uaddv<mode>4"
563 [(match_operand:SIDI 0 "register_operand")
564 (match_operand:SIDI 1 "register_operand")
565 (match_operand:SIDI 2 "register_operand")
566 (match_operand 3 "")]
567 "TARGET_32BIT"
568 {
569 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
570 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
571
572 DONE;
573 })
574
575 (define_expand "addsi3"
576 [(set (match_operand:SI 0 "s_register_operand" "")
577 (plus:SI (match_operand:SI 1 "s_register_operand" "")
578 (match_operand:SI 2 "reg_or_int_operand" "")))]
579 "TARGET_EITHER"
580 "
581 if (TARGET_32BIT && CONST_INT_P (operands[2]))
582 {
583 arm_split_constant (PLUS, SImode, NULL_RTX,
584 INTVAL (operands[2]), operands[0], operands[1],
585 optimize && can_create_pseudo_p ());
586 DONE;
587 }
588 "
589 )
590
591 ; If there is a scratch available, this will be faster than synthesizing the
592 ; addition.
593 (define_peephole2
594 [(match_scratch:SI 3 "r")
595 (set (match_operand:SI 0 "arm_general_register_operand" "")
596 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
597 (match_operand:SI 2 "const_int_operand" "")))]
598 "TARGET_32BIT &&
599 !(const_ok_for_arm (INTVAL (operands[2]))
600 || const_ok_for_arm (-INTVAL (operands[2])))
601 && const_ok_for_arm (~INTVAL (operands[2]))"
602 [(set (match_dup 3) (match_dup 2))
603 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
604 ""
605 )
606
607 ;; The r/r/k alternative is required when reloading the address
608 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
609 ;; put the duplicated register first, and not try the commutative version.
610 (define_insn_and_split "*arm_addsi3"
611 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
612 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,r ,rk,k ,rk,k,r,rk,k ,rk")
613 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
614 "TARGET_32BIT"
615 "@
616 add%?\\t%0, %0, %2
617 add%?\\t%0, %1, %2
618 add%?\\t%0, %1, %2
619 add%?\\t%0, %1, %2
620 add%?\\t%0, %1, %2
621 add%?\\t%0, %1, %2
622 add%?\\t%0, %2, %1
623 add%?\\t%0, %1, %2
624 addw%?\\t%0, %1, %2
625 addw%?\\t%0, %1, %2
626 sub%?\\t%0, %1, #%n2
627 sub%?\\t%0, %1, #%n2
628 sub%?\\t%0, %1, #%n2
629 subw%?\\t%0, %1, #%n2
630 subw%?\\t%0, %1, #%n2
631 #"
632 "TARGET_32BIT
633 && CONST_INT_P (operands[2])
634 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
635 && (reload_completed || !arm_eliminable_register (operands[1]))"
636 [(clobber (const_int 0))]
637 "
638 arm_split_constant (PLUS, SImode, curr_insn,
639 INTVAL (operands[2]), operands[0],
640 operands[1], 0);
641 DONE;
642 "
643 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
644 (set_attr "predicable" "yes")
645 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
646 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
647 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
648 (const_string "alu_imm")
649 (const_string "alu_sreg")))
650 ]
651 )
652
653 (define_insn_and_split "adddi3_compareV"
654 [(set (reg:CC_V CC_REGNUM)
655 (ne:CC_V
656 (plus:TI
657 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
658 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
659 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
660 (set (match_operand:DI 0 "register_operand" "=&r")
661 (plus:DI (match_dup 1) (match_dup 2)))]
662 "TARGET_32BIT"
663 "#"
664 "&& reload_completed"
665 [(parallel [(set (reg:CC_C CC_REGNUM)
666 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
667 (match_dup 1)))
668 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
669 (parallel [(set (reg:CC_V CC_REGNUM)
670 (ne:CC_V
671 (plus:DI (plus:DI
672 (sign_extend:DI (match_dup 4))
673 (sign_extend:DI (match_dup 5)))
674 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
675 (plus:DI (sign_extend:DI
676 (plus:SI (match_dup 4) (match_dup 5)))
677 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
678 (set (match_dup 3) (plus:SI (plus:SI
679 (match_dup 4) (match_dup 5))
680 (ltu:SI (reg:CC_C CC_REGNUM)
681 (const_int 0))))])]
682 "
683 {
684 operands[3] = gen_highpart (SImode, operands[0]);
685 operands[0] = gen_lowpart (SImode, operands[0]);
686 operands[4] = gen_highpart (SImode, operands[1]);
687 operands[1] = gen_lowpart (SImode, operands[1]);
688 operands[5] = gen_highpart (SImode, operands[2]);
689 operands[2] = gen_lowpart (SImode, operands[2]);
690 }"
691 [(set_attr "conds" "set")
692 (set_attr "length" "8")
693 (set_attr "type" "multiple")]
694 )
695
696 (define_insn "addsi3_compareV"
697 [(set (reg:CC_V CC_REGNUM)
698 (ne:CC_V
699 (plus:DI
700 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
701 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
702 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
703 (set (match_operand:SI 0 "register_operand" "=r")
704 (plus:SI (match_dup 1) (match_dup 2)))]
705 "TARGET_32BIT"
706 "adds%?\\t%0, %1, %2"
707 [(set_attr "conds" "set")
708 (set_attr "type" "alus_sreg")]
709 )
710
711 (define_insn "*addsi3_compareV_upper"
712 [(set (reg:CC_V CC_REGNUM)
713 (ne:CC_V
714 (plus:DI
715 (plus:DI
716 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
717 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
718 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
719 (plus:DI (sign_extend:DI
720 (plus:SI (match_dup 1) (match_dup 2)))
721 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
722 (set (match_operand:SI 0 "register_operand" "=r")
723 (plus:SI
724 (plus:SI (match_dup 1) (match_dup 2))
725 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
726 "TARGET_32BIT"
727 "adcs%?\\t%0, %1, %2"
728 [(set_attr "conds" "set")
729 (set_attr "type" "adcs_reg")]
730 )
731
732 (define_insn_and_split "adddi3_compareC"
733 [(set (reg:CC_C CC_REGNUM)
734 (ne:CC_C
735 (plus:TI
736 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
737 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
738 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
739 (set (match_operand:DI 0 "register_operand" "=&r")
740 (plus:DI (match_dup 1) (match_dup 2)))]
741 "TARGET_32BIT"
742 "#"
743 "&& reload_completed"
744 [(parallel [(set (reg:CC_C CC_REGNUM)
745 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
746 (match_dup 1)))
747 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
748 (parallel [(set (reg:CC_C CC_REGNUM)
749 (ne:CC_C
750 (plus:DI (plus:DI
751 (zero_extend:DI (match_dup 4))
752 (zero_extend:DI (match_dup 5)))
753 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
754 (plus:DI (zero_extend:DI
755 (plus:SI (match_dup 4) (match_dup 5)))
756 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
757 (set (match_dup 3) (plus:SI
758 (plus:SI (match_dup 4) (match_dup 5))
759 (ltu:SI (reg:CC_C CC_REGNUM)
760 (const_int 0))))])]
761 "
762 {
763 operands[3] = gen_highpart (SImode, operands[0]);
764 operands[0] = gen_lowpart (SImode, operands[0]);
765 operands[4] = gen_highpart (SImode, operands[1]);
766 operands[5] = gen_highpart (SImode, operands[2]);
767 operands[1] = gen_lowpart (SImode, operands[1]);
768 operands[2] = gen_lowpart (SImode, operands[2]);
769 }"
770 [(set_attr "conds" "set")
771 (set_attr "length" "8")
772 (set_attr "type" "multiple")]
773 )
774
775 (define_insn "*addsi3_compareC_upper"
776 [(set (reg:CC_C CC_REGNUM)
777 (ne:CC_C
778 (plus:DI
779 (plus:DI
780 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
781 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
782 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
783 (plus:DI (zero_extend:DI
784 (plus:SI (match_dup 1) (match_dup 2)))
785 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
786 (set (match_operand:SI 0 "register_operand" "=r")
787 (plus:SI
788 (plus:SI (match_dup 1) (match_dup 2))
789 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
790 "TARGET_32BIT"
791 "adcs%?\\t%0, %1, %2"
792 [(set_attr "conds" "set")
793 (set_attr "type" "adcs_reg")]
794 )
795
796 (define_insn "addsi3_compareC"
797 [(set (reg:CC_C CC_REGNUM)
798 (ne:CC_C
799 (plus:DI
800 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
801 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
802 (zero_extend:DI
803 (plus:SI (match_dup 1) (match_dup 2)))))
804 (set (match_operand:SI 0 "register_operand" "=r")
805 (plus:SI (match_dup 1) (match_dup 2)))]
806 "TARGET_32BIT"
807 "adds%?\\t%0, %1, %2"
808 [(set_attr "conds" "set")
809 (set_attr "type" "alus_sreg")]
810 )
811
812 (define_insn "addsi3_compare0"
813 [(set (reg:CC_NOOV CC_REGNUM)
814 (compare:CC_NOOV
815 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
816 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
817 (const_int 0)))
818 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
819 (plus:SI (match_dup 1) (match_dup 2)))]
820 "TARGET_ARM"
821 "@
822 adds%?\\t%0, %1, %2
823 subs%?\\t%0, %1, #%n2
824 adds%?\\t%0, %1, %2"
825 [(set_attr "conds" "set")
826 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
827 )
828
829 (define_insn "*addsi3_compare0_scratch"
830 [(set (reg:CC_NOOV CC_REGNUM)
831 (compare:CC_NOOV
832 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
833 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
834 (const_int 0)))]
835 "TARGET_ARM"
836 "@
837 cmn%?\\t%0, %1
838 cmp%?\\t%0, #%n1
839 cmn%?\\t%0, %1"
840 [(set_attr "conds" "set")
841 (set_attr "predicable" "yes")
842 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
843 )
844
845 (define_insn "*compare_negsi_si"
846 [(set (reg:CC_Z CC_REGNUM)
847 (compare:CC_Z
848 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
849 (match_operand:SI 1 "s_register_operand" "l,r")))]
850 "TARGET_32BIT"
851 "cmn%?\\t%1, %0"
852 [(set_attr "conds" "set")
853 (set_attr "predicable" "yes")
854 (set_attr "arch" "t2,*")
855 (set_attr "length" "2,4")
856 (set_attr "predicable_short_it" "yes,no")
857 (set_attr "type" "alus_sreg")]
858 )
859
860 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
861 ;; addend is a constant.
862 (define_insn "cmpsi2_addneg"
863 [(set (reg:CC CC_REGNUM)
864 (compare:CC
865 (match_operand:SI 1 "s_register_operand" "r,r")
866 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
867 (set (match_operand:SI 0 "s_register_operand" "=r,r")
868 (plus:SI (match_dup 1)
869 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
870 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
871 "@
872 adds%?\\t%0, %1, %3
873 subs%?\\t%0, %1, #%n3"
874 [(set_attr "conds" "set")
875 (set_attr "type" "alus_sreg")]
876 )
877
878 ;; Convert the sequence
879 ;; sub rd, rn, #1
880 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
881 ;; bne dest
882 ;; into
883 ;; subs rd, rn, #1
884 ;; bcs dest ((unsigned)rn >= 1)
885 ;; similarly for the beq variant using bcc.
886 ;; This is a common looping idiom (while (n--))
887 (define_peephole2
888 [(set (match_operand:SI 0 "arm_general_register_operand" "")
889 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
890 (const_int -1)))
891 (set (match_operand 2 "cc_register" "")
892 (compare (match_dup 0) (const_int -1)))
893 (set (pc)
894 (if_then_else (match_operator 3 "equality_operator"
895 [(match_dup 2) (const_int 0)])
896 (match_operand 4 "" "")
897 (match_operand 5 "" "")))]
898 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
899 [(parallel[
900 (set (match_dup 2)
901 (compare:CC
902 (match_dup 1) (const_int 1)))
903 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
904 (set (pc)
905 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
906 (match_dup 4)
907 (match_dup 5)))]
908 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
909 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
910 ? GEU : LTU),
911 VOIDmode,
912 operands[2], const0_rtx);"
913 )
914
915 ;; The next four insns work because they compare the result with one of
916 ;; the operands, and we know that the use of the condition code is
917 ;; either GEU or LTU, so we can use the carry flag from the addition
918 ;; instead of doing the compare a second time.
919 (define_insn "*addsi3_compare_op1"
920 [(set (reg:CC_C CC_REGNUM)
921 (compare:CC_C
922 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
923 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
924 (match_dup 1)))
925 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
926 (plus:SI (match_dup 1) (match_dup 2)))]
927 "TARGET_32BIT"
928 "@
929 adds%?\\t%0, %1, %2
930 subs%?\\t%0, %1, #%n2
931 adds%?\\t%0, %1, %2"
932 [(set_attr "conds" "set")
933 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
934 )
935
936 (define_insn "*addsi3_compare_op2"
937 [(set (reg:CC_C CC_REGNUM)
938 (compare:CC_C
939 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
940 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
941 (match_dup 2)))
942 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
943 (plus:SI (match_dup 1) (match_dup 2)))]
944 "TARGET_32BIT"
945 "@
946 adds%?\\t%0, %1, %2
947 subs%?\\t%0, %1, #%n2
948 adds%?\\t%0, %1, %2"
949 [(set_attr "conds" "set")
950 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
951 )
952
953 (define_insn "*compare_addsi2_op0"
954 [(set (reg:CC_C CC_REGNUM)
955 (compare:CC_C
956 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
957 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
958 (match_dup 0)))]
959 "TARGET_32BIT"
960 "@
961 cmp%?\\t%0, #%n1
962 cmn%?\\t%0, %1
963 cmn%?\\t%0, %1
964 cmp%?\\t%0, #%n1
965 cmn%?\\t%0, %1"
966 [(set_attr "conds" "set")
967 (set_attr "predicable" "yes")
968 (set_attr "arch" "t2,t2,*,*,*")
969 (set_attr "predicable_short_it" "yes,yes,no,no,no")
970 (set_attr "length" "2,2,4,4,4")
971 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
972 )
973
974 (define_insn "*compare_addsi2_op1"
975 [(set (reg:CC_C CC_REGNUM)
976 (compare:CC_C
977 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
978 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
979 (match_dup 1)))]
980 "TARGET_32BIT"
981 "@
982 cmp%?\\t%0, #%n1
983 cmn%?\\t%0, %1
984 cmn%?\\t%0, %1
985 cmp%?\\t%0, #%n1
986 cmn%?\\t%0, %1"
987 [(set_attr "conds" "set")
988 (set_attr "predicable" "yes")
989 (set_attr "arch" "t2,t2,*,*,*")
990 (set_attr "predicable_short_it" "yes,yes,no,no,no")
991 (set_attr "length" "2,2,4,4,4")
992 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
993 )
994
995 (define_insn "*addsi3_carryin_<optab>"
996 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
997 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
998 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
999 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1000 "TARGET_32BIT"
1001 "@
1002 adc%?\\t%0, %1, %2
1003 adc%?\\t%0, %1, %2
1004 sbc%?\\t%0, %1, #%B2"
1005 [(set_attr "conds" "use")
1006 (set_attr "predicable" "yes")
1007 (set_attr "arch" "t2,*,*")
1008 (set_attr "length" "4")
1009 (set_attr "predicable_short_it" "yes,no,no")
1010 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1011 )
1012
1013 (define_insn "*addsi3_carryin_alt2_<optab>"
1014 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1015 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1016 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1017 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1018 "TARGET_32BIT"
1019 "@
1020 adc%?\\t%0, %1, %2
1021 adc%?\\t%0, %1, %2
1022 sbc%?\\t%0, %1, #%B2"
1023 [(set_attr "conds" "use")
1024 (set_attr "predicable" "yes")
1025 (set_attr "arch" "t2,*,*")
1026 (set_attr "length" "4")
1027 (set_attr "predicable_short_it" "yes,no,no")
1028 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1029 )
1030
1031 (define_insn "*addsi3_carryin_shift_<optab>"
1032 [(set (match_operand:SI 0 "s_register_operand" "=r")
1033 (plus:SI (plus:SI
1034 (match_operator:SI 2 "shift_operator"
1035 [(match_operand:SI 3 "s_register_operand" "r")
1036 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1037 (match_operand:SI 1 "s_register_operand" "r"))
1038 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1039 "TARGET_32BIT"
1040 "adc%?\\t%0, %1, %3%S2"
1041 [(set_attr "conds" "use")
1042 (set_attr "predicable" "yes")
1043 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1044 (const_string "alu_shift_imm")
1045 (const_string "alu_shift_reg")))]
1046 )
1047
1048 (define_insn "*addsi3_carryin_clobercc_<optab>"
1049 [(set (match_operand:SI 0 "s_register_operand" "=r")
1050 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1051 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1052 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1053 (clobber (reg:CC CC_REGNUM))]
1054 "TARGET_32BIT"
1055 "adcs%?\\t%0, %1, %2"
1056 [(set_attr "conds" "set")
1057 (set_attr "type" "adcs_reg")]
1058 )
1059
1060 (define_expand "subv<mode>4"
1061 [(match_operand:SIDI 0 "register_operand")
1062 (match_operand:SIDI 1 "register_operand")
1063 (match_operand:SIDI 2 "register_operand")
1064 (match_operand 3 "")]
1065 "TARGET_32BIT"
1066 {
1067 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1068 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1069
1070 DONE;
1071 })
1072
1073 (define_expand "usubv<mode>4"
1074 [(match_operand:SIDI 0 "register_operand")
1075 (match_operand:SIDI 1 "register_operand")
1076 (match_operand:SIDI 2 "register_operand")
1077 (match_operand 3 "")]
1078 "TARGET_32BIT"
1079 {
1080 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1081 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1082
1083 DONE;
1084 })
1085
1086 (define_insn_and_split "subdi3_compare1"
1087 [(set (reg:CC CC_REGNUM)
1088 (compare:CC
1089 (match_operand:DI 1 "register_operand" "r")
1090 (match_operand:DI 2 "register_operand" "r")))
1091 (set (match_operand:DI 0 "register_operand" "=&r")
1092 (minus:DI (match_dup 1) (match_dup 2)))]
1093 "TARGET_32BIT"
1094 "#"
1095 "&& reload_completed"
1096 [(parallel [(set (reg:CC CC_REGNUM)
1097 (compare:CC (match_dup 1) (match_dup 2)))
1098 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1099 (parallel [(set (reg:CC CC_REGNUM)
1100 (compare:CC (match_dup 4) (match_dup 5)))
1101 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1102 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1103 {
1104 operands[3] = gen_highpart (SImode, operands[0]);
1105 operands[0] = gen_lowpart (SImode, operands[0]);
1106 operands[4] = gen_highpart (SImode, operands[1]);
1107 operands[1] = gen_lowpart (SImode, operands[1]);
1108 operands[5] = gen_highpart (SImode, operands[2]);
1109 operands[2] = gen_lowpart (SImode, operands[2]);
1110 }
1111 [(set_attr "conds" "set")
1112 (set_attr "length" "8")
1113 (set_attr "type" "multiple")]
1114 )
1115
1116 (define_insn "subsi3_compare1"
1117 [(set (reg:CC CC_REGNUM)
1118 (compare:CC
1119 (match_operand:SI 1 "register_operand" "r")
1120 (match_operand:SI 2 "register_operand" "r")))
1121 (set (match_operand:SI 0 "register_operand" "=r")
1122 (minus:SI (match_dup 1) (match_dup 2)))]
1123 "TARGET_32BIT"
1124 "subs%?\\t%0, %1, %2"
1125 [(set_attr "conds" "set")
1126 (set_attr "type" "alus_sreg")]
1127 )
1128
1129 (define_insn "*subsi3_carryin"
1130 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1131 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1132 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1133 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1134 "TARGET_32BIT"
1135 "@
1136 sbc%?\\t%0, %1, %2
1137 rsc%?\\t%0, %2, %1
1138 sbc%?\\t%0, %2, %2, lsl #1"
1139 [(set_attr "conds" "use")
1140 (set_attr "arch" "*,a,t2")
1141 (set_attr "predicable" "yes")
1142 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1143 )
1144
1145 (define_insn "*subsi3_carryin_const"
1146 [(set (match_operand:SI 0 "s_register_operand" "=r")
1147 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1148 (match_operand:SI 2 "arm_neg_immediate_operand" "L"))
1149 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1150 "TARGET_32BIT"
1151 "sbc\\t%0, %1, #%n2"
1152 [(set_attr "conds" "use")
1153 (set_attr "type" "adc_imm")]
1154 )
1155
1156 (define_insn "*subsi3_carryin_const0"
1157 [(set (match_operand:SI 0 "s_register_operand" "=r")
1158 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
1159 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1160 "TARGET_32BIT"
1161 "sbc\\t%0, %1, #0"
1162 [(set_attr "conds" "use")
1163 (set_attr "type" "adc_imm")]
1164 )
1165
1166 (define_insn "*subsi3_carryin_compare"
1167 [(set (reg:CC CC_REGNUM)
1168 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1169 (match_operand:SI 2 "s_register_operand" "r")))
1170 (set (match_operand:SI 0 "s_register_operand" "=r")
1171 (minus:SI (minus:SI (match_dup 1)
1172 (match_dup 2))
1173 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1174 "TARGET_32BIT"
1175 "sbcs\\t%0, %1, %2"
1176 [(set_attr "conds" "set")
1177 (set_attr "type" "adcs_reg")]
1178 )
1179
1180 (define_insn "*subsi3_carryin_compare_const"
1181 [(set (reg:CC CC_REGNUM)
1182 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1183 (match_operand:SI 2 "const_int_I_operand" "I")))
1184 (set (match_operand:SI 0 "s_register_operand" "=r")
1185 (minus:SI (plus:SI (match_dup 1)
1186 (match_operand:SI 3 "arm_neg_immediate_operand" "L"))
1187 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1188 "TARGET_32BIT && UINTVAL (operands[2]) == -UINTVAL (operands[3])"
1189 "sbcs\\t%0, %1, #%n3"
1190 [(set_attr "conds" "set")
1191 (set_attr "type" "adcs_imm")]
1192 )
1193
1194 (define_insn "*subsi3_carryin_compare_const0"
1195 [(set (reg:CC CC_REGNUM)
1196 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1197 (const_int 0)))
1198 (set (match_operand:SI 0 "s_register_operand" "=r")
1199 (minus:SI (match_dup 1)
1200 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1201 "TARGET_32BIT"
1202 "sbcs\\t%0, %1, #0"
1203 [(set_attr "conds" "set")
1204 (set_attr "type" "adcs_imm")]
1205 )
1206
1207 (define_insn "*subsi3_carryin_shift"
1208 [(set (match_operand:SI 0 "s_register_operand" "=r")
1209 (minus:SI (minus:SI
1210 (match_operand:SI 1 "s_register_operand" "r")
1211 (match_operator:SI 2 "shift_operator"
1212 [(match_operand:SI 3 "s_register_operand" "r")
1213 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1214 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1215 "TARGET_32BIT"
1216 "sbc%?\\t%0, %1, %3%S2"
1217 [(set_attr "conds" "use")
1218 (set_attr "predicable" "yes")
1219 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1220 (const_string "alu_shift_imm")
1221 (const_string "alu_shift_reg")))]
1222 )
1223
1224 (define_insn "*rsbsi3_carryin_shift"
1225 [(set (match_operand:SI 0 "s_register_operand" "=r")
1226 (minus:SI (minus:SI
1227 (match_operator:SI 2 "shift_operator"
1228 [(match_operand:SI 3 "s_register_operand" "r")
1229 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1230 (match_operand:SI 1 "s_register_operand" "r"))
1231 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1232 "TARGET_ARM"
1233 "rsc%?\\t%0, %1, %3%S2"
1234 [(set_attr "conds" "use")
1235 (set_attr "predicable" "yes")
1236 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1237 (const_string "alu_shift_imm")
1238 (const_string "alu_shift_reg")))]
1239 )
1240
1241 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1242 (define_split
1243 [(set (match_operand:SI 0 "s_register_operand" "")
1244 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1245 (match_operand:SI 2 "s_register_operand" ""))
1246 (const_int -1)))
1247 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1248 "TARGET_32BIT"
1249 [(set (match_dup 3) (match_dup 1))
1250 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1251 "
1252 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1253 ")
1254
1255 (define_expand "addsf3"
1256 [(set (match_operand:SF 0 "s_register_operand" "")
1257 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1258 (match_operand:SF 2 "s_register_operand" "")))]
1259 "TARGET_32BIT && TARGET_HARD_FLOAT"
1260 "
1261 ")
1262
1263 (define_expand "adddf3"
1264 [(set (match_operand:DF 0 "s_register_operand" "")
1265 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1266 (match_operand:DF 2 "s_register_operand" "")))]
1267 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1268 "
1269 ")
1270
1271 (define_expand "subdi3"
1272 [(parallel
1273 [(set (match_operand:DI 0 "s_register_operand" "")
1274 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1275 (match_operand:DI 2 "s_register_operand" "")))
1276 (clobber (reg:CC CC_REGNUM))])]
1277 "TARGET_EITHER"
1278 "
1279 if (TARGET_THUMB1)
1280 {
1281 if (!REG_P (operands[1]))
1282 operands[1] = force_reg (DImode, operands[1]);
1283 if (!REG_P (operands[2]))
1284 operands[2] = force_reg (DImode, operands[2]);
1285 }
1286 "
1287 )
1288
1289 (define_insn_and_split "*arm_subdi3"
1290 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
1291 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1292 (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1293 (clobber (reg:CC CC_REGNUM))]
1294 "TARGET_32BIT && !TARGET_NEON"
1295 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1296 "&& (!TARGET_IWMMXT || reload_completed)"
1297 [(parallel [(set (reg:CC CC_REGNUM)
1298 (compare:CC (match_dup 1) (match_dup 2)))
1299 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1300 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1301 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1302 {
1303 operands[3] = gen_highpart (SImode, operands[0]);
1304 operands[0] = gen_lowpart (SImode, operands[0]);
1305 operands[4] = gen_highpart (SImode, operands[1]);
1306 operands[1] = gen_lowpart (SImode, operands[1]);
1307 operands[5] = gen_highpart (SImode, operands[2]);
1308 operands[2] = gen_lowpart (SImode, operands[2]);
1309 }
1310 [(set_attr "conds" "clob")
1311 (set_attr "length" "8")
1312 (set_attr "type" "multiple")]
1313 )
1314
1315 (define_insn_and_split "*subdi_di_zesidi"
1316 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1317 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1318 (zero_extend:DI
1319 (match_operand:SI 2 "s_register_operand" "r,r"))))
1320 (clobber (reg:CC CC_REGNUM))]
1321 "TARGET_32BIT"
1322 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1323 "&& reload_completed"
1324 [(parallel [(set (reg:CC CC_REGNUM)
1325 (compare:CC (match_dup 1) (match_dup 2)))
1326 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1327 (set (match_dup 3) (minus:SI (match_dup 4)
1328 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1329 {
1330 operands[3] = gen_highpart (SImode, operands[0]);
1331 operands[0] = gen_lowpart (SImode, operands[0]);
1332 operands[4] = gen_highpart (SImode, operands[1]);
1333 operands[1] = gen_lowpart (SImode, operands[1]);
1334 }
1335 [(set_attr "conds" "clob")
1336 (set_attr "length" "8")
1337 (set_attr "type" "multiple")]
1338 )
1339
1340 (define_insn_and_split "*subdi_di_sesidi"
1341 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1342 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1343 (sign_extend:DI
1344 (match_operand:SI 2 "s_register_operand" "r,r"))))
1345 (clobber (reg:CC CC_REGNUM))]
1346 "TARGET_32BIT"
1347 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1348 "&& reload_completed"
1349 [(parallel [(set (reg:CC CC_REGNUM)
1350 (compare:CC (match_dup 1) (match_dup 2)))
1351 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1352 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1353 (ashiftrt:SI (match_dup 2)
1354 (const_int 31)))
1355 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1356 {
1357 operands[3] = gen_highpart (SImode, operands[0]);
1358 operands[0] = gen_lowpart (SImode, operands[0]);
1359 operands[4] = gen_highpart (SImode, operands[1]);
1360 operands[1] = gen_lowpart (SImode, operands[1]);
1361 }
1362 [(set_attr "conds" "clob")
1363 (set_attr "length" "8")
1364 (set_attr "type" "multiple")]
1365 )
1366
1367 (define_insn_and_split "*subdi_zesidi_di"
1368 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1369 (minus:DI (zero_extend:DI
1370 (match_operand:SI 2 "s_register_operand" "r,r"))
1371 (match_operand:DI 1 "s_register_operand" "0,r")))
1372 (clobber (reg:CC CC_REGNUM))]
1373 "TARGET_ARM"
1374 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1375 ; is equivalent to:
1376 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1377 "&& reload_completed"
1378 [(parallel [(set (reg:CC CC_REGNUM)
1379 (compare:CC (match_dup 2) (match_dup 1)))
1380 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1381 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1382 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1383 {
1384 operands[3] = gen_highpart (SImode, operands[0]);
1385 operands[0] = gen_lowpart (SImode, operands[0]);
1386 operands[4] = gen_highpart (SImode, operands[1]);
1387 operands[1] = gen_lowpart (SImode, operands[1]);
1388 }
1389 [(set_attr "conds" "clob")
1390 (set_attr "length" "8")
1391 (set_attr "type" "multiple")]
1392 )
1393
1394 (define_insn_and_split "*subdi_sesidi_di"
1395 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1396 (minus:DI (sign_extend:DI
1397 (match_operand:SI 2 "s_register_operand" "r,r"))
1398 (match_operand:DI 1 "s_register_operand" "0,r")))
1399 (clobber (reg:CC CC_REGNUM))]
1400 "TARGET_ARM"
1401 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1402 ; is equivalent to:
1403 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1404 "&& reload_completed"
1405 [(parallel [(set (reg:CC CC_REGNUM)
1406 (compare:CC (match_dup 2) (match_dup 1)))
1407 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1408 (set (match_dup 3) (minus:SI (minus:SI
1409 (ashiftrt:SI (match_dup 2)
1410 (const_int 31))
1411 (match_dup 4))
1412 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1413 {
1414 operands[3] = gen_highpart (SImode, operands[0]);
1415 operands[0] = gen_lowpart (SImode, operands[0]);
1416 operands[4] = gen_highpart (SImode, operands[1]);
1417 operands[1] = gen_lowpart (SImode, operands[1]);
1418 }
1419 [(set_attr "conds" "clob")
1420 (set_attr "length" "8")
1421 (set_attr "type" "multiple")]
1422 )
1423
1424 (define_insn_and_split "*subdi_zesidi_zesidi"
1425 [(set (match_operand:DI 0 "s_register_operand" "=r")
1426 (minus:DI (zero_extend:DI
1427 (match_operand:SI 1 "s_register_operand" "r"))
1428 (zero_extend:DI
1429 (match_operand:SI 2 "s_register_operand" "r"))))
1430 (clobber (reg:CC CC_REGNUM))]
1431 "TARGET_32BIT"
1432 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1433 "&& reload_completed"
1434 [(parallel [(set (reg:CC CC_REGNUM)
1435 (compare:CC (match_dup 1) (match_dup 2)))
1436 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1437 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1438 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1439 {
1440 operands[3] = gen_highpart (SImode, operands[0]);
1441 operands[0] = gen_lowpart (SImode, operands[0]);
1442 }
1443 [(set_attr "conds" "clob")
1444 (set_attr "length" "8")
1445 (set_attr "type" "multiple")]
1446 )
1447
1448 (define_expand "subsi3"
1449 [(set (match_operand:SI 0 "s_register_operand" "")
1450 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1451 (match_operand:SI 2 "s_register_operand" "")))]
1452 "TARGET_EITHER"
1453 "
1454 if (CONST_INT_P (operands[1]))
1455 {
1456 if (TARGET_32BIT)
1457 {
1458 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1459 operands[1] = force_reg (SImode, operands[1]);
1460 else
1461 {
1462 arm_split_constant (MINUS, SImode, NULL_RTX,
1463 INTVAL (operands[1]), operands[0],
1464 operands[2],
1465 optimize && can_create_pseudo_p ());
1466 DONE;
1467 }
1468 }
1469 else /* TARGET_THUMB1 */
1470 operands[1] = force_reg (SImode, operands[1]);
1471 }
1472 "
1473 )
1474
1475 ; ??? Check Thumb-2 split length
1476 (define_insn_and_split "*arm_subsi3_insn"
1477 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1478 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1479 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1480 "TARGET_32BIT"
1481 "@
1482 sub%?\\t%0, %1, %2
1483 sub%?\\t%0, %2
1484 sub%?\\t%0, %1, %2
1485 rsb%?\\t%0, %2, %1
1486 rsb%?\\t%0, %2, %1
1487 sub%?\\t%0, %1, %2
1488 sub%?\\t%0, %1, %2
1489 sub%?\\t%0, %1, %2
1490 #"
1491 "&& (CONST_INT_P (operands[1])
1492 && !const_ok_for_arm (INTVAL (operands[1])))"
1493 [(clobber (const_int 0))]
1494 "
1495 arm_split_constant (MINUS, SImode, curr_insn,
1496 INTVAL (operands[1]), operands[0], operands[2], 0);
1497 DONE;
1498 "
1499 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1500 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1501 (set_attr "predicable" "yes")
1502 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1503 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1504 )
1505
1506 (define_peephole2
1507 [(match_scratch:SI 3 "r")
1508 (set (match_operand:SI 0 "arm_general_register_operand" "")
1509 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1510 (match_operand:SI 2 "arm_general_register_operand" "")))]
1511 "TARGET_32BIT
1512 && !const_ok_for_arm (INTVAL (operands[1]))
1513 && const_ok_for_arm (~INTVAL (operands[1]))"
1514 [(set (match_dup 3) (match_dup 1))
1515 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1516 ""
1517 )
1518
1519 (define_insn "subsi3_compare0"
1520 [(set (reg:CC_NOOV CC_REGNUM)
1521 (compare:CC_NOOV
1522 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1523 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1524 (const_int 0)))
1525 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1526 (minus:SI (match_dup 1) (match_dup 2)))]
1527 "TARGET_32BIT"
1528 "@
1529 subs%?\\t%0, %1, %2
1530 subs%?\\t%0, %1, %2
1531 rsbs%?\\t%0, %2, %1"
1532 [(set_attr "conds" "set")
1533 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1534 )
1535
1536 (define_insn "subsi3_compare"
1537 [(set (reg:CC CC_REGNUM)
1538 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1539 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1540 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1541 (minus:SI (match_dup 1) (match_dup 2)))]
1542 "TARGET_32BIT"
1543 "@
1544 subs%?\\t%0, %1, %2
1545 subs%?\\t%0, %1, %2
1546 rsbs%?\\t%0, %2, %1"
1547 [(set_attr "conds" "set")
1548 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1549 )
1550
1551 (define_expand "subsf3"
1552 [(set (match_operand:SF 0 "s_register_operand" "")
1553 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1554 (match_operand:SF 2 "s_register_operand" "")))]
1555 "TARGET_32BIT && TARGET_HARD_FLOAT"
1556 "
1557 ")
1558
1559 (define_expand "subdf3"
1560 [(set (match_operand:DF 0 "s_register_operand" "")
1561 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1562 (match_operand:DF 2 "s_register_operand" "")))]
1563 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1564 "
1565 ")
1566
1567 \f
1568 ;; Multiplication insns
1569
1570 (define_expand "mulhi3"
1571 [(set (match_operand:HI 0 "s_register_operand" "")
1572 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1573 (match_operand:HI 2 "s_register_operand" "")))]
1574 "TARGET_DSP_MULTIPLY"
1575 "
1576 {
1577 rtx result = gen_reg_rtx (SImode);
1578 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1579 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1580 DONE;
1581 }"
1582 )
1583
1584 (define_expand "mulsi3"
1585 [(set (match_operand:SI 0 "s_register_operand" "")
1586 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1587 (match_operand:SI 1 "s_register_operand" "")))]
1588 "TARGET_EITHER"
1589 ""
1590 )
1591
1592 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1593 (define_insn "*arm_mulsi3"
1594 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1595 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1596 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1597 "TARGET_32BIT && !arm_arch6"
1598 "mul%?\\t%0, %2, %1"
1599 [(set_attr "type" "mul")
1600 (set_attr "predicable" "yes")]
1601 )
1602
1603 (define_insn "*arm_mulsi3_v6"
1604 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1605 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1606 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1607 "TARGET_32BIT && arm_arch6"
1608 "mul%?\\t%0, %1, %2"
1609 [(set_attr "type" "mul")
1610 (set_attr "predicable" "yes")
1611 (set_attr "arch" "t2,t2,*")
1612 (set_attr "length" "4")
1613 (set_attr "predicable_short_it" "yes,yes,no")]
1614 )
1615
1616 (define_insn "*mulsi3_compare0"
1617 [(set (reg:CC_NOOV CC_REGNUM)
1618 (compare:CC_NOOV (mult:SI
1619 (match_operand:SI 2 "s_register_operand" "r,r")
1620 (match_operand:SI 1 "s_register_operand" "%0,r"))
1621 (const_int 0)))
1622 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1623 (mult:SI (match_dup 2) (match_dup 1)))]
1624 "TARGET_ARM && !arm_arch6"
1625 "muls%?\\t%0, %2, %1"
1626 [(set_attr "conds" "set")
1627 (set_attr "type" "muls")]
1628 )
1629
1630 (define_insn "*mulsi3_compare0_v6"
1631 [(set (reg:CC_NOOV CC_REGNUM)
1632 (compare:CC_NOOV (mult:SI
1633 (match_operand:SI 2 "s_register_operand" "r")
1634 (match_operand:SI 1 "s_register_operand" "r"))
1635 (const_int 0)))
1636 (set (match_operand:SI 0 "s_register_operand" "=r")
1637 (mult:SI (match_dup 2) (match_dup 1)))]
1638 "TARGET_ARM && arm_arch6 && optimize_size"
1639 "muls%?\\t%0, %2, %1"
1640 [(set_attr "conds" "set")
1641 (set_attr "type" "muls")]
1642 )
1643
1644 (define_insn "*mulsi_compare0_scratch"
1645 [(set (reg:CC_NOOV CC_REGNUM)
1646 (compare:CC_NOOV (mult:SI
1647 (match_operand:SI 2 "s_register_operand" "r,r")
1648 (match_operand:SI 1 "s_register_operand" "%0,r"))
1649 (const_int 0)))
1650 (clobber (match_scratch:SI 0 "=&r,&r"))]
1651 "TARGET_ARM && !arm_arch6"
1652 "muls%?\\t%0, %2, %1"
1653 [(set_attr "conds" "set")
1654 (set_attr "type" "muls")]
1655 )
1656
1657 (define_insn "*mulsi_compare0_scratch_v6"
1658 [(set (reg:CC_NOOV CC_REGNUM)
1659 (compare:CC_NOOV (mult:SI
1660 (match_operand:SI 2 "s_register_operand" "r")
1661 (match_operand:SI 1 "s_register_operand" "r"))
1662 (const_int 0)))
1663 (clobber (match_scratch:SI 0 "=r"))]
1664 "TARGET_ARM && arm_arch6 && optimize_size"
1665 "muls%?\\t%0, %2, %1"
1666 [(set_attr "conds" "set")
1667 (set_attr "type" "muls")]
1668 )
1669
1670 ;; Unnamed templates to match MLA instruction.
1671
1672 (define_insn "*mulsi3addsi"
1673 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1674 (plus:SI
1675 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1676 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1677 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1678 "TARGET_32BIT && !arm_arch6"
1679 "mla%?\\t%0, %2, %1, %3"
1680 [(set_attr "type" "mla")
1681 (set_attr "predicable" "yes")]
1682 )
1683
1684 (define_insn "*mulsi3addsi_v6"
1685 [(set (match_operand:SI 0 "s_register_operand" "=r")
1686 (plus:SI
1687 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1688 (match_operand:SI 1 "s_register_operand" "r"))
1689 (match_operand:SI 3 "s_register_operand" "r")))]
1690 "TARGET_32BIT && arm_arch6"
1691 "mla%?\\t%0, %2, %1, %3"
1692 [(set_attr "type" "mla")
1693 (set_attr "predicable" "yes")]
1694 )
1695
1696 (define_insn "*mulsi3addsi_compare0"
1697 [(set (reg:CC_NOOV CC_REGNUM)
1698 (compare:CC_NOOV
1699 (plus:SI (mult:SI
1700 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1701 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1702 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1703 (const_int 0)))
1704 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1705 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1706 (match_dup 3)))]
1707 "TARGET_ARM && arm_arch6"
1708 "mlas%?\\t%0, %2, %1, %3"
1709 [(set_attr "conds" "set")
1710 (set_attr "type" "mlas")]
1711 )
1712
1713 (define_insn "*mulsi3addsi_compare0_v6"
1714 [(set (reg:CC_NOOV CC_REGNUM)
1715 (compare:CC_NOOV
1716 (plus:SI (mult:SI
1717 (match_operand:SI 2 "s_register_operand" "r")
1718 (match_operand:SI 1 "s_register_operand" "r"))
1719 (match_operand:SI 3 "s_register_operand" "r"))
1720 (const_int 0)))
1721 (set (match_operand:SI 0 "s_register_operand" "=r")
1722 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1723 (match_dup 3)))]
1724 "TARGET_ARM && arm_arch6 && optimize_size"
1725 "mlas%?\\t%0, %2, %1, %3"
1726 [(set_attr "conds" "set")
1727 (set_attr "type" "mlas")]
1728 )
1729
1730 (define_insn "*mulsi3addsi_compare0_scratch"
1731 [(set (reg:CC_NOOV CC_REGNUM)
1732 (compare:CC_NOOV
1733 (plus:SI (mult:SI
1734 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1735 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1736 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1737 (const_int 0)))
1738 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1739 "TARGET_ARM && !arm_arch6"
1740 "mlas%?\\t%0, %2, %1, %3"
1741 [(set_attr "conds" "set")
1742 (set_attr "type" "mlas")]
1743 )
1744
1745 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1746 [(set (reg:CC_NOOV CC_REGNUM)
1747 (compare:CC_NOOV
1748 (plus:SI (mult:SI
1749 (match_operand:SI 2 "s_register_operand" "r")
1750 (match_operand:SI 1 "s_register_operand" "r"))
1751 (match_operand:SI 3 "s_register_operand" "r"))
1752 (const_int 0)))
1753 (clobber (match_scratch:SI 0 "=r"))]
1754 "TARGET_ARM && arm_arch6 && optimize_size"
1755 "mlas%?\\t%0, %2, %1, %3"
1756 [(set_attr "conds" "set")
1757 (set_attr "type" "mlas")]
1758 )
1759
1760 (define_insn "*mulsi3subsi"
1761 [(set (match_operand:SI 0 "s_register_operand" "=r")
1762 (minus:SI
1763 (match_operand:SI 3 "s_register_operand" "r")
1764 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1765 (match_operand:SI 1 "s_register_operand" "r"))))]
1766 "TARGET_32BIT && arm_arch_thumb2"
1767 "mls%?\\t%0, %2, %1, %3"
1768 [(set_attr "type" "mla")
1769 (set_attr "predicable" "yes")]
1770 )
1771
1772 (define_expand "maddsidi4"
1773 [(set (match_operand:DI 0 "s_register_operand" "")
1774 (plus:DI
1775 (mult:DI
1776 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1777 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1778 (match_operand:DI 3 "s_register_operand" "")))]
1779 "TARGET_32BIT"
1780 "")
1781
1782 (define_insn "*mulsidi3adddi"
1783 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1784 (plus:DI
1785 (mult:DI
1786 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1787 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1788 (match_operand:DI 1 "s_register_operand" "0")))]
1789 "TARGET_32BIT && !arm_arch6"
1790 "smlal%?\\t%Q0, %R0, %3, %2"
1791 [(set_attr "type" "smlal")
1792 (set_attr "predicable" "yes")]
1793 )
1794
1795 (define_insn "*mulsidi3adddi_v6"
1796 [(set (match_operand:DI 0 "s_register_operand" "=r")
1797 (plus:DI
1798 (mult:DI
1799 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1800 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1801 (match_operand:DI 1 "s_register_operand" "0")))]
1802 "TARGET_32BIT && arm_arch6"
1803 "smlal%?\\t%Q0, %R0, %3, %2"
1804 [(set_attr "type" "smlal")
1805 (set_attr "predicable" "yes")]
1806 )
1807
1808 ;; 32x32->64 widening multiply.
1809 ;; As with mulsi3, the only difference between the v3-5 and v6+
1810 ;; versions of these patterns is the requirement that the output not
1811 ;; overlap the inputs, but that still means we have to have a named
1812 ;; expander and two different starred insns.
1813
1814 (define_expand "mulsidi3"
1815 [(set (match_operand:DI 0 "s_register_operand" "")
1816 (mult:DI
1817 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1818 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1819 "TARGET_32BIT"
1820 ""
1821 )
1822
1823 (define_insn "*mulsidi3_nov6"
1824 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1825 (mult:DI
1826 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1827 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1828 "TARGET_32BIT && !arm_arch6"
1829 "smull%?\\t%Q0, %R0, %1, %2"
1830 [(set_attr "type" "smull")
1831 (set_attr "predicable" "yes")]
1832 )
1833
1834 (define_insn "*mulsidi3_v6"
1835 [(set (match_operand:DI 0 "s_register_operand" "=r")
1836 (mult:DI
1837 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1838 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1839 "TARGET_32BIT && arm_arch6"
1840 "smull%?\\t%Q0, %R0, %1, %2"
1841 [(set_attr "type" "smull")
1842 (set_attr "predicable" "yes")]
1843 )
1844
1845 (define_expand "umulsidi3"
1846 [(set (match_operand:DI 0 "s_register_operand" "")
1847 (mult:DI
1848 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1849 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1850 "TARGET_32BIT"
1851 ""
1852 )
1853
1854 (define_insn "*umulsidi3_nov6"
1855 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1856 (mult:DI
1857 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1858 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1859 "TARGET_32BIT && !arm_arch6"
1860 "umull%?\\t%Q0, %R0, %1, %2"
1861 [(set_attr "type" "umull")
1862 (set_attr "predicable" "yes")]
1863 )
1864
1865 (define_insn "*umulsidi3_v6"
1866 [(set (match_operand:DI 0 "s_register_operand" "=r")
1867 (mult:DI
1868 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1869 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1870 "TARGET_32BIT && arm_arch6"
1871 "umull%?\\t%Q0, %R0, %1, %2"
1872 [(set_attr "type" "umull")
1873 (set_attr "predicable" "yes")]
1874 )
1875
1876 (define_expand "umaddsidi4"
1877 [(set (match_operand:DI 0 "s_register_operand" "")
1878 (plus:DI
1879 (mult:DI
1880 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1881 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1882 (match_operand:DI 3 "s_register_operand" "")))]
1883 "TARGET_32BIT"
1884 "")
1885
1886 (define_insn "*umulsidi3adddi"
1887 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1888 (plus:DI
1889 (mult:DI
1890 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1891 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1892 (match_operand:DI 1 "s_register_operand" "0")))]
1893 "TARGET_32BIT && !arm_arch6"
1894 "umlal%?\\t%Q0, %R0, %3, %2"
1895 [(set_attr "type" "umlal")
1896 (set_attr "predicable" "yes")]
1897 )
1898
1899 (define_insn "*umulsidi3adddi_v6"
1900 [(set (match_operand:DI 0 "s_register_operand" "=r")
1901 (plus:DI
1902 (mult:DI
1903 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1904 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1905 (match_operand:DI 1 "s_register_operand" "0")))]
1906 "TARGET_32BIT && arm_arch6"
1907 "umlal%?\\t%Q0, %R0, %3, %2"
1908 [(set_attr "type" "umlal")
1909 (set_attr "predicable" "yes")]
1910 )
1911
1912 (define_expand "smulsi3_highpart"
1913 [(parallel
1914 [(set (match_operand:SI 0 "s_register_operand" "")
1915 (truncate:SI
1916 (lshiftrt:DI
1917 (mult:DI
1918 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1919 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1920 (const_int 32))))
1921 (clobber (match_scratch:SI 3 ""))])]
1922 "TARGET_32BIT"
1923 ""
1924 )
1925
1926 (define_insn "*smulsi3_highpart_nov6"
1927 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1928 (truncate:SI
1929 (lshiftrt:DI
1930 (mult:DI
1931 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1932 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1933 (const_int 32))))
1934 (clobber (match_scratch:SI 3 "=&r,&r"))]
1935 "TARGET_32BIT && !arm_arch6"
1936 "smull%?\\t%3, %0, %2, %1"
1937 [(set_attr "type" "smull")
1938 (set_attr "predicable" "yes")]
1939 )
1940
1941 (define_insn "*smulsi3_highpart_v6"
1942 [(set (match_operand:SI 0 "s_register_operand" "=r")
1943 (truncate:SI
1944 (lshiftrt:DI
1945 (mult:DI
1946 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1947 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1948 (const_int 32))))
1949 (clobber (match_scratch:SI 3 "=r"))]
1950 "TARGET_32BIT && arm_arch6"
1951 "smull%?\\t%3, %0, %2, %1"
1952 [(set_attr "type" "smull")
1953 (set_attr "predicable" "yes")]
1954 )
1955
1956 (define_expand "umulsi3_highpart"
1957 [(parallel
1958 [(set (match_operand:SI 0 "s_register_operand" "")
1959 (truncate:SI
1960 (lshiftrt:DI
1961 (mult:DI
1962 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1963 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1964 (const_int 32))))
1965 (clobber (match_scratch:SI 3 ""))])]
1966 "TARGET_32BIT"
1967 ""
1968 )
1969
1970 (define_insn "*umulsi3_highpart_nov6"
1971 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1972 (truncate:SI
1973 (lshiftrt:DI
1974 (mult:DI
1975 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1976 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1977 (const_int 32))))
1978 (clobber (match_scratch:SI 3 "=&r,&r"))]
1979 "TARGET_32BIT && !arm_arch6"
1980 "umull%?\\t%3, %0, %2, %1"
1981 [(set_attr "type" "umull")
1982 (set_attr "predicable" "yes")]
1983 )
1984
1985 (define_insn "*umulsi3_highpart_v6"
1986 [(set (match_operand:SI 0 "s_register_operand" "=r")
1987 (truncate:SI
1988 (lshiftrt:DI
1989 (mult:DI
1990 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1991 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1992 (const_int 32))))
1993 (clobber (match_scratch:SI 3 "=r"))]
1994 "TARGET_32BIT && arm_arch6"
1995 "umull%?\\t%3, %0, %2, %1"
1996 [(set_attr "type" "umull")
1997 (set_attr "predicable" "yes")]
1998 )
1999
2000 (define_insn "mulhisi3"
2001 [(set (match_operand:SI 0 "s_register_operand" "=r")
2002 (mult:SI (sign_extend:SI
2003 (match_operand:HI 1 "s_register_operand" "%r"))
2004 (sign_extend:SI
2005 (match_operand:HI 2 "s_register_operand" "r"))))]
2006 "TARGET_DSP_MULTIPLY"
2007 "smulbb%?\\t%0, %1, %2"
2008 [(set_attr "type" "smulxy")
2009 (set_attr "predicable" "yes")]
2010 )
2011
2012 (define_insn "*mulhisi3tb"
2013 [(set (match_operand:SI 0 "s_register_operand" "=r")
2014 (mult:SI (ashiftrt:SI
2015 (match_operand:SI 1 "s_register_operand" "r")
2016 (const_int 16))
2017 (sign_extend:SI
2018 (match_operand:HI 2 "s_register_operand" "r"))))]
2019 "TARGET_DSP_MULTIPLY"
2020 "smultb%?\\t%0, %1, %2"
2021 [(set_attr "type" "smulxy")
2022 (set_attr "predicable" "yes")]
2023 )
2024
2025 (define_insn "*mulhisi3bt"
2026 [(set (match_operand:SI 0 "s_register_operand" "=r")
2027 (mult:SI (sign_extend:SI
2028 (match_operand:HI 1 "s_register_operand" "r"))
2029 (ashiftrt:SI
2030 (match_operand:SI 2 "s_register_operand" "r")
2031 (const_int 16))))]
2032 "TARGET_DSP_MULTIPLY"
2033 "smulbt%?\\t%0, %1, %2"
2034 [(set_attr "type" "smulxy")
2035 (set_attr "predicable" "yes")]
2036 )
2037
2038 (define_insn "*mulhisi3tt"
2039 [(set (match_operand:SI 0 "s_register_operand" "=r")
2040 (mult:SI (ashiftrt:SI
2041 (match_operand:SI 1 "s_register_operand" "r")
2042 (const_int 16))
2043 (ashiftrt:SI
2044 (match_operand:SI 2 "s_register_operand" "r")
2045 (const_int 16))))]
2046 "TARGET_DSP_MULTIPLY"
2047 "smultt%?\\t%0, %1, %2"
2048 [(set_attr "type" "smulxy")
2049 (set_attr "predicable" "yes")]
2050 )
2051
2052 (define_insn "maddhisi4"
2053 [(set (match_operand:SI 0 "s_register_operand" "=r")
2054 (plus:SI (mult:SI (sign_extend:SI
2055 (match_operand:HI 1 "s_register_operand" "r"))
2056 (sign_extend:SI
2057 (match_operand:HI 2 "s_register_operand" "r")))
2058 (match_operand:SI 3 "s_register_operand" "r")))]
2059 "TARGET_DSP_MULTIPLY"
2060 "smlabb%?\\t%0, %1, %2, %3"
2061 [(set_attr "type" "smlaxy")
2062 (set_attr "predicable" "yes")]
2063 )
2064
2065 ;; Note: there is no maddhisi4ibt because this one is canonical form
2066 (define_insn "*maddhisi4tb"
2067 [(set (match_operand:SI 0 "s_register_operand" "=r")
2068 (plus:SI (mult:SI (ashiftrt:SI
2069 (match_operand:SI 1 "s_register_operand" "r")
2070 (const_int 16))
2071 (sign_extend:SI
2072 (match_operand:HI 2 "s_register_operand" "r")))
2073 (match_operand:SI 3 "s_register_operand" "r")))]
2074 "TARGET_DSP_MULTIPLY"
2075 "smlatb%?\\t%0, %1, %2, %3"
2076 [(set_attr "type" "smlaxy")
2077 (set_attr "predicable" "yes")]
2078 )
2079
2080 (define_insn "*maddhisi4tt"
2081 [(set (match_operand:SI 0 "s_register_operand" "=r")
2082 (plus:SI (mult:SI (ashiftrt:SI
2083 (match_operand:SI 1 "s_register_operand" "r")
2084 (const_int 16))
2085 (ashiftrt:SI
2086 (match_operand:SI 2 "s_register_operand" "r")
2087 (const_int 16)))
2088 (match_operand:SI 3 "s_register_operand" "r")))]
2089 "TARGET_DSP_MULTIPLY"
2090 "smlatt%?\\t%0, %1, %2, %3"
2091 [(set_attr "type" "smlaxy")
2092 (set_attr "predicable" "yes")]
2093 )
2094
2095 (define_insn "maddhidi4"
2096 [(set (match_operand:DI 0 "s_register_operand" "=r")
2097 (plus:DI
2098 (mult:DI (sign_extend:DI
2099 (match_operand:HI 1 "s_register_operand" "r"))
2100 (sign_extend:DI
2101 (match_operand:HI 2 "s_register_operand" "r")))
2102 (match_operand:DI 3 "s_register_operand" "0")))]
2103 "TARGET_DSP_MULTIPLY"
2104 "smlalbb%?\\t%Q0, %R0, %1, %2"
2105 [(set_attr "type" "smlalxy")
2106 (set_attr "predicable" "yes")])
2107
2108 ;; Note: there is no maddhidi4ibt because this one is canonical form
2109 (define_insn "*maddhidi4tb"
2110 [(set (match_operand:DI 0 "s_register_operand" "=r")
2111 (plus:DI
2112 (mult:DI (sign_extend:DI
2113 (ashiftrt:SI
2114 (match_operand:SI 1 "s_register_operand" "r")
2115 (const_int 16)))
2116 (sign_extend:DI
2117 (match_operand:HI 2 "s_register_operand" "r")))
2118 (match_operand:DI 3 "s_register_operand" "0")))]
2119 "TARGET_DSP_MULTIPLY"
2120 "smlaltb%?\\t%Q0, %R0, %1, %2"
2121 [(set_attr "type" "smlalxy")
2122 (set_attr "predicable" "yes")])
2123
2124 (define_insn "*maddhidi4tt"
2125 [(set (match_operand:DI 0 "s_register_operand" "=r")
2126 (plus:DI
2127 (mult:DI (sign_extend:DI
2128 (ashiftrt:SI
2129 (match_operand:SI 1 "s_register_operand" "r")
2130 (const_int 16)))
2131 (sign_extend:DI
2132 (ashiftrt:SI
2133 (match_operand:SI 2 "s_register_operand" "r")
2134 (const_int 16))))
2135 (match_operand:DI 3 "s_register_operand" "0")))]
2136 "TARGET_DSP_MULTIPLY"
2137 "smlaltt%?\\t%Q0, %R0, %1, %2"
2138 [(set_attr "type" "smlalxy")
2139 (set_attr "predicable" "yes")])
2140
2141 (define_expand "mulsf3"
2142 [(set (match_operand:SF 0 "s_register_operand" "")
2143 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2144 (match_operand:SF 2 "s_register_operand" "")))]
2145 "TARGET_32BIT && TARGET_HARD_FLOAT"
2146 "
2147 ")
2148
2149 (define_expand "muldf3"
2150 [(set (match_operand:DF 0 "s_register_operand" "")
2151 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2152 (match_operand:DF 2 "s_register_operand" "")))]
2153 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2154 "
2155 ")
2156 \f
2157 ;; Division insns
2158
2159 (define_expand "divsf3"
2160 [(set (match_operand:SF 0 "s_register_operand" "")
2161 (div:SF (match_operand:SF 1 "s_register_operand" "")
2162 (match_operand:SF 2 "s_register_operand" "")))]
2163 "TARGET_32BIT && TARGET_HARD_FLOAT"
2164 "")
2165
2166 (define_expand "divdf3"
2167 [(set (match_operand:DF 0 "s_register_operand" "")
2168 (div:DF (match_operand:DF 1 "s_register_operand" "")
2169 (match_operand:DF 2 "s_register_operand" "")))]
2170 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2171 "")
2172 \f
2173 ;; Boolean and,ior,xor insns
2174
2175 ;; Split up double word logical operations
2176
2177 ;; Split up simple DImode logical operations. Simply perform the logical
2178 ;; operation on the upper and lower halves of the registers.
2179 (define_split
2180 [(set (match_operand:DI 0 "s_register_operand" "")
2181 (match_operator:DI 6 "logical_binary_operator"
2182 [(match_operand:DI 1 "s_register_operand" "")
2183 (match_operand:DI 2 "s_register_operand" "")]))]
2184 "TARGET_32BIT && reload_completed
2185 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2186 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2187 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2188 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2189 "
2190 {
2191 operands[3] = gen_highpart (SImode, operands[0]);
2192 operands[0] = gen_lowpart (SImode, operands[0]);
2193 operands[4] = gen_highpart (SImode, operands[1]);
2194 operands[1] = gen_lowpart (SImode, operands[1]);
2195 operands[5] = gen_highpart (SImode, operands[2]);
2196 operands[2] = gen_lowpart (SImode, operands[2]);
2197 }"
2198 )
2199
2200 (define_split
2201 [(set (match_operand:DI 0 "s_register_operand" "")
2202 (match_operator:DI 6 "logical_binary_operator"
2203 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2204 (match_operand:DI 1 "s_register_operand" "")]))]
2205 "TARGET_32BIT && reload_completed"
2206 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2207 (set (match_dup 3) (match_op_dup:SI 6
2208 [(ashiftrt:SI (match_dup 2) (const_int 31))
2209 (match_dup 4)]))]
2210 "
2211 {
2212 operands[3] = gen_highpart (SImode, operands[0]);
2213 operands[0] = gen_lowpart (SImode, operands[0]);
2214 operands[4] = gen_highpart (SImode, operands[1]);
2215 operands[1] = gen_lowpart (SImode, operands[1]);
2216 operands[5] = gen_highpart (SImode, operands[2]);
2217 operands[2] = gen_lowpart (SImode, operands[2]);
2218 }"
2219 )
2220
2221 ;; The zero extend of operand 2 means we can just copy the high part of
2222 ;; operand1 into operand0.
2223 (define_split
2224 [(set (match_operand:DI 0 "s_register_operand" "")
2225 (ior:DI
2226 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2227 (match_operand:DI 1 "s_register_operand" "")))]
2228 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2229 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2230 (set (match_dup 3) (match_dup 4))]
2231 "
2232 {
2233 operands[4] = gen_highpart (SImode, operands[1]);
2234 operands[3] = gen_highpart (SImode, operands[0]);
2235 operands[0] = gen_lowpart (SImode, operands[0]);
2236 operands[1] = gen_lowpart (SImode, operands[1]);
2237 }"
2238 )
2239
2240 ;; The zero extend of operand 2 means we can just copy the high part of
2241 ;; operand1 into operand0.
2242 (define_split
2243 [(set (match_operand:DI 0 "s_register_operand" "")
2244 (xor:DI
2245 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2246 (match_operand:DI 1 "s_register_operand" "")))]
2247 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2248 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2249 (set (match_dup 3) (match_dup 4))]
2250 "
2251 {
2252 operands[4] = gen_highpart (SImode, operands[1]);
2253 operands[3] = gen_highpart (SImode, operands[0]);
2254 operands[0] = gen_lowpart (SImode, operands[0]);
2255 operands[1] = gen_lowpart (SImode, operands[1]);
2256 }"
2257 )
2258
2259 (define_expand "anddi3"
2260 [(set (match_operand:DI 0 "s_register_operand" "")
2261 (and:DI (match_operand:DI 1 "s_register_operand" "")
2262 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2263 "TARGET_32BIT"
2264 "
2265 if (!TARGET_NEON && !TARGET_IWMMXT)
2266 {
2267 rtx low = simplify_gen_binary (AND, SImode,
2268 gen_lowpart (SImode, operands[1]),
2269 gen_lowpart (SImode, operands[2]));
2270 rtx high = simplify_gen_binary (AND, SImode,
2271 gen_highpart (SImode, operands[1]),
2272 gen_highpart_mode (SImode, DImode,
2273 operands[2]));
2274
2275 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2276 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2277
2278 DONE;
2279 }
2280 /* Otherwise expand pattern as above. */
2281 "
2282 )
2283
2284 (define_insn_and_split "*anddi3_insn"
2285 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2286 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2287 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2288 "TARGET_32BIT && !TARGET_IWMMXT"
2289 {
2290 switch (which_alternative)
2291 {
2292 case 0: /* fall through */
2293 case 6: return "vand\t%P0, %P1, %P2";
2294 case 1: /* fall through */
2295 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2296 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2297 case 2:
2298 case 3:
2299 case 4:
2300 case 5: /* fall through */
2301 return "#";
2302 default: gcc_unreachable ();
2303 }
2304 }
2305 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2306 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2307 [(set (match_dup 3) (match_dup 4))
2308 (set (match_dup 5) (match_dup 6))]
2309 "
2310 {
2311 operands[3] = gen_lowpart (SImode, operands[0]);
2312 operands[5] = gen_highpart (SImode, operands[0]);
2313
2314 operands[4] = simplify_gen_binary (AND, SImode,
2315 gen_lowpart (SImode, operands[1]),
2316 gen_lowpart (SImode, operands[2]));
2317 operands[6] = simplify_gen_binary (AND, SImode,
2318 gen_highpart (SImode, operands[1]),
2319 gen_highpart_mode (SImode, DImode, operands[2]));
2320
2321 }"
2322 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2323 multiple,multiple,neon_logic,neon_logic")
2324 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2325 avoid_neon_for_64bits,avoid_neon_for_64bits")
2326 (set_attr "length" "*,*,8,8,8,8,*,*")
2327 ]
2328 )
2329
2330 (define_insn_and_split "*anddi_zesidi_di"
2331 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2332 (and:DI (zero_extend:DI
2333 (match_operand:SI 2 "s_register_operand" "r,r"))
2334 (match_operand:DI 1 "s_register_operand" "0,r")))]
2335 "TARGET_32BIT"
2336 "#"
2337 "TARGET_32BIT && reload_completed"
2338 ; The zero extend of operand 2 clears the high word of the output
2339 ; operand.
2340 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2341 (set (match_dup 3) (const_int 0))]
2342 "
2343 {
2344 operands[3] = gen_highpart (SImode, operands[0]);
2345 operands[0] = gen_lowpart (SImode, operands[0]);
2346 operands[1] = gen_lowpart (SImode, operands[1]);
2347 }"
2348 [(set_attr "length" "8")
2349 (set_attr "type" "multiple")]
2350 )
2351
2352 (define_insn "*anddi_sesdi_di"
2353 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2354 (and:DI (sign_extend:DI
2355 (match_operand:SI 2 "s_register_operand" "r,r"))
2356 (match_operand:DI 1 "s_register_operand" "0,r")))]
2357 "TARGET_32BIT"
2358 "#"
2359 [(set_attr "length" "8")
2360 (set_attr "type" "multiple")]
2361 )
2362
2363 (define_expand "andsi3"
2364 [(set (match_operand:SI 0 "s_register_operand" "")
2365 (and:SI (match_operand:SI 1 "s_register_operand" "")
2366 (match_operand:SI 2 "reg_or_int_operand" "")))]
2367 "TARGET_EITHER"
2368 "
2369 if (TARGET_32BIT)
2370 {
2371 if (CONST_INT_P (operands[2]))
2372 {
2373 if (INTVAL (operands[2]) == 255 && arm_arch6)
2374 {
2375 operands[1] = convert_to_mode (QImode, operands[1], 1);
2376 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2377 operands[1]));
2378 DONE;
2379 }
2380 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2381 operands[2] = force_reg (SImode, operands[2]);
2382 else
2383 {
2384 arm_split_constant (AND, SImode, NULL_RTX,
2385 INTVAL (operands[2]), operands[0],
2386 operands[1],
2387 optimize && can_create_pseudo_p ());
2388
2389 DONE;
2390 }
2391 }
2392 }
2393 else /* TARGET_THUMB1 */
2394 {
2395 if (!CONST_INT_P (operands[2]))
2396 {
2397 rtx tmp = force_reg (SImode, operands[2]);
2398 if (rtx_equal_p (operands[0], operands[1]))
2399 operands[2] = tmp;
2400 else
2401 {
2402 operands[2] = operands[1];
2403 operands[1] = tmp;
2404 }
2405 }
2406 else
2407 {
2408 int i;
2409
2410 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2411 {
2412 operands[2] = force_reg (SImode,
2413 GEN_INT (~INTVAL (operands[2])));
2414
2415 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2416
2417 DONE;
2418 }
2419
2420 for (i = 9; i <= 31; i++)
2421 {
2422 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2423 {
2424 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2425 const0_rtx));
2426 DONE;
2427 }
2428 else if ((HOST_WIDE_INT_1 << i) - 1
2429 == ~INTVAL (operands[2]))
2430 {
2431 rtx shift = GEN_INT (i);
2432 rtx reg = gen_reg_rtx (SImode);
2433
2434 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2435 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2436
2437 DONE;
2438 }
2439 }
2440
2441 operands[2] = force_reg (SImode, operands[2]);
2442 }
2443 }
2444 "
2445 )
2446
2447 ; ??? Check split length for Thumb-2
2448 (define_insn_and_split "*arm_andsi3_insn"
2449 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2450 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2451 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2452 "TARGET_32BIT"
2453 "@
2454 and%?\\t%0, %1, %2
2455 and%?\\t%0, %1, %2
2456 bic%?\\t%0, %1, #%B2
2457 and%?\\t%0, %1, %2
2458 #"
2459 "TARGET_32BIT
2460 && CONST_INT_P (operands[2])
2461 && !(const_ok_for_arm (INTVAL (operands[2]))
2462 || const_ok_for_arm (~INTVAL (operands[2])))"
2463 [(clobber (const_int 0))]
2464 "
2465 arm_split_constant (AND, SImode, curr_insn,
2466 INTVAL (operands[2]), operands[0], operands[1], 0);
2467 DONE;
2468 "
2469 [(set_attr "length" "4,4,4,4,16")
2470 (set_attr "predicable" "yes")
2471 (set_attr "predicable_short_it" "no,yes,no,no,no")
2472 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2473 )
2474
2475 (define_insn "*andsi3_compare0"
2476 [(set (reg:CC_NOOV CC_REGNUM)
2477 (compare:CC_NOOV
2478 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2479 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2480 (const_int 0)))
2481 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2482 (and:SI (match_dup 1) (match_dup 2)))]
2483 "TARGET_32BIT"
2484 "@
2485 ands%?\\t%0, %1, %2
2486 bics%?\\t%0, %1, #%B2
2487 ands%?\\t%0, %1, %2"
2488 [(set_attr "conds" "set")
2489 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2490 )
2491
2492 (define_insn "*andsi3_compare0_scratch"
2493 [(set (reg:CC_NOOV CC_REGNUM)
2494 (compare:CC_NOOV
2495 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2496 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2497 (const_int 0)))
2498 (clobber (match_scratch:SI 2 "=X,r,X"))]
2499 "TARGET_32BIT"
2500 "@
2501 tst%?\\t%0, %1
2502 bics%?\\t%2, %0, #%B1
2503 tst%?\\t%0, %1"
2504 [(set_attr "conds" "set")
2505 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2506 )
2507
2508 (define_insn "*zeroextractsi_compare0_scratch"
2509 [(set (reg:CC_NOOV CC_REGNUM)
2510 (compare:CC_NOOV (zero_extract:SI
2511 (match_operand:SI 0 "s_register_operand" "r")
2512 (match_operand 1 "const_int_operand" "n")
2513 (match_operand 2 "const_int_operand" "n"))
2514 (const_int 0)))]
2515 "TARGET_32BIT
2516 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2517 && INTVAL (operands[1]) > 0
2518 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2519 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2520 "*
2521 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2522 << INTVAL (operands[2]));
2523 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2524 return \"\";
2525 "
2526 [(set_attr "conds" "set")
2527 (set_attr "predicable" "yes")
2528 (set_attr "type" "logics_imm")]
2529 )
2530
2531 (define_insn_and_split "*ne_zeroextractsi"
2532 [(set (match_operand:SI 0 "s_register_operand" "=r")
2533 (ne:SI (zero_extract:SI
2534 (match_operand:SI 1 "s_register_operand" "r")
2535 (match_operand:SI 2 "const_int_operand" "n")
2536 (match_operand:SI 3 "const_int_operand" "n"))
2537 (const_int 0)))
2538 (clobber (reg:CC CC_REGNUM))]
2539 "TARGET_32BIT
2540 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2541 && INTVAL (operands[2]) > 0
2542 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2543 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2544 "#"
2545 "TARGET_32BIT
2546 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2547 && INTVAL (operands[2]) > 0
2548 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2549 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2550 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2551 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2552 (const_int 0)))
2553 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2554 (set (match_dup 0)
2555 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2556 (match_dup 0) (const_int 1)))]
2557 "
2558 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2559 << INTVAL (operands[3]));
2560 "
2561 [(set_attr "conds" "clob")
2562 (set (attr "length")
2563 (if_then_else (eq_attr "is_thumb" "yes")
2564 (const_int 12)
2565 (const_int 8)))
2566 (set_attr "type" "multiple")]
2567 )
2568
2569 (define_insn_and_split "*ne_zeroextractsi_shifted"
2570 [(set (match_operand:SI 0 "s_register_operand" "=r")
2571 (ne:SI (zero_extract:SI
2572 (match_operand:SI 1 "s_register_operand" "r")
2573 (match_operand:SI 2 "const_int_operand" "n")
2574 (const_int 0))
2575 (const_int 0)))
2576 (clobber (reg:CC CC_REGNUM))]
2577 "TARGET_ARM"
2578 "#"
2579 "TARGET_ARM"
2580 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2581 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2582 (const_int 0)))
2583 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2584 (set (match_dup 0)
2585 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2586 (match_dup 0) (const_int 1)))]
2587 "
2588 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2589 "
2590 [(set_attr "conds" "clob")
2591 (set_attr "length" "8")
2592 (set_attr "type" "multiple")]
2593 )
2594
2595 (define_insn_and_split "*ite_ne_zeroextractsi"
2596 [(set (match_operand:SI 0 "s_register_operand" "=r")
2597 (if_then_else:SI (ne (zero_extract:SI
2598 (match_operand:SI 1 "s_register_operand" "r")
2599 (match_operand:SI 2 "const_int_operand" "n")
2600 (match_operand:SI 3 "const_int_operand" "n"))
2601 (const_int 0))
2602 (match_operand:SI 4 "arm_not_operand" "rIK")
2603 (const_int 0)))
2604 (clobber (reg:CC CC_REGNUM))]
2605 "TARGET_ARM
2606 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2607 && INTVAL (operands[2]) > 0
2608 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2609 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2610 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2611 "#"
2612 "TARGET_ARM
2613 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2614 && INTVAL (operands[2]) > 0
2615 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2616 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2617 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2618 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2619 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2620 (const_int 0)))
2621 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2622 (set (match_dup 0)
2623 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2624 (match_dup 0) (match_dup 4)))]
2625 "
2626 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2627 << INTVAL (operands[3]));
2628 "
2629 [(set_attr "conds" "clob")
2630 (set_attr "length" "8")
2631 (set_attr "type" "multiple")]
2632 )
2633
2634 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2635 [(set (match_operand:SI 0 "s_register_operand" "=r")
2636 (if_then_else:SI (ne (zero_extract:SI
2637 (match_operand:SI 1 "s_register_operand" "r")
2638 (match_operand:SI 2 "const_int_operand" "n")
2639 (const_int 0))
2640 (const_int 0))
2641 (match_operand:SI 3 "arm_not_operand" "rIK")
2642 (const_int 0)))
2643 (clobber (reg:CC CC_REGNUM))]
2644 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2645 "#"
2646 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2647 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2648 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2649 (const_int 0)))
2650 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2651 (set (match_dup 0)
2652 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2653 (match_dup 0) (match_dup 3)))]
2654 "
2655 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2656 "
2657 [(set_attr "conds" "clob")
2658 (set_attr "length" "8")
2659 (set_attr "type" "multiple")]
2660 )
2661
2662 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2663 (define_split
2664 [(set (match_operand:SI 0 "s_register_operand" "")
2665 (match_operator:SI 1 "shiftable_operator"
2666 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2667 (match_operand:SI 3 "const_int_operand" "")
2668 (match_operand:SI 4 "const_int_operand" ""))
2669 (match_operand:SI 5 "s_register_operand" "")]))
2670 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2671 "TARGET_ARM"
2672 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2673 (set (match_dup 0)
2674 (match_op_dup 1
2675 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2676 (match_dup 5)]))]
2677 "{
2678 HOST_WIDE_INT temp = INTVAL (operands[3]);
2679
2680 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2681 operands[4] = GEN_INT (32 - temp);
2682 }"
2683 )
2684
2685 (define_split
2686 [(set (match_operand:SI 0 "s_register_operand" "")
2687 (match_operator:SI 1 "shiftable_operator"
2688 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2689 (match_operand:SI 3 "const_int_operand" "")
2690 (match_operand:SI 4 "const_int_operand" ""))
2691 (match_operand:SI 5 "s_register_operand" "")]))
2692 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2693 "TARGET_ARM"
2694 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2695 (set (match_dup 0)
2696 (match_op_dup 1
2697 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2698 (match_dup 5)]))]
2699 "{
2700 HOST_WIDE_INT temp = INTVAL (operands[3]);
2701
2702 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2703 operands[4] = GEN_INT (32 - temp);
2704 }"
2705 )
2706
2707 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2708 ;;; represented by the bitfield, then this will produce incorrect results.
2709 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2710 ;;; which have a real bit-field insert instruction, the truncation happens
2711 ;;; in the bit-field insert instruction itself. Since arm does not have a
2712 ;;; bit-field insert instruction, we would have to emit code here to truncate
2713 ;;; the value before we insert. This loses some of the advantage of having
2714 ;;; this insv pattern, so this pattern needs to be reevalutated.
2715
2716 (define_expand "insv"
2717 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2718 (match_operand 1 "general_operand" "")
2719 (match_operand 2 "general_operand" ""))
2720 (match_operand 3 "reg_or_int_operand" ""))]
2721 "TARGET_ARM || arm_arch_thumb2"
2722 "
2723 {
2724 int start_bit = INTVAL (operands[2]);
2725 int width = INTVAL (operands[1]);
2726 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2727 rtx target, subtarget;
2728
2729 if (arm_arch_thumb2)
2730 {
2731 if (unaligned_access && MEM_P (operands[0])
2732 && s_register_operand (operands[3], GET_MODE (operands[3]))
2733 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2734 {
2735 rtx base_addr;
2736
2737 if (BYTES_BIG_ENDIAN)
2738 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2739 - start_bit;
2740
2741 if (width == 32)
2742 {
2743 base_addr = adjust_address (operands[0], SImode,
2744 start_bit / BITS_PER_UNIT);
2745 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2746 }
2747 else
2748 {
2749 rtx tmp = gen_reg_rtx (HImode);
2750
2751 base_addr = adjust_address (operands[0], HImode,
2752 start_bit / BITS_PER_UNIT);
2753 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2754 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2755 }
2756 DONE;
2757 }
2758 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2759 {
2760 bool use_bfi = TRUE;
2761
2762 if (CONST_INT_P (operands[3]))
2763 {
2764 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2765
2766 if (val == 0)
2767 {
2768 emit_insn (gen_insv_zero (operands[0], operands[1],
2769 operands[2]));
2770 DONE;
2771 }
2772
2773 /* See if the set can be done with a single orr instruction. */
2774 if (val == mask && const_ok_for_arm (val << start_bit))
2775 use_bfi = FALSE;
2776 }
2777
2778 if (use_bfi)
2779 {
2780 if (!REG_P (operands[3]))
2781 operands[3] = force_reg (SImode, operands[3]);
2782
2783 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2784 operands[3]));
2785 DONE;
2786 }
2787 }
2788 else
2789 FAIL;
2790 }
2791
2792 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2793 FAIL;
2794
2795 target = copy_rtx (operands[0]);
2796 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2797 subreg as the final target. */
2798 if (GET_CODE (target) == SUBREG)
2799 {
2800 subtarget = gen_reg_rtx (SImode);
2801 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2802 < GET_MODE_SIZE (SImode))
2803 target = SUBREG_REG (target);
2804 }
2805 else
2806 subtarget = target;
2807
2808 if (CONST_INT_P (operands[3]))
2809 {
2810 /* Since we are inserting a known constant, we may be able to
2811 reduce the number of bits that we have to clear so that
2812 the mask becomes simple. */
2813 /* ??? This code does not check to see if the new mask is actually
2814 simpler. It may not be. */
2815 rtx op1 = gen_reg_rtx (SImode);
2816 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2817 start of this pattern. */
2818 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2819 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2820
2821 emit_insn (gen_andsi3 (op1, operands[0],
2822 gen_int_mode (~mask2, SImode)));
2823 emit_insn (gen_iorsi3 (subtarget, op1,
2824 gen_int_mode (op3_value << start_bit, SImode)));
2825 }
2826 else if (start_bit == 0
2827 && !(const_ok_for_arm (mask)
2828 || const_ok_for_arm (~mask)))
2829 {
2830 /* A Trick, since we are setting the bottom bits in the word,
2831 we can shift operand[3] up, operand[0] down, OR them together
2832 and rotate the result back again. This takes 3 insns, and
2833 the third might be mergeable into another op. */
2834 /* The shift up copes with the possibility that operand[3] is
2835 wider than the bitfield. */
2836 rtx op0 = gen_reg_rtx (SImode);
2837 rtx op1 = gen_reg_rtx (SImode);
2838
2839 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2840 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2841 emit_insn (gen_iorsi3 (op1, op1, op0));
2842 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2843 }
2844 else if ((width + start_bit == 32)
2845 && !(const_ok_for_arm (mask)
2846 || const_ok_for_arm (~mask)))
2847 {
2848 /* Similar trick, but slightly less efficient. */
2849
2850 rtx op0 = gen_reg_rtx (SImode);
2851 rtx op1 = gen_reg_rtx (SImode);
2852
2853 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2854 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2855 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2856 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2857 }
2858 else
2859 {
2860 rtx op0 = gen_int_mode (mask, SImode);
2861 rtx op1 = gen_reg_rtx (SImode);
2862 rtx op2 = gen_reg_rtx (SImode);
2863
2864 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2865 {
2866 rtx tmp = gen_reg_rtx (SImode);
2867
2868 emit_insn (gen_movsi (tmp, op0));
2869 op0 = tmp;
2870 }
2871
2872 /* Mask out any bits in operand[3] that are not needed. */
2873 emit_insn (gen_andsi3 (op1, operands[3], op0));
2874
2875 if (CONST_INT_P (op0)
2876 && (const_ok_for_arm (mask << start_bit)
2877 || const_ok_for_arm (~(mask << start_bit))))
2878 {
2879 op0 = gen_int_mode (~(mask << start_bit), SImode);
2880 emit_insn (gen_andsi3 (op2, operands[0], op0));
2881 }
2882 else
2883 {
2884 if (CONST_INT_P (op0))
2885 {
2886 rtx tmp = gen_reg_rtx (SImode);
2887
2888 emit_insn (gen_movsi (tmp, op0));
2889 op0 = tmp;
2890 }
2891
2892 if (start_bit != 0)
2893 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2894
2895 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2896 }
2897
2898 if (start_bit != 0)
2899 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2900
2901 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2902 }
2903
2904 if (subtarget != target)
2905 {
2906 /* If TARGET is still a SUBREG, then it must be wider than a word,
2907 so we must be careful only to set the subword we were asked to. */
2908 if (GET_CODE (target) == SUBREG)
2909 emit_move_insn (target, subtarget);
2910 else
2911 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2912 }
2913
2914 DONE;
2915 }"
2916 )
2917
2918 (define_insn "insv_zero"
2919 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2920 (match_operand:SI 1 "const_int_M_operand" "M")
2921 (match_operand:SI 2 "const_int_M_operand" "M"))
2922 (const_int 0))]
2923 "arm_arch_thumb2"
2924 "bfc%?\t%0, %2, %1"
2925 [(set_attr "length" "4")
2926 (set_attr "predicable" "yes")
2927 (set_attr "type" "bfm")]
2928 )
2929
2930 (define_insn "insv_t2"
2931 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2932 (match_operand:SI 1 "const_int_M_operand" "M")
2933 (match_operand:SI 2 "const_int_M_operand" "M"))
2934 (match_operand:SI 3 "s_register_operand" "r"))]
2935 "arm_arch_thumb2"
2936 "bfi%?\t%0, %3, %2, %1"
2937 [(set_attr "length" "4")
2938 (set_attr "predicable" "yes")
2939 (set_attr "type" "bfm")]
2940 )
2941
2942 ; constants for op 2 will never be given to these patterns.
2943 (define_insn_and_split "*anddi_notdi_di"
2944 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2945 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2946 (match_operand:DI 2 "s_register_operand" "r,0")))]
2947 "TARGET_32BIT"
2948 "#"
2949 "TARGET_32BIT && reload_completed
2950 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2951 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2952 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2953 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2954 "
2955 {
2956 operands[3] = gen_highpart (SImode, operands[0]);
2957 operands[0] = gen_lowpart (SImode, operands[0]);
2958 operands[4] = gen_highpart (SImode, operands[1]);
2959 operands[1] = gen_lowpart (SImode, operands[1]);
2960 operands[5] = gen_highpart (SImode, operands[2]);
2961 operands[2] = gen_lowpart (SImode, operands[2]);
2962 }"
2963 [(set_attr "length" "8")
2964 (set_attr "predicable" "yes")
2965 (set_attr "type" "multiple")]
2966 )
2967
2968 (define_insn_and_split "*anddi_notzesidi_di"
2969 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2970 (and:DI (not:DI (zero_extend:DI
2971 (match_operand:SI 2 "s_register_operand" "r,r")))
2972 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2973 "TARGET_32BIT"
2974 "@
2975 bic%?\\t%Q0, %Q1, %2
2976 #"
2977 ; (not (zero_extend ...)) allows us to just copy the high word from
2978 ; operand1 to operand0.
2979 "TARGET_32BIT
2980 && reload_completed
2981 && operands[0] != operands[1]"
2982 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2983 (set (match_dup 3) (match_dup 4))]
2984 "
2985 {
2986 operands[3] = gen_highpart (SImode, operands[0]);
2987 operands[0] = gen_lowpart (SImode, operands[0]);
2988 operands[4] = gen_highpart (SImode, operands[1]);
2989 operands[1] = gen_lowpart (SImode, operands[1]);
2990 }"
2991 [(set_attr "length" "4,8")
2992 (set_attr "predicable" "yes")
2993 (set_attr "type" "multiple")]
2994 )
2995
2996 (define_insn_and_split "*anddi_notdi_zesidi"
2997 [(set (match_operand:DI 0 "s_register_operand" "=r")
2998 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2999 (zero_extend:DI
3000 (match_operand:SI 1 "s_register_operand" "r"))))]
3001 "TARGET_32BIT"
3002 "#"
3003 "TARGET_32BIT && reload_completed"
3004 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3005 (set (match_dup 3) (const_int 0))]
3006 "
3007 {
3008 operands[3] = gen_highpart (SImode, operands[0]);
3009 operands[0] = gen_lowpart (SImode, operands[0]);
3010 operands[2] = gen_lowpart (SImode, operands[2]);
3011 }"
3012 [(set_attr "length" "8")
3013 (set_attr "predicable" "yes")
3014 (set_attr "type" "multiple")]
3015 )
3016
3017 (define_insn_and_split "*anddi_notsesidi_di"
3018 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3019 (and:DI (not:DI (sign_extend:DI
3020 (match_operand:SI 2 "s_register_operand" "r,r")))
3021 (match_operand:DI 1 "s_register_operand" "0,r")))]
3022 "TARGET_32BIT"
3023 "#"
3024 "TARGET_32BIT && reload_completed"
3025 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3026 (set (match_dup 3) (and:SI (not:SI
3027 (ashiftrt:SI (match_dup 2) (const_int 31)))
3028 (match_dup 4)))]
3029 "
3030 {
3031 operands[3] = gen_highpart (SImode, operands[0]);
3032 operands[0] = gen_lowpart (SImode, operands[0]);
3033 operands[4] = gen_highpart (SImode, operands[1]);
3034 operands[1] = gen_lowpart (SImode, operands[1]);
3035 }"
3036 [(set_attr "length" "8")
3037 (set_attr "predicable" "yes")
3038 (set_attr "type" "multiple")]
3039 )
3040
3041 (define_insn "andsi_notsi_si"
3042 [(set (match_operand:SI 0 "s_register_operand" "=r")
3043 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3044 (match_operand:SI 1 "s_register_operand" "r")))]
3045 "TARGET_32BIT"
3046 "bic%?\\t%0, %1, %2"
3047 [(set_attr "predicable" "yes")
3048 (set_attr "type" "logic_reg")]
3049 )
3050
3051 (define_insn "andsi_not_shiftsi_si"
3052 [(set (match_operand:SI 0 "s_register_operand" "=r")
3053 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3054 [(match_operand:SI 2 "s_register_operand" "r")
3055 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3056 (match_operand:SI 1 "s_register_operand" "r")))]
3057 "TARGET_ARM"
3058 "bic%?\\t%0, %1, %2%S4"
3059 [(set_attr "predicable" "yes")
3060 (set_attr "shift" "2")
3061 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3062 (const_string "logic_shift_imm")
3063 (const_string "logic_shift_reg")))]
3064 )
3065
3066 ;; Shifted bics pattern used to set up CC status register and not reusing
3067 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3068 ;; does not support shift by register.
3069 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3070 [(set (reg:CC_NOOV CC_REGNUM)
3071 (compare:CC_NOOV
3072 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3073 [(match_operand:SI 1 "s_register_operand" "r")
3074 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3075 (match_operand:SI 3 "s_register_operand" "r"))
3076 (const_int 0)))
3077 (clobber (match_scratch:SI 4 "=r"))]
3078 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3079 "bics%?\\t%4, %3, %1%S0"
3080 [(set_attr "predicable" "yes")
3081 (set_attr "conds" "set")
3082 (set_attr "shift" "1")
3083 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3084 (const_string "logic_shift_imm")
3085 (const_string "logic_shift_reg")))]
3086 )
3087
3088 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3089 ;; getting reused later.
3090 (define_insn "andsi_not_shiftsi_si_scc"
3091 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3092 (compare:CC_NOOV
3093 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3094 [(match_operand:SI 1 "s_register_operand" "r")
3095 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3096 (match_operand:SI 3 "s_register_operand" "r"))
3097 (const_int 0)))
3098 (set (match_operand:SI 4 "s_register_operand" "=r")
3099 (and:SI (not:SI (match_op_dup 0
3100 [(match_dup 1)
3101 (match_dup 2)]))
3102 (match_dup 3)))])]
3103 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3104 "bics%?\\t%4, %3, %1%S0"
3105 [(set_attr "predicable" "yes")
3106 (set_attr "conds" "set")
3107 (set_attr "shift" "1")
3108 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3109 (const_string "logic_shift_imm")
3110 (const_string "logic_shift_reg")))]
3111 )
3112
3113 (define_insn "*andsi_notsi_si_compare0"
3114 [(set (reg:CC_NOOV CC_REGNUM)
3115 (compare:CC_NOOV
3116 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3117 (match_operand:SI 1 "s_register_operand" "r"))
3118 (const_int 0)))
3119 (set (match_operand:SI 0 "s_register_operand" "=r")
3120 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3121 "TARGET_32BIT"
3122 "bics\\t%0, %1, %2"
3123 [(set_attr "conds" "set")
3124 (set_attr "type" "logics_shift_reg")]
3125 )
3126
3127 (define_insn "*andsi_notsi_si_compare0_scratch"
3128 [(set (reg:CC_NOOV CC_REGNUM)
3129 (compare:CC_NOOV
3130 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3131 (match_operand:SI 1 "s_register_operand" "r"))
3132 (const_int 0)))
3133 (clobber (match_scratch:SI 0 "=r"))]
3134 "TARGET_32BIT"
3135 "bics\\t%0, %1, %2"
3136 [(set_attr "conds" "set")
3137 (set_attr "type" "logics_shift_reg")]
3138 )
3139
3140 (define_expand "iordi3"
3141 [(set (match_operand:DI 0 "s_register_operand" "")
3142 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3143 (match_operand:DI 2 "neon_logic_op2" "")))]
3144 "TARGET_32BIT"
3145 "
3146 if (!TARGET_NEON && !TARGET_IWMMXT)
3147 {
3148 rtx low = simplify_gen_binary (IOR, SImode,
3149 gen_lowpart (SImode, operands[1]),
3150 gen_lowpart (SImode, operands[2]));
3151 rtx high = simplify_gen_binary (IOR, SImode,
3152 gen_highpart (SImode, operands[1]),
3153 gen_highpart_mode (SImode, DImode,
3154 operands[2]));
3155
3156 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3157 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3158
3159 DONE;
3160 }
3161 /* Otherwise expand pattern as above. */
3162 "
3163 )
3164
3165 (define_insn_and_split "*iordi3_insn"
3166 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3167 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3168 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3169 "TARGET_32BIT && !TARGET_IWMMXT"
3170 {
3171 switch (which_alternative)
3172 {
3173 case 0: /* fall through */
3174 case 6: return "vorr\t%P0, %P1, %P2";
3175 case 1: /* fall through */
3176 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3177 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3178 case 2:
3179 case 3:
3180 case 4:
3181 case 5:
3182 return "#";
3183 default: gcc_unreachable ();
3184 }
3185 }
3186 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3187 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3188 [(set (match_dup 3) (match_dup 4))
3189 (set (match_dup 5) (match_dup 6))]
3190 "
3191 {
3192 operands[3] = gen_lowpart (SImode, operands[0]);
3193 operands[5] = gen_highpart (SImode, operands[0]);
3194
3195 operands[4] = simplify_gen_binary (IOR, SImode,
3196 gen_lowpart (SImode, operands[1]),
3197 gen_lowpart (SImode, operands[2]));
3198 operands[6] = simplify_gen_binary (IOR, SImode,
3199 gen_highpart (SImode, operands[1]),
3200 gen_highpart_mode (SImode, DImode, operands[2]));
3201
3202 }"
3203 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3204 multiple,neon_logic,neon_logic")
3205 (set_attr "length" "*,*,8,8,8,8,*,*")
3206 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3207 )
3208
3209 (define_insn "*iordi_zesidi_di"
3210 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3211 (ior:DI (zero_extend:DI
3212 (match_operand:SI 2 "s_register_operand" "r,r"))
3213 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3214 "TARGET_32BIT"
3215 "@
3216 orr%?\\t%Q0, %Q1, %2
3217 #"
3218 [(set_attr "length" "4,8")
3219 (set_attr "predicable" "yes")
3220 (set_attr "type" "logic_reg,multiple")]
3221 )
3222
3223 (define_insn "*iordi_sesidi_di"
3224 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3225 (ior:DI (sign_extend:DI
3226 (match_operand:SI 2 "s_register_operand" "r,r"))
3227 (match_operand:DI 1 "s_register_operand" "0,r")))]
3228 "TARGET_32BIT"
3229 "#"
3230 [(set_attr "length" "8")
3231 (set_attr "predicable" "yes")
3232 (set_attr "type" "multiple")]
3233 )
3234
3235 (define_expand "iorsi3"
3236 [(set (match_operand:SI 0 "s_register_operand" "")
3237 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3238 (match_operand:SI 2 "reg_or_int_operand" "")))]
3239 "TARGET_EITHER"
3240 "
3241 if (CONST_INT_P (operands[2]))
3242 {
3243 if (TARGET_32BIT)
3244 {
3245 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3246 operands[2] = force_reg (SImode, operands[2]);
3247 else
3248 {
3249 arm_split_constant (IOR, SImode, NULL_RTX,
3250 INTVAL (operands[2]), operands[0],
3251 operands[1],
3252 optimize && can_create_pseudo_p ());
3253 DONE;
3254 }
3255 }
3256 else /* TARGET_THUMB1 */
3257 {
3258 rtx tmp = force_reg (SImode, operands[2]);
3259 if (rtx_equal_p (operands[0], operands[1]))
3260 operands[2] = tmp;
3261 else
3262 {
3263 operands[2] = operands[1];
3264 operands[1] = tmp;
3265 }
3266 }
3267 }
3268 "
3269 )
3270
3271 (define_insn_and_split "*iorsi3_insn"
3272 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3273 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3274 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3275 "TARGET_32BIT"
3276 "@
3277 orr%?\\t%0, %1, %2
3278 orr%?\\t%0, %1, %2
3279 orn%?\\t%0, %1, #%B2
3280 orr%?\\t%0, %1, %2
3281 #"
3282 "TARGET_32BIT
3283 && CONST_INT_P (operands[2])
3284 && !(const_ok_for_arm (INTVAL (operands[2]))
3285 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3286 [(clobber (const_int 0))]
3287 {
3288 arm_split_constant (IOR, SImode, curr_insn,
3289 INTVAL (operands[2]), operands[0], operands[1], 0);
3290 DONE;
3291 }
3292 [(set_attr "length" "4,4,4,4,16")
3293 (set_attr "arch" "32,t2,t2,32,32")
3294 (set_attr "predicable" "yes")
3295 (set_attr "predicable_short_it" "no,yes,no,no,no")
3296 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3297 )
3298
3299 (define_peephole2
3300 [(match_scratch:SI 3 "r")
3301 (set (match_operand:SI 0 "arm_general_register_operand" "")
3302 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3303 (match_operand:SI 2 "const_int_operand" "")))]
3304 "TARGET_ARM
3305 && !const_ok_for_arm (INTVAL (operands[2]))
3306 && const_ok_for_arm (~INTVAL (operands[2]))"
3307 [(set (match_dup 3) (match_dup 2))
3308 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3309 ""
3310 )
3311
3312 (define_insn "*iorsi3_compare0"
3313 [(set (reg:CC_NOOV CC_REGNUM)
3314 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3315 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3316 (const_int 0)))
3317 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3318 (ior:SI (match_dup 1) (match_dup 2)))]
3319 "TARGET_32BIT"
3320 "orrs%?\\t%0, %1, %2"
3321 [(set_attr "conds" "set")
3322 (set_attr "type" "logics_imm,logics_reg")]
3323 )
3324
3325 (define_insn "*iorsi3_compare0_scratch"
3326 [(set (reg:CC_NOOV CC_REGNUM)
3327 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3328 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3329 (const_int 0)))
3330 (clobber (match_scratch:SI 0 "=r,r"))]
3331 "TARGET_32BIT"
3332 "orrs%?\\t%0, %1, %2"
3333 [(set_attr "conds" "set")
3334 (set_attr "type" "logics_imm,logics_reg")]
3335 )
3336
3337 (define_expand "xordi3"
3338 [(set (match_operand:DI 0 "s_register_operand" "")
3339 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3340 (match_operand:DI 2 "arm_xordi_operand" "")))]
3341 "TARGET_32BIT"
3342 {
3343 /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3344 to reuse this expander for all TARGET_32BIT targets so just force the
3345 constants into a register. Unlike for the anddi3 and iordi3 there are
3346 no NEON instructions that take an immediate. */
3347 if (TARGET_IWMMXT && !REG_P (operands[2]))
3348 operands[2] = force_reg (DImode, operands[2]);
3349 if (!TARGET_NEON && !TARGET_IWMMXT)
3350 {
3351 rtx low = simplify_gen_binary (XOR, SImode,
3352 gen_lowpart (SImode, operands[1]),
3353 gen_lowpart (SImode, operands[2]));
3354 rtx high = simplify_gen_binary (XOR, SImode,
3355 gen_highpart (SImode, operands[1]),
3356 gen_highpart_mode (SImode, DImode,
3357 operands[2]));
3358
3359 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3360 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3361
3362 DONE;
3363 }
3364 /* Otherwise expand pattern as above. */
3365 }
3366 )
3367
3368 (define_insn_and_split "*xordi3_insn"
3369 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3370 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3371 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3372 "TARGET_32BIT && !TARGET_IWMMXT"
3373 {
3374 switch (which_alternative)
3375 {
3376 case 1:
3377 case 2:
3378 case 3:
3379 case 4: /* fall through */
3380 return "#";
3381 case 0: /* fall through */
3382 case 5: return "veor\t%P0, %P1, %P2";
3383 default: gcc_unreachable ();
3384 }
3385 }
3386 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3387 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3388 [(set (match_dup 3) (match_dup 4))
3389 (set (match_dup 5) (match_dup 6))]
3390 "
3391 {
3392 operands[3] = gen_lowpart (SImode, operands[0]);
3393 operands[5] = gen_highpart (SImode, operands[0]);
3394
3395 operands[4] = simplify_gen_binary (XOR, SImode,
3396 gen_lowpart (SImode, operands[1]),
3397 gen_lowpart (SImode, operands[2]));
3398 operands[6] = simplify_gen_binary (XOR, SImode,
3399 gen_highpart (SImode, operands[1]),
3400 gen_highpart_mode (SImode, DImode, operands[2]));
3401
3402 }"
3403 [(set_attr "length" "*,8,8,8,8,*")
3404 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3405 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3406 )
3407
3408 (define_insn "*xordi_zesidi_di"
3409 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3410 (xor:DI (zero_extend:DI
3411 (match_operand:SI 2 "s_register_operand" "r,r"))
3412 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3413 "TARGET_32BIT"
3414 "@
3415 eor%?\\t%Q0, %Q1, %2
3416 #"
3417 [(set_attr "length" "4,8")
3418 (set_attr "predicable" "yes")
3419 (set_attr "type" "logic_reg")]
3420 )
3421
3422 (define_insn "*xordi_sesidi_di"
3423 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3424 (xor:DI (sign_extend:DI
3425 (match_operand:SI 2 "s_register_operand" "r,r"))
3426 (match_operand:DI 1 "s_register_operand" "0,r")))]
3427 "TARGET_32BIT"
3428 "#"
3429 [(set_attr "length" "8")
3430 (set_attr "predicable" "yes")
3431 (set_attr "type" "multiple")]
3432 )
3433
3434 (define_expand "xorsi3"
3435 [(set (match_operand:SI 0 "s_register_operand" "")
3436 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3437 (match_operand:SI 2 "reg_or_int_operand" "")))]
3438 "TARGET_EITHER"
3439 "if (CONST_INT_P (operands[2]))
3440 {
3441 if (TARGET_32BIT)
3442 {
3443 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3444 operands[2] = force_reg (SImode, operands[2]);
3445 else
3446 {
3447 arm_split_constant (XOR, SImode, NULL_RTX,
3448 INTVAL (operands[2]), operands[0],
3449 operands[1],
3450 optimize && can_create_pseudo_p ());
3451 DONE;
3452 }
3453 }
3454 else /* TARGET_THUMB1 */
3455 {
3456 rtx tmp = force_reg (SImode, operands[2]);
3457 if (rtx_equal_p (operands[0], operands[1]))
3458 operands[2] = tmp;
3459 else
3460 {
3461 operands[2] = operands[1];
3462 operands[1] = tmp;
3463 }
3464 }
3465 }"
3466 )
3467
3468 (define_insn_and_split "*arm_xorsi3"
3469 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3470 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3471 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3472 "TARGET_32BIT"
3473 "@
3474 eor%?\\t%0, %1, %2
3475 eor%?\\t%0, %1, %2
3476 eor%?\\t%0, %1, %2
3477 #"
3478 "TARGET_32BIT
3479 && CONST_INT_P (operands[2])
3480 && !const_ok_for_arm (INTVAL (operands[2]))"
3481 [(clobber (const_int 0))]
3482 {
3483 arm_split_constant (XOR, SImode, curr_insn,
3484 INTVAL (operands[2]), operands[0], operands[1], 0);
3485 DONE;
3486 }
3487 [(set_attr "length" "4,4,4,16")
3488 (set_attr "predicable" "yes")
3489 (set_attr "predicable_short_it" "no,yes,no,no")
3490 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3491 )
3492
3493 (define_insn "*xorsi3_compare0"
3494 [(set (reg:CC_NOOV CC_REGNUM)
3495 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3496 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3497 (const_int 0)))
3498 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3499 (xor:SI (match_dup 1) (match_dup 2)))]
3500 "TARGET_32BIT"
3501 "eors%?\\t%0, %1, %2"
3502 [(set_attr "conds" "set")
3503 (set_attr "type" "logics_imm,logics_reg")]
3504 )
3505
3506 (define_insn "*xorsi3_compare0_scratch"
3507 [(set (reg:CC_NOOV CC_REGNUM)
3508 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3509 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3510 (const_int 0)))]
3511 "TARGET_32BIT"
3512 "teq%?\\t%0, %1"
3513 [(set_attr "conds" "set")
3514 (set_attr "type" "logics_imm,logics_reg")]
3515 )
3516
3517 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3518 ; (NOT D) we can sometimes merge the final NOT into one of the following
3519 ; insns.
3520
3521 (define_split
3522 [(set (match_operand:SI 0 "s_register_operand" "")
3523 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3524 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3525 (match_operand:SI 3 "arm_rhs_operand" "")))
3526 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3527 "TARGET_32BIT"
3528 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3529 (not:SI (match_dup 3))))
3530 (set (match_dup 0) (not:SI (match_dup 4)))]
3531 ""
3532 )
3533
3534 (define_insn_and_split "*andsi_iorsi3_notsi"
3535 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3536 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3537 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3538 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3539 "TARGET_32BIT"
3540 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3541 "&& reload_completed"
3542 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3543 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3544 {
3545 /* If operands[3] is a constant make sure to fold the NOT into it
3546 to avoid creating a NOT of a CONST_INT. */
3547 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3548 if (CONST_INT_P (not_rtx))
3549 {
3550 operands[4] = operands[0];
3551 operands[5] = not_rtx;
3552 }
3553 else
3554 {
3555 operands[5] = operands[0];
3556 operands[4] = not_rtx;
3557 }
3558 }
3559 [(set_attr "length" "8")
3560 (set_attr "ce_count" "2")
3561 (set_attr "predicable" "yes")
3562 (set_attr "type" "multiple")]
3563 )
3564
3565 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3566 ; insns are available?
3567 (define_split
3568 [(set (match_operand:SI 0 "s_register_operand" "")
3569 (match_operator:SI 1 "logical_binary_operator"
3570 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3571 (match_operand:SI 3 "const_int_operand" "")
3572 (match_operand:SI 4 "const_int_operand" ""))
3573 (match_operator:SI 9 "logical_binary_operator"
3574 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3575 (match_operand:SI 6 "const_int_operand" ""))
3576 (match_operand:SI 7 "s_register_operand" "")])]))
3577 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3578 "TARGET_32BIT
3579 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3580 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3581 [(set (match_dup 8)
3582 (match_op_dup 1
3583 [(ashift:SI (match_dup 2) (match_dup 4))
3584 (match_dup 5)]))
3585 (set (match_dup 0)
3586 (match_op_dup 1
3587 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3588 (match_dup 7)]))]
3589 "
3590 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3591 ")
3592
3593 (define_split
3594 [(set (match_operand:SI 0 "s_register_operand" "")
3595 (match_operator:SI 1 "logical_binary_operator"
3596 [(match_operator:SI 9 "logical_binary_operator"
3597 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3598 (match_operand:SI 6 "const_int_operand" ""))
3599 (match_operand:SI 7 "s_register_operand" "")])
3600 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3601 (match_operand:SI 3 "const_int_operand" "")
3602 (match_operand:SI 4 "const_int_operand" ""))]))
3603 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3604 "TARGET_32BIT
3605 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3606 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3607 [(set (match_dup 8)
3608 (match_op_dup 1
3609 [(ashift:SI (match_dup 2) (match_dup 4))
3610 (match_dup 5)]))
3611 (set (match_dup 0)
3612 (match_op_dup 1
3613 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3614 (match_dup 7)]))]
3615 "
3616 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3617 ")
3618
3619 (define_split
3620 [(set (match_operand:SI 0 "s_register_operand" "")
3621 (match_operator:SI 1 "logical_binary_operator"
3622 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3623 (match_operand:SI 3 "const_int_operand" "")
3624 (match_operand:SI 4 "const_int_operand" ""))
3625 (match_operator:SI 9 "logical_binary_operator"
3626 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3627 (match_operand:SI 6 "const_int_operand" ""))
3628 (match_operand:SI 7 "s_register_operand" "")])]))
3629 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3630 "TARGET_32BIT
3631 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3632 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3633 [(set (match_dup 8)
3634 (match_op_dup 1
3635 [(ashift:SI (match_dup 2) (match_dup 4))
3636 (match_dup 5)]))
3637 (set (match_dup 0)
3638 (match_op_dup 1
3639 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3640 (match_dup 7)]))]
3641 "
3642 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3643 ")
3644
3645 (define_split
3646 [(set (match_operand:SI 0 "s_register_operand" "")
3647 (match_operator:SI 1 "logical_binary_operator"
3648 [(match_operator:SI 9 "logical_binary_operator"
3649 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3650 (match_operand:SI 6 "const_int_operand" ""))
3651 (match_operand:SI 7 "s_register_operand" "")])
3652 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3653 (match_operand:SI 3 "const_int_operand" "")
3654 (match_operand:SI 4 "const_int_operand" ""))]))
3655 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3656 "TARGET_32BIT
3657 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3658 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3659 [(set (match_dup 8)
3660 (match_op_dup 1
3661 [(ashift:SI (match_dup 2) (match_dup 4))
3662 (match_dup 5)]))
3663 (set (match_dup 0)
3664 (match_op_dup 1
3665 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3666 (match_dup 7)]))]
3667 "
3668 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3669 ")
3670 \f
3671
3672 ;; Minimum and maximum insns
3673
3674 (define_expand "smaxsi3"
3675 [(parallel [
3676 (set (match_operand:SI 0 "s_register_operand" "")
3677 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3678 (match_operand:SI 2 "arm_rhs_operand" "")))
3679 (clobber (reg:CC CC_REGNUM))])]
3680 "TARGET_32BIT"
3681 "
3682 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3683 {
3684 /* No need for a clobber of the condition code register here. */
3685 emit_insn (gen_rtx_SET (operands[0],
3686 gen_rtx_SMAX (SImode, operands[1],
3687 operands[2])));
3688 DONE;
3689 }
3690 ")
3691
3692 (define_insn "*smax_0"
3693 [(set (match_operand:SI 0 "s_register_operand" "=r")
3694 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3695 (const_int 0)))]
3696 "TARGET_32BIT"
3697 "bic%?\\t%0, %1, %1, asr #31"
3698 [(set_attr "predicable" "yes")
3699 (set_attr "type" "logic_shift_reg")]
3700 )
3701
3702 (define_insn "*smax_m1"
3703 [(set (match_operand:SI 0 "s_register_operand" "=r")
3704 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3705 (const_int -1)))]
3706 "TARGET_32BIT"
3707 "orr%?\\t%0, %1, %1, asr #31"
3708 [(set_attr "predicable" "yes")
3709 (set_attr "type" "logic_shift_reg")]
3710 )
3711
3712 (define_insn_and_split "*arm_smax_insn"
3713 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3714 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3715 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3716 (clobber (reg:CC CC_REGNUM))]
3717 "TARGET_ARM"
3718 "#"
3719 ; cmp\\t%1, %2\;movlt\\t%0, %2
3720 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3721 "TARGET_ARM"
3722 [(set (reg:CC CC_REGNUM)
3723 (compare:CC (match_dup 1) (match_dup 2)))
3724 (set (match_dup 0)
3725 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3726 (match_dup 1)
3727 (match_dup 2)))]
3728 ""
3729 [(set_attr "conds" "clob")
3730 (set_attr "length" "8,12")
3731 (set_attr "type" "multiple")]
3732 )
3733
3734 (define_expand "sminsi3"
3735 [(parallel [
3736 (set (match_operand:SI 0 "s_register_operand" "")
3737 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3738 (match_operand:SI 2 "arm_rhs_operand" "")))
3739 (clobber (reg:CC CC_REGNUM))])]
3740 "TARGET_32BIT"
3741 "
3742 if (operands[2] == const0_rtx)
3743 {
3744 /* No need for a clobber of the condition code register here. */
3745 emit_insn (gen_rtx_SET (operands[0],
3746 gen_rtx_SMIN (SImode, operands[1],
3747 operands[2])));
3748 DONE;
3749 }
3750 ")
3751
3752 (define_insn "*smin_0"
3753 [(set (match_operand:SI 0 "s_register_operand" "=r")
3754 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3755 (const_int 0)))]
3756 "TARGET_32BIT"
3757 "and%?\\t%0, %1, %1, asr #31"
3758 [(set_attr "predicable" "yes")
3759 (set_attr "type" "logic_shift_reg")]
3760 )
3761
3762 (define_insn_and_split "*arm_smin_insn"
3763 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3764 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3765 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3766 (clobber (reg:CC CC_REGNUM))]
3767 "TARGET_ARM"
3768 "#"
3769 ; cmp\\t%1, %2\;movge\\t%0, %2
3770 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3771 "TARGET_ARM"
3772 [(set (reg:CC CC_REGNUM)
3773 (compare:CC (match_dup 1) (match_dup 2)))
3774 (set (match_dup 0)
3775 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3776 (match_dup 1)
3777 (match_dup 2)))]
3778 ""
3779 [(set_attr "conds" "clob")
3780 (set_attr "length" "8,12")
3781 (set_attr "type" "multiple,multiple")]
3782 )
3783
3784 (define_expand "umaxsi3"
3785 [(parallel [
3786 (set (match_operand:SI 0 "s_register_operand" "")
3787 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3788 (match_operand:SI 2 "arm_rhs_operand" "")))
3789 (clobber (reg:CC CC_REGNUM))])]
3790 "TARGET_32BIT"
3791 ""
3792 )
3793
3794 (define_insn_and_split "*arm_umaxsi3"
3795 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3796 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3797 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3798 (clobber (reg:CC CC_REGNUM))]
3799 "TARGET_ARM"
3800 "#"
3801 ; cmp\\t%1, %2\;movcc\\t%0, %2
3802 ; cmp\\t%1, %2\;movcs\\t%0, %1
3803 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3804 "TARGET_ARM"
3805 [(set (reg:CC CC_REGNUM)
3806 (compare:CC (match_dup 1) (match_dup 2)))
3807 (set (match_dup 0)
3808 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3809 (match_dup 1)
3810 (match_dup 2)))]
3811 ""
3812 [(set_attr "conds" "clob")
3813 (set_attr "length" "8,8,12")
3814 (set_attr "type" "store_4")]
3815 )
3816
3817 (define_expand "uminsi3"
3818 [(parallel [
3819 (set (match_operand:SI 0 "s_register_operand" "")
3820 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3821 (match_operand:SI 2 "arm_rhs_operand" "")))
3822 (clobber (reg:CC CC_REGNUM))])]
3823 "TARGET_32BIT"
3824 ""
3825 )
3826
3827 (define_insn_and_split "*arm_uminsi3"
3828 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3829 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3830 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3831 (clobber (reg:CC CC_REGNUM))]
3832 "TARGET_ARM"
3833 "#"
3834 ; cmp\\t%1, %2\;movcs\\t%0, %2
3835 ; cmp\\t%1, %2\;movcc\\t%0, %1
3836 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3837 "TARGET_ARM"
3838 [(set (reg:CC CC_REGNUM)
3839 (compare:CC (match_dup 1) (match_dup 2)))
3840 (set (match_dup 0)
3841 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3842 (match_dup 1)
3843 (match_dup 2)))]
3844 ""
3845 [(set_attr "conds" "clob")
3846 (set_attr "length" "8,8,12")
3847 (set_attr "type" "store_4")]
3848 )
3849
3850 (define_insn "*store_minmaxsi"
3851 [(set (match_operand:SI 0 "memory_operand" "=m")
3852 (match_operator:SI 3 "minmax_operator"
3853 [(match_operand:SI 1 "s_register_operand" "r")
3854 (match_operand:SI 2 "s_register_operand" "r")]))
3855 (clobber (reg:CC CC_REGNUM))]
3856 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3857 "*
3858 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3859 operands[1], operands[2]);
3860 output_asm_insn (\"cmp\\t%1, %2\", operands);
3861 if (TARGET_THUMB2)
3862 output_asm_insn (\"ite\t%d3\", operands);
3863 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3864 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3865 return \"\";
3866 "
3867 [(set_attr "conds" "clob")
3868 (set (attr "length")
3869 (if_then_else (eq_attr "is_thumb" "yes")
3870 (const_int 14)
3871 (const_int 12)))
3872 (set_attr "type" "store_4")]
3873 )
3874
3875 ; Reject the frame pointer in operand[1], since reloading this after
3876 ; it has been eliminated can cause carnage.
3877 (define_insn "*minmax_arithsi"
3878 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3879 (match_operator:SI 4 "shiftable_operator"
3880 [(match_operator:SI 5 "minmax_operator"
3881 [(match_operand:SI 2 "s_register_operand" "r,r")
3882 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3883 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3884 (clobber (reg:CC CC_REGNUM))]
3885 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3886 "*
3887 {
3888 enum rtx_code code = GET_CODE (operands[4]);
3889 bool need_else;
3890
3891 if (which_alternative != 0 || operands[3] != const0_rtx
3892 || (code != PLUS && code != IOR && code != XOR))
3893 need_else = true;
3894 else
3895 need_else = false;
3896
3897 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3898 operands[2], operands[3]);
3899 output_asm_insn (\"cmp\\t%2, %3\", operands);
3900 if (TARGET_THUMB2)
3901 {
3902 if (need_else)
3903 output_asm_insn (\"ite\\t%d5\", operands);
3904 else
3905 output_asm_insn (\"it\\t%d5\", operands);
3906 }
3907 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3908 if (need_else)
3909 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3910 return \"\";
3911 }"
3912 [(set_attr "conds" "clob")
3913 (set (attr "length")
3914 (if_then_else (eq_attr "is_thumb" "yes")
3915 (const_int 14)
3916 (const_int 12)))
3917 (set_attr "type" "multiple")]
3918 )
3919
3920 ; Reject the frame pointer in operand[1], since reloading this after
3921 ; it has been eliminated can cause carnage.
3922 (define_insn_and_split "*minmax_arithsi_non_canon"
3923 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3924 (minus:SI
3925 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3926 (match_operator:SI 4 "minmax_operator"
3927 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3928 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3929 (clobber (reg:CC CC_REGNUM))]
3930 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3931 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3932 "#"
3933 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3934 [(set (reg:CC CC_REGNUM)
3935 (compare:CC (match_dup 2) (match_dup 3)))
3936
3937 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3938 (set (match_dup 0)
3939 (minus:SI (match_dup 1)
3940 (match_dup 2))))
3941 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3942 (set (match_dup 0)
3943 (match_dup 6)))]
3944 {
3945 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3946 operands[2], operands[3]);
3947 enum rtx_code rc = minmax_code (operands[4]);
3948 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3949 operands[2], operands[3]);
3950
3951 if (mode == CCFPmode || mode == CCFPEmode)
3952 rc = reverse_condition_maybe_unordered (rc);
3953 else
3954 rc = reverse_condition (rc);
3955 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3956 if (CONST_INT_P (operands[3]))
3957 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3958 else
3959 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3960 }
3961 [(set_attr "conds" "clob")
3962 (set (attr "length")
3963 (if_then_else (eq_attr "is_thumb" "yes")
3964 (const_int 14)
3965 (const_int 12)))
3966 (set_attr "type" "multiple")]
3967 )
3968
3969 (define_code_iterator SAT [smin smax])
3970 (define_code_iterator SATrev [smin smax])
3971 (define_code_attr SATlo [(smin "1") (smax "2")])
3972 (define_code_attr SAThi [(smin "2") (smax "1")])
3973
3974 (define_insn "*satsi_<SAT:code>"
3975 [(set (match_operand:SI 0 "s_register_operand" "=r")
3976 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3977 (match_operand:SI 1 "const_int_operand" "i"))
3978 (match_operand:SI 2 "const_int_operand" "i")))]
3979 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3980 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3981 {
3982 int mask;
3983 bool signed_sat;
3984 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3985 &mask, &signed_sat))
3986 gcc_unreachable ();
3987
3988 operands[1] = GEN_INT (mask);
3989 if (signed_sat)
3990 return "ssat%?\t%0, %1, %3";
3991 else
3992 return "usat%?\t%0, %1, %3";
3993 }
3994 [(set_attr "predicable" "yes")
3995 (set_attr "type" "alus_imm")]
3996 )
3997
3998 (define_insn "*satsi_<SAT:code>_shift"
3999 [(set (match_operand:SI 0 "s_register_operand" "=r")
4000 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
4001 [(match_operand:SI 4 "s_register_operand" "r")
4002 (match_operand:SI 5 "const_int_operand" "i")])
4003 (match_operand:SI 1 "const_int_operand" "i"))
4004 (match_operand:SI 2 "const_int_operand" "i")))]
4005 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
4006 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
4007 {
4008 int mask;
4009 bool signed_sat;
4010 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
4011 &mask, &signed_sat))
4012 gcc_unreachable ();
4013
4014 operands[1] = GEN_INT (mask);
4015 if (signed_sat)
4016 return "ssat%?\t%0, %1, %4%S3";
4017 else
4018 return "usat%?\t%0, %1, %4%S3";
4019 }
4020 [(set_attr "predicable" "yes")
4021 (set_attr "shift" "3")
4022 (set_attr "type" "logic_shift_reg")])
4023 \f
4024 ;; Shift and rotation insns
4025
4026 (define_expand "ashldi3"
4027 [(set (match_operand:DI 0 "s_register_operand" "")
4028 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
4029 (match_operand:SI 2 "general_operand" "")))]
4030 "TARGET_32BIT"
4031 "
4032 if (TARGET_NEON)
4033 {
4034 /* Delay the decision whether to use NEON or core-regs until
4035 register allocation. */
4036 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4037 DONE;
4038 }
4039 else
4040 {
4041 /* Only the NEON case can handle in-memory shift counts. */
4042 if (!reg_or_int_operand (operands[2], SImode))
4043 operands[2] = force_reg (SImode, operands[2]);
4044 }
4045
4046 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4047 ; /* No special preparation statements; expand pattern as above. */
4048 else
4049 {
4050 rtx scratch1, scratch2;
4051
4052 /* Ideally we should use iwmmxt here if we could know that operands[1]
4053 ends up already living in an iwmmxt register. Otherwise it's
4054 cheaper to have the alternate code being generated than moving
4055 values to iwmmxt regs and back. */
4056
4057 /* Expand operation using core-registers.
4058 'FAIL' would achieve the same thing, but this is a bit smarter. */
4059 scratch1 = gen_reg_rtx (SImode);
4060 scratch2 = gen_reg_rtx (SImode);
4061 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4062 operands[2], scratch1, scratch2);
4063 DONE;
4064 }
4065 "
4066 )
4067
4068 (define_expand "ashlsi3"
4069 [(set (match_operand:SI 0 "s_register_operand" "")
4070 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4071 (match_operand:SI 2 "arm_rhs_operand" "")))]
4072 "TARGET_EITHER"
4073 "
4074 if (CONST_INT_P (operands[2])
4075 && (UINTVAL (operands[2])) > 31)
4076 {
4077 emit_insn (gen_movsi (operands[0], const0_rtx));
4078 DONE;
4079 }
4080 "
4081 )
4082
4083 (define_expand "ashrdi3"
4084 [(set (match_operand:DI 0 "s_register_operand" "")
4085 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4086 (match_operand:SI 2 "reg_or_int_operand" "")))]
4087 "TARGET_32BIT"
4088 "
4089 if (TARGET_NEON)
4090 {
4091 /* Delay the decision whether to use NEON or core-regs until
4092 register allocation. */
4093 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4094 DONE;
4095 }
4096
4097 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4098 ; /* No special preparation statements; expand pattern as above. */
4099 else
4100 {
4101 rtx scratch1, scratch2;
4102
4103 /* Ideally we should use iwmmxt here if we could know that operands[1]
4104 ends up already living in an iwmmxt register. Otherwise it's
4105 cheaper to have the alternate code being generated than moving
4106 values to iwmmxt regs and back. */
4107
4108 /* Expand operation using core-registers.
4109 'FAIL' would achieve the same thing, but this is a bit smarter. */
4110 scratch1 = gen_reg_rtx (SImode);
4111 scratch2 = gen_reg_rtx (SImode);
4112 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4113 operands[2], scratch1, scratch2);
4114 DONE;
4115 }
4116 "
4117 )
4118
4119 (define_expand "ashrsi3"
4120 [(set (match_operand:SI 0 "s_register_operand" "")
4121 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4122 (match_operand:SI 2 "arm_rhs_operand" "")))]
4123 "TARGET_EITHER"
4124 "
4125 if (CONST_INT_P (operands[2])
4126 && UINTVAL (operands[2]) > 31)
4127 operands[2] = GEN_INT (31);
4128 "
4129 )
4130
4131 (define_expand "lshrdi3"
4132 [(set (match_operand:DI 0 "s_register_operand" "")
4133 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4134 (match_operand:SI 2 "reg_or_int_operand" "")))]
4135 "TARGET_32BIT"
4136 "
4137 if (TARGET_NEON)
4138 {
4139 /* Delay the decision whether to use NEON or core-regs until
4140 register allocation. */
4141 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4142 DONE;
4143 }
4144
4145 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4146 ; /* No special preparation statements; expand pattern as above. */
4147 else
4148 {
4149 rtx scratch1, scratch2;
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_expand "lshrsi3"
4168 [(set (match_operand:SI 0 "s_register_operand" "")
4169 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4170 (match_operand:SI 2 "arm_rhs_operand" "")))]
4171 "TARGET_EITHER"
4172 "
4173 if (CONST_INT_P (operands[2])
4174 && (UINTVAL (operands[2])) > 31)
4175 {
4176 emit_insn (gen_movsi (operands[0], const0_rtx));
4177 DONE;
4178 }
4179 "
4180 )
4181
4182 (define_expand "rotlsi3"
4183 [(set (match_operand:SI 0 "s_register_operand" "")
4184 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4185 (match_operand:SI 2 "reg_or_int_operand" "")))]
4186 "TARGET_32BIT"
4187 "
4188 if (CONST_INT_P (operands[2]))
4189 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4190 else
4191 {
4192 rtx reg = gen_reg_rtx (SImode);
4193 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4194 operands[2] = reg;
4195 }
4196 "
4197 )
4198
4199 (define_expand "rotrsi3"
4200 [(set (match_operand:SI 0 "s_register_operand" "")
4201 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4202 (match_operand:SI 2 "arm_rhs_operand" "")))]
4203 "TARGET_EITHER"
4204 "
4205 if (TARGET_32BIT)
4206 {
4207 if (CONST_INT_P (operands[2])
4208 && UINTVAL (operands[2]) > 31)
4209 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4210 }
4211 else /* TARGET_THUMB1 */
4212 {
4213 if (CONST_INT_P (operands [2]))
4214 operands [2] = force_reg (SImode, operands[2]);
4215 }
4216 "
4217 )
4218
4219 (define_insn "*arm_shiftsi3"
4220 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4221 (match_operator:SI 3 "shift_operator"
4222 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4223 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4224 "TARGET_32BIT"
4225 "* return arm_output_shift(operands, 0);"
4226 [(set_attr "predicable" "yes")
4227 (set_attr "arch" "t2,t2,*,*")
4228 (set_attr "predicable_short_it" "yes,yes,no,no")
4229 (set_attr "length" "4")
4230 (set_attr "shift" "1")
4231 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4232 )
4233
4234 (define_insn "*shiftsi3_compare0"
4235 [(set (reg:CC_NOOV CC_REGNUM)
4236 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4237 [(match_operand:SI 1 "s_register_operand" "r,r")
4238 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4239 (const_int 0)))
4240 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4241 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4242 "TARGET_32BIT"
4243 "* return arm_output_shift(operands, 1);"
4244 [(set_attr "conds" "set")
4245 (set_attr "shift" "1")
4246 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4247 )
4248
4249 (define_insn "*shiftsi3_compare0_scratch"
4250 [(set (reg:CC_NOOV CC_REGNUM)
4251 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4252 [(match_operand:SI 1 "s_register_operand" "r,r")
4253 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4254 (const_int 0)))
4255 (clobber (match_scratch:SI 0 "=r,r"))]
4256 "TARGET_32BIT"
4257 "* return arm_output_shift(operands, 1);"
4258 [(set_attr "conds" "set")
4259 (set_attr "shift" "1")
4260 (set_attr "type" "shift_imm,shift_reg")]
4261 )
4262
4263 (define_insn "*not_shiftsi"
4264 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4265 (not:SI (match_operator:SI 3 "shift_operator"
4266 [(match_operand:SI 1 "s_register_operand" "r,r")
4267 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4268 "TARGET_32BIT"
4269 "mvn%?\\t%0, %1%S3"
4270 [(set_attr "predicable" "yes")
4271 (set_attr "shift" "1")
4272 (set_attr "arch" "32,a")
4273 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4274
4275 (define_insn "*not_shiftsi_compare0"
4276 [(set (reg:CC_NOOV CC_REGNUM)
4277 (compare:CC_NOOV
4278 (not:SI (match_operator:SI 3 "shift_operator"
4279 [(match_operand:SI 1 "s_register_operand" "r,r")
4280 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4281 (const_int 0)))
4282 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4283 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4284 "TARGET_32BIT"
4285 "mvns%?\\t%0, %1%S3"
4286 [(set_attr "conds" "set")
4287 (set_attr "shift" "1")
4288 (set_attr "arch" "32,a")
4289 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4290
4291 (define_insn "*not_shiftsi_compare0_scratch"
4292 [(set (reg:CC_NOOV CC_REGNUM)
4293 (compare:CC_NOOV
4294 (not:SI (match_operator:SI 3 "shift_operator"
4295 [(match_operand:SI 1 "s_register_operand" "r,r")
4296 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4297 (const_int 0)))
4298 (clobber (match_scratch:SI 0 "=r,r"))]
4299 "TARGET_32BIT"
4300 "mvns%?\\t%0, %1%S3"
4301 [(set_attr "conds" "set")
4302 (set_attr "shift" "1")
4303 (set_attr "arch" "32,a")
4304 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4305
4306 ;; We don't really have extzv, but defining this using shifts helps
4307 ;; to reduce register pressure later on.
4308
4309 (define_expand "extzv"
4310 [(set (match_operand 0 "s_register_operand" "")
4311 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4312 (match_operand 2 "const_int_operand" "")
4313 (match_operand 3 "const_int_operand" "")))]
4314 "TARGET_THUMB1 || arm_arch_thumb2"
4315 "
4316 {
4317 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4318 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4319
4320 if (arm_arch_thumb2)
4321 {
4322 HOST_WIDE_INT width = INTVAL (operands[2]);
4323 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4324
4325 if (unaligned_access && MEM_P (operands[1])
4326 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4327 {
4328 rtx base_addr;
4329
4330 if (BYTES_BIG_ENDIAN)
4331 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4332 - bitpos;
4333
4334 if (width == 32)
4335 {
4336 base_addr = adjust_address (operands[1], SImode,
4337 bitpos / BITS_PER_UNIT);
4338 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4339 }
4340 else
4341 {
4342 rtx dest = operands[0];
4343 rtx tmp = gen_reg_rtx (SImode);
4344
4345 /* We may get a paradoxical subreg here. Strip it off. */
4346 if (GET_CODE (dest) == SUBREG
4347 && GET_MODE (dest) == SImode
4348 && GET_MODE (SUBREG_REG (dest)) == HImode)
4349 dest = SUBREG_REG (dest);
4350
4351 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4352 FAIL;
4353
4354 base_addr = adjust_address (operands[1], HImode,
4355 bitpos / BITS_PER_UNIT);
4356 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4357 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4358 }
4359 DONE;
4360 }
4361 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4362 {
4363 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4364 operands[3]));
4365 DONE;
4366 }
4367 else
4368 FAIL;
4369 }
4370
4371 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4372 FAIL;
4373
4374 operands[3] = GEN_INT (rshift);
4375
4376 if (lshift == 0)
4377 {
4378 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4379 DONE;
4380 }
4381
4382 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4383 operands[3], gen_reg_rtx (SImode)));
4384 DONE;
4385 }"
4386 )
4387
4388 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4389
4390 (define_expand "extzv_t1"
4391 [(set (match_operand:SI 4 "s_register_operand" "")
4392 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4393 (match_operand:SI 2 "const_int_operand" "")))
4394 (set (match_operand:SI 0 "s_register_operand" "")
4395 (lshiftrt:SI (match_dup 4)
4396 (match_operand:SI 3 "const_int_operand" "")))]
4397 "TARGET_THUMB1"
4398 "")
4399
4400 (define_expand "extv"
4401 [(set (match_operand 0 "s_register_operand" "")
4402 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4403 (match_operand 2 "const_int_operand" "")
4404 (match_operand 3 "const_int_operand" "")))]
4405 "arm_arch_thumb2"
4406 {
4407 HOST_WIDE_INT width = INTVAL (operands[2]);
4408 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4409
4410 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4411 && (bitpos % BITS_PER_UNIT) == 0)
4412 {
4413 rtx base_addr;
4414
4415 if (BYTES_BIG_ENDIAN)
4416 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4417
4418 if (width == 32)
4419 {
4420 base_addr = adjust_address (operands[1], SImode,
4421 bitpos / BITS_PER_UNIT);
4422 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4423 }
4424 else
4425 {
4426 rtx dest = operands[0];
4427 rtx tmp = gen_reg_rtx (SImode);
4428
4429 /* We may get a paradoxical subreg here. Strip it off. */
4430 if (GET_CODE (dest) == SUBREG
4431 && GET_MODE (dest) == SImode
4432 && GET_MODE (SUBREG_REG (dest)) == HImode)
4433 dest = SUBREG_REG (dest);
4434
4435 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4436 FAIL;
4437
4438 base_addr = adjust_address (operands[1], HImode,
4439 bitpos / BITS_PER_UNIT);
4440 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4441 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4442 }
4443
4444 DONE;
4445 }
4446 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4447 FAIL;
4448 else if (GET_MODE (operands[0]) == SImode
4449 && GET_MODE (operands[1]) == SImode)
4450 {
4451 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4452 operands[3]));
4453 DONE;
4454 }
4455
4456 FAIL;
4457 })
4458
4459 ; Helper to expand register forms of extv with the proper modes.
4460
4461 (define_expand "extv_regsi"
4462 [(set (match_operand:SI 0 "s_register_operand" "")
4463 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4464 (match_operand 2 "const_int_operand" "")
4465 (match_operand 3 "const_int_operand" "")))]
4466 ""
4467 {
4468 })
4469
4470 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4471
4472 (define_insn "unaligned_loadsi"
4473 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4474 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4475 UNSPEC_UNALIGNED_LOAD))]
4476 "unaligned_access"
4477 "ldr%?\t%0, %1\t@ unaligned"
4478 [(set_attr "arch" "t2,any")
4479 (set_attr "length" "2,4")
4480 (set_attr "predicable" "yes")
4481 (set_attr "predicable_short_it" "yes,no")
4482 (set_attr "type" "load_4")])
4483
4484 (define_insn "unaligned_loadhis"
4485 [(set (match_operand:SI 0 "s_register_operand" "=r")
4486 (sign_extend:SI
4487 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
4488 UNSPEC_UNALIGNED_LOAD)))]
4489 "unaligned_access"
4490 "ldrsh%?\t%0, %1\t@ unaligned"
4491 [(set_attr "predicable" "yes")
4492 (set_attr "type" "load_byte")])
4493
4494 (define_insn "unaligned_loadhiu"
4495 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4496 (zero_extend:SI
4497 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4498 UNSPEC_UNALIGNED_LOAD)))]
4499 "unaligned_access"
4500 "ldrh%?\t%0, %1\t@ unaligned"
4501 [(set_attr "arch" "t2,any")
4502 (set_attr "length" "2,4")
4503 (set_attr "predicable" "yes")
4504 (set_attr "predicable_short_it" "yes,no")
4505 (set_attr "type" "load_byte")])
4506
4507 (define_insn "unaligned_storesi"
4508 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4509 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4510 UNSPEC_UNALIGNED_STORE))]
4511 "unaligned_access"
4512 "str%?\t%1, %0\t@ unaligned"
4513 [(set_attr "arch" "t2,any")
4514 (set_attr "length" "2,4")
4515 (set_attr "predicable" "yes")
4516 (set_attr "predicable_short_it" "yes,no")
4517 (set_attr "type" "store_4")])
4518
4519 (define_insn "unaligned_storehi"
4520 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4521 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4522 UNSPEC_UNALIGNED_STORE))]
4523 "unaligned_access"
4524 "strh%?\t%1, %0\t@ unaligned"
4525 [(set_attr "arch" "t2,any")
4526 (set_attr "length" "2,4")
4527 (set_attr "predicable" "yes")
4528 (set_attr "predicable_short_it" "yes,no")
4529 (set_attr "type" "store_4")])
4530
4531
4532 (define_insn "*extv_reg"
4533 [(set (match_operand:SI 0 "s_register_operand" "=r")
4534 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4535 (match_operand:SI 2 "const_int_operand" "n")
4536 (match_operand:SI 3 "const_int_operand" "n")))]
4537 "arm_arch_thumb2
4538 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4539 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4540 "sbfx%?\t%0, %1, %3, %2"
4541 [(set_attr "length" "4")
4542 (set_attr "predicable" "yes")
4543 (set_attr "type" "bfm")]
4544 )
4545
4546 (define_insn "extzv_t2"
4547 [(set (match_operand:SI 0 "s_register_operand" "=r")
4548 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4549 (match_operand:SI 2 "const_int_operand" "n")
4550 (match_operand:SI 3 "const_int_operand" "n")))]
4551 "arm_arch_thumb2
4552 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4553 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4554 "ubfx%?\t%0, %1, %3, %2"
4555 [(set_attr "length" "4")
4556 (set_attr "predicable" "yes")
4557 (set_attr "type" "bfm")]
4558 )
4559
4560
4561 ;; Division instructions
4562 (define_insn "divsi3"
4563 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4564 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4565 (match_operand:SI 2 "s_register_operand" "r,r")))]
4566 "TARGET_IDIV"
4567 "@
4568 sdiv%?\t%0, %1, %2
4569 sdiv\t%0, %1, %2"
4570 [(set_attr "arch" "32,v8mb")
4571 (set_attr "predicable" "yes")
4572 (set_attr "type" "sdiv")]
4573 )
4574
4575 (define_insn "udivsi3"
4576 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4577 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4578 (match_operand:SI 2 "s_register_operand" "r,r")))]
4579 "TARGET_IDIV"
4580 "@
4581 udiv%?\t%0, %1, %2
4582 udiv\t%0, %1, %2"
4583 [(set_attr "arch" "32,v8mb")
4584 (set_attr "predicable" "yes")
4585 (set_attr "type" "udiv")]
4586 )
4587
4588 \f
4589 ;; Unary arithmetic insns
4590
4591 (define_expand "negvsi3"
4592 [(match_operand:SI 0 "register_operand")
4593 (match_operand:SI 1 "register_operand")
4594 (match_operand 2 "")]
4595 "TARGET_32BIT"
4596 {
4597 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4598 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4599
4600 DONE;
4601 })
4602
4603 (define_expand "negvdi3"
4604 [(match_operand:DI 0 "register_operand")
4605 (match_operand:DI 1 "register_operand")
4606 (match_operand 2 "")]
4607 "TARGET_ARM"
4608 {
4609 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4610 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4611
4612 DONE;
4613 })
4614
4615
4616 (define_insn_and_split "negdi2_compare"
4617 [(set (reg:CC CC_REGNUM)
4618 (compare:CC
4619 (const_int 0)
4620 (match_operand:DI 1 "register_operand" "0,r")))
4621 (set (match_operand:DI 0 "register_operand" "=r,&r")
4622 (minus:DI (const_int 0) (match_dup 1)))]
4623 "TARGET_ARM"
4624 "#"
4625 "&& reload_completed"
4626 [(parallel [(set (reg:CC CC_REGNUM)
4627 (compare:CC (const_int 0) (match_dup 1)))
4628 (set (match_dup 0) (minus:SI (const_int 0)
4629 (match_dup 1)))])
4630 (parallel [(set (reg:CC CC_REGNUM)
4631 (compare:CC (const_int 0) (match_dup 3)))
4632 (set (match_dup 2)
4633 (minus:SI
4634 (minus:SI (const_int 0) (match_dup 3))
4635 (ltu:SI (reg:CC_C CC_REGNUM)
4636 (const_int 0))))])]
4637 {
4638 operands[2] = gen_highpart (SImode, operands[0]);
4639 operands[0] = gen_lowpart (SImode, operands[0]);
4640 operands[3] = gen_highpart (SImode, operands[1]);
4641 operands[1] = gen_lowpart (SImode, operands[1]);
4642 }
4643 [(set_attr "conds" "set")
4644 (set_attr "length" "8")
4645 (set_attr "type" "multiple")]
4646 )
4647
4648 (define_expand "negdi2"
4649 [(parallel
4650 [(set (match_operand:DI 0 "s_register_operand" "")
4651 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4652 (clobber (reg:CC CC_REGNUM))])]
4653 "TARGET_EITHER"
4654 {
4655 if (TARGET_NEON)
4656 {
4657 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4658 DONE;
4659 }
4660 }
4661 )
4662
4663 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4664 ;; The first alternative allows the common case of a *full* overlap.
4665 (define_insn_and_split "*negdi2_insn"
4666 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4667 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4668 (clobber (reg:CC CC_REGNUM))]
4669 "TARGET_32BIT"
4670 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4671 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4672 "&& reload_completed"
4673 [(parallel [(set (reg:CC CC_REGNUM)
4674 (compare:CC (const_int 0) (match_dup 1)))
4675 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4676 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4677 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4678 {
4679 operands[2] = gen_highpart (SImode, operands[0]);
4680 operands[0] = gen_lowpart (SImode, operands[0]);
4681 operands[3] = gen_highpart (SImode, operands[1]);
4682 operands[1] = gen_lowpart (SImode, operands[1]);
4683 }
4684 [(set_attr "conds" "clob")
4685 (set_attr "length" "8")
4686 (set_attr "type" "multiple")]
4687 )
4688
4689 (define_insn "*negsi2_carryin_compare"
4690 [(set (reg:CC CC_REGNUM)
4691 (compare:CC (const_int 0)
4692 (match_operand:SI 1 "s_register_operand" "r")))
4693 (set (match_operand:SI 0 "s_register_operand" "=r")
4694 (minus:SI (minus:SI (const_int 0)
4695 (match_dup 1))
4696 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4697 "TARGET_ARM"
4698 "rscs\\t%0, %1, #0"
4699 [(set_attr "conds" "set")
4700 (set_attr "type" "alus_imm")]
4701 )
4702
4703 (define_expand "negsi2"
4704 [(set (match_operand:SI 0 "s_register_operand" "")
4705 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4706 "TARGET_EITHER"
4707 ""
4708 )
4709
4710 (define_insn "*arm_negsi2"
4711 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4712 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4713 "TARGET_32BIT"
4714 "rsb%?\\t%0, %1, #0"
4715 [(set_attr "predicable" "yes")
4716 (set_attr "predicable_short_it" "yes,no")
4717 (set_attr "arch" "t2,*")
4718 (set_attr "length" "4")
4719 (set_attr "type" "alu_sreg")]
4720 )
4721
4722 (define_expand "negsf2"
4723 [(set (match_operand:SF 0 "s_register_operand" "")
4724 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4725 "TARGET_32BIT && TARGET_HARD_FLOAT"
4726 ""
4727 )
4728
4729 (define_expand "negdf2"
4730 [(set (match_operand:DF 0 "s_register_operand" "")
4731 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4732 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4733 "")
4734
4735 (define_insn_and_split "*zextendsidi_negsi"
4736 [(set (match_operand:DI 0 "s_register_operand" "=r")
4737 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4738 "TARGET_32BIT"
4739 "#"
4740 ""
4741 [(set (match_dup 2)
4742 (neg:SI (match_dup 1)))
4743 (set (match_dup 3)
4744 (const_int 0))]
4745 {
4746 operands[2] = gen_lowpart (SImode, operands[0]);
4747 operands[3] = gen_highpart (SImode, operands[0]);
4748 }
4749 [(set_attr "length" "8")
4750 (set_attr "type" "multiple")]
4751 )
4752
4753 ;; Negate an extended 32-bit value.
4754 (define_insn_and_split "*negdi_extendsidi"
4755 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4756 (neg:DI (sign_extend:DI
4757 (match_operand:SI 1 "s_register_operand" "l,r"))))
4758 (clobber (reg:CC CC_REGNUM))]
4759 "TARGET_32BIT"
4760 "#"
4761 "&& reload_completed"
4762 [(const_int 0)]
4763 {
4764 rtx low = gen_lowpart (SImode, operands[0]);
4765 rtx high = gen_highpart (SImode, operands[0]);
4766
4767 if (reg_overlap_mentioned_p (low, operands[1]))
4768 {
4769 /* Input overlaps the low word of the output. Use:
4770 asr Rhi, Rin, #31
4771 rsbs Rlo, Rin, #0
4772 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4773 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4774
4775 emit_insn (gen_rtx_SET (high,
4776 gen_rtx_ASHIFTRT (SImode, operands[1],
4777 GEN_INT (31))));
4778
4779 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4780 if (TARGET_ARM)
4781 emit_insn (gen_rtx_SET (high,
4782 gen_rtx_MINUS (SImode,
4783 gen_rtx_MINUS (SImode,
4784 const0_rtx,
4785 high),
4786 gen_rtx_LTU (SImode,
4787 cc_reg,
4788 const0_rtx))));
4789 else
4790 {
4791 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4792 emit_insn (gen_rtx_SET (high,
4793 gen_rtx_MINUS (SImode,
4794 gen_rtx_MINUS (SImode,
4795 high,
4796 two_x),
4797 gen_rtx_LTU (SImode,
4798 cc_reg,
4799 const0_rtx))));
4800 }
4801 }
4802 else
4803 {
4804 /* No overlap, or overlap on high word. Use:
4805 rsb Rlo, Rin, #0
4806 bic Rhi, Rlo, Rin
4807 asr Rhi, Rhi, #31
4808 Flags not needed for this sequence. */
4809 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4810 emit_insn (gen_rtx_SET (high,
4811 gen_rtx_AND (SImode,
4812 gen_rtx_NOT (SImode, operands[1]),
4813 low)));
4814 emit_insn (gen_rtx_SET (high,
4815 gen_rtx_ASHIFTRT (SImode, high,
4816 GEN_INT (31))));
4817 }
4818 DONE;
4819 }
4820 [(set_attr "length" "12")
4821 (set_attr "arch" "t2,*")
4822 (set_attr "type" "multiple")]
4823 )
4824
4825 (define_insn_and_split "*negdi_zero_extendsidi"
4826 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4827 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4828 (clobber (reg:CC CC_REGNUM))]
4829 "TARGET_32BIT"
4830 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4831 ;; Don't care what register is input to sbc,
4832 ;; since we just need to propagate the carry.
4833 "&& reload_completed"
4834 [(parallel [(set (reg:CC CC_REGNUM)
4835 (compare:CC (const_int 0) (match_dup 1)))
4836 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4837 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4838 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4839 {
4840 operands[2] = gen_highpart (SImode, operands[0]);
4841 operands[0] = gen_lowpart (SImode, operands[0]);
4842 }
4843 [(set_attr "conds" "clob")
4844 (set_attr "length" "8")
4845 (set_attr "type" "multiple")] ;; length in thumb is 4
4846 )
4847
4848 ;; abssi2 doesn't really clobber the condition codes if a different register
4849 ;; is being set. To keep things simple, assume during rtl manipulations that
4850 ;; it does, but tell the final scan operator the truth. Similarly for
4851 ;; (neg (abs...))
4852
4853 (define_expand "abssi2"
4854 [(parallel
4855 [(set (match_operand:SI 0 "s_register_operand" "")
4856 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4857 (clobber (match_dup 2))])]
4858 "TARGET_EITHER"
4859 "
4860 if (TARGET_THUMB1)
4861 operands[2] = gen_rtx_SCRATCH (SImode);
4862 else
4863 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4864 ")
4865
4866 (define_insn_and_split "*arm_abssi2"
4867 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4868 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4869 (clobber (reg:CC CC_REGNUM))]
4870 "TARGET_ARM"
4871 "#"
4872 "&& reload_completed"
4873 [(const_int 0)]
4874 {
4875 /* if (which_alternative == 0) */
4876 if (REGNO(operands[0]) == REGNO(operands[1]))
4877 {
4878 /* Emit the pattern:
4879 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4880 [(set (reg:CC CC_REGNUM)
4881 (compare:CC (match_dup 0) (const_int 0)))
4882 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4883 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4884 */
4885 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4886 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4887 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4888 (gen_rtx_LT (SImode,
4889 gen_rtx_REG (CCmode, CC_REGNUM),
4890 const0_rtx)),
4891 (gen_rtx_SET (operands[0],
4892 (gen_rtx_MINUS (SImode,
4893 const0_rtx,
4894 operands[1]))))));
4895 DONE;
4896 }
4897 else
4898 {
4899 /* Emit the pattern:
4900 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4901 [(set (match_dup 0)
4902 (xor:SI (match_dup 1)
4903 (ashiftrt:SI (match_dup 1) (const_int 31))))
4904 (set (match_dup 0)
4905 (minus:SI (match_dup 0)
4906 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4907 */
4908 emit_insn (gen_rtx_SET (operands[0],
4909 gen_rtx_XOR (SImode,
4910 gen_rtx_ASHIFTRT (SImode,
4911 operands[1],
4912 GEN_INT (31)),
4913 operands[1])));
4914 emit_insn (gen_rtx_SET (operands[0],
4915 gen_rtx_MINUS (SImode,
4916 operands[0],
4917 gen_rtx_ASHIFTRT (SImode,
4918 operands[1],
4919 GEN_INT (31)))));
4920 DONE;
4921 }
4922 }
4923 [(set_attr "conds" "clob,*")
4924 (set_attr "shift" "1")
4925 (set_attr "predicable" "no, yes")
4926 (set_attr "length" "8")
4927 (set_attr "type" "multiple")]
4928 )
4929
4930 (define_insn_and_split "*arm_neg_abssi2"
4931 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4932 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4933 (clobber (reg:CC CC_REGNUM))]
4934 "TARGET_ARM"
4935 "#"
4936 "&& reload_completed"
4937 [(const_int 0)]
4938 {
4939 /* if (which_alternative == 0) */
4940 if (REGNO (operands[0]) == REGNO (operands[1]))
4941 {
4942 /* Emit the pattern:
4943 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4944 */
4945 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4946 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4947 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4948 gen_rtx_GT (SImode,
4949 gen_rtx_REG (CCmode, CC_REGNUM),
4950 const0_rtx),
4951 gen_rtx_SET (operands[0],
4952 (gen_rtx_MINUS (SImode,
4953 const0_rtx,
4954 operands[1])))));
4955 }
4956 else
4957 {
4958 /* Emit the pattern:
4959 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4960 */
4961 emit_insn (gen_rtx_SET (operands[0],
4962 gen_rtx_XOR (SImode,
4963 gen_rtx_ASHIFTRT (SImode,
4964 operands[1],
4965 GEN_INT (31)),
4966 operands[1])));
4967 emit_insn (gen_rtx_SET (operands[0],
4968 gen_rtx_MINUS (SImode,
4969 gen_rtx_ASHIFTRT (SImode,
4970 operands[1],
4971 GEN_INT (31)),
4972 operands[0])));
4973 }
4974 DONE;
4975 }
4976 [(set_attr "conds" "clob,*")
4977 (set_attr "shift" "1")
4978 (set_attr "predicable" "no, yes")
4979 (set_attr "length" "8")
4980 (set_attr "type" "multiple")]
4981 )
4982
4983 (define_expand "abssf2"
4984 [(set (match_operand:SF 0 "s_register_operand" "")
4985 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4986 "TARGET_32BIT && TARGET_HARD_FLOAT"
4987 "")
4988
4989 (define_expand "absdf2"
4990 [(set (match_operand:DF 0 "s_register_operand" "")
4991 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
4992 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4993 "")
4994
4995 (define_expand "sqrtsf2"
4996 [(set (match_operand:SF 0 "s_register_operand" "")
4997 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
4998 "TARGET_32BIT && TARGET_HARD_FLOAT"
4999 "")
5000
5001 (define_expand "sqrtdf2"
5002 [(set (match_operand:DF 0 "s_register_operand" "")
5003 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5004 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5005 "")
5006
5007 (define_expand "one_cmpldi2"
5008 [(set (match_operand:DI 0 "s_register_operand" "")
5009 (not:DI (match_operand:DI 1 "s_register_operand" "")))]
5010 "TARGET_32BIT"
5011 "
5012 if (!TARGET_NEON && !TARGET_IWMMXT)
5013 {
5014 rtx low = simplify_gen_unary (NOT, SImode,
5015 gen_lowpart (SImode, operands[1]),
5016 SImode);
5017 rtx high = simplify_gen_unary (NOT, SImode,
5018 gen_highpart_mode (SImode, DImode,
5019 operands[1]),
5020 SImode);
5021
5022 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5023 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5024
5025 DONE;
5026 }
5027 /* Otherwise expand pattern as above. */
5028 "
5029 )
5030
5031 (define_insn_and_split "*one_cmpldi2_insn"
5032 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5033 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5034 "TARGET_32BIT"
5035 "@
5036 vmvn\t%P0, %P1
5037 #
5038 #
5039 vmvn\t%P0, %P1"
5040 "TARGET_32BIT && reload_completed
5041 && arm_general_register_operand (operands[0], DImode)"
5042 [(set (match_dup 0) (not:SI (match_dup 1)))
5043 (set (match_dup 2) (not:SI (match_dup 3)))]
5044 "
5045 {
5046 operands[2] = gen_highpart (SImode, operands[0]);
5047 operands[0] = gen_lowpart (SImode, operands[0]);
5048 operands[3] = gen_highpart (SImode, operands[1]);
5049 operands[1] = gen_lowpart (SImode, operands[1]);
5050 }"
5051 [(set_attr "length" "*,8,8,*")
5052 (set_attr "predicable" "no,yes,yes,no")
5053 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5054 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5055 )
5056
5057 (define_expand "one_cmplsi2"
5058 [(set (match_operand:SI 0 "s_register_operand" "")
5059 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5060 "TARGET_EITHER"
5061 ""
5062 )
5063
5064 (define_insn "*arm_one_cmplsi2"
5065 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5066 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5067 "TARGET_32BIT"
5068 "mvn%?\\t%0, %1"
5069 [(set_attr "predicable" "yes")
5070 (set_attr "predicable_short_it" "yes,no")
5071 (set_attr "arch" "t2,*")
5072 (set_attr "length" "4")
5073 (set_attr "type" "mvn_reg")]
5074 )
5075
5076 (define_insn "*notsi_compare0"
5077 [(set (reg:CC_NOOV CC_REGNUM)
5078 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5079 (const_int 0)))
5080 (set (match_operand:SI 0 "s_register_operand" "=r")
5081 (not:SI (match_dup 1)))]
5082 "TARGET_32BIT"
5083 "mvns%?\\t%0, %1"
5084 [(set_attr "conds" "set")
5085 (set_attr "type" "mvn_reg")]
5086 )
5087
5088 (define_insn "*notsi_compare0_scratch"
5089 [(set (reg:CC_NOOV CC_REGNUM)
5090 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5091 (const_int 0)))
5092 (clobber (match_scratch:SI 0 "=r"))]
5093 "TARGET_32BIT"
5094 "mvns%?\\t%0, %1"
5095 [(set_attr "conds" "set")
5096 (set_attr "type" "mvn_reg")]
5097 )
5098 \f
5099 ;; Fixed <--> Floating conversion insns
5100
5101 (define_expand "floatsihf2"
5102 [(set (match_operand:HF 0 "general_operand" "")
5103 (float:HF (match_operand:SI 1 "general_operand" "")))]
5104 "TARGET_EITHER"
5105 "
5106 {
5107 rtx op1 = gen_reg_rtx (SFmode);
5108 expand_float (op1, operands[1], 0);
5109 op1 = convert_to_mode (HFmode, op1, 0);
5110 emit_move_insn (operands[0], op1);
5111 DONE;
5112 }"
5113 )
5114
5115 (define_expand "floatdihf2"
5116 [(set (match_operand:HF 0 "general_operand" "")
5117 (float:HF (match_operand:DI 1 "general_operand" "")))]
5118 "TARGET_EITHER"
5119 "
5120 {
5121 rtx op1 = gen_reg_rtx (SFmode);
5122 expand_float (op1, operands[1], 0);
5123 op1 = convert_to_mode (HFmode, op1, 0);
5124 emit_move_insn (operands[0], op1);
5125 DONE;
5126 }"
5127 )
5128
5129 (define_expand "floatsisf2"
5130 [(set (match_operand:SF 0 "s_register_operand" "")
5131 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5132 "TARGET_32BIT && TARGET_HARD_FLOAT"
5133 "
5134 ")
5135
5136 (define_expand "floatsidf2"
5137 [(set (match_operand:DF 0 "s_register_operand" "")
5138 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5139 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5140 "
5141 ")
5142
5143 (define_expand "fix_trunchfsi2"
5144 [(set (match_operand:SI 0 "general_operand" "")
5145 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5146 "TARGET_EITHER"
5147 "
5148 {
5149 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5150 expand_fix (operands[0], op1, 0);
5151 DONE;
5152 }"
5153 )
5154
5155 (define_expand "fix_trunchfdi2"
5156 [(set (match_operand:DI 0 "general_operand" "")
5157 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5158 "TARGET_EITHER"
5159 "
5160 {
5161 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5162 expand_fix (operands[0], op1, 0);
5163 DONE;
5164 }"
5165 )
5166
5167 (define_expand "fix_truncsfsi2"
5168 [(set (match_operand:SI 0 "s_register_operand" "")
5169 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5170 "TARGET_32BIT && TARGET_HARD_FLOAT"
5171 "
5172 ")
5173
5174 (define_expand "fix_truncdfsi2"
5175 [(set (match_operand:SI 0 "s_register_operand" "")
5176 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5177 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5178 "
5179 ")
5180
5181 ;; Truncation insns
5182
5183 (define_expand "truncdfsf2"
5184 [(set (match_operand:SF 0 "s_register_operand" "")
5185 (float_truncate:SF
5186 (match_operand:DF 1 "s_register_operand" "")))]
5187 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5188 ""
5189 )
5190
5191 ;; DFmode to HFmode conversions on targets without a single-step hardware
5192 ;; instruction for it would have to go through SFmode. This is dangerous
5193 ;; as it introduces double rounding.
5194 ;;
5195 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5196 ;; a single-step instruction.
5197
5198 (define_expand "truncdfhf2"
5199 [(set (match_operand:HF 0 "s_register_operand" "")
5200 (float_truncate:HF
5201 (match_operand:DF 1 "s_register_operand" "")))]
5202 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5203 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5204 {
5205 /* We don't have a direct instruction for this, so we must be in
5206 an unsafe math mode, and going via SFmode. */
5207
5208 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5209 {
5210 rtx op1;
5211 op1 = convert_to_mode (SFmode, operands[1], 0);
5212 op1 = convert_to_mode (HFmode, op1, 0);
5213 emit_move_insn (operands[0], op1);
5214 DONE;
5215 }
5216 /* Otherwise, we will pick this up as a single instruction with
5217 no intermediary rounding. */
5218 }
5219 )
5220 \f
5221 ;; Zero and sign extension instructions.
5222
5223 (define_insn "zero_extend<mode>di2"
5224 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5225 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5226 "<qhs_zextenddi_cstr>")))]
5227 "TARGET_32BIT <qhs_zextenddi_cond>"
5228 "#"
5229 [(set_attr "length" "8,4,8,8")
5230 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5231 (set_attr "ce_count" "2")
5232 (set_attr "predicable" "yes")
5233 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5234 )
5235
5236 (define_insn "extend<mode>di2"
5237 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5238 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5239 "<qhs_extenddi_cstr>")))]
5240 "TARGET_32BIT <qhs_sextenddi_cond>"
5241 "#"
5242 [(set_attr "length" "8,4,8,8,8")
5243 (set_attr "ce_count" "2")
5244 (set_attr "shift" "1")
5245 (set_attr "predicable" "yes")
5246 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5247 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5248 )
5249
5250 ;; Splits for all extensions to DImode
5251 (define_split
5252 [(set (match_operand:DI 0 "s_register_operand" "")
5253 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5254 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5255 [(set (match_dup 0) (match_dup 1))]
5256 {
5257 rtx lo_part = gen_lowpart (SImode, operands[0]);
5258 machine_mode src_mode = GET_MODE (operands[1]);
5259
5260 if (REG_P (operands[0])
5261 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5262 emit_clobber (operands[0]);
5263 if (!REG_P (lo_part) || src_mode != SImode
5264 || !rtx_equal_p (lo_part, operands[1]))
5265 {
5266 if (src_mode == SImode)
5267 emit_move_insn (lo_part, operands[1]);
5268 else
5269 emit_insn (gen_rtx_SET (lo_part,
5270 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5271 operands[1] = lo_part;
5272 }
5273 operands[0] = gen_highpart (SImode, operands[0]);
5274 operands[1] = const0_rtx;
5275 })
5276
5277 (define_split
5278 [(set (match_operand:DI 0 "s_register_operand" "")
5279 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5280 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5281 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5282 {
5283 rtx lo_part = gen_lowpart (SImode, operands[0]);
5284 machine_mode src_mode = GET_MODE (operands[1]);
5285
5286 if (REG_P (operands[0])
5287 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5288 emit_clobber (operands[0]);
5289
5290 if (!REG_P (lo_part) || src_mode != SImode
5291 || !rtx_equal_p (lo_part, operands[1]))
5292 {
5293 if (src_mode == SImode)
5294 emit_move_insn (lo_part, operands[1]);
5295 else
5296 emit_insn (gen_rtx_SET (lo_part,
5297 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5298 operands[1] = lo_part;
5299 }
5300 operands[0] = gen_highpart (SImode, operands[0]);
5301 })
5302
5303 (define_expand "zero_extendhisi2"
5304 [(set (match_operand:SI 0 "s_register_operand" "")
5305 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5306 "TARGET_EITHER"
5307 {
5308 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5309 {
5310 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5311 DONE;
5312 }
5313 if (!arm_arch6 && !MEM_P (operands[1]))
5314 {
5315 rtx t = gen_lowpart (SImode, operands[1]);
5316 rtx tmp = gen_reg_rtx (SImode);
5317 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5318 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5319 DONE;
5320 }
5321 })
5322
5323 (define_split
5324 [(set (match_operand:SI 0 "s_register_operand" "")
5325 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5326 "!TARGET_THUMB2 && !arm_arch6"
5327 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5328 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5329 {
5330 operands[2] = gen_lowpart (SImode, operands[1]);
5331 })
5332
5333 (define_insn "*arm_zero_extendhisi2"
5334 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5335 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5336 "TARGET_ARM && arm_arch4 && !arm_arch6"
5337 "@
5338 #
5339 ldrh%?\\t%0, %1"
5340 [(set_attr "type" "alu_shift_reg,load_byte")
5341 (set_attr "predicable" "yes")]
5342 )
5343
5344 (define_insn "*arm_zero_extendhisi2_v6"
5345 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5346 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5347 "TARGET_ARM && arm_arch6"
5348 "@
5349 uxth%?\\t%0, %1
5350 ldrh%?\\t%0, %1"
5351 [(set_attr "predicable" "yes")
5352 (set_attr "type" "extend,load_byte")]
5353 )
5354
5355 (define_insn "*arm_zero_extendhisi2addsi"
5356 [(set (match_operand:SI 0 "s_register_operand" "=r")
5357 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5358 (match_operand:SI 2 "s_register_operand" "r")))]
5359 "TARGET_INT_SIMD"
5360 "uxtah%?\\t%0, %2, %1"
5361 [(set_attr "type" "alu_shift_reg")
5362 (set_attr "predicable" "yes")]
5363 )
5364
5365 (define_expand "zero_extendqisi2"
5366 [(set (match_operand:SI 0 "s_register_operand" "")
5367 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5368 "TARGET_EITHER"
5369 {
5370 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5371 {
5372 emit_insn (gen_andsi3 (operands[0],
5373 gen_lowpart (SImode, operands[1]),
5374 GEN_INT (255)));
5375 DONE;
5376 }
5377 if (!arm_arch6 && !MEM_P (operands[1]))
5378 {
5379 rtx t = gen_lowpart (SImode, operands[1]);
5380 rtx tmp = gen_reg_rtx (SImode);
5381 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5382 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5383 DONE;
5384 }
5385 })
5386
5387 (define_split
5388 [(set (match_operand:SI 0 "s_register_operand" "")
5389 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5390 "!arm_arch6"
5391 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5392 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5393 {
5394 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5395 if (TARGET_ARM)
5396 {
5397 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5398 DONE;
5399 }
5400 })
5401
5402 (define_insn "*arm_zero_extendqisi2"
5403 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5404 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5405 "TARGET_ARM && !arm_arch6"
5406 "@
5407 #
5408 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5409 [(set_attr "length" "8,4")
5410 (set_attr "type" "alu_shift_reg,load_byte")
5411 (set_attr "predicable" "yes")]
5412 )
5413
5414 (define_insn "*arm_zero_extendqisi2_v6"
5415 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5416 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5417 "TARGET_ARM && arm_arch6"
5418 "@
5419 uxtb%?\\t%0, %1
5420 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5421 [(set_attr "type" "extend,load_byte")
5422 (set_attr "predicable" "yes")]
5423 )
5424
5425 (define_insn "*arm_zero_extendqisi2addsi"
5426 [(set (match_operand:SI 0 "s_register_operand" "=r")
5427 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5428 (match_operand:SI 2 "s_register_operand" "r")))]
5429 "TARGET_INT_SIMD"
5430 "uxtab%?\\t%0, %2, %1"
5431 [(set_attr "predicable" "yes")
5432 (set_attr "type" "alu_shift_reg")]
5433 )
5434
5435 (define_split
5436 [(set (match_operand:SI 0 "s_register_operand" "")
5437 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5438 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5439 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5440 [(set (match_dup 2) (match_dup 1))
5441 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5442 ""
5443 )
5444
5445 (define_split
5446 [(set (match_operand:SI 0 "s_register_operand" "")
5447 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5448 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5449 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5450 [(set (match_dup 2) (match_dup 1))
5451 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5452 ""
5453 )
5454
5455
5456 (define_split
5457 [(set (match_operand:SI 0 "s_register_operand" "")
5458 (IOR_XOR:SI (and:SI (ashift:SI
5459 (match_operand:SI 1 "s_register_operand" "")
5460 (match_operand:SI 2 "const_int_operand" ""))
5461 (match_operand:SI 3 "const_int_operand" ""))
5462 (zero_extend:SI
5463 (match_operator 5 "subreg_lowpart_operator"
5464 [(match_operand:SI 4 "s_register_operand" "")]))))]
5465 "TARGET_32BIT
5466 && (UINTVAL (operands[3])
5467 == (GET_MODE_MASK (GET_MODE (operands[5]))
5468 & (GET_MODE_MASK (GET_MODE (operands[5]))
5469 << (INTVAL (operands[2])))))"
5470 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5471 (match_dup 4)))
5472 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5473 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5474 )
5475
5476 (define_insn "*compareqi_eq0"
5477 [(set (reg:CC_Z CC_REGNUM)
5478 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5479 (const_int 0)))]
5480 "TARGET_32BIT"
5481 "tst%?\\t%0, #255"
5482 [(set_attr "conds" "set")
5483 (set_attr "predicable" "yes")
5484 (set_attr "type" "logic_imm")]
5485 )
5486
5487 (define_expand "extendhisi2"
5488 [(set (match_operand:SI 0 "s_register_operand" "")
5489 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5490 "TARGET_EITHER"
5491 {
5492 if (TARGET_THUMB1)
5493 {
5494 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5495 DONE;
5496 }
5497 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5498 {
5499 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5500 DONE;
5501 }
5502
5503 if (!arm_arch6 && !MEM_P (operands[1]))
5504 {
5505 rtx t = gen_lowpart (SImode, operands[1]);
5506 rtx tmp = gen_reg_rtx (SImode);
5507 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5508 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5509 DONE;
5510 }
5511 })
5512
5513 (define_split
5514 [(parallel
5515 [(set (match_operand:SI 0 "register_operand" "")
5516 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5517 (clobber (match_scratch:SI 2 ""))])]
5518 "!arm_arch6"
5519 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5520 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5521 {
5522 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5523 })
5524
5525 ;; This pattern will only be used when ldsh is not available
5526 (define_expand "extendhisi2_mem"
5527 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5528 (set (match_dup 3)
5529 (zero_extend:SI (match_dup 7)))
5530 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5531 (set (match_operand:SI 0 "" "")
5532 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5533 "TARGET_ARM"
5534 "
5535 {
5536 rtx mem1, mem2;
5537 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5538
5539 mem1 = change_address (operands[1], QImode, addr);
5540 mem2 = change_address (operands[1], QImode,
5541 plus_constant (Pmode, addr, 1));
5542 operands[0] = gen_lowpart (SImode, operands[0]);
5543 operands[1] = mem1;
5544 operands[2] = gen_reg_rtx (SImode);
5545 operands[3] = gen_reg_rtx (SImode);
5546 operands[6] = gen_reg_rtx (SImode);
5547 operands[7] = mem2;
5548
5549 if (BYTES_BIG_ENDIAN)
5550 {
5551 operands[4] = operands[2];
5552 operands[5] = operands[3];
5553 }
5554 else
5555 {
5556 operands[4] = operands[3];
5557 operands[5] = operands[2];
5558 }
5559 }"
5560 )
5561
5562 (define_split
5563 [(set (match_operand:SI 0 "register_operand" "")
5564 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5565 "!arm_arch6"
5566 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5567 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5568 {
5569 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5570 })
5571
5572 (define_insn "*arm_extendhisi2"
5573 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5574 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5575 "TARGET_ARM && arm_arch4 && !arm_arch6"
5576 "@
5577 #
5578 ldrsh%?\\t%0, %1"
5579 [(set_attr "length" "8,4")
5580 (set_attr "type" "alu_shift_reg,load_byte")
5581 (set_attr "predicable" "yes")]
5582 )
5583
5584 ;; ??? Check Thumb-2 pool range
5585 (define_insn "*arm_extendhisi2_v6"
5586 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5587 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5588 "TARGET_32BIT && arm_arch6"
5589 "@
5590 sxth%?\\t%0, %1
5591 ldrsh%?\\t%0, %1"
5592 [(set_attr "type" "extend,load_byte")
5593 (set_attr "predicable" "yes")]
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 )
5699
5700 (define_expand "extendsfdf2"
5701 [(set (match_operand:DF 0 "s_register_operand" "")
5702 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5703 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5704 ""
5705 )
5706
5707 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5708 ;; must go through SFmode.
5709 ;;
5710 ;; This is always safe for an extend.
5711
5712 (define_expand "extendhfdf2"
5713 [(set (match_operand:DF 0 "s_register_operand" "")
5714 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5715 "TARGET_EITHER"
5716 {
5717 /* We don't have a direct instruction for this, so go via SFmode. */
5718 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5719 {
5720 rtx op1;
5721 op1 = convert_to_mode (SFmode, operands[1], 0);
5722 op1 = convert_to_mode (DFmode, op1, 0);
5723 emit_insn (gen_movdf (operands[0], op1));
5724 DONE;
5725 }
5726 /* Otherwise, we're done producing RTL and will pick up the correct
5727 pattern to do this with one rounding-step in a single instruction. */
5728 }
5729 )
5730 \f
5731 ;; Move insns (including loads and stores)
5732
5733 ;; XXX Just some ideas about movti.
5734 ;; I don't think these are a good idea on the arm, there just aren't enough
5735 ;; registers
5736 ;;(define_expand "loadti"
5737 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5738 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5739 ;; "" "")
5740
5741 ;;(define_expand "storeti"
5742 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5743 ;; (match_operand:TI 1 "s_register_operand" ""))]
5744 ;; "" "")
5745
5746 ;;(define_expand "movti"
5747 ;; [(set (match_operand:TI 0 "general_operand" "")
5748 ;; (match_operand:TI 1 "general_operand" ""))]
5749 ;; ""
5750 ;; "
5751 ;;{
5752 ;; rtx insn;
5753 ;;
5754 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5755 ;; operands[1] = copy_to_reg (operands[1]);
5756 ;; if (MEM_P (operands[0]))
5757 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5758 ;; else if (MEM_P (operands[1]))
5759 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5760 ;; else
5761 ;; FAIL;
5762 ;;
5763 ;; emit_insn (insn);
5764 ;; DONE;
5765 ;;}")
5766
5767 ;; Recognize garbage generated above.
5768
5769 ;;(define_insn ""
5770 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5771 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5772 ;; ""
5773 ;; "*
5774 ;; {
5775 ;; register mem = (which_alternative < 3);
5776 ;; register const char *template;
5777 ;;
5778 ;; operands[mem] = XEXP (operands[mem], 0);
5779 ;; switch (which_alternative)
5780 ;; {
5781 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5782 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5783 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5784 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5785 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5786 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5787 ;; }
5788 ;; output_asm_insn (template, operands);
5789 ;; return \"\";
5790 ;; }")
5791
5792 (define_expand "movdi"
5793 [(set (match_operand:DI 0 "general_operand" "")
5794 (match_operand:DI 1 "general_operand" ""))]
5795 "TARGET_EITHER"
5796 "
5797 if (can_create_pseudo_p ())
5798 {
5799 if (!REG_P (operands[0]))
5800 operands[1] = force_reg (DImode, operands[1]);
5801 }
5802 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5803 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5804 {
5805 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5806 when expanding function calls. */
5807 gcc_assert (can_create_pseudo_p ());
5808 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5809 {
5810 /* Perform load into legal reg pair first, then move. */
5811 rtx reg = gen_reg_rtx (DImode);
5812 emit_insn (gen_movdi (reg, operands[1]));
5813 operands[1] = reg;
5814 }
5815 emit_move_insn (gen_lowpart (SImode, operands[0]),
5816 gen_lowpart (SImode, operands[1]));
5817 emit_move_insn (gen_highpart (SImode, operands[0]),
5818 gen_highpart (SImode, operands[1]));
5819 DONE;
5820 }
5821 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5822 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5823 {
5824 /* Avoid STRD's from an odd-numbered register pair in ARM state
5825 when expanding function prologue. */
5826 gcc_assert (can_create_pseudo_p ());
5827 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5828 ? gen_reg_rtx (DImode)
5829 : operands[0];
5830 emit_move_insn (gen_lowpart (SImode, split_dest),
5831 gen_lowpart (SImode, operands[1]));
5832 emit_move_insn (gen_highpart (SImode, split_dest),
5833 gen_highpart (SImode, operands[1]));
5834 if (split_dest != operands[0])
5835 emit_insn (gen_movdi (operands[0], split_dest));
5836 DONE;
5837 }
5838 "
5839 )
5840
5841 (define_insn "*arm_movdi"
5842 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
5843 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
5844 "TARGET_32BIT
5845 && !(TARGET_HARD_FLOAT)
5846 && !TARGET_IWMMXT
5847 && ( register_operand (operands[0], DImode)
5848 || register_operand (operands[1], DImode))"
5849 "*
5850 switch (which_alternative)
5851 {
5852 case 0:
5853 case 1:
5854 case 2:
5855 return \"#\";
5856 case 3:
5857 /* Cannot load it directly, split to load it via MOV / MOVT. */
5858 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
5859 return \"#\";
5860 /* Fall through. */
5861 default:
5862 return output_move_double (operands, true, NULL);
5863 }
5864 "
5865 [(set_attr "length" "8,12,16,8,8")
5866 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5867 (set_attr "arm_pool_range" "*,*,*,1020,*")
5868 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5869 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5870 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5871 )
5872
5873 (define_split
5874 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5875 (match_operand:ANY64 1 "immediate_operand" ""))]
5876 "TARGET_32BIT
5877 && reload_completed
5878 && (arm_disable_literal_pool
5879 || (arm_const_double_inline_cost (operands[1])
5880 <= arm_max_const_double_inline_cost ()))"
5881 [(const_int 0)]
5882 "
5883 arm_split_constant (SET, SImode, curr_insn,
5884 INTVAL (gen_lowpart (SImode, operands[1])),
5885 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5886 arm_split_constant (SET, SImode, curr_insn,
5887 INTVAL (gen_highpart_mode (SImode,
5888 GET_MODE (operands[0]),
5889 operands[1])),
5890 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5891 DONE;
5892 "
5893 )
5894
5895 ; If optimizing for size, or if we have load delay slots, then
5896 ; we want to split the constant into two separate operations.
5897 ; In both cases this may split a trivial part into a single data op
5898 ; leaving a single complex constant to load. We can also get longer
5899 ; offsets in a LDR which means we get better chances of sharing the pool
5900 ; entries. Finally, we can normally do a better job of scheduling
5901 ; LDR instructions than we can with LDM.
5902 ; This pattern will only match if the one above did not.
5903 (define_split
5904 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5905 (match_operand:ANY64 1 "const_double_operand" ""))]
5906 "TARGET_ARM && reload_completed
5907 && arm_const_double_by_parts (operands[1])"
5908 [(set (match_dup 0) (match_dup 1))
5909 (set (match_dup 2) (match_dup 3))]
5910 "
5911 operands[2] = gen_highpart (SImode, operands[0]);
5912 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5913 operands[1]);
5914 operands[0] = gen_lowpart (SImode, operands[0]);
5915 operands[1] = gen_lowpart (SImode, operands[1]);
5916 "
5917 )
5918
5919 (define_split
5920 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5921 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5922 "TARGET_EITHER && reload_completed"
5923 [(set (match_dup 0) (match_dup 1))
5924 (set (match_dup 2) (match_dup 3))]
5925 "
5926 operands[2] = gen_highpart (SImode, operands[0]);
5927 operands[3] = gen_highpart (SImode, operands[1]);
5928 operands[0] = gen_lowpart (SImode, operands[0]);
5929 operands[1] = gen_lowpart (SImode, operands[1]);
5930
5931 /* Handle a partial overlap. */
5932 if (rtx_equal_p (operands[0], operands[3]))
5933 {
5934 rtx tmp0 = operands[0];
5935 rtx tmp1 = operands[1];
5936
5937 operands[0] = operands[2];
5938 operands[1] = operands[3];
5939 operands[2] = tmp0;
5940 operands[3] = tmp1;
5941 }
5942 "
5943 )
5944
5945 ;; We can't actually do base+index doubleword loads if the index and
5946 ;; destination overlap. Split here so that we at least have chance to
5947 ;; schedule.
5948 (define_split
5949 [(set (match_operand:DI 0 "s_register_operand" "")
5950 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5951 (match_operand:SI 2 "s_register_operand" ""))))]
5952 "TARGET_LDRD
5953 && reg_overlap_mentioned_p (operands[0], operands[1])
5954 && reg_overlap_mentioned_p (operands[0], operands[2])"
5955 [(set (match_dup 4)
5956 (plus:SI (match_dup 1)
5957 (match_dup 2)))
5958 (set (match_dup 0)
5959 (mem:DI (match_dup 4)))]
5960 "
5961 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5962 "
5963 )
5964
5965 (define_expand "movsi"
5966 [(set (match_operand:SI 0 "general_operand" "")
5967 (match_operand:SI 1 "general_operand" ""))]
5968 "TARGET_EITHER"
5969 "
5970 {
5971 rtx base, offset, tmp;
5972
5973 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5974 {
5975 /* Everything except mem = const or mem = mem can be done easily. */
5976 if (MEM_P (operands[0]))
5977 operands[1] = force_reg (SImode, operands[1]);
5978 if (arm_general_register_operand (operands[0], SImode)
5979 && CONST_INT_P (operands[1])
5980 && !(const_ok_for_arm (INTVAL (operands[1]))
5981 || const_ok_for_arm (~INTVAL (operands[1]))))
5982 {
5983 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5984 {
5985 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5986 DONE;
5987 }
5988 else
5989 {
5990 arm_split_constant (SET, SImode, NULL_RTX,
5991 INTVAL (operands[1]), operands[0], NULL_RTX,
5992 optimize && can_create_pseudo_p ());
5993 DONE;
5994 }
5995 }
5996 }
5997 else /* Target doesn't have MOVT... */
5998 {
5999 if (can_create_pseudo_p ())
6000 {
6001 if (!REG_P (operands[0]))
6002 operands[1] = force_reg (SImode, operands[1]);
6003 }
6004 }
6005
6006 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6007 {
6008 split_const (operands[1], &base, &offset);
6009 if (GET_CODE (base) == SYMBOL_REF
6010 && !offset_within_block_p (base, INTVAL (offset)))
6011 {
6012 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6013 emit_move_insn (tmp, base);
6014 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6015 DONE;
6016 }
6017 }
6018
6019 /* Recognize the case where operand[1] is a reference to thread-local
6020 data and load its address to a register. */
6021 if (arm_tls_referenced_p (operands[1]))
6022 {
6023 rtx tmp = operands[1];
6024 rtx addend = NULL;
6025
6026 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6027 {
6028 addend = XEXP (XEXP (tmp, 0), 1);
6029 tmp = XEXP (XEXP (tmp, 0), 0);
6030 }
6031
6032 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6033 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6034
6035 tmp = legitimize_tls_address (tmp,
6036 !can_create_pseudo_p () ? operands[0] : 0);
6037 if (addend)
6038 {
6039 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6040 tmp = force_operand (tmp, operands[0]);
6041 }
6042 operands[1] = tmp;
6043 }
6044 else if (flag_pic
6045 && (CONSTANT_P (operands[1])
6046 || symbol_mentioned_p (operands[1])
6047 || label_mentioned_p (operands[1])))
6048 operands[1] = legitimize_pic_address (operands[1], SImode,
6049 (!can_create_pseudo_p ()
6050 ? operands[0]
6051 : NULL_RTX), NULL_RTX,
6052 false /*compute_now*/);
6053 }
6054 "
6055 )
6056
6057 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6058 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6059 ;; so this does not matter.
6060 (define_insn "*arm_movt"
6061 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6062 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6063 (match_operand:SI 2 "general_operand" "i,i")))]
6064 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6065 "@
6066 movt%?\t%0, #:upper16:%c2
6067 movt\t%0, #:upper16:%c2"
6068 [(set_attr "arch" "32,v8mb")
6069 (set_attr "predicable" "yes")
6070 (set_attr "length" "4")
6071 (set_attr "type" "alu_sreg")]
6072 )
6073
6074 (define_insn "*arm_movsi_insn"
6075 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6076 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6077 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6078 && ( register_operand (operands[0], SImode)
6079 || register_operand (operands[1], SImode))"
6080 "@
6081 mov%?\\t%0, %1
6082 mov%?\\t%0, %1
6083 mvn%?\\t%0, #%B1
6084 movw%?\\t%0, %1
6085 ldr%?\\t%0, %1
6086 str%?\\t%1, %0"
6087 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6088 (set_attr "predicable" "yes")
6089 (set_attr "arch" "*,*,*,v6t2,*,*")
6090 (set_attr "pool_range" "*,*,*,*,4096,*")
6091 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6092 )
6093
6094 (define_split
6095 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6096 (match_operand:SI 1 "const_int_operand" ""))]
6097 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6098 && (!(const_ok_for_arm (INTVAL (operands[1]))
6099 || const_ok_for_arm (~INTVAL (operands[1]))))"
6100 [(clobber (const_int 0))]
6101 "
6102 arm_split_constant (SET, SImode, NULL_RTX,
6103 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6104 DONE;
6105 "
6106 )
6107
6108 ;; A normal way to do (symbol + offset) requires three instructions at least
6109 ;; (depends on how big the offset is) as below:
6110 ;; movw r0, #:lower16:g
6111 ;; movw r0, #:upper16:g
6112 ;; adds r0, #4
6113 ;;
6114 ;; A better way would be:
6115 ;; movw r0, #:lower16:g+4
6116 ;; movw r0, #:upper16:g+4
6117 ;;
6118 ;; The limitation of this way is that the length of offset should be a 16-bit
6119 ;; signed value, because current assembler only supports REL type relocation for
6120 ;; such case. If the more powerful RELA type is supported in future, we should
6121 ;; update this pattern to go with better way.
6122 (define_split
6123 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6124 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6125 (match_operand:SI 2 "const_int_operand" ""))))]
6126 "TARGET_THUMB
6127 && TARGET_HAVE_MOVT
6128 && arm_disable_literal_pool
6129 && reload_completed
6130 && GET_CODE (operands[1]) == SYMBOL_REF"
6131 [(clobber (const_int 0))]
6132 "
6133 int offset = INTVAL (operands[2]);
6134
6135 if (offset < -0x8000 || offset > 0x7fff)
6136 {
6137 arm_emit_movpair (operands[0], operands[1]);
6138 emit_insn (gen_rtx_SET (operands[0],
6139 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6140 }
6141 else
6142 {
6143 rtx op = gen_rtx_CONST (SImode,
6144 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6145 arm_emit_movpair (operands[0], op);
6146 }
6147 "
6148 )
6149
6150 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6151 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6152 ;; and lo_sum would be merged back into memory load at cprop. However,
6153 ;; if the default is to prefer movt/movw rather than a load from the constant
6154 ;; pool, the performance is better.
6155 (define_split
6156 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6157 (match_operand:SI 1 "general_operand" ""))]
6158 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6159 && !target_word_relocations
6160 && !arm_tls_referenced_p (operands[1])"
6161 [(clobber (const_int 0))]
6162 {
6163 arm_emit_movpair (operands[0], operands[1]);
6164 DONE;
6165 })
6166
6167 ;; When generating pic, we need to load the symbol offset into a register.
6168 ;; So that the optimizer does not confuse this with a normal symbol load
6169 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6170 ;; since that is the only type of relocation we can use.
6171
6172 ;; Wrap calculation of the whole PIC address in a single pattern for the
6173 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6174 ;; a PIC address involves two loads from memory, so we want to CSE it
6175 ;; as often as possible.
6176 ;; This pattern will be split into one of the pic_load_addr_* patterns
6177 ;; and a move after GCSE optimizations.
6178 ;;
6179 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6180 (define_expand "calculate_pic_address"
6181 [(set (match_operand:SI 0 "register_operand" "")
6182 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6183 (unspec:SI [(match_operand:SI 2 "" "")]
6184 UNSPEC_PIC_SYM))))]
6185 "flag_pic"
6186 )
6187
6188 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6189 (define_split
6190 [(set (match_operand:SI 0 "register_operand" "")
6191 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6192 (unspec:SI [(match_operand:SI 2 "" "")]
6193 UNSPEC_PIC_SYM))))]
6194 "flag_pic"
6195 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6196 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6197 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6198 )
6199
6200 ;; operand1 is the memory address to go into
6201 ;; pic_load_addr_32bit.
6202 ;; operand2 is the PIC label to be emitted
6203 ;; from pic_add_dot_plus_eight.
6204 ;; We do this to allow hoisting of the entire insn.
6205 (define_insn_and_split "pic_load_addr_unified"
6206 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6207 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6208 (match_operand:SI 2 "" "")]
6209 UNSPEC_PIC_UNIFIED))]
6210 "flag_pic"
6211 "#"
6212 "&& reload_completed"
6213 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6214 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6215 (match_dup 2)] UNSPEC_PIC_BASE))]
6216 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6217 [(set_attr "type" "load_4,load_4,load_4")
6218 (set_attr "pool_range" "4096,4094,1022")
6219 (set_attr "neg_pool_range" "4084,0,0")
6220 (set_attr "arch" "a,t2,t1")
6221 (set_attr "length" "8,6,4")]
6222 )
6223
6224 ;; The rather odd constraints on the following are to force reload to leave
6225 ;; the insn alone, and to force the minipool generation pass to then move
6226 ;; the GOT symbol to memory.
6227
6228 (define_insn "pic_load_addr_32bit"
6229 [(set (match_operand:SI 0 "s_register_operand" "=r")
6230 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6231 "TARGET_32BIT && flag_pic"
6232 "ldr%?\\t%0, %1"
6233 [(set_attr "type" "load_4")
6234 (set (attr "pool_range")
6235 (if_then_else (eq_attr "is_thumb" "no")
6236 (const_int 4096)
6237 (const_int 4094)))
6238 (set (attr "neg_pool_range")
6239 (if_then_else (eq_attr "is_thumb" "no")
6240 (const_int 4084)
6241 (const_int 0)))]
6242 )
6243
6244 (define_insn "pic_load_addr_thumb1"
6245 [(set (match_operand:SI 0 "s_register_operand" "=l")
6246 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6247 "TARGET_THUMB1 && flag_pic"
6248 "ldr\\t%0, %1"
6249 [(set_attr "type" "load_4")
6250 (set (attr "pool_range") (const_int 1018))]
6251 )
6252
6253 (define_insn "pic_add_dot_plus_four"
6254 [(set (match_operand:SI 0 "register_operand" "=r")
6255 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6256 (const_int 4)
6257 (match_operand 2 "" "")]
6258 UNSPEC_PIC_BASE))]
6259 "TARGET_THUMB"
6260 "*
6261 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6262 INTVAL (operands[2]));
6263 return \"add\\t%0, %|pc\";
6264 "
6265 [(set_attr "length" "2")
6266 (set_attr "type" "alu_sreg")]
6267 )
6268
6269 (define_insn "pic_add_dot_plus_eight"
6270 [(set (match_operand:SI 0 "register_operand" "=r")
6271 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6272 (const_int 8)
6273 (match_operand 2 "" "")]
6274 UNSPEC_PIC_BASE))]
6275 "TARGET_ARM"
6276 "*
6277 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6278 INTVAL (operands[2]));
6279 return \"add%?\\t%0, %|pc, %1\";
6280 "
6281 [(set_attr "predicable" "yes")
6282 (set_attr "type" "alu_sreg")]
6283 )
6284
6285 (define_insn "tls_load_dot_plus_eight"
6286 [(set (match_operand:SI 0 "register_operand" "=r")
6287 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6288 (const_int 8)
6289 (match_operand 2 "" "")]
6290 UNSPEC_PIC_BASE)))]
6291 "TARGET_ARM"
6292 "*
6293 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6294 INTVAL (operands[2]));
6295 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6296 "
6297 [(set_attr "predicable" "yes")
6298 (set_attr "type" "load_4")]
6299 )
6300
6301 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6302 ;; followed by a load. These sequences can be crunched down to
6303 ;; tls_load_dot_plus_eight by a peephole.
6304
6305 (define_peephole2
6306 [(set (match_operand:SI 0 "register_operand" "")
6307 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6308 (const_int 8)
6309 (match_operand 1 "" "")]
6310 UNSPEC_PIC_BASE))
6311 (set (match_operand:SI 2 "arm_general_register_operand" "")
6312 (mem:SI (match_dup 0)))]
6313 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6314 [(set (match_dup 2)
6315 (mem:SI (unspec:SI [(match_dup 3)
6316 (const_int 8)
6317 (match_dup 1)]
6318 UNSPEC_PIC_BASE)))]
6319 ""
6320 )
6321
6322 (define_insn "pic_offset_arm"
6323 [(set (match_operand:SI 0 "register_operand" "=r")
6324 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6325 (unspec:SI [(match_operand:SI 2 "" "X")]
6326 UNSPEC_PIC_OFFSET))))]
6327 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6328 "ldr%?\\t%0, [%1,%2]"
6329 [(set_attr "type" "load_4")]
6330 )
6331
6332 (define_expand "builtin_setjmp_receiver"
6333 [(label_ref (match_operand 0 "" ""))]
6334 "flag_pic"
6335 "
6336 {
6337 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6338 register. */
6339 if (arm_pic_register != INVALID_REGNUM)
6340 arm_load_pic_register (1UL << 3, NULL_RTX);
6341 DONE;
6342 }")
6343
6344 ;; If copying one reg to another we can set the condition codes according to
6345 ;; its value. Such a move is common after a return from subroutine and the
6346 ;; result is being tested against zero.
6347
6348 (define_insn "*movsi_compare0"
6349 [(set (reg:CC CC_REGNUM)
6350 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6351 (const_int 0)))
6352 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6353 (match_dup 1))]
6354 "TARGET_32BIT"
6355 "@
6356 cmp%?\\t%0, #0
6357 subs%?\\t%0, %1, #0"
6358 [(set_attr "conds" "set")
6359 (set_attr "type" "alus_imm,alus_imm")]
6360 )
6361
6362 ;; Subroutine to store a half word from a register into memory.
6363 ;; Operand 0 is the source register (HImode)
6364 ;; Operand 1 is the destination address in a register (SImode)
6365
6366 ;; In both this routine and the next, we must be careful not to spill
6367 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6368 ;; can generate unrecognizable rtl.
6369
6370 (define_expand "storehi"
6371 [;; store the low byte
6372 (set (match_operand 1 "" "") (match_dup 3))
6373 ;; extract the high byte
6374 (set (match_dup 2)
6375 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6376 ;; store the high byte
6377 (set (match_dup 4) (match_dup 5))]
6378 "TARGET_ARM"
6379 "
6380 {
6381 rtx op1 = operands[1];
6382 rtx addr = XEXP (op1, 0);
6383 enum rtx_code code = GET_CODE (addr);
6384
6385 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6386 || code == MINUS)
6387 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6388
6389 operands[4] = adjust_address (op1, QImode, 1);
6390 operands[1] = adjust_address (operands[1], QImode, 0);
6391 operands[3] = gen_lowpart (QImode, operands[0]);
6392 operands[0] = gen_lowpart (SImode, operands[0]);
6393 operands[2] = gen_reg_rtx (SImode);
6394 operands[5] = gen_lowpart (QImode, operands[2]);
6395 }"
6396 )
6397
6398 (define_expand "storehi_bigend"
6399 [(set (match_dup 4) (match_dup 3))
6400 (set (match_dup 2)
6401 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6402 (set (match_operand 1 "" "") (match_dup 5))]
6403 "TARGET_ARM"
6404 "
6405 {
6406 rtx op1 = operands[1];
6407 rtx addr = XEXP (op1, 0);
6408 enum rtx_code code = GET_CODE (addr);
6409
6410 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6411 || code == MINUS)
6412 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6413
6414 operands[4] = adjust_address (op1, QImode, 1);
6415 operands[1] = adjust_address (operands[1], QImode, 0);
6416 operands[3] = gen_lowpart (QImode, operands[0]);
6417 operands[0] = gen_lowpart (SImode, operands[0]);
6418 operands[2] = gen_reg_rtx (SImode);
6419 operands[5] = gen_lowpart (QImode, operands[2]);
6420 }"
6421 )
6422
6423 ;; Subroutine to store a half word integer constant into memory.
6424 (define_expand "storeinthi"
6425 [(set (match_operand 0 "" "")
6426 (match_operand 1 "" ""))
6427 (set (match_dup 3) (match_dup 2))]
6428 "TARGET_ARM"
6429 "
6430 {
6431 HOST_WIDE_INT value = INTVAL (operands[1]);
6432 rtx addr = XEXP (operands[0], 0);
6433 rtx op0 = operands[0];
6434 enum rtx_code code = GET_CODE (addr);
6435
6436 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6437 || code == MINUS)
6438 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6439
6440 operands[1] = gen_reg_rtx (SImode);
6441 if (BYTES_BIG_ENDIAN)
6442 {
6443 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6444 if ((value & 255) == ((value >> 8) & 255))
6445 operands[2] = operands[1];
6446 else
6447 {
6448 operands[2] = gen_reg_rtx (SImode);
6449 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6450 }
6451 }
6452 else
6453 {
6454 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6455 if ((value & 255) == ((value >> 8) & 255))
6456 operands[2] = operands[1];
6457 else
6458 {
6459 operands[2] = gen_reg_rtx (SImode);
6460 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6461 }
6462 }
6463
6464 operands[3] = adjust_address (op0, QImode, 1);
6465 operands[0] = adjust_address (operands[0], QImode, 0);
6466 operands[2] = gen_lowpart (QImode, operands[2]);
6467 operands[1] = gen_lowpart (QImode, operands[1]);
6468 }"
6469 )
6470
6471 (define_expand "storehi_single_op"
6472 [(set (match_operand:HI 0 "memory_operand" "")
6473 (match_operand:HI 1 "general_operand" ""))]
6474 "TARGET_32BIT && arm_arch4"
6475 "
6476 if (!s_register_operand (operands[1], HImode))
6477 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6478 "
6479 )
6480
6481 (define_expand "movhi"
6482 [(set (match_operand:HI 0 "general_operand" "")
6483 (match_operand:HI 1 "general_operand" ""))]
6484 "TARGET_EITHER"
6485 "
6486 if (TARGET_ARM)
6487 {
6488 if (can_create_pseudo_p ())
6489 {
6490 if (MEM_P (operands[0]))
6491 {
6492 if (arm_arch4)
6493 {
6494 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6495 DONE;
6496 }
6497 if (CONST_INT_P (operands[1]))
6498 emit_insn (gen_storeinthi (operands[0], operands[1]));
6499 else
6500 {
6501 if (MEM_P (operands[1]))
6502 operands[1] = force_reg (HImode, operands[1]);
6503 if (BYTES_BIG_ENDIAN)
6504 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6505 else
6506 emit_insn (gen_storehi (operands[1], operands[0]));
6507 }
6508 DONE;
6509 }
6510 /* Sign extend a constant, and keep it in an SImode reg. */
6511 else if (CONST_INT_P (operands[1]))
6512 {
6513 rtx reg = gen_reg_rtx (SImode);
6514 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6515
6516 /* If the constant is already valid, leave it alone. */
6517 if (!const_ok_for_arm (val))
6518 {
6519 /* If setting all the top bits will make the constant
6520 loadable in a single instruction, then set them.
6521 Otherwise, sign extend the number. */
6522
6523 if (const_ok_for_arm (~(val | ~0xffff)))
6524 val |= ~0xffff;
6525 else if (val & 0x8000)
6526 val |= ~0xffff;
6527 }
6528
6529 emit_insn (gen_movsi (reg, GEN_INT (val)));
6530 operands[1] = gen_lowpart (HImode, reg);
6531 }
6532 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6533 && MEM_P (operands[1]))
6534 {
6535 rtx reg = gen_reg_rtx (SImode);
6536
6537 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6538 operands[1] = gen_lowpart (HImode, reg);
6539 }
6540 else if (!arm_arch4)
6541 {
6542 if (MEM_P (operands[1]))
6543 {
6544 rtx base;
6545 rtx offset = const0_rtx;
6546 rtx reg = gen_reg_rtx (SImode);
6547
6548 if ((REG_P (base = XEXP (operands[1], 0))
6549 || (GET_CODE (base) == PLUS
6550 && (CONST_INT_P (offset = XEXP (base, 1)))
6551 && ((INTVAL(offset) & 1) != 1)
6552 && REG_P (base = XEXP (base, 0))))
6553 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6554 {
6555 rtx new_rtx;
6556
6557 new_rtx = widen_memory_access (operands[1], SImode,
6558 ((INTVAL (offset) & ~3)
6559 - INTVAL (offset)));
6560 emit_insn (gen_movsi (reg, new_rtx));
6561 if (((INTVAL (offset) & 2) != 0)
6562 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6563 {
6564 rtx reg2 = gen_reg_rtx (SImode);
6565
6566 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6567 reg = reg2;
6568 }
6569 }
6570 else
6571 emit_insn (gen_movhi_bytes (reg, operands[1]));
6572
6573 operands[1] = gen_lowpart (HImode, reg);
6574 }
6575 }
6576 }
6577 /* Handle loading a large integer during reload. */
6578 else if (CONST_INT_P (operands[1])
6579 && !const_ok_for_arm (INTVAL (operands[1]))
6580 && !const_ok_for_arm (~INTVAL (operands[1])))
6581 {
6582 /* Writing a constant to memory needs a scratch, which should
6583 be handled with SECONDARY_RELOADs. */
6584 gcc_assert (REG_P (operands[0]));
6585
6586 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6587 emit_insn (gen_movsi (operands[0], operands[1]));
6588 DONE;
6589 }
6590 }
6591 else if (TARGET_THUMB2)
6592 {
6593 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6594 if (can_create_pseudo_p ())
6595 {
6596 if (!REG_P (operands[0]))
6597 operands[1] = force_reg (HImode, operands[1]);
6598 /* Zero extend a constant, and keep it in an SImode reg. */
6599 else if (CONST_INT_P (operands[1]))
6600 {
6601 rtx reg = gen_reg_rtx (SImode);
6602 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6603
6604 emit_insn (gen_movsi (reg, GEN_INT (val)));
6605 operands[1] = gen_lowpart (HImode, reg);
6606 }
6607 }
6608 }
6609 else /* TARGET_THUMB1 */
6610 {
6611 if (can_create_pseudo_p ())
6612 {
6613 if (CONST_INT_P (operands[1]))
6614 {
6615 rtx reg = gen_reg_rtx (SImode);
6616
6617 emit_insn (gen_movsi (reg, operands[1]));
6618 operands[1] = gen_lowpart (HImode, reg);
6619 }
6620
6621 /* ??? We shouldn't really get invalid addresses here, but this can
6622 happen if we are passed a SP (never OK for HImode/QImode) or
6623 virtual register (also rejected as illegitimate for HImode/QImode)
6624 relative address. */
6625 /* ??? This should perhaps be fixed elsewhere, for instance, in
6626 fixup_stack_1, by checking for other kinds of invalid addresses,
6627 e.g. a bare reference to a virtual register. This may confuse the
6628 alpha though, which must handle this case differently. */
6629 if (MEM_P (operands[0])
6630 && !memory_address_p (GET_MODE (operands[0]),
6631 XEXP (operands[0], 0)))
6632 operands[0]
6633 = replace_equiv_address (operands[0],
6634 copy_to_reg (XEXP (operands[0], 0)));
6635
6636 if (MEM_P (operands[1])
6637 && !memory_address_p (GET_MODE (operands[1]),
6638 XEXP (operands[1], 0)))
6639 operands[1]
6640 = replace_equiv_address (operands[1],
6641 copy_to_reg (XEXP (operands[1], 0)));
6642
6643 if (MEM_P (operands[1]) && optimize > 0)
6644 {
6645 rtx reg = gen_reg_rtx (SImode);
6646
6647 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6648 operands[1] = gen_lowpart (HImode, reg);
6649 }
6650
6651 if (MEM_P (operands[0]))
6652 operands[1] = force_reg (HImode, operands[1]);
6653 }
6654 else if (CONST_INT_P (operands[1])
6655 && !satisfies_constraint_I (operands[1]))
6656 {
6657 /* Handle loading a large integer during reload. */
6658
6659 /* Writing a constant to memory needs a scratch, which should
6660 be handled with SECONDARY_RELOADs. */
6661 gcc_assert (REG_P (operands[0]));
6662
6663 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6664 emit_insn (gen_movsi (operands[0], operands[1]));
6665 DONE;
6666 }
6667 }
6668 "
6669 )
6670
6671 (define_expand "movhi_bytes"
6672 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6673 (set (match_dup 3)
6674 (zero_extend:SI (match_dup 6)))
6675 (set (match_operand:SI 0 "" "")
6676 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6677 "TARGET_ARM"
6678 "
6679 {
6680 rtx mem1, mem2;
6681 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6682
6683 mem1 = change_address (operands[1], QImode, addr);
6684 mem2 = change_address (operands[1], QImode,
6685 plus_constant (Pmode, addr, 1));
6686 operands[0] = gen_lowpart (SImode, operands[0]);
6687 operands[1] = mem1;
6688 operands[2] = gen_reg_rtx (SImode);
6689 operands[3] = gen_reg_rtx (SImode);
6690 operands[6] = mem2;
6691
6692 if (BYTES_BIG_ENDIAN)
6693 {
6694 operands[4] = operands[2];
6695 operands[5] = operands[3];
6696 }
6697 else
6698 {
6699 operands[4] = operands[3];
6700 operands[5] = operands[2];
6701 }
6702 }"
6703 )
6704
6705 (define_expand "movhi_bigend"
6706 [(set (match_dup 2)
6707 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6708 (const_int 16)))
6709 (set (match_dup 3)
6710 (ashiftrt:SI (match_dup 2) (const_int 16)))
6711 (set (match_operand:HI 0 "s_register_operand" "")
6712 (match_dup 4))]
6713 "TARGET_ARM"
6714 "
6715 operands[2] = gen_reg_rtx (SImode);
6716 operands[3] = gen_reg_rtx (SImode);
6717 operands[4] = gen_lowpart (HImode, operands[3]);
6718 "
6719 )
6720
6721 ;; Pattern to recognize insn generated default case above
6722 (define_insn "*movhi_insn_arch4"
6723 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6724 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6725 "TARGET_ARM
6726 && arm_arch4 && !TARGET_HARD_FLOAT
6727 && (register_operand (operands[0], HImode)
6728 || register_operand (operands[1], HImode))"
6729 "@
6730 mov%?\\t%0, %1\\t%@ movhi
6731 mvn%?\\t%0, #%B1\\t%@ movhi
6732 movw%?\\t%0, %L1\\t%@ movhi
6733 strh%?\\t%1, %0\\t%@ movhi
6734 ldrh%?\\t%0, %1\\t%@ movhi"
6735 [(set_attr "predicable" "yes")
6736 (set_attr "pool_range" "*,*,*,*,256")
6737 (set_attr "neg_pool_range" "*,*,*,*,244")
6738 (set_attr "arch" "*,*,v6t2,*,*")
6739 (set_attr_alternative "type"
6740 [(if_then_else (match_operand 1 "const_int_operand" "")
6741 (const_string "mov_imm" )
6742 (const_string "mov_reg"))
6743 (const_string "mvn_imm")
6744 (const_string "mov_imm")
6745 (const_string "store_4")
6746 (const_string "load_4")])]
6747 )
6748
6749 (define_insn "*movhi_bytes"
6750 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6751 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6752 "TARGET_ARM && !TARGET_HARD_FLOAT"
6753 "@
6754 mov%?\\t%0, %1\\t%@ movhi
6755 mov%?\\t%0, %1\\t%@ movhi
6756 mvn%?\\t%0, #%B1\\t%@ movhi"
6757 [(set_attr "predicable" "yes")
6758 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6759 )
6760
6761 ;; We use a DImode scratch because we may occasionally need an additional
6762 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6763 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6764 (define_expand "reload_outhi"
6765 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6766 (match_operand:HI 1 "s_register_operand" "r")
6767 (match_operand:DI 2 "s_register_operand" "=&l")])]
6768 "TARGET_EITHER"
6769 "if (TARGET_ARM)
6770 arm_reload_out_hi (operands);
6771 else
6772 thumb_reload_out_hi (operands);
6773 DONE;
6774 "
6775 )
6776
6777 (define_expand "reload_inhi"
6778 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6779 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6780 (match_operand:DI 2 "s_register_operand" "=&r")])]
6781 "TARGET_EITHER"
6782 "
6783 if (TARGET_ARM)
6784 arm_reload_in_hi (operands);
6785 else
6786 thumb_reload_out_hi (operands);
6787 DONE;
6788 ")
6789
6790 (define_expand "movqi"
6791 [(set (match_operand:QI 0 "general_operand" "")
6792 (match_operand:QI 1 "general_operand" ""))]
6793 "TARGET_EITHER"
6794 "
6795 /* Everything except mem = const or mem = mem can be done easily */
6796
6797 if (can_create_pseudo_p ())
6798 {
6799 if (CONST_INT_P (operands[1]))
6800 {
6801 rtx reg = gen_reg_rtx (SImode);
6802
6803 /* For thumb we want an unsigned immediate, then we are more likely
6804 to be able to use a movs insn. */
6805 if (TARGET_THUMB)
6806 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6807
6808 emit_insn (gen_movsi (reg, operands[1]));
6809 operands[1] = gen_lowpart (QImode, reg);
6810 }
6811
6812 if (TARGET_THUMB)
6813 {
6814 /* ??? We shouldn't really get invalid addresses here, but this can
6815 happen if we are passed a SP (never OK for HImode/QImode) or
6816 virtual register (also rejected as illegitimate for HImode/QImode)
6817 relative address. */
6818 /* ??? This should perhaps be fixed elsewhere, for instance, in
6819 fixup_stack_1, by checking for other kinds of invalid addresses,
6820 e.g. a bare reference to a virtual register. This may confuse the
6821 alpha though, which must handle this case differently. */
6822 if (MEM_P (operands[0])
6823 && !memory_address_p (GET_MODE (operands[0]),
6824 XEXP (operands[0], 0)))
6825 operands[0]
6826 = replace_equiv_address (operands[0],
6827 copy_to_reg (XEXP (operands[0], 0)));
6828 if (MEM_P (operands[1])
6829 && !memory_address_p (GET_MODE (operands[1]),
6830 XEXP (operands[1], 0)))
6831 operands[1]
6832 = replace_equiv_address (operands[1],
6833 copy_to_reg (XEXP (operands[1], 0)));
6834 }
6835
6836 if (MEM_P (operands[1]) && optimize > 0)
6837 {
6838 rtx reg = gen_reg_rtx (SImode);
6839
6840 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6841 operands[1] = gen_lowpart (QImode, reg);
6842 }
6843
6844 if (MEM_P (operands[0]))
6845 operands[1] = force_reg (QImode, operands[1]);
6846 }
6847 else if (TARGET_THUMB
6848 && CONST_INT_P (operands[1])
6849 && !satisfies_constraint_I (operands[1]))
6850 {
6851 /* Handle loading a large integer during reload. */
6852
6853 /* Writing a constant to memory needs a scratch, which should
6854 be handled with SECONDARY_RELOADs. */
6855 gcc_assert (REG_P (operands[0]));
6856
6857 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6858 emit_insn (gen_movsi (operands[0], operands[1]));
6859 DONE;
6860 }
6861 "
6862 )
6863
6864 (define_insn "*arm_movqi_insn"
6865 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6866 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6867 "TARGET_32BIT
6868 && ( register_operand (operands[0], QImode)
6869 || register_operand (operands[1], QImode))"
6870 "@
6871 mov%?\\t%0, %1
6872 mov%?\\t%0, %1
6873 mov%?\\t%0, %1
6874 mov%?\\t%0, %1
6875 mvn%?\\t%0, #%B1
6876 ldrb%?\\t%0, %1
6877 strb%?\\t%1, %0
6878 ldrb%?\\t%0, %1
6879 strb%?\\t%1, %0"
6880 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6881 (set_attr "predicable" "yes")
6882 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6883 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6884 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6885 )
6886
6887 ;; HFmode moves
6888 (define_expand "movhf"
6889 [(set (match_operand:HF 0 "general_operand" "")
6890 (match_operand:HF 1 "general_operand" ""))]
6891 "TARGET_EITHER"
6892 "
6893 if (TARGET_32BIT)
6894 {
6895 if (MEM_P (operands[0]))
6896 operands[1] = force_reg (HFmode, operands[1]);
6897 }
6898 else /* TARGET_THUMB1 */
6899 {
6900 if (can_create_pseudo_p ())
6901 {
6902 if (!REG_P (operands[0]))
6903 operands[1] = force_reg (HFmode, operands[1]);
6904 }
6905 }
6906 "
6907 )
6908
6909 (define_insn "*arm32_movhf"
6910 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6911 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6912 "TARGET_32BIT && !TARGET_HARD_FLOAT
6913 && ( s_register_operand (operands[0], HFmode)
6914 || s_register_operand (operands[1], HFmode))"
6915 "*
6916 switch (which_alternative)
6917 {
6918 case 0: /* ARM register from memory */
6919 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6920 case 1: /* memory from ARM register */
6921 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6922 case 2: /* ARM register from ARM register */
6923 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6924 case 3: /* ARM register from constant */
6925 {
6926 long bits;
6927 rtx ops[4];
6928
6929 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6930 HFmode);
6931 ops[0] = operands[0];
6932 ops[1] = GEN_INT (bits);
6933 ops[2] = GEN_INT (bits & 0xff00);
6934 ops[3] = GEN_INT (bits & 0x00ff);
6935
6936 if (arm_arch_thumb2)
6937 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6938 else
6939 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6940 return \"\";
6941 }
6942 default:
6943 gcc_unreachable ();
6944 }
6945 "
6946 [(set_attr "conds" "unconditional")
6947 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6948 (set_attr "length" "4,4,4,8")
6949 (set_attr "predicable" "yes")]
6950 )
6951
6952 (define_expand "movsf"
6953 [(set (match_operand:SF 0 "general_operand" "")
6954 (match_operand:SF 1 "general_operand" ""))]
6955 "TARGET_EITHER"
6956 "
6957 if (TARGET_32BIT)
6958 {
6959 if (MEM_P (operands[0]))
6960 operands[1] = force_reg (SFmode, operands[1]);
6961 }
6962 else /* TARGET_THUMB1 */
6963 {
6964 if (can_create_pseudo_p ())
6965 {
6966 if (!REG_P (operands[0]))
6967 operands[1] = force_reg (SFmode, operands[1]);
6968 }
6969 }
6970
6971 /* Cannot load it directly, generate a load with clobber so that it can be
6972 loaded via GPR with MOV / MOVT. */
6973 if (arm_disable_literal_pool
6974 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6975 && CONST_DOUBLE_P (operands[1])
6976 && TARGET_HARD_FLOAT
6977 && !vfp3_const_double_rtx (operands[1]))
6978 {
6979 rtx clobreg = gen_reg_rtx (SFmode);
6980 emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
6981 clobreg));
6982 DONE;
6983 }
6984 "
6985 )
6986
6987 ;; Transform a floating-point move of a constant into a core register into
6988 ;; an SImode operation.
6989 (define_split
6990 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6991 (match_operand:SF 1 "immediate_operand" ""))]
6992 "TARGET_EITHER
6993 && reload_completed
6994 && CONST_DOUBLE_P (operands[1])"
6995 [(set (match_dup 2) (match_dup 3))]
6996 "
6997 operands[2] = gen_lowpart (SImode, operands[0]);
6998 operands[3] = gen_lowpart (SImode, operands[1]);
6999 if (operands[2] == 0 || operands[3] == 0)
7000 FAIL;
7001 "
7002 )
7003
7004 (define_insn "*arm_movsf_soft_insn"
7005 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7006 (match_operand:SF 1 "general_operand" "r,mE,r"))]
7007 "TARGET_32BIT
7008 && TARGET_SOFT_FLOAT
7009 && (!MEM_P (operands[0])
7010 || register_operand (operands[1], SFmode))"
7011 {
7012 switch (which_alternative)
7013 {
7014 case 0: return \"mov%?\\t%0, %1\";
7015 case 1:
7016 /* Cannot load it directly, split to load it via MOV / MOVT. */
7017 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7018 return \"#\";
7019 return \"ldr%?\\t%0, %1\\t%@ float\";
7020 case 2: return \"str%?\\t%1, %0\\t%@ float\";
7021 default: gcc_unreachable ();
7022 }
7023 }
7024 [(set_attr "predicable" "yes")
7025 (set_attr "type" "mov_reg,load_4,store_4")
7026 (set_attr "arm_pool_range" "*,4096,*")
7027 (set_attr "thumb2_pool_range" "*,4094,*")
7028 (set_attr "arm_neg_pool_range" "*,4084,*")
7029 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7030 )
7031
7032 ;; Splitter for the above.
7033 (define_split
7034 [(set (match_operand:SF 0 "s_register_operand")
7035 (match_operand:SF 1 "const_double_operand"))]
7036 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7037 [(const_int 0)]
7038 {
7039 long buf;
7040 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
7041 rtx cst = gen_int_mode (buf, SImode);
7042 emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
7043 DONE;
7044 }
7045 )
7046
7047 (define_expand "movdf"
7048 [(set (match_operand:DF 0 "general_operand" "")
7049 (match_operand:DF 1 "general_operand" ""))]
7050 "TARGET_EITHER"
7051 "
7052 if (TARGET_32BIT)
7053 {
7054 if (MEM_P (operands[0]))
7055 operands[1] = force_reg (DFmode, operands[1]);
7056 }
7057 else /* TARGET_THUMB */
7058 {
7059 if (can_create_pseudo_p ())
7060 {
7061 if (!REG_P (operands[0]))
7062 operands[1] = force_reg (DFmode, operands[1]);
7063 }
7064 }
7065
7066 /* Cannot load it directly, generate a load with clobber so that it can be
7067 loaded via GPR with MOV / MOVT. */
7068 if (arm_disable_literal_pool
7069 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
7070 && CONSTANT_P (operands[1])
7071 && TARGET_HARD_FLOAT
7072 && !arm_const_double_rtx (operands[1])
7073 && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
7074 {
7075 rtx clobreg = gen_reg_rtx (DFmode);
7076 emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
7077 clobreg));
7078 DONE;
7079 }
7080 "
7081 )
7082
7083 ;; Reloading a df mode value stored in integer regs to memory can require a
7084 ;; scratch reg.
7085 (define_expand "reload_outdf"
7086 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7087 (match_operand:DF 1 "s_register_operand" "r")
7088 (match_operand:SI 2 "s_register_operand" "=&r")]
7089 "TARGET_THUMB2"
7090 "
7091 {
7092 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7093
7094 if (code == REG)
7095 operands[2] = XEXP (operands[0], 0);
7096 else if (code == POST_INC || code == PRE_DEC)
7097 {
7098 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7099 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7100 emit_insn (gen_movdi (operands[0], operands[1]));
7101 DONE;
7102 }
7103 else if (code == PRE_INC)
7104 {
7105 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7106
7107 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7108 operands[2] = reg;
7109 }
7110 else if (code == POST_DEC)
7111 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7112 else
7113 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7114 XEXP (XEXP (operands[0], 0), 1)));
7115
7116 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7117 operands[1]));
7118
7119 if (code == POST_DEC)
7120 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7121
7122 DONE;
7123 }"
7124 )
7125
7126 (define_insn "*movdf_soft_insn"
7127 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
7128 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
7129 "TARGET_32BIT && TARGET_SOFT_FLOAT
7130 && ( register_operand (operands[0], DFmode)
7131 || register_operand (operands[1], DFmode))"
7132 "*
7133 switch (which_alternative)
7134 {
7135 case 0:
7136 case 1:
7137 case 2:
7138 return \"#\";
7139 case 3:
7140 /* Cannot load it directly, split to load it via MOV / MOVT. */
7141 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7142 return \"#\";
7143 /* Fall through. */
7144 default:
7145 return output_move_double (operands, true, NULL);
7146 }
7147 "
7148 [(set_attr "length" "8,12,16,8,8")
7149 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7150 (set_attr "arm_pool_range" "*,*,*,1020,*")
7151 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7152 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7153 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7154 )
7155
7156 ;; Splitter for the above.
7157 (define_split
7158 [(set (match_operand:DF 0 "s_register_operand")
7159 (match_operand:DF 1 "const_double_operand"))]
7160 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7161 [(const_int 0)]
7162 {
7163 long buf[2];
7164 int order = BYTES_BIG_ENDIAN ? 1 : 0;
7165 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
7166 unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
7167 ival |= (zext_hwi (buf[1 - order], 32) << 32);
7168 rtx cst = gen_int_mode (ival, DImode);
7169 emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
7170 DONE;
7171 }
7172 )
7173 \f
7174
7175 ;; load- and store-multiple insns
7176 ;; The arm can load/store any set of registers, provided that they are in
7177 ;; ascending order, but these expanders assume a contiguous set.
7178
7179 (define_expand "load_multiple"
7180 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7181 (match_operand:SI 1 "" ""))
7182 (use (match_operand:SI 2 "" ""))])]
7183 "TARGET_32BIT"
7184 {
7185 HOST_WIDE_INT offset = 0;
7186
7187 /* Support only fixed point registers. */
7188 if (!CONST_INT_P (operands[2])
7189 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7190 || INTVAL (operands[2]) < 2
7191 || !MEM_P (operands[1])
7192 || !REG_P (operands[0])
7193 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7194 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7195 FAIL;
7196
7197 operands[3]
7198 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7199 INTVAL (operands[2]),
7200 force_reg (SImode, XEXP (operands[1], 0)),
7201 FALSE, operands[1], &offset);
7202 })
7203
7204 (define_expand "store_multiple"
7205 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7206 (match_operand:SI 1 "" ""))
7207 (use (match_operand:SI 2 "" ""))])]
7208 "TARGET_32BIT"
7209 {
7210 HOST_WIDE_INT offset = 0;
7211
7212 /* Support only fixed point registers. */
7213 if (!CONST_INT_P (operands[2])
7214 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7215 || INTVAL (operands[2]) < 2
7216 || !REG_P (operands[1])
7217 || !MEM_P (operands[0])
7218 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7219 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7220 FAIL;
7221
7222 operands[3]
7223 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7224 INTVAL (operands[2]),
7225 force_reg (SImode, XEXP (operands[0], 0)),
7226 FALSE, operands[0], &offset);
7227 })
7228
7229
7230 (define_expand "setmemsi"
7231 [(match_operand:BLK 0 "general_operand" "")
7232 (match_operand:SI 1 "const_int_operand" "")
7233 (match_operand:SI 2 "const_int_operand" "")
7234 (match_operand:SI 3 "const_int_operand" "")]
7235 "TARGET_32BIT"
7236 {
7237 if (arm_gen_setmem (operands))
7238 DONE;
7239
7240 FAIL;
7241 })
7242
7243
7244 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7245 ;; We could let this apply for blocks of less than this, but it clobbers so
7246 ;; many registers that there is then probably a better way.
7247
7248 (define_expand "movmemqi"
7249 [(match_operand:BLK 0 "general_operand" "")
7250 (match_operand:BLK 1 "general_operand" "")
7251 (match_operand:SI 2 "const_int_operand" "")
7252 (match_operand:SI 3 "const_int_operand" "")]
7253 ""
7254 "
7255 if (TARGET_32BIT)
7256 {
7257 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7258 && !optimize_function_for_size_p (cfun))
7259 {
7260 if (gen_movmem_ldrd_strd (operands))
7261 DONE;
7262 FAIL;
7263 }
7264
7265 if (arm_gen_movmemqi (operands))
7266 DONE;
7267 FAIL;
7268 }
7269 else /* TARGET_THUMB1 */
7270 {
7271 if ( INTVAL (operands[3]) != 4
7272 || INTVAL (operands[2]) > 48)
7273 FAIL;
7274
7275 thumb_expand_movmemqi (operands);
7276 DONE;
7277 }
7278 "
7279 )
7280 \f
7281
7282 ;; Compare & branch insns
7283 ;; The range calculations are based as follows:
7284 ;; For forward branches, the address calculation returns the address of
7285 ;; the next instruction. This is 2 beyond the branch instruction.
7286 ;; For backward branches, the address calculation returns the address of
7287 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7288 ;; instruction for the shortest sequence, and 4 before the branch instruction
7289 ;; if we have to jump around an unconditional branch.
7290 ;; To the basic branch range the PC offset must be added (this is +4).
7291 ;; So for forward branches we have
7292 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7293 ;; And for backward branches we have
7294 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7295 ;;
7296 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7297 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7298
7299 (define_expand "cbranchsi4"
7300 [(set (pc) (if_then_else
7301 (match_operator 0 "expandable_comparison_operator"
7302 [(match_operand:SI 1 "s_register_operand" "")
7303 (match_operand:SI 2 "nonmemory_operand" "")])
7304 (label_ref (match_operand 3 "" ""))
7305 (pc)))]
7306 "TARGET_EITHER"
7307 "
7308 if (!TARGET_THUMB1)
7309 {
7310 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7311 FAIL;
7312 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7313 operands[3]));
7314 DONE;
7315 }
7316 if (thumb1_cmpneg_operand (operands[2], SImode))
7317 {
7318 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7319 operands[3], operands[0]));
7320 DONE;
7321 }
7322 if (!thumb1_cmp_operand (operands[2], SImode))
7323 operands[2] = force_reg (SImode, operands[2]);
7324 ")
7325
7326 (define_expand "cbranchsf4"
7327 [(set (pc) (if_then_else
7328 (match_operator 0 "expandable_comparison_operator"
7329 [(match_operand:SF 1 "s_register_operand" "")
7330 (match_operand:SF 2 "vfp_compare_operand" "")])
7331 (label_ref (match_operand 3 "" ""))
7332 (pc)))]
7333 "TARGET_32BIT && TARGET_HARD_FLOAT"
7334 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7335 operands[3])); DONE;"
7336 )
7337
7338 (define_expand "cbranchdf4"
7339 [(set (pc) (if_then_else
7340 (match_operator 0 "expandable_comparison_operator"
7341 [(match_operand:DF 1 "s_register_operand" "")
7342 (match_operand:DF 2 "vfp_compare_operand" "")])
7343 (label_ref (match_operand 3 "" ""))
7344 (pc)))]
7345 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7346 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7347 operands[3])); DONE;"
7348 )
7349
7350 (define_expand "cbranchdi4"
7351 [(set (pc) (if_then_else
7352 (match_operator 0 "expandable_comparison_operator"
7353 [(match_operand:DI 1 "s_register_operand" "")
7354 (match_operand:DI 2 "cmpdi_operand" "")])
7355 (label_ref (match_operand 3 "" ""))
7356 (pc)))]
7357 "TARGET_32BIT"
7358 "{
7359 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7360 FAIL;
7361 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7362 operands[3]));
7363 DONE;
7364 }"
7365 )
7366
7367 ;; Comparison and test insns
7368
7369 (define_insn "*arm_cmpsi_insn"
7370 [(set (reg:CC CC_REGNUM)
7371 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7372 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7373 "TARGET_32BIT"
7374 "@
7375 cmp%?\\t%0, %1
7376 cmp%?\\t%0, %1
7377 cmp%?\\t%0, %1
7378 cmp%?\\t%0, %1
7379 cmn%?\\t%0, #%n1"
7380 [(set_attr "conds" "set")
7381 (set_attr "arch" "t2,t2,any,any,any")
7382 (set_attr "length" "2,2,4,4,4")
7383 (set_attr "predicable" "yes")
7384 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7385 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7386 )
7387
7388 (define_insn "*cmpsi_shiftsi"
7389 [(set (reg:CC CC_REGNUM)
7390 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7391 (match_operator:SI 3 "shift_operator"
7392 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7393 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7394 "TARGET_32BIT"
7395 "cmp\\t%0, %1%S3"
7396 [(set_attr "conds" "set")
7397 (set_attr "shift" "1")
7398 (set_attr "arch" "32,a,a")
7399 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7400
7401 (define_insn "*cmpsi_shiftsi_swp"
7402 [(set (reg:CC_SWP CC_REGNUM)
7403 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7404 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7405 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7406 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7407 "TARGET_32BIT"
7408 "cmp%?\\t%0, %1%S3"
7409 [(set_attr "conds" "set")
7410 (set_attr "shift" "1")
7411 (set_attr "arch" "32,a,a")
7412 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7413
7414 (define_insn "*arm_cmpsi_negshiftsi_si"
7415 [(set (reg:CC_Z CC_REGNUM)
7416 (compare:CC_Z
7417 (neg:SI (match_operator:SI 1 "shift_operator"
7418 [(match_operand:SI 2 "s_register_operand" "r")
7419 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7420 (match_operand:SI 0 "s_register_operand" "r")))]
7421 "TARGET_ARM"
7422 "cmn%?\\t%0, %2%S1"
7423 [(set_attr "conds" "set")
7424 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7425 (const_string "alus_shift_imm")
7426 (const_string "alus_shift_reg")))
7427 (set_attr "predicable" "yes")]
7428 )
7429
7430 ;; DImode comparisons. The generic code generates branches that
7431 ;; if-conversion cannot reduce to a conditional compare, so we do
7432 ;; that directly.
7433
7434 (define_insn_and_split "*arm_cmpdi_insn"
7435 [(set (reg:CC_NCV CC_REGNUM)
7436 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7437 (match_operand:DI 1 "arm_di_operand" "rDi")))
7438 (clobber (match_scratch:SI 2 "=r"))]
7439 "TARGET_32BIT"
7440 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7441 "&& reload_completed"
7442 [(set (reg:CC CC_REGNUM)
7443 (compare:CC (match_dup 0) (match_dup 1)))
7444 (parallel [(set (reg:CC CC_REGNUM)
7445 (compare:CC (match_dup 3) (match_dup 4)))
7446 (set (match_dup 2)
7447 (minus:SI (match_dup 5)
7448 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7449 {
7450 operands[3] = gen_highpart (SImode, operands[0]);
7451 operands[0] = gen_lowpart (SImode, operands[0]);
7452 if (CONST_INT_P (operands[1]))
7453 {
7454 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);
7455 if (operands[4] == const0_rtx)
7456 operands[5] = operands[3];
7457 else
7458 operands[5] = gen_rtx_PLUS (SImode, operands[3],
7459 gen_int_mode (-UINTVAL (operands[4]),
7460 SImode));
7461 }
7462 else
7463 {
7464 operands[4] = gen_highpart (SImode, operands[1]);
7465 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7466 }
7467 operands[1] = gen_lowpart (SImode, operands[1]);
7468 operands[2] = gen_lowpart (SImode, operands[2]);
7469 }
7470 [(set_attr "conds" "set")
7471 (set_attr "length" "8")
7472 (set_attr "type" "multiple")]
7473 )
7474
7475 (define_insn_and_split "*arm_cmpdi_unsigned"
7476 [(set (reg:CC_CZ CC_REGNUM)
7477 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7478 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7479
7480 "TARGET_32BIT"
7481 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7482 "&& reload_completed"
7483 [(set (reg:CC CC_REGNUM)
7484 (compare:CC (match_dup 2) (match_dup 3)))
7485 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7486 (set (reg:CC CC_REGNUM)
7487 (compare:CC (match_dup 0) (match_dup 1))))]
7488 {
7489 operands[2] = gen_highpart (SImode, operands[0]);
7490 operands[0] = gen_lowpart (SImode, operands[0]);
7491 if (CONST_INT_P (operands[1]))
7492 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7493 else
7494 operands[3] = gen_highpart (SImode, operands[1]);
7495 operands[1] = gen_lowpart (SImode, operands[1]);
7496 }
7497 [(set_attr "conds" "set")
7498 (set_attr "enabled_for_short_it" "yes,yes,no,*")
7499 (set_attr "arch" "t2,t2,t2,a")
7500 (set_attr "length" "6,6,10,8")
7501 (set_attr "type" "multiple")]
7502 )
7503
7504 (define_insn "*arm_cmpdi_zero"
7505 [(set (reg:CC_Z CC_REGNUM)
7506 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7507 (const_int 0)))
7508 (clobber (match_scratch:SI 1 "=r"))]
7509 "TARGET_32BIT"
7510 "orrs%?\\t%1, %Q0, %R0"
7511 [(set_attr "conds" "set")
7512 (set_attr "type" "logics_reg")]
7513 )
7514
7515 ; This insn allows redundant compares to be removed by cse, nothing should
7516 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7517 ; is deleted later on. The match_dup will match the mode here, so that
7518 ; mode changes of the condition codes aren't lost by this even though we don't
7519 ; specify what they are.
7520
7521 (define_insn "*deleted_compare"
7522 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7523 "TARGET_32BIT"
7524 "\\t%@ deleted compare"
7525 [(set_attr "conds" "set")
7526 (set_attr "length" "0")
7527 (set_attr "type" "no_insn")]
7528 )
7529
7530 \f
7531 ;; Conditional branch insns
7532
7533 (define_expand "cbranch_cc"
7534 [(set (pc)
7535 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7536 (match_operand 2 "" "")])
7537 (label_ref (match_operand 3 "" ""))
7538 (pc)))]
7539 "TARGET_32BIT"
7540 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7541 operands[1], operands[2], NULL_RTX);
7542 operands[2] = const0_rtx;"
7543 )
7544
7545 ;;
7546 ;; Patterns to match conditional branch insns.
7547 ;;
7548
7549 (define_insn "arm_cond_branch"
7550 [(set (pc)
7551 (if_then_else (match_operator 1 "arm_comparison_operator"
7552 [(match_operand 2 "cc_register" "") (const_int 0)])
7553 (label_ref (match_operand 0 "" ""))
7554 (pc)))]
7555 "TARGET_32BIT"
7556 "*
7557 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7558 {
7559 arm_ccfsm_state += 2;
7560 return \"\";
7561 }
7562 return \"b%d1\\t%l0\";
7563 "
7564 [(set_attr "conds" "use")
7565 (set_attr "type" "branch")
7566 (set (attr "length")
7567 (if_then_else
7568 (and (match_test "TARGET_THUMB2")
7569 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7570 (le (minus (match_dup 0) (pc)) (const_int 256))))
7571 (const_int 2)
7572 (const_int 4)))]
7573 )
7574
7575 (define_insn "*arm_cond_branch_reversed"
7576 [(set (pc)
7577 (if_then_else (match_operator 1 "arm_comparison_operator"
7578 [(match_operand 2 "cc_register" "") (const_int 0)])
7579 (pc)
7580 (label_ref (match_operand 0 "" ""))))]
7581 "TARGET_32BIT"
7582 "*
7583 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7584 {
7585 arm_ccfsm_state += 2;
7586 return \"\";
7587 }
7588 return \"b%D1\\t%l0\";
7589 "
7590 [(set_attr "conds" "use")
7591 (set_attr "type" "branch")
7592 (set (attr "length")
7593 (if_then_else
7594 (and (match_test "TARGET_THUMB2")
7595 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7596 (le (minus (match_dup 0) (pc)) (const_int 256))))
7597 (const_int 2)
7598 (const_int 4)))]
7599 )
7600
7601 \f
7602
7603 ; scc insns
7604
7605 (define_expand "cstore_cc"
7606 [(set (match_operand:SI 0 "s_register_operand" "")
7607 (match_operator:SI 1 "" [(match_operand 2 "" "")
7608 (match_operand 3 "" "")]))]
7609 "TARGET_32BIT"
7610 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7611 operands[2], operands[3], NULL_RTX);
7612 operands[3] = const0_rtx;"
7613 )
7614
7615 (define_insn_and_split "*mov_scc"
7616 [(set (match_operand:SI 0 "s_register_operand" "=r")
7617 (match_operator:SI 1 "arm_comparison_operator_mode"
7618 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7619 "TARGET_ARM"
7620 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7621 "TARGET_ARM"
7622 [(set (match_dup 0)
7623 (if_then_else:SI (match_dup 1)
7624 (const_int 1)
7625 (const_int 0)))]
7626 ""
7627 [(set_attr "conds" "use")
7628 (set_attr "length" "8")
7629 (set_attr "type" "multiple")]
7630 )
7631
7632 (define_insn_and_split "*mov_negscc"
7633 [(set (match_operand:SI 0 "s_register_operand" "=r")
7634 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7635 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7636 "TARGET_ARM"
7637 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7638 "TARGET_ARM"
7639 [(set (match_dup 0)
7640 (if_then_else:SI (match_dup 1)
7641 (match_dup 3)
7642 (const_int 0)))]
7643 {
7644 operands[3] = GEN_INT (~0);
7645 }
7646 [(set_attr "conds" "use")
7647 (set_attr "length" "8")
7648 (set_attr "type" "multiple")]
7649 )
7650
7651 (define_insn_and_split "*mov_notscc"
7652 [(set (match_operand:SI 0 "s_register_operand" "=r")
7653 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7654 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7655 "TARGET_ARM"
7656 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7657 "TARGET_ARM"
7658 [(set (match_dup 0)
7659 (if_then_else:SI (match_dup 1)
7660 (match_dup 3)
7661 (match_dup 4)))]
7662 {
7663 operands[3] = GEN_INT (~1);
7664 operands[4] = GEN_INT (~0);
7665 }
7666 [(set_attr "conds" "use")
7667 (set_attr "length" "8")
7668 (set_attr "type" "multiple")]
7669 )
7670
7671 (define_expand "cstoresi4"
7672 [(set (match_operand:SI 0 "s_register_operand" "")
7673 (match_operator:SI 1 "expandable_comparison_operator"
7674 [(match_operand:SI 2 "s_register_operand" "")
7675 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7676 "TARGET_32BIT || TARGET_THUMB1"
7677 "{
7678 rtx op3, scratch, scratch2;
7679
7680 if (!TARGET_THUMB1)
7681 {
7682 if (!arm_add_operand (operands[3], SImode))
7683 operands[3] = force_reg (SImode, operands[3]);
7684 emit_insn (gen_cstore_cc (operands[0], operands[1],
7685 operands[2], operands[3]));
7686 DONE;
7687 }
7688
7689 if (operands[3] == const0_rtx)
7690 {
7691 switch (GET_CODE (operands[1]))
7692 {
7693 case EQ:
7694 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7695 break;
7696
7697 case NE:
7698 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7699 break;
7700
7701 case LE:
7702 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7703 NULL_RTX, 0, OPTAB_WIDEN);
7704 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7705 NULL_RTX, 0, OPTAB_WIDEN);
7706 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7707 operands[0], 1, OPTAB_WIDEN);
7708 break;
7709
7710 case GE:
7711 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7712 NULL_RTX, 1);
7713 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7714 NULL_RTX, 1, OPTAB_WIDEN);
7715 break;
7716
7717 case GT:
7718 scratch = expand_binop (SImode, ashr_optab, operands[2],
7719 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7720 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7721 NULL_RTX, 0, OPTAB_WIDEN);
7722 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7723 0, OPTAB_WIDEN);
7724 break;
7725
7726 /* LT is handled by generic code. No need for unsigned with 0. */
7727 default:
7728 FAIL;
7729 }
7730 DONE;
7731 }
7732
7733 switch (GET_CODE (operands[1]))
7734 {
7735 case EQ:
7736 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7737 NULL_RTX, 0, OPTAB_WIDEN);
7738 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7739 break;
7740
7741 case NE:
7742 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7743 NULL_RTX, 0, OPTAB_WIDEN);
7744 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7745 break;
7746
7747 case LE:
7748 op3 = force_reg (SImode, operands[3]);
7749
7750 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7751 NULL_RTX, 1, OPTAB_WIDEN);
7752 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7753 NULL_RTX, 0, OPTAB_WIDEN);
7754 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7755 op3, operands[2]));
7756 break;
7757
7758 case GE:
7759 op3 = operands[3];
7760 if (!thumb1_cmp_operand (op3, SImode))
7761 op3 = force_reg (SImode, op3);
7762 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7763 NULL_RTX, 0, OPTAB_WIDEN);
7764 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7765 NULL_RTX, 1, OPTAB_WIDEN);
7766 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7767 operands[2], op3));
7768 break;
7769
7770 case LEU:
7771 op3 = force_reg (SImode, operands[3]);
7772 scratch = force_reg (SImode, const0_rtx);
7773 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7774 op3, operands[2]));
7775 break;
7776
7777 case GEU:
7778 op3 = operands[3];
7779 if (!thumb1_cmp_operand (op3, SImode))
7780 op3 = force_reg (SImode, op3);
7781 scratch = force_reg (SImode, const0_rtx);
7782 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7783 operands[2], op3));
7784 break;
7785
7786 case LTU:
7787 op3 = operands[3];
7788 if (!thumb1_cmp_operand (op3, SImode))
7789 op3 = force_reg (SImode, op3);
7790 scratch = gen_reg_rtx (SImode);
7791 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7792 break;
7793
7794 case GTU:
7795 op3 = force_reg (SImode, operands[3]);
7796 scratch = gen_reg_rtx (SImode);
7797 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7798 break;
7799
7800 /* No good sequences for GT, LT. */
7801 default:
7802 FAIL;
7803 }
7804 DONE;
7805 }")
7806
7807 (define_expand "cstorehf4"
7808 [(set (match_operand:SI 0 "s_register_operand")
7809 (match_operator:SI 1 "expandable_comparison_operator"
7810 [(match_operand:HF 2 "s_register_operand")
7811 (match_operand:HF 3 "vfp_compare_operand")]))]
7812 "TARGET_VFP_FP16INST"
7813 {
7814 if (!arm_validize_comparison (&operands[1],
7815 &operands[2],
7816 &operands[3]))
7817 FAIL;
7818
7819 emit_insn (gen_cstore_cc (operands[0], operands[1],
7820 operands[2], operands[3]));
7821 DONE;
7822 }
7823 )
7824
7825 (define_expand "cstoresf4"
7826 [(set (match_operand:SI 0 "s_register_operand" "")
7827 (match_operator:SI 1 "expandable_comparison_operator"
7828 [(match_operand:SF 2 "s_register_operand" "")
7829 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7830 "TARGET_32BIT && TARGET_HARD_FLOAT"
7831 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7832 operands[2], operands[3])); DONE;"
7833 )
7834
7835 (define_expand "cstoredf4"
7836 [(set (match_operand:SI 0 "s_register_operand" "")
7837 (match_operator:SI 1 "expandable_comparison_operator"
7838 [(match_operand:DF 2 "s_register_operand" "")
7839 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7840 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7841 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7842 operands[2], operands[3])); DONE;"
7843 )
7844
7845 (define_expand "cstoredi4"
7846 [(set (match_operand:SI 0 "s_register_operand" "")
7847 (match_operator:SI 1 "expandable_comparison_operator"
7848 [(match_operand:DI 2 "s_register_operand" "")
7849 (match_operand:DI 3 "cmpdi_operand" "")]))]
7850 "TARGET_32BIT"
7851 "{
7852 if (!arm_validize_comparison (&operands[1],
7853 &operands[2],
7854 &operands[3]))
7855 FAIL;
7856 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7857 operands[3]));
7858 DONE;
7859 }"
7860 )
7861
7862 \f
7863 ;; Conditional move insns
7864
7865 (define_expand "movsicc"
7866 [(set (match_operand:SI 0 "s_register_operand" "")
7867 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7868 (match_operand:SI 2 "arm_not_operand" "")
7869 (match_operand:SI 3 "arm_not_operand" "")))]
7870 "TARGET_32BIT"
7871 "
7872 {
7873 enum rtx_code code;
7874 rtx ccreg;
7875
7876 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7877 &XEXP (operands[1], 1)))
7878 FAIL;
7879
7880 code = GET_CODE (operands[1]);
7881 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7882 XEXP (operands[1], 1), NULL_RTX);
7883 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7884 }"
7885 )
7886
7887 (define_expand "movhfcc"
7888 [(set (match_operand:HF 0 "s_register_operand")
7889 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7890 (match_operand:HF 2 "s_register_operand")
7891 (match_operand:HF 3 "s_register_operand")))]
7892 "TARGET_VFP_FP16INST"
7893 "
7894 {
7895 enum rtx_code code = GET_CODE (operands[1]);
7896 rtx ccreg;
7897
7898 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7899 &XEXP (operands[1], 1)))
7900 FAIL;
7901
7902 code = GET_CODE (operands[1]);
7903 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7904 XEXP (operands[1], 1), NULL_RTX);
7905 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7906 }"
7907 )
7908
7909 (define_expand "movsfcc"
7910 [(set (match_operand:SF 0 "s_register_operand" "")
7911 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7912 (match_operand:SF 2 "s_register_operand" "")
7913 (match_operand:SF 3 "s_register_operand" "")))]
7914 "TARGET_32BIT && TARGET_HARD_FLOAT"
7915 "
7916 {
7917 enum rtx_code code = GET_CODE (operands[1]);
7918 rtx ccreg;
7919
7920 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7921 &XEXP (operands[1], 1)))
7922 FAIL;
7923
7924 code = GET_CODE (operands[1]);
7925 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7926 XEXP (operands[1], 1), NULL_RTX);
7927 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7928 }"
7929 )
7930
7931 (define_expand "movdfcc"
7932 [(set (match_operand:DF 0 "s_register_operand" "")
7933 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7934 (match_operand:DF 2 "s_register_operand" "")
7935 (match_operand:DF 3 "s_register_operand" "")))]
7936 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7937 "
7938 {
7939 enum rtx_code code = GET_CODE (operands[1]);
7940 rtx ccreg;
7941
7942 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7943 &XEXP (operands[1], 1)))
7944 FAIL;
7945 code = GET_CODE (operands[1]);
7946 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7947 XEXP (operands[1], 1), NULL_RTX);
7948 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7949 }"
7950 )
7951
7952 (define_insn "*cmov<mode>"
7953 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7954 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7955 [(match_operand 2 "cc_register" "") (const_int 0)])
7956 (match_operand:SDF 3 "s_register_operand"
7957 "<F_constraint>")
7958 (match_operand:SDF 4 "s_register_operand"
7959 "<F_constraint>")))]
7960 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7961 "*
7962 {
7963 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7964 switch (code)
7965 {
7966 case ARM_GE:
7967 case ARM_GT:
7968 case ARM_EQ:
7969 case ARM_VS:
7970 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7971 case ARM_LT:
7972 case ARM_LE:
7973 case ARM_NE:
7974 case ARM_VC:
7975 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7976 default:
7977 gcc_unreachable ();
7978 }
7979 return \"\";
7980 }"
7981 [(set_attr "conds" "use")
7982 (set_attr "type" "fcsel")]
7983 )
7984
7985 (define_insn "*cmovhf"
7986 [(set (match_operand:HF 0 "s_register_operand" "=t")
7987 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7988 [(match_operand 2 "cc_register" "") (const_int 0)])
7989 (match_operand:HF 3 "s_register_operand" "t")
7990 (match_operand:HF 4 "s_register_operand" "t")))]
7991 "TARGET_VFP_FP16INST"
7992 "*
7993 {
7994 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7995 switch (code)
7996 {
7997 case ARM_GE:
7998 case ARM_GT:
7999 case ARM_EQ:
8000 case ARM_VS:
8001 return \"vsel%d1.f16\\t%0, %3, %4\";
8002 case ARM_LT:
8003 case ARM_LE:
8004 case ARM_NE:
8005 case ARM_VC:
8006 return \"vsel%D1.f16\\t%0, %4, %3\";
8007 default:
8008 gcc_unreachable ();
8009 }
8010 return \"\";
8011 }"
8012 [(set_attr "conds" "use")
8013 (set_attr "type" "fcsel")]
8014 )
8015
8016 (define_insn_and_split "*movsicc_insn"
8017 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8018 (if_then_else:SI
8019 (match_operator 3 "arm_comparison_operator"
8020 [(match_operand 4 "cc_register" "") (const_int 0)])
8021 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8022 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8023 "TARGET_ARM"
8024 "@
8025 mov%D3\\t%0, %2
8026 mvn%D3\\t%0, #%B2
8027 mov%d3\\t%0, %1
8028 mvn%d3\\t%0, #%B1
8029 #
8030 #
8031 #
8032 #"
8033 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8034 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8035 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8036 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8037 "&& reload_completed"
8038 [(const_int 0)]
8039 {
8040 enum rtx_code rev_code;
8041 machine_mode mode;
8042 rtx rev_cond;
8043
8044 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8045 operands[3],
8046 gen_rtx_SET (operands[0], operands[1])));
8047
8048 rev_code = GET_CODE (operands[3]);
8049 mode = GET_MODE (operands[4]);
8050 if (mode == CCFPmode || mode == CCFPEmode)
8051 rev_code = reverse_condition_maybe_unordered (rev_code);
8052 else
8053 rev_code = reverse_condition (rev_code);
8054
8055 rev_cond = gen_rtx_fmt_ee (rev_code,
8056 VOIDmode,
8057 operands[4],
8058 const0_rtx);
8059 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8060 rev_cond,
8061 gen_rtx_SET (operands[0], operands[2])));
8062 DONE;
8063 }
8064 [(set_attr "length" "4,4,4,4,8,8,8,8")
8065 (set_attr "conds" "use")
8066 (set_attr_alternative "type"
8067 [(if_then_else (match_operand 2 "const_int_operand" "")
8068 (const_string "mov_imm")
8069 (const_string "mov_reg"))
8070 (const_string "mvn_imm")
8071 (if_then_else (match_operand 1 "const_int_operand" "")
8072 (const_string "mov_imm")
8073 (const_string "mov_reg"))
8074 (const_string "mvn_imm")
8075 (const_string "multiple")
8076 (const_string "multiple")
8077 (const_string "multiple")
8078 (const_string "multiple")])]
8079 )
8080
8081 (define_insn "*movsfcc_soft_insn"
8082 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8083 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8084 [(match_operand 4 "cc_register" "") (const_int 0)])
8085 (match_operand:SF 1 "s_register_operand" "0,r")
8086 (match_operand:SF 2 "s_register_operand" "r,0")))]
8087 "TARGET_ARM && TARGET_SOFT_FLOAT"
8088 "@
8089 mov%D3\\t%0, %2
8090 mov%d3\\t%0, %1"
8091 [(set_attr "conds" "use")
8092 (set_attr "type" "mov_reg")]
8093 )
8094
8095 \f
8096 ;; Jump and linkage insns
8097
8098 (define_expand "jump"
8099 [(set (pc)
8100 (label_ref (match_operand 0 "" "")))]
8101 "TARGET_EITHER"
8102 ""
8103 )
8104
8105 (define_insn "*arm_jump"
8106 [(set (pc)
8107 (label_ref (match_operand 0 "" "")))]
8108 "TARGET_32BIT"
8109 "*
8110 {
8111 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8112 {
8113 arm_ccfsm_state += 2;
8114 return \"\";
8115 }
8116 return \"b%?\\t%l0\";
8117 }
8118 "
8119 [(set_attr "predicable" "yes")
8120 (set (attr "length")
8121 (if_then_else
8122 (and (match_test "TARGET_THUMB2")
8123 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8124 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8125 (const_int 2)
8126 (const_int 4)))
8127 (set_attr "type" "branch")]
8128 )
8129
8130 (define_expand "call"
8131 [(parallel [(call (match_operand 0 "memory_operand" "")
8132 (match_operand 1 "general_operand" ""))
8133 (use (match_operand 2 "" ""))
8134 (clobber (reg:SI LR_REGNUM))])]
8135 "TARGET_EITHER"
8136 "
8137 {
8138 rtx callee, pat;
8139 tree addr = MEM_EXPR (operands[0]);
8140
8141 /* In an untyped call, we can get NULL for operand 2. */
8142 if (operands[2] == NULL_RTX)
8143 operands[2] = const0_rtx;
8144
8145 /* Decide if we should generate indirect calls by loading the
8146 32-bit address of the callee into a register before performing the
8147 branch and link. */
8148 callee = XEXP (operands[0], 0);
8149 if (GET_CODE (callee) == SYMBOL_REF
8150 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8151 : !REG_P (callee))
8152 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8153
8154 if (detect_cmse_nonsecure_call (addr))
8155 {
8156 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8157 operands[2]);
8158 emit_call_insn (pat);
8159 }
8160 else
8161 {
8162 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8163 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8164 }
8165 DONE;
8166 }"
8167 )
8168
8169 (define_expand "call_internal"
8170 [(parallel [(call (match_operand 0 "memory_operand" "")
8171 (match_operand 1 "general_operand" ""))
8172 (use (match_operand 2 "" ""))
8173 (clobber (reg:SI LR_REGNUM))])])
8174
8175 (define_expand "nonsecure_call_internal"
8176 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8177 UNSPEC_NONSECURE_MEM)
8178 (match_operand 1 "general_operand" ""))
8179 (use (match_operand 2 "" ""))
8180 (clobber (reg:SI LR_REGNUM))])]
8181 "use_cmse"
8182 "
8183 {
8184 rtx tmp;
8185 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8186 gen_rtx_REG (SImode, R4_REGNUM),
8187 SImode);
8188
8189 operands[0] = replace_equiv_address (operands[0], tmp);
8190 }")
8191
8192 (define_insn "*call_reg_armv5"
8193 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8194 (match_operand 1 "" ""))
8195 (use (match_operand 2 "" ""))
8196 (clobber (reg:SI LR_REGNUM))]
8197 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8198 "blx%?\\t%0"
8199 [(set_attr "type" "call")]
8200 )
8201
8202 (define_insn "*call_reg_arm"
8203 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8204 (match_operand 1 "" ""))
8205 (use (match_operand 2 "" ""))
8206 (clobber (reg:SI LR_REGNUM))]
8207 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8208 "*
8209 return output_call (operands);
8210 "
8211 ;; length is worst case, normally it is only two
8212 [(set_attr "length" "12")
8213 (set_attr "type" "call")]
8214 )
8215
8216
8217 (define_expand "call_value"
8218 [(parallel [(set (match_operand 0 "" "")
8219 (call (match_operand 1 "memory_operand" "")
8220 (match_operand 2 "general_operand" "")))
8221 (use (match_operand 3 "" ""))
8222 (clobber (reg:SI LR_REGNUM))])]
8223 "TARGET_EITHER"
8224 "
8225 {
8226 rtx pat, callee;
8227 tree addr = MEM_EXPR (operands[1]);
8228
8229 /* In an untyped call, we can get NULL for operand 2. */
8230 if (operands[3] == 0)
8231 operands[3] = const0_rtx;
8232
8233 /* Decide if we should generate indirect calls by loading the
8234 32-bit address of the callee into a register before performing the
8235 branch and link. */
8236 callee = XEXP (operands[1], 0);
8237 if (GET_CODE (callee) == SYMBOL_REF
8238 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8239 : !REG_P (callee))
8240 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8241
8242 if (detect_cmse_nonsecure_call (addr))
8243 {
8244 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8245 operands[2], operands[3]);
8246 emit_call_insn (pat);
8247 }
8248 else
8249 {
8250 pat = gen_call_value_internal (operands[0], operands[1],
8251 operands[2], operands[3]);
8252 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8253 }
8254 DONE;
8255 }"
8256 )
8257
8258 (define_expand "call_value_internal"
8259 [(parallel [(set (match_operand 0 "" "")
8260 (call (match_operand 1 "memory_operand" "")
8261 (match_operand 2 "general_operand" "")))
8262 (use (match_operand 3 "" ""))
8263 (clobber (reg:SI LR_REGNUM))])])
8264
8265 (define_expand "nonsecure_call_value_internal"
8266 [(parallel [(set (match_operand 0 "" "")
8267 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8268 UNSPEC_NONSECURE_MEM)
8269 (match_operand 2 "general_operand" "")))
8270 (use (match_operand 3 "" ""))
8271 (clobber (reg:SI LR_REGNUM))])]
8272 "use_cmse"
8273 "
8274 {
8275 rtx tmp;
8276 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8277 gen_rtx_REG (SImode, R4_REGNUM),
8278 SImode);
8279
8280 operands[1] = replace_equiv_address (operands[1], tmp);
8281 }")
8282
8283 (define_insn "*call_value_reg_armv5"
8284 [(set (match_operand 0 "" "")
8285 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8286 (match_operand 2 "" "")))
8287 (use (match_operand 3 "" ""))
8288 (clobber (reg:SI LR_REGNUM))]
8289 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8290 "blx%?\\t%1"
8291 [(set_attr "type" "call")]
8292 )
8293
8294 (define_insn "*call_value_reg_arm"
8295 [(set (match_operand 0 "" "")
8296 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8297 (match_operand 2 "" "")))
8298 (use (match_operand 3 "" ""))
8299 (clobber (reg:SI LR_REGNUM))]
8300 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8301 "*
8302 return output_call (&operands[1]);
8303 "
8304 [(set_attr "length" "12")
8305 (set_attr "type" "call")]
8306 )
8307
8308 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8309 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8310
8311 (define_insn "*call_symbol"
8312 [(call (mem:SI (match_operand:SI 0 "" ""))
8313 (match_operand 1 "" ""))
8314 (use (match_operand 2 "" ""))
8315 (clobber (reg:SI LR_REGNUM))]
8316 "TARGET_32BIT
8317 && !SIBLING_CALL_P (insn)
8318 && (GET_CODE (operands[0]) == SYMBOL_REF)
8319 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8320 "*
8321 {
8322 rtx op = operands[0];
8323
8324 /* Switch mode now when possible. */
8325 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8326 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8327 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8328
8329 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8330 }"
8331 [(set_attr "type" "call")]
8332 )
8333
8334 (define_insn "*call_value_symbol"
8335 [(set (match_operand 0 "" "")
8336 (call (mem:SI (match_operand:SI 1 "" ""))
8337 (match_operand:SI 2 "" "")))
8338 (use (match_operand 3 "" ""))
8339 (clobber (reg:SI LR_REGNUM))]
8340 "TARGET_32BIT
8341 && !SIBLING_CALL_P (insn)
8342 && (GET_CODE (operands[1]) == SYMBOL_REF)
8343 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8344 "*
8345 {
8346 rtx op = operands[1];
8347
8348 /* Switch mode now when possible. */
8349 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8350 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8351 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8352
8353 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8354 }"
8355 [(set_attr "type" "call")]
8356 )
8357
8358 (define_expand "sibcall_internal"
8359 [(parallel [(call (match_operand 0 "memory_operand" "")
8360 (match_operand 1 "general_operand" ""))
8361 (return)
8362 (use (match_operand 2 "" ""))])])
8363
8364 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8365 (define_expand "sibcall"
8366 [(parallel [(call (match_operand 0 "memory_operand" "")
8367 (match_operand 1 "general_operand" ""))
8368 (return)
8369 (use (match_operand 2 "" ""))])]
8370 "TARGET_32BIT"
8371 "
8372 {
8373 rtx pat;
8374
8375 if ((!REG_P (XEXP (operands[0], 0))
8376 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8377 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8378 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8379 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8380
8381 if (operands[2] == NULL_RTX)
8382 operands[2] = const0_rtx;
8383
8384 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8385 arm_emit_call_insn (pat, operands[0], true);
8386 DONE;
8387 }"
8388 )
8389
8390 (define_expand "sibcall_value_internal"
8391 [(parallel [(set (match_operand 0 "" "")
8392 (call (match_operand 1 "memory_operand" "")
8393 (match_operand 2 "general_operand" "")))
8394 (return)
8395 (use (match_operand 3 "" ""))])])
8396
8397 (define_expand "sibcall_value"
8398 [(parallel [(set (match_operand 0 "" "")
8399 (call (match_operand 1 "memory_operand" "")
8400 (match_operand 2 "general_operand" "")))
8401 (return)
8402 (use (match_operand 3 "" ""))])]
8403 "TARGET_32BIT"
8404 "
8405 {
8406 rtx pat;
8407
8408 if ((!REG_P (XEXP (operands[1], 0))
8409 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8410 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8411 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8412 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8413
8414 if (operands[3] == NULL_RTX)
8415 operands[3] = const0_rtx;
8416
8417 pat = gen_sibcall_value_internal (operands[0], operands[1],
8418 operands[2], operands[3]);
8419 arm_emit_call_insn (pat, operands[1], true);
8420 DONE;
8421 }"
8422 )
8423
8424 (define_insn "*sibcall_insn"
8425 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8426 (match_operand 1 "" ""))
8427 (return)
8428 (use (match_operand 2 "" ""))]
8429 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8430 "*
8431 if (which_alternative == 1)
8432 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8433 else
8434 {
8435 if (arm_arch5t || arm_arch4t)
8436 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8437 else
8438 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8439 }
8440 "
8441 [(set_attr "type" "call")]
8442 )
8443
8444 (define_insn "*sibcall_value_insn"
8445 [(set (match_operand 0 "" "")
8446 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8447 (match_operand 2 "" "")))
8448 (return)
8449 (use (match_operand 3 "" ""))]
8450 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8451 "*
8452 if (which_alternative == 1)
8453 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8454 else
8455 {
8456 if (arm_arch5t || arm_arch4t)
8457 return \"bx%?\\t%1\";
8458 else
8459 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8460 }
8461 "
8462 [(set_attr "type" "call")]
8463 )
8464
8465 (define_expand "<return_str>return"
8466 [(RETURNS)]
8467 "(TARGET_ARM || (TARGET_THUMB2
8468 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8469 && !IS_STACKALIGN (arm_current_func_type ())))
8470 <return_cond_false>"
8471 "
8472 {
8473 if (TARGET_THUMB2)
8474 {
8475 thumb2_expand_return (<return_simple_p>);
8476 DONE;
8477 }
8478 }
8479 "
8480 )
8481
8482 ;; Often the return insn will be the same as loading from memory, so set attr
8483 (define_insn "*arm_return"
8484 [(return)]
8485 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8486 "*
8487 {
8488 if (arm_ccfsm_state == 2)
8489 {
8490 arm_ccfsm_state += 2;
8491 return \"\";
8492 }
8493 return output_return_instruction (const_true_rtx, true, false, false);
8494 }"
8495 [(set_attr "type" "load_4")
8496 (set_attr "length" "12")
8497 (set_attr "predicable" "yes")]
8498 )
8499
8500 (define_insn "*cond_<return_str>return"
8501 [(set (pc)
8502 (if_then_else (match_operator 0 "arm_comparison_operator"
8503 [(match_operand 1 "cc_register" "") (const_int 0)])
8504 (RETURNS)
8505 (pc)))]
8506 "TARGET_ARM <return_cond_true>"
8507 "*
8508 {
8509 if (arm_ccfsm_state == 2)
8510 {
8511 arm_ccfsm_state += 2;
8512 return \"\";
8513 }
8514 return output_return_instruction (operands[0], true, false,
8515 <return_simple_p>);
8516 }"
8517 [(set_attr "conds" "use")
8518 (set_attr "length" "12")
8519 (set_attr "type" "load_4")]
8520 )
8521
8522 (define_insn "*cond_<return_str>return_inverted"
8523 [(set (pc)
8524 (if_then_else (match_operator 0 "arm_comparison_operator"
8525 [(match_operand 1 "cc_register" "") (const_int 0)])
8526 (pc)
8527 (RETURNS)))]
8528 "TARGET_ARM <return_cond_true>"
8529 "*
8530 {
8531 if (arm_ccfsm_state == 2)
8532 {
8533 arm_ccfsm_state += 2;
8534 return \"\";
8535 }
8536 return output_return_instruction (operands[0], true, true,
8537 <return_simple_p>);
8538 }"
8539 [(set_attr "conds" "use")
8540 (set_attr "length" "12")
8541 (set_attr "type" "load_4")]
8542 )
8543
8544 (define_insn "*arm_simple_return"
8545 [(simple_return)]
8546 "TARGET_ARM"
8547 "*
8548 {
8549 if (arm_ccfsm_state == 2)
8550 {
8551 arm_ccfsm_state += 2;
8552 return \"\";
8553 }
8554 return output_return_instruction (const_true_rtx, true, false, true);
8555 }"
8556 [(set_attr "type" "branch")
8557 (set_attr "length" "4")
8558 (set_attr "predicable" "yes")]
8559 )
8560
8561 ;; Generate a sequence of instructions to determine if the processor is
8562 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8563 ;; mask.
8564
8565 (define_expand "return_addr_mask"
8566 [(set (match_dup 1)
8567 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8568 (const_int 0)))
8569 (set (match_operand:SI 0 "s_register_operand" "")
8570 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8571 (const_int -1)
8572 (const_int 67108860)))] ; 0x03fffffc
8573 "TARGET_ARM"
8574 "
8575 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8576 ")
8577
8578 (define_insn "*check_arch2"
8579 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8580 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8581 (const_int 0)))]
8582 "TARGET_ARM"
8583 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8584 [(set_attr "length" "8")
8585 (set_attr "conds" "set")
8586 (set_attr "type" "multiple")]
8587 )
8588
8589 ;; Call subroutine returning any type.
8590
8591 (define_expand "untyped_call"
8592 [(parallel [(call (match_operand 0 "" "")
8593 (const_int 0))
8594 (match_operand 1 "" "")
8595 (match_operand 2 "" "")])]
8596 "TARGET_EITHER"
8597 "
8598 {
8599 int i;
8600 rtx par = gen_rtx_PARALLEL (VOIDmode,
8601 rtvec_alloc (XVECLEN (operands[2], 0)));
8602 rtx addr = gen_reg_rtx (Pmode);
8603 rtx mem;
8604 int size = 0;
8605
8606 emit_move_insn (addr, XEXP (operands[1], 0));
8607 mem = change_address (operands[1], BLKmode, addr);
8608
8609 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8610 {
8611 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8612
8613 /* Default code only uses r0 as a return value, but we could
8614 be using anything up to 4 registers. */
8615 if (REGNO (src) == R0_REGNUM)
8616 src = gen_rtx_REG (TImode, R0_REGNUM);
8617
8618 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8619 GEN_INT (size));
8620 size += GET_MODE_SIZE (GET_MODE (src));
8621 }
8622
8623 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8624
8625 size = 0;
8626
8627 for (i = 0; i < XVECLEN (par, 0); i++)
8628 {
8629 HOST_WIDE_INT offset = 0;
8630 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8631
8632 if (size != 0)
8633 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8634
8635 mem = change_address (mem, GET_MODE (reg), NULL);
8636 if (REGNO (reg) == R0_REGNUM)
8637 {
8638 /* On thumb we have to use a write-back instruction. */
8639 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8640 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8641 size = TARGET_ARM ? 16 : 0;
8642 }
8643 else
8644 {
8645 emit_move_insn (mem, reg);
8646 size = GET_MODE_SIZE (GET_MODE (reg));
8647 }
8648 }
8649
8650 /* The optimizer does not know that the call sets the function value
8651 registers we stored in the result block. We avoid problems by
8652 claiming that all hard registers are used and clobbered at this
8653 point. */
8654 emit_insn (gen_blockage ());
8655
8656 DONE;
8657 }"
8658 )
8659
8660 (define_expand "untyped_return"
8661 [(match_operand:BLK 0 "memory_operand" "")
8662 (match_operand 1 "" "")]
8663 "TARGET_EITHER"
8664 "
8665 {
8666 int i;
8667 rtx addr = gen_reg_rtx (Pmode);
8668 rtx mem;
8669 int size = 0;
8670
8671 emit_move_insn (addr, XEXP (operands[0], 0));
8672 mem = change_address (operands[0], BLKmode, addr);
8673
8674 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8675 {
8676 HOST_WIDE_INT offset = 0;
8677 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8678
8679 if (size != 0)
8680 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8681
8682 mem = change_address (mem, GET_MODE (reg), NULL);
8683 if (REGNO (reg) == R0_REGNUM)
8684 {
8685 /* On thumb we have to use a write-back instruction. */
8686 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8687 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8688 size = TARGET_ARM ? 16 : 0;
8689 }
8690 else
8691 {
8692 emit_move_insn (reg, mem);
8693 size = GET_MODE_SIZE (GET_MODE (reg));
8694 }
8695 }
8696
8697 /* Emit USE insns before the return. */
8698 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8699 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8700
8701 /* Construct the return. */
8702 expand_naked_return ();
8703
8704 DONE;
8705 }"
8706 )
8707
8708 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8709 ;; all of memory. This blocks insns from being moved across this point.
8710
8711 (define_insn "blockage"
8712 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8713 "TARGET_EITHER"
8714 ""
8715 [(set_attr "length" "0")
8716 (set_attr "type" "block")]
8717 )
8718
8719 ;; Since we hard code r0 here use the 'o' constraint to prevent
8720 ;; provoking undefined behaviour in the hardware with putting out
8721 ;; auto-increment operations with potentially r0 as the base register.
8722 (define_insn "probe_stack"
8723 [(set (match_operand:SI 0 "memory_operand" "=o")
8724 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8725 "TARGET_32BIT"
8726 "str%?\\tr0, %0"
8727 [(set_attr "type" "store_4")
8728 (set_attr "predicable" "yes")]
8729 )
8730
8731 (define_insn "probe_stack_range"
8732 [(set (match_operand:SI 0 "register_operand" "=r")
8733 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8734 (match_operand:SI 2 "register_operand" "r")]
8735 VUNSPEC_PROBE_STACK_RANGE))]
8736 "TARGET_32BIT"
8737 {
8738 return output_probe_stack_range (operands[0], operands[2]);
8739 }
8740 [(set_attr "type" "multiple")
8741 (set_attr "conds" "clob")]
8742 )
8743
8744 ;; Named patterns for stack smashing protection.
8745 (define_expand "stack_protect_combined_set"
8746 [(parallel
8747 [(set (match_operand:SI 0 "memory_operand" "")
8748 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8749 UNSPEC_SP_SET))
8750 (clobber (match_scratch:SI 2 ""))
8751 (clobber (match_scratch:SI 3 ""))])]
8752 ""
8753 ""
8754 )
8755
8756 ;; Use a separate insn from the above expand to be able to have the mem outside
8757 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8758 ;; try to reload the guard since we need to control how PIC access is done in
8759 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8760 ;; legitimize_pic_address ()).
8761 (define_insn_and_split "*stack_protect_combined_set_insn"
8762 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8763 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8764 UNSPEC_SP_SET))
8765 (clobber (match_scratch:SI 2 "=&l,&r"))
8766 (clobber (match_scratch:SI 3 "=&l,&r"))]
8767 ""
8768 "#"
8769 "reload_completed"
8770 [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))]
8771 UNSPEC_SP_SET))
8772 (clobber (match_dup 2))])]
8773 "
8774 {
8775 if (flag_pic)
8776 {
8777 /* Forces recomputing of GOT base now. */
8778 legitimize_pic_address (operands[1], SImode, operands[2], operands[3],
8779 true /*compute_now*/);
8780 }
8781 else
8782 {
8783 if (address_operand (operands[1], SImode))
8784 operands[2] = operands[1];
8785 else
8786 {
8787 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8788 emit_move_insn (operands[2], mem);
8789 }
8790 }
8791 }"
8792 [(set_attr "arch" "t1,32")]
8793 )
8794
8795 (define_insn "*stack_protect_set_insn"
8796 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8797 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))]
8798 UNSPEC_SP_SET))
8799 (clobber (match_dup 1))]
8800 ""
8801 "@
8802 ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1,#0
8803 ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1,#0"
8804 [(set_attr "length" "8,12")
8805 (set_attr "conds" "clob,nocond")
8806 (set_attr "type" "multiple")
8807 (set_attr "arch" "t1,32")]
8808 )
8809
8810 (define_expand "stack_protect_combined_test"
8811 [(parallel
8812 [(set (pc)
8813 (if_then_else
8814 (eq (match_operand:SI 0 "memory_operand" "")
8815 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8816 UNSPEC_SP_TEST))
8817 (label_ref (match_operand 2))
8818 (pc)))
8819 (clobber (match_scratch:SI 3 ""))
8820 (clobber (match_scratch:SI 4 ""))
8821 (clobber (reg:CC CC_REGNUM))])]
8822 ""
8823 ""
8824 )
8825
8826 ;; Use a separate insn from the above expand to be able to have the mem outside
8827 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8828 ;; try to reload the guard since we need to control how PIC access is done in
8829 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8830 ;; legitimize_pic_address ()).
8831 (define_insn_and_split "*stack_protect_combined_test_insn"
8832 [(set (pc)
8833 (if_then_else
8834 (eq (match_operand:SI 0 "memory_operand" "m,m")
8835 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8836 UNSPEC_SP_TEST))
8837 (label_ref (match_operand 2))
8838 (pc)))
8839 (clobber (match_scratch:SI 3 "=&l,&r"))
8840 (clobber (match_scratch:SI 4 "=&l,&r"))
8841 (clobber (reg:CC CC_REGNUM))]
8842 ""
8843 "#"
8844 "reload_completed"
8845 [(const_int 0)]
8846 {
8847 rtx eq;
8848
8849 if (flag_pic)
8850 {
8851 /* Forces recomputing of GOT base now. */
8852 legitimize_pic_address (operands[1], SImode, operands[3], operands[4],
8853 true /*compute_now*/);
8854 }
8855 else
8856 {
8857 if (address_operand (operands[1], SImode))
8858 operands[3] = operands[1];
8859 else
8860 {
8861 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8862 emit_move_insn (operands[3], mem);
8863 }
8864 }
8865 if (TARGET_32BIT)
8866 {
8867 emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0],
8868 operands[3]));
8869 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
8870 eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx);
8871 emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg));
8872 }
8873 else
8874 {
8875 emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0],
8876 operands[3]));
8877 eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
8878 emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx,
8879 operands[2]));
8880 }
8881 DONE;
8882 }
8883 [(set_attr "arch" "t1,32")]
8884 )
8885
8886 (define_insn "arm_stack_protect_test_insn"
8887 [(set (reg:CC_Z CC_REGNUM)
8888 (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m")
8889 (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))]
8890 UNSPEC_SP_TEST)
8891 (const_int 0)))
8892 (clobber (match_operand:SI 0 "register_operand" "=&l,&r"))
8893 (clobber (match_dup 2))]
8894 "TARGET_32BIT"
8895 "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0"
8896 [(set_attr "length" "8,12")
8897 (set_attr "conds" "set")
8898 (set_attr "type" "multiple")
8899 (set_attr "arch" "t,32")]
8900 )
8901
8902 (define_expand "casesi"
8903 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8904 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8905 (match_operand:SI 2 "const_int_operand" "") ; total range
8906 (match_operand:SI 3 "" "") ; table label
8907 (match_operand:SI 4 "" "")] ; Out of range label
8908 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8909 "
8910 {
8911 enum insn_code code;
8912 if (operands[1] != const0_rtx)
8913 {
8914 rtx reg = gen_reg_rtx (SImode);
8915
8916 emit_insn (gen_addsi3 (reg, operands[0],
8917 gen_int_mode (-INTVAL (operands[1]),
8918 SImode)));
8919 operands[0] = reg;
8920 }
8921
8922 if (TARGET_ARM)
8923 code = CODE_FOR_arm_casesi_internal;
8924 else if (TARGET_THUMB1)
8925 code = CODE_FOR_thumb1_casesi_internal_pic;
8926 else if (flag_pic)
8927 code = CODE_FOR_thumb2_casesi_internal_pic;
8928 else
8929 code = CODE_FOR_thumb2_casesi_internal;
8930
8931 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8932 operands[2] = force_reg (SImode, operands[2]);
8933
8934 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8935 operands[3], operands[4]));
8936 DONE;
8937 }"
8938 )
8939
8940 ;; The USE in this pattern is needed to tell flow analysis that this is
8941 ;; a CASESI insn. It has no other purpose.
8942 (define_insn "arm_casesi_internal"
8943 [(parallel [(set (pc)
8944 (if_then_else
8945 (leu (match_operand:SI 0 "s_register_operand" "r")
8946 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8947 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8948 (label_ref (match_operand 2 "" ""))))
8949 (label_ref (match_operand 3 "" ""))))
8950 (clobber (reg:CC CC_REGNUM))
8951 (use (label_ref (match_dup 2)))])]
8952 "TARGET_ARM"
8953 "*
8954 if (flag_pic)
8955 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8956 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8957 "
8958 [(set_attr "conds" "clob")
8959 (set_attr "length" "12")
8960 (set_attr "type" "multiple")]
8961 )
8962
8963 (define_expand "indirect_jump"
8964 [(set (pc)
8965 (match_operand:SI 0 "s_register_operand" ""))]
8966 "TARGET_EITHER"
8967 "
8968 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8969 address and use bx. */
8970 if (TARGET_THUMB2)
8971 {
8972 rtx tmp;
8973 tmp = gen_reg_rtx (SImode);
8974 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8975 operands[0] = tmp;
8976 }
8977 "
8978 )
8979
8980 ;; NB Never uses BX.
8981 (define_insn "*arm_indirect_jump"
8982 [(set (pc)
8983 (match_operand:SI 0 "s_register_operand" "r"))]
8984 "TARGET_ARM"
8985 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8986 [(set_attr "predicable" "yes")
8987 (set_attr "type" "branch")]
8988 )
8989
8990 (define_insn "*load_indirect_jump"
8991 [(set (pc)
8992 (match_operand:SI 0 "memory_operand" "m"))]
8993 "TARGET_ARM"
8994 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8995 [(set_attr "type" "load_4")
8996 (set_attr "pool_range" "4096")
8997 (set_attr "neg_pool_range" "4084")
8998 (set_attr "predicable" "yes")]
8999 )
9000
9001 \f
9002 ;; Misc insns
9003
9004 (define_insn "nop"
9005 [(const_int 0)]
9006 "TARGET_EITHER"
9007 "nop"
9008 [(set (attr "length")
9009 (if_then_else (eq_attr "is_thumb" "yes")
9010 (const_int 2)
9011 (const_int 4)))
9012 (set_attr "type" "mov_reg")]
9013 )
9014
9015 (define_insn "trap"
9016 [(trap_if (const_int 1) (const_int 0))]
9017 ""
9018 "*
9019 if (TARGET_ARM)
9020 return \".inst\\t0xe7f000f0\";
9021 else
9022 return \".inst\\t0xdeff\";
9023 "
9024 [(set (attr "length")
9025 (if_then_else (eq_attr "is_thumb" "yes")
9026 (const_int 2)
9027 (const_int 4)))
9028 (set_attr "type" "trap")
9029 (set_attr "conds" "unconditional")]
9030 )
9031
9032 \f
9033 ;; Patterns to allow combination of arithmetic, cond code and shifts
9034
9035 (define_insn "*<arith_shift_insn>_multsi"
9036 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9037 (SHIFTABLE_OPS:SI
9038 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
9039 (match_operand:SI 3 "power_of_two_operand" ""))
9040 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
9041 "TARGET_32BIT"
9042 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
9043 [(set_attr "predicable" "yes")
9044 (set_attr "shift" "2")
9045 (set_attr "arch" "a,t2")
9046 (set_attr "type" "alu_shift_imm")])
9047
9048 (define_insn "*<arith_shift_insn>_shiftsi"
9049 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9050 (SHIFTABLE_OPS:SI
9051 (match_operator:SI 2 "shift_nomul_operator"
9052 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9053 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
9054 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
9055 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
9056 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
9057 [(set_attr "predicable" "yes")
9058 (set_attr "shift" "3")
9059 (set_attr "arch" "a,t2,a")
9060 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9061
9062 (define_split
9063 [(set (match_operand:SI 0 "s_register_operand" "")
9064 (match_operator:SI 1 "shiftable_operator"
9065 [(match_operator:SI 2 "shiftable_operator"
9066 [(match_operator:SI 3 "shift_operator"
9067 [(match_operand:SI 4 "s_register_operand" "")
9068 (match_operand:SI 5 "reg_or_int_operand" "")])
9069 (match_operand:SI 6 "s_register_operand" "")])
9070 (match_operand:SI 7 "arm_rhs_operand" "")]))
9071 (clobber (match_operand:SI 8 "s_register_operand" ""))]
9072 "TARGET_32BIT"
9073 [(set (match_dup 8)
9074 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9075 (match_dup 6)]))
9076 (set (match_dup 0)
9077 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
9078 "")
9079
9080 (define_insn "*arith_shiftsi_compare0"
9081 [(set (reg:CC_NOOV CC_REGNUM)
9082 (compare:CC_NOOV
9083 (match_operator:SI 1 "shiftable_operator"
9084 [(match_operator:SI 3 "shift_operator"
9085 [(match_operand:SI 4 "s_register_operand" "r,r")
9086 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9087 (match_operand:SI 2 "s_register_operand" "r,r")])
9088 (const_int 0)))
9089 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9090 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9091 (match_dup 2)]))]
9092 "TARGET_32BIT"
9093 "%i1s%?\\t%0, %2, %4%S3"
9094 [(set_attr "conds" "set")
9095 (set_attr "shift" "4")
9096 (set_attr "arch" "32,a")
9097 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9098
9099 (define_insn "*arith_shiftsi_compare0_scratch"
9100 [(set (reg:CC_NOOV CC_REGNUM)
9101 (compare:CC_NOOV
9102 (match_operator:SI 1 "shiftable_operator"
9103 [(match_operator:SI 3 "shift_operator"
9104 [(match_operand:SI 4 "s_register_operand" "r,r")
9105 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9106 (match_operand:SI 2 "s_register_operand" "r,r")])
9107 (const_int 0)))
9108 (clobber (match_scratch:SI 0 "=r,r"))]
9109 "TARGET_32BIT"
9110 "%i1s%?\\t%0, %2, %4%S3"
9111 [(set_attr "conds" "set")
9112 (set_attr "shift" "4")
9113 (set_attr "arch" "32,a")
9114 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9115
9116 (define_insn "*sub_shiftsi"
9117 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9118 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9119 (match_operator:SI 2 "shift_operator"
9120 [(match_operand:SI 3 "s_register_operand" "r,r")
9121 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
9122 "TARGET_32BIT"
9123 "sub%?\\t%0, %1, %3%S2"
9124 [(set_attr "predicable" "yes")
9125 (set_attr "predicable_short_it" "no")
9126 (set_attr "shift" "3")
9127 (set_attr "arch" "32,a")
9128 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9129
9130 (define_insn "*sub_shiftsi_compare0"
9131 [(set (reg:CC_NOOV CC_REGNUM)
9132 (compare:CC_NOOV
9133 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9134 (match_operator:SI 2 "shift_operator"
9135 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9136 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9137 (const_int 0)))
9138 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9139 (minus:SI (match_dup 1)
9140 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
9141 "TARGET_32BIT"
9142 "subs%?\\t%0, %1, %3%S2"
9143 [(set_attr "conds" "set")
9144 (set_attr "shift" "3")
9145 (set_attr "arch" "32,a,a")
9146 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9147
9148 (define_insn "*sub_shiftsi_compare0_scratch"
9149 [(set (reg:CC_NOOV CC_REGNUM)
9150 (compare:CC_NOOV
9151 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9152 (match_operator:SI 2 "shift_operator"
9153 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9154 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9155 (const_int 0)))
9156 (clobber (match_scratch:SI 0 "=r,r,r"))]
9157 "TARGET_32BIT"
9158 "subs%?\\t%0, %1, %3%S2"
9159 [(set_attr "conds" "set")
9160 (set_attr "shift" "3")
9161 (set_attr "arch" "32,a,a")
9162 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9163 \f
9164
9165 (define_insn_and_split "*and_scc"
9166 [(set (match_operand:SI 0 "s_register_operand" "=r")
9167 (and:SI (match_operator:SI 1 "arm_comparison_operator"
9168 [(match_operand 2 "cc_register" "") (const_int 0)])
9169 (match_operand:SI 3 "s_register_operand" "r")))]
9170 "TARGET_ARM"
9171 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
9172 "&& reload_completed"
9173 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
9174 (cond_exec (match_dup 4) (set (match_dup 0)
9175 (and:SI (match_dup 3) (const_int 1))))]
9176 {
9177 machine_mode mode = GET_MODE (operands[2]);
9178 enum rtx_code rc = GET_CODE (operands[1]);
9179
9180 /* Note that operands[4] is the same as operands[1],
9181 but with VOIDmode as the result. */
9182 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9183 if (mode == CCFPmode || mode == CCFPEmode)
9184 rc = reverse_condition_maybe_unordered (rc);
9185 else
9186 rc = reverse_condition (rc);
9187 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9188 }
9189 [(set_attr "conds" "use")
9190 (set_attr "type" "multiple")
9191 (set_attr "length" "8")]
9192 )
9193
9194 (define_insn_and_split "*ior_scc"
9195 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9196 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
9197 [(match_operand 2 "cc_register" "") (const_int 0)])
9198 (match_operand:SI 3 "s_register_operand" "0,?r")))]
9199 "TARGET_ARM"
9200 "@
9201 orr%d1\\t%0, %3, #1
9202 #"
9203 "&& reload_completed
9204 && REGNO (operands [0]) != REGNO (operands[3])"
9205 ;; && which_alternative == 1
9206 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
9207 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
9208 (cond_exec (match_dup 4) (set (match_dup 0)
9209 (ior:SI (match_dup 3) (const_int 1))))]
9210 {
9211 machine_mode mode = GET_MODE (operands[2]);
9212 enum rtx_code rc = GET_CODE (operands[1]);
9213
9214 /* Note that operands[4] is the same as operands[1],
9215 but with VOIDmode as the result. */
9216 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9217 if (mode == CCFPmode || mode == CCFPEmode)
9218 rc = reverse_condition_maybe_unordered (rc);
9219 else
9220 rc = reverse_condition (rc);
9221 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9222 }
9223 [(set_attr "conds" "use")
9224 (set_attr "length" "4,8")
9225 (set_attr "type" "logic_imm,multiple")]
9226 )
9227
9228 ; A series of splitters for the compare_scc pattern below. Note that
9229 ; order is important.
9230 (define_split
9231 [(set (match_operand:SI 0 "s_register_operand" "")
9232 (lt:SI (match_operand:SI 1 "s_register_operand" "")
9233 (const_int 0)))
9234 (clobber (reg:CC CC_REGNUM))]
9235 "TARGET_32BIT && reload_completed"
9236 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9237
9238 (define_split
9239 [(set (match_operand:SI 0 "s_register_operand" "")
9240 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9241 (const_int 0)))
9242 (clobber (reg:CC CC_REGNUM))]
9243 "TARGET_32BIT && reload_completed"
9244 [(set (match_dup 0) (not:SI (match_dup 1)))
9245 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9246
9247 (define_split
9248 [(set (match_operand:SI 0 "s_register_operand" "")
9249 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9250 (const_int 0)))
9251 (clobber (reg:CC CC_REGNUM))]
9252 "arm_arch5t && TARGET_32BIT"
9253 [(set (match_dup 0) (clz:SI (match_dup 1)))
9254 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9255 )
9256
9257 (define_split
9258 [(set (match_operand:SI 0 "s_register_operand" "")
9259 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9260 (const_int 0)))
9261 (clobber (reg:CC CC_REGNUM))]
9262 "TARGET_32BIT && reload_completed"
9263 [(parallel
9264 [(set (reg:CC CC_REGNUM)
9265 (compare:CC (const_int 1) (match_dup 1)))
9266 (set (match_dup 0)
9267 (minus:SI (const_int 1) (match_dup 1)))])
9268 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9269 (set (match_dup 0) (const_int 0)))])
9270
9271 (define_split
9272 [(set (match_operand:SI 0 "s_register_operand" "")
9273 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9274 (match_operand:SI 2 "const_int_operand" "")))
9275 (clobber (reg:CC CC_REGNUM))]
9276 "TARGET_32BIT && reload_completed"
9277 [(parallel
9278 [(set (reg:CC CC_REGNUM)
9279 (compare:CC (match_dup 1) (match_dup 2)))
9280 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9281 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9282 (set (match_dup 0) (const_int 1)))]
9283 {
9284 operands[3] = GEN_INT (-INTVAL (operands[2]));
9285 })
9286
9287 (define_split
9288 [(set (match_operand:SI 0 "s_register_operand" "")
9289 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9290 (match_operand:SI 2 "arm_add_operand" "")))
9291 (clobber (reg:CC CC_REGNUM))]
9292 "TARGET_32BIT && reload_completed"
9293 [(parallel
9294 [(set (reg:CC_NOOV CC_REGNUM)
9295 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9296 (const_int 0)))
9297 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9298 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9299 (set (match_dup 0) (const_int 1)))])
9300
9301 (define_insn_and_split "*compare_scc"
9302 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9303 (match_operator:SI 1 "arm_comparison_operator"
9304 [(match_operand:SI 2 "s_register_operand" "r,r")
9305 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9306 (clobber (reg:CC CC_REGNUM))]
9307 "TARGET_32BIT"
9308 "#"
9309 "&& reload_completed"
9310 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9311 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9312 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9313 {
9314 rtx tmp1;
9315 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9316 operands[2], operands[3]);
9317 enum rtx_code rc = GET_CODE (operands[1]);
9318
9319 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9320
9321 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9322 if (mode == CCFPmode || mode == CCFPEmode)
9323 rc = reverse_condition_maybe_unordered (rc);
9324 else
9325 rc = reverse_condition (rc);
9326 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9327 }
9328 [(set_attr "type" "multiple")]
9329 )
9330
9331 ;; Attempt to improve the sequence generated by the compare_scc splitters
9332 ;; not to use conditional execution.
9333
9334 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9335 ;; clz Rd, reg1
9336 ;; lsr Rd, Rd, #5
9337 (define_peephole2
9338 [(set (reg:CC CC_REGNUM)
9339 (compare:CC (match_operand:SI 1 "register_operand" "")
9340 (const_int 0)))
9341 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9342 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9343 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9344 (set (match_dup 0) (const_int 1)))]
9345 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9346 [(set (match_dup 0) (clz:SI (match_dup 1)))
9347 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9348 )
9349
9350 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9351 ;; negs Rd, reg1
9352 ;; adc Rd, Rd, reg1
9353 (define_peephole2
9354 [(set (reg:CC CC_REGNUM)
9355 (compare:CC (match_operand:SI 1 "register_operand" "")
9356 (const_int 0)))
9357 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9358 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9359 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9360 (set (match_dup 0) (const_int 1)))
9361 (match_scratch:SI 2 "r")]
9362 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9363 [(parallel
9364 [(set (reg:CC CC_REGNUM)
9365 (compare:CC (const_int 0) (match_dup 1)))
9366 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9367 (set (match_dup 0)
9368 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9369 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9370 )
9371
9372 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9373 ;; sub Rd, Reg1, reg2
9374 ;; clz Rd, Rd
9375 ;; lsr Rd, Rd, #5
9376 (define_peephole2
9377 [(set (reg:CC CC_REGNUM)
9378 (compare:CC (match_operand:SI 1 "register_operand" "")
9379 (match_operand:SI 2 "arm_rhs_operand" "")))
9380 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9381 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9382 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9383 (set (match_dup 0) (const_int 1)))]
9384 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9385 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9386 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9387 (set (match_dup 0) (clz:SI (match_dup 0)))
9388 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9389 )
9390
9391
9392 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9393 ;; sub T1, Reg1, reg2
9394 ;; negs Rd, T1
9395 ;; adc Rd, Rd, T1
9396 (define_peephole2
9397 [(set (reg:CC CC_REGNUM)
9398 (compare:CC (match_operand:SI 1 "register_operand" "")
9399 (match_operand:SI 2 "arm_rhs_operand" "")))
9400 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9401 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9402 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9403 (set (match_dup 0) (const_int 1)))
9404 (match_scratch:SI 3 "r")]
9405 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9406 [(set (match_dup 3) (match_dup 4))
9407 (parallel
9408 [(set (reg:CC CC_REGNUM)
9409 (compare:CC (const_int 0) (match_dup 3)))
9410 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9411 (set (match_dup 0)
9412 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9413 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9414 "
9415 if (CONST_INT_P (operands[2]))
9416 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9417 else
9418 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9419 ")
9420
9421 (define_insn "*cond_move"
9422 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9423 (if_then_else:SI (match_operator 3 "equality_operator"
9424 [(match_operator 4 "arm_comparison_operator"
9425 [(match_operand 5 "cc_register" "") (const_int 0)])
9426 (const_int 0)])
9427 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9428 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9429 "TARGET_ARM"
9430 "*
9431 if (GET_CODE (operands[3]) == NE)
9432 {
9433 if (which_alternative != 1)
9434 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9435 if (which_alternative != 0)
9436 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9437 return \"\";
9438 }
9439 if (which_alternative != 0)
9440 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9441 if (which_alternative != 1)
9442 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9443 return \"\";
9444 "
9445 [(set_attr "conds" "use")
9446 (set_attr_alternative "type"
9447 [(if_then_else (match_operand 2 "const_int_operand" "")
9448 (const_string "mov_imm")
9449 (const_string "mov_reg"))
9450 (if_then_else (match_operand 1 "const_int_operand" "")
9451 (const_string "mov_imm")
9452 (const_string "mov_reg"))
9453 (const_string "multiple")])
9454 (set_attr "length" "4,4,8")]
9455 )
9456
9457 (define_insn "*cond_arith"
9458 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9459 (match_operator:SI 5 "shiftable_operator"
9460 [(match_operator:SI 4 "arm_comparison_operator"
9461 [(match_operand:SI 2 "s_register_operand" "r,r")
9462 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9463 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9464 (clobber (reg:CC CC_REGNUM))]
9465 "TARGET_ARM"
9466 "*
9467 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9468 return \"%i5\\t%0, %1, %2, lsr #31\";
9469
9470 output_asm_insn (\"cmp\\t%2, %3\", operands);
9471 if (GET_CODE (operands[5]) == AND)
9472 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9473 else if (GET_CODE (operands[5]) == MINUS)
9474 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9475 else if (which_alternative != 0)
9476 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9477 return \"%i5%d4\\t%0, %1, #1\";
9478 "
9479 [(set_attr "conds" "clob")
9480 (set_attr "length" "12")
9481 (set_attr "type" "multiple")]
9482 )
9483
9484 (define_insn "*cond_sub"
9485 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9486 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9487 (match_operator:SI 4 "arm_comparison_operator"
9488 [(match_operand:SI 2 "s_register_operand" "r,r")
9489 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9490 (clobber (reg:CC CC_REGNUM))]
9491 "TARGET_ARM"
9492 "*
9493 output_asm_insn (\"cmp\\t%2, %3\", operands);
9494 if (which_alternative != 0)
9495 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9496 return \"sub%d4\\t%0, %1, #1\";
9497 "
9498 [(set_attr "conds" "clob")
9499 (set_attr "length" "8,12")
9500 (set_attr "type" "multiple")]
9501 )
9502
9503 (define_insn "*cmp_ite0"
9504 [(set (match_operand 6 "dominant_cc_register" "")
9505 (compare
9506 (if_then_else:SI
9507 (match_operator 4 "arm_comparison_operator"
9508 [(match_operand:SI 0 "s_register_operand"
9509 "l,l,l,r,r,r,r,r,r")
9510 (match_operand:SI 1 "arm_add_operand"
9511 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9512 (match_operator:SI 5 "arm_comparison_operator"
9513 [(match_operand:SI 2 "s_register_operand"
9514 "l,r,r,l,l,r,r,r,r")
9515 (match_operand:SI 3 "arm_add_operand"
9516 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9517 (const_int 0))
9518 (const_int 0)))]
9519 "TARGET_32BIT"
9520 "*
9521 {
9522 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9523 {
9524 {\"cmp%d5\\t%0, %1\",
9525 \"cmp%d4\\t%2, %3\"},
9526 {\"cmn%d5\\t%0, #%n1\",
9527 \"cmp%d4\\t%2, %3\"},
9528 {\"cmp%d5\\t%0, %1\",
9529 \"cmn%d4\\t%2, #%n3\"},
9530 {\"cmn%d5\\t%0, #%n1\",
9531 \"cmn%d4\\t%2, #%n3\"}
9532 };
9533 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9534 {
9535 {\"cmp\\t%2, %3\",
9536 \"cmp\\t%0, %1\"},
9537 {\"cmp\\t%2, %3\",
9538 \"cmn\\t%0, #%n1\"},
9539 {\"cmn\\t%2, #%n3\",
9540 \"cmp\\t%0, %1\"},
9541 {\"cmn\\t%2, #%n3\",
9542 \"cmn\\t%0, #%n1\"}
9543 };
9544 static const char * const ite[2] =
9545 {
9546 \"it\\t%d5\",
9547 \"it\\t%d4\"
9548 };
9549 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9550 CMP_CMP, CMN_CMP, CMP_CMP,
9551 CMN_CMP, CMP_CMN, CMN_CMN};
9552 int swap =
9553 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9554
9555 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9556 if (TARGET_THUMB2) {
9557 output_asm_insn (ite[swap], operands);
9558 }
9559 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9560 return \"\";
9561 }"
9562 [(set_attr "conds" "set")
9563 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9564 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9565 (set_attr "type" "multiple")
9566 (set_attr_alternative "length"
9567 [(const_int 6)
9568 (const_int 8)
9569 (const_int 8)
9570 (const_int 8)
9571 (const_int 8)
9572 (if_then_else (eq_attr "is_thumb" "no")
9573 (const_int 8)
9574 (const_int 10))
9575 (if_then_else (eq_attr "is_thumb" "no")
9576 (const_int 8)
9577 (const_int 10))
9578 (if_then_else (eq_attr "is_thumb" "no")
9579 (const_int 8)
9580 (const_int 10))
9581 (if_then_else (eq_attr "is_thumb" "no")
9582 (const_int 8)
9583 (const_int 10))])]
9584 )
9585
9586 (define_insn "*cmp_ite1"
9587 [(set (match_operand 6 "dominant_cc_register" "")
9588 (compare
9589 (if_then_else:SI
9590 (match_operator 4 "arm_comparison_operator"
9591 [(match_operand:SI 0 "s_register_operand"
9592 "l,l,l,r,r,r,r,r,r")
9593 (match_operand:SI 1 "arm_add_operand"
9594 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9595 (match_operator:SI 5 "arm_comparison_operator"
9596 [(match_operand:SI 2 "s_register_operand"
9597 "l,r,r,l,l,r,r,r,r")
9598 (match_operand:SI 3 "arm_add_operand"
9599 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9600 (const_int 1))
9601 (const_int 0)))]
9602 "TARGET_32BIT"
9603 "*
9604 {
9605 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9606 {
9607 {\"cmp\\t%0, %1\",
9608 \"cmp\\t%2, %3\"},
9609 {\"cmn\\t%0, #%n1\",
9610 \"cmp\\t%2, %3\"},
9611 {\"cmp\\t%0, %1\",
9612 \"cmn\\t%2, #%n3\"},
9613 {\"cmn\\t%0, #%n1\",
9614 \"cmn\\t%2, #%n3\"}
9615 };
9616 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9617 {
9618 {\"cmp%d4\\t%2, %3\",
9619 \"cmp%D5\\t%0, %1\"},
9620 {\"cmp%d4\\t%2, %3\",
9621 \"cmn%D5\\t%0, #%n1\"},
9622 {\"cmn%d4\\t%2, #%n3\",
9623 \"cmp%D5\\t%0, %1\"},
9624 {\"cmn%d4\\t%2, #%n3\",
9625 \"cmn%D5\\t%0, #%n1\"}
9626 };
9627 static const char * const ite[2] =
9628 {
9629 \"it\\t%d4\",
9630 \"it\\t%D5\"
9631 };
9632 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9633 CMP_CMP, CMN_CMP, CMP_CMP,
9634 CMN_CMP, CMP_CMN, CMN_CMN};
9635 int swap =
9636 comparison_dominates_p (GET_CODE (operands[5]),
9637 reverse_condition (GET_CODE (operands[4])));
9638
9639 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9640 if (TARGET_THUMB2) {
9641 output_asm_insn (ite[swap], operands);
9642 }
9643 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9644 return \"\";
9645 }"
9646 [(set_attr "conds" "set")
9647 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9648 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9649 (set_attr_alternative "length"
9650 [(const_int 6)
9651 (const_int 8)
9652 (const_int 8)
9653 (const_int 8)
9654 (const_int 8)
9655 (if_then_else (eq_attr "is_thumb" "no")
9656 (const_int 8)
9657 (const_int 10))
9658 (if_then_else (eq_attr "is_thumb" "no")
9659 (const_int 8)
9660 (const_int 10))
9661 (if_then_else (eq_attr "is_thumb" "no")
9662 (const_int 8)
9663 (const_int 10))
9664 (if_then_else (eq_attr "is_thumb" "no")
9665 (const_int 8)
9666 (const_int 10))])
9667 (set_attr "type" "multiple")]
9668 )
9669
9670 (define_insn "*cmp_and"
9671 [(set (match_operand 6 "dominant_cc_register" "")
9672 (compare
9673 (and:SI
9674 (match_operator 4 "arm_comparison_operator"
9675 [(match_operand:SI 0 "s_register_operand"
9676 "l,l,l,r,r,r,r,r,r")
9677 (match_operand:SI 1 "arm_add_operand"
9678 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9679 (match_operator:SI 5 "arm_comparison_operator"
9680 [(match_operand:SI 2 "s_register_operand"
9681 "l,r,r,l,l,r,r,r,r")
9682 (match_operand:SI 3 "arm_add_operand"
9683 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9684 (const_int 0)))]
9685 "TARGET_32BIT"
9686 "*
9687 {
9688 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9689 {
9690 {\"cmp%d5\\t%0, %1\",
9691 \"cmp%d4\\t%2, %3\"},
9692 {\"cmn%d5\\t%0, #%n1\",
9693 \"cmp%d4\\t%2, %3\"},
9694 {\"cmp%d5\\t%0, %1\",
9695 \"cmn%d4\\t%2, #%n3\"},
9696 {\"cmn%d5\\t%0, #%n1\",
9697 \"cmn%d4\\t%2, #%n3\"}
9698 };
9699 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9700 {
9701 {\"cmp\\t%2, %3\",
9702 \"cmp\\t%0, %1\"},
9703 {\"cmp\\t%2, %3\",
9704 \"cmn\\t%0, #%n1\"},
9705 {\"cmn\\t%2, #%n3\",
9706 \"cmp\\t%0, %1\"},
9707 {\"cmn\\t%2, #%n3\",
9708 \"cmn\\t%0, #%n1\"}
9709 };
9710 static const char *const ite[2] =
9711 {
9712 \"it\\t%d5\",
9713 \"it\\t%d4\"
9714 };
9715 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9716 CMP_CMP, CMN_CMP, CMP_CMP,
9717 CMN_CMP, CMP_CMN, CMN_CMN};
9718 int swap =
9719 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9720
9721 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9722 if (TARGET_THUMB2) {
9723 output_asm_insn (ite[swap], operands);
9724 }
9725 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9726 return \"\";
9727 }"
9728 [(set_attr "conds" "set")
9729 (set_attr "predicable" "no")
9730 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9731 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9732 (set_attr_alternative "length"
9733 [(const_int 6)
9734 (const_int 8)
9735 (const_int 8)
9736 (const_int 8)
9737 (const_int 8)
9738 (if_then_else (eq_attr "is_thumb" "no")
9739 (const_int 8)
9740 (const_int 10))
9741 (if_then_else (eq_attr "is_thumb" "no")
9742 (const_int 8)
9743 (const_int 10))
9744 (if_then_else (eq_attr "is_thumb" "no")
9745 (const_int 8)
9746 (const_int 10))
9747 (if_then_else (eq_attr "is_thumb" "no")
9748 (const_int 8)
9749 (const_int 10))])
9750 (set_attr "type" "multiple")]
9751 )
9752
9753 (define_insn "*cmp_ior"
9754 [(set (match_operand 6 "dominant_cc_register" "")
9755 (compare
9756 (ior:SI
9757 (match_operator 4 "arm_comparison_operator"
9758 [(match_operand:SI 0 "s_register_operand"
9759 "l,l,l,r,r,r,r,r,r")
9760 (match_operand:SI 1 "arm_add_operand"
9761 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9762 (match_operator:SI 5 "arm_comparison_operator"
9763 [(match_operand:SI 2 "s_register_operand"
9764 "l,r,r,l,l,r,r,r,r")
9765 (match_operand:SI 3 "arm_add_operand"
9766 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9767 (const_int 0)))]
9768 "TARGET_32BIT"
9769 "*
9770 {
9771 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9772 {
9773 {\"cmp\\t%0, %1\",
9774 \"cmp\\t%2, %3\"},
9775 {\"cmn\\t%0, #%n1\",
9776 \"cmp\\t%2, %3\"},
9777 {\"cmp\\t%0, %1\",
9778 \"cmn\\t%2, #%n3\"},
9779 {\"cmn\\t%0, #%n1\",
9780 \"cmn\\t%2, #%n3\"}
9781 };
9782 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9783 {
9784 {\"cmp%D4\\t%2, %3\",
9785 \"cmp%D5\\t%0, %1\"},
9786 {\"cmp%D4\\t%2, %3\",
9787 \"cmn%D5\\t%0, #%n1\"},
9788 {\"cmn%D4\\t%2, #%n3\",
9789 \"cmp%D5\\t%0, %1\"},
9790 {\"cmn%D4\\t%2, #%n3\",
9791 \"cmn%D5\\t%0, #%n1\"}
9792 };
9793 static const char *const ite[2] =
9794 {
9795 \"it\\t%D4\",
9796 \"it\\t%D5\"
9797 };
9798 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9799 CMP_CMP, CMN_CMP, CMP_CMP,
9800 CMN_CMP, CMP_CMN, CMN_CMN};
9801 int swap =
9802 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9803
9804 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9805 if (TARGET_THUMB2) {
9806 output_asm_insn (ite[swap], operands);
9807 }
9808 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9809 return \"\";
9810 }
9811 "
9812 [(set_attr "conds" "set")
9813 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9814 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9815 (set_attr_alternative "length"
9816 [(const_int 6)
9817 (const_int 8)
9818 (const_int 8)
9819 (const_int 8)
9820 (const_int 8)
9821 (if_then_else (eq_attr "is_thumb" "no")
9822 (const_int 8)
9823 (const_int 10))
9824 (if_then_else (eq_attr "is_thumb" "no")
9825 (const_int 8)
9826 (const_int 10))
9827 (if_then_else (eq_attr "is_thumb" "no")
9828 (const_int 8)
9829 (const_int 10))
9830 (if_then_else (eq_attr "is_thumb" "no")
9831 (const_int 8)
9832 (const_int 10))])
9833 (set_attr "type" "multiple")]
9834 )
9835
9836 (define_insn_and_split "*ior_scc_scc"
9837 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9838 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9839 [(match_operand:SI 1 "s_register_operand" "l,r")
9840 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9841 (match_operator:SI 6 "arm_comparison_operator"
9842 [(match_operand:SI 4 "s_register_operand" "l,r")
9843 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9844 (clobber (reg:CC CC_REGNUM))]
9845 "TARGET_32BIT
9846 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9847 != CCmode)"
9848 "#"
9849 "TARGET_32BIT && reload_completed"
9850 [(set (match_dup 7)
9851 (compare
9852 (ior:SI
9853 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9854 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9855 (const_int 0)))
9856 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9857 "operands[7]
9858 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9859 DOM_CC_X_OR_Y),
9860 CC_REGNUM);"
9861 [(set_attr "conds" "clob")
9862 (set_attr "enabled_for_short_it" "yes,no")
9863 (set_attr "length" "16")
9864 (set_attr "type" "multiple")]
9865 )
9866
9867 ; If the above pattern is followed by a CMP insn, then the compare is
9868 ; redundant, since we can rework the conditional instruction that follows.
9869 (define_insn_and_split "*ior_scc_scc_cmp"
9870 [(set (match_operand 0 "dominant_cc_register" "")
9871 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9872 [(match_operand:SI 1 "s_register_operand" "l,r")
9873 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9874 (match_operator:SI 6 "arm_comparison_operator"
9875 [(match_operand:SI 4 "s_register_operand" "l,r")
9876 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9877 (const_int 0)))
9878 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9879 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9880 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9881 "TARGET_32BIT"
9882 "#"
9883 "TARGET_32BIT && reload_completed"
9884 [(set (match_dup 0)
9885 (compare
9886 (ior:SI
9887 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9888 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9889 (const_int 0)))
9890 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9891 ""
9892 [(set_attr "conds" "set")
9893 (set_attr "enabled_for_short_it" "yes,no")
9894 (set_attr "length" "16")
9895 (set_attr "type" "multiple")]
9896 )
9897
9898 (define_insn_and_split "*and_scc_scc"
9899 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9900 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9901 [(match_operand:SI 1 "s_register_operand" "l,r")
9902 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9903 (match_operator:SI 6 "arm_comparison_operator"
9904 [(match_operand:SI 4 "s_register_operand" "l,r")
9905 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9906 (clobber (reg:CC CC_REGNUM))]
9907 "TARGET_32BIT
9908 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9909 != CCmode)"
9910 "#"
9911 "TARGET_32BIT && reload_completed
9912 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9913 != CCmode)"
9914 [(set (match_dup 7)
9915 (compare
9916 (and:SI
9917 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9918 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9919 (const_int 0)))
9920 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9921 "operands[7]
9922 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9923 DOM_CC_X_AND_Y),
9924 CC_REGNUM);"
9925 [(set_attr "conds" "clob")
9926 (set_attr "enabled_for_short_it" "yes,no")
9927 (set_attr "length" "16")
9928 (set_attr "type" "multiple")]
9929 )
9930
9931 ; If the above pattern is followed by a CMP insn, then the compare is
9932 ; redundant, since we can rework the conditional instruction that follows.
9933 (define_insn_and_split "*and_scc_scc_cmp"
9934 [(set (match_operand 0 "dominant_cc_register" "")
9935 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9936 [(match_operand:SI 1 "s_register_operand" "l,r")
9937 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9938 (match_operator:SI 6 "arm_comparison_operator"
9939 [(match_operand:SI 4 "s_register_operand" "l,r")
9940 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9941 (const_int 0)))
9942 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9943 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9944 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9945 "TARGET_32BIT"
9946 "#"
9947 "TARGET_32BIT && reload_completed"
9948 [(set (match_dup 0)
9949 (compare
9950 (and:SI
9951 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9952 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9953 (const_int 0)))
9954 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9955 ""
9956 [(set_attr "conds" "set")
9957 (set_attr "enabled_for_short_it" "yes,no")
9958 (set_attr "length" "16")
9959 (set_attr "type" "multiple")]
9960 )
9961
9962 ;; If there is no dominance in the comparison, then we can still save an
9963 ;; instruction in the AND case, since we can know that the second compare
9964 ;; need only zero the value if false (if true, then the value is already
9965 ;; correct).
9966 (define_insn_and_split "*and_scc_scc_nodom"
9967 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9968 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9969 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9970 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9971 (match_operator:SI 6 "arm_comparison_operator"
9972 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9973 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9974 (clobber (reg:CC CC_REGNUM))]
9975 "TARGET_32BIT
9976 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9977 == CCmode)"
9978 "#"
9979 "TARGET_32BIT && reload_completed"
9980 [(parallel [(set (match_dup 0)
9981 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9982 (clobber (reg:CC CC_REGNUM))])
9983 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9984 (set (match_dup 0)
9985 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9986 (match_dup 0)
9987 (const_int 0)))]
9988 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9989 operands[4], operands[5]),
9990 CC_REGNUM);
9991 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9992 operands[5]);"
9993 [(set_attr "conds" "clob")
9994 (set_attr "length" "20")
9995 (set_attr "type" "multiple")]
9996 )
9997
9998 (define_split
9999 [(set (reg:CC_NOOV CC_REGNUM)
10000 (compare:CC_NOOV (ior:SI
10001 (and:SI (match_operand:SI 0 "s_register_operand" "")
10002 (const_int 1))
10003 (match_operator:SI 1 "arm_comparison_operator"
10004 [(match_operand:SI 2 "s_register_operand" "")
10005 (match_operand:SI 3 "arm_add_operand" "")]))
10006 (const_int 0)))
10007 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10008 "TARGET_ARM"
10009 [(set (match_dup 4)
10010 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10011 (match_dup 0)))
10012 (set (reg:CC_NOOV CC_REGNUM)
10013 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10014 (const_int 0)))]
10015 "")
10016
10017 (define_split
10018 [(set (reg:CC_NOOV CC_REGNUM)
10019 (compare:CC_NOOV (ior:SI
10020 (match_operator:SI 1 "arm_comparison_operator"
10021 [(match_operand:SI 2 "s_register_operand" "")
10022 (match_operand:SI 3 "arm_add_operand" "")])
10023 (and:SI (match_operand:SI 0 "s_register_operand" "")
10024 (const_int 1)))
10025 (const_int 0)))
10026 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10027 "TARGET_ARM"
10028 [(set (match_dup 4)
10029 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10030 (match_dup 0)))
10031 (set (reg:CC_NOOV CC_REGNUM)
10032 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10033 (const_int 0)))]
10034 "")
10035 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10036
10037 (define_insn_and_split "*negscc"
10038 [(set (match_operand:SI 0 "s_register_operand" "=r")
10039 (neg:SI (match_operator 3 "arm_comparison_operator"
10040 [(match_operand:SI 1 "s_register_operand" "r")
10041 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10042 (clobber (reg:CC CC_REGNUM))]
10043 "TARGET_ARM"
10044 "#"
10045 "&& reload_completed"
10046 [(const_int 0)]
10047 {
10048 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10049
10050 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10051 {
10052 /* Emit mov\\t%0, %1, asr #31 */
10053 emit_insn (gen_rtx_SET (operands[0],
10054 gen_rtx_ASHIFTRT (SImode,
10055 operands[1],
10056 GEN_INT (31))));
10057 DONE;
10058 }
10059 else if (GET_CODE (operands[3]) == NE)
10060 {
10061 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10062 if (CONST_INT_P (operands[2]))
10063 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10064 GEN_INT (- INTVAL (operands[2]))));
10065 else
10066 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10067
10068 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10069 gen_rtx_NE (SImode,
10070 cc_reg,
10071 const0_rtx),
10072 gen_rtx_SET (operands[0],
10073 GEN_INT (~0))));
10074 DONE;
10075 }
10076 else
10077 {
10078 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10079 emit_insn (gen_rtx_SET (cc_reg,
10080 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10081 enum rtx_code rc = GET_CODE (operands[3]);
10082
10083 rc = reverse_condition (rc);
10084 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10085 gen_rtx_fmt_ee (rc,
10086 VOIDmode,
10087 cc_reg,
10088 const0_rtx),
10089 gen_rtx_SET (operands[0], const0_rtx)));
10090 rc = GET_CODE (operands[3]);
10091 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10092 gen_rtx_fmt_ee (rc,
10093 VOIDmode,
10094 cc_reg,
10095 const0_rtx),
10096 gen_rtx_SET (operands[0],
10097 GEN_INT (~0))));
10098 DONE;
10099 }
10100 FAIL;
10101 }
10102 [(set_attr "conds" "clob")
10103 (set_attr "length" "12")
10104 (set_attr "type" "multiple")]
10105 )
10106
10107 (define_insn_and_split "movcond_addsi"
10108 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
10109 (if_then_else:SI
10110 (match_operator 5 "comparison_operator"
10111 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
10112 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
10113 (const_int 0)])
10114 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
10115 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
10116 (clobber (reg:CC CC_REGNUM))]
10117 "TARGET_32BIT"
10118 "#"
10119 "&& reload_completed"
10120 [(set (reg:CC_NOOV CC_REGNUM)
10121 (compare:CC_NOOV
10122 (plus:SI (match_dup 3)
10123 (match_dup 4))
10124 (const_int 0)))
10125 (set (match_dup 0) (match_dup 1))
10126 (cond_exec (match_dup 6)
10127 (set (match_dup 0) (match_dup 2)))]
10128 "
10129 {
10130 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
10131 operands[3], operands[4]);
10132 enum rtx_code rc = GET_CODE (operands[5]);
10133 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10134 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
10135 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
10136 rc = reverse_condition (rc);
10137 else
10138 std::swap (operands[1], operands[2]);
10139
10140 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10141 }
10142 "
10143 [(set_attr "conds" "clob")
10144 (set_attr "enabled_for_short_it" "no,yes,yes")
10145 (set_attr "type" "multiple")]
10146 )
10147
10148 (define_insn "movcond"
10149 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10150 (if_then_else:SI
10151 (match_operator 5 "arm_comparison_operator"
10152 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10153 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
10154 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10155 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
10156 (clobber (reg:CC CC_REGNUM))]
10157 "TARGET_ARM"
10158 "*
10159 if (GET_CODE (operands[5]) == LT
10160 && (operands[4] == const0_rtx))
10161 {
10162 if (which_alternative != 1 && REG_P (operands[1]))
10163 {
10164 if (operands[2] == const0_rtx)
10165 return \"and\\t%0, %1, %3, asr #31\";
10166 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
10167 }
10168 else if (which_alternative != 0 && REG_P (operands[2]))
10169 {
10170 if (operands[1] == const0_rtx)
10171 return \"bic\\t%0, %2, %3, asr #31\";
10172 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
10173 }
10174 /* The only case that falls through to here is when both ops 1 & 2
10175 are constants. */
10176 }
10177
10178 if (GET_CODE (operands[5]) == GE
10179 && (operands[4] == const0_rtx))
10180 {
10181 if (which_alternative != 1 && REG_P (operands[1]))
10182 {
10183 if (operands[2] == const0_rtx)
10184 return \"bic\\t%0, %1, %3, asr #31\";
10185 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
10186 }
10187 else if (which_alternative != 0 && REG_P (operands[2]))
10188 {
10189 if (operands[1] == const0_rtx)
10190 return \"and\\t%0, %2, %3, asr #31\";
10191 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
10192 }
10193 /* The only case that falls through to here is when both ops 1 & 2
10194 are constants. */
10195 }
10196 if (CONST_INT_P (operands[4])
10197 && !const_ok_for_arm (INTVAL (operands[4])))
10198 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
10199 else
10200 output_asm_insn (\"cmp\\t%3, %4\", operands);
10201 if (which_alternative != 0)
10202 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
10203 if (which_alternative != 1)
10204 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
10205 return \"\";
10206 "
10207 [(set_attr "conds" "clob")
10208 (set_attr "length" "8,8,12")
10209 (set_attr "type" "multiple")]
10210 )
10211
10212 ;; ??? The patterns below need checking for Thumb-2 usefulness.
10213
10214 (define_insn "*ifcompare_plus_move"
10215 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10216 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10217 [(match_operand:SI 4 "s_register_operand" "r,r")
10218 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10219 (plus:SI
10220 (match_operand:SI 2 "s_register_operand" "r,r")
10221 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10222 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10223 (clobber (reg:CC CC_REGNUM))]
10224 "TARGET_ARM"
10225 "#"
10226 [(set_attr "conds" "clob")
10227 (set_attr "length" "8,12")
10228 (set_attr "type" "multiple")]
10229 )
10230
10231 (define_insn "*if_plus_move"
10232 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10233 (if_then_else:SI
10234 (match_operator 4 "arm_comparison_operator"
10235 [(match_operand 5 "cc_register" "") (const_int 0)])
10236 (plus:SI
10237 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10238 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10239 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10240 "TARGET_ARM"
10241 "@
10242 add%d4\\t%0, %2, %3
10243 sub%d4\\t%0, %2, #%n3
10244 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10245 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10246 [(set_attr "conds" "use")
10247 (set_attr "length" "4,4,8,8")
10248 (set_attr_alternative "type"
10249 [(if_then_else (match_operand 3 "const_int_operand" "")
10250 (const_string "alu_imm" )
10251 (const_string "alu_sreg"))
10252 (const_string "alu_imm")
10253 (const_string "multiple")
10254 (const_string "multiple")])]
10255 )
10256
10257 (define_insn "*ifcompare_move_plus"
10258 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10259 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10260 [(match_operand:SI 4 "s_register_operand" "r,r")
10261 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10262 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10263 (plus:SI
10264 (match_operand:SI 2 "s_register_operand" "r,r")
10265 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10266 (clobber (reg:CC CC_REGNUM))]
10267 "TARGET_ARM"
10268 "#"
10269 [(set_attr "conds" "clob")
10270 (set_attr "length" "8,12")
10271 (set_attr "type" "multiple")]
10272 )
10273
10274 (define_insn "*if_move_plus"
10275 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10276 (if_then_else:SI
10277 (match_operator 4 "arm_comparison_operator"
10278 [(match_operand 5 "cc_register" "") (const_int 0)])
10279 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10280 (plus:SI
10281 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10282 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10283 "TARGET_ARM"
10284 "@
10285 add%D4\\t%0, %2, %3
10286 sub%D4\\t%0, %2, #%n3
10287 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10288 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10289 [(set_attr "conds" "use")
10290 (set_attr "length" "4,4,8,8")
10291 (set_attr_alternative "type"
10292 [(if_then_else (match_operand 3 "const_int_operand" "")
10293 (const_string "alu_imm" )
10294 (const_string "alu_sreg"))
10295 (const_string "alu_imm")
10296 (const_string "multiple")
10297 (const_string "multiple")])]
10298 )
10299
10300 (define_insn "*ifcompare_arith_arith"
10301 [(set (match_operand:SI 0 "s_register_operand" "=r")
10302 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10303 [(match_operand:SI 5 "s_register_operand" "r")
10304 (match_operand:SI 6 "arm_add_operand" "rIL")])
10305 (match_operator:SI 8 "shiftable_operator"
10306 [(match_operand:SI 1 "s_register_operand" "r")
10307 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10308 (match_operator:SI 7 "shiftable_operator"
10309 [(match_operand:SI 3 "s_register_operand" "r")
10310 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10311 (clobber (reg:CC CC_REGNUM))]
10312 "TARGET_ARM"
10313 "#"
10314 [(set_attr "conds" "clob")
10315 (set_attr "length" "12")
10316 (set_attr "type" "multiple")]
10317 )
10318
10319 (define_insn "*if_arith_arith"
10320 [(set (match_operand:SI 0 "s_register_operand" "=r")
10321 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10322 [(match_operand 8 "cc_register" "") (const_int 0)])
10323 (match_operator:SI 6 "shiftable_operator"
10324 [(match_operand:SI 1 "s_register_operand" "r")
10325 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10326 (match_operator:SI 7 "shiftable_operator"
10327 [(match_operand:SI 3 "s_register_operand" "r")
10328 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10329 "TARGET_ARM"
10330 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10331 [(set_attr "conds" "use")
10332 (set_attr "length" "8")
10333 (set_attr "type" "multiple")]
10334 )
10335
10336 (define_insn "*ifcompare_arith_move"
10337 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10338 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10339 [(match_operand:SI 2 "s_register_operand" "r,r")
10340 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10341 (match_operator:SI 7 "shiftable_operator"
10342 [(match_operand:SI 4 "s_register_operand" "r,r")
10343 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10344 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10345 (clobber (reg:CC CC_REGNUM))]
10346 "TARGET_ARM"
10347 "*
10348 /* If we have an operation where (op x 0) is the identity operation and
10349 the conditional operator is LT or GE and we are comparing against zero and
10350 everything is in registers then we can do this in two instructions. */
10351 if (operands[3] == const0_rtx
10352 && GET_CODE (operands[7]) != AND
10353 && REG_P (operands[5])
10354 && REG_P (operands[1])
10355 && REGNO (operands[1]) == REGNO (operands[4])
10356 && REGNO (operands[4]) != REGNO (operands[0]))
10357 {
10358 if (GET_CODE (operands[6]) == LT)
10359 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10360 else if (GET_CODE (operands[6]) == GE)
10361 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10362 }
10363 if (CONST_INT_P (operands[3])
10364 && !const_ok_for_arm (INTVAL (operands[3])))
10365 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10366 else
10367 output_asm_insn (\"cmp\\t%2, %3\", operands);
10368 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10369 if (which_alternative != 0)
10370 return \"mov%D6\\t%0, %1\";
10371 return \"\";
10372 "
10373 [(set_attr "conds" "clob")
10374 (set_attr "length" "8,12")
10375 (set_attr "type" "multiple")]
10376 )
10377
10378 (define_insn "*if_arith_move"
10379 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10380 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10381 [(match_operand 6 "cc_register" "") (const_int 0)])
10382 (match_operator:SI 5 "shiftable_operator"
10383 [(match_operand:SI 2 "s_register_operand" "r,r")
10384 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10385 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10386 "TARGET_ARM"
10387 "@
10388 %I5%d4\\t%0, %2, %3
10389 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10390 [(set_attr "conds" "use")
10391 (set_attr "length" "4,8")
10392 (set_attr_alternative "type"
10393 [(if_then_else (match_operand 3 "const_int_operand" "")
10394 (const_string "alu_shift_imm" )
10395 (const_string "alu_shift_reg"))
10396 (const_string "multiple")])]
10397 )
10398
10399 (define_insn "*ifcompare_move_arith"
10400 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10401 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10402 [(match_operand:SI 4 "s_register_operand" "r,r")
10403 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10404 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10405 (match_operator:SI 7 "shiftable_operator"
10406 [(match_operand:SI 2 "s_register_operand" "r,r")
10407 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10408 (clobber (reg:CC CC_REGNUM))]
10409 "TARGET_ARM"
10410 "*
10411 /* If we have an operation where (op x 0) is the identity operation and
10412 the conditional operator is LT or GE and we are comparing against zero and
10413 everything is in registers then we can do this in two instructions */
10414 if (operands[5] == const0_rtx
10415 && GET_CODE (operands[7]) != AND
10416 && REG_P (operands[3])
10417 && REG_P (operands[1])
10418 && REGNO (operands[1]) == REGNO (operands[2])
10419 && REGNO (operands[2]) != REGNO (operands[0]))
10420 {
10421 if (GET_CODE (operands[6]) == GE)
10422 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10423 else if (GET_CODE (operands[6]) == LT)
10424 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10425 }
10426
10427 if (CONST_INT_P (operands[5])
10428 && !const_ok_for_arm (INTVAL (operands[5])))
10429 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10430 else
10431 output_asm_insn (\"cmp\\t%4, %5\", operands);
10432
10433 if (which_alternative != 0)
10434 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10435 return \"%I7%D6\\t%0, %2, %3\";
10436 "
10437 [(set_attr "conds" "clob")
10438 (set_attr "length" "8,12")
10439 (set_attr "type" "multiple")]
10440 )
10441
10442 (define_insn "*if_move_arith"
10443 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10444 (if_then_else:SI
10445 (match_operator 4 "arm_comparison_operator"
10446 [(match_operand 6 "cc_register" "") (const_int 0)])
10447 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10448 (match_operator:SI 5 "shiftable_operator"
10449 [(match_operand:SI 2 "s_register_operand" "r,r")
10450 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10451 "TARGET_ARM"
10452 "@
10453 %I5%D4\\t%0, %2, %3
10454 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10455 [(set_attr "conds" "use")
10456 (set_attr "length" "4,8")
10457 (set_attr_alternative "type"
10458 [(if_then_else (match_operand 3 "const_int_operand" "")
10459 (const_string "alu_shift_imm" )
10460 (const_string "alu_shift_reg"))
10461 (const_string "multiple")])]
10462 )
10463
10464 (define_insn "*ifcompare_move_not"
10465 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10466 (if_then_else:SI
10467 (match_operator 5 "arm_comparison_operator"
10468 [(match_operand:SI 3 "s_register_operand" "r,r")
10469 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10470 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10471 (not:SI
10472 (match_operand:SI 2 "s_register_operand" "r,r"))))
10473 (clobber (reg:CC CC_REGNUM))]
10474 "TARGET_ARM"
10475 "#"
10476 [(set_attr "conds" "clob")
10477 (set_attr "length" "8,12")
10478 (set_attr "type" "multiple")]
10479 )
10480
10481 (define_insn "*if_move_not"
10482 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10483 (if_then_else:SI
10484 (match_operator 4 "arm_comparison_operator"
10485 [(match_operand 3 "cc_register" "") (const_int 0)])
10486 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10487 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10488 "TARGET_ARM"
10489 "@
10490 mvn%D4\\t%0, %2
10491 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10492 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10493 [(set_attr "conds" "use")
10494 (set_attr "type" "mvn_reg")
10495 (set_attr "length" "4,8,8")
10496 (set_attr "type" "mvn_reg,multiple,multiple")]
10497 )
10498
10499 (define_insn "*ifcompare_not_move"
10500 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10501 (if_then_else:SI
10502 (match_operator 5 "arm_comparison_operator"
10503 [(match_operand:SI 3 "s_register_operand" "r,r")
10504 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10505 (not:SI
10506 (match_operand:SI 2 "s_register_operand" "r,r"))
10507 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10508 (clobber (reg:CC CC_REGNUM))]
10509 "TARGET_ARM"
10510 "#"
10511 [(set_attr "conds" "clob")
10512 (set_attr "length" "8,12")
10513 (set_attr "type" "multiple")]
10514 )
10515
10516 (define_insn "*if_not_move"
10517 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10518 (if_then_else:SI
10519 (match_operator 4 "arm_comparison_operator"
10520 [(match_operand 3 "cc_register" "") (const_int 0)])
10521 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10522 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10523 "TARGET_ARM"
10524 "@
10525 mvn%d4\\t%0, %2
10526 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10527 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10528 [(set_attr "conds" "use")
10529 (set_attr "type" "mvn_reg,multiple,multiple")
10530 (set_attr "length" "4,8,8")]
10531 )
10532
10533 (define_insn "*ifcompare_shift_move"
10534 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10535 (if_then_else:SI
10536 (match_operator 6 "arm_comparison_operator"
10537 [(match_operand:SI 4 "s_register_operand" "r,r")
10538 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10539 (match_operator:SI 7 "shift_operator"
10540 [(match_operand:SI 2 "s_register_operand" "r,r")
10541 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10542 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10543 (clobber (reg:CC CC_REGNUM))]
10544 "TARGET_ARM"
10545 "#"
10546 [(set_attr "conds" "clob")
10547 (set_attr "length" "8,12")
10548 (set_attr "type" "multiple")]
10549 )
10550
10551 (define_insn "*if_shift_move"
10552 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10553 (if_then_else:SI
10554 (match_operator 5 "arm_comparison_operator"
10555 [(match_operand 6 "cc_register" "") (const_int 0)])
10556 (match_operator:SI 4 "shift_operator"
10557 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10558 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10559 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10560 "TARGET_ARM"
10561 "@
10562 mov%d5\\t%0, %2%S4
10563 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10564 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10565 [(set_attr "conds" "use")
10566 (set_attr "shift" "2")
10567 (set_attr "length" "4,8,8")
10568 (set_attr_alternative "type"
10569 [(if_then_else (match_operand 3 "const_int_operand" "")
10570 (const_string "mov_shift" )
10571 (const_string "mov_shift_reg"))
10572 (const_string "multiple")
10573 (const_string "multiple")])]
10574 )
10575
10576 (define_insn "*ifcompare_move_shift"
10577 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10578 (if_then_else:SI
10579 (match_operator 6 "arm_comparison_operator"
10580 [(match_operand:SI 4 "s_register_operand" "r,r")
10581 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10582 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10583 (match_operator:SI 7 "shift_operator"
10584 [(match_operand:SI 2 "s_register_operand" "r,r")
10585 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10586 (clobber (reg:CC CC_REGNUM))]
10587 "TARGET_ARM"
10588 "#"
10589 [(set_attr "conds" "clob")
10590 (set_attr "length" "8,12")
10591 (set_attr "type" "multiple")]
10592 )
10593
10594 (define_insn "*if_move_shift"
10595 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10596 (if_then_else:SI
10597 (match_operator 5 "arm_comparison_operator"
10598 [(match_operand 6 "cc_register" "") (const_int 0)])
10599 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10600 (match_operator:SI 4 "shift_operator"
10601 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10602 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10603 "TARGET_ARM"
10604 "@
10605 mov%D5\\t%0, %2%S4
10606 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10607 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10608 [(set_attr "conds" "use")
10609 (set_attr "shift" "2")
10610 (set_attr "length" "4,8,8")
10611 (set_attr_alternative "type"
10612 [(if_then_else (match_operand 3 "const_int_operand" "")
10613 (const_string "mov_shift" )
10614 (const_string "mov_shift_reg"))
10615 (const_string "multiple")
10616 (const_string "multiple")])]
10617 )
10618
10619 (define_insn "*ifcompare_shift_shift"
10620 [(set (match_operand:SI 0 "s_register_operand" "=r")
10621 (if_then_else:SI
10622 (match_operator 7 "arm_comparison_operator"
10623 [(match_operand:SI 5 "s_register_operand" "r")
10624 (match_operand:SI 6 "arm_add_operand" "rIL")])
10625 (match_operator:SI 8 "shift_operator"
10626 [(match_operand:SI 1 "s_register_operand" "r")
10627 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10628 (match_operator:SI 9 "shift_operator"
10629 [(match_operand:SI 3 "s_register_operand" "r")
10630 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10631 (clobber (reg:CC CC_REGNUM))]
10632 "TARGET_ARM"
10633 "#"
10634 [(set_attr "conds" "clob")
10635 (set_attr "length" "12")
10636 (set_attr "type" "multiple")]
10637 )
10638
10639 (define_insn "*if_shift_shift"
10640 [(set (match_operand:SI 0 "s_register_operand" "=r")
10641 (if_then_else:SI
10642 (match_operator 5 "arm_comparison_operator"
10643 [(match_operand 8 "cc_register" "") (const_int 0)])
10644 (match_operator:SI 6 "shift_operator"
10645 [(match_operand:SI 1 "s_register_operand" "r")
10646 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10647 (match_operator:SI 7 "shift_operator"
10648 [(match_operand:SI 3 "s_register_operand" "r")
10649 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10650 "TARGET_ARM"
10651 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10652 [(set_attr "conds" "use")
10653 (set_attr "shift" "1")
10654 (set_attr "length" "8")
10655 (set (attr "type") (if_then_else
10656 (and (match_operand 2 "const_int_operand" "")
10657 (match_operand 4 "const_int_operand" ""))
10658 (const_string "mov_shift")
10659 (const_string "mov_shift_reg")))]
10660 )
10661
10662 (define_insn "*ifcompare_not_arith"
10663 [(set (match_operand:SI 0 "s_register_operand" "=r")
10664 (if_then_else:SI
10665 (match_operator 6 "arm_comparison_operator"
10666 [(match_operand:SI 4 "s_register_operand" "r")
10667 (match_operand:SI 5 "arm_add_operand" "rIL")])
10668 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10669 (match_operator:SI 7 "shiftable_operator"
10670 [(match_operand:SI 2 "s_register_operand" "r")
10671 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10672 (clobber (reg:CC CC_REGNUM))]
10673 "TARGET_ARM"
10674 "#"
10675 [(set_attr "conds" "clob")
10676 (set_attr "length" "12")
10677 (set_attr "type" "multiple")]
10678 )
10679
10680 (define_insn "*if_not_arith"
10681 [(set (match_operand:SI 0 "s_register_operand" "=r")
10682 (if_then_else:SI
10683 (match_operator 5 "arm_comparison_operator"
10684 [(match_operand 4 "cc_register" "") (const_int 0)])
10685 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10686 (match_operator:SI 6 "shiftable_operator"
10687 [(match_operand:SI 2 "s_register_operand" "r")
10688 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10689 "TARGET_ARM"
10690 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10691 [(set_attr "conds" "use")
10692 (set_attr "type" "mvn_reg")
10693 (set_attr "length" "8")]
10694 )
10695
10696 (define_insn "*ifcompare_arith_not"
10697 [(set (match_operand:SI 0 "s_register_operand" "=r")
10698 (if_then_else:SI
10699 (match_operator 6 "arm_comparison_operator"
10700 [(match_operand:SI 4 "s_register_operand" "r")
10701 (match_operand:SI 5 "arm_add_operand" "rIL")])
10702 (match_operator:SI 7 "shiftable_operator"
10703 [(match_operand:SI 2 "s_register_operand" "r")
10704 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10705 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10706 (clobber (reg:CC CC_REGNUM))]
10707 "TARGET_ARM"
10708 "#"
10709 [(set_attr "conds" "clob")
10710 (set_attr "length" "12")
10711 (set_attr "type" "multiple")]
10712 )
10713
10714 (define_insn "*if_arith_not"
10715 [(set (match_operand:SI 0 "s_register_operand" "=r")
10716 (if_then_else:SI
10717 (match_operator 5 "arm_comparison_operator"
10718 [(match_operand 4 "cc_register" "") (const_int 0)])
10719 (match_operator:SI 6 "shiftable_operator"
10720 [(match_operand:SI 2 "s_register_operand" "r")
10721 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10722 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10723 "TARGET_ARM"
10724 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10725 [(set_attr "conds" "use")
10726 (set_attr "type" "multiple")
10727 (set_attr "length" "8")]
10728 )
10729
10730 (define_insn "*ifcompare_neg_move"
10731 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10732 (if_then_else:SI
10733 (match_operator 5 "arm_comparison_operator"
10734 [(match_operand:SI 3 "s_register_operand" "r,r")
10735 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10736 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10737 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10738 (clobber (reg:CC CC_REGNUM))]
10739 "TARGET_ARM"
10740 "#"
10741 [(set_attr "conds" "clob")
10742 (set_attr "length" "8,12")
10743 (set_attr "type" "multiple")]
10744 )
10745
10746 (define_insn_and_split "*if_neg_move"
10747 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10748 (if_then_else:SI
10749 (match_operator 4 "arm_comparison_operator"
10750 [(match_operand 3 "cc_register" "") (const_int 0)])
10751 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10752 (match_operand:SI 1 "s_register_operand" "0,0")))]
10753 "TARGET_32BIT"
10754 "#"
10755 "&& reload_completed"
10756 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10757 (set (match_dup 0) (neg:SI (match_dup 2))))]
10758 ""
10759 [(set_attr "conds" "use")
10760 (set_attr "length" "4")
10761 (set_attr "arch" "t2,32")
10762 (set_attr "enabled_for_short_it" "yes,no")
10763 (set_attr "type" "logic_shift_imm")]
10764 )
10765
10766 (define_insn "*ifcompare_move_neg"
10767 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10768 (if_then_else:SI
10769 (match_operator 5 "arm_comparison_operator"
10770 [(match_operand:SI 3 "s_register_operand" "r,r")
10771 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10772 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10773 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10774 (clobber (reg:CC CC_REGNUM))]
10775 "TARGET_ARM"
10776 "#"
10777 [(set_attr "conds" "clob")
10778 (set_attr "length" "8,12")
10779 (set_attr "type" "multiple")]
10780 )
10781
10782 (define_insn_and_split "*if_move_neg"
10783 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10784 (if_then_else:SI
10785 (match_operator 4 "arm_comparison_operator"
10786 [(match_operand 3 "cc_register" "") (const_int 0)])
10787 (match_operand:SI 1 "s_register_operand" "0,0")
10788 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10789 "TARGET_32BIT"
10790 "#"
10791 "&& reload_completed"
10792 [(cond_exec (match_dup 5)
10793 (set (match_dup 0) (neg:SI (match_dup 2))))]
10794 {
10795 machine_mode mode = GET_MODE (operands[3]);
10796 rtx_code rc = GET_CODE (operands[4]);
10797
10798 if (mode == CCFPmode || mode == CCFPEmode)
10799 rc = reverse_condition_maybe_unordered (rc);
10800 else
10801 rc = reverse_condition (rc);
10802
10803 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10804 }
10805 [(set_attr "conds" "use")
10806 (set_attr "length" "4")
10807 (set_attr "arch" "t2,32")
10808 (set_attr "enabled_for_short_it" "yes,no")
10809 (set_attr "type" "logic_shift_imm")]
10810 )
10811
10812 (define_insn "*arith_adjacentmem"
10813 [(set (match_operand:SI 0 "s_register_operand" "=r")
10814 (match_operator:SI 1 "shiftable_operator"
10815 [(match_operand:SI 2 "memory_operand" "m")
10816 (match_operand:SI 3 "memory_operand" "m")]))
10817 (clobber (match_scratch:SI 4 "=r"))]
10818 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10819 "*
10820 {
10821 rtx ldm[3];
10822 rtx arith[4];
10823 rtx base_reg;
10824 HOST_WIDE_INT val1 = 0, val2 = 0;
10825
10826 if (REGNO (operands[0]) > REGNO (operands[4]))
10827 {
10828 ldm[1] = operands[4];
10829 ldm[2] = operands[0];
10830 }
10831 else
10832 {
10833 ldm[1] = operands[0];
10834 ldm[2] = operands[4];
10835 }
10836
10837 base_reg = XEXP (operands[2], 0);
10838
10839 if (!REG_P (base_reg))
10840 {
10841 val1 = INTVAL (XEXP (base_reg, 1));
10842 base_reg = XEXP (base_reg, 0);
10843 }
10844
10845 if (!REG_P (XEXP (operands[3], 0)))
10846 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10847
10848 arith[0] = operands[0];
10849 arith[3] = operands[1];
10850
10851 if (val1 < val2)
10852 {
10853 arith[1] = ldm[1];
10854 arith[2] = ldm[2];
10855 }
10856 else
10857 {
10858 arith[1] = ldm[2];
10859 arith[2] = ldm[1];
10860 }
10861
10862 ldm[0] = base_reg;
10863 if (val1 !=0 && val2 != 0)
10864 {
10865 rtx ops[3];
10866
10867 if (val1 == 4 || val2 == 4)
10868 /* Other val must be 8, since we know they are adjacent and neither
10869 is zero. */
10870 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10871 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10872 {
10873 ldm[0] = ops[0] = operands[4];
10874 ops[1] = base_reg;
10875 ops[2] = GEN_INT (val1);
10876 output_add_immediate (ops);
10877 if (val1 < val2)
10878 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10879 else
10880 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10881 }
10882 else
10883 {
10884 /* Offset is out of range for a single add, so use two ldr. */
10885 ops[0] = ldm[1];
10886 ops[1] = base_reg;
10887 ops[2] = GEN_INT (val1);
10888 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10889 ops[0] = ldm[2];
10890 ops[2] = GEN_INT (val2);
10891 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10892 }
10893 }
10894 else if (val1 != 0)
10895 {
10896 if (val1 < val2)
10897 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10898 else
10899 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10900 }
10901 else
10902 {
10903 if (val1 < val2)
10904 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10905 else
10906 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10907 }
10908 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10909 return \"\";
10910 }"
10911 [(set_attr "length" "12")
10912 (set_attr "predicable" "yes")
10913 (set_attr "type" "load_4")]
10914 )
10915
10916 ; This pattern is never tried by combine, so do it as a peephole
10917
10918 (define_peephole2
10919 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10920 (match_operand:SI 1 "arm_general_register_operand" ""))
10921 (set (reg:CC CC_REGNUM)
10922 (compare:CC (match_dup 1) (const_int 0)))]
10923 "TARGET_ARM"
10924 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10925 (set (match_dup 0) (match_dup 1))])]
10926 ""
10927 )
10928
10929 (define_split
10930 [(set (match_operand:SI 0 "s_register_operand" "")
10931 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10932 (const_int 0))
10933 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10934 [(match_operand:SI 3 "s_register_operand" "")
10935 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10936 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10937 "TARGET_ARM"
10938 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10939 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10940 (match_dup 5)))]
10941 ""
10942 )
10943
10944 ;; This split can be used because CC_Z mode implies that the following
10945 ;; branch will be an equality, or an unsigned inequality, so the sign
10946 ;; extension is not needed.
10947
10948 (define_split
10949 [(set (reg:CC_Z CC_REGNUM)
10950 (compare:CC_Z
10951 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10952 (const_int 24))
10953 (match_operand 1 "const_int_operand" "")))
10954 (clobber (match_scratch:SI 2 ""))]
10955 "TARGET_ARM
10956 && ((UINTVAL (operands[1]))
10957 == ((UINTVAL (operands[1])) >> 24) << 24)"
10958 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10959 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10960 "
10961 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10962 "
10963 )
10964 ;; ??? Check the patterns above for Thumb-2 usefulness
10965
10966 (define_expand "prologue"
10967 [(clobber (const_int 0))]
10968 "TARGET_EITHER"
10969 "if (TARGET_32BIT)
10970 arm_expand_prologue ();
10971 else
10972 thumb1_expand_prologue ();
10973 DONE;
10974 "
10975 )
10976
10977 (define_expand "epilogue"
10978 [(clobber (const_int 0))]
10979 "TARGET_EITHER"
10980 "
10981 if (crtl->calls_eh_return)
10982 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10983 if (TARGET_THUMB1)
10984 {
10985 thumb1_expand_epilogue ();
10986 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10987 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10988 }
10989 else if (HAVE_return)
10990 {
10991 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10992 no need for explicit testing again. */
10993 emit_jump_insn (gen_return ());
10994 }
10995 else if (TARGET_32BIT)
10996 {
10997 arm_expand_epilogue (true);
10998 }
10999 DONE;
11000 "
11001 )
11002
11003 ;; Note - although unspec_volatile's USE all hard registers,
11004 ;; USEs are ignored after relaod has completed. Thus we need
11005 ;; to add an unspec of the link register to ensure that flow
11006 ;; does not think that it is unused by the sibcall branch that
11007 ;; will replace the standard function epilogue.
11008 (define_expand "sibcall_epilogue"
11009 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
11010 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
11011 "TARGET_32BIT"
11012 "
11013 arm_expand_epilogue (false);
11014 DONE;
11015 "
11016 )
11017
11018 (define_expand "eh_epilogue"
11019 [(use (match_operand:SI 0 "register_operand" ""))
11020 (use (match_operand:SI 1 "register_operand" ""))
11021 (use (match_operand:SI 2 "register_operand" ""))]
11022 "TARGET_EITHER"
11023 "
11024 {
11025 cfun->machine->eh_epilogue_sp_ofs = operands[1];
11026 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11027 {
11028 rtx ra = gen_rtx_REG (Pmode, 2);
11029
11030 emit_move_insn (ra, operands[2]);
11031 operands[2] = ra;
11032 }
11033 /* This is a hack -- we may have crystalized the function type too
11034 early. */
11035 cfun->machine->func_type = 0;
11036 }"
11037 )
11038
11039 ;; This split is only used during output to reduce the number of patterns
11040 ;; that need assembler instructions adding to them. We allowed the setting
11041 ;; of the conditions to be implicit during rtl generation so that
11042 ;; the conditional compare patterns would work. However this conflicts to
11043 ;; some extent with the conditional data operations, so we have to split them
11044 ;; up again here.
11045
11046 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
11047 ;; conditional execution sufficient?
11048
11049 (define_split
11050 [(set (match_operand:SI 0 "s_register_operand" "")
11051 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11052 [(match_operand 2 "" "") (match_operand 3 "" "")])
11053 (match_dup 0)
11054 (match_operand 4 "" "")))
11055 (clobber (reg:CC CC_REGNUM))]
11056 "TARGET_ARM && reload_completed"
11057 [(set (match_dup 5) (match_dup 6))
11058 (cond_exec (match_dup 7)
11059 (set (match_dup 0) (match_dup 4)))]
11060 "
11061 {
11062 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11063 operands[2], operands[3]);
11064 enum rtx_code rc = GET_CODE (operands[1]);
11065
11066 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11067 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11068 if (mode == CCFPmode || mode == CCFPEmode)
11069 rc = reverse_condition_maybe_unordered (rc);
11070 else
11071 rc = reverse_condition (rc);
11072
11073 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11074 }"
11075 )
11076
11077 (define_split
11078 [(set (match_operand:SI 0 "s_register_operand" "")
11079 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11080 [(match_operand 2 "" "") (match_operand 3 "" "")])
11081 (match_operand 4 "" "")
11082 (match_dup 0)))
11083 (clobber (reg:CC CC_REGNUM))]
11084 "TARGET_ARM && reload_completed"
11085 [(set (match_dup 5) (match_dup 6))
11086 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11087 (set (match_dup 0) (match_dup 4)))]
11088 "
11089 {
11090 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11091 operands[2], operands[3]);
11092
11093 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11094 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11095 }"
11096 )
11097
11098 (define_split
11099 [(set (match_operand:SI 0 "s_register_operand" "")
11100 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11101 [(match_operand 2 "" "") (match_operand 3 "" "")])
11102 (match_operand 4 "" "")
11103 (match_operand 5 "" "")))
11104 (clobber (reg:CC CC_REGNUM))]
11105 "TARGET_ARM && reload_completed"
11106 [(set (match_dup 6) (match_dup 7))
11107 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11108 (set (match_dup 0) (match_dup 4)))
11109 (cond_exec (match_dup 8)
11110 (set (match_dup 0) (match_dup 5)))]
11111 "
11112 {
11113 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11114 operands[2], operands[3]);
11115 enum rtx_code rc = GET_CODE (operands[1]);
11116
11117 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11118 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11119 if (mode == CCFPmode || mode == CCFPEmode)
11120 rc = reverse_condition_maybe_unordered (rc);
11121 else
11122 rc = reverse_condition (rc);
11123
11124 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11125 }"
11126 )
11127
11128 (define_split
11129 [(set (match_operand:SI 0 "s_register_operand" "")
11130 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11131 [(match_operand:SI 2 "s_register_operand" "")
11132 (match_operand:SI 3 "arm_add_operand" "")])
11133 (match_operand:SI 4 "arm_rhs_operand" "")
11134 (not:SI
11135 (match_operand:SI 5 "s_register_operand" ""))))
11136 (clobber (reg:CC CC_REGNUM))]
11137 "TARGET_ARM && reload_completed"
11138 [(set (match_dup 6) (match_dup 7))
11139 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11140 (set (match_dup 0) (match_dup 4)))
11141 (cond_exec (match_dup 8)
11142 (set (match_dup 0) (not:SI (match_dup 5))))]
11143 "
11144 {
11145 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11146 operands[2], operands[3]);
11147 enum rtx_code rc = GET_CODE (operands[1]);
11148
11149 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11150 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11151 if (mode == CCFPmode || mode == CCFPEmode)
11152 rc = reverse_condition_maybe_unordered (rc);
11153 else
11154 rc = reverse_condition (rc);
11155
11156 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11157 }"
11158 )
11159
11160 (define_insn "*cond_move_not"
11161 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11162 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11163 [(match_operand 3 "cc_register" "") (const_int 0)])
11164 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11165 (not:SI
11166 (match_operand:SI 2 "s_register_operand" "r,r"))))]
11167 "TARGET_ARM"
11168 "@
11169 mvn%D4\\t%0, %2
11170 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11171 [(set_attr "conds" "use")
11172 (set_attr "type" "mvn_reg,multiple")
11173 (set_attr "length" "4,8")]
11174 )
11175
11176 ;; The next two patterns occur when an AND operation is followed by a
11177 ;; scc insn sequence
11178
11179 (define_insn "*sign_extract_onebit"
11180 [(set (match_operand:SI 0 "s_register_operand" "=r")
11181 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11182 (const_int 1)
11183 (match_operand:SI 2 "const_int_operand" "n")))
11184 (clobber (reg:CC CC_REGNUM))]
11185 "TARGET_ARM"
11186 "*
11187 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11188 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
11189 return \"mvnne\\t%0, #0\";
11190 "
11191 [(set_attr "conds" "clob")
11192 (set_attr "length" "8")
11193 (set_attr "type" "multiple")]
11194 )
11195
11196 (define_insn "*not_signextract_onebit"
11197 [(set (match_operand:SI 0 "s_register_operand" "=r")
11198 (not:SI
11199 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11200 (const_int 1)
11201 (match_operand:SI 2 "const_int_operand" "n"))))
11202 (clobber (reg:CC CC_REGNUM))]
11203 "TARGET_ARM"
11204 "*
11205 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11206 output_asm_insn (\"tst\\t%1, %2\", operands);
11207 output_asm_insn (\"mvneq\\t%0, #0\", operands);
11208 return \"movne\\t%0, #0\";
11209 "
11210 [(set_attr "conds" "clob")
11211 (set_attr "length" "12")
11212 (set_attr "type" "multiple")]
11213 )
11214 ;; ??? The above patterns need auditing for Thumb-2
11215
11216 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
11217 ;; expressions. For simplicity, the first register is also in the unspec
11218 ;; part.
11219 ;; To avoid the usage of GNU extension, the length attribute is computed
11220 ;; in a C function arm_attr_length_push_multi.
11221 (define_insn "*push_multi"
11222 [(match_parallel 2 "multi_register_push"
11223 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11224 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11225 UNSPEC_PUSH_MULT))])]
11226 ""
11227 "*
11228 {
11229 int num_saves = XVECLEN (operands[2], 0);
11230
11231 /* For the StrongARM at least it is faster to
11232 use STR to store only a single register.
11233 In Thumb mode always use push, and the assembler will pick
11234 something appropriate. */
11235 if (num_saves == 1 && TARGET_ARM)
11236 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11237 else
11238 {
11239 int i;
11240 char pattern[100];
11241
11242 if (TARGET_32BIT)
11243 strcpy (pattern, \"push%?\\t{%1\");
11244 else
11245 strcpy (pattern, \"push\\t{%1\");
11246
11247 for (i = 1; i < num_saves; i++)
11248 {
11249 strcat (pattern, \", %|\");
11250 strcat (pattern,
11251 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11252 }
11253
11254 strcat (pattern, \"}\");
11255 output_asm_insn (pattern, operands);
11256 }
11257
11258 return \"\";
11259 }"
11260 [(set_attr "type" "store_16")
11261 (set (attr "length")
11262 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11263 )
11264
11265 (define_insn "stack_tie"
11266 [(set (mem:BLK (scratch))
11267 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11268 (match_operand:SI 1 "s_register_operand" "rk")]
11269 UNSPEC_PRLG_STK))]
11270 ""
11271 ""
11272 [(set_attr "length" "0")
11273 (set_attr "type" "block")]
11274 )
11275
11276 ;; Pop (as used in epilogue RTL)
11277 ;;
11278 (define_insn "*load_multiple_with_writeback"
11279 [(match_parallel 0 "load_multiple_operation"
11280 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11281 (plus:SI (match_dup 1)
11282 (match_operand:SI 2 "const_int_I_operand" "I")))
11283 (set (match_operand:SI 3 "s_register_operand" "=rk")
11284 (mem:SI (match_dup 1)))
11285 ])]
11286 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11287 "*
11288 {
11289 arm_output_multireg_pop (operands, /*return_pc=*/false,
11290 /*cond=*/const_true_rtx,
11291 /*reverse=*/false,
11292 /*update=*/true);
11293 return \"\";
11294 }
11295 "
11296 [(set_attr "type" "load_16")
11297 (set_attr "predicable" "yes")
11298 (set (attr "length")
11299 (symbol_ref "arm_attr_length_pop_multi (operands,
11300 /*return_pc=*/false,
11301 /*write_back_p=*/true)"))]
11302 )
11303
11304 ;; Pop with return (as used in epilogue RTL)
11305 ;;
11306 ;; This instruction is generated when the registers are popped at the end of
11307 ;; epilogue. Here, instead of popping the value into LR and then generating
11308 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11309 ;; with (return).
11310 (define_insn "*pop_multiple_with_writeback_and_return"
11311 [(match_parallel 0 "pop_multiple_return"
11312 [(return)
11313 (set (match_operand:SI 1 "s_register_operand" "+rk")
11314 (plus:SI (match_dup 1)
11315 (match_operand:SI 2 "const_int_I_operand" "I")))
11316 (set (match_operand:SI 3 "s_register_operand" "=rk")
11317 (mem:SI (match_dup 1)))
11318 ])]
11319 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11320 "*
11321 {
11322 arm_output_multireg_pop (operands, /*return_pc=*/true,
11323 /*cond=*/const_true_rtx,
11324 /*reverse=*/false,
11325 /*update=*/true);
11326 return \"\";
11327 }
11328 "
11329 [(set_attr "type" "load_16")
11330 (set_attr "predicable" "yes")
11331 (set (attr "length")
11332 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11333 /*write_back_p=*/true)"))]
11334 )
11335
11336 (define_insn "*pop_multiple_with_return"
11337 [(match_parallel 0 "pop_multiple_return"
11338 [(return)
11339 (set (match_operand:SI 2 "s_register_operand" "=rk")
11340 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11341 ])]
11342 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11343 "*
11344 {
11345 arm_output_multireg_pop (operands, /*return_pc=*/true,
11346 /*cond=*/const_true_rtx,
11347 /*reverse=*/false,
11348 /*update=*/false);
11349 return \"\";
11350 }
11351 "
11352 [(set_attr "type" "load_16")
11353 (set_attr "predicable" "yes")
11354 (set (attr "length")
11355 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11356 /*write_back_p=*/false)"))]
11357 )
11358
11359 ;; Load into PC and return
11360 (define_insn "*ldr_with_return"
11361 [(return)
11362 (set (reg:SI PC_REGNUM)
11363 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11364 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11365 "ldr%?\t%|pc, [%0], #4"
11366 [(set_attr "type" "load_4")
11367 (set_attr "predicable" "yes")]
11368 )
11369 ;; Pop for floating point registers (as used in epilogue RTL)
11370 (define_insn "*vfp_pop_multiple_with_writeback"
11371 [(match_parallel 0 "pop_multiple_fp"
11372 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11373 (plus:SI (match_dup 1)
11374 (match_operand:SI 2 "const_int_I_operand" "I")))
11375 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11376 (mem:DF (match_dup 1)))])]
11377 "TARGET_32BIT && TARGET_HARD_FLOAT"
11378 "*
11379 {
11380 int num_regs = XVECLEN (operands[0], 0);
11381 char pattern[100];
11382 rtx op_list[2];
11383 strcpy (pattern, \"vldm\\t\");
11384 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11385 strcat (pattern, \"!, {\");
11386 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11387 strcat (pattern, \"%P0\");
11388 if ((num_regs - 1) > 1)
11389 {
11390 strcat (pattern, \"-%P1\");
11391 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11392 }
11393
11394 strcat (pattern, \"}\");
11395 output_asm_insn (pattern, op_list);
11396 return \"\";
11397 }
11398 "
11399 [(set_attr "type" "load_16")
11400 (set_attr "conds" "unconditional")
11401 (set_attr "predicable" "no")]
11402 )
11403
11404 ;; Special patterns for dealing with the constant pool
11405
11406 (define_insn "align_4"
11407 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11408 "TARGET_EITHER"
11409 "*
11410 assemble_align (32);
11411 return \"\";
11412 "
11413 [(set_attr "type" "no_insn")]
11414 )
11415
11416 (define_insn "align_8"
11417 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11418 "TARGET_EITHER"
11419 "*
11420 assemble_align (64);
11421 return \"\";
11422 "
11423 [(set_attr "type" "no_insn")]
11424 )
11425
11426 (define_insn "consttable_end"
11427 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11428 "TARGET_EITHER"
11429 "*
11430 making_const_table = FALSE;
11431 return \"\";
11432 "
11433 [(set_attr "type" "no_insn")]
11434 )
11435
11436 (define_insn "consttable_1"
11437 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11438 "TARGET_EITHER"
11439 "*
11440 making_const_table = TRUE;
11441 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11442 assemble_zeros (3);
11443 return \"\";
11444 "
11445 [(set_attr "length" "4")
11446 (set_attr "type" "no_insn")]
11447 )
11448
11449 (define_insn "consttable_2"
11450 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11451 "TARGET_EITHER"
11452 "*
11453 {
11454 rtx x = operands[0];
11455 making_const_table = TRUE;
11456 switch (GET_MODE_CLASS (GET_MODE (x)))
11457 {
11458 case MODE_FLOAT:
11459 arm_emit_fp16_const (x);
11460 break;
11461 default:
11462 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11463 assemble_zeros (2);
11464 break;
11465 }
11466 return \"\";
11467 }"
11468 [(set_attr "length" "4")
11469 (set_attr "type" "no_insn")]
11470 )
11471
11472 (define_insn "consttable_4"
11473 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11474 "TARGET_EITHER"
11475 "*
11476 {
11477 rtx x = operands[0];
11478 making_const_table = TRUE;
11479 scalar_float_mode float_mode;
11480 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11481 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11482 else
11483 {
11484 /* XXX: Sometimes gcc does something really dumb and ends up with
11485 a HIGH in a constant pool entry, usually because it's trying to
11486 load into a VFP register. We know this will always be used in
11487 combination with a LO_SUM which ignores the high bits, so just
11488 strip off the HIGH. */
11489 if (GET_CODE (x) == HIGH)
11490 x = XEXP (x, 0);
11491 assemble_integer (x, 4, BITS_PER_WORD, 1);
11492 mark_symbol_refs_as_used (x);
11493 }
11494 return \"\";
11495 }"
11496 [(set_attr "length" "4")
11497 (set_attr "type" "no_insn")]
11498 )
11499
11500 (define_insn "consttable_8"
11501 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11502 "TARGET_EITHER"
11503 "*
11504 {
11505 making_const_table = TRUE;
11506 scalar_float_mode float_mode;
11507 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11508 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11509 float_mode, BITS_PER_WORD);
11510 else
11511 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11512 return \"\";
11513 }"
11514 [(set_attr "length" "8")
11515 (set_attr "type" "no_insn")]
11516 )
11517
11518 (define_insn "consttable_16"
11519 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11520 "TARGET_EITHER"
11521 "*
11522 {
11523 making_const_table = TRUE;
11524 scalar_float_mode float_mode;
11525 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11526 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11527 float_mode, BITS_PER_WORD);
11528 else
11529 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11530 return \"\";
11531 }"
11532 [(set_attr "length" "16")
11533 (set_attr "type" "no_insn")]
11534 )
11535
11536 ;; V5 Instructions,
11537
11538 (define_insn "clzsi2"
11539 [(set (match_operand:SI 0 "s_register_operand" "=r")
11540 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11541 "TARGET_32BIT && arm_arch5t"
11542 "clz%?\\t%0, %1"
11543 [(set_attr "predicable" "yes")
11544 (set_attr "type" "clz")])
11545
11546 (define_insn "rbitsi2"
11547 [(set (match_operand:SI 0 "s_register_operand" "=r")
11548 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11549 "TARGET_32BIT && arm_arch_thumb2"
11550 "rbit%?\\t%0, %1"
11551 [(set_attr "predicable" "yes")
11552 (set_attr "type" "clz")])
11553
11554 ;; Keep this as a CTZ expression until after reload and then split
11555 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11556 ;; to fold with any other expression.
11557
11558 (define_insn_and_split "ctzsi2"
11559 [(set (match_operand:SI 0 "s_register_operand" "=r")
11560 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11561 "TARGET_32BIT && arm_arch_thumb2"
11562 "#"
11563 "&& reload_completed"
11564 [(const_int 0)]
11565 "
11566 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11567 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11568 DONE;
11569 ")
11570
11571 ;; V5E instructions.
11572
11573 (define_insn "prefetch"
11574 [(prefetch (match_operand:SI 0 "address_operand" "p")
11575 (match_operand:SI 1 "" "")
11576 (match_operand:SI 2 "" ""))]
11577 "TARGET_32BIT && arm_arch5te"
11578 "pld\\t%a0"
11579 [(set_attr "type" "load_4")]
11580 )
11581
11582 ;; General predication pattern
11583
11584 (define_cond_exec
11585 [(match_operator 0 "arm_comparison_operator"
11586 [(match_operand 1 "cc_register" "")
11587 (const_int 0)])]
11588 "TARGET_32BIT
11589 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11590 ""
11591 [(set_attr "predicated" "yes")]
11592 )
11593
11594 (define_insn "force_register_use"
11595 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11596 ""
11597 "%@ %0 needed"
11598 [(set_attr "length" "0")
11599 (set_attr "type" "no_insn")]
11600 )
11601
11602
11603 ;; Patterns for exception handling
11604
11605 (define_expand "eh_return"
11606 [(use (match_operand 0 "general_operand" ""))]
11607 "TARGET_EITHER"
11608 "
11609 {
11610 if (TARGET_32BIT)
11611 emit_insn (gen_arm_eh_return (operands[0]));
11612 else
11613 emit_insn (gen_thumb_eh_return (operands[0]));
11614 DONE;
11615 }"
11616 )
11617
11618 ;; We can't expand this before we know where the link register is stored.
11619 (define_insn_and_split "arm_eh_return"
11620 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11621 VUNSPEC_EH_RETURN)
11622 (clobber (match_scratch:SI 1 "=&r"))]
11623 "TARGET_ARM"
11624 "#"
11625 "&& reload_completed"
11626 [(const_int 0)]
11627 "
11628 {
11629 arm_set_return_address (operands[0], operands[1]);
11630 DONE;
11631 }"
11632 )
11633
11634 \f
11635 ;; TLS support
11636
11637 (define_insn "load_tp_hard"
11638 [(set (match_operand:SI 0 "register_operand" "=r")
11639 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11640 "TARGET_HARD_TP"
11641 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11642 [(set_attr "predicable" "yes")
11643 (set_attr "type" "mrs")]
11644 )
11645
11646 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11647 (define_insn "load_tp_soft"
11648 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11649 (clobber (reg:SI LR_REGNUM))
11650 (clobber (reg:SI IP_REGNUM))
11651 (clobber (reg:CC CC_REGNUM))]
11652 "TARGET_SOFT_TP"
11653 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11654 [(set_attr "conds" "clob")
11655 (set_attr "type" "branch")]
11656 )
11657
11658 ;; tls descriptor call
11659 (define_insn "tlscall"
11660 [(set (reg:SI R0_REGNUM)
11661 (unspec:SI [(reg:SI R0_REGNUM)
11662 (match_operand:SI 0 "" "X")
11663 (match_operand 1 "" "")] UNSPEC_TLS))
11664 (clobber (reg:SI R1_REGNUM))
11665 (clobber (reg:SI LR_REGNUM))
11666 (clobber (reg:SI CC_REGNUM))]
11667 "TARGET_GNU2_TLS"
11668 {
11669 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11670 INTVAL (operands[1]));
11671 return "bl\\t%c0(tlscall)";
11672 }
11673 [(set_attr "conds" "clob")
11674 (set_attr "length" "4")
11675 (set_attr "type" "branch")]
11676 )
11677
11678 ;; For thread pointer builtin
11679 (define_expand "get_thread_pointersi"
11680 [(match_operand:SI 0 "s_register_operand" "=r")]
11681 ""
11682 "
11683 {
11684 arm_load_tp (operands[0]);
11685 DONE;
11686 }")
11687
11688 ;;
11689
11690 ;; We only care about the lower 16 bits of the constant
11691 ;; being inserted into the upper 16 bits of the register.
11692 (define_insn "*arm_movtas_ze"
11693 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11694 (const_int 16)
11695 (const_int 16))
11696 (match_operand:SI 1 "const_int_operand" ""))]
11697 "TARGET_HAVE_MOVT"
11698 "@
11699 movt%?\t%0, %L1
11700 movt\t%0, %L1"
11701 [(set_attr "arch" "32,v8mb")
11702 (set_attr "predicable" "yes")
11703 (set_attr "length" "4")
11704 (set_attr "type" "alu_sreg")]
11705 )
11706
11707 (define_insn "*arm_rev"
11708 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11709 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11710 "arm_arch6"
11711 "@
11712 rev\t%0, %1
11713 rev%?\t%0, %1
11714 rev%?\t%0, %1"
11715 [(set_attr "arch" "t1,t2,32")
11716 (set_attr "length" "2,2,4")
11717 (set_attr "predicable" "no,yes,yes")
11718 (set_attr "type" "rev")]
11719 )
11720
11721 (define_expand "arm_legacy_rev"
11722 [(set (match_operand:SI 2 "s_register_operand" "")
11723 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11724 (const_int 16))
11725 (match_dup 1)))
11726 (set (match_dup 2)
11727 (lshiftrt:SI (match_dup 2)
11728 (const_int 8)))
11729 (set (match_operand:SI 3 "s_register_operand" "")
11730 (rotatert:SI (match_dup 1)
11731 (const_int 8)))
11732 (set (match_dup 2)
11733 (and:SI (match_dup 2)
11734 (const_int -65281)))
11735 (set (match_operand:SI 0 "s_register_operand" "")
11736 (xor:SI (match_dup 3)
11737 (match_dup 2)))]
11738 "TARGET_32BIT"
11739 ""
11740 )
11741
11742 ;; Reuse temporaries to keep register pressure down.
11743 (define_expand "thumb_legacy_rev"
11744 [(set (match_operand:SI 2 "s_register_operand" "")
11745 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11746 (const_int 24)))
11747 (set (match_operand:SI 3 "s_register_operand" "")
11748 (lshiftrt:SI (match_dup 1)
11749 (const_int 24)))
11750 (set (match_dup 3)
11751 (ior:SI (match_dup 3)
11752 (match_dup 2)))
11753 (set (match_operand:SI 4 "s_register_operand" "")
11754 (const_int 16))
11755 (set (match_operand:SI 5 "s_register_operand" "")
11756 (rotatert:SI (match_dup 1)
11757 (match_dup 4)))
11758 (set (match_dup 2)
11759 (ashift:SI (match_dup 5)
11760 (const_int 24)))
11761 (set (match_dup 5)
11762 (lshiftrt:SI (match_dup 5)
11763 (const_int 24)))
11764 (set (match_dup 5)
11765 (ior:SI (match_dup 5)
11766 (match_dup 2)))
11767 (set (match_dup 5)
11768 (rotatert:SI (match_dup 5)
11769 (match_dup 4)))
11770 (set (match_operand:SI 0 "s_register_operand" "")
11771 (ior:SI (match_dup 5)
11772 (match_dup 3)))]
11773 "TARGET_THUMB"
11774 ""
11775 )
11776
11777 ;; ARM-specific expansion of signed mod by power of 2
11778 ;; using conditional negate.
11779 ;; For r0 % n where n is a power of 2 produce:
11780 ;; rsbs r1, r0, #0
11781 ;; and r0, r0, #(n - 1)
11782 ;; and r1, r1, #(n - 1)
11783 ;; rsbpl r0, r1, #0
11784
11785 (define_expand "modsi3"
11786 [(match_operand:SI 0 "register_operand" "")
11787 (match_operand:SI 1 "register_operand" "")
11788 (match_operand:SI 2 "const_int_operand" "")]
11789 "TARGET_32BIT"
11790 {
11791 HOST_WIDE_INT val = INTVAL (operands[2]);
11792
11793 if (val <= 0
11794 || exact_log2 (val) <= 0)
11795 FAIL;
11796
11797 rtx mask = GEN_INT (val - 1);
11798
11799 /* In the special case of x0 % 2 we can do the even shorter:
11800 cmp r0, #0
11801 and r0, r0, #1
11802 rsblt r0, r0, #0. */
11803
11804 if (val == 2)
11805 {
11806 rtx cc_reg = arm_gen_compare_reg (LT,
11807 operands[1], const0_rtx, NULL_RTX);
11808 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11809 rtx masked = gen_reg_rtx (SImode);
11810
11811 emit_insn (gen_andsi3 (masked, operands[1], mask));
11812 emit_move_insn (operands[0],
11813 gen_rtx_IF_THEN_ELSE (SImode, cond,
11814 gen_rtx_NEG (SImode,
11815 masked),
11816 masked));
11817 DONE;
11818 }
11819
11820 rtx neg_op = gen_reg_rtx (SImode);
11821 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11822 operands[1]));
11823
11824 /* Extract the condition register and mode. */
11825 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11826 rtx cc_reg = SET_DEST (cmp);
11827 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11828
11829 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11830
11831 rtx masked_neg = gen_reg_rtx (SImode);
11832 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11833
11834 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11835 during expand does not always work. Do an IF_THEN_ELSE instead. */
11836 emit_move_insn (operands[0],
11837 gen_rtx_IF_THEN_ELSE (SImode, cond,
11838 gen_rtx_NEG (SImode, masked_neg),
11839 operands[0]));
11840
11841
11842 DONE;
11843 }
11844 )
11845
11846 (define_expand "bswapsi2"
11847 [(set (match_operand:SI 0 "s_register_operand" "=r")
11848 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11849 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11850 "
11851 if (!arm_arch6)
11852 {
11853 rtx op2 = gen_reg_rtx (SImode);
11854 rtx op3 = gen_reg_rtx (SImode);
11855
11856 if (TARGET_THUMB)
11857 {
11858 rtx op4 = gen_reg_rtx (SImode);
11859 rtx op5 = gen_reg_rtx (SImode);
11860
11861 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11862 op2, op3, op4, op5));
11863 }
11864 else
11865 {
11866 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11867 op2, op3));
11868 }
11869
11870 DONE;
11871 }
11872 "
11873 )
11874
11875 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11876 ;; and unsigned variants, respectively. For rev16, expose
11877 ;; byte-swapping in the lower 16 bits only.
11878 (define_insn "*arm_revsh"
11879 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11880 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11881 "arm_arch6"
11882 "@
11883 revsh\t%0, %1
11884 revsh%?\t%0, %1
11885 revsh%?\t%0, %1"
11886 [(set_attr "arch" "t1,t2,32")
11887 (set_attr "length" "2,2,4")
11888 (set_attr "type" "rev")]
11889 )
11890
11891 (define_insn "*arm_rev16"
11892 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11893 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11894 "arm_arch6"
11895 "@
11896 rev16\t%0, %1
11897 rev16%?\t%0, %1
11898 rev16%?\t%0, %1"
11899 [(set_attr "arch" "t1,t2,32")
11900 (set_attr "length" "2,2,4")
11901 (set_attr "type" "rev")]
11902 )
11903
11904 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11905 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11906 ;; each valid permutation.
11907
11908 (define_insn "arm_rev16si2"
11909 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11910 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11911 (const_int 8))
11912 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11913 (and:SI (lshiftrt:SI (match_dup 1)
11914 (const_int 8))
11915 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11916 "arm_arch6
11917 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11918 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11919 "rev16\\t%0, %1"
11920 [(set_attr "arch" "t1,t2,32")
11921 (set_attr "length" "2,2,4")
11922 (set_attr "type" "rev")]
11923 )
11924
11925 (define_insn "arm_rev16si2_alt"
11926 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11927 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11928 (const_int 8))
11929 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11930 (and:SI (ashift:SI (match_dup 1)
11931 (const_int 8))
11932 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11933 "arm_arch6
11934 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11935 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11936 "rev16\\t%0, %1"
11937 [(set_attr "arch" "t1,t2,32")
11938 (set_attr "length" "2,2,4")
11939 (set_attr "type" "rev")]
11940 )
11941
11942 (define_expand "bswaphi2"
11943 [(set (match_operand:HI 0 "s_register_operand" "=r")
11944 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11945 "arm_arch6"
11946 ""
11947 )
11948
11949 ;; Patterns for LDRD/STRD in Thumb2 mode
11950
11951 (define_insn "*thumb2_ldrd"
11952 [(set (match_operand:SI 0 "s_register_operand" "=r")
11953 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11954 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11955 (set (match_operand:SI 3 "s_register_operand" "=r")
11956 (mem:SI (plus:SI (match_dup 1)
11957 (match_operand:SI 4 "const_int_operand" ""))))]
11958 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11959 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11960 && (operands_ok_ldrd_strd (operands[0], operands[3],
11961 operands[1], INTVAL (operands[2]),
11962 false, true))"
11963 "ldrd%?\t%0, %3, [%1, %2]"
11964 [(set_attr "type" "load_8")
11965 (set_attr "predicable" "yes")])
11966
11967 (define_insn "*thumb2_ldrd_base"
11968 [(set (match_operand:SI 0 "s_register_operand" "=r")
11969 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11970 (set (match_operand:SI 2 "s_register_operand" "=r")
11971 (mem:SI (plus:SI (match_dup 1)
11972 (const_int 4))))]
11973 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11974 && (operands_ok_ldrd_strd (operands[0], operands[2],
11975 operands[1], 0, false, true))"
11976 "ldrd%?\t%0, %2, [%1]"
11977 [(set_attr "type" "load_8")
11978 (set_attr "predicable" "yes")])
11979
11980 (define_insn "*thumb2_ldrd_base_neg"
11981 [(set (match_operand:SI 0 "s_register_operand" "=r")
11982 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11983 (const_int -4))))
11984 (set (match_operand:SI 2 "s_register_operand" "=r")
11985 (mem:SI (match_dup 1)))]
11986 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11987 && (operands_ok_ldrd_strd (operands[0], operands[2],
11988 operands[1], -4, false, true))"
11989 "ldrd%?\t%0, %2, [%1, #-4]"
11990 [(set_attr "type" "load_8")
11991 (set_attr "predicable" "yes")])
11992
11993 (define_insn "*thumb2_strd"
11994 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11995 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11996 (match_operand:SI 2 "s_register_operand" "r"))
11997 (set (mem:SI (plus:SI (match_dup 0)
11998 (match_operand:SI 3 "const_int_operand" "")))
11999 (match_operand:SI 4 "s_register_operand" "r"))]
12000 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12001 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
12002 && (operands_ok_ldrd_strd (operands[2], operands[4],
12003 operands[0], INTVAL (operands[1]),
12004 false, false))"
12005 "strd%?\t%2, %4, [%0, %1]"
12006 [(set_attr "type" "store_8")
12007 (set_attr "predicable" "yes")])
12008
12009 (define_insn "*thumb2_strd_base"
12010 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
12011 (match_operand:SI 1 "s_register_operand" "r"))
12012 (set (mem:SI (plus:SI (match_dup 0)
12013 (const_int 4)))
12014 (match_operand:SI 2 "s_register_operand" "r"))]
12015 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12016 && (operands_ok_ldrd_strd (operands[1], operands[2],
12017 operands[0], 0, false, false))"
12018 "strd%?\t%1, %2, [%0]"
12019 [(set_attr "type" "store_8")
12020 (set_attr "predicable" "yes")])
12021
12022 (define_insn "*thumb2_strd_base_neg"
12023 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12024 (const_int -4)))
12025 (match_operand:SI 1 "s_register_operand" "r"))
12026 (set (mem:SI (match_dup 0))
12027 (match_operand:SI 2 "s_register_operand" "r"))]
12028 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12029 && (operands_ok_ldrd_strd (operands[1], operands[2],
12030 operands[0], -4, false, false))"
12031 "strd%?\t%1, %2, [%0, #-4]"
12032 [(set_attr "type" "store_8")
12033 (set_attr "predicable" "yes")])
12034
12035 ;; ARMv8 CRC32 instructions.
12036 (define_insn "<crc_variant>"
12037 [(set (match_operand:SI 0 "s_register_operand" "=r")
12038 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
12039 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
12040 CRC))]
12041 "TARGET_CRC32"
12042 "<crc_variant>\\t%0, %1, %2"
12043 [(set_attr "type" "crc")
12044 (set_attr "conds" "unconditional")]
12045 )
12046
12047 ;; Load the load/store double peephole optimizations.
12048 (include "ldrdstrd.md")
12049
12050 ;; Load the load/store multiple patterns
12051 (include "ldmstm.md")
12052
12053 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12054 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12055 ;; The operands are validated through the load_multiple_operation
12056 ;; match_parallel predicate rather than through constraints so enable it only
12057 ;; after reload.
12058 (define_insn "*load_multiple"
12059 [(match_parallel 0 "load_multiple_operation"
12060 [(set (match_operand:SI 2 "s_register_operand" "=rk")
12061 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12062 ])]
12063 "TARGET_32BIT && reload_completed"
12064 "*
12065 {
12066 arm_output_multireg_pop (operands, /*return_pc=*/false,
12067 /*cond=*/const_true_rtx,
12068 /*reverse=*/false,
12069 /*update=*/false);
12070 return \"\";
12071 }
12072 "
12073 [(set_attr "predicable" "yes")]
12074 )
12075
12076 (define_expand "copysignsf3"
12077 [(match_operand:SF 0 "register_operand")
12078 (match_operand:SF 1 "register_operand")
12079 (match_operand:SF 2 "register_operand")]
12080 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12081 "{
12082 emit_move_insn (operands[0], operands[2]);
12083 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
12084 GEN_INT (31), GEN_INT (0),
12085 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
12086 DONE;
12087 }"
12088 )
12089
12090 (define_expand "copysigndf3"
12091 [(match_operand:DF 0 "register_operand")
12092 (match_operand:DF 1 "register_operand")
12093 (match_operand:DF 2 "register_operand")]
12094 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12095 "{
12096 rtx op0_low = gen_lowpart (SImode, operands[0]);
12097 rtx op0_high = gen_highpart (SImode, operands[0]);
12098 rtx op1_low = gen_lowpart (SImode, operands[1]);
12099 rtx op1_high = gen_highpart (SImode, operands[1]);
12100 rtx op2_high = gen_highpart (SImode, operands[2]);
12101
12102 rtx scratch1 = gen_reg_rtx (SImode);
12103 rtx scratch2 = gen_reg_rtx (SImode);
12104 emit_move_insn (scratch1, op2_high);
12105 emit_move_insn (scratch2, op1_high);
12106
12107 emit_insn(gen_rtx_SET(scratch1,
12108 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
12109 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
12110 emit_move_insn (op0_low, op1_low);
12111 emit_move_insn (op0_high, scratch2);
12112
12113 DONE;
12114 }"
12115 )
12116
12117 ;; movmisalign patterns for HImode and SImode.
12118 (define_expand "movmisalign<mode>"
12119 [(match_operand:HSI 0 "general_operand")
12120 (match_operand:HSI 1 "general_operand")]
12121 "unaligned_access"
12122 {
12123 /* This pattern is not permitted to fail during expansion: if both arguments
12124 are non-registers (e.g. memory := constant), force operand 1 into a
12125 register. */
12126 rtx (* gen_unaligned_load)(rtx, rtx);
12127 rtx tmp_dest = operands[0];
12128 if (!s_register_operand (operands[0], <MODE>mode)
12129 && !s_register_operand (operands[1], <MODE>mode))
12130 operands[1] = force_reg (<MODE>mode, operands[1]);
12131
12132 if (<MODE>mode == HImode)
12133 {
12134 gen_unaligned_load = gen_unaligned_loadhiu;
12135 tmp_dest = gen_reg_rtx (SImode);
12136 }
12137 else
12138 gen_unaligned_load = gen_unaligned_loadsi;
12139
12140 if (MEM_P (operands[1]))
12141 {
12142 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
12143 if (<MODE>mode == HImode)
12144 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
12145 }
12146 else
12147 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
12148
12149 DONE;
12150 })
12151
12152 (define_insn "<cdp>"
12153 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12154 (match_operand:SI 1 "immediate_operand" "n")
12155 (match_operand:SI 2 "immediate_operand" "n")
12156 (match_operand:SI 3 "immediate_operand" "n")
12157 (match_operand:SI 4 "immediate_operand" "n")
12158 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
12159 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
12160 {
12161 arm_const_bounds (operands[0], 0, 16);
12162 arm_const_bounds (operands[1], 0, 16);
12163 arm_const_bounds (operands[2], 0, (1 << 5));
12164 arm_const_bounds (operands[3], 0, (1 << 5));
12165 arm_const_bounds (operands[4], 0, (1 << 5));
12166 arm_const_bounds (operands[5], 0, 8);
12167 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
12168 }
12169 [(set_attr "length" "4")
12170 (set_attr "type" "coproc")])
12171
12172 (define_insn "*ldc"
12173 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12174 (match_operand:SI 1 "immediate_operand" "n")
12175 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
12176 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
12177 {
12178 arm_const_bounds (operands[0], 0, 16);
12179 arm_const_bounds (operands[1], 0, (1 << 5));
12180 return "<ldc>\\tp%c0, CR%c1, %2";
12181 }
12182 [(set_attr "length" "4")
12183 (set_attr "type" "coproc")])
12184
12185 (define_insn "*stc"
12186 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12187 (match_operand:SI 1 "immediate_operand" "n")
12188 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
12189 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
12190 {
12191 arm_const_bounds (operands[0], 0, 16);
12192 arm_const_bounds (operands[1], 0, (1 << 5));
12193 return "<stc>\\tp%c0, CR%c1, %2";
12194 }
12195 [(set_attr "length" "4")
12196 (set_attr "type" "coproc")])
12197
12198 (define_expand "<ldc>"
12199 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12200 (match_operand:SI 1 "immediate_operand")
12201 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
12202 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
12203
12204 (define_expand "<stc>"
12205 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12206 (match_operand:SI 1 "immediate_operand")
12207 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12208 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12209
12210 (define_insn "<mcr>"
12211 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12212 (match_operand:SI 1 "immediate_operand" "n")
12213 (match_operand:SI 2 "s_register_operand" "r")
12214 (match_operand:SI 3 "immediate_operand" "n")
12215 (match_operand:SI 4 "immediate_operand" "n")
12216 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12217 (use (match_dup 2))]
12218 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12219 {
12220 arm_const_bounds (operands[0], 0, 16);
12221 arm_const_bounds (operands[1], 0, 8);
12222 arm_const_bounds (operands[3], 0, (1 << 5));
12223 arm_const_bounds (operands[4], 0, (1 << 5));
12224 arm_const_bounds (operands[5], 0, 8);
12225 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12226 }
12227 [(set_attr "length" "4")
12228 (set_attr "type" "coproc")])
12229
12230 (define_insn "<mrc>"
12231 [(set (match_operand:SI 0 "s_register_operand" "=r")
12232 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12233 (match_operand:SI 2 "immediate_operand" "n")
12234 (match_operand:SI 3 "immediate_operand" "n")
12235 (match_operand:SI 4 "immediate_operand" "n")
12236 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12237 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12238 {
12239 arm_const_bounds (operands[1], 0, 16);
12240 arm_const_bounds (operands[2], 0, 8);
12241 arm_const_bounds (operands[3], 0, (1 << 5));
12242 arm_const_bounds (operands[4], 0, (1 << 5));
12243 arm_const_bounds (operands[5], 0, 8);
12244 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12245 }
12246 [(set_attr "length" "4")
12247 (set_attr "type" "coproc")])
12248
12249 (define_insn "<mcrr>"
12250 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12251 (match_operand:SI 1 "immediate_operand" "n")
12252 (match_operand:DI 2 "s_register_operand" "r")
12253 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12254 (use (match_dup 2))]
12255 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12256 {
12257 arm_const_bounds (operands[0], 0, 16);
12258 arm_const_bounds (operands[1], 0, 8);
12259 arm_const_bounds (operands[3], 0, (1 << 5));
12260 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12261 }
12262 [(set_attr "length" "4")
12263 (set_attr "type" "coproc")])
12264
12265 (define_insn "<mrrc>"
12266 [(set (match_operand:DI 0 "s_register_operand" "=r")
12267 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12268 (match_operand:SI 2 "immediate_operand" "n")
12269 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12270 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12271 {
12272 arm_const_bounds (operands[1], 0, 16);
12273 arm_const_bounds (operands[2], 0, 8);
12274 arm_const_bounds (operands[3], 0, (1 << 5));
12275 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12276 }
12277 [(set_attr "length" "4")
12278 (set_attr "type" "coproc")])
12279
12280 (define_expand "speculation_barrier"
12281 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12282 "TARGET_EITHER"
12283 "
12284 /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
12285 have a usable barrier (and probably don't need one in practice).
12286 But to be safe if such code is run on later architectures, call a
12287 helper function in libgcc that will do the thing for the active
12288 system. */
12289 if (!(arm_arch7 || arm_arch8))
12290 {
12291 arm_emit_speculation_barrier_function ();
12292 DONE;
12293 }
12294 "
12295 )
12296
12297 ;; Generate a hard speculation barrier when we have not enabled speculation
12298 ;; tracking.
12299 (define_insn "*speculation_barrier_insn"
12300 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12301 "arm_arch7 || arm_arch8"
12302 "isb\;dsb\\tsy"
12303 [(set_attr "type" "block")
12304 (set_attr "length" "8")]
12305 )
12306
12307 ;; Vector bits common to IWMMXT and Neon
12308 (include "vec-common.md")
12309 ;; Load the Intel Wireless Multimedia Extension patterns
12310 (include "iwmmxt.md")
12311 ;; Load the VFP co-processor patterns
12312 (include "vfp.md")
12313 ;; Thumb-1 patterns
12314 (include "thumb1.md")
12315 ;; Thumb-2 patterns
12316 (include "thumb2.md")
12317 ;; Neon patterns
12318 (include "neon.md")
12319 ;; Crypto patterns
12320 (include "crypto.md")
12321 ;; Synchronization Primitives
12322 (include "sync.md")
12323 ;; Fixed-point patterns
12324 (include "arm-fixed.md")