]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm.md
[ARM] Fix PR89222
[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
871 && (INTVAL (operands[2])
872 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
873 {
874 /* For 0 and INT_MIN it is essential that we use subs, as adds
875 will result in different condition codes (like cmn rather than
876 like cmp). For other immediates, we should choose whatever
877 will have smaller encoding. */
878 if (operands[2] == const0_rtx
879 || INTVAL (operands[2]) == -HOST_WIDE_INT_C (0x80000000)
880 || which_alternative == 1)
881 return "subs%?\\t%0, %1, #%n3";
882 else
883 return "adds%?\\t%0, %1, %3";
884 }
885 [(set_attr "conds" "set")
886 (set_attr "type" "alus_sreg")]
887 )
888
889 ;; Convert the sequence
890 ;; sub rd, rn, #1
891 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
892 ;; bne dest
893 ;; into
894 ;; subs rd, rn, #1
895 ;; bcs dest ((unsigned)rn >= 1)
896 ;; similarly for the beq variant using bcc.
897 ;; This is a common looping idiom (while (n--))
898 (define_peephole2
899 [(set (match_operand:SI 0 "arm_general_register_operand" "")
900 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
901 (const_int -1)))
902 (set (match_operand 2 "cc_register" "")
903 (compare (match_dup 0) (const_int -1)))
904 (set (pc)
905 (if_then_else (match_operator 3 "equality_operator"
906 [(match_dup 2) (const_int 0)])
907 (match_operand 4 "" "")
908 (match_operand 5 "" "")))]
909 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
910 [(parallel[
911 (set (match_dup 2)
912 (compare:CC
913 (match_dup 1) (const_int 1)))
914 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
915 (set (pc)
916 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
917 (match_dup 4)
918 (match_dup 5)))]
919 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
920 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
921 ? GEU : LTU),
922 VOIDmode,
923 operands[2], const0_rtx);"
924 )
925
926 ;; The next four insns work because they compare the result with one of
927 ;; the operands, and we know that the use of the condition code is
928 ;; either GEU or LTU, so we can use the carry flag from the addition
929 ;; instead of doing the compare a second time.
930 (define_insn "*addsi3_compare_op1"
931 [(set (reg:CC_C CC_REGNUM)
932 (compare:CC_C
933 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
934 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
935 (match_dup 1)))
936 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
937 (plus:SI (match_dup 1) (match_dup 2)))]
938 "TARGET_32BIT"
939 "@
940 adds%?\\t%0, %1, %2
941 subs%?\\t%0, %1, #%n2
942 adds%?\\t%0, %1, %2"
943 [(set_attr "conds" "set")
944 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
945 )
946
947 (define_insn "*addsi3_compare_op2"
948 [(set (reg:CC_C CC_REGNUM)
949 (compare:CC_C
950 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
951 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
952 (match_dup 2)))
953 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
954 (plus:SI (match_dup 1) (match_dup 2)))]
955 "TARGET_32BIT"
956 "@
957 adds%?\\t%0, %1, %2
958 subs%?\\t%0, %1, #%n2
959 adds%?\\t%0, %1, %2"
960 [(set_attr "conds" "set")
961 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
962 )
963
964 (define_insn "*compare_addsi2_op0"
965 [(set (reg:CC_C CC_REGNUM)
966 (compare:CC_C
967 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
968 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
969 (match_dup 0)))]
970 "TARGET_32BIT"
971 "@
972 cmp%?\\t%0, #%n1
973 cmn%?\\t%0, %1
974 cmn%?\\t%0, %1
975 cmp%?\\t%0, #%n1
976 cmn%?\\t%0, %1"
977 [(set_attr "conds" "set")
978 (set_attr "predicable" "yes")
979 (set_attr "arch" "t2,t2,*,*,*")
980 (set_attr "predicable_short_it" "yes,yes,no,no,no")
981 (set_attr "length" "2,2,4,4,4")
982 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
983 )
984
985 (define_insn "*compare_addsi2_op1"
986 [(set (reg:CC_C CC_REGNUM)
987 (compare:CC_C
988 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
989 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
990 (match_dup 1)))]
991 "TARGET_32BIT"
992 "@
993 cmp%?\\t%0, #%n1
994 cmn%?\\t%0, %1
995 cmn%?\\t%0, %1
996 cmp%?\\t%0, #%n1
997 cmn%?\\t%0, %1"
998 [(set_attr "conds" "set")
999 (set_attr "predicable" "yes")
1000 (set_attr "arch" "t2,t2,*,*,*")
1001 (set_attr "predicable_short_it" "yes,yes,no,no,no")
1002 (set_attr "length" "2,2,4,4,4")
1003 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
1004 )
1005
1006 (define_insn "*addsi3_carryin_<optab>"
1007 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1008 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
1009 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
1010 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1011 "TARGET_32BIT"
1012 "@
1013 adc%?\\t%0, %1, %2
1014 adc%?\\t%0, %1, %2
1015 sbc%?\\t%0, %1, #%B2"
1016 [(set_attr "conds" "use")
1017 (set_attr "predicable" "yes")
1018 (set_attr "arch" "t2,*,*")
1019 (set_attr "length" "4")
1020 (set_attr "predicable_short_it" "yes,no,no")
1021 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1022 )
1023
1024 (define_insn "*addsi3_carryin_alt2_<optab>"
1025 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1026 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1027 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1028 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1029 "TARGET_32BIT"
1030 "@
1031 adc%?\\t%0, %1, %2
1032 adc%?\\t%0, %1, %2
1033 sbc%?\\t%0, %1, #%B2"
1034 [(set_attr "conds" "use")
1035 (set_attr "predicable" "yes")
1036 (set_attr "arch" "t2,*,*")
1037 (set_attr "length" "4")
1038 (set_attr "predicable_short_it" "yes,no,no")
1039 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1040 )
1041
1042 (define_insn "*addsi3_carryin_shift_<optab>"
1043 [(set (match_operand:SI 0 "s_register_operand" "=r")
1044 (plus:SI (plus:SI
1045 (match_operator:SI 2 "shift_operator"
1046 [(match_operand:SI 3 "s_register_operand" "r")
1047 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1048 (match_operand:SI 1 "s_register_operand" "r"))
1049 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1050 "TARGET_32BIT"
1051 "adc%?\\t%0, %1, %3%S2"
1052 [(set_attr "conds" "use")
1053 (set_attr "predicable" "yes")
1054 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1055 (const_string "alu_shift_imm")
1056 (const_string "alu_shift_reg")))]
1057 )
1058
1059 (define_insn "*addsi3_carryin_clobercc_<optab>"
1060 [(set (match_operand:SI 0 "s_register_operand" "=r")
1061 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1062 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1063 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1064 (clobber (reg:CC CC_REGNUM))]
1065 "TARGET_32BIT"
1066 "adcs%?\\t%0, %1, %2"
1067 [(set_attr "conds" "set")
1068 (set_attr "type" "adcs_reg")]
1069 )
1070
1071 (define_expand "subv<mode>4"
1072 [(match_operand:SIDI 0 "register_operand")
1073 (match_operand:SIDI 1 "register_operand")
1074 (match_operand:SIDI 2 "register_operand")
1075 (match_operand 3 "")]
1076 "TARGET_32BIT"
1077 {
1078 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1079 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1080
1081 DONE;
1082 })
1083
1084 (define_expand "usubv<mode>4"
1085 [(match_operand:SIDI 0 "register_operand")
1086 (match_operand:SIDI 1 "register_operand")
1087 (match_operand:SIDI 2 "register_operand")
1088 (match_operand 3 "")]
1089 "TARGET_32BIT"
1090 {
1091 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1092 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1093
1094 DONE;
1095 })
1096
1097 (define_insn_and_split "subdi3_compare1"
1098 [(set (reg:CC CC_REGNUM)
1099 (compare:CC
1100 (match_operand:DI 1 "register_operand" "r")
1101 (match_operand:DI 2 "register_operand" "r")))
1102 (set (match_operand:DI 0 "register_operand" "=&r")
1103 (minus:DI (match_dup 1) (match_dup 2)))]
1104 "TARGET_32BIT"
1105 "#"
1106 "&& reload_completed"
1107 [(parallel [(set (reg:CC CC_REGNUM)
1108 (compare:CC (match_dup 1) (match_dup 2)))
1109 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1110 (parallel [(set (reg:CC CC_REGNUM)
1111 (compare:CC (match_dup 4) (match_dup 5)))
1112 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1113 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1114 {
1115 operands[3] = gen_highpart (SImode, operands[0]);
1116 operands[0] = gen_lowpart (SImode, operands[0]);
1117 operands[4] = gen_highpart (SImode, operands[1]);
1118 operands[1] = gen_lowpart (SImode, operands[1]);
1119 operands[5] = gen_highpart (SImode, operands[2]);
1120 operands[2] = gen_lowpart (SImode, operands[2]);
1121 }
1122 [(set_attr "conds" "set")
1123 (set_attr "length" "8")
1124 (set_attr "type" "multiple")]
1125 )
1126
1127 (define_insn "subsi3_compare1"
1128 [(set (reg:CC CC_REGNUM)
1129 (compare:CC
1130 (match_operand:SI 1 "register_operand" "r")
1131 (match_operand:SI 2 "register_operand" "r")))
1132 (set (match_operand:SI 0 "register_operand" "=r")
1133 (minus:SI (match_dup 1) (match_dup 2)))]
1134 "TARGET_32BIT"
1135 "subs%?\\t%0, %1, %2"
1136 [(set_attr "conds" "set")
1137 (set_attr "type" "alus_sreg")]
1138 )
1139
1140 (define_insn "*subsi3_carryin"
1141 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1142 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1143 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1144 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1145 "TARGET_32BIT"
1146 "@
1147 sbc%?\\t%0, %1, %2
1148 rsc%?\\t%0, %2, %1
1149 sbc%?\\t%0, %2, %2, lsl #1"
1150 [(set_attr "conds" "use")
1151 (set_attr "arch" "*,a,t2")
1152 (set_attr "predicable" "yes")
1153 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1154 )
1155
1156 (define_insn "*subsi3_carryin_const"
1157 [(set (match_operand:SI 0 "s_register_operand" "=r")
1158 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1159 (match_operand:SI 2 "arm_neg_immediate_operand" "L"))
1160 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1161 "TARGET_32BIT"
1162 "sbc\\t%0, %1, #%n2"
1163 [(set_attr "conds" "use")
1164 (set_attr "type" "adc_imm")]
1165 )
1166
1167 (define_insn "*subsi3_carryin_const0"
1168 [(set (match_operand:SI 0 "s_register_operand" "=r")
1169 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
1170 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1171 "TARGET_32BIT"
1172 "sbc\\t%0, %1, #0"
1173 [(set_attr "conds" "use")
1174 (set_attr "type" "adc_imm")]
1175 )
1176
1177 (define_insn "*subsi3_carryin_compare"
1178 [(set (reg:CC CC_REGNUM)
1179 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1180 (match_operand:SI 2 "s_register_operand" "r")))
1181 (set (match_operand:SI 0 "s_register_operand" "=r")
1182 (minus:SI (minus:SI (match_dup 1)
1183 (match_dup 2))
1184 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1185 "TARGET_32BIT"
1186 "sbcs\\t%0, %1, %2"
1187 [(set_attr "conds" "set")
1188 (set_attr "type" "adcs_reg")]
1189 )
1190
1191 (define_insn "*subsi3_carryin_compare_const"
1192 [(set (reg:CC CC_REGNUM)
1193 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1194 (match_operand:SI 2 "const_int_I_operand" "I")))
1195 (set (match_operand:SI 0 "s_register_operand" "=r")
1196 (minus:SI (plus:SI (match_dup 1)
1197 (match_operand:SI 3 "arm_neg_immediate_operand" "L"))
1198 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1199 "TARGET_32BIT
1200 && (INTVAL (operands[2])
1201 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
1202 "sbcs\\t%0, %1, #%n3"
1203 [(set_attr "conds" "set")
1204 (set_attr "type" "adcs_imm")]
1205 )
1206
1207 (define_insn "*subsi3_carryin_compare_const0"
1208 [(set (reg:CC CC_REGNUM)
1209 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1210 (const_int 0)))
1211 (set (match_operand:SI 0 "s_register_operand" "=r")
1212 (minus:SI (match_dup 1)
1213 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1214 "TARGET_32BIT"
1215 "sbcs\\t%0, %1, #0"
1216 [(set_attr "conds" "set")
1217 (set_attr "type" "adcs_imm")]
1218 )
1219
1220 (define_insn "*subsi3_carryin_shift"
1221 [(set (match_operand:SI 0 "s_register_operand" "=r")
1222 (minus:SI (minus:SI
1223 (match_operand:SI 1 "s_register_operand" "r")
1224 (match_operator:SI 2 "shift_operator"
1225 [(match_operand:SI 3 "s_register_operand" "r")
1226 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1227 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1228 "TARGET_32BIT"
1229 "sbc%?\\t%0, %1, %3%S2"
1230 [(set_attr "conds" "use")
1231 (set_attr "predicable" "yes")
1232 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1233 (const_string "alu_shift_imm")
1234 (const_string "alu_shift_reg")))]
1235 )
1236
1237 (define_insn "*rsbsi3_carryin_shift"
1238 [(set (match_operand:SI 0 "s_register_operand" "=r")
1239 (minus:SI (minus:SI
1240 (match_operator:SI 2 "shift_operator"
1241 [(match_operand:SI 3 "s_register_operand" "r")
1242 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1243 (match_operand:SI 1 "s_register_operand" "r"))
1244 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1245 "TARGET_ARM"
1246 "rsc%?\\t%0, %1, %3%S2"
1247 [(set_attr "conds" "use")
1248 (set_attr "predicable" "yes")
1249 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1250 (const_string "alu_shift_imm")
1251 (const_string "alu_shift_reg")))]
1252 )
1253
1254 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1255 (define_split
1256 [(set (match_operand:SI 0 "s_register_operand" "")
1257 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1258 (match_operand:SI 2 "s_register_operand" ""))
1259 (const_int -1)))
1260 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1261 "TARGET_32BIT"
1262 [(set (match_dup 3) (match_dup 1))
1263 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1264 "
1265 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1266 ")
1267
1268 (define_expand "addsf3"
1269 [(set (match_operand:SF 0 "s_register_operand" "")
1270 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1271 (match_operand:SF 2 "s_register_operand" "")))]
1272 "TARGET_32BIT && TARGET_HARD_FLOAT"
1273 "
1274 ")
1275
1276 (define_expand "adddf3"
1277 [(set (match_operand:DF 0 "s_register_operand" "")
1278 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1279 (match_operand:DF 2 "s_register_operand" "")))]
1280 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1281 "
1282 ")
1283
1284 (define_expand "subdi3"
1285 [(parallel
1286 [(set (match_operand:DI 0 "s_register_operand" "")
1287 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1288 (match_operand:DI 2 "s_register_operand" "")))
1289 (clobber (reg:CC CC_REGNUM))])]
1290 "TARGET_EITHER"
1291 "
1292 if (TARGET_THUMB1)
1293 {
1294 if (!REG_P (operands[1]))
1295 operands[1] = force_reg (DImode, operands[1]);
1296 if (!REG_P (operands[2]))
1297 operands[2] = force_reg (DImode, operands[2]);
1298 }
1299 "
1300 )
1301
1302 (define_insn_and_split "*arm_subdi3"
1303 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
1304 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1305 (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1306 (clobber (reg:CC CC_REGNUM))]
1307 "TARGET_32BIT && !TARGET_NEON"
1308 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1309 "&& (!TARGET_IWMMXT || reload_completed)"
1310 [(parallel [(set (reg:CC CC_REGNUM)
1311 (compare:CC (match_dup 1) (match_dup 2)))
1312 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1313 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1314 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1315 {
1316 operands[3] = gen_highpart (SImode, operands[0]);
1317 operands[0] = gen_lowpart (SImode, operands[0]);
1318 operands[4] = gen_highpart (SImode, operands[1]);
1319 operands[1] = gen_lowpart (SImode, operands[1]);
1320 operands[5] = gen_highpart (SImode, operands[2]);
1321 operands[2] = gen_lowpart (SImode, operands[2]);
1322 }
1323 [(set_attr "conds" "clob")
1324 (set_attr "length" "8")
1325 (set_attr "type" "multiple")]
1326 )
1327
1328 (define_insn_and_split "*subdi_di_zesidi"
1329 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1330 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1331 (zero_extend:DI
1332 (match_operand:SI 2 "s_register_operand" "r,r"))))
1333 (clobber (reg:CC CC_REGNUM))]
1334 "TARGET_32BIT"
1335 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1336 "&& reload_completed"
1337 [(parallel [(set (reg:CC CC_REGNUM)
1338 (compare:CC (match_dup 1) (match_dup 2)))
1339 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1340 (set (match_dup 3) (minus:SI (match_dup 4)
1341 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1342 {
1343 operands[3] = gen_highpart (SImode, operands[0]);
1344 operands[0] = gen_lowpart (SImode, operands[0]);
1345 operands[4] = gen_highpart (SImode, operands[1]);
1346 operands[1] = gen_lowpart (SImode, operands[1]);
1347 }
1348 [(set_attr "conds" "clob")
1349 (set_attr "length" "8")
1350 (set_attr "type" "multiple")]
1351 )
1352
1353 (define_insn_and_split "*subdi_di_sesidi"
1354 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1355 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1356 (sign_extend:DI
1357 (match_operand:SI 2 "s_register_operand" "r,r"))))
1358 (clobber (reg:CC CC_REGNUM))]
1359 "TARGET_32BIT"
1360 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1361 "&& reload_completed"
1362 [(parallel [(set (reg:CC CC_REGNUM)
1363 (compare:CC (match_dup 1) (match_dup 2)))
1364 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1365 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1366 (ashiftrt:SI (match_dup 2)
1367 (const_int 31)))
1368 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1369 {
1370 operands[3] = gen_highpart (SImode, operands[0]);
1371 operands[0] = gen_lowpart (SImode, operands[0]);
1372 operands[4] = gen_highpart (SImode, operands[1]);
1373 operands[1] = gen_lowpart (SImode, operands[1]);
1374 }
1375 [(set_attr "conds" "clob")
1376 (set_attr "length" "8")
1377 (set_attr "type" "multiple")]
1378 )
1379
1380 (define_insn_and_split "*subdi_zesidi_di"
1381 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1382 (minus:DI (zero_extend:DI
1383 (match_operand:SI 2 "s_register_operand" "r,r"))
1384 (match_operand:DI 1 "s_register_operand" "0,r")))
1385 (clobber (reg:CC CC_REGNUM))]
1386 "TARGET_ARM"
1387 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1388 ; is equivalent to:
1389 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1390 "&& reload_completed"
1391 [(parallel [(set (reg:CC CC_REGNUM)
1392 (compare:CC (match_dup 2) (match_dup 1)))
1393 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1394 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1395 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1396 {
1397 operands[3] = gen_highpart (SImode, operands[0]);
1398 operands[0] = gen_lowpart (SImode, operands[0]);
1399 operands[4] = gen_highpart (SImode, operands[1]);
1400 operands[1] = gen_lowpart (SImode, operands[1]);
1401 }
1402 [(set_attr "conds" "clob")
1403 (set_attr "length" "8")
1404 (set_attr "type" "multiple")]
1405 )
1406
1407 (define_insn_and_split "*subdi_sesidi_di"
1408 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1409 (minus:DI (sign_extend:DI
1410 (match_operand:SI 2 "s_register_operand" "r,r"))
1411 (match_operand:DI 1 "s_register_operand" "0,r")))
1412 (clobber (reg:CC CC_REGNUM))]
1413 "TARGET_ARM"
1414 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1415 ; is equivalent to:
1416 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1417 "&& reload_completed"
1418 [(parallel [(set (reg:CC CC_REGNUM)
1419 (compare:CC (match_dup 2) (match_dup 1)))
1420 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1421 (set (match_dup 3) (minus:SI (minus:SI
1422 (ashiftrt:SI (match_dup 2)
1423 (const_int 31))
1424 (match_dup 4))
1425 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1426 {
1427 operands[3] = gen_highpart (SImode, operands[0]);
1428 operands[0] = gen_lowpart (SImode, operands[0]);
1429 operands[4] = gen_highpart (SImode, operands[1]);
1430 operands[1] = gen_lowpart (SImode, operands[1]);
1431 }
1432 [(set_attr "conds" "clob")
1433 (set_attr "length" "8")
1434 (set_attr "type" "multiple")]
1435 )
1436
1437 (define_insn_and_split "*subdi_zesidi_zesidi"
1438 [(set (match_operand:DI 0 "s_register_operand" "=r")
1439 (minus:DI (zero_extend:DI
1440 (match_operand:SI 1 "s_register_operand" "r"))
1441 (zero_extend:DI
1442 (match_operand:SI 2 "s_register_operand" "r"))))
1443 (clobber (reg:CC CC_REGNUM))]
1444 "TARGET_32BIT"
1445 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1446 "&& reload_completed"
1447 [(parallel [(set (reg:CC CC_REGNUM)
1448 (compare:CC (match_dup 1) (match_dup 2)))
1449 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1450 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1451 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1452 {
1453 operands[3] = gen_highpart (SImode, operands[0]);
1454 operands[0] = gen_lowpart (SImode, operands[0]);
1455 }
1456 [(set_attr "conds" "clob")
1457 (set_attr "length" "8")
1458 (set_attr "type" "multiple")]
1459 )
1460
1461 (define_expand "subsi3"
1462 [(set (match_operand:SI 0 "s_register_operand" "")
1463 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1464 (match_operand:SI 2 "s_register_operand" "")))]
1465 "TARGET_EITHER"
1466 "
1467 if (CONST_INT_P (operands[1]))
1468 {
1469 if (TARGET_32BIT)
1470 {
1471 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1472 operands[1] = force_reg (SImode, operands[1]);
1473 else
1474 {
1475 arm_split_constant (MINUS, SImode, NULL_RTX,
1476 INTVAL (operands[1]), operands[0],
1477 operands[2],
1478 optimize && can_create_pseudo_p ());
1479 DONE;
1480 }
1481 }
1482 else /* TARGET_THUMB1 */
1483 operands[1] = force_reg (SImode, operands[1]);
1484 }
1485 "
1486 )
1487
1488 ; ??? Check Thumb-2 split length
1489 (define_insn_and_split "*arm_subsi3_insn"
1490 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1491 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1492 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1493 "TARGET_32BIT"
1494 "@
1495 sub%?\\t%0, %1, %2
1496 sub%?\\t%0, %2
1497 sub%?\\t%0, %1, %2
1498 rsb%?\\t%0, %2, %1
1499 rsb%?\\t%0, %2, %1
1500 sub%?\\t%0, %1, %2
1501 sub%?\\t%0, %1, %2
1502 sub%?\\t%0, %1, %2
1503 #"
1504 "&& (CONST_INT_P (operands[1])
1505 && !const_ok_for_arm (INTVAL (operands[1])))"
1506 [(clobber (const_int 0))]
1507 "
1508 arm_split_constant (MINUS, SImode, curr_insn,
1509 INTVAL (operands[1]), operands[0], operands[2], 0);
1510 DONE;
1511 "
1512 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1513 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1514 (set_attr "predicable" "yes")
1515 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1516 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1517 )
1518
1519 (define_peephole2
1520 [(match_scratch:SI 3 "r")
1521 (set (match_operand:SI 0 "arm_general_register_operand" "")
1522 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1523 (match_operand:SI 2 "arm_general_register_operand" "")))]
1524 "TARGET_32BIT
1525 && !const_ok_for_arm (INTVAL (operands[1]))
1526 && const_ok_for_arm (~INTVAL (operands[1]))"
1527 [(set (match_dup 3) (match_dup 1))
1528 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1529 ""
1530 )
1531
1532 (define_insn "subsi3_compare0"
1533 [(set (reg:CC_NOOV CC_REGNUM)
1534 (compare:CC_NOOV
1535 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1536 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1537 (const_int 0)))
1538 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1539 (minus:SI (match_dup 1) (match_dup 2)))]
1540 "TARGET_32BIT"
1541 "@
1542 subs%?\\t%0, %1, %2
1543 subs%?\\t%0, %1, %2
1544 rsbs%?\\t%0, %2, %1"
1545 [(set_attr "conds" "set")
1546 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1547 )
1548
1549 (define_insn "subsi3_compare"
1550 [(set (reg:CC CC_REGNUM)
1551 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1552 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1553 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1554 (minus:SI (match_dup 1) (match_dup 2)))]
1555 "TARGET_32BIT"
1556 "@
1557 subs%?\\t%0, %1, %2
1558 subs%?\\t%0, %1, %2
1559 rsbs%?\\t%0, %2, %1"
1560 [(set_attr "conds" "set")
1561 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1562 )
1563
1564 (define_expand "subsf3"
1565 [(set (match_operand:SF 0 "s_register_operand" "")
1566 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1567 (match_operand:SF 2 "s_register_operand" "")))]
1568 "TARGET_32BIT && TARGET_HARD_FLOAT"
1569 "
1570 ")
1571
1572 (define_expand "subdf3"
1573 [(set (match_operand:DF 0 "s_register_operand" "")
1574 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1575 (match_operand:DF 2 "s_register_operand" "")))]
1576 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1577 "
1578 ")
1579
1580 \f
1581 ;; Multiplication insns
1582
1583 (define_expand "mulhi3"
1584 [(set (match_operand:HI 0 "s_register_operand" "")
1585 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1586 (match_operand:HI 2 "s_register_operand" "")))]
1587 "TARGET_DSP_MULTIPLY"
1588 "
1589 {
1590 rtx result = gen_reg_rtx (SImode);
1591 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1592 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1593 DONE;
1594 }"
1595 )
1596
1597 (define_expand "mulsi3"
1598 [(set (match_operand:SI 0 "s_register_operand" "")
1599 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1600 (match_operand:SI 1 "s_register_operand" "")))]
1601 "TARGET_EITHER"
1602 ""
1603 )
1604
1605 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1606 (define_insn "*arm_mulsi3"
1607 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1608 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1609 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1610 "TARGET_32BIT && !arm_arch6"
1611 "mul%?\\t%0, %2, %1"
1612 [(set_attr "type" "mul")
1613 (set_attr "predicable" "yes")]
1614 )
1615
1616 (define_insn "*arm_mulsi3_v6"
1617 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1618 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1619 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1620 "TARGET_32BIT && arm_arch6"
1621 "mul%?\\t%0, %1, %2"
1622 [(set_attr "type" "mul")
1623 (set_attr "predicable" "yes")
1624 (set_attr "arch" "t2,t2,*")
1625 (set_attr "length" "4")
1626 (set_attr "predicable_short_it" "yes,yes,no")]
1627 )
1628
1629 (define_insn "*mulsi3_compare0"
1630 [(set (reg:CC_NOOV CC_REGNUM)
1631 (compare:CC_NOOV (mult:SI
1632 (match_operand:SI 2 "s_register_operand" "r,r")
1633 (match_operand:SI 1 "s_register_operand" "%0,r"))
1634 (const_int 0)))
1635 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1636 (mult:SI (match_dup 2) (match_dup 1)))]
1637 "TARGET_ARM && !arm_arch6"
1638 "muls%?\\t%0, %2, %1"
1639 [(set_attr "conds" "set")
1640 (set_attr "type" "muls")]
1641 )
1642
1643 (define_insn "*mulsi3_compare0_v6"
1644 [(set (reg:CC_NOOV CC_REGNUM)
1645 (compare:CC_NOOV (mult:SI
1646 (match_operand:SI 2 "s_register_operand" "r")
1647 (match_operand:SI 1 "s_register_operand" "r"))
1648 (const_int 0)))
1649 (set (match_operand:SI 0 "s_register_operand" "=r")
1650 (mult:SI (match_dup 2) (match_dup 1)))]
1651 "TARGET_ARM && arm_arch6 && optimize_size"
1652 "muls%?\\t%0, %2, %1"
1653 [(set_attr "conds" "set")
1654 (set_attr "type" "muls")]
1655 )
1656
1657 (define_insn "*mulsi_compare0_scratch"
1658 [(set (reg:CC_NOOV CC_REGNUM)
1659 (compare:CC_NOOV (mult:SI
1660 (match_operand:SI 2 "s_register_operand" "r,r")
1661 (match_operand:SI 1 "s_register_operand" "%0,r"))
1662 (const_int 0)))
1663 (clobber (match_scratch:SI 0 "=&r,&r"))]
1664 "TARGET_ARM && !arm_arch6"
1665 "muls%?\\t%0, %2, %1"
1666 [(set_attr "conds" "set")
1667 (set_attr "type" "muls")]
1668 )
1669
1670 (define_insn "*mulsi_compare0_scratch_v6"
1671 [(set (reg:CC_NOOV CC_REGNUM)
1672 (compare:CC_NOOV (mult:SI
1673 (match_operand:SI 2 "s_register_operand" "r")
1674 (match_operand:SI 1 "s_register_operand" "r"))
1675 (const_int 0)))
1676 (clobber (match_scratch:SI 0 "=r"))]
1677 "TARGET_ARM && arm_arch6 && optimize_size"
1678 "muls%?\\t%0, %2, %1"
1679 [(set_attr "conds" "set")
1680 (set_attr "type" "muls")]
1681 )
1682
1683 ;; Unnamed templates to match MLA instruction.
1684
1685 (define_insn "*mulsi3addsi"
1686 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1687 (plus:SI
1688 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1689 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1690 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1691 "TARGET_32BIT && !arm_arch6"
1692 "mla%?\\t%0, %2, %1, %3"
1693 [(set_attr "type" "mla")
1694 (set_attr "predicable" "yes")]
1695 )
1696
1697 (define_insn "*mulsi3addsi_v6"
1698 [(set (match_operand:SI 0 "s_register_operand" "=r")
1699 (plus:SI
1700 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1701 (match_operand:SI 1 "s_register_operand" "r"))
1702 (match_operand:SI 3 "s_register_operand" "r")))]
1703 "TARGET_32BIT && arm_arch6"
1704 "mla%?\\t%0, %2, %1, %3"
1705 [(set_attr "type" "mla")
1706 (set_attr "predicable" "yes")]
1707 )
1708
1709 (define_insn "*mulsi3addsi_compare0"
1710 [(set (reg:CC_NOOV CC_REGNUM)
1711 (compare:CC_NOOV
1712 (plus:SI (mult:SI
1713 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1714 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1715 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1716 (const_int 0)))
1717 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1718 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1719 (match_dup 3)))]
1720 "TARGET_ARM && arm_arch6"
1721 "mlas%?\\t%0, %2, %1, %3"
1722 [(set_attr "conds" "set")
1723 (set_attr "type" "mlas")]
1724 )
1725
1726 (define_insn "*mulsi3addsi_compare0_v6"
1727 [(set (reg:CC_NOOV CC_REGNUM)
1728 (compare:CC_NOOV
1729 (plus:SI (mult:SI
1730 (match_operand:SI 2 "s_register_operand" "r")
1731 (match_operand:SI 1 "s_register_operand" "r"))
1732 (match_operand:SI 3 "s_register_operand" "r"))
1733 (const_int 0)))
1734 (set (match_operand:SI 0 "s_register_operand" "=r")
1735 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1736 (match_dup 3)))]
1737 "TARGET_ARM && arm_arch6 && optimize_size"
1738 "mlas%?\\t%0, %2, %1, %3"
1739 [(set_attr "conds" "set")
1740 (set_attr "type" "mlas")]
1741 )
1742
1743 (define_insn "*mulsi3addsi_compare0_scratch"
1744 [(set (reg:CC_NOOV CC_REGNUM)
1745 (compare:CC_NOOV
1746 (plus:SI (mult:SI
1747 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1748 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1749 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1750 (const_int 0)))
1751 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1752 "TARGET_ARM && !arm_arch6"
1753 "mlas%?\\t%0, %2, %1, %3"
1754 [(set_attr "conds" "set")
1755 (set_attr "type" "mlas")]
1756 )
1757
1758 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1759 [(set (reg:CC_NOOV CC_REGNUM)
1760 (compare:CC_NOOV
1761 (plus:SI (mult:SI
1762 (match_operand:SI 2 "s_register_operand" "r")
1763 (match_operand:SI 1 "s_register_operand" "r"))
1764 (match_operand:SI 3 "s_register_operand" "r"))
1765 (const_int 0)))
1766 (clobber (match_scratch:SI 0 "=r"))]
1767 "TARGET_ARM && arm_arch6 && optimize_size"
1768 "mlas%?\\t%0, %2, %1, %3"
1769 [(set_attr "conds" "set")
1770 (set_attr "type" "mlas")]
1771 )
1772
1773 (define_insn "*mulsi3subsi"
1774 [(set (match_operand:SI 0 "s_register_operand" "=r")
1775 (minus:SI
1776 (match_operand:SI 3 "s_register_operand" "r")
1777 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1778 (match_operand:SI 1 "s_register_operand" "r"))))]
1779 "TARGET_32BIT && arm_arch_thumb2"
1780 "mls%?\\t%0, %2, %1, %3"
1781 [(set_attr "type" "mla")
1782 (set_attr "predicable" "yes")]
1783 )
1784
1785 (define_expand "maddsidi4"
1786 [(set (match_operand:DI 0 "s_register_operand" "")
1787 (plus:DI
1788 (mult:DI
1789 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1790 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1791 (match_operand:DI 3 "s_register_operand" "")))]
1792 "TARGET_32BIT"
1793 "")
1794
1795 (define_insn "*mulsidi3adddi"
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 (define_insn "*mulsidi3adddi_v6"
1809 [(set (match_operand:DI 0 "s_register_operand" "=r")
1810 (plus:DI
1811 (mult:DI
1812 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1813 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1814 (match_operand:DI 1 "s_register_operand" "0")))]
1815 "TARGET_32BIT && arm_arch6"
1816 "smlal%?\\t%Q0, %R0, %3, %2"
1817 [(set_attr "type" "smlal")
1818 (set_attr "predicable" "yes")]
1819 )
1820
1821 ;; 32x32->64 widening multiply.
1822 ;; As with mulsi3, the only difference between the v3-5 and v6+
1823 ;; versions of these patterns is the requirement that the output not
1824 ;; overlap the inputs, but that still means we have to have a named
1825 ;; expander and two different starred insns.
1826
1827 (define_expand "mulsidi3"
1828 [(set (match_operand:DI 0 "s_register_operand" "")
1829 (mult:DI
1830 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1831 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1832 "TARGET_32BIT"
1833 ""
1834 )
1835
1836 (define_insn "*mulsidi3_nov6"
1837 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1838 (mult:DI
1839 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1840 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1841 "TARGET_32BIT && !arm_arch6"
1842 "smull%?\\t%Q0, %R0, %1, %2"
1843 [(set_attr "type" "smull")
1844 (set_attr "predicable" "yes")]
1845 )
1846
1847 (define_insn "*mulsidi3_v6"
1848 [(set (match_operand:DI 0 "s_register_operand" "=r")
1849 (mult:DI
1850 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1851 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1852 "TARGET_32BIT && arm_arch6"
1853 "smull%?\\t%Q0, %R0, %1, %2"
1854 [(set_attr "type" "smull")
1855 (set_attr "predicable" "yes")]
1856 )
1857
1858 (define_expand "umulsidi3"
1859 [(set (match_operand:DI 0 "s_register_operand" "")
1860 (mult:DI
1861 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1862 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1863 "TARGET_32BIT"
1864 ""
1865 )
1866
1867 (define_insn "*umulsidi3_nov6"
1868 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1869 (mult:DI
1870 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1871 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1872 "TARGET_32BIT && !arm_arch6"
1873 "umull%?\\t%Q0, %R0, %1, %2"
1874 [(set_attr "type" "umull")
1875 (set_attr "predicable" "yes")]
1876 )
1877
1878 (define_insn "*umulsidi3_v6"
1879 [(set (match_operand:DI 0 "s_register_operand" "=r")
1880 (mult:DI
1881 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1882 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1883 "TARGET_32BIT && arm_arch6"
1884 "umull%?\\t%Q0, %R0, %1, %2"
1885 [(set_attr "type" "umull")
1886 (set_attr "predicable" "yes")]
1887 )
1888
1889 (define_expand "umaddsidi4"
1890 [(set (match_operand:DI 0 "s_register_operand" "")
1891 (plus:DI
1892 (mult:DI
1893 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1894 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1895 (match_operand:DI 3 "s_register_operand" "")))]
1896 "TARGET_32BIT"
1897 "")
1898
1899 (define_insn "*umulsidi3adddi"
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_insn "*umulsidi3adddi_v6"
1913 [(set (match_operand:DI 0 "s_register_operand" "=r")
1914 (plus:DI
1915 (mult:DI
1916 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1917 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1918 (match_operand:DI 1 "s_register_operand" "0")))]
1919 "TARGET_32BIT && arm_arch6"
1920 "umlal%?\\t%Q0, %R0, %3, %2"
1921 [(set_attr "type" "umlal")
1922 (set_attr "predicable" "yes")]
1923 )
1924
1925 (define_expand "smulsi3_highpart"
1926 [(parallel
1927 [(set (match_operand:SI 0 "s_register_operand" "")
1928 (truncate:SI
1929 (lshiftrt:DI
1930 (mult:DI
1931 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1932 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1933 (const_int 32))))
1934 (clobber (match_scratch:SI 3 ""))])]
1935 "TARGET_32BIT"
1936 ""
1937 )
1938
1939 (define_insn "*smulsi3_highpart_nov6"
1940 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1941 (truncate:SI
1942 (lshiftrt:DI
1943 (mult:DI
1944 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1945 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1946 (const_int 32))))
1947 (clobber (match_scratch:SI 3 "=&r,&r"))]
1948 "TARGET_32BIT && !arm_arch6"
1949 "smull%?\\t%3, %0, %2, %1"
1950 [(set_attr "type" "smull")
1951 (set_attr "predicable" "yes")]
1952 )
1953
1954 (define_insn "*smulsi3_highpart_v6"
1955 [(set (match_operand:SI 0 "s_register_operand" "=r")
1956 (truncate:SI
1957 (lshiftrt:DI
1958 (mult:DI
1959 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1960 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1961 (const_int 32))))
1962 (clobber (match_scratch:SI 3 "=r"))]
1963 "TARGET_32BIT && arm_arch6"
1964 "smull%?\\t%3, %0, %2, %1"
1965 [(set_attr "type" "smull")
1966 (set_attr "predicable" "yes")]
1967 )
1968
1969 (define_expand "umulsi3_highpart"
1970 [(parallel
1971 [(set (match_operand:SI 0 "s_register_operand" "")
1972 (truncate:SI
1973 (lshiftrt:DI
1974 (mult:DI
1975 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1976 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1977 (const_int 32))))
1978 (clobber (match_scratch:SI 3 ""))])]
1979 "TARGET_32BIT"
1980 ""
1981 )
1982
1983 (define_insn "*umulsi3_highpart_nov6"
1984 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1985 (truncate:SI
1986 (lshiftrt:DI
1987 (mult:DI
1988 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1989 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1990 (const_int 32))))
1991 (clobber (match_scratch:SI 3 "=&r,&r"))]
1992 "TARGET_32BIT && !arm_arch6"
1993 "umull%?\\t%3, %0, %2, %1"
1994 [(set_attr "type" "umull")
1995 (set_attr "predicable" "yes")]
1996 )
1997
1998 (define_insn "*umulsi3_highpart_v6"
1999 [(set (match_operand:SI 0 "s_register_operand" "=r")
2000 (truncate:SI
2001 (lshiftrt:DI
2002 (mult:DI
2003 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
2004 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
2005 (const_int 32))))
2006 (clobber (match_scratch:SI 3 "=r"))]
2007 "TARGET_32BIT && arm_arch6"
2008 "umull%?\\t%3, %0, %2, %1"
2009 [(set_attr "type" "umull")
2010 (set_attr "predicable" "yes")]
2011 )
2012
2013 (define_insn "mulhisi3"
2014 [(set (match_operand:SI 0 "s_register_operand" "=r")
2015 (mult:SI (sign_extend:SI
2016 (match_operand:HI 1 "s_register_operand" "%r"))
2017 (sign_extend:SI
2018 (match_operand:HI 2 "s_register_operand" "r"))))]
2019 "TARGET_DSP_MULTIPLY"
2020 "smulbb%?\\t%0, %1, %2"
2021 [(set_attr "type" "smulxy")
2022 (set_attr "predicable" "yes")]
2023 )
2024
2025 (define_insn "*mulhisi3tb"
2026 [(set (match_operand:SI 0 "s_register_operand" "=r")
2027 (mult:SI (ashiftrt:SI
2028 (match_operand:SI 1 "s_register_operand" "r")
2029 (const_int 16))
2030 (sign_extend:SI
2031 (match_operand:HI 2 "s_register_operand" "r"))))]
2032 "TARGET_DSP_MULTIPLY"
2033 "smultb%?\\t%0, %1, %2"
2034 [(set_attr "type" "smulxy")
2035 (set_attr "predicable" "yes")]
2036 )
2037
2038 (define_insn "*mulhisi3bt"
2039 [(set (match_operand:SI 0 "s_register_operand" "=r")
2040 (mult:SI (sign_extend:SI
2041 (match_operand:HI 1 "s_register_operand" "r"))
2042 (ashiftrt:SI
2043 (match_operand:SI 2 "s_register_operand" "r")
2044 (const_int 16))))]
2045 "TARGET_DSP_MULTIPLY"
2046 "smulbt%?\\t%0, %1, %2"
2047 [(set_attr "type" "smulxy")
2048 (set_attr "predicable" "yes")]
2049 )
2050
2051 (define_insn "*mulhisi3tt"
2052 [(set (match_operand:SI 0 "s_register_operand" "=r")
2053 (mult:SI (ashiftrt:SI
2054 (match_operand:SI 1 "s_register_operand" "r")
2055 (const_int 16))
2056 (ashiftrt:SI
2057 (match_operand:SI 2 "s_register_operand" "r")
2058 (const_int 16))))]
2059 "TARGET_DSP_MULTIPLY"
2060 "smultt%?\\t%0, %1, %2"
2061 [(set_attr "type" "smulxy")
2062 (set_attr "predicable" "yes")]
2063 )
2064
2065 (define_insn "maddhisi4"
2066 [(set (match_operand:SI 0 "s_register_operand" "=r")
2067 (plus:SI (mult:SI (sign_extend:SI
2068 (match_operand:HI 1 "s_register_operand" "r"))
2069 (sign_extend:SI
2070 (match_operand:HI 2 "s_register_operand" "r")))
2071 (match_operand:SI 3 "s_register_operand" "r")))]
2072 "TARGET_DSP_MULTIPLY"
2073 "smlabb%?\\t%0, %1, %2, %3"
2074 [(set_attr "type" "smlaxy")
2075 (set_attr "predicable" "yes")]
2076 )
2077
2078 ;; Note: there is no maddhisi4ibt because this one is canonical form
2079 (define_insn "*maddhisi4tb"
2080 [(set (match_operand:SI 0 "s_register_operand" "=r")
2081 (plus:SI (mult:SI (ashiftrt:SI
2082 (match_operand:SI 1 "s_register_operand" "r")
2083 (const_int 16))
2084 (sign_extend:SI
2085 (match_operand:HI 2 "s_register_operand" "r")))
2086 (match_operand:SI 3 "s_register_operand" "r")))]
2087 "TARGET_DSP_MULTIPLY"
2088 "smlatb%?\\t%0, %1, %2, %3"
2089 [(set_attr "type" "smlaxy")
2090 (set_attr "predicable" "yes")]
2091 )
2092
2093 (define_insn "*maddhisi4tt"
2094 [(set (match_operand:SI 0 "s_register_operand" "=r")
2095 (plus:SI (mult:SI (ashiftrt:SI
2096 (match_operand:SI 1 "s_register_operand" "r")
2097 (const_int 16))
2098 (ashiftrt:SI
2099 (match_operand:SI 2 "s_register_operand" "r")
2100 (const_int 16)))
2101 (match_operand:SI 3 "s_register_operand" "r")))]
2102 "TARGET_DSP_MULTIPLY"
2103 "smlatt%?\\t%0, %1, %2, %3"
2104 [(set_attr "type" "smlaxy")
2105 (set_attr "predicable" "yes")]
2106 )
2107
2108 (define_insn "maddhidi4"
2109 [(set (match_operand:DI 0 "s_register_operand" "=r")
2110 (plus:DI
2111 (mult:DI (sign_extend:DI
2112 (match_operand:HI 1 "s_register_operand" "r"))
2113 (sign_extend:DI
2114 (match_operand:HI 2 "s_register_operand" "r")))
2115 (match_operand:DI 3 "s_register_operand" "0")))]
2116 "TARGET_DSP_MULTIPLY"
2117 "smlalbb%?\\t%Q0, %R0, %1, %2"
2118 [(set_attr "type" "smlalxy")
2119 (set_attr "predicable" "yes")])
2120
2121 ;; Note: there is no maddhidi4ibt because this one is canonical form
2122 (define_insn "*maddhidi4tb"
2123 [(set (match_operand:DI 0 "s_register_operand" "=r")
2124 (plus:DI
2125 (mult:DI (sign_extend:DI
2126 (ashiftrt:SI
2127 (match_operand:SI 1 "s_register_operand" "r")
2128 (const_int 16)))
2129 (sign_extend:DI
2130 (match_operand:HI 2 "s_register_operand" "r")))
2131 (match_operand:DI 3 "s_register_operand" "0")))]
2132 "TARGET_DSP_MULTIPLY"
2133 "smlaltb%?\\t%Q0, %R0, %1, %2"
2134 [(set_attr "type" "smlalxy")
2135 (set_attr "predicable" "yes")])
2136
2137 (define_insn "*maddhidi4tt"
2138 [(set (match_operand:DI 0 "s_register_operand" "=r")
2139 (plus:DI
2140 (mult:DI (sign_extend:DI
2141 (ashiftrt:SI
2142 (match_operand:SI 1 "s_register_operand" "r")
2143 (const_int 16)))
2144 (sign_extend:DI
2145 (ashiftrt:SI
2146 (match_operand:SI 2 "s_register_operand" "r")
2147 (const_int 16))))
2148 (match_operand:DI 3 "s_register_operand" "0")))]
2149 "TARGET_DSP_MULTIPLY"
2150 "smlaltt%?\\t%Q0, %R0, %1, %2"
2151 [(set_attr "type" "smlalxy")
2152 (set_attr "predicable" "yes")])
2153
2154 (define_expand "mulsf3"
2155 [(set (match_operand:SF 0 "s_register_operand" "")
2156 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2157 (match_operand:SF 2 "s_register_operand" "")))]
2158 "TARGET_32BIT && TARGET_HARD_FLOAT"
2159 "
2160 ")
2161
2162 (define_expand "muldf3"
2163 [(set (match_operand:DF 0 "s_register_operand" "")
2164 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2165 (match_operand:DF 2 "s_register_operand" "")))]
2166 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2167 "
2168 ")
2169 \f
2170 ;; Division insns
2171
2172 (define_expand "divsf3"
2173 [(set (match_operand:SF 0 "s_register_operand" "")
2174 (div:SF (match_operand:SF 1 "s_register_operand" "")
2175 (match_operand:SF 2 "s_register_operand" "")))]
2176 "TARGET_32BIT && TARGET_HARD_FLOAT"
2177 "")
2178
2179 (define_expand "divdf3"
2180 [(set (match_operand:DF 0 "s_register_operand" "")
2181 (div:DF (match_operand:DF 1 "s_register_operand" "")
2182 (match_operand:DF 2 "s_register_operand" "")))]
2183 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2184 "")
2185 \f
2186 ;; Boolean and,ior,xor insns
2187
2188 ;; Split up double word logical operations
2189
2190 ;; Split up simple DImode logical operations. Simply perform the logical
2191 ;; operation on the upper and lower halves of the registers.
2192 (define_split
2193 [(set (match_operand:DI 0 "s_register_operand" "")
2194 (match_operator:DI 6 "logical_binary_operator"
2195 [(match_operand:DI 1 "s_register_operand" "")
2196 (match_operand:DI 2 "s_register_operand" "")]))]
2197 "TARGET_32BIT && reload_completed
2198 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2199 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2200 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2201 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2202 "
2203 {
2204 operands[3] = gen_highpart (SImode, operands[0]);
2205 operands[0] = gen_lowpart (SImode, operands[0]);
2206 operands[4] = gen_highpart (SImode, operands[1]);
2207 operands[1] = gen_lowpart (SImode, operands[1]);
2208 operands[5] = gen_highpart (SImode, operands[2]);
2209 operands[2] = gen_lowpart (SImode, operands[2]);
2210 }"
2211 )
2212
2213 (define_split
2214 [(set (match_operand:DI 0 "s_register_operand" "")
2215 (match_operator:DI 6 "logical_binary_operator"
2216 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2217 (match_operand:DI 1 "s_register_operand" "")]))]
2218 "TARGET_32BIT && reload_completed"
2219 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2220 (set (match_dup 3) (match_op_dup:SI 6
2221 [(ashiftrt:SI (match_dup 2) (const_int 31))
2222 (match_dup 4)]))]
2223 "
2224 {
2225 operands[3] = gen_highpart (SImode, operands[0]);
2226 operands[0] = gen_lowpart (SImode, operands[0]);
2227 operands[4] = gen_highpart (SImode, operands[1]);
2228 operands[1] = gen_lowpart (SImode, operands[1]);
2229 operands[5] = gen_highpart (SImode, operands[2]);
2230 operands[2] = gen_lowpart (SImode, operands[2]);
2231 }"
2232 )
2233
2234 ;; The zero extend of operand 2 means we can just copy the high part of
2235 ;; operand1 into operand0.
2236 (define_split
2237 [(set (match_operand:DI 0 "s_register_operand" "")
2238 (ior:DI
2239 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2240 (match_operand:DI 1 "s_register_operand" "")))]
2241 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2242 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2243 (set (match_dup 3) (match_dup 4))]
2244 "
2245 {
2246 operands[4] = gen_highpart (SImode, operands[1]);
2247 operands[3] = gen_highpart (SImode, operands[0]);
2248 operands[0] = gen_lowpart (SImode, operands[0]);
2249 operands[1] = gen_lowpart (SImode, operands[1]);
2250 }"
2251 )
2252
2253 ;; The zero extend of operand 2 means we can just copy the high part of
2254 ;; operand1 into operand0.
2255 (define_split
2256 [(set (match_operand:DI 0 "s_register_operand" "")
2257 (xor:DI
2258 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2259 (match_operand:DI 1 "s_register_operand" "")))]
2260 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2261 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2262 (set (match_dup 3) (match_dup 4))]
2263 "
2264 {
2265 operands[4] = gen_highpart (SImode, operands[1]);
2266 operands[3] = gen_highpart (SImode, operands[0]);
2267 operands[0] = gen_lowpart (SImode, operands[0]);
2268 operands[1] = gen_lowpart (SImode, operands[1]);
2269 }"
2270 )
2271
2272 (define_expand "anddi3"
2273 [(set (match_operand:DI 0 "s_register_operand" "")
2274 (and:DI (match_operand:DI 1 "s_register_operand" "")
2275 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2276 "TARGET_32BIT"
2277 "
2278 if (!TARGET_NEON && !TARGET_IWMMXT)
2279 {
2280 rtx low = simplify_gen_binary (AND, SImode,
2281 gen_lowpart (SImode, operands[1]),
2282 gen_lowpart (SImode, operands[2]));
2283 rtx high = simplify_gen_binary (AND, SImode,
2284 gen_highpart (SImode, operands[1]),
2285 gen_highpart_mode (SImode, DImode,
2286 operands[2]));
2287
2288 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2289 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2290
2291 DONE;
2292 }
2293 /* Otherwise expand pattern as above. */
2294 "
2295 )
2296
2297 (define_insn_and_split "*anddi3_insn"
2298 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2299 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2300 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2301 "TARGET_32BIT && !TARGET_IWMMXT"
2302 {
2303 switch (which_alternative)
2304 {
2305 case 0: /* fall through */
2306 case 6: return "vand\t%P0, %P1, %P2";
2307 case 1: /* fall through */
2308 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2309 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2310 case 2:
2311 case 3:
2312 case 4:
2313 case 5: /* fall through */
2314 return "#";
2315 default: gcc_unreachable ();
2316 }
2317 }
2318 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2319 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2320 [(set (match_dup 3) (match_dup 4))
2321 (set (match_dup 5) (match_dup 6))]
2322 "
2323 {
2324 operands[3] = gen_lowpart (SImode, operands[0]);
2325 operands[5] = gen_highpart (SImode, operands[0]);
2326
2327 operands[4] = simplify_gen_binary (AND, SImode,
2328 gen_lowpart (SImode, operands[1]),
2329 gen_lowpart (SImode, operands[2]));
2330 operands[6] = simplify_gen_binary (AND, SImode,
2331 gen_highpart (SImode, operands[1]),
2332 gen_highpart_mode (SImode, DImode, operands[2]));
2333
2334 }"
2335 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2336 multiple,multiple,neon_logic,neon_logic")
2337 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2338 avoid_neon_for_64bits,avoid_neon_for_64bits")
2339 (set_attr "length" "*,*,8,8,8,8,*,*")
2340 ]
2341 )
2342
2343 (define_insn_and_split "*anddi_zesidi_di"
2344 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2345 (and:DI (zero_extend:DI
2346 (match_operand:SI 2 "s_register_operand" "r,r"))
2347 (match_operand:DI 1 "s_register_operand" "0,r")))]
2348 "TARGET_32BIT"
2349 "#"
2350 "TARGET_32BIT && reload_completed"
2351 ; The zero extend of operand 2 clears the high word of the output
2352 ; operand.
2353 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2354 (set (match_dup 3) (const_int 0))]
2355 "
2356 {
2357 operands[3] = gen_highpart (SImode, operands[0]);
2358 operands[0] = gen_lowpart (SImode, operands[0]);
2359 operands[1] = gen_lowpart (SImode, operands[1]);
2360 }"
2361 [(set_attr "length" "8")
2362 (set_attr "type" "multiple")]
2363 )
2364
2365 (define_insn "*anddi_sesdi_di"
2366 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2367 (and:DI (sign_extend:DI
2368 (match_operand:SI 2 "s_register_operand" "r,r"))
2369 (match_operand:DI 1 "s_register_operand" "0,r")))]
2370 "TARGET_32BIT"
2371 "#"
2372 [(set_attr "length" "8")
2373 (set_attr "type" "multiple")]
2374 )
2375
2376 (define_expand "andsi3"
2377 [(set (match_operand:SI 0 "s_register_operand" "")
2378 (and:SI (match_operand:SI 1 "s_register_operand" "")
2379 (match_operand:SI 2 "reg_or_int_operand" "")))]
2380 "TARGET_EITHER"
2381 "
2382 if (TARGET_32BIT)
2383 {
2384 if (CONST_INT_P (operands[2]))
2385 {
2386 if (INTVAL (operands[2]) == 255 && arm_arch6)
2387 {
2388 operands[1] = convert_to_mode (QImode, operands[1], 1);
2389 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2390 operands[1]));
2391 DONE;
2392 }
2393 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2394 operands[2] = force_reg (SImode, operands[2]);
2395 else
2396 {
2397 arm_split_constant (AND, SImode, NULL_RTX,
2398 INTVAL (operands[2]), operands[0],
2399 operands[1],
2400 optimize && can_create_pseudo_p ());
2401
2402 DONE;
2403 }
2404 }
2405 }
2406 else /* TARGET_THUMB1 */
2407 {
2408 if (!CONST_INT_P (operands[2]))
2409 {
2410 rtx tmp = force_reg (SImode, operands[2]);
2411 if (rtx_equal_p (operands[0], operands[1]))
2412 operands[2] = tmp;
2413 else
2414 {
2415 operands[2] = operands[1];
2416 operands[1] = tmp;
2417 }
2418 }
2419 else
2420 {
2421 int i;
2422
2423 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2424 {
2425 operands[2] = force_reg (SImode,
2426 GEN_INT (~INTVAL (operands[2])));
2427
2428 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2429
2430 DONE;
2431 }
2432
2433 for (i = 9; i <= 31; i++)
2434 {
2435 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2436 {
2437 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2438 const0_rtx));
2439 DONE;
2440 }
2441 else if ((HOST_WIDE_INT_1 << i) - 1
2442 == ~INTVAL (operands[2]))
2443 {
2444 rtx shift = GEN_INT (i);
2445 rtx reg = gen_reg_rtx (SImode);
2446
2447 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2448 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2449
2450 DONE;
2451 }
2452 }
2453
2454 operands[2] = force_reg (SImode, operands[2]);
2455 }
2456 }
2457 "
2458 )
2459
2460 ; ??? Check split length for Thumb-2
2461 (define_insn_and_split "*arm_andsi3_insn"
2462 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2463 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2464 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2465 "TARGET_32BIT"
2466 "@
2467 and%?\\t%0, %1, %2
2468 and%?\\t%0, %1, %2
2469 bic%?\\t%0, %1, #%B2
2470 and%?\\t%0, %1, %2
2471 #"
2472 "TARGET_32BIT
2473 && CONST_INT_P (operands[2])
2474 && !(const_ok_for_arm (INTVAL (operands[2]))
2475 || const_ok_for_arm (~INTVAL (operands[2])))"
2476 [(clobber (const_int 0))]
2477 "
2478 arm_split_constant (AND, SImode, curr_insn,
2479 INTVAL (operands[2]), operands[0], operands[1], 0);
2480 DONE;
2481 "
2482 [(set_attr "length" "4,4,4,4,16")
2483 (set_attr "predicable" "yes")
2484 (set_attr "predicable_short_it" "no,yes,no,no,no")
2485 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2486 )
2487
2488 (define_insn "*andsi3_compare0"
2489 [(set (reg:CC_NOOV CC_REGNUM)
2490 (compare:CC_NOOV
2491 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2492 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2493 (const_int 0)))
2494 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2495 (and:SI (match_dup 1) (match_dup 2)))]
2496 "TARGET_32BIT"
2497 "@
2498 ands%?\\t%0, %1, %2
2499 bics%?\\t%0, %1, #%B2
2500 ands%?\\t%0, %1, %2"
2501 [(set_attr "conds" "set")
2502 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2503 )
2504
2505 (define_insn "*andsi3_compare0_scratch"
2506 [(set (reg:CC_NOOV CC_REGNUM)
2507 (compare:CC_NOOV
2508 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2509 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2510 (const_int 0)))
2511 (clobber (match_scratch:SI 2 "=X,r,X"))]
2512 "TARGET_32BIT"
2513 "@
2514 tst%?\\t%0, %1
2515 bics%?\\t%2, %0, #%B1
2516 tst%?\\t%0, %1"
2517 [(set_attr "conds" "set")
2518 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2519 )
2520
2521 (define_insn "*zeroextractsi_compare0_scratch"
2522 [(set (reg:CC_NOOV CC_REGNUM)
2523 (compare:CC_NOOV (zero_extract:SI
2524 (match_operand:SI 0 "s_register_operand" "r")
2525 (match_operand 1 "const_int_operand" "n")
2526 (match_operand 2 "const_int_operand" "n"))
2527 (const_int 0)))]
2528 "TARGET_32BIT
2529 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2530 && INTVAL (operands[1]) > 0
2531 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2532 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2533 "*
2534 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2535 << INTVAL (operands[2]));
2536 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2537 return \"\";
2538 "
2539 [(set_attr "conds" "set")
2540 (set_attr "predicable" "yes")
2541 (set_attr "type" "logics_imm")]
2542 )
2543
2544 (define_insn_and_split "*ne_zeroextractsi"
2545 [(set (match_operand:SI 0 "s_register_operand" "=r")
2546 (ne:SI (zero_extract:SI
2547 (match_operand:SI 1 "s_register_operand" "r")
2548 (match_operand:SI 2 "const_int_operand" "n")
2549 (match_operand:SI 3 "const_int_operand" "n"))
2550 (const_int 0)))
2551 (clobber (reg:CC CC_REGNUM))]
2552 "TARGET_32BIT
2553 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2554 && INTVAL (operands[2]) > 0
2555 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2556 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2557 "#"
2558 "TARGET_32BIT
2559 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2560 && INTVAL (operands[2]) > 0
2561 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2562 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2563 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2564 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2565 (const_int 0)))
2566 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2567 (set (match_dup 0)
2568 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2569 (match_dup 0) (const_int 1)))]
2570 "
2571 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2572 << INTVAL (operands[3]));
2573 "
2574 [(set_attr "conds" "clob")
2575 (set (attr "length")
2576 (if_then_else (eq_attr "is_thumb" "yes")
2577 (const_int 12)
2578 (const_int 8)))
2579 (set_attr "type" "multiple")]
2580 )
2581
2582 (define_insn_and_split "*ne_zeroextractsi_shifted"
2583 [(set (match_operand:SI 0 "s_register_operand" "=r")
2584 (ne:SI (zero_extract:SI
2585 (match_operand:SI 1 "s_register_operand" "r")
2586 (match_operand:SI 2 "const_int_operand" "n")
2587 (const_int 0))
2588 (const_int 0)))
2589 (clobber (reg:CC CC_REGNUM))]
2590 "TARGET_ARM"
2591 "#"
2592 "TARGET_ARM"
2593 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2594 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2595 (const_int 0)))
2596 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2597 (set (match_dup 0)
2598 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2599 (match_dup 0) (const_int 1)))]
2600 "
2601 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2602 "
2603 [(set_attr "conds" "clob")
2604 (set_attr "length" "8")
2605 (set_attr "type" "multiple")]
2606 )
2607
2608 (define_insn_and_split "*ite_ne_zeroextractsi"
2609 [(set (match_operand:SI 0 "s_register_operand" "=r")
2610 (if_then_else:SI (ne (zero_extract:SI
2611 (match_operand:SI 1 "s_register_operand" "r")
2612 (match_operand:SI 2 "const_int_operand" "n")
2613 (match_operand:SI 3 "const_int_operand" "n"))
2614 (const_int 0))
2615 (match_operand:SI 4 "arm_not_operand" "rIK")
2616 (const_int 0)))
2617 (clobber (reg:CC CC_REGNUM))]
2618 "TARGET_ARM
2619 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2620 && INTVAL (operands[2]) > 0
2621 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2622 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2623 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2624 "#"
2625 "TARGET_ARM
2626 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2627 && INTVAL (operands[2]) > 0
2628 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2629 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2630 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2631 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2632 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2633 (const_int 0)))
2634 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2635 (set (match_dup 0)
2636 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2637 (match_dup 0) (match_dup 4)))]
2638 "
2639 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2640 << INTVAL (operands[3]));
2641 "
2642 [(set_attr "conds" "clob")
2643 (set_attr "length" "8")
2644 (set_attr "type" "multiple")]
2645 )
2646
2647 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2648 [(set (match_operand:SI 0 "s_register_operand" "=r")
2649 (if_then_else:SI (ne (zero_extract:SI
2650 (match_operand:SI 1 "s_register_operand" "r")
2651 (match_operand:SI 2 "const_int_operand" "n")
2652 (const_int 0))
2653 (const_int 0))
2654 (match_operand:SI 3 "arm_not_operand" "rIK")
2655 (const_int 0)))
2656 (clobber (reg:CC CC_REGNUM))]
2657 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2658 "#"
2659 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2660 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2661 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2662 (const_int 0)))
2663 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2664 (set (match_dup 0)
2665 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2666 (match_dup 0) (match_dup 3)))]
2667 "
2668 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2669 "
2670 [(set_attr "conds" "clob")
2671 (set_attr "length" "8")
2672 (set_attr "type" "multiple")]
2673 )
2674
2675 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2676 (define_split
2677 [(set (match_operand:SI 0 "s_register_operand" "")
2678 (match_operator:SI 1 "shiftable_operator"
2679 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2680 (match_operand:SI 3 "const_int_operand" "")
2681 (match_operand:SI 4 "const_int_operand" ""))
2682 (match_operand:SI 5 "s_register_operand" "")]))
2683 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2684 "TARGET_ARM"
2685 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2686 (set (match_dup 0)
2687 (match_op_dup 1
2688 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2689 (match_dup 5)]))]
2690 "{
2691 HOST_WIDE_INT temp = INTVAL (operands[3]);
2692
2693 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2694 operands[4] = GEN_INT (32 - temp);
2695 }"
2696 )
2697
2698 (define_split
2699 [(set (match_operand:SI 0 "s_register_operand" "")
2700 (match_operator:SI 1 "shiftable_operator"
2701 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2702 (match_operand:SI 3 "const_int_operand" "")
2703 (match_operand:SI 4 "const_int_operand" ""))
2704 (match_operand:SI 5 "s_register_operand" "")]))
2705 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2706 "TARGET_ARM"
2707 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2708 (set (match_dup 0)
2709 (match_op_dup 1
2710 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2711 (match_dup 5)]))]
2712 "{
2713 HOST_WIDE_INT temp = INTVAL (operands[3]);
2714
2715 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2716 operands[4] = GEN_INT (32 - temp);
2717 }"
2718 )
2719
2720 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2721 ;;; represented by the bitfield, then this will produce incorrect results.
2722 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2723 ;;; which have a real bit-field insert instruction, the truncation happens
2724 ;;; in the bit-field insert instruction itself. Since arm does not have a
2725 ;;; bit-field insert instruction, we would have to emit code here to truncate
2726 ;;; the value before we insert. This loses some of the advantage of having
2727 ;;; this insv pattern, so this pattern needs to be reevalutated.
2728
2729 (define_expand "insv"
2730 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2731 (match_operand 1 "general_operand" "")
2732 (match_operand 2 "general_operand" ""))
2733 (match_operand 3 "reg_or_int_operand" ""))]
2734 "TARGET_ARM || arm_arch_thumb2"
2735 "
2736 {
2737 int start_bit = INTVAL (operands[2]);
2738 int width = INTVAL (operands[1]);
2739 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2740 rtx target, subtarget;
2741
2742 if (arm_arch_thumb2)
2743 {
2744 if (unaligned_access && MEM_P (operands[0])
2745 && s_register_operand (operands[3], GET_MODE (operands[3]))
2746 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2747 {
2748 rtx base_addr;
2749
2750 if (BYTES_BIG_ENDIAN)
2751 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2752 - start_bit;
2753
2754 if (width == 32)
2755 {
2756 base_addr = adjust_address (operands[0], SImode,
2757 start_bit / BITS_PER_UNIT);
2758 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2759 }
2760 else
2761 {
2762 rtx tmp = gen_reg_rtx (HImode);
2763
2764 base_addr = adjust_address (operands[0], HImode,
2765 start_bit / BITS_PER_UNIT);
2766 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2767 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2768 }
2769 DONE;
2770 }
2771 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2772 {
2773 bool use_bfi = TRUE;
2774
2775 if (CONST_INT_P (operands[3]))
2776 {
2777 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2778
2779 if (val == 0)
2780 {
2781 emit_insn (gen_insv_zero (operands[0], operands[1],
2782 operands[2]));
2783 DONE;
2784 }
2785
2786 /* See if the set can be done with a single orr instruction. */
2787 if (val == mask && const_ok_for_arm (val << start_bit))
2788 use_bfi = FALSE;
2789 }
2790
2791 if (use_bfi)
2792 {
2793 if (!REG_P (operands[3]))
2794 operands[3] = force_reg (SImode, operands[3]);
2795
2796 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2797 operands[3]));
2798 DONE;
2799 }
2800 }
2801 else
2802 FAIL;
2803 }
2804
2805 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2806 FAIL;
2807
2808 target = copy_rtx (operands[0]);
2809 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2810 subreg as the final target. */
2811 if (GET_CODE (target) == SUBREG)
2812 {
2813 subtarget = gen_reg_rtx (SImode);
2814 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2815 < GET_MODE_SIZE (SImode))
2816 target = SUBREG_REG (target);
2817 }
2818 else
2819 subtarget = target;
2820
2821 if (CONST_INT_P (operands[3]))
2822 {
2823 /* Since we are inserting a known constant, we may be able to
2824 reduce the number of bits that we have to clear so that
2825 the mask becomes simple. */
2826 /* ??? This code does not check to see if the new mask is actually
2827 simpler. It may not be. */
2828 rtx op1 = gen_reg_rtx (SImode);
2829 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2830 start of this pattern. */
2831 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2832 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2833
2834 emit_insn (gen_andsi3 (op1, operands[0],
2835 gen_int_mode (~mask2, SImode)));
2836 emit_insn (gen_iorsi3 (subtarget, op1,
2837 gen_int_mode (op3_value << start_bit, SImode)));
2838 }
2839 else if (start_bit == 0
2840 && !(const_ok_for_arm (mask)
2841 || const_ok_for_arm (~mask)))
2842 {
2843 /* A Trick, since we are setting the bottom bits in the word,
2844 we can shift operand[3] up, operand[0] down, OR them together
2845 and rotate the result back again. This takes 3 insns, and
2846 the third might be mergeable into another op. */
2847 /* The shift up copes with the possibility that operand[3] is
2848 wider than the bitfield. */
2849 rtx op0 = gen_reg_rtx (SImode);
2850 rtx op1 = gen_reg_rtx (SImode);
2851
2852 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2853 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2854 emit_insn (gen_iorsi3 (op1, op1, op0));
2855 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2856 }
2857 else if ((width + start_bit == 32)
2858 && !(const_ok_for_arm (mask)
2859 || const_ok_for_arm (~mask)))
2860 {
2861 /* Similar trick, but slightly less efficient. */
2862
2863 rtx op0 = gen_reg_rtx (SImode);
2864 rtx op1 = gen_reg_rtx (SImode);
2865
2866 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2867 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2868 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2869 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2870 }
2871 else
2872 {
2873 rtx op0 = gen_int_mode (mask, SImode);
2874 rtx op1 = gen_reg_rtx (SImode);
2875 rtx op2 = gen_reg_rtx (SImode);
2876
2877 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2878 {
2879 rtx tmp = gen_reg_rtx (SImode);
2880
2881 emit_insn (gen_movsi (tmp, op0));
2882 op0 = tmp;
2883 }
2884
2885 /* Mask out any bits in operand[3] that are not needed. */
2886 emit_insn (gen_andsi3 (op1, operands[3], op0));
2887
2888 if (CONST_INT_P (op0)
2889 && (const_ok_for_arm (mask << start_bit)
2890 || const_ok_for_arm (~(mask << start_bit))))
2891 {
2892 op0 = gen_int_mode (~(mask << start_bit), SImode);
2893 emit_insn (gen_andsi3 (op2, operands[0], op0));
2894 }
2895 else
2896 {
2897 if (CONST_INT_P (op0))
2898 {
2899 rtx tmp = gen_reg_rtx (SImode);
2900
2901 emit_insn (gen_movsi (tmp, op0));
2902 op0 = tmp;
2903 }
2904
2905 if (start_bit != 0)
2906 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2907
2908 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2909 }
2910
2911 if (start_bit != 0)
2912 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2913
2914 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2915 }
2916
2917 if (subtarget != target)
2918 {
2919 /* If TARGET is still a SUBREG, then it must be wider than a word,
2920 so we must be careful only to set the subword we were asked to. */
2921 if (GET_CODE (target) == SUBREG)
2922 emit_move_insn (target, subtarget);
2923 else
2924 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2925 }
2926
2927 DONE;
2928 }"
2929 )
2930
2931 (define_insn "insv_zero"
2932 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2933 (match_operand:SI 1 "const_int_M_operand" "M")
2934 (match_operand:SI 2 "const_int_M_operand" "M"))
2935 (const_int 0))]
2936 "arm_arch_thumb2"
2937 "bfc%?\t%0, %2, %1"
2938 [(set_attr "length" "4")
2939 (set_attr "predicable" "yes")
2940 (set_attr "type" "bfm")]
2941 )
2942
2943 (define_insn "insv_t2"
2944 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2945 (match_operand:SI 1 "const_int_M_operand" "M")
2946 (match_operand:SI 2 "const_int_M_operand" "M"))
2947 (match_operand:SI 3 "s_register_operand" "r"))]
2948 "arm_arch_thumb2"
2949 "bfi%?\t%0, %3, %2, %1"
2950 [(set_attr "length" "4")
2951 (set_attr "predicable" "yes")
2952 (set_attr "type" "bfm")]
2953 )
2954
2955 ; constants for op 2 will never be given to these patterns.
2956 (define_insn_and_split "*anddi_notdi_di"
2957 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2958 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2959 (match_operand:DI 2 "s_register_operand" "r,0")))]
2960 "TARGET_32BIT"
2961 "#"
2962 "TARGET_32BIT && reload_completed
2963 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2964 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2965 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2966 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2967 "
2968 {
2969 operands[3] = gen_highpart (SImode, operands[0]);
2970 operands[0] = gen_lowpart (SImode, operands[0]);
2971 operands[4] = gen_highpart (SImode, operands[1]);
2972 operands[1] = gen_lowpart (SImode, operands[1]);
2973 operands[5] = gen_highpart (SImode, operands[2]);
2974 operands[2] = gen_lowpart (SImode, operands[2]);
2975 }"
2976 [(set_attr "length" "8")
2977 (set_attr "predicable" "yes")
2978 (set_attr "type" "multiple")]
2979 )
2980
2981 (define_insn_and_split "*anddi_notzesidi_di"
2982 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2983 (and:DI (not:DI (zero_extend:DI
2984 (match_operand:SI 2 "s_register_operand" "r,r")))
2985 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2986 "TARGET_32BIT"
2987 "@
2988 bic%?\\t%Q0, %Q1, %2
2989 #"
2990 ; (not (zero_extend ...)) allows us to just copy the high word from
2991 ; operand1 to operand0.
2992 "TARGET_32BIT
2993 && reload_completed
2994 && operands[0] != operands[1]"
2995 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2996 (set (match_dup 3) (match_dup 4))]
2997 "
2998 {
2999 operands[3] = gen_highpart (SImode, operands[0]);
3000 operands[0] = gen_lowpart (SImode, operands[0]);
3001 operands[4] = gen_highpart (SImode, operands[1]);
3002 operands[1] = gen_lowpart (SImode, operands[1]);
3003 }"
3004 [(set_attr "length" "4,8")
3005 (set_attr "predicable" "yes")
3006 (set_attr "type" "multiple")]
3007 )
3008
3009 (define_insn_and_split "*anddi_notdi_zesidi"
3010 [(set (match_operand:DI 0 "s_register_operand" "=r")
3011 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
3012 (zero_extend:DI
3013 (match_operand:SI 1 "s_register_operand" "r"))))]
3014 "TARGET_32BIT"
3015 "#"
3016 "TARGET_32BIT && reload_completed"
3017 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3018 (set (match_dup 3) (const_int 0))]
3019 "
3020 {
3021 operands[3] = gen_highpart (SImode, operands[0]);
3022 operands[0] = gen_lowpart (SImode, operands[0]);
3023 operands[2] = gen_lowpart (SImode, operands[2]);
3024 }"
3025 [(set_attr "length" "8")
3026 (set_attr "predicable" "yes")
3027 (set_attr "type" "multiple")]
3028 )
3029
3030 (define_insn_and_split "*anddi_notsesidi_di"
3031 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3032 (and:DI (not:DI (sign_extend:DI
3033 (match_operand:SI 2 "s_register_operand" "r,r")))
3034 (match_operand:DI 1 "s_register_operand" "0,r")))]
3035 "TARGET_32BIT"
3036 "#"
3037 "TARGET_32BIT && reload_completed"
3038 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3039 (set (match_dup 3) (and:SI (not:SI
3040 (ashiftrt:SI (match_dup 2) (const_int 31)))
3041 (match_dup 4)))]
3042 "
3043 {
3044 operands[3] = gen_highpart (SImode, operands[0]);
3045 operands[0] = gen_lowpart (SImode, operands[0]);
3046 operands[4] = gen_highpart (SImode, operands[1]);
3047 operands[1] = gen_lowpart (SImode, operands[1]);
3048 }"
3049 [(set_attr "length" "8")
3050 (set_attr "predicable" "yes")
3051 (set_attr "type" "multiple")]
3052 )
3053
3054 (define_insn "andsi_notsi_si"
3055 [(set (match_operand:SI 0 "s_register_operand" "=r")
3056 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3057 (match_operand:SI 1 "s_register_operand" "r")))]
3058 "TARGET_32BIT"
3059 "bic%?\\t%0, %1, %2"
3060 [(set_attr "predicable" "yes")
3061 (set_attr "type" "logic_reg")]
3062 )
3063
3064 (define_insn "andsi_not_shiftsi_si"
3065 [(set (match_operand:SI 0 "s_register_operand" "=r")
3066 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3067 [(match_operand:SI 2 "s_register_operand" "r")
3068 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3069 (match_operand:SI 1 "s_register_operand" "r")))]
3070 "TARGET_ARM"
3071 "bic%?\\t%0, %1, %2%S4"
3072 [(set_attr "predicable" "yes")
3073 (set_attr "shift" "2")
3074 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3075 (const_string "logic_shift_imm")
3076 (const_string "logic_shift_reg")))]
3077 )
3078
3079 ;; Shifted bics pattern used to set up CC status register and not reusing
3080 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3081 ;; does not support shift by register.
3082 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3083 [(set (reg:CC_NOOV CC_REGNUM)
3084 (compare:CC_NOOV
3085 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3086 [(match_operand:SI 1 "s_register_operand" "r")
3087 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3088 (match_operand:SI 3 "s_register_operand" "r"))
3089 (const_int 0)))
3090 (clobber (match_scratch:SI 4 "=r"))]
3091 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3092 "bics%?\\t%4, %3, %1%S0"
3093 [(set_attr "predicable" "yes")
3094 (set_attr "conds" "set")
3095 (set_attr "shift" "1")
3096 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3097 (const_string "logic_shift_imm")
3098 (const_string "logic_shift_reg")))]
3099 )
3100
3101 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3102 ;; getting reused later.
3103 (define_insn "andsi_not_shiftsi_si_scc"
3104 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3105 (compare:CC_NOOV
3106 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3107 [(match_operand:SI 1 "s_register_operand" "r")
3108 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3109 (match_operand:SI 3 "s_register_operand" "r"))
3110 (const_int 0)))
3111 (set (match_operand:SI 4 "s_register_operand" "=r")
3112 (and:SI (not:SI (match_op_dup 0
3113 [(match_dup 1)
3114 (match_dup 2)]))
3115 (match_dup 3)))])]
3116 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3117 "bics%?\\t%4, %3, %1%S0"
3118 [(set_attr "predicable" "yes")
3119 (set_attr "conds" "set")
3120 (set_attr "shift" "1")
3121 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3122 (const_string "logic_shift_imm")
3123 (const_string "logic_shift_reg")))]
3124 )
3125
3126 (define_insn "*andsi_notsi_si_compare0"
3127 [(set (reg:CC_NOOV CC_REGNUM)
3128 (compare:CC_NOOV
3129 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3130 (match_operand:SI 1 "s_register_operand" "r"))
3131 (const_int 0)))
3132 (set (match_operand:SI 0 "s_register_operand" "=r")
3133 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
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_insn "*andsi_notsi_si_compare0_scratch"
3141 [(set (reg:CC_NOOV CC_REGNUM)
3142 (compare:CC_NOOV
3143 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3144 (match_operand:SI 1 "s_register_operand" "r"))
3145 (const_int 0)))
3146 (clobber (match_scratch:SI 0 "=r"))]
3147 "TARGET_32BIT"
3148 "bics\\t%0, %1, %2"
3149 [(set_attr "conds" "set")
3150 (set_attr "type" "logics_shift_reg")]
3151 )
3152
3153 (define_expand "iordi3"
3154 [(set (match_operand:DI 0 "s_register_operand" "")
3155 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3156 (match_operand:DI 2 "neon_logic_op2" "")))]
3157 "TARGET_32BIT"
3158 "
3159 if (!TARGET_NEON && !TARGET_IWMMXT)
3160 {
3161 rtx low = simplify_gen_binary (IOR, SImode,
3162 gen_lowpart (SImode, operands[1]),
3163 gen_lowpart (SImode, operands[2]));
3164 rtx high = simplify_gen_binary (IOR, SImode,
3165 gen_highpart (SImode, operands[1]),
3166 gen_highpart_mode (SImode, DImode,
3167 operands[2]));
3168
3169 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3170 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3171
3172 DONE;
3173 }
3174 /* Otherwise expand pattern as above. */
3175 "
3176 )
3177
3178 (define_insn_and_split "*iordi3_insn"
3179 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3180 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3181 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3182 "TARGET_32BIT && !TARGET_IWMMXT"
3183 {
3184 switch (which_alternative)
3185 {
3186 case 0: /* fall through */
3187 case 6: return "vorr\t%P0, %P1, %P2";
3188 case 1: /* fall through */
3189 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3190 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3191 case 2:
3192 case 3:
3193 case 4:
3194 case 5:
3195 return "#";
3196 default: gcc_unreachable ();
3197 }
3198 }
3199 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3200 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3201 [(set (match_dup 3) (match_dup 4))
3202 (set (match_dup 5) (match_dup 6))]
3203 "
3204 {
3205 operands[3] = gen_lowpart (SImode, operands[0]);
3206 operands[5] = gen_highpart (SImode, operands[0]);
3207
3208 operands[4] = simplify_gen_binary (IOR, SImode,
3209 gen_lowpart (SImode, operands[1]),
3210 gen_lowpart (SImode, operands[2]));
3211 operands[6] = simplify_gen_binary (IOR, SImode,
3212 gen_highpart (SImode, operands[1]),
3213 gen_highpart_mode (SImode, DImode, operands[2]));
3214
3215 }"
3216 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3217 multiple,neon_logic,neon_logic")
3218 (set_attr "length" "*,*,8,8,8,8,*,*")
3219 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3220 )
3221
3222 (define_insn "*iordi_zesidi_di"
3223 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3224 (ior:DI (zero_extend:DI
3225 (match_operand:SI 2 "s_register_operand" "r,r"))
3226 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3227 "TARGET_32BIT"
3228 "@
3229 orr%?\\t%Q0, %Q1, %2
3230 #"
3231 [(set_attr "length" "4,8")
3232 (set_attr "predicable" "yes")
3233 (set_attr "type" "logic_reg,multiple")]
3234 )
3235
3236 (define_insn "*iordi_sesidi_di"
3237 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3238 (ior:DI (sign_extend:DI
3239 (match_operand:SI 2 "s_register_operand" "r,r"))
3240 (match_operand:DI 1 "s_register_operand" "0,r")))]
3241 "TARGET_32BIT"
3242 "#"
3243 [(set_attr "length" "8")
3244 (set_attr "predicable" "yes")
3245 (set_attr "type" "multiple")]
3246 )
3247
3248 (define_expand "iorsi3"
3249 [(set (match_operand:SI 0 "s_register_operand" "")
3250 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3251 (match_operand:SI 2 "reg_or_int_operand" "")))]
3252 "TARGET_EITHER"
3253 "
3254 if (CONST_INT_P (operands[2]))
3255 {
3256 if (TARGET_32BIT)
3257 {
3258 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3259 operands[2] = force_reg (SImode, operands[2]);
3260 else
3261 {
3262 arm_split_constant (IOR, SImode, NULL_RTX,
3263 INTVAL (operands[2]), operands[0],
3264 operands[1],
3265 optimize && can_create_pseudo_p ());
3266 DONE;
3267 }
3268 }
3269 else /* TARGET_THUMB1 */
3270 {
3271 rtx tmp = force_reg (SImode, operands[2]);
3272 if (rtx_equal_p (operands[0], operands[1]))
3273 operands[2] = tmp;
3274 else
3275 {
3276 operands[2] = operands[1];
3277 operands[1] = tmp;
3278 }
3279 }
3280 }
3281 "
3282 )
3283
3284 (define_insn_and_split "*iorsi3_insn"
3285 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3286 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3287 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3288 "TARGET_32BIT"
3289 "@
3290 orr%?\\t%0, %1, %2
3291 orr%?\\t%0, %1, %2
3292 orn%?\\t%0, %1, #%B2
3293 orr%?\\t%0, %1, %2
3294 #"
3295 "TARGET_32BIT
3296 && CONST_INT_P (operands[2])
3297 && !(const_ok_for_arm (INTVAL (operands[2]))
3298 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3299 [(clobber (const_int 0))]
3300 {
3301 arm_split_constant (IOR, SImode, curr_insn,
3302 INTVAL (operands[2]), operands[0], operands[1], 0);
3303 DONE;
3304 }
3305 [(set_attr "length" "4,4,4,4,16")
3306 (set_attr "arch" "32,t2,t2,32,32")
3307 (set_attr "predicable" "yes")
3308 (set_attr "predicable_short_it" "no,yes,no,no,no")
3309 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3310 )
3311
3312 (define_peephole2
3313 [(match_scratch:SI 3 "r")
3314 (set (match_operand:SI 0 "arm_general_register_operand" "")
3315 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3316 (match_operand:SI 2 "const_int_operand" "")))]
3317 "TARGET_ARM
3318 && !const_ok_for_arm (INTVAL (operands[2]))
3319 && const_ok_for_arm (~INTVAL (operands[2]))"
3320 [(set (match_dup 3) (match_dup 2))
3321 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3322 ""
3323 )
3324
3325 (define_insn "*iorsi3_compare0"
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 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3331 (ior:SI (match_dup 1) (match_dup 2)))]
3332 "TARGET_32BIT"
3333 "orrs%?\\t%0, %1, %2"
3334 [(set_attr "conds" "set")
3335 (set_attr "type" "logics_imm,logics_reg")]
3336 )
3337
3338 (define_insn "*iorsi3_compare0_scratch"
3339 [(set (reg:CC_NOOV CC_REGNUM)
3340 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3341 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3342 (const_int 0)))
3343 (clobber (match_scratch:SI 0 "=r,r"))]
3344 "TARGET_32BIT"
3345 "orrs%?\\t%0, %1, %2"
3346 [(set_attr "conds" "set")
3347 (set_attr "type" "logics_imm,logics_reg")]
3348 )
3349
3350 (define_expand "xordi3"
3351 [(set (match_operand:DI 0 "s_register_operand" "")
3352 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3353 (match_operand:DI 2 "arm_xordi_operand" "")))]
3354 "TARGET_32BIT"
3355 {
3356 /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3357 to reuse this expander for all TARGET_32BIT targets so just force the
3358 constants into a register. Unlike for the anddi3 and iordi3 there are
3359 no NEON instructions that take an immediate. */
3360 if (TARGET_IWMMXT && !REG_P (operands[2]))
3361 operands[2] = force_reg (DImode, operands[2]);
3362 if (!TARGET_NEON && !TARGET_IWMMXT)
3363 {
3364 rtx low = simplify_gen_binary (XOR, SImode,
3365 gen_lowpart (SImode, operands[1]),
3366 gen_lowpart (SImode, operands[2]));
3367 rtx high = simplify_gen_binary (XOR, SImode,
3368 gen_highpart (SImode, operands[1]),
3369 gen_highpart_mode (SImode, DImode,
3370 operands[2]));
3371
3372 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3373 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3374
3375 DONE;
3376 }
3377 /* Otherwise expand pattern as above. */
3378 }
3379 )
3380
3381 (define_insn_and_split "*xordi3_insn"
3382 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3383 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3384 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3385 "TARGET_32BIT && !TARGET_IWMMXT"
3386 {
3387 switch (which_alternative)
3388 {
3389 case 1:
3390 case 2:
3391 case 3:
3392 case 4: /* fall through */
3393 return "#";
3394 case 0: /* fall through */
3395 case 5: return "veor\t%P0, %P1, %P2";
3396 default: gcc_unreachable ();
3397 }
3398 }
3399 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3400 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3401 [(set (match_dup 3) (match_dup 4))
3402 (set (match_dup 5) (match_dup 6))]
3403 "
3404 {
3405 operands[3] = gen_lowpart (SImode, operands[0]);
3406 operands[5] = gen_highpart (SImode, operands[0]);
3407
3408 operands[4] = simplify_gen_binary (XOR, SImode,
3409 gen_lowpart (SImode, operands[1]),
3410 gen_lowpart (SImode, operands[2]));
3411 operands[6] = simplify_gen_binary (XOR, SImode,
3412 gen_highpart (SImode, operands[1]),
3413 gen_highpart_mode (SImode, DImode, operands[2]));
3414
3415 }"
3416 [(set_attr "length" "*,8,8,8,8,*")
3417 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3418 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3419 )
3420
3421 (define_insn "*xordi_zesidi_di"
3422 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3423 (xor:DI (zero_extend:DI
3424 (match_operand:SI 2 "s_register_operand" "r,r"))
3425 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3426 "TARGET_32BIT"
3427 "@
3428 eor%?\\t%Q0, %Q1, %2
3429 #"
3430 [(set_attr "length" "4,8")
3431 (set_attr "predicable" "yes")
3432 (set_attr "type" "logic_reg")]
3433 )
3434
3435 (define_insn "*xordi_sesidi_di"
3436 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3437 (xor:DI (sign_extend:DI
3438 (match_operand:SI 2 "s_register_operand" "r,r"))
3439 (match_operand:DI 1 "s_register_operand" "0,r")))]
3440 "TARGET_32BIT"
3441 "#"
3442 [(set_attr "length" "8")
3443 (set_attr "predicable" "yes")
3444 (set_attr "type" "multiple")]
3445 )
3446
3447 (define_expand "xorsi3"
3448 [(set (match_operand:SI 0 "s_register_operand" "")
3449 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3450 (match_operand:SI 2 "reg_or_int_operand" "")))]
3451 "TARGET_EITHER"
3452 "if (CONST_INT_P (operands[2]))
3453 {
3454 if (TARGET_32BIT)
3455 {
3456 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3457 operands[2] = force_reg (SImode, operands[2]);
3458 else
3459 {
3460 arm_split_constant (XOR, SImode, NULL_RTX,
3461 INTVAL (operands[2]), operands[0],
3462 operands[1],
3463 optimize && can_create_pseudo_p ());
3464 DONE;
3465 }
3466 }
3467 else /* TARGET_THUMB1 */
3468 {
3469 rtx tmp = force_reg (SImode, operands[2]);
3470 if (rtx_equal_p (operands[0], operands[1]))
3471 operands[2] = tmp;
3472 else
3473 {
3474 operands[2] = operands[1];
3475 operands[1] = tmp;
3476 }
3477 }
3478 }"
3479 )
3480
3481 (define_insn_and_split "*arm_xorsi3"
3482 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3483 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3484 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3485 "TARGET_32BIT"
3486 "@
3487 eor%?\\t%0, %1, %2
3488 eor%?\\t%0, %1, %2
3489 eor%?\\t%0, %1, %2
3490 #"
3491 "TARGET_32BIT
3492 && CONST_INT_P (operands[2])
3493 && !const_ok_for_arm (INTVAL (operands[2]))"
3494 [(clobber (const_int 0))]
3495 {
3496 arm_split_constant (XOR, SImode, curr_insn,
3497 INTVAL (operands[2]), operands[0], operands[1], 0);
3498 DONE;
3499 }
3500 [(set_attr "length" "4,4,4,16")
3501 (set_attr "predicable" "yes")
3502 (set_attr "predicable_short_it" "no,yes,no,no")
3503 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3504 )
3505
3506 (define_insn "*xorsi3_compare0"
3507 [(set (reg:CC_NOOV CC_REGNUM)
3508 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3509 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3510 (const_int 0)))
3511 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3512 (xor:SI (match_dup 1) (match_dup 2)))]
3513 "TARGET_32BIT"
3514 "eors%?\\t%0, %1, %2"
3515 [(set_attr "conds" "set")
3516 (set_attr "type" "logics_imm,logics_reg")]
3517 )
3518
3519 (define_insn "*xorsi3_compare0_scratch"
3520 [(set (reg:CC_NOOV CC_REGNUM)
3521 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3522 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3523 (const_int 0)))]
3524 "TARGET_32BIT"
3525 "teq%?\\t%0, %1"
3526 [(set_attr "conds" "set")
3527 (set_attr "type" "logics_imm,logics_reg")]
3528 )
3529
3530 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3531 ; (NOT D) we can sometimes merge the final NOT into one of the following
3532 ; insns.
3533
3534 (define_split
3535 [(set (match_operand:SI 0 "s_register_operand" "")
3536 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3537 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3538 (match_operand:SI 3 "arm_rhs_operand" "")))
3539 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3540 "TARGET_32BIT"
3541 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3542 (not:SI (match_dup 3))))
3543 (set (match_dup 0) (not:SI (match_dup 4)))]
3544 ""
3545 )
3546
3547 (define_insn_and_split "*andsi_iorsi3_notsi"
3548 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3549 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3550 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3551 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3552 "TARGET_32BIT"
3553 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3554 "&& reload_completed"
3555 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3556 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3557 {
3558 /* If operands[3] is a constant make sure to fold the NOT into it
3559 to avoid creating a NOT of a CONST_INT. */
3560 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3561 if (CONST_INT_P (not_rtx))
3562 {
3563 operands[4] = operands[0];
3564 operands[5] = not_rtx;
3565 }
3566 else
3567 {
3568 operands[5] = operands[0];
3569 operands[4] = not_rtx;
3570 }
3571 }
3572 [(set_attr "length" "8")
3573 (set_attr "ce_count" "2")
3574 (set_attr "predicable" "yes")
3575 (set_attr "type" "multiple")]
3576 )
3577
3578 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3579 ; insns are available?
3580 (define_split
3581 [(set (match_operand:SI 0 "s_register_operand" "")
3582 (match_operator:SI 1 "logical_binary_operator"
3583 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3584 (match_operand:SI 3 "const_int_operand" "")
3585 (match_operand:SI 4 "const_int_operand" ""))
3586 (match_operator:SI 9 "logical_binary_operator"
3587 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3588 (match_operand:SI 6 "const_int_operand" ""))
3589 (match_operand:SI 7 "s_register_operand" "")])]))
3590 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3591 "TARGET_32BIT
3592 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3593 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3594 [(set (match_dup 8)
3595 (match_op_dup 1
3596 [(ashift:SI (match_dup 2) (match_dup 4))
3597 (match_dup 5)]))
3598 (set (match_dup 0)
3599 (match_op_dup 1
3600 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3601 (match_dup 7)]))]
3602 "
3603 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3604 ")
3605
3606 (define_split
3607 [(set (match_operand:SI 0 "s_register_operand" "")
3608 (match_operator:SI 1 "logical_binary_operator"
3609 [(match_operator:SI 9 "logical_binary_operator"
3610 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3611 (match_operand:SI 6 "const_int_operand" ""))
3612 (match_operand:SI 7 "s_register_operand" "")])
3613 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3614 (match_operand:SI 3 "const_int_operand" "")
3615 (match_operand:SI 4 "const_int_operand" ""))]))
3616 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3617 "TARGET_32BIT
3618 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3619 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3620 [(set (match_dup 8)
3621 (match_op_dup 1
3622 [(ashift:SI (match_dup 2) (match_dup 4))
3623 (match_dup 5)]))
3624 (set (match_dup 0)
3625 (match_op_dup 1
3626 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3627 (match_dup 7)]))]
3628 "
3629 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3630 ")
3631
3632 (define_split
3633 [(set (match_operand:SI 0 "s_register_operand" "")
3634 (match_operator:SI 1 "logical_binary_operator"
3635 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3636 (match_operand:SI 3 "const_int_operand" "")
3637 (match_operand:SI 4 "const_int_operand" ""))
3638 (match_operator:SI 9 "logical_binary_operator"
3639 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3640 (match_operand:SI 6 "const_int_operand" ""))
3641 (match_operand:SI 7 "s_register_operand" "")])]))
3642 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3643 "TARGET_32BIT
3644 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3645 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3646 [(set (match_dup 8)
3647 (match_op_dup 1
3648 [(ashift:SI (match_dup 2) (match_dup 4))
3649 (match_dup 5)]))
3650 (set (match_dup 0)
3651 (match_op_dup 1
3652 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3653 (match_dup 7)]))]
3654 "
3655 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3656 ")
3657
3658 (define_split
3659 [(set (match_operand:SI 0 "s_register_operand" "")
3660 (match_operator:SI 1 "logical_binary_operator"
3661 [(match_operator:SI 9 "logical_binary_operator"
3662 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3663 (match_operand:SI 6 "const_int_operand" ""))
3664 (match_operand:SI 7 "s_register_operand" "")])
3665 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3666 (match_operand:SI 3 "const_int_operand" "")
3667 (match_operand:SI 4 "const_int_operand" ""))]))
3668 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3669 "TARGET_32BIT
3670 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3671 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3672 [(set (match_dup 8)
3673 (match_op_dup 1
3674 [(ashift:SI (match_dup 2) (match_dup 4))
3675 (match_dup 5)]))
3676 (set (match_dup 0)
3677 (match_op_dup 1
3678 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3679 (match_dup 7)]))]
3680 "
3681 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3682 ")
3683 \f
3684
3685 ;; Minimum and maximum insns
3686
3687 (define_expand "smaxsi3"
3688 [(parallel [
3689 (set (match_operand:SI 0 "s_register_operand" "")
3690 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3691 (match_operand:SI 2 "arm_rhs_operand" "")))
3692 (clobber (reg:CC CC_REGNUM))])]
3693 "TARGET_32BIT"
3694 "
3695 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3696 {
3697 /* No need for a clobber of the condition code register here. */
3698 emit_insn (gen_rtx_SET (operands[0],
3699 gen_rtx_SMAX (SImode, operands[1],
3700 operands[2])));
3701 DONE;
3702 }
3703 ")
3704
3705 (define_insn "*smax_0"
3706 [(set (match_operand:SI 0 "s_register_operand" "=r")
3707 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3708 (const_int 0)))]
3709 "TARGET_32BIT"
3710 "bic%?\\t%0, %1, %1, asr #31"
3711 [(set_attr "predicable" "yes")
3712 (set_attr "type" "logic_shift_reg")]
3713 )
3714
3715 (define_insn "*smax_m1"
3716 [(set (match_operand:SI 0 "s_register_operand" "=r")
3717 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3718 (const_int -1)))]
3719 "TARGET_32BIT"
3720 "orr%?\\t%0, %1, %1, asr #31"
3721 [(set_attr "predicable" "yes")
3722 (set_attr "type" "logic_shift_reg")]
3723 )
3724
3725 (define_insn_and_split "*arm_smax_insn"
3726 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3727 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3728 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3729 (clobber (reg:CC CC_REGNUM))]
3730 "TARGET_ARM"
3731 "#"
3732 ; cmp\\t%1, %2\;movlt\\t%0, %2
3733 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3734 "TARGET_ARM"
3735 [(set (reg:CC CC_REGNUM)
3736 (compare:CC (match_dup 1) (match_dup 2)))
3737 (set (match_dup 0)
3738 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3739 (match_dup 1)
3740 (match_dup 2)))]
3741 ""
3742 [(set_attr "conds" "clob")
3743 (set_attr "length" "8,12")
3744 (set_attr "type" "multiple")]
3745 )
3746
3747 (define_expand "sminsi3"
3748 [(parallel [
3749 (set (match_operand:SI 0 "s_register_operand" "")
3750 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3751 (match_operand:SI 2 "arm_rhs_operand" "")))
3752 (clobber (reg:CC CC_REGNUM))])]
3753 "TARGET_32BIT"
3754 "
3755 if (operands[2] == const0_rtx)
3756 {
3757 /* No need for a clobber of the condition code register here. */
3758 emit_insn (gen_rtx_SET (operands[0],
3759 gen_rtx_SMIN (SImode, operands[1],
3760 operands[2])));
3761 DONE;
3762 }
3763 ")
3764
3765 (define_insn "*smin_0"
3766 [(set (match_operand:SI 0 "s_register_operand" "=r")
3767 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3768 (const_int 0)))]
3769 "TARGET_32BIT"
3770 "and%?\\t%0, %1, %1, asr #31"
3771 [(set_attr "predicable" "yes")
3772 (set_attr "type" "logic_shift_reg")]
3773 )
3774
3775 (define_insn_and_split "*arm_smin_insn"
3776 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3777 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3778 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3779 (clobber (reg:CC CC_REGNUM))]
3780 "TARGET_ARM"
3781 "#"
3782 ; cmp\\t%1, %2\;movge\\t%0, %2
3783 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3784 "TARGET_ARM"
3785 [(set (reg:CC CC_REGNUM)
3786 (compare:CC (match_dup 1) (match_dup 2)))
3787 (set (match_dup 0)
3788 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3789 (match_dup 1)
3790 (match_dup 2)))]
3791 ""
3792 [(set_attr "conds" "clob")
3793 (set_attr "length" "8,12")
3794 (set_attr "type" "multiple,multiple")]
3795 )
3796
3797 (define_expand "umaxsi3"
3798 [(parallel [
3799 (set (match_operand:SI 0 "s_register_operand" "")
3800 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3801 (match_operand:SI 2 "arm_rhs_operand" "")))
3802 (clobber (reg:CC CC_REGNUM))])]
3803 "TARGET_32BIT"
3804 ""
3805 )
3806
3807 (define_insn_and_split "*arm_umaxsi3"
3808 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3809 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3810 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3811 (clobber (reg:CC CC_REGNUM))]
3812 "TARGET_ARM"
3813 "#"
3814 ; cmp\\t%1, %2\;movcc\\t%0, %2
3815 ; cmp\\t%1, %2\;movcs\\t%0, %1
3816 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3817 "TARGET_ARM"
3818 [(set (reg:CC CC_REGNUM)
3819 (compare:CC (match_dup 1) (match_dup 2)))
3820 (set (match_dup 0)
3821 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3822 (match_dup 1)
3823 (match_dup 2)))]
3824 ""
3825 [(set_attr "conds" "clob")
3826 (set_attr "length" "8,8,12")
3827 (set_attr "type" "store_4")]
3828 )
3829
3830 (define_expand "uminsi3"
3831 [(parallel [
3832 (set (match_operand:SI 0 "s_register_operand" "")
3833 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3834 (match_operand:SI 2 "arm_rhs_operand" "")))
3835 (clobber (reg:CC CC_REGNUM))])]
3836 "TARGET_32BIT"
3837 ""
3838 )
3839
3840 (define_insn_and_split "*arm_uminsi3"
3841 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3842 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3843 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3844 (clobber (reg:CC CC_REGNUM))]
3845 "TARGET_ARM"
3846 "#"
3847 ; cmp\\t%1, %2\;movcs\\t%0, %2
3848 ; cmp\\t%1, %2\;movcc\\t%0, %1
3849 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3850 "TARGET_ARM"
3851 [(set (reg:CC CC_REGNUM)
3852 (compare:CC (match_dup 1) (match_dup 2)))
3853 (set (match_dup 0)
3854 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3855 (match_dup 1)
3856 (match_dup 2)))]
3857 ""
3858 [(set_attr "conds" "clob")
3859 (set_attr "length" "8,8,12")
3860 (set_attr "type" "store_4")]
3861 )
3862
3863 (define_insn "*store_minmaxsi"
3864 [(set (match_operand:SI 0 "memory_operand" "=m")
3865 (match_operator:SI 3 "minmax_operator"
3866 [(match_operand:SI 1 "s_register_operand" "r")
3867 (match_operand:SI 2 "s_register_operand" "r")]))
3868 (clobber (reg:CC CC_REGNUM))]
3869 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3870 "*
3871 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3872 operands[1], operands[2]);
3873 output_asm_insn (\"cmp\\t%1, %2\", operands);
3874 if (TARGET_THUMB2)
3875 output_asm_insn (\"ite\t%d3\", operands);
3876 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3877 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3878 return \"\";
3879 "
3880 [(set_attr "conds" "clob")
3881 (set (attr "length")
3882 (if_then_else (eq_attr "is_thumb" "yes")
3883 (const_int 14)
3884 (const_int 12)))
3885 (set_attr "type" "store_4")]
3886 )
3887
3888 ; Reject the frame pointer in operand[1], since reloading this after
3889 ; it has been eliminated can cause carnage.
3890 (define_insn "*minmax_arithsi"
3891 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3892 (match_operator:SI 4 "shiftable_operator"
3893 [(match_operator:SI 5 "minmax_operator"
3894 [(match_operand:SI 2 "s_register_operand" "r,r")
3895 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3896 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3897 (clobber (reg:CC CC_REGNUM))]
3898 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3899 "*
3900 {
3901 enum rtx_code code = GET_CODE (operands[4]);
3902 bool need_else;
3903
3904 if (which_alternative != 0 || operands[3] != const0_rtx
3905 || (code != PLUS && code != IOR && code != XOR))
3906 need_else = true;
3907 else
3908 need_else = false;
3909
3910 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3911 operands[2], operands[3]);
3912 output_asm_insn (\"cmp\\t%2, %3\", operands);
3913 if (TARGET_THUMB2)
3914 {
3915 if (need_else)
3916 output_asm_insn (\"ite\\t%d5\", operands);
3917 else
3918 output_asm_insn (\"it\\t%d5\", operands);
3919 }
3920 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3921 if (need_else)
3922 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3923 return \"\";
3924 }"
3925 [(set_attr "conds" "clob")
3926 (set (attr "length")
3927 (if_then_else (eq_attr "is_thumb" "yes")
3928 (const_int 14)
3929 (const_int 12)))
3930 (set_attr "type" "multiple")]
3931 )
3932
3933 ; Reject the frame pointer in operand[1], since reloading this after
3934 ; it has been eliminated can cause carnage.
3935 (define_insn_and_split "*minmax_arithsi_non_canon"
3936 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3937 (minus:SI
3938 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3939 (match_operator:SI 4 "minmax_operator"
3940 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3941 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3942 (clobber (reg:CC CC_REGNUM))]
3943 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3944 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3945 "#"
3946 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3947 [(set (reg:CC CC_REGNUM)
3948 (compare:CC (match_dup 2) (match_dup 3)))
3949
3950 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3951 (set (match_dup 0)
3952 (minus:SI (match_dup 1)
3953 (match_dup 2))))
3954 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3955 (set (match_dup 0)
3956 (match_dup 6)))]
3957 {
3958 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3959 operands[2], operands[3]);
3960 enum rtx_code rc = minmax_code (operands[4]);
3961 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3962 operands[2], operands[3]);
3963
3964 if (mode == CCFPmode || mode == CCFPEmode)
3965 rc = reverse_condition_maybe_unordered (rc);
3966 else
3967 rc = reverse_condition (rc);
3968 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3969 if (CONST_INT_P (operands[3]))
3970 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3971 else
3972 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3973 }
3974 [(set_attr "conds" "clob")
3975 (set (attr "length")
3976 (if_then_else (eq_attr "is_thumb" "yes")
3977 (const_int 14)
3978 (const_int 12)))
3979 (set_attr "type" "multiple")]
3980 )
3981
3982 (define_code_iterator SAT [smin smax])
3983 (define_code_iterator SATrev [smin smax])
3984 (define_code_attr SATlo [(smin "1") (smax "2")])
3985 (define_code_attr SAThi [(smin "2") (smax "1")])
3986
3987 (define_insn "*satsi_<SAT:code>"
3988 [(set (match_operand:SI 0 "s_register_operand" "=r")
3989 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3990 (match_operand:SI 1 "const_int_operand" "i"))
3991 (match_operand:SI 2 "const_int_operand" "i")))]
3992 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3993 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3994 {
3995 int mask;
3996 bool signed_sat;
3997 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3998 &mask, &signed_sat))
3999 gcc_unreachable ();
4000
4001 operands[1] = GEN_INT (mask);
4002 if (signed_sat)
4003 return "ssat%?\t%0, %1, %3";
4004 else
4005 return "usat%?\t%0, %1, %3";
4006 }
4007 [(set_attr "predicable" "yes")
4008 (set_attr "type" "alus_imm")]
4009 )
4010
4011 (define_insn "*satsi_<SAT:code>_shift"
4012 [(set (match_operand:SI 0 "s_register_operand" "=r")
4013 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
4014 [(match_operand:SI 4 "s_register_operand" "r")
4015 (match_operand:SI 5 "const_int_operand" "i")])
4016 (match_operand:SI 1 "const_int_operand" "i"))
4017 (match_operand:SI 2 "const_int_operand" "i")))]
4018 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
4019 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
4020 {
4021 int mask;
4022 bool signed_sat;
4023 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
4024 &mask, &signed_sat))
4025 gcc_unreachable ();
4026
4027 operands[1] = GEN_INT (mask);
4028 if (signed_sat)
4029 return "ssat%?\t%0, %1, %4%S3";
4030 else
4031 return "usat%?\t%0, %1, %4%S3";
4032 }
4033 [(set_attr "predicable" "yes")
4034 (set_attr "shift" "3")
4035 (set_attr "type" "logic_shift_reg")])
4036 \f
4037 ;; Shift and rotation insns
4038
4039 (define_expand "ashldi3"
4040 [(set (match_operand:DI 0 "s_register_operand" "")
4041 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
4042 (match_operand:SI 2 "general_operand" "")))]
4043 "TARGET_32BIT"
4044 "
4045 if (TARGET_NEON)
4046 {
4047 /* Delay the decision whether to use NEON or core-regs until
4048 register allocation. */
4049 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4050 DONE;
4051 }
4052 else
4053 {
4054 /* Only the NEON case can handle in-memory shift counts. */
4055 if (!reg_or_int_operand (operands[2], SImode))
4056 operands[2] = force_reg (SImode, operands[2]);
4057 }
4058
4059 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4060 ; /* No special preparation statements; expand pattern as above. */
4061 else
4062 {
4063 rtx scratch1, scratch2;
4064
4065 /* Ideally we should use iwmmxt here if we could know that operands[1]
4066 ends up already living in an iwmmxt register. Otherwise it's
4067 cheaper to have the alternate code being generated than moving
4068 values to iwmmxt regs and back. */
4069
4070 /* Expand operation using core-registers.
4071 'FAIL' would achieve the same thing, but this is a bit smarter. */
4072 scratch1 = gen_reg_rtx (SImode);
4073 scratch2 = gen_reg_rtx (SImode);
4074 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4075 operands[2], scratch1, scratch2);
4076 DONE;
4077 }
4078 "
4079 )
4080
4081 (define_expand "ashlsi3"
4082 [(set (match_operand:SI 0 "s_register_operand" "")
4083 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4084 (match_operand:SI 2 "arm_rhs_operand" "")))]
4085 "TARGET_EITHER"
4086 "
4087 if (CONST_INT_P (operands[2])
4088 && (UINTVAL (operands[2])) > 31)
4089 {
4090 emit_insn (gen_movsi (operands[0], const0_rtx));
4091 DONE;
4092 }
4093 "
4094 )
4095
4096 (define_expand "ashrdi3"
4097 [(set (match_operand:DI 0 "s_register_operand" "")
4098 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4099 (match_operand:SI 2 "reg_or_int_operand" "")))]
4100 "TARGET_32BIT"
4101 "
4102 if (TARGET_NEON)
4103 {
4104 /* Delay the decision whether to use NEON or core-regs until
4105 register allocation. */
4106 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4107 DONE;
4108 }
4109
4110 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4111 ; /* No special preparation statements; expand pattern as above. */
4112 else
4113 {
4114 rtx scratch1, scratch2;
4115
4116 /* Ideally we should use iwmmxt here if we could know that operands[1]
4117 ends up already living in an iwmmxt register. Otherwise it's
4118 cheaper to have the alternate code being generated than moving
4119 values to iwmmxt regs and back. */
4120
4121 /* Expand operation using core-registers.
4122 'FAIL' would achieve the same thing, but this is a bit smarter. */
4123 scratch1 = gen_reg_rtx (SImode);
4124 scratch2 = gen_reg_rtx (SImode);
4125 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4126 operands[2], scratch1, scratch2);
4127 DONE;
4128 }
4129 "
4130 )
4131
4132 (define_expand "ashrsi3"
4133 [(set (match_operand:SI 0 "s_register_operand" "")
4134 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4135 (match_operand:SI 2 "arm_rhs_operand" "")))]
4136 "TARGET_EITHER"
4137 "
4138 if (CONST_INT_P (operands[2])
4139 && UINTVAL (operands[2]) > 31)
4140 operands[2] = GEN_INT (31);
4141 "
4142 )
4143
4144 (define_expand "lshrdi3"
4145 [(set (match_operand:DI 0 "s_register_operand" "")
4146 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4147 (match_operand:SI 2 "reg_or_int_operand" "")))]
4148 "TARGET_32BIT"
4149 "
4150 if (TARGET_NEON)
4151 {
4152 /* Delay the decision whether to use NEON or core-regs until
4153 register allocation. */
4154 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4155 DONE;
4156 }
4157
4158 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4159 ; /* No special preparation statements; expand pattern as above. */
4160 else
4161 {
4162 rtx scratch1, scratch2;
4163
4164 /* Ideally we should use iwmmxt here if we could know that operands[1]
4165 ends up already living in an iwmmxt register. Otherwise it's
4166 cheaper to have the alternate code being generated than moving
4167 values to iwmmxt regs and back. */
4168
4169 /* Expand operation using core-registers.
4170 'FAIL' would achieve the same thing, but this is a bit smarter. */
4171 scratch1 = gen_reg_rtx (SImode);
4172 scratch2 = gen_reg_rtx (SImode);
4173 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4174 operands[2], scratch1, scratch2);
4175 DONE;
4176 }
4177 "
4178 )
4179
4180 (define_expand "lshrsi3"
4181 [(set (match_operand:SI 0 "s_register_operand" "")
4182 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4183 (match_operand:SI 2 "arm_rhs_operand" "")))]
4184 "TARGET_EITHER"
4185 "
4186 if (CONST_INT_P (operands[2])
4187 && (UINTVAL (operands[2])) > 31)
4188 {
4189 emit_insn (gen_movsi (operands[0], const0_rtx));
4190 DONE;
4191 }
4192 "
4193 )
4194
4195 (define_expand "rotlsi3"
4196 [(set (match_operand:SI 0 "s_register_operand" "")
4197 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4198 (match_operand:SI 2 "reg_or_int_operand" "")))]
4199 "TARGET_32BIT"
4200 "
4201 if (CONST_INT_P (operands[2]))
4202 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4203 else
4204 {
4205 rtx reg = gen_reg_rtx (SImode);
4206 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4207 operands[2] = reg;
4208 }
4209 "
4210 )
4211
4212 (define_expand "rotrsi3"
4213 [(set (match_operand:SI 0 "s_register_operand" "")
4214 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4215 (match_operand:SI 2 "arm_rhs_operand" "")))]
4216 "TARGET_EITHER"
4217 "
4218 if (TARGET_32BIT)
4219 {
4220 if (CONST_INT_P (operands[2])
4221 && UINTVAL (operands[2]) > 31)
4222 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4223 }
4224 else /* TARGET_THUMB1 */
4225 {
4226 if (CONST_INT_P (operands [2]))
4227 operands [2] = force_reg (SImode, operands[2]);
4228 }
4229 "
4230 )
4231
4232 (define_insn "*arm_shiftsi3"
4233 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4234 (match_operator:SI 3 "shift_operator"
4235 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4236 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4237 "TARGET_32BIT"
4238 "* return arm_output_shift(operands, 0);"
4239 [(set_attr "predicable" "yes")
4240 (set_attr "arch" "t2,t2,*,*")
4241 (set_attr "predicable_short_it" "yes,yes,no,no")
4242 (set_attr "length" "4")
4243 (set_attr "shift" "1")
4244 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4245 )
4246
4247 (define_insn "*shiftsi3_compare0"
4248 [(set (reg:CC_NOOV CC_REGNUM)
4249 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4250 [(match_operand:SI 1 "s_register_operand" "r,r")
4251 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4252 (const_int 0)))
4253 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4254 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4255 "TARGET_32BIT"
4256 "* return arm_output_shift(operands, 1);"
4257 [(set_attr "conds" "set")
4258 (set_attr "shift" "1")
4259 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4260 )
4261
4262 (define_insn "*shiftsi3_compare0_scratch"
4263 [(set (reg:CC_NOOV CC_REGNUM)
4264 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4265 [(match_operand:SI 1 "s_register_operand" "r,r")
4266 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4267 (const_int 0)))
4268 (clobber (match_scratch:SI 0 "=r,r"))]
4269 "TARGET_32BIT"
4270 "* return arm_output_shift(operands, 1);"
4271 [(set_attr "conds" "set")
4272 (set_attr "shift" "1")
4273 (set_attr "type" "shift_imm,shift_reg")]
4274 )
4275
4276 (define_insn "*not_shiftsi"
4277 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
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 "TARGET_32BIT"
4282 "mvn%?\\t%0, %1%S3"
4283 [(set_attr "predicable" "yes")
4284 (set_attr "shift" "1")
4285 (set_attr "arch" "32,a")
4286 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4287
4288 (define_insn "*not_shiftsi_compare0"
4289 [(set (reg:CC_NOOV CC_REGNUM)
4290 (compare:CC_NOOV
4291 (not:SI (match_operator:SI 3 "shift_operator"
4292 [(match_operand:SI 1 "s_register_operand" "r,r")
4293 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4294 (const_int 0)))
4295 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4296 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4297 "TARGET_32BIT"
4298 "mvns%?\\t%0, %1%S3"
4299 [(set_attr "conds" "set")
4300 (set_attr "shift" "1")
4301 (set_attr "arch" "32,a")
4302 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4303
4304 (define_insn "*not_shiftsi_compare0_scratch"
4305 [(set (reg:CC_NOOV CC_REGNUM)
4306 (compare:CC_NOOV
4307 (not:SI (match_operator:SI 3 "shift_operator"
4308 [(match_operand:SI 1 "s_register_operand" "r,r")
4309 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4310 (const_int 0)))
4311 (clobber (match_scratch:SI 0 "=r,r"))]
4312 "TARGET_32BIT"
4313 "mvns%?\\t%0, %1%S3"
4314 [(set_attr "conds" "set")
4315 (set_attr "shift" "1")
4316 (set_attr "arch" "32,a")
4317 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4318
4319 ;; We don't really have extzv, but defining this using shifts helps
4320 ;; to reduce register pressure later on.
4321
4322 (define_expand "extzv"
4323 [(set (match_operand 0 "s_register_operand" "")
4324 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4325 (match_operand 2 "const_int_operand" "")
4326 (match_operand 3 "const_int_operand" "")))]
4327 "TARGET_THUMB1 || arm_arch_thumb2"
4328 "
4329 {
4330 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4331 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4332
4333 if (arm_arch_thumb2)
4334 {
4335 HOST_WIDE_INT width = INTVAL (operands[2]);
4336 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4337
4338 if (unaligned_access && MEM_P (operands[1])
4339 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4340 {
4341 rtx base_addr;
4342
4343 if (BYTES_BIG_ENDIAN)
4344 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4345 - bitpos;
4346
4347 if (width == 32)
4348 {
4349 base_addr = adjust_address (operands[1], SImode,
4350 bitpos / BITS_PER_UNIT);
4351 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4352 }
4353 else
4354 {
4355 rtx dest = operands[0];
4356 rtx tmp = gen_reg_rtx (SImode);
4357
4358 /* We may get a paradoxical subreg here. Strip it off. */
4359 if (GET_CODE (dest) == SUBREG
4360 && GET_MODE (dest) == SImode
4361 && GET_MODE (SUBREG_REG (dest)) == HImode)
4362 dest = SUBREG_REG (dest);
4363
4364 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4365 FAIL;
4366
4367 base_addr = adjust_address (operands[1], HImode,
4368 bitpos / BITS_PER_UNIT);
4369 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4370 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4371 }
4372 DONE;
4373 }
4374 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4375 {
4376 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4377 operands[3]));
4378 DONE;
4379 }
4380 else
4381 FAIL;
4382 }
4383
4384 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4385 FAIL;
4386
4387 operands[3] = GEN_INT (rshift);
4388
4389 if (lshift == 0)
4390 {
4391 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4392 DONE;
4393 }
4394
4395 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4396 operands[3], gen_reg_rtx (SImode)));
4397 DONE;
4398 }"
4399 )
4400
4401 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4402
4403 (define_expand "extzv_t1"
4404 [(set (match_operand:SI 4 "s_register_operand" "")
4405 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4406 (match_operand:SI 2 "const_int_operand" "")))
4407 (set (match_operand:SI 0 "s_register_operand" "")
4408 (lshiftrt:SI (match_dup 4)
4409 (match_operand:SI 3 "const_int_operand" "")))]
4410 "TARGET_THUMB1"
4411 "")
4412
4413 (define_expand "extv"
4414 [(set (match_operand 0 "s_register_operand" "")
4415 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4416 (match_operand 2 "const_int_operand" "")
4417 (match_operand 3 "const_int_operand" "")))]
4418 "arm_arch_thumb2"
4419 {
4420 HOST_WIDE_INT width = INTVAL (operands[2]);
4421 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4422
4423 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4424 && (bitpos % BITS_PER_UNIT) == 0)
4425 {
4426 rtx base_addr;
4427
4428 if (BYTES_BIG_ENDIAN)
4429 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4430
4431 if (width == 32)
4432 {
4433 base_addr = adjust_address (operands[1], SImode,
4434 bitpos / BITS_PER_UNIT);
4435 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4436 }
4437 else
4438 {
4439 rtx dest = operands[0];
4440 rtx tmp = gen_reg_rtx (SImode);
4441
4442 /* We may get a paradoxical subreg here. Strip it off. */
4443 if (GET_CODE (dest) == SUBREG
4444 && GET_MODE (dest) == SImode
4445 && GET_MODE (SUBREG_REG (dest)) == HImode)
4446 dest = SUBREG_REG (dest);
4447
4448 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4449 FAIL;
4450
4451 base_addr = adjust_address (operands[1], HImode,
4452 bitpos / BITS_PER_UNIT);
4453 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4454 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4455 }
4456
4457 DONE;
4458 }
4459 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4460 FAIL;
4461 else if (GET_MODE (operands[0]) == SImode
4462 && GET_MODE (operands[1]) == SImode)
4463 {
4464 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4465 operands[3]));
4466 DONE;
4467 }
4468
4469 FAIL;
4470 })
4471
4472 ; Helper to expand register forms of extv with the proper modes.
4473
4474 (define_expand "extv_regsi"
4475 [(set (match_operand:SI 0 "s_register_operand" "")
4476 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4477 (match_operand 2 "const_int_operand" "")
4478 (match_operand 3 "const_int_operand" "")))]
4479 ""
4480 {
4481 })
4482
4483 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4484
4485 (define_insn "unaligned_loadsi"
4486 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4487 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4488 UNSPEC_UNALIGNED_LOAD))]
4489 "unaligned_access"
4490 "ldr%?\t%0, %1\t@ unaligned"
4491 [(set_attr "arch" "t2,any")
4492 (set_attr "length" "2,4")
4493 (set_attr "predicable" "yes")
4494 (set_attr "predicable_short_it" "yes,no")
4495 (set_attr "type" "load_4")])
4496
4497 (define_insn "unaligned_loadhis"
4498 [(set (match_operand:SI 0 "s_register_operand" "=r")
4499 (sign_extend:SI
4500 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
4501 UNSPEC_UNALIGNED_LOAD)))]
4502 "unaligned_access"
4503 "ldrsh%?\t%0, %1\t@ unaligned"
4504 [(set_attr "predicable" "yes")
4505 (set_attr "type" "load_byte")])
4506
4507 (define_insn "unaligned_loadhiu"
4508 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4509 (zero_extend:SI
4510 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4511 UNSPEC_UNALIGNED_LOAD)))]
4512 "unaligned_access"
4513 "ldrh%?\t%0, %1\t@ unaligned"
4514 [(set_attr "arch" "t2,any")
4515 (set_attr "length" "2,4")
4516 (set_attr "predicable" "yes")
4517 (set_attr "predicable_short_it" "yes,no")
4518 (set_attr "type" "load_byte")])
4519
4520 (define_insn "unaligned_storesi"
4521 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4522 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4523 UNSPEC_UNALIGNED_STORE))]
4524 "unaligned_access"
4525 "str%?\t%1, %0\t@ unaligned"
4526 [(set_attr "arch" "t2,any")
4527 (set_attr "length" "2,4")
4528 (set_attr "predicable" "yes")
4529 (set_attr "predicable_short_it" "yes,no")
4530 (set_attr "type" "store_4")])
4531
4532 (define_insn "unaligned_storehi"
4533 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4534 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4535 UNSPEC_UNALIGNED_STORE))]
4536 "unaligned_access"
4537 "strh%?\t%1, %0\t@ unaligned"
4538 [(set_attr "arch" "t2,any")
4539 (set_attr "length" "2,4")
4540 (set_attr "predicable" "yes")
4541 (set_attr "predicable_short_it" "yes,no")
4542 (set_attr "type" "store_4")])
4543
4544
4545 (define_insn "*extv_reg"
4546 [(set (match_operand:SI 0 "s_register_operand" "=r")
4547 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4548 (match_operand:SI 2 "const_int_operand" "n")
4549 (match_operand:SI 3 "const_int_operand" "n")))]
4550 "arm_arch_thumb2
4551 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4552 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4553 "sbfx%?\t%0, %1, %3, %2"
4554 [(set_attr "length" "4")
4555 (set_attr "predicable" "yes")
4556 (set_attr "type" "bfm")]
4557 )
4558
4559 (define_insn "extzv_t2"
4560 [(set (match_operand:SI 0 "s_register_operand" "=r")
4561 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4562 (match_operand:SI 2 "const_int_operand" "n")
4563 (match_operand:SI 3 "const_int_operand" "n")))]
4564 "arm_arch_thumb2
4565 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4566 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4567 "ubfx%?\t%0, %1, %3, %2"
4568 [(set_attr "length" "4")
4569 (set_attr "predicable" "yes")
4570 (set_attr "type" "bfm")]
4571 )
4572
4573
4574 ;; Division instructions
4575 (define_insn "divsi3"
4576 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4577 (div: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 sdiv%?\t%0, %1, %2
4582 sdiv\t%0, %1, %2"
4583 [(set_attr "arch" "32,v8mb")
4584 (set_attr "predicable" "yes")
4585 (set_attr "type" "sdiv")]
4586 )
4587
4588 (define_insn "udivsi3"
4589 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4590 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4591 (match_operand:SI 2 "s_register_operand" "r,r")))]
4592 "TARGET_IDIV"
4593 "@
4594 udiv%?\t%0, %1, %2
4595 udiv\t%0, %1, %2"
4596 [(set_attr "arch" "32,v8mb")
4597 (set_attr "predicable" "yes")
4598 (set_attr "type" "udiv")]
4599 )
4600
4601 \f
4602 ;; Unary arithmetic insns
4603
4604 (define_expand "negvsi3"
4605 [(match_operand:SI 0 "register_operand")
4606 (match_operand:SI 1 "register_operand")
4607 (match_operand 2 "")]
4608 "TARGET_32BIT"
4609 {
4610 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4611 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4612
4613 DONE;
4614 })
4615
4616 (define_expand "negvdi3"
4617 [(match_operand:DI 0 "register_operand")
4618 (match_operand:DI 1 "register_operand")
4619 (match_operand 2 "")]
4620 "TARGET_ARM"
4621 {
4622 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4623 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4624
4625 DONE;
4626 })
4627
4628
4629 (define_insn_and_split "negdi2_compare"
4630 [(set (reg:CC CC_REGNUM)
4631 (compare:CC
4632 (const_int 0)
4633 (match_operand:DI 1 "register_operand" "0,r")))
4634 (set (match_operand:DI 0 "register_operand" "=r,&r")
4635 (minus:DI (const_int 0) (match_dup 1)))]
4636 "TARGET_ARM"
4637 "#"
4638 "&& reload_completed"
4639 [(parallel [(set (reg:CC CC_REGNUM)
4640 (compare:CC (const_int 0) (match_dup 1)))
4641 (set (match_dup 0) (minus:SI (const_int 0)
4642 (match_dup 1)))])
4643 (parallel [(set (reg:CC CC_REGNUM)
4644 (compare:CC (const_int 0) (match_dup 3)))
4645 (set (match_dup 2)
4646 (minus:SI
4647 (minus:SI (const_int 0) (match_dup 3))
4648 (ltu:SI (reg:CC_C CC_REGNUM)
4649 (const_int 0))))])]
4650 {
4651 operands[2] = gen_highpart (SImode, operands[0]);
4652 operands[0] = gen_lowpart (SImode, operands[0]);
4653 operands[3] = gen_highpart (SImode, operands[1]);
4654 operands[1] = gen_lowpart (SImode, operands[1]);
4655 }
4656 [(set_attr "conds" "set")
4657 (set_attr "length" "8")
4658 (set_attr "type" "multiple")]
4659 )
4660
4661 (define_expand "negdi2"
4662 [(parallel
4663 [(set (match_operand:DI 0 "s_register_operand" "")
4664 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4665 (clobber (reg:CC CC_REGNUM))])]
4666 "TARGET_EITHER"
4667 {
4668 if (TARGET_NEON)
4669 {
4670 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4671 DONE;
4672 }
4673 }
4674 )
4675
4676 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4677 ;; The first alternative allows the common case of a *full* overlap.
4678 (define_insn_and_split "*negdi2_insn"
4679 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4680 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4681 (clobber (reg:CC CC_REGNUM))]
4682 "TARGET_32BIT"
4683 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4684 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4685 "&& reload_completed"
4686 [(parallel [(set (reg:CC CC_REGNUM)
4687 (compare:CC (const_int 0) (match_dup 1)))
4688 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4689 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4690 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4691 {
4692 operands[2] = gen_highpart (SImode, operands[0]);
4693 operands[0] = gen_lowpart (SImode, operands[0]);
4694 operands[3] = gen_highpart (SImode, operands[1]);
4695 operands[1] = gen_lowpart (SImode, operands[1]);
4696 }
4697 [(set_attr "conds" "clob")
4698 (set_attr "length" "8")
4699 (set_attr "type" "multiple")]
4700 )
4701
4702 (define_insn "*negsi2_carryin_compare"
4703 [(set (reg:CC CC_REGNUM)
4704 (compare:CC (const_int 0)
4705 (match_operand:SI 1 "s_register_operand" "r")))
4706 (set (match_operand:SI 0 "s_register_operand" "=r")
4707 (minus:SI (minus:SI (const_int 0)
4708 (match_dup 1))
4709 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4710 "TARGET_ARM"
4711 "rscs\\t%0, %1, #0"
4712 [(set_attr "conds" "set")
4713 (set_attr "type" "alus_imm")]
4714 )
4715
4716 (define_expand "negsi2"
4717 [(set (match_operand:SI 0 "s_register_operand" "")
4718 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4719 "TARGET_EITHER"
4720 ""
4721 )
4722
4723 (define_insn "*arm_negsi2"
4724 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4725 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4726 "TARGET_32BIT"
4727 "rsb%?\\t%0, %1, #0"
4728 [(set_attr "predicable" "yes")
4729 (set_attr "predicable_short_it" "yes,no")
4730 (set_attr "arch" "t2,*")
4731 (set_attr "length" "4")
4732 (set_attr "type" "alu_sreg")]
4733 )
4734
4735 (define_expand "negsf2"
4736 [(set (match_operand:SF 0 "s_register_operand" "")
4737 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4738 "TARGET_32BIT && TARGET_HARD_FLOAT"
4739 ""
4740 )
4741
4742 (define_expand "negdf2"
4743 [(set (match_operand:DF 0 "s_register_operand" "")
4744 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4745 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4746 "")
4747
4748 (define_insn_and_split "*zextendsidi_negsi"
4749 [(set (match_operand:DI 0 "s_register_operand" "=r")
4750 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4751 "TARGET_32BIT"
4752 "#"
4753 ""
4754 [(set (match_dup 2)
4755 (neg:SI (match_dup 1)))
4756 (set (match_dup 3)
4757 (const_int 0))]
4758 {
4759 operands[2] = gen_lowpart (SImode, operands[0]);
4760 operands[3] = gen_highpart (SImode, operands[0]);
4761 }
4762 [(set_attr "length" "8")
4763 (set_attr "type" "multiple")]
4764 )
4765
4766 ;; Negate an extended 32-bit value.
4767 (define_insn_and_split "*negdi_extendsidi"
4768 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4769 (neg:DI (sign_extend:DI
4770 (match_operand:SI 1 "s_register_operand" "l,r"))))
4771 (clobber (reg:CC CC_REGNUM))]
4772 "TARGET_32BIT"
4773 "#"
4774 "&& reload_completed"
4775 [(const_int 0)]
4776 {
4777 rtx low = gen_lowpart (SImode, operands[0]);
4778 rtx high = gen_highpart (SImode, operands[0]);
4779
4780 if (reg_overlap_mentioned_p (low, operands[1]))
4781 {
4782 /* Input overlaps the low word of the output. Use:
4783 asr Rhi, Rin, #31
4784 rsbs Rlo, Rin, #0
4785 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4786 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4787
4788 emit_insn (gen_rtx_SET (high,
4789 gen_rtx_ASHIFTRT (SImode, operands[1],
4790 GEN_INT (31))));
4791
4792 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4793 if (TARGET_ARM)
4794 emit_insn (gen_rtx_SET (high,
4795 gen_rtx_MINUS (SImode,
4796 gen_rtx_MINUS (SImode,
4797 const0_rtx,
4798 high),
4799 gen_rtx_LTU (SImode,
4800 cc_reg,
4801 const0_rtx))));
4802 else
4803 {
4804 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4805 emit_insn (gen_rtx_SET (high,
4806 gen_rtx_MINUS (SImode,
4807 gen_rtx_MINUS (SImode,
4808 high,
4809 two_x),
4810 gen_rtx_LTU (SImode,
4811 cc_reg,
4812 const0_rtx))));
4813 }
4814 }
4815 else
4816 {
4817 /* No overlap, or overlap on high word. Use:
4818 rsb Rlo, Rin, #0
4819 bic Rhi, Rlo, Rin
4820 asr Rhi, Rhi, #31
4821 Flags not needed for this sequence. */
4822 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4823 emit_insn (gen_rtx_SET (high,
4824 gen_rtx_AND (SImode,
4825 gen_rtx_NOT (SImode, operands[1]),
4826 low)));
4827 emit_insn (gen_rtx_SET (high,
4828 gen_rtx_ASHIFTRT (SImode, high,
4829 GEN_INT (31))));
4830 }
4831 DONE;
4832 }
4833 [(set_attr "length" "12")
4834 (set_attr "arch" "t2,*")
4835 (set_attr "type" "multiple")]
4836 )
4837
4838 (define_insn_and_split "*negdi_zero_extendsidi"
4839 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4840 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4841 (clobber (reg:CC CC_REGNUM))]
4842 "TARGET_32BIT"
4843 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4844 ;; Don't care what register is input to sbc,
4845 ;; since we just need to propagate the carry.
4846 "&& reload_completed"
4847 [(parallel [(set (reg:CC CC_REGNUM)
4848 (compare:CC (const_int 0) (match_dup 1)))
4849 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4850 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4851 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4852 {
4853 operands[2] = gen_highpart (SImode, operands[0]);
4854 operands[0] = gen_lowpart (SImode, operands[0]);
4855 }
4856 [(set_attr "conds" "clob")
4857 (set_attr "length" "8")
4858 (set_attr "type" "multiple")] ;; length in thumb is 4
4859 )
4860
4861 ;; abssi2 doesn't really clobber the condition codes if a different register
4862 ;; is being set. To keep things simple, assume during rtl manipulations that
4863 ;; it does, but tell the final scan operator the truth. Similarly for
4864 ;; (neg (abs...))
4865
4866 (define_expand "abssi2"
4867 [(parallel
4868 [(set (match_operand:SI 0 "s_register_operand" "")
4869 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4870 (clobber (match_dup 2))])]
4871 "TARGET_EITHER"
4872 "
4873 if (TARGET_THUMB1)
4874 operands[2] = gen_rtx_SCRATCH (SImode);
4875 else
4876 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4877 ")
4878
4879 (define_insn_and_split "*arm_abssi2"
4880 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4881 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4882 (clobber (reg:CC CC_REGNUM))]
4883 "TARGET_ARM"
4884 "#"
4885 "&& reload_completed"
4886 [(const_int 0)]
4887 {
4888 /* if (which_alternative == 0) */
4889 if (REGNO(operands[0]) == REGNO(operands[1]))
4890 {
4891 /* Emit the pattern:
4892 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4893 [(set (reg:CC CC_REGNUM)
4894 (compare:CC (match_dup 0) (const_int 0)))
4895 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4896 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4897 */
4898 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4899 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4900 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4901 (gen_rtx_LT (SImode,
4902 gen_rtx_REG (CCmode, CC_REGNUM),
4903 const0_rtx)),
4904 (gen_rtx_SET (operands[0],
4905 (gen_rtx_MINUS (SImode,
4906 const0_rtx,
4907 operands[1]))))));
4908 DONE;
4909 }
4910 else
4911 {
4912 /* Emit the pattern:
4913 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4914 [(set (match_dup 0)
4915 (xor:SI (match_dup 1)
4916 (ashiftrt:SI (match_dup 1) (const_int 31))))
4917 (set (match_dup 0)
4918 (minus:SI (match_dup 0)
4919 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4920 */
4921 emit_insn (gen_rtx_SET (operands[0],
4922 gen_rtx_XOR (SImode,
4923 gen_rtx_ASHIFTRT (SImode,
4924 operands[1],
4925 GEN_INT (31)),
4926 operands[1])));
4927 emit_insn (gen_rtx_SET (operands[0],
4928 gen_rtx_MINUS (SImode,
4929 operands[0],
4930 gen_rtx_ASHIFTRT (SImode,
4931 operands[1],
4932 GEN_INT (31)))));
4933 DONE;
4934 }
4935 }
4936 [(set_attr "conds" "clob,*")
4937 (set_attr "shift" "1")
4938 (set_attr "predicable" "no, yes")
4939 (set_attr "length" "8")
4940 (set_attr "type" "multiple")]
4941 )
4942
4943 (define_insn_and_split "*arm_neg_abssi2"
4944 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4945 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4946 (clobber (reg:CC CC_REGNUM))]
4947 "TARGET_ARM"
4948 "#"
4949 "&& reload_completed"
4950 [(const_int 0)]
4951 {
4952 /* if (which_alternative == 0) */
4953 if (REGNO (operands[0]) == REGNO (operands[1]))
4954 {
4955 /* Emit the pattern:
4956 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4957 */
4958 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4959 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4960 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4961 gen_rtx_GT (SImode,
4962 gen_rtx_REG (CCmode, CC_REGNUM),
4963 const0_rtx),
4964 gen_rtx_SET (operands[0],
4965 (gen_rtx_MINUS (SImode,
4966 const0_rtx,
4967 operands[1])))));
4968 }
4969 else
4970 {
4971 /* Emit the pattern:
4972 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4973 */
4974 emit_insn (gen_rtx_SET (operands[0],
4975 gen_rtx_XOR (SImode,
4976 gen_rtx_ASHIFTRT (SImode,
4977 operands[1],
4978 GEN_INT (31)),
4979 operands[1])));
4980 emit_insn (gen_rtx_SET (operands[0],
4981 gen_rtx_MINUS (SImode,
4982 gen_rtx_ASHIFTRT (SImode,
4983 operands[1],
4984 GEN_INT (31)),
4985 operands[0])));
4986 }
4987 DONE;
4988 }
4989 [(set_attr "conds" "clob,*")
4990 (set_attr "shift" "1")
4991 (set_attr "predicable" "no, yes")
4992 (set_attr "length" "8")
4993 (set_attr "type" "multiple")]
4994 )
4995
4996 (define_expand "abssf2"
4997 [(set (match_operand:SF 0 "s_register_operand" "")
4998 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
4999 "TARGET_32BIT && TARGET_HARD_FLOAT"
5000 "")
5001
5002 (define_expand "absdf2"
5003 [(set (match_operand:DF 0 "s_register_operand" "")
5004 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5005 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5006 "")
5007
5008 (define_expand "sqrtsf2"
5009 [(set (match_operand:SF 0 "s_register_operand" "")
5010 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5011 "TARGET_32BIT && TARGET_HARD_FLOAT"
5012 "")
5013
5014 (define_expand "sqrtdf2"
5015 [(set (match_operand:DF 0 "s_register_operand" "")
5016 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5017 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5018 "")
5019
5020 (define_expand "one_cmpldi2"
5021 [(set (match_operand:DI 0 "s_register_operand" "")
5022 (not:DI (match_operand:DI 1 "s_register_operand" "")))]
5023 "TARGET_32BIT"
5024 "
5025 if (!TARGET_NEON && !TARGET_IWMMXT)
5026 {
5027 rtx low = simplify_gen_unary (NOT, SImode,
5028 gen_lowpart (SImode, operands[1]),
5029 SImode);
5030 rtx high = simplify_gen_unary (NOT, SImode,
5031 gen_highpart_mode (SImode, DImode,
5032 operands[1]),
5033 SImode);
5034
5035 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5036 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5037
5038 DONE;
5039 }
5040 /* Otherwise expand pattern as above. */
5041 "
5042 )
5043
5044 (define_insn_and_split "*one_cmpldi2_insn"
5045 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5046 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5047 "TARGET_32BIT"
5048 "@
5049 vmvn\t%P0, %P1
5050 #
5051 #
5052 vmvn\t%P0, %P1"
5053 "TARGET_32BIT && reload_completed
5054 && arm_general_register_operand (operands[0], DImode)"
5055 [(set (match_dup 0) (not:SI (match_dup 1)))
5056 (set (match_dup 2) (not:SI (match_dup 3)))]
5057 "
5058 {
5059 operands[2] = gen_highpart (SImode, operands[0]);
5060 operands[0] = gen_lowpart (SImode, operands[0]);
5061 operands[3] = gen_highpart (SImode, operands[1]);
5062 operands[1] = gen_lowpart (SImode, operands[1]);
5063 }"
5064 [(set_attr "length" "*,8,8,*")
5065 (set_attr "predicable" "no,yes,yes,no")
5066 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5067 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5068 )
5069
5070 (define_expand "one_cmplsi2"
5071 [(set (match_operand:SI 0 "s_register_operand" "")
5072 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5073 "TARGET_EITHER"
5074 ""
5075 )
5076
5077 (define_insn "*arm_one_cmplsi2"
5078 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5079 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5080 "TARGET_32BIT"
5081 "mvn%?\\t%0, %1"
5082 [(set_attr "predicable" "yes")
5083 (set_attr "predicable_short_it" "yes,no")
5084 (set_attr "arch" "t2,*")
5085 (set_attr "length" "4")
5086 (set_attr "type" "mvn_reg")]
5087 )
5088
5089 (define_insn "*notsi_compare0"
5090 [(set (reg:CC_NOOV CC_REGNUM)
5091 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5092 (const_int 0)))
5093 (set (match_operand:SI 0 "s_register_operand" "=r")
5094 (not:SI (match_dup 1)))]
5095 "TARGET_32BIT"
5096 "mvns%?\\t%0, %1"
5097 [(set_attr "conds" "set")
5098 (set_attr "type" "mvn_reg")]
5099 )
5100
5101 (define_insn "*notsi_compare0_scratch"
5102 [(set (reg:CC_NOOV CC_REGNUM)
5103 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5104 (const_int 0)))
5105 (clobber (match_scratch:SI 0 "=r"))]
5106 "TARGET_32BIT"
5107 "mvns%?\\t%0, %1"
5108 [(set_attr "conds" "set")
5109 (set_attr "type" "mvn_reg")]
5110 )
5111 \f
5112 ;; Fixed <--> Floating conversion insns
5113
5114 (define_expand "floatsihf2"
5115 [(set (match_operand:HF 0 "general_operand" "")
5116 (float:HF (match_operand:SI 1 "general_operand" "")))]
5117 "TARGET_EITHER"
5118 "
5119 {
5120 rtx op1 = gen_reg_rtx (SFmode);
5121 expand_float (op1, operands[1], 0);
5122 op1 = convert_to_mode (HFmode, op1, 0);
5123 emit_move_insn (operands[0], op1);
5124 DONE;
5125 }"
5126 )
5127
5128 (define_expand "floatdihf2"
5129 [(set (match_operand:HF 0 "general_operand" "")
5130 (float:HF (match_operand:DI 1 "general_operand" "")))]
5131 "TARGET_EITHER"
5132 "
5133 {
5134 rtx op1 = gen_reg_rtx (SFmode);
5135 expand_float (op1, operands[1], 0);
5136 op1 = convert_to_mode (HFmode, op1, 0);
5137 emit_move_insn (operands[0], op1);
5138 DONE;
5139 }"
5140 )
5141
5142 (define_expand "floatsisf2"
5143 [(set (match_operand:SF 0 "s_register_operand" "")
5144 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5145 "TARGET_32BIT && TARGET_HARD_FLOAT"
5146 "
5147 ")
5148
5149 (define_expand "floatsidf2"
5150 [(set (match_operand:DF 0 "s_register_operand" "")
5151 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5152 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5153 "
5154 ")
5155
5156 (define_expand "fix_trunchfsi2"
5157 [(set (match_operand:SI 0 "general_operand" "")
5158 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5159 "TARGET_EITHER"
5160 "
5161 {
5162 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5163 expand_fix (operands[0], op1, 0);
5164 DONE;
5165 }"
5166 )
5167
5168 (define_expand "fix_trunchfdi2"
5169 [(set (match_operand:DI 0 "general_operand" "")
5170 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5171 "TARGET_EITHER"
5172 "
5173 {
5174 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5175 expand_fix (operands[0], op1, 0);
5176 DONE;
5177 }"
5178 )
5179
5180 (define_expand "fix_truncsfsi2"
5181 [(set (match_operand:SI 0 "s_register_operand" "")
5182 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5183 "TARGET_32BIT && TARGET_HARD_FLOAT"
5184 "
5185 ")
5186
5187 (define_expand "fix_truncdfsi2"
5188 [(set (match_operand:SI 0 "s_register_operand" "")
5189 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5190 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5191 "
5192 ")
5193
5194 ;; Truncation insns
5195
5196 (define_expand "truncdfsf2"
5197 [(set (match_operand:SF 0 "s_register_operand" "")
5198 (float_truncate:SF
5199 (match_operand:DF 1 "s_register_operand" "")))]
5200 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5201 ""
5202 )
5203
5204 ;; DFmode to HFmode conversions on targets without a single-step hardware
5205 ;; instruction for it would have to go through SFmode. This is dangerous
5206 ;; as it introduces double rounding.
5207 ;;
5208 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5209 ;; a single-step instruction.
5210
5211 (define_expand "truncdfhf2"
5212 [(set (match_operand:HF 0 "s_register_operand" "")
5213 (float_truncate:HF
5214 (match_operand:DF 1 "s_register_operand" "")))]
5215 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5216 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5217 {
5218 /* We don't have a direct instruction for this, so we must be in
5219 an unsafe math mode, and going via SFmode. */
5220
5221 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5222 {
5223 rtx op1;
5224 op1 = convert_to_mode (SFmode, operands[1], 0);
5225 op1 = convert_to_mode (HFmode, op1, 0);
5226 emit_move_insn (operands[0], op1);
5227 DONE;
5228 }
5229 /* Otherwise, we will pick this up as a single instruction with
5230 no intermediary rounding. */
5231 }
5232 )
5233 \f
5234 ;; Zero and sign extension instructions.
5235
5236 (define_insn "zero_extend<mode>di2"
5237 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5238 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5239 "<qhs_zextenddi_cstr>")))]
5240 "TARGET_32BIT <qhs_zextenddi_cond>"
5241 "#"
5242 [(set_attr "length" "8,4,8,8")
5243 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5244 (set_attr "ce_count" "2")
5245 (set_attr "predicable" "yes")
5246 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5247 )
5248
5249 (define_insn "extend<mode>di2"
5250 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5251 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5252 "<qhs_extenddi_cstr>")))]
5253 "TARGET_32BIT <qhs_sextenddi_cond>"
5254 "#"
5255 [(set_attr "length" "8,4,8,8,8")
5256 (set_attr "ce_count" "2")
5257 (set_attr "shift" "1")
5258 (set_attr "predicable" "yes")
5259 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5260 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5261 )
5262
5263 ;; Splits for all extensions to DImode
5264 (define_split
5265 [(set (match_operand:DI 0 "s_register_operand" "")
5266 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5267 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5268 [(set (match_dup 0) (match_dup 1))]
5269 {
5270 rtx lo_part = gen_lowpart (SImode, operands[0]);
5271 machine_mode src_mode = GET_MODE (operands[1]);
5272
5273 if (REG_P (operands[0])
5274 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5275 emit_clobber (operands[0]);
5276 if (!REG_P (lo_part) || src_mode != SImode
5277 || !rtx_equal_p (lo_part, operands[1]))
5278 {
5279 if (src_mode == SImode)
5280 emit_move_insn (lo_part, operands[1]);
5281 else
5282 emit_insn (gen_rtx_SET (lo_part,
5283 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5284 operands[1] = lo_part;
5285 }
5286 operands[0] = gen_highpart (SImode, operands[0]);
5287 operands[1] = const0_rtx;
5288 })
5289
5290 (define_split
5291 [(set (match_operand:DI 0 "s_register_operand" "")
5292 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5293 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5294 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5295 {
5296 rtx lo_part = gen_lowpart (SImode, operands[0]);
5297 machine_mode src_mode = GET_MODE (operands[1]);
5298
5299 if (REG_P (operands[0])
5300 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5301 emit_clobber (operands[0]);
5302
5303 if (!REG_P (lo_part) || src_mode != SImode
5304 || !rtx_equal_p (lo_part, operands[1]))
5305 {
5306 if (src_mode == SImode)
5307 emit_move_insn (lo_part, operands[1]);
5308 else
5309 emit_insn (gen_rtx_SET (lo_part,
5310 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5311 operands[1] = lo_part;
5312 }
5313 operands[0] = gen_highpart (SImode, operands[0]);
5314 })
5315
5316 (define_expand "zero_extendhisi2"
5317 [(set (match_operand:SI 0 "s_register_operand" "")
5318 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5319 "TARGET_EITHER"
5320 {
5321 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5322 {
5323 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5324 DONE;
5325 }
5326 if (!arm_arch6 && !MEM_P (operands[1]))
5327 {
5328 rtx t = gen_lowpart (SImode, operands[1]);
5329 rtx tmp = gen_reg_rtx (SImode);
5330 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5331 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5332 DONE;
5333 }
5334 })
5335
5336 (define_split
5337 [(set (match_operand:SI 0 "s_register_operand" "")
5338 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5339 "!TARGET_THUMB2 && !arm_arch6"
5340 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5341 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5342 {
5343 operands[2] = gen_lowpart (SImode, operands[1]);
5344 })
5345
5346 (define_insn "*arm_zero_extendhisi2"
5347 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5348 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5349 "TARGET_ARM && arm_arch4 && !arm_arch6"
5350 "@
5351 #
5352 ldrh%?\\t%0, %1"
5353 [(set_attr "type" "alu_shift_reg,load_byte")
5354 (set_attr "predicable" "yes")]
5355 )
5356
5357 (define_insn "*arm_zero_extendhisi2_v6"
5358 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5359 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5360 "TARGET_ARM && arm_arch6"
5361 "@
5362 uxth%?\\t%0, %1
5363 ldrh%?\\t%0, %1"
5364 [(set_attr "predicable" "yes")
5365 (set_attr "type" "extend,load_byte")]
5366 )
5367
5368 (define_insn "*arm_zero_extendhisi2addsi"
5369 [(set (match_operand:SI 0 "s_register_operand" "=r")
5370 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5371 (match_operand:SI 2 "s_register_operand" "r")))]
5372 "TARGET_INT_SIMD"
5373 "uxtah%?\\t%0, %2, %1"
5374 [(set_attr "type" "alu_shift_reg")
5375 (set_attr "predicable" "yes")]
5376 )
5377
5378 (define_expand "zero_extendqisi2"
5379 [(set (match_operand:SI 0 "s_register_operand" "")
5380 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5381 "TARGET_EITHER"
5382 {
5383 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5384 {
5385 emit_insn (gen_andsi3 (operands[0],
5386 gen_lowpart (SImode, operands[1]),
5387 GEN_INT (255)));
5388 DONE;
5389 }
5390 if (!arm_arch6 && !MEM_P (operands[1]))
5391 {
5392 rtx t = gen_lowpart (SImode, operands[1]);
5393 rtx tmp = gen_reg_rtx (SImode);
5394 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5395 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5396 DONE;
5397 }
5398 })
5399
5400 (define_split
5401 [(set (match_operand:SI 0 "s_register_operand" "")
5402 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5403 "!arm_arch6"
5404 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5405 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5406 {
5407 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5408 if (TARGET_ARM)
5409 {
5410 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5411 DONE;
5412 }
5413 })
5414
5415 (define_insn "*arm_zero_extendqisi2"
5416 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5417 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5418 "TARGET_ARM && !arm_arch6"
5419 "@
5420 #
5421 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5422 [(set_attr "length" "8,4")
5423 (set_attr "type" "alu_shift_reg,load_byte")
5424 (set_attr "predicable" "yes")]
5425 )
5426
5427 (define_insn "*arm_zero_extendqisi2_v6"
5428 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5429 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5430 "TARGET_ARM && arm_arch6"
5431 "@
5432 uxtb%?\\t%0, %1
5433 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5434 [(set_attr "type" "extend,load_byte")
5435 (set_attr "predicable" "yes")]
5436 )
5437
5438 (define_insn "*arm_zero_extendqisi2addsi"
5439 [(set (match_operand:SI 0 "s_register_operand" "=r")
5440 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5441 (match_operand:SI 2 "s_register_operand" "r")))]
5442 "TARGET_INT_SIMD"
5443 "uxtab%?\\t%0, %2, %1"
5444 [(set_attr "predicable" "yes")
5445 (set_attr "type" "alu_shift_reg")]
5446 )
5447
5448 (define_split
5449 [(set (match_operand:SI 0 "s_register_operand" "")
5450 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5451 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5452 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5453 [(set (match_dup 2) (match_dup 1))
5454 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5455 ""
5456 )
5457
5458 (define_split
5459 [(set (match_operand:SI 0 "s_register_operand" "")
5460 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5461 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5462 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5463 [(set (match_dup 2) (match_dup 1))
5464 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5465 ""
5466 )
5467
5468
5469 (define_split
5470 [(set (match_operand:SI 0 "s_register_operand" "")
5471 (IOR_XOR:SI (and:SI (ashift:SI
5472 (match_operand:SI 1 "s_register_operand" "")
5473 (match_operand:SI 2 "const_int_operand" ""))
5474 (match_operand:SI 3 "const_int_operand" ""))
5475 (zero_extend:SI
5476 (match_operator 5 "subreg_lowpart_operator"
5477 [(match_operand:SI 4 "s_register_operand" "")]))))]
5478 "TARGET_32BIT
5479 && (UINTVAL (operands[3])
5480 == (GET_MODE_MASK (GET_MODE (operands[5]))
5481 & (GET_MODE_MASK (GET_MODE (operands[5]))
5482 << (INTVAL (operands[2])))))"
5483 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5484 (match_dup 4)))
5485 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5486 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5487 )
5488
5489 (define_insn "*compareqi_eq0"
5490 [(set (reg:CC_Z CC_REGNUM)
5491 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5492 (const_int 0)))]
5493 "TARGET_32BIT"
5494 "tst%?\\t%0, #255"
5495 [(set_attr "conds" "set")
5496 (set_attr "predicable" "yes")
5497 (set_attr "type" "logic_imm")]
5498 )
5499
5500 (define_expand "extendhisi2"
5501 [(set (match_operand:SI 0 "s_register_operand" "")
5502 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5503 "TARGET_EITHER"
5504 {
5505 if (TARGET_THUMB1)
5506 {
5507 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5508 DONE;
5509 }
5510 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5511 {
5512 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5513 DONE;
5514 }
5515
5516 if (!arm_arch6 && !MEM_P (operands[1]))
5517 {
5518 rtx t = gen_lowpart (SImode, operands[1]);
5519 rtx tmp = gen_reg_rtx (SImode);
5520 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5521 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5522 DONE;
5523 }
5524 })
5525
5526 (define_split
5527 [(parallel
5528 [(set (match_operand:SI 0 "register_operand" "")
5529 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5530 (clobber (match_scratch:SI 2 ""))])]
5531 "!arm_arch6"
5532 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5533 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5534 {
5535 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5536 })
5537
5538 ;; This pattern will only be used when ldsh is not available
5539 (define_expand "extendhisi2_mem"
5540 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5541 (set (match_dup 3)
5542 (zero_extend:SI (match_dup 7)))
5543 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5544 (set (match_operand:SI 0 "" "")
5545 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5546 "TARGET_ARM"
5547 "
5548 {
5549 rtx mem1, mem2;
5550 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5551
5552 mem1 = change_address (operands[1], QImode, addr);
5553 mem2 = change_address (operands[1], QImode,
5554 plus_constant (Pmode, addr, 1));
5555 operands[0] = gen_lowpart (SImode, operands[0]);
5556 operands[1] = mem1;
5557 operands[2] = gen_reg_rtx (SImode);
5558 operands[3] = gen_reg_rtx (SImode);
5559 operands[6] = gen_reg_rtx (SImode);
5560 operands[7] = mem2;
5561
5562 if (BYTES_BIG_ENDIAN)
5563 {
5564 operands[4] = operands[2];
5565 operands[5] = operands[3];
5566 }
5567 else
5568 {
5569 operands[4] = operands[3];
5570 operands[5] = operands[2];
5571 }
5572 }"
5573 )
5574
5575 (define_split
5576 [(set (match_operand:SI 0 "register_operand" "")
5577 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5578 "!arm_arch6"
5579 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5580 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5581 {
5582 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5583 })
5584
5585 (define_insn "*arm_extendhisi2"
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_ARM && arm_arch4 && !arm_arch6"
5589 "@
5590 #
5591 ldrsh%?\\t%0, %1"
5592 [(set_attr "length" "8,4")
5593 (set_attr "type" "alu_shift_reg,load_byte")
5594 (set_attr "predicable" "yes")]
5595 )
5596
5597 ;; ??? Check Thumb-2 pool range
5598 (define_insn "*arm_extendhisi2_v6"
5599 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5600 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5601 "TARGET_32BIT && arm_arch6"
5602 "@
5603 sxth%?\\t%0, %1
5604 ldrsh%?\\t%0, %1"
5605 [(set_attr "type" "extend,load_byte")
5606 (set_attr "predicable" "yes")]
5607 )
5608
5609 (define_insn "*arm_extendhisi2addsi"
5610 [(set (match_operand:SI 0 "s_register_operand" "=r")
5611 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5612 (match_operand:SI 2 "s_register_operand" "r")))]
5613 "TARGET_INT_SIMD"
5614 "sxtah%?\\t%0, %2, %1"
5615 [(set_attr "type" "alu_shift_reg")]
5616 )
5617
5618 (define_expand "extendqihi2"
5619 [(set (match_dup 2)
5620 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5621 (const_int 24)))
5622 (set (match_operand:HI 0 "s_register_operand" "")
5623 (ashiftrt:SI (match_dup 2)
5624 (const_int 24)))]
5625 "TARGET_ARM"
5626 "
5627 {
5628 if (arm_arch4 && MEM_P (operands[1]))
5629 {
5630 emit_insn (gen_rtx_SET (operands[0],
5631 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5632 DONE;
5633 }
5634 if (!s_register_operand (operands[1], QImode))
5635 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5636 operands[0] = gen_lowpart (SImode, operands[0]);
5637 operands[1] = gen_lowpart (SImode, operands[1]);
5638 operands[2] = gen_reg_rtx (SImode);
5639 }"
5640 )
5641
5642 (define_insn "*arm_extendqihi_insn"
5643 [(set (match_operand:HI 0 "s_register_operand" "=r")
5644 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5645 "TARGET_ARM && arm_arch4"
5646 "ldrsb%?\\t%0, %1"
5647 [(set_attr "type" "load_byte")
5648 (set_attr "predicable" "yes")]
5649 )
5650
5651 (define_expand "extendqisi2"
5652 [(set (match_operand:SI 0 "s_register_operand" "")
5653 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5654 "TARGET_EITHER"
5655 {
5656 if (!arm_arch4 && MEM_P (operands[1]))
5657 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5658
5659 if (!arm_arch6 && !MEM_P (operands[1]))
5660 {
5661 rtx t = gen_lowpart (SImode, operands[1]);
5662 rtx tmp = gen_reg_rtx (SImode);
5663 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5664 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5665 DONE;
5666 }
5667 })
5668
5669 (define_split
5670 [(set (match_operand:SI 0 "register_operand" "")
5671 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5672 "!arm_arch6"
5673 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5674 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5675 {
5676 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5677 })
5678
5679 (define_insn "*arm_extendqisi"
5680 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5681 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5682 "TARGET_ARM && arm_arch4 && !arm_arch6"
5683 "@
5684 #
5685 ldrsb%?\\t%0, %1"
5686 [(set_attr "length" "8,4")
5687 (set_attr "type" "alu_shift_reg,load_byte")
5688 (set_attr "predicable" "yes")]
5689 )
5690
5691 (define_insn "*arm_extendqisi_v6"
5692 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5693 (sign_extend:SI
5694 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5695 "TARGET_ARM && arm_arch6"
5696 "@
5697 sxtb%?\\t%0, %1
5698 ldrsb%?\\t%0, %1"
5699 [(set_attr "type" "extend,load_byte")
5700 (set_attr "predicable" "yes")]
5701 )
5702
5703 (define_insn "*arm_extendqisi2addsi"
5704 [(set (match_operand:SI 0 "s_register_operand" "=r")
5705 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5706 (match_operand:SI 2 "s_register_operand" "r")))]
5707 "TARGET_INT_SIMD"
5708 "sxtab%?\\t%0, %2, %1"
5709 [(set_attr "type" "alu_shift_reg")
5710 (set_attr "predicable" "yes")]
5711 )
5712
5713 (define_expand "extendsfdf2"
5714 [(set (match_operand:DF 0 "s_register_operand" "")
5715 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5716 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5717 ""
5718 )
5719
5720 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5721 ;; must go through SFmode.
5722 ;;
5723 ;; This is always safe for an extend.
5724
5725 (define_expand "extendhfdf2"
5726 [(set (match_operand:DF 0 "s_register_operand" "")
5727 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5728 "TARGET_EITHER"
5729 {
5730 /* We don't have a direct instruction for this, so go via SFmode. */
5731 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5732 {
5733 rtx op1;
5734 op1 = convert_to_mode (SFmode, operands[1], 0);
5735 op1 = convert_to_mode (DFmode, op1, 0);
5736 emit_insn (gen_movdf (operands[0], op1));
5737 DONE;
5738 }
5739 /* Otherwise, we're done producing RTL and will pick up the correct
5740 pattern to do this with one rounding-step in a single instruction. */
5741 }
5742 )
5743 \f
5744 ;; Move insns (including loads and stores)
5745
5746 ;; XXX Just some ideas about movti.
5747 ;; I don't think these are a good idea on the arm, there just aren't enough
5748 ;; registers
5749 ;;(define_expand "loadti"
5750 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5751 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5752 ;; "" "")
5753
5754 ;;(define_expand "storeti"
5755 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5756 ;; (match_operand:TI 1 "s_register_operand" ""))]
5757 ;; "" "")
5758
5759 ;;(define_expand "movti"
5760 ;; [(set (match_operand:TI 0 "general_operand" "")
5761 ;; (match_operand:TI 1 "general_operand" ""))]
5762 ;; ""
5763 ;; "
5764 ;;{
5765 ;; rtx insn;
5766 ;;
5767 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5768 ;; operands[1] = copy_to_reg (operands[1]);
5769 ;; if (MEM_P (operands[0]))
5770 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5771 ;; else if (MEM_P (operands[1]))
5772 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5773 ;; else
5774 ;; FAIL;
5775 ;;
5776 ;; emit_insn (insn);
5777 ;; DONE;
5778 ;;}")
5779
5780 ;; Recognize garbage generated above.
5781
5782 ;;(define_insn ""
5783 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5784 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5785 ;; ""
5786 ;; "*
5787 ;; {
5788 ;; register mem = (which_alternative < 3);
5789 ;; register const char *template;
5790 ;;
5791 ;; operands[mem] = XEXP (operands[mem], 0);
5792 ;; switch (which_alternative)
5793 ;; {
5794 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5795 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5796 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5797 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5798 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5799 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5800 ;; }
5801 ;; output_asm_insn (template, operands);
5802 ;; return \"\";
5803 ;; }")
5804
5805 (define_expand "movdi"
5806 [(set (match_operand:DI 0 "general_operand" "")
5807 (match_operand:DI 1 "general_operand" ""))]
5808 "TARGET_EITHER"
5809 "
5810 if (can_create_pseudo_p ())
5811 {
5812 if (!REG_P (operands[0]))
5813 operands[1] = force_reg (DImode, operands[1]);
5814 }
5815 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5816 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5817 {
5818 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5819 when expanding function calls. */
5820 gcc_assert (can_create_pseudo_p ());
5821 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5822 {
5823 /* Perform load into legal reg pair first, then move. */
5824 rtx reg = gen_reg_rtx (DImode);
5825 emit_insn (gen_movdi (reg, operands[1]));
5826 operands[1] = reg;
5827 }
5828 emit_move_insn (gen_lowpart (SImode, operands[0]),
5829 gen_lowpart (SImode, operands[1]));
5830 emit_move_insn (gen_highpart (SImode, operands[0]),
5831 gen_highpart (SImode, operands[1]));
5832 DONE;
5833 }
5834 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5835 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5836 {
5837 /* Avoid STRD's from an odd-numbered register pair in ARM state
5838 when expanding function prologue. */
5839 gcc_assert (can_create_pseudo_p ());
5840 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5841 ? gen_reg_rtx (DImode)
5842 : operands[0];
5843 emit_move_insn (gen_lowpart (SImode, split_dest),
5844 gen_lowpart (SImode, operands[1]));
5845 emit_move_insn (gen_highpart (SImode, split_dest),
5846 gen_highpart (SImode, operands[1]));
5847 if (split_dest != operands[0])
5848 emit_insn (gen_movdi (operands[0], split_dest));
5849 DONE;
5850 }
5851 "
5852 )
5853
5854 (define_insn "*arm_movdi"
5855 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
5856 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
5857 "TARGET_32BIT
5858 && !(TARGET_HARD_FLOAT)
5859 && !TARGET_IWMMXT
5860 && ( register_operand (operands[0], DImode)
5861 || register_operand (operands[1], DImode))"
5862 "*
5863 switch (which_alternative)
5864 {
5865 case 0:
5866 case 1:
5867 case 2:
5868 return \"#\";
5869 case 3:
5870 /* Cannot load it directly, split to load it via MOV / MOVT. */
5871 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
5872 return \"#\";
5873 /* Fall through. */
5874 default:
5875 return output_move_double (operands, true, NULL);
5876 }
5877 "
5878 [(set_attr "length" "8,12,16,8,8")
5879 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5880 (set_attr "arm_pool_range" "*,*,*,1020,*")
5881 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5882 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5883 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5884 )
5885
5886 (define_split
5887 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5888 (match_operand:ANY64 1 "immediate_operand" ""))]
5889 "TARGET_32BIT
5890 && reload_completed
5891 && (arm_disable_literal_pool
5892 || (arm_const_double_inline_cost (operands[1])
5893 <= arm_max_const_double_inline_cost ()))"
5894 [(const_int 0)]
5895 "
5896 arm_split_constant (SET, SImode, curr_insn,
5897 INTVAL (gen_lowpart (SImode, operands[1])),
5898 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5899 arm_split_constant (SET, SImode, curr_insn,
5900 INTVAL (gen_highpart_mode (SImode,
5901 GET_MODE (operands[0]),
5902 operands[1])),
5903 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5904 DONE;
5905 "
5906 )
5907
5908 ; If optimizing for size, or if we have load delay slots, then
5909 ; we want to split the constant into two separate operations.
5910 ; In both cases this may split a trivial part into a single data op
5911 ; leaving a single complex constant to load. We can also get longer
5912 ; offsets in a LDR which means we get better chances of sharing the pool
5913 ; entries. Finally, we can normally do a better job of scheduling
5914 ; LDR instructions than we can with LDM.
5915 ; This pattern will only match if the one above did not.
5916 (define_split
5917 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5918 (match_operand:ANY64 1 "const_double_operand" ""))]
5919 "TARGET_ARM && reload_completed
5920 && arm_const_double_by_parts (operands[1])"
5921 [(set (match_dup 0) (match_dup 1))
5922 (set (match_dup 2) (match_dup 3))]
5923 "
5924 operands[2] = gen_highpart (SImode, operands[0]);
5925 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5926 operands[1]);
5927 operands[0] = gen_lowpart (SImode, operands[0]);
5928 operands[1] = gen_lowpart (SImode, operands[1]);
5929 "
5930 )
5931
5932 (define_split
5933 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5934 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5935 "TARGET_EITHER && reload_completed"
5936 [(set (match_dup 0) (match_dup 1))
5937 (set (match_dup 2) (match_dup 3))]
5938 "
5939 operands[2] = gen_highpart (SImode, operands[0]);
5940 operands[3] = gen_highpart (SImode, operands[1]);
5941 operands[0] = gen_lowpart (SImode, operands[0]);
5942 operands[1] = gen_lowpart (SImode, operands[1]);
5943
5944 /* Handle a partial overlap. */
5945 if (rtx_equal_p (operands[0], operands[3]))
5946 {
5947 rtx tmp0 = operands[0];
5948 rtx tmp1 = operands[1];
5949
5950 operands[0] = operands[2];
5951 operands[1] = operands[3];
5952 operands[2] = tmp0;
5953 operands[3] = tmp1;
5954 }
5955 "
5956 )
5957
5958 ;; We can't actually do base+index doubleword loads if the index and
5959 ;; destination overlap. Split here so that we at least have chance to
5960 ;; schedule.
5961 (define_split
5962 [(set (match_operand:DI 0 "s_register_operand" "")
5963 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5964 (match_operand:SI 2 "s_register_operand" ""))))]
5965 "TARGET_LDRD
5966 && reg_overlap_mentioned_p (operands[0], operands[1])
5967 && reg_overlap_mentioned_p (operands[0], operands[2])"
5968 [(set (match_dup 4)
5969 (plus:SI (match_dup 1)
5970 (match_dup 2)))
5971 (set (match_dup 0)
5972 (mem:DI (match_dup 4)))]
5973 "
5974 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5975 "
5976 )
5977
5978 (define_expand "movsi"
5979 [(set (match_operand:SI 0 "general_operand" "")
5980 (match_operand:SI 1 "general_operand" ""))]
5981 "TARGET_EITHER"
5982 "
5983 {
5984 rtx base, offset, tmp;
5985
5986 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5987 {
5988 /* Everything except mem = const or mem = mem can be done easily. */
5989 if (MEM_P (operands[0]))
5990 operands[1] = force_reg (SImode, operands[1]);
5991 if (arm_general_register_operand (operands[0], SImode)
5992 && CONST_INT_P (operands[1])
5993 && !(const_ok_for_arm (INTVAL (operands[1]))
5994 || const_ok_for_arm (~INTVAL (operands[1]))))
5995 {
5996 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5997 {
5998 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5999 DONE;
6000 }
6001 else
6002 {
6003 arm_split_constant (SET, SImode, NULL_RTX,
6004 INTVAL (operands[1]), operands[0], NULL_RTX,
6005 optimize && can_create_pseudo_p ());
6006 DONE;
6007 }
6008 }
6009 }
6010 else /* Target doesn't have MOVT... */
6011 {
6012 if (can_create_pseudo_p ())
6013 {
6014 if (!REG_P (operands[0]))
6015 operands[1] = force_reg (SImode, operands[1]);
6016 }
6017 }
6018
6019 split_const (operands[1], &base, &offset);
6020 if (INTVAL (offset) != 0
6021 && targetm.cannot_force_const_mem (SImode, operands[1]))
6022 {
6023 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6024 emit_move_insn (tmp, base);
6025 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6026 DONE;
6027 }
6028
6029 tmp = can_create_pseudo_p () ? NULL_RTX : operands[0];
6030
6031 /* Recognize the case where operand[1] is a reference to thread-local
6032 data and load its address to a register. Offsets have been split off
6033 already. */
6034 if (arm_tls_referenced_p (operands[1]))
6035 operands[1] = legitimize_tls_address (operands[1], tmp);
6036 else if (flag_pic
6037 && (CONSTANT_P (operands[1])
6038 || symbol_mentioned_p (operands[1])
6039 || label_mentioned_p (operands[1])))
6040 operands[1] =
6041 legitimize_pic_address (operands[1], SImode, tmp, NULL_RTX, false);
6042 }
6043 "
6044 )
6045
6046 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6047 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6048 ;; so this does not matter.
6049 (define_insn "*arm_movt"
6050 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6051 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6052 (match_operand:SI 2 "general_operand" "i,i")))]
6053 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6054 "@
6055 movt%?\t%0, #:upper16:%c2
6056 movt\t%0, #:upper16:%c2"
6057 [(set_attr "arch" "32,v8mb")
6058 (set_attr "predicable" "yes")
6059 (set_attr "length" "4")
6060 (set_attr "type" "alu_sreg")]
6061 )
6062
6063 (define_insn "*arm_movsi_insn"
6064 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6065 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6066 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6067 && ( register_operand (operands[0], SImode)
6068 || register_operand (operands[1], SImode))"
6069 "@
6070 mov%?\\t%0, %1
6071 mov%?\\t%0, %1
6072 mvn%?\\t%0, #%B1
6073 movw%?\\t%0, %1
6074 ldr%?\\t%0, %1
6075 str%?\\t%1, %0"
6076 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6077 (set_attr "predicable" "yes")
6078 (set_attr "arch" "*,*,*,v6t2,*,*")
6079 (set_attr "pool_range" "*,*,*,*,4096,*")
6080 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6081 )
6082
6083 (define_split
6084 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6085 (match_operand:SI 1 "const_int_operand" ""))]
6086 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6087 && (!(const_ok_for_arm (INTVAL (operands[1]))
6088 || const_ok_for_arm (~INTVAL (operands[1]))))"
6089 [(clobber (const_int 0))]
6090 "
6091 arm_split_constant (SET, SImode, NULL_RTX,
6092 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6093 DONE;
6094 "
6095 )
6096
6097 ;; A normal way to do (symbol + offset) requires three instructions at least
6098 ;; (depends on how big the offset is) as below:
6099 ;; movw r0, #:lower16:g
6100 ;; movw r0, #:upper16:g
6101 ;; adds r0, #4
6102 ;;
6103 ;; A better way would be:
6104 ;; movw r0, #:lower16:g+4
6105 ;; movw r0, #:upper16:g+4
6106 ;;
6107 ;; The limitation of this way is that the length of offset should be a 16-bit
6108 ;; signed value, because current assembler only supports REL type relocation for
6109 ;; such case. If the more powerful RELA type is supported in future, we should
6110 ;; update this pattern to go with better way.
6111 (define_split
6112 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6113 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6114 (match_operand:SI 2 "const_int_operand" ""))))]
6115 "TARGET_THUMB
6116 && TARGET_HAVE_MOVT
6117 && arm_disable_literal_pool
6118 && reload_completed
6119 && GET_CODE (operands[1]) == SYMBOL_REF"
6120 [(clobber (const_int 0))]
6121 "
6122 int offset = INTVAL (operands[2]);
6123
6124 if (offset < -0x8000 || offset > 0x7fff)
6125 {
6126 arm_emit_movpair (operands[0], operands[1]);
6127 emit_insn (gen_rtx_SET (operands[0],
6128 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6129 }
6130 else
6131 {
6132 rtx op = gen_rtx_CONST (SImode,
6133 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6134 arm_emit_movpair (operands[0], op);
6135 }
6136 "
6137 )
6138
6139 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6140 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6141 ;; and lo_sum would be merged back into memory load at cprop. However,
6142 ;; if the default is to prefer movt/movw rather than a load from the constant
6143 ;; pool, the performance is better.
6144 (define_split
6145 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6146 (match_operand:SI 1 "general_operand" ""))]
6147 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6148 && !target_word_relocations
6149 && !arm_tls_referenced_p (operands[1])"
6150 [(clobber (const_int 0))]
6151 {
6152 arm_emit_movpair (operands[0], operands[1]);
6153 DONE;
6154 })
6155
6156 ;; When generating pic, we need to load the symbol offset into a register.
6157 ;; So that the optimizer does not confuse this with a normal symbol load
6158 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6159 ;; since that is the only type of relocation we can use.
6160
6161 ;; Wrap calculation of the whole PIC address in a single pattern for the
6162 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6163 ;; a PIC address involves two loads from memory, so we want to CSE it
6164 ;; as often as possible.
6165 ;; This pattern will be split into one of the pic_load_addr_* patterns
6166 ;; and a move after GCSE optimizations.
6167 ;;
6168 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6169 (define_expand "calculate_pic_address"
6170 [(set (match_operand:SI 0 "register_operand" "")
6171 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6172 (unspec:SI [(match_operand:SI 2 "" "")]
6173 UNSPEC_PIC_SYM))))]
6174 "flag_pic"
6175 )
6176
6177 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6178 (define_split
6179 [(set (match_operand:SI 0 "register_operand" "")
6180 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6181 (unspec:SI [(match_operand:SI 2 "" "")]
6182 UNSPEC_PIC_SYM))))]
6183 "flag_pic"
6184 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6185 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6186 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6187 )
6188
6189 ;; operand1 is the memory address to go into
6190 ;; pic_load_addr_32bit.
6191 ;; operand2 is the PIC label to be emitted
6192 ;; from pic_add_dot_plus_eight.
6193 ;; We do this to allow hoisting of the entire insn.
6194 (define_insn_and_split "pic_load_addr_unified"
6195 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6196 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6197 (match_operand:SI 2 "" "")]
6198 UNSPEC_PIC_UNIFIED))]
6199 "flag_pic"
6200 "#"
6201 "&& reload_completed"
6202 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6203 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6204 (match_dup 2)] UNSPEC_PIC_BASE))]
6205 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6206 [(set_attr "type" "load_4,load_4,load_4")
6207 (set_attr "pool_range" "4096,4094,1022")
6208 (set_attr "neg_pool_range" "4084,0,0")
6209 (set_attr "arch" "a,t2,t1")
6210 (set_attr "length" "8,6,4")]
6211 )
6212
6213 ;; The rather odd constraints on the following are to force reload to leave
6214 ;; the insn alone, and to force the minipool generation pass to then move
6215 ;; the GOT symbol to memory.
6216
6217 (define_insn "pic_load_addr_32bit"
6218 [(set (match_operand:SI 0 "s_register_operand" "=r")
6219 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6220 "TARGET_32BIT && flag_pic"
6221 "ldr%?\\t%0, %1"
6222 [(set_attr "type" "load_4")
6223 (set (attr "pool_range")
6224 (if_then_else (eq_attr "is_thumb" "no")
6225 (const_int 4096)
6226 (const_int 4094)))
6227 (set (attr "neg_pool_range")
6228 (if_then_else (eq_attr "is_thumb" "no")
6229 (const_int 4084)
6230 (const_int 0)))]
6231 )
6232
6233 (define_insn "pic_load_addr_thumb1"
6234 [(set (match_operand:SI 0 "s_register_operand" "=l")
6235 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6236 "TARGET_THUMB1 && flag_pic"
6237 "ldr\\t%0, %1"
6238 [(set_attr "type" "load_4")
6239 (set (attr "pool_range") (const_int 1018))]
6240 )
6241
6242 (define_insn "pic_add_dot_plus_four"
6243 [(set (match_operand:SI 0 "register_operand" "=r")
6244 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6245 (const_int 4)
6246 (match_operand 2 "" "")]
6247 UNSPEC_PIC_BASE))]
6248 "TARGET_THUMB"
6249 "*
6250 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6251 INTVAL (operands[2]));
6252 return \"add\\t%0, %|pc\";
6253 "
6254 [(set_attr "length" "2")
6255 (set_attr "type" "alu_sreg")]
6256 )
6257
6258 (define_insn "pic_add_dot_plus_eight"
6259 [(set (match_operand:SI 0 "register_operand" "=r")
6260 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6261 (const_int 8)
6262 (match_operand 2 "" "")]
6263 UNSPEC_PIC_BASE))]
6264 "TARGET_ARM"
6265 "*
6266 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6267 INTVAL (operands[2]));
6268 return \"add%?\\t%0, %|pc, %1\";
6269 "
6270 [(set_attr "predicable" "yes")
6271 (set_attr "type" "alu_sreg")]
6272 )
6273
6274 (define_insn "tls_load_dot_plus_eight"
6275 [(set (match_operand:SI 0 "register_operand" "=r")
6276 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6277 (const_int 8)
6278 (match_operand 2 "" "")]
6279 UNSPEC_PIC_BASE)))]
6280 "TARGET_ARM"
6281 "*
6282 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6283 INTVAL (operands[2]));
6284 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6285 "
6286 [(set_attr "predicable" "yes")
6287 (set_attr "type" "load_4")]
6288 )
6289
6290 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6291 ;; followed by a load. These sequences can be crunched down to
6292 ;; tls_load_dot_plus_eight by a peephole.
6293
6294 (define_peephole2
6295 [(set (match_operand:SI 0 "register_operand" "")
6296 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6297 (const_int 8)
6298 (match_operand 1 "" "")]
6299 UNSPEC_PIC_BASE))
6300 (set (match_operand:SI 2 "arm_general_register_operand" "")
6301 (mem:SI (match_dup 0)))]
6302 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6303 [(set (match_dup 2)
6304 (mem:SI (unspec:SI [(match_dup 3)
6305 (const_int 8)
6306 (match_dup 1)]
6307 UNSPEC_PIC_BASE)))]
6308 ""
6309 )
6310
6311 (define_insn "pic_offset_arm"
6312 [(set (match_operand:SI 0 "register_operand" "=r")
6313 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6314 (unspec:SI [(match_operand:SI 2 "" "X")]
6315 UNSPEC_PIC_OFFSET))))]
6316 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6317 "ldr%?\\t%0, [%1,%2]"
6318 [(set_attr "type" "load_4")]
6319 )
6320
6321 (define_expand "builtin_setjmp_receiver"
6322 [(label_ref (match_operand 0 "" ""))]
6323 "flag_pic"
6324 "
6325 {
6326 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6327 register. */
6328 if (arm_pic_register != INVALID_REGNUM)
6329 arm_load_pic_register (1UL << 3, NULL_RTX);
6330 DONE;
6331 }")
6332
6333 ;; If copying one reg to another we can set the condition codes according to
6334 ;; its value. Such a move is common after a return from subroutine and the
6335 ;; result is being tested against zero.
6336
6337 (define_insn "*movsi_compare0"
6338 [(set (reg:CC CC_REGNUM)
6339 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6340 (const_int 0)))
6341 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6342 (match_dup 1))]
6343 "TARGET_32BIT"
6344 "@
6345 cmp%?\\t%0, #0
6346 subs%?\\t%0, %1, #0"
6347 [(set_attr "conds" "set")
6348 (set_attr "type" "alus_imm,alus_imm")]
6349 )
6350
6351 ;; Subroutine to store a half word from a register into memory.
6352 ;; Operand 0 is the source register (HImode)
6353 ;; Operand 1 is the destination address in a register (SImode)
6354
6355 ;; In both this routine and the next, we must be careful not to spill
6356 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6357 ;; can generate unrecognizable rtl.
6358
6359 (define_expand "storehi"
6360 [;; store the low byte
6361 (set (match_operand 1 "" "") (match_dup 3))
6362 ;; extract the high byte
6363 (set (match_dup 2)
6364 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6365 ;; store the high byte
6366 (set (match_dup 4) (match_dup 5))]
6367 "TARGET_ARM"
6368 "
6369 {
6370 rtx op1 = operands[1];
6371 rtx addr = XEXP (op1, 0);
6372 enum rtx_code code = GET_CODE (addr);
6373
6374 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6375 || code == MINUS)
6376 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6377
6378 operands[4] = adjust_address (op1, QImode, 1);
6379 operands[1] = adjust_address (operands[1], QImode, 0);
6380 operands[3] = gen_lowpart (QImode, operands[0]);
6381 operands[0] = gen_lowpart (SImode, operands[0]);
6382 operands[2] = gen_reg_rtx (SImode);
6383 operands[5] = gen_lowpart (QImode, operands[2]);
6384 }"
6385 )
6386
6387 (define_expand "storehi_bigend"
6388 [(set (match_dup 4) (match_dup 3))
6389 (set (match_dup 2)
6390 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6391 (set (match_operand 1 "" "") (match_dup 5))]
6392 "TARGET_ARM"
6393 "
6394 {
6395 rtx op1 = operands[1];
6396 rtx addr = XEXP (op1, 0);
6397 enum rtx_code code = GET_CODE (addr);
6398
6399 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6400 || code == MINUS)
6401 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6402
6403 operands[4] = adjust_address (op1, QImode, 1);
6404 operands[1] = adjust_address (operands[1], QImode, 0);
6405 operands[3] = gen_lowpart (QImode, operands[0]);
6406 operands[0] = gen_lowpart (SImode, operands[0]);
6407 operands[2] = gen_reg_rtx (SImode);
6408 operands[5] = gen_lowpart (QImode, operands[2]);
6409 }"
6410 )
6411
6412 ;; Subroutine to store a half word integer constant into memory.
6413 (define_expand "storeinthi"
6414 [(set (match_operand 0 "" "")
6415 (match_operand 1 "" ""))
6416 (set (match_dup 3) (match_dup 2))]
6417 "TARGET_ARM"
6418 "
6419 {
6420 HOST_WIDE_INT value = INTVAL (operands[1]);
6421 rtx addr = XEXP (operands[0], 0);
6422 rtx op0 = operands[0];
6423 enum rtx_code code = GET_CODE (addr);
6424
6425 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6426 || code == MINUS)
6427 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6428
6429 operands[1] = gen_reg_rtx (SImode);
6430 if (BYTES_BIG_ENDIAN)
6431 {
6432 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6433 if ((value & 255) == ((value >> 8) & 255))
6434 operands[2] = operands[1];
6435 else
6436 {
6437 operands[2] = gen_reg_rtx (SImode);
6438 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6439 }
6440 }
6441 else
6442 {
6443 emit_insn (gen_movsi (operands[1], GEN_INT (value & 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 >> 8) & 255)));
6450 }
6451 }
6452
6453 operands[3] = adjust_address (op0, QImode, 1);
6454 operands[0] = adjust_address (operands[0], QImode, 0);
6455 operands[2] = gen_lowpart (QImode, operands[2]);
6456 operands[1] = gen_lowpart (QImode, operands[1]);
6457 }"
6458 )
6459
6460 (define_expand "storehi_single_op"
6461 [(set (match_operand:HI 0 "memory_operand" "")
6462 (match_operand:HI 1 "general_operand" ""))]
6463 "TARGET_32BIT && arm_arch4"
6464 "
6465 if (!s_register_operand (operands[1], HImode))
6466 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6467 "
6468 )
6469
6470 (define_expand "movhi"
6471 [(set (match_operand:HI 0 "general_operand" "")
6472 (match_operand:HI 1 "general_operand" ""))]
6473 "TARGET_EITHER"
6474 "
6475 if (TARGET_ARM)
6476 {
6477 if (can_create_pseudo_p ())
6478 {
6479 if (MEM_P (operands[0]))
6480 {
6481 if (arm_arch4)
6482 {
6483 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6484 DONE;
6485 }
6486 if (CONST_INT_P (operands[1]))
6487 emit_insn (gen_storeinthi (operands[0], operands[1]));
6488 else
6489 {
6490 if (MEM_P (operands[1]))
6491 operands[1] = force_reg (HImode, operands[1]);
6492 if (BYTES_BIG_ENDIAN)
6493 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6494 else
6495 emit_insn (gen_storehi (operands[1], operands[0]));
6496 }
6497 DONE;
6498 }
6499 /* Sign extend a constant, and keep it in an SImode reg. */
6500 else if (CONST_INT_P (operands[1]))
6501 {
6502 rtx reg = gen_reg_rtx (SImode);
6503 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6504
6505 /* If the constant is already valid, leave it alone. */
6506 if (!const_ok_for_arm (val))
6507 {
6508 /* If setting all the top bits will make the constant
6509 loadable in a single instruction, then set them.
6510 Otherwise, sign extend the number. */
6511
6512 if (const_ok_for_arm (~(val | ~0xffff)))
6513 val |= ~0xffff;
6514 else if (val & 0x8000)
6515 val |= ~0xffff;
6516 }
6517
6518 emit_insn (gen_movsi (reg, GEN_INT (val)));
6519 operands[1] = gen_lowpart (HImode, reg);
6520 }
6521 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6522 && MEM_P (operands[1]))
6523 {
6524 rtx reg = gen_reg_rtx (SImode);
6525
6526 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6527 operands[1] = gen_lowpart (HImode, reg);
6528 }
6529 else if (!arm_arch4)
6530 {
6531 if (MEM_P (operands[1]))
6532 {
6533 rtx base;
6534 rtx offset = const0_rtx;
6535 rtx reg = gen_reg_rtx (SImode);
6536
6537 if ((REG_P (base = XEXP (operands[1], 0))
6538 || (GET_CODE (base) == PLUS
6539 && (CONST_INT_P (offset = XEXP (base, 1)))
6540 && ((INTVAL(offset) & 1) != 1)
6541 && REG_P (base = XEXP (base, 0))))
6542 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6543 {
6544 rtx new_rtx;
6545
6546 new_rtx = widen_memory_access (operands[1], SImode,
6547 ((INTVAL (offset) & ~3)
6548 - INTVAL (offset)));
6549 emit_insn (gen_movsi (reg, new_rtx));
6550 if (((INTVAL (offset) & 2) != 0)
6551 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6552 {
6553 rtx reg2 = gen_reg_rtx (SImode);
6554
6555 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6556 reg = reg2;
6557 }
6558 }
6559 else
6560 emit_insn (gen_movhi_bytes (reg, operands[1]));
6561
6562 operands[1] = gen_lowpart (HImode, reg);
6563 }
6564 }
6565 }
6566 /* Handle loading a large integer during reload. */
6567 else if (CONST_INT_P (operands[1])
6568 && !const_ok_for_arm (INTVAL (operands[1]))
6569 && !const_ok_for_arm (~INTVAL (operands[1])))
6570 {
6571 /* Writing a constant to memory needs a scratch, which should
6572 be handled with SECONDARY_RELOADs. */
6573 gcc_assert (REG_P (operands[0]));
6574
6575 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6576 emit_insn (gen_movsi (operands[0], operands[1]));
6577 DONE;
6578 }
6579 }
6580 else if (TARGET_THUMB2)
6581 {
6582 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6583 if (can_create_pseudo_p ())
6584 {
6585 if (!REG_P (operands[0]))
6586 operands[1] = force_reg (HImode, operands[1]);
6587 /* Zero extend a constant, and keep it in an SImode reg. */
6588 else if (CONST_INT_P (operands[1]))
6589 {
6590 rtx reg = gen_reg_rtx (SImode);
6591 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6592
6593 emit_insn (gen_movsi (reg, GEN_INT (val)));
6594 operands[1] = gen_lowpart (HImode, reg);
6595 }
6596 }
6597 }
6598 else /* TARGET_THUMB1 */
6599 {
6600 if (can_create_pseudo_p ())
6601 {
6602 if (CONST_INT_P (operands[1]))
6603 {
6604 rtx reg = gen_reg_rtx (SImode);
6605
6606 emit_insn (gen_movsi (reg, operands[1]));
6607 operands[1] = gen_lowpart (HImode, reg);
6608 }
6609
6610 /* ??? We shouldn't really get invalid addresses here, but this can
6611 happen if we are passed a SP (never OK for HImode/QImode) or
6612 virtual register (also rejected as illegitimate for HImode/QImode)
6613 relative address. */
6614 /* ??? This should perhaps be fixed elsewhere, for instance, in
6615 fixup_stack_1, by checking for other kinds of invalid addresses,
6616 e.g. a bare reference to a virtual register. This may confuse the
6617 alpha though, which must handle this case differently. */
6618 if (MEM_P (operands[0])
6619 && !memory_address_p (GET_MODE (operands[0]),
6620 XEXP (operands[0], 0)))
6621 operands[0]
6622 = replace_equiv_address (operands[0],
6623 copy_to_reg (XEXP (operands[0], 0)));
6624
6625 if (MEM_P (operands[1])
6626 && !memory_address_p (GET_MODE (operands[1]),
6627 XEXP (operands[1], 0)))
6628 operands[1]
6629 = replace_equiv_address (operands[1],
6630 copy_to_reg (XEXP (operands[1], 0)));
6631
6632 if (MEM_P (operands[1]) && optimize > 0)
6633 {
6634 rtx reg = gen_reg_rtx (SImode);
6635
6636 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6637 operands[1] = gen_lowpart (HImode, reg);
6638 }
6639
6640 if (MEM_P (operands[0]))
6641 operands[1] = force_reg (HImode, operands[1]);
6642 }
6643 else if (CONST_INT_P (operands[1])
6644 && !satisfies_constraint_I (operands[1]))
6645 {
6646 /* Handle loading a large integer during reload. */
6647
6648 /* Writing a constant to memory needs a scratch, which should
6649 be handled with SECONDARY_RELOADs. */
6650 gcc_assert (REG_P (operands[0]));
6651
6652 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6653 emit_insn (gen_movsi (operands[0], operands[1]));
6654 DONE;
6655 }
6656 }
6657 "
6658 )
6659
6660 (define_expand "movhi_bytes"
6661 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6662 (set (match_dup 3)
6663 (zero_extend:SI (match_dup 6)))
6664 (set (match_operand:SI 0 "" "")
6665 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6666 "TARGET_ARM"
6667 "
6668 {
6669 rtx mem1, mem2;
6670 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6671
6672 mem1 = change_address (operands[1], QImode, addr);
6673 mem2 = change_address (operands[1], QImode,
6674 plus_constant (Pmode, addr, 1));
6675 operands[0] = gen_lowpart (SImode, operands[0]);
6676 operands[1] = mem1;
6677 operands[2] = gen_reg_rtx (SImode);
6678 operands[3] = gen_reg_rtx (SImode);
6679 operands[6] = mem2;
6680
6681 if (BYTES_BIG_ENDIAN)
6682 {
6683 operands[4] = operands[2];
6684 operands[5] = operands[3];
6685 }
6686 else
6687 {
6688 operands[4] = operands[3];
6689 operands[5] = operands[2];
6690 }
6691 }"
6692 )
6693
6694 (define_expand "movhi_bigend"
6695 [(set (match_dup 2)
6696 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6697 (const_int 16)))
6698 (set (match_dup 3)
6699 (ashiftrt:SI (match_dup 2) (const_int 16)))
6700 (set (match_operand:HI 0 "s_register_operand" "")
6701 (match_dup 4))]
6702 "TARGET_ARM"
6703 "
6704 operands[2] = gen_reg_rtx (SImode);
6705 operands[3] = gen_reg_rtx (SImode);
6706 operands[4] = gen_lowpart (HImode, operands[3]);
6707 "
6708 )
6709
6710 ;; Pattern to recognize insn generated default case above
6711 (define_insn "*movhi_insn_arch4"
6712 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6713 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6714 "TARGET_ARM
6715 && arm_arch4 && !TARGET_HARD_FLOAT
6716 && (register_operand (operands[0], HImode)
6717 || register_operand (operands[1], HImode))"
6718 "@
6719 mov%?\\t%0, %1\\t%@ movhi
6720 mvn%?\\t%0, #%B1\\t%@ movhi
6721 movw%?\\t%0, %L1\\t%@ movhi
6722 strh%?\\t%1, %0\\t%@ movhi
6723 ldrh%?\\t%0, %1\\t%@ movhi"
6724 [(set_attr "predicable" "yes")
6725 (set_attr "pool_range" "*,*,*,*,256")
6726 (set_attr "neg_pool_range" "*,*,*,*,244")
6727 (set_attr "arch" "*,*,v6t2,*,*")
6728 (set_attr_alternative "type"
6729 [(if_then_else (match_operand 1 "const_int_operand" "")
6730 (const_string "mov_imm" )
6731 (const_string "mov_reg"))
6732 (const_string "mvn_imm")
6733 (const_string "mov_imm")
6734 (const_string "store_4")
6735 (const_string "load_4")])]
6736 )
6737
6738 (define_insn "*movhi_bytes"
6739 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6740 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6741 "TARGET_ARM && !TARGET_HARD_FLOAT"
6742 "@
6743 mov%?\\t%0, %1\\t%@ movhi
6744 mov%?\\t%0, %1\\t%@ movhi
6745 mvn%?\\t%0, #%B1\\t%@ movhi"
6746 [(set_attr "predicable" "yes")
6747 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6748 )
6749
6750 ;; We use a DImode scratch because we may occasionally need an additional
6751 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6752 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6753 (define_expand "reload_outhi"
6754 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6755 (match_operand:HI 1 "s_register_operand" "r")
6756 (match_operand:DI 2 "s_register_operand" "=&l")])]
6757 "TARGET_EITHER"
6758 "if (TARGET_ARM)
6759 arm_reload_out_hi (operands);
6760 else
6761 thumb_reload_out_hi (operands);
6762 DONE;
6763 "
6764 )
6765
6766 (define_expand "reload_inhi"
6767 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6768 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6769 (match_operand:DI 2 "s_register_operand" "=&r")])]
6770 "TARGET_EITHER"
6771 "
6772 if (TARGET_ARM)
6773 arm_reload_in_hi (operands);
6774 else
6775 thumb_reload_out_hi (operands);
6776 DONE;
6777 ")
6778
6779 (define_expand "movqi"
6780 [(set (match_operand:QI 0 "general_operand" "")
6781 (match_operand:QI 1 "general_operand" ""))]
6782 "TARGET_EITHER"
6783 "
6784 /* Everything except mem = const or mem = mem can be done easily */
6785
6786 if (can_create_pseudo_p ())
6787 {
6788 if (CONST_INT_P (operands[1]))
6789 {
6790 rtx reg = gen_reg_rtx (SImode);
6791
6792 /* For thumb we want an unsigned immediate, then we are more likely
6793 to be able to use a movs insn. */
6794 if (TARGET_THUMB)
6795 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6796
6797 emit_insn (gen_movsi (reg, operands[1]));
6798 operands[1] = gen_lowpart (QImode, reg);
6799 }
6800
6801 if (TARGET_THUMB)
6802 {
6803 /* ??? We shouldn't really get invalid addresses here, but this can
6804 happen if we are passed a SP (never OK for HImode/QImode) or
6805 virtual register (also rejected as illegitimate for HImode/QImode)
6806 relative address. */
6807 /* ??? This should perhaps be fixed elsewhere, for instance, in
6808 fixup_stack_1, by checking for other kinds of invalid addresses,
6809 e.g. a bare reference to a virtual register. This may confuse the
6810 alpha though, which must handle this case differently. */
6811 if (MEM_P (operands[0])
6812 && !memory_address_p (GET_MODE (operands[0]),
6813 XEXP (operands[0], 0)))
6814 operands[0]
6815 = replace_equiv_address (operands[0],
6816 copy_to_reg (XEXP (operands[0], 0)));
6817 if (MEM_P (operands[1])
6818 && !memory_address_p (GET_MODE (operands[1]),
6819 XEXP (operands[1], 0)))
6820 operands[1]
6821 = replace_equiv_address (operands[1],
6822 copy_to_reg (XEXP (operands[1], 0)));
6823 }
6824
6825 if (MEM_P (operands[1]) && optimize > 0)
6826 {
6827 rtx reg = gen_reg_rtx (SImode);
6828
6829 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6830 operands[1] = gen_lowpart (QImode, reg);
6831 }
6832
6833 if (MEM_P (operands[0]))
6834 operands[1] = force_reg (QImode, operands[1]);
6835 }
6836 else if (TARGET_THUMB
6837 && CONST_INT_P (operands[1])
6838 && !satisfies_constraint_I (operands[1]))
6839 {
6840 /* Handle loading a large integer during reload. */
6841
6842 /* Writing a constant to memory needs a scratch, which should
6843 be handled with SECONDARY_RELOADs. */
6844 gcc_assert (REG_P (operands[0]));
6845
6846 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6847 emit_insn (gen_movsi (operands[0], operands[1]));
6848 DONE;
6849 }
6850 "
6851 )
6852
6853 (define_insn "*arm_movqi_insn"
6854 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6855 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6856 "TARGET_32BIT
6857 && ( register_operand (operands[0], QImode)
6858 || register_operand (operands[1], QImode))"
6859 "@
6860 mov%?\\t%0, %1
6861 mov%?\\t%0, %1
6862 mov%?\\t%0, %1
6863 mov%?\\t%0, %1
6864 mvn%?\\t%0, #%B1
6865 ldrb%?\\t%0, %1
6866 strb%?\\t%1, %0
6867 ldrb%?\\t%0, %1
6868 strb%?\\t%1, %0"
6869 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6870 (set_attr "predicable" "yes")
6871 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6872 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6873 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6874 )
6875
6876 ;; HFmode moves
6877 (define_expand "movhf"
6878 [(set (match_operand:HF 0 "general_operand" "")
6879 (match_operand:HF 1 "general_operand" ""))]
6880 "TARGET_EITHER"
6881 "
6882 if (TARGET_32BIT)
6883 {
6884 if (MEM_P (operands[0]))
6885 operands[1] = force_reg (HFmode, operands[1]);
6886 }
6887 else /* TARGET_THUMB1 */
6888 {
6889 if (can_create_pseudo_p ())
6890 {
6891 if (!REG_P (operands[0]))
6892 operands[1] = force_reg (HFmode, operands[1]);
6893 }
6894 }
6895 "
6896 )
6897
6898 (define_insn "*arm32_movhf"
6899 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6900 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6901 "TARGET_32BIT && !TARGET_HARD_FLOAT
6902 && ( s_register_operand (operands[0], HFmode)
6903 || s_register_operand (operands[1], HFmode))"
6904 "*
6905 switch (which_alternative)
6906 {
6907 case 0: /* ARM register from memory */
6908 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6909 case 1: /* memory from ARM register */
6910 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6911 case 2: /* ARM register from ARM register */
6912 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6913 case 3: /* ARM register from constant */
6914 {
6915 long bits;
6916 rtx ops[4];
6917
6918 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6919 HFmode);
6920 ops[0] = operands[0];
6921 ops[1] = GEN_INT (bits);
6922 ops[2] = GEN_INT (bits & 0xff00);
6923 ops[3] = GEN_INT (bits & 0x00ff);
6924
6925 if (arm_arch_thumb2)
6926 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6927 else
6928 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6929 return \"\";
6930 }
6931 default:
6932 gcc_unreachable ();
6933 }
6934 "
6935 [(set_attr "conds" "unconditional")
6936 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6937 (set_attr "length" "4,4,4,8")
6938 (set_attr "predicable" "yes")]
6939 )
6940
6941 (define_expand "movsf"
6942 [(set (match_operand:SF 0 "general_operand" "")
6943 (match_operand:SF 1 "general_operand" ""))]
6944 "TARGET_EITHER"
6945 "
6946 if (TARGET_32BIT)
6947 {
6948 if (MEM_P (operands[0]))
6949 operands[1] = force_reg (SFmode, operands[1]);
6950 }
6951 else /* TARGET_THUMB1 */
6952 {
6953 if (can_create_pseudo_p ())
6954 {
6955 if (!REG_P (operands[0]))
6956 operands[1] = force_reg (SFmode, operands[1]);
6957 }
6958 }
6959
6960 /* Cannot load it directly, generate a load with clobber so that it can be
6961 loaded via GPR with MOV / MOVT. */
6962 if (arm_disable_literal_pool
6963 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6964 && CONST_DOUBLE_P (operands[1])
6965 && TARGET_HARD_FLOAT
6966 && !vfp3_const_double_rtx (operands[1]))
6967 {
6968 rtx clobreg = gen_reg_rtx (SFmode);
6969 emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
6970 clobreg));
6971 DONE;
6972 }
6973 "
6974 )
6975
6976 ;; Transform a floating-point move of a constant into a core register into
6977 ;; an SImode operation.
6978 (define_split
6979 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6980 (match_operand:SF 1 "immediate_operand" ""))]
6981 "TARGET_EITHER
6982 && reload_completed
6983 && CONST_DOUBLE_P (operands[1])"
6984 [(set (match_dup 2) (match_dup 3))]
6985 "
6986 operands[2] = gen_lowpart (SImode, operands[0]);
6987 operands[3] = gen_lowpart (SImode, operands[1]);
6988 if (operands[2] == 0 || operands[3] == 0)
6989 FAIL;
6990 "
6991 )
6992
6993 (define_insn "*arm_movsf_soft_insn"
6994 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6995 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6996 "TARGET_32BIT
6997 && TARGET_SOFT_FLOAT
6998 && (!MEM_P (operands[0])
6999 || register_operand (operands[1], SFmode))"
7000 {
7001 switch (which_alternative)
7002 {
7003 case 0: return \"mov%?\\t%0, %1\";
7004 case 1:
7005 /* Cannot load it directly, split to load it via MOV / MOVT. */
7006 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7007 return \"#\";
7008 return \"ldr%?\\t%0, %1\\t%@ float\";
7009 case 2: return \"str%?\\t%1, %0\\t%@ float\";
7010 default: gcc_unreachable ();
7011 }
7012 }
7013 [(set_attr "predicable" "yes")
7014 (set_attr "type" "mov_reg,load_4,store_4")
7015 (set_attr "arm_pool_range" "*,4096,*")
7016 (set_attr "thumb2_pool_range" "*,4094,*")
7017 (set_attr "arm_neg_pool_range" "*,4084,*")
7018 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7019 )
7020
7021 ;; Splitter for the above.
7022 (define_split
7023 [(set (match_operand:SF 0 "s_register_operand")
7024 (match_operand:SF 1 "const_double_operand"))]
7025 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7026 [(const_int 0)]
7027 {
7028 long buf;
7029 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
7030 rtx cst = gen_int_mode (buf, SImode);
7031 emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
7032 DONE;
7033 }
7034 )
7035
7036 (define_expand "movdf"
7037 [(set (match_operand:DF 0 "general_operand" "")
7038 (match_operand:DF 1 "general_operand" ""))]
7039 "TARGET_EITHER"
7040 "
7041 if (TARGET_32BIT)
7042 {
7043 if (MEM_P (operands[0]))
7044 operands[1] = force_reg (DFmode, operands[1]);
7045 }
7046 else /* TARGET_THUMB */
7047 {
7048 if (can_create_pseudo_p ())
7049 {
7050 if (!REG_P (operands[0]))
7051 operands[1] = force_reg (DFmode, operands[1]);
7052 }
7053 }
7054
7055 /* Cannot load it directly, generate a load with clobber so that it can be
7056 loaded via GPR with MOV / MOVT. */
7057 if (arm_disable_literal_pool
7058 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
7059 && CONSTANT_P (operands[1])
7060 && TARGET_HARD_FLOAT
7061 && !arm_const_double_rtx (operands[1])
7062 && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
7063 {
7064 rtx clobreg = gen_reg_rtx (DFmode);
7065 emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
7066 clobreg));
7067 DONE;
7068 }
7069 "
7070 )
7071
7072 ;; Reloading a df mode value stored in integer regs to memory can require a
7073 ;; scratch reg.
7074 (define_expand "reload_outdf"
7075 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7076 (match_operand:DF 1 "s_register_operand" "r")
7077 (match_operand:SI 2 "s_register_operand" "=&r")]
7078 "TARGET_THUMB2"
7079 "
7080 {
7081 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7082
7083 if (code == REG)
7084 operands[2] = XEXP (operands[0], 0);
7085 else if (code == POST_INC || code == PRE_DEC)
7086 {
7087 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7088 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7089 emit_insn (gen_movdi (operands[0], operands[1]));
7090 DONE;
7091 }
7092 else if (code == PRE_INC)
7093 {
7094 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7095
7096 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7097 operands[2] = reg;
7098 }
7099 else if (code == POST_DEC)
7100 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7101 else
7102 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7103 XEXP (XEXP (operands[0], 0), 1)));
7104
7105 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7106 operands[1]));
7107
7108 if (code == POST_DEC)
7109 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7110
7111 DONE;
7112 }"
7113 )
7114
7115 (define_insn "*movdf_soft_insn"
7116 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
7117 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
7118 "TARGET_32BIT && TARGET_SOFT_FLOAT
7119 && ( register_operand (operands[0], DFmode)
7120 || register_operand (operands[1], DFmode))"
7121 "*
7122 switch (which_alternative)
7123 {
7124 case 0:
7125 case 1:
7126 case 2:
7127 return \"#\";
7128 case 3:
7129 /* Cannot load it directly, split to load it via MOV / MOVT. */
7130 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
7131 return \"#\";
7132 /* Fall through. */
7133 default:
7134 return output_move_double (operands, true, NULL);
7135 }
7136 "
7137 [(set_attr "length" "8,12,16,8,8")
7138 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7139 (set_attr "arm_pool_range" "*,*,*,1020,*")
7140 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7141 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7142 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7143 )
7144
7145 ;; Splitter for the above.
7146 (define_split
7147 [(set (match_operand:DF 0 "s_register_operand")
7148 (match_operand:DF 1 "const_double_operand"))]
7149 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
7150 [(const_int 0)]
7151 {
7152 long buf[2];
7153 int order = BYTES_BIG_ENDIAN ? 1 : 0;
7154 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
7155 unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
7156 ival |= (zext_hwi (buf[1 - order], 32) << 32);
7157 rtx cst = gen_int_mode (ival, DImode);
7158 emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
7159 DONE;
7160 }
7161 )
7162 \f
7163
7164 ;; load- and store-multiple insns
7165 ;; The arm can load/store any set of registers, provided that they are in
7166 ;; ascending order, but these expanders assume a contiguous set.
7167
7168 (define_expand "load_multiple"
7169 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7170 (match_operand:SI 1 "" ""))
7171 (use (match_operand:SI 2 "" ""))])]
7172 "TARGET_32BIT"
7173 {
7174 HOST_WIDE_INT offset = 0;
7175
7176 /* Support only fixed point registers. */
7177 if (!CONST_INT_P (operands[2])
7178 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7179 || INTVAL (operands[2]) < 2
7180 || !MEM_P (operands[1])
7181 || !REG_P (operands[0])
7182 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7183 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7184 FAIL;
7185
7186 operands[3]
7187 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7188 INTVAL (operands[2]),
7189 force_reg (SImode, XEXP (operands[1], 0)),
7190 FALSE, operands[1], &offset);
7191 })
7192
7193 (define_expand "store_multiple"
7194 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7195 (match_operand:SI 1 "" ""))
7196 (use (match_operand:SI 2 "" ""))])]
7197 "TARGET_32BIT"
7198 {
7199 HOST_WIDE_INT offset = 0;
7200
7201 /* Support only fixed point registers. */
7202 if (!CONST_INT_P (operands[2])
7203 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7204 || INTVAL (operands[2]) < 2
7205 || !REG_P (operands[1])
7206 || !MEM_P (operands[0])
7207 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7208 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7209 FAIL;
7210
7211 operands[3]
7212 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7213 INTVAL (operands[2]),
7214 force_reg (SImode, XEXP (operands[0], 0)),
7215 FALSE, operands[0], &offset);
7216 })
7217
7218
7219 (define_expand "setmemsi"
7220 [(match_operand:BLK 0 "general_operand" "")
7221 (match_operand:SI 1 "const_int_operand" "")
7222 (match_operand:SI 2 "const_int_operand" "")
7223 (match_operand:SI 3 "const_int_operand" "")]
7224 "TARGET_32BIT"
7225 {
7226 if (arm_gen_setmem (operands))
7227 DONE;
7228
7229 FAIL;
7230 })
7231
7232
7233 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7234 ;; We could let this apply for blocks of less than this, but it clobbers so
7235 ;; many registers that there is then probably a better way.
7236
7237 (define_expand "movmemqi"
7238 [(match_operand:BLK 0 "general_operand" "")
7239 (match_operand:BLK 1 "general_operand" "")
7240 (match_operand:SI 2 "const_int_operand" "")
7241 (match_operand:SI 3 "const_int_operand" "")]
7242 ""
7243 "
7244 if (TARGET_32BIT)
7245 {
7246 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7247 && !optimize_function_for_size_p (cfun))
7248 {
7249 if (gen_movmem_ldrd_strd (operands))
7250 DONE;
7251 FAIL;
7252 }
7253
7254 if (arm_gen_movmemqi (operands))
7255 DONE;
7256 FAIL;
7257 }
7258 else /* TARGET_THUMB1 */
7259 {
7260 if ( INTVAL (operands[3]) != 4
7261 || INTVAL (operands[2]) > 48)
7262 FAIL;
7263
7264 thumb_expand_movmemqi (operands);
7265 DONE;
7266 }
7267 "
7268 )
7269 \f
7270
7271 ;; Compare & branch insns
7272 ;; The range calculations are based as follows:
7273 ;; For forward branches, the address calculation returns the address of
7274 ;; the next instruction. This is 2 beyond the branch instruction.
7275 ;; For backward branches, the address calculation returns the address of
7276 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7277 ;; instruction for the shortest sequence, and 4 before the branch instruction
7278 ;; if we have to jump around an unconditional branch.
7279 ;; To the basic branch range the PC offset must be added (this is +4).
7280 ;; So for forward branches we have
7281 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7282 ;; And for backward branches we have
7283 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7284 ;;
7285 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7286 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7287
7288 (define_expand "cbranchsi4"
7289 [(set (pc) (if_then_else
7290 (match_operator 0 "expandable_comparison_operator"
7291 [(match_operand:SI 1 "s_register_operand" "")
7292 (match_operand:SI 2 "nonmemory_operand" "")])
7293 (label_ref (match_operand 3 "" ""))
7294 (pc)))]
7295 "TARGET_EITHER"
7296 "
7297 if (!TARGET_THUMB1)
7298 {
7299 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7300 FAIL;
7301 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7302 operands[3]));
7303 DONE;
7304 }
7305 if (thumb1_cmpneg_operand (operands[2], SImode))
7306 {
7307 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7308 operands[3], operands[0]));
7309 DONE;
7310 }
7311 if (!thumb1_cmp_operand (operands[2], SImode))
7312 operands[2] = force_reg (SImode, operands[2]);
7313 ")
7314
7315 (define_expand "cbranchsf4"
7316 [(set (pc) (if_then_else
7317 (match_operator 0 "expandable_comparison_operator"
7318 [(match_operand:SF 1 "s_register_operand" "")
7319 (match_operand:SF 2 "vfp_compare_operand" "")])
7320 (label_ref (match_operand 3 "" ""))
7321 (pc)))]
7322 "TARGET_32BIT && TARGET_HARD_FLOAT"
7323 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7324 operands[3])); DONE;"
7325 )
7326
7327 (define_expand "cbranchdf4"
7328 [(set (pc) (if_then_else
7329 (match_operator 0 "expandable_comparison_operator"
7330 [(match_operand:DF 1 "s_register_operand" "")
7331 (match_operand:DF 2 "vfp_compare_operand" "")])
7332 (label_ref (match_operand 3 "" ""))
7333 (pc)))]
7334 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7335 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7336 operands[3])); DONE;"
7337 )
7338
7339 (define_expand "cbranchdi4"
7340 [(set (pc) (if_then_else
7341 (match_operator 0 "expandable_comparison_operator"
7342 [(match_operand:DI 1 "s_register_operand" "")
7343 (match_operand:DI 2 "cmpdi_operand" "")])
7344 (label_ref (match_operand 3 "" ""))
7345 (pc)))]
7346 "TARGET_32BIT"
7347 "{
7348 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7349 FAIL;
7350 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7351 operands[3]));
7352 DONE;
7353 }"
7354 )
7355
7356 ;; Comparison and test insns
7357
7358 (define_insn "*arm_cmpsi_insn"
7359 [(set (reg:CC CC_REGNUM)
7360 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7361 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7362 "TARGET_32BIT"
7363 "@
7364 cmp%?\\t%0, %1
7365 cmp%?\\t%0, %1
7366 cmp%?\\t%0, %1
7367 cmp%?\\t%0, %1
7368 cmn%?\\t%0, #%n1"
7369 [(set_attr "conds" "set")
7370 (set_attr "arch" "t2,t2,any,any,any")
7371 (set_attr "length" "2,2,4,4,4")
7372 (set_attr "predicable" "yes")
7373 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7374 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7375 )
7376
7377 (define_insn "*cmpsi_shiftsi"
7378 [(set (reg:CC CC_REGNUM)
7379 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7380 (match_operator:SI 3 "shift_operator"
7381 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7382 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7383 "TARGET_32BIT"
7384 "cmp\\t%0, %1%S3"
7385 [(set_attr "conds" "set")
7386 (set_attr "shift" "1")
7387 (set_attr "arch" "32,a,a")
7388 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7389
7390 (define_insn "*cmpsi_shiftsi_swp"
7391 [(set (reg:CC_SWP CC_REGNUM)
7392 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7393 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7394 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7395 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7396 "TARGET_32BIT"
7397 "cmp%?\\t%0, %1%S3"
7398 [(set_attr "conds" "set")
7399 (set_attr "shift" "1")
7400 (set_attr "arch" "32,a,a")
7401 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7402
7403 (define_insn "*arm_cmpsi_negshiftsi_si"
7404 [(set (reg:CC_Z CC_REGNUM)
7405 (compare:CC_Z
7406 (neg:SI (match_operator:SI 1 "shift_operator"
7407 [(match_operand:SI 2 "s_register_operand" "r")
7408 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7409 (match_operand:SI 0 "s_register_operand" "r")))]
7410 "TARGET_ARM"
7411 "cmn%?\\t%0, %2%S1"
7412 [(set_attr "conds" "set")
7413 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7414 (const_string "alus_shift_imm")
7415 (const_string "alus_shift_reg")))
7416 (set_attr "predicable" "yes")]
7417 )
7418
7419 ;; DImode comparisons. The generic code generates branches that
7420 ;; if-conversion cannot reduce to a conditional compare, so we do
7421 ;; that directly.
7422
7423 (define_insn_and_split "*arm_cmpdi_insn"
7424 [(set (reg:CC_NCV CC_REGNUM)
7425 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7426 (match_operand:DI 1 "arm_di_operand" "rDi")))
7427 (clobber (match_scratch:SI 2 "=r"))]
7428 "TARGET_32BIT"
7429 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7430 "&& reload_completed"
7431 [(set (reg:CC CC_REGNUM)
7432 (compare:CC (match_dup 0) (match_dup 1)))
7433 (parallel [(set (reg:CC CC_REGNUM)
7434 (compare:CC (match_dup 3) (match_dup 4)))
7435 (set (match_dup 2)
7436 (minus:SI (match_dup 5)
7437 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7438 {
7439 operands[3] = gen_highpart (SImode, operands[0]);
7440 operands[0] = gen_lowpart (SImode, operands[0]);
7441 if (CONST_INT_P (operands[1]))
7442 {
7443 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);
7444 if (operands[4] == const0_rtx)
7445 operands[5] = operands[3];
7446 else
7447 operands[5] = gen_rtx_PLUS (SImode, operands[3],
7448 gen_int_mode (-UINTVAL (operands[4]),
7449 SImode));
7450 }
7451 else
7452 {
7453 operands[4] = gen_highpart (SImode, operands[1]);
7454 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7455 }
7456 operands[1] = gen_lowpart (SImode, operands[1]);
7457 operands[2] = gen_lowpart (SImode, operands[2]);
7458 }
7459 [(set_attr "conds" "set")
7460 (set_attr "length" "8")
7461 (set_attr "type" "multiple")]
7462 )
7463
7464 (define_insn_and_split "*arm_cmpdi_unsigned"
7465 [(set (reg:CC_CZ CC_REGNUM)
7466 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7467 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7468
7469 "TARGET_32BIT"
7470 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7471 "&& reload_completed"
7472 [(set (reg:CC CC_REGNUM)
7473 (compare:CC (match_dup 2) (match_dup 3)))
7474 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7475 (set (reg:CC CC_REGNUM)
7476 (compare:CC (match_dup 0) (match_dup 1))))]
7477 {
7478 operands[2] = gen_highpart (SImode, operands[0]);
7479 operands[0] = gen_lowpart (SImode, operands[0]);
7480 if (CONST_INT_P (operands[1]))
7481 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7482 else
7483 operands[3] = gen_highpart (SImode, operands[1]);
7484 operands[1] = gen_lowpart (SImode, operands[1]);
7485 }
7486 [(set_attr "conds" "set")
7487 (set_attr "enabled_for_short_it" "yes,yes,no,*")
7488 (set_attr "arch" "t2,t2,t2,a")
7489 (set_attr "length" "6,6,10,8")
7490 (set_attr "type" "multiple")]
7491 )
7492
7493 (define_insn "*arm_cmpdi_zero"
7494 [(set (reg:CC_Z CC_REGNUM)
7495 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7496 (const_int 0)))
7497 (clobber (match_scratch:SI 1 "=r"))]
7498 "TARGET_32BIT"
7499 "orrs%?\\t%1, %Q0, %R0"
7500 [(set_attr "conds" "set")
7501 (set_attr "type" "logics_reg")]
7502 )
7503
7504 ; This insn allows redundant compares to be removed by cse, nothing should
7505 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7506 ; is deleted later on. The match_dup will match the mode here, so that
7507 ; mode changes of the condition codes aren't lost by this even though we don't
7508 ; specify what they are.
7509
7510 (define_insn "*deleted_compare"
7511 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7512 "TARGET_32BIT"
7513 "\\t%@ deleted compare"
7514 [(set_attr "conds" "set")
7515 (set_attr "length" "0")
7516 (set_attr "type" "no_insn")]
7517 )
7518
7519 \f
7520 ;; Conditional branch insns
7521
7522 (define_expand "cbranch_cc"
7523 [(set (pc)
7524 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7525 (match_operand 2 "" "")])
7526 (label_ref (match_operand 3 "" ""))
7527 (pc)))]
7528 "TARGET_32BIT"
7529 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7530 operands[1], operands[2], NULL_RTX);
7531 operands[2] = const0_rtx;"
7532 )
7533
7534 ;;
7535 ;; Patterns to match conditional branch insns.
7536 ;;
7537
7538 (define_insn "arm_cond_branch"
7539 [(set (pc)
7540 (if_then_else (match_operator 1 "arm_comparison_operator"
7541 [(match_operand 2 "cc_register" "") (const_int 0)])
7542 (label_ref (match_operand 0 "" ""))
7543 (pc)))]
7544 "TARGET_32BIT"
7545 "*
7546 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7547 {
7548 arm_ccfsm_state += 2;
7549 return \"\";
7550 }
7551 return \"b%d1\\t%l0\";
7552 "
7553 [(set_attr "conds" "use")
7554 (set_attr "type" "branch")
7555 (set (attr "length")
7556 (if_then_else
7557 (and (match_test "TARGET_THUMB2")
7558 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7559 (le (minus (match_dup 0) (pc)) (const_int 256))))
7560 (const_int 2)
7561 (const_int 4)))]
7562 )
7563
7564 (define_insn "*arm_cond_branch_reversed"
7565 [(set (pc)
7566 (if_then_else (match_operator 1 "arm_comparison_operator"
7567 [(match_operand 2 "cc_register" "") (const_int 0)])
7568 (pc)
7569 (label_ref (match_operand 0 "" ""))))]
7570 "TARGET_32BIT"
7571 "*
7572 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7573 {
7574 arm_ccfsm_state += 2;
7575 return \"\";
7576 }
7577 return \"b%D1\\t%l0\";
7578 "
7579 [(set_attr "conds" "use")
7580 (set_attr "type" "branch")
7581 (set (attr "length")
7582 (if_then_else
7583 (and (match_test "TARGET_THUMB2")
7584 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7585 (le (minus (match_dup 0) (pc)) (const_int 256))))
7586 (const_int 2)
7587 (const_int 4)))]
7588 )
7589
7590 \f
7591
7592 ; scc insns
7593
7594 (define_expand "cstore_cc"
7595 [(set (match_operand:SI 0 "s_register_operand" "")
7596 (match_operator:SI 1 "" [(match_operand 2 "" "")
7597 (match_operand 3 "" "")]))]
7598 "TARGET_32BIT"
7599 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7600 operands[2], operands[3], NULL_RTX);
7601 operands[3] = const0_rtx;"
7602 )
7603
7604 (define_insn_and_split "*mov_scc"
7605 [(set (match_operand:SI 0 "s_register_operand" "=r")
7606 (match_operator:SI 1 "arm_comparison_operator_mode"
7607 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7608 "TARGET_ARM"
7609 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7610 "TARGET_ARM"
7611 [(set (match_dup 0)
7612 (if_then_else:SI (match_dup 1)
7613 (const_int 1)
7614 (const_int 0)))]
7615 ""
7616 [(set_attr "conds" "use")
7617 (set_attr "length" "8")
7618 (set_attr "type" "multiple")]
7619 )
7620
7621 (define_insn_and_split "*mov_negscc"
7622 [(set (match_operand:SI 0 "s_register_operand" "=r")
7623 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7624 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7625 "TARGET_ARM"
7626 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7627 "TARGET_ARM"
7628 [(set (match_dup 0)
7629 (if_then_else:SI (match_dup 1)
7630 (match_dup 3)
7631 (const_int 0)))]
7632 {
7633 operands[3] = GEN_INT (~0);
7634 }
7635 [(set_attr "conds" "use")
7636 (set_attr "length" "8")
7637 (set_attr "type" "multiple")]
7638 )
7639
7640 (define_insn_and_split "*mov_notscc"
7641 [(set (match_operand:SI 0 "s_register_operand" "=r")
7642 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7643 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7644 "TARGET_ARM"
7645 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7646 "TARGET_ARM"
7647 [(set (match_dup 0)
7648 (if_then_else:SI (match_dup 1)
7649 (match_dup 3)
7650 (match_dup 4)))]
7651 {
7652 operands[3] = GEN_INT (~1);
7653 operands[4] = GEN_INT (~0);
7654 }
7655 [(set_attr "conds" "use")
7656 (set_attr "length" "8")
7657 (set_attr "type" "multiple")]
7658 )
7659
7660 (define_expand "cstoresi4"
7661 [(set (match_operand:SI 0 "s_register_operand" "")
7662 (match_operator:SI 1 "expandable_comparison_operator"
7663 [(match_operand:SI 2 "s_register_operand" "")
7664 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7665 "TARGET_32BIT || TARGET_THUMB1"
7666 "{
7667 rtx op3, scratch, scratch2;
7668
7669 if (!TARGET_THUMB1)
7670 {
7671 if (!arm_add_operand (operands[3], SImode))
7672 operands[3] = force_reg (SImode, operands[3]);
7673 emit_insn (gen_cstore_cc (operands[0], operands[1],
7674 operands[2], operands[3]));
7675 DONE;
7676 }
7677
7678 if (operands[3] == const0_rtx)
7679 {
7680 switch (GET_CODE (operands[1]))
7681 {
7682 case EQ:
7683 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7684 break;
7685
7686 case NE:
7687 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7688 break;
7689
7690 case LE:
7691 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7692 NULL_RTX, 0, OPTAB_WIDEN);
7693 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7694 NULL_RTX, 0, OPTAB_WIDEN);
7695 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7696 operands[0], 1, OPTAB_WIDEN);
7697 break;
7698
7699 case GE:
7700 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7701 NULL_RTX, 1);
7702 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7703 NULL_RTX, 1, OPTAB_WIDEN);
7704 break;
7705
7706 case GT:
7707 scratch = expand_binop (SImode, ashr_optab, operands[2],
7708 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7709 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7710 NULL_RTX, 0, OPTAB_WIDEN);
7711 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7712 0, OPTAB_WIDEN);
7713 break;
7714
7715 /* LT is handled by generic code. No need for unsigned with 0. */
7716 default:
7717 FAIL;
7718 }
7719 DONE;
7720 }
7721
7722 switch (GET_CODE (operands[1]))
7723 {
7724 case EQ:
7725 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7726 NULL_RTX, 0, OPTAB_WIDEN);
7727 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7728 break;
7729
7730 case NE:
7731 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7732 NULL_RTX, 0, OPTAB_WIDEN);
7733 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7734 break;
7735
7736 case LE:
7737 op3 = force_reg (SImode, operands[3]);
7738
7739 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7740 NULL_RTX, 1, OPTAB_WIDEN);
7741 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7742 NULL_RTX, 0, OPTAB_WIDEN);
7743 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7744 op3, operands[2]));
7745 break;
7746
7747 case GE:
7748 op3 = operands[3];
7749 if (!thumb1_cmp_operand (op3, SImode))
7750 op3 = force_reg (SImode, op3);
7751 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7752 NULL_RTX, 0, OPTAB_WIDEN);
7753 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7754 NULL_RTX, 1, OPTAB_WIDEN);
7755 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7756 operands[2], op3));
7757 break;
7758
7759 case LEU:
7760 op3 = force_reg (SImode, operands[3]);
7761 scratch = force_reg (SImode, const0_rtx);
7762 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7763 op3, operands[2]));
7764 break;
7765
7766 case GEU:
7767 op3 = operands[3];
7768 if (!thumb1_cmp_operand (op3, SImode))
7769 op3 = force_reg (SImode, op3);
7770 scratch = force_reg (SImode, const0_rtx);
7771 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7772 operands[2], op3));
7773 break;
7774
7775 case LTU:
7776 op3 = operands[3];
7777 if (!thumb1_cmp_operand (op3, SImode))
7778 op3 = force_reg (SImode, op3);
7779 scratch = gen_reg_rtx (SImode);
7780 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7781 break;
7782
7783 case GTU:
7784 op3 = force_reg (SImode, operands[3]);
7785 scratch = gen_reg_rtx (SImode);
7786 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7787 break;
7788
7789 /* No good sequences for GT, LT. */
7790 default:
7791 FAIL;
7792 }
7793 DONE;
7794 }")
7795
7796 (define_expand "cstorehf4"
7797 [(set (match_operand:SI 0 "s_register_operand")
7798 (match_operator:SI 1 "expandable_comparison_operator"
7799 [(match_operand:HF 2 "s_register_operand")
7800 (match_operand:HF 3 "vfp_compare_operand")]))]
7801 "TARGET_VFP_FP16INST"
7802 {
7803 if (!arm_validize_comparison (&operands[1],
7804 &operands[2],
7805 &operands[3]))
7806 FAIL;
7807
7808 emit_insn (gen_cstore_cc (operands[0], operands[1],
7809 operands[2], operands[3]));
7810 DONE;
7811 }
7812 )
7813
7814 (define_expand "cstoresf4"
7815 [(set (match_operand:SI 0 "s_register_operand" "")
7816 (match_operator:SI 1 "expandable_comparison_operator"
7817 [(match_operand:SF 2 "s_register_operand" "")
7818 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7819 "TARGET_32BIT && TARGET_HARD_FLOAT"
7820 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7821 operands[2], operands[3])); DONE;"
7822 )
7823
7824 (define_expand "cstoredf4"
7825 [(set (match_operand:SI 0 "s_register_operand" "")
7826 (match_operator:SI 1 "expandable_comparison_operator"
7827 [(match_operand:DF 2 "s_register_operand" "")
7828 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7829 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7830 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7831 operands[2], operands[3])); DONE;"
7832 )
7833
7834 (define_expand "cstoredi4"
7835 [(set (match_operand:SI 0 "s_register_operand" "")
7836 (match_operator:SI 1 "expandable_comparison_operator"
7837 [(match_operand:DI 2 "s_register_operand" "")
7838 (match_operand:DI 3 "cmpdi_operand" "")]))]
7839 "TARGET_32BIT"
7840 "{
7841 if (!arm_validize_comparison (&operands[1],
7842 &operands[2],
7843 &operands[3]))
7844 FAIL;
7845 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7846 operands[3]));
7847 DONE;
7848 }"
7849 )
7850
7851 \f
7852 ;; Conditional move insns
7853
7854 (define_expand "movsicc"
7855 [(set (match_operand:SI 0 "s_register_operand" "")
7856 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7857 (match_operand:SI 2 "arm_not_operand" "")
7858 (match_operand:SI 3 "arm_not_operand" "")))]
7859 "TARGET_32BIT"
7860 "
7861 {
7862 enum rtx_code code;
7863 rtx ccreg;
7864
7865 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7866 &XEXP (operands[1], 1)))
7867 FAIL;
7868
7869 code = GET_CODE (operands[1]);
7870 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7871 XEXP (operands[1], 1), NULL_RTX);
7872 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7873 }"
7874 )
7875
7876 (define_expand "movhfcc"
7877 [(set (match_operand:HF 0 "s_register_operand")
7878 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7879 (match_operand:HF 2 "s_register_operand")
7880 (match_operand:HF 3 "s_register_operand")))]
7881 "TARGET_VFP_FP16INST"
7882 "
7883 {
7884 enum rtx_code code = GET_CODE (operands[1]);
7885 rtx ccreg;
7886
7887 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7888 &XEXP (operands[1], 1)))
7889 FAIL;
7890
7891 code = GET_CODE (operands[1]);
7892 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7893 XEXP (operands[1], 1), NULL_RTX);
7894 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7895 }"
7896 )
7897
7898 (define_expand "movsfcc"
7899 [(set (match_operand:SF 0 "s_register_operand" "")
7900 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7901 (match_operand:SF 2 "s_register_operand" "")
7902 (match_operand:SF 3 "s_register_operand" "")))]
7903 "TARGET_32BIT && TARGET_HARD_FLOAT"
7904 "
7905 {
7906 enum rtx_code code = GET_CODE (operands[1]);
7907 rtx ccreg;
7908
7909 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7910 &XEXP (operands[1], 1)))
7911 FAIL;
7912
7913 code = GET_CODE (operands[1]);
7914 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7915 XEXP (operands[1], 1), NULL_RTX);
7916 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7917 }"
7918 )
7919
7920 (define_expand "movdfcc"
7921 [(set (match_operand:DF 0 "s_register_operand" "")
7922 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7923 (match_operand:DF 2 "s_register_operand" "")
7924 (match_operand:DF 3 "s_register_operand" "")))]
7925 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7926 "
7927 {
7928 enum rtx_code code = GET_CODE (operands[1]);
7929 rtx ccreg;
7930
7931 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7932 &XEXP (operands[1], 1)))
7933 FAIL;
7934 code = GET_CODE (operands[1]);
7935 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7936 XEXP (operands[1], 1), NULL_RTX);
7937 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7938 }"
7939 )
7940
7941 (define_insn "*cmov<mode>"
7942 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7943 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7944 [(match_operand 2 "cc_register" "") (const_int 0)])
7945 (match_operand:SDF 3 "s_register_operand"
7946 "<F_constraint>")
7947 (match_operand:SDF 4 "s_register_operand"
7948 "<F_constraint>")))]
7949 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7950 "*
7951 {
7952 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7953 switch (code)
7954 {
7955 case ARM_GE:
7956 case ARM_GT:
7957 case ARM_EQ:
7958 case ARM_VS:
7959 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7960 case ARM_LT:
7961 case ARM_LE:
7962 case ARM_NE:
7963 case ARM_VC:
7964 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7965 default:
7966 gcc_unreachable ();
7967 }
7968 return \"\";
7969 }"
7970 [(set_attr "conds" "use")
7971 (set_attr "type" "fcsel")]
7972 )
7973
7974 (define_insn "*cmovhf"
7975 [(set (match_operand:HF 0 "s_register_operand" "=t")
7976 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7977 [(match_operand 2 "cc_register" "") (const_int 0)])
7978 (match_operand:HF 3 "s_register_operand" "t")
7979 (match_operand:HF 4 "s_register_operand" "t")))]
7980 "TARGET_VFP_FP16INST"
7981 "*
7982 {
7983 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7984 switch (code)
7985 {
7986 case ARM_GE:
7987 case ARM_GT:
7988 case ARM_EQ:
7989 case ARM_VS:
7990 return \"vsel%d1.f16\\t%0, %3, %4\";
7991 case ARM_LT:
7992 case ARM_LE:
7993 case ARM_NE:
7994 case ARM_VC:
7995 return \"vsel%D1.f16\\t%0, %4, %3\";
7996 default:
7997 gcc_unreachable ();
7998 }
7999 return \"\";
8000 }"
8001 [(set_attr "conds" "use")
8002 (set_attr "type" "fcsel")]
8003 )
8004
8005 (define_insn_and_split "*movsicc_insn"
8006 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8007 (if_then_else:SI
8008 (match_operator 3 "arm_comparison_operator"
8009 [(match_operand 4 "cc_register" "") (const_int 0)])
8010 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8011 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8012 "TARGET_ARM"
8013 "@
8014 mov%D3\\t%0, %2
8015 mvn%D3\\t%0, #%B2
8016 mov%d3\\t%0, %1
8017 mvn%d3\\t%0, #%B1
8018 #
8019 #
8020 #
8021 #"
8022 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8023 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8024 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8025 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8026 "&& reload_completed"
8027 [(const_int 0)]
8028 {
8029 enum rtx_code rev_code;
8030 machine_mode mode;
8031 rtx rev_cond;
8032
8033 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8034 operands[3],
8035 gen_rtx_SET (operands[0], operands[1])));
8036
8037 rev_code = GET_CODE (operands[3]);
8038 mode = GET_MODE (operands[4]);
8039 if (mode == CCFPmode || mode == CCFPEmode)
8040 rev_code = reverse_condition_maybe_unordered (rev_code);
8041 else
8042 rev_code = reverse_condition (rev_code);
8043
8044 rev_cond = gen_rtx_fmt_ee (rev_code,
8045 VOIDmode,
8046 operands[4],
8047 const0_rtx);
8048 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8049 rev_cond,
8050 gen_rtx_SET (operands[0], operands[2])));
8051 DONE;
8052 }
8053 [(set_attr "length" "4,4,4,4,8,8,8,8")
8054 (set_attr "conds" "use")
8055 (set_attr_alternative "type"
8056 [(if_then_else (match_operand 2 "const_int_operand" "")
8057 (const_string "mov_imm")
8058 (const_string "mov_reg"))
8059 (const_string "mvn_imm")
8060 (if_then_else (match_operand 1 "const_int_operand" "")
8061 (const_string "mov_imm")
8062 (const_string "mov_reg"))
8063 (const_string "mvn_imm")
8064 (const_string "multiple")
8065 (const_string "multiple")
8066 (const_string "multiple")
8067 (const_string "multiple")])]
8068 )
8069
8070 (define_insn "*movsfcc_soft_insn"
8071 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8072 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8073 [(match_operand 4 "cc_register" "") (const_int 0)])
8074 (match_operand:SF 1 "s_register_operand" "0,r")
8075 (match_operand:SF 2 "s_register_operand" "r,0")))]
8076 "TARGET_ARM && TARGET_SOFT_FLOAT"
8077 "@
8078 mov%D3\\t%0, %2
8079 mov%d3\\t%0, %1"
8080 [(set_attr "conds" "use")
8081 (set_attr "type" "mov_reg")]
8082 )
8083
8084 \f
8085 ;; Jump and linkage insns
8086
8087 (define_expand "jump"
8088 [(set (pc)
8089 (label_ref (match_operand 0 "" "")))]
8090 "TARGET_EITHER"
8091 ""
8092 )
8093
8094 (define_insn "*arm_jump"
8095 [(set (pc)
8096 (label_ref (match_operand 0 "" "")))]
8097 "TARGET_32BIT"
8098 "*
8099 {
8100 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8101 {
8102 arm_ccfsm_state += 2;
8103 return \"\";
8104 }
8105 return \"b%?\\t%l0\";
8106 }
8107 "
8108 [(set_attr "predicable" "yes")
8109 (set (attr "length")
8110 (if_then_else
8111 (and (match_test "TARGET_THUMB2")
8112 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8113 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8114 (const_int 2)
8115 (const_int 4)))
8116 (set_attr "type" "branch")]
8117 )
8118
8119 (define_expand "call"
8120 [(parallel [(call (match_operand 0 "memory_operand" "")
8121 (match_operand 1 "general_operand" ""))
8122 (use (match_operand 2 "" ""))
8123 (clobber (reg:SI LR_REGNUM))])]
8124 "TARGET_EITHER"
8125 "
8126 {
8127 rtx callee, pat;
8128 tree addr = MEM_EXPR (operands[0]);
8129
8130 /* In an untyped call, we can get NULL for operand 2. */
8131 if (operands[2] == NULL_RTX)
8132 operands[2] = const0_rtx;
8133
8134 /* Decide if we should generate indirect calls by loading the
8135 32-bit address of the callee into a register before performing the
8136 branch and link. */
8137 callee = XEXP (operands[0], 0);
8138 if (GET_CODE (callee) == SYMBOL_REF
8139 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8140 : !REG_P (callee))
8141 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8142
8143 if (detect_cmse_nonsecure_call (addr))
8144 {
8145 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8146 operands[2]);
8147 emit_call_insn (pat);
8148 }
8149 else
8150 {
8151 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8152 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8153 }
8154 DONE;
8155 }"
8156 )
8157
8158 (define_expand "call_internal"
8159 [(parallel [(call (match_operand 0 "memory_operand" "")
8160 (match_operand 1 "general_operand" ""))
8161 (use (match_operand 2 "" ""))
8162 (clobber (reg:SI LR_REGNUM))])])
8163
8164 (define_expand "nonsecure_call_internal"
8165 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8166 UNSPEC_NONSECURE_MEM)
8167 (match_operand 1 "general_operand" ""))
8168 (use (match_operand 2 "" ""))
8169 (clobber (reg:SI LR_REGNUM))])]
8170 "use_cmse"
8171 "
8172 {
8173 rtx tmp;
8174 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8175 gen_rtx_REG (SImode, R4_REGNUM),
8176 SImode);
8177
8178 operands[0] = replace_equiv_address (operands[0], tmp);
8179 }")
8180
8181 (define_insn "*call_reg_armv5"
8182 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8183 (match_operand 1 "" ""))
8184 (use (match_operand 2 "" ""))
8185 (clobber (reg:SI LR_REGNUM))]
8186 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8187 "blx%?\\t%0"
8188 [(set_attr "type" "call")]
8189 )
8190
8191 (define_insn "*call_reg_arm"
8192 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8193 (match_operand 1 "" ""))
8194 (use (match_operand 2 "" ""))
8195 (clobber (reg:SI LR_REGNUM))]
8196 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
8197 "*
8198 return output_call (operands);
8199 "
8200 ;; length is worst case, normally it is only two
8201 [(set_attr "length" "12")
8202 (set_attr "type" "call")]
8203 )
8204
8205
8206 (define_expand "call_value"
8207 [(parallel [(set (match_operand 0 "" "")
8208 (call (match_operand 1 "memory_operand" "")
8209 (match_operand 2 "general_operand" "")))
8210 (use (match_operand 3 "" ""))
8211 (clobber (reg:SI LR_REGNUM))])]
8212 "TARGET_EITHER"
8213 "
8214 {
8215 rtx pat, callee;
8216 tree addr = MEM_EXPR (operands[1]);
8217
8218 /* In an untyped call, we can get NULL for operand 2. */
8219 if (operands[3] == 0)
8220 operands[3] = const0_rtx;
8221
8222 /* Decide if we should generate indirect calls by loading the
8223 32-bit address of the callee into a register before performing the
8224 branch and link. */
8225 callee = XEXP (operands[1], 0);
8226 if (GET_CODE (callee) == SYMBOL_REF
8227 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8228 : !REG_P (callee))
8229 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8230
8231 if (detect_cmse_nonsecure_call (addr))
8232 {
8233 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8234 operands[2], operands[3]);
8235 emit_call_insn (pat);
8236 }
8237 else
8238 {
8239 pat = gen_call_value_internal (operands[0], operands[1],
8240 operands[2], operands[3]);
8241 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8242 }
8243 DONE;
8244 }"
8245 )
8246
8247 (define_expand "call_value_internal"
8248 [(parallel [(set (match_operand 0 "" "")
8249 (call (match_operand 1 "memory_operand" "")
8250 (match_operand 2 "general_operand" "")))
8251 (use (match_operand 3 "" ""))
8252 (clobber (reg:SI LR_REGNUM))])])
8253
8254 (define_expand "nonsecure_call_value_internal"
8255 [(parallel [(set (match_operand 0 "" "")
8256 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8257 UNSPEC_NONSECURE_MEM)
8258 (match_operand 2 "general_operand" "")))
8259 (use (match_operand 3 "" ""))
8260 (clobber (reg:SI LR_REGNUM))])]
8261 "use_cmse"
8262 "
8263 {
8264 rtx tmp;
8265 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8266 gen_rtx_REG (SImode, R4_REGNUM),
8267 SImode);
8268
8269 operands[1] = replace_equiv_address (operands[1], tmp);
8270 }")
8271
8272 (define_insn "*call_value_reg_armv5"
8273 [(set (match_operand 0 "" "")
8274 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8275 (match_operand 2 "" "")))
8276 (use (match_operand 3 "" ""))
8277 (clobber (reg:SI LR_REGNUM))]
8278 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
8279 "blx%?\\t%1"
8280 [(set_attr "type" "call")]
8281 )
8282
8283 (define_insn "*call_value_reg_arm"
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 "*
8291 return output_call (&operands[1]);
8292 "
8293 [(set_attr "length" "12")
8294 (set_attr "type" "call")]
8295 )
8296
8297 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8298 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8299
8300 (define_insn "*call_symbol"
8301 [(call (mem:SI (match_operand:SI 0 "" ""))
8302 (match_operand 1 "" ""))
8303 (use (match_operand 2 "" ""))
8304 (clobber (reg:SI LR_REGNUM))]
8305 "TARGET_32BIT
8306 && !SIBLING_CALL_P (insn)
8307 && (GET_CODE (operands[0]) == SYMBOL_REF)
8308 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8309 "*
8310 {
8311 rtx op = operands[0];
8312
8313 /* Switch mode now when possible. */
8314 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8315 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8316 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8317
8318 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8319 }"
8320 [(set_attr "type" "call")]
8321 )
8322
8323 (define_insn "*call_value_symbol"
8324 [(set (match_operand 0 "" "")
8325 (call (mem:SI (match_operand:SI 1 "" ""))
8326 (match_operand:SI 2 "" "")))
8327 (use (match_operand 3 "" ""))
8328 (clobber (reg:SI LR_REGNUM))]
8329 "TARGET_32BIT
8330 && !SIBLING_CALL_P (insn)
8331 && (GET_CODE (operands[1]) == SYMBOL_REF)
8332 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8333 "*
8334 {
8335 rtx op = operands[1];
8336
8337 /* Switch mode now when possible. */
8338 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8339 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8340 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8341
8342 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8343 }"
8344 [(set_attr "type" "call")]
8345 )
8346
8347 (define_expand "sibcall_internal"
8348 [(parallel [(call (match_operand 0 "memory_operand" "")
8349 (match_operand 1 "general_operand" ""))
8350 (return)
8351 (use (match_operand 2 "" ""))])])
8352
8353 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8354 (define_expand "sibcall"
8355 [(parallel [(call (match_operand 0 "memory_operand" "")
8356 (match_operand 1 "general_operand" ""))
8357 (return)
8358 (use (match_operand 2 "" ""))])]
8359 "TARGET_32BIT"
8360 "
8361 {
8362 rtx pat;
8363
8364 if ((!REG_P (XEXP (operands[0], 0))
8365 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8366 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8367 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8368 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8369
8370 if (operands[2] == NULL_RTX)
8371 operands[2] = const0_rtx;
8372
8373 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8374 arm_emit_call_insn (pat, operands[0], true);
8375 DONE;
8376 }"
8377 )
8378
8379 (define_expand "sibcall_value_internal"
8380 [(parallel [(set (match_operand 0 "" "")
8381 (call (match_operand 1 "memory_operand" "")
8382 (match_operand 2 "general_operand" "")))
8383 (return)
8384 (use (match_operand 3 "" ""))])])
8385
8386 (define_expand "sibcall_value"
8387 [(parallel [(set (match_operand 0 "" "")
8388 (call (match_operand 1 "memory_operand" "")
8389 (match_operand 2 "general_operand" "")))
8390 (return)
8391 (use (match_operand 3 "" ""))])]
8392 "TARGET_32BIT"
8393 "
8394 {
8395 rtx pat;
8396
8397 if ((!REG_P (XEXP (operands[1], 0))
8398 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8399 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8400 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8401 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8402
8403 if (operands[3] == NULL_RTX)
8404 operands[3] = const0_rtx;
8405
8406 pat = gen_sibcall_value_internal (operands[0], operands[1],
8407 operands[2], operands[3]);
8408 arm_emit_call_insn (pat, operands[1], true);
8409 DONE;
8410 }"
8411 )
8412
8413 (define_insn "*sibcall_insn"
8414 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8415 (match_operand 1 "" ""))
8416 (return)
8417 (use (match_operand 2 "" ""))]
8418 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8419 "*
8420 if (which_alternative == 1)
8421 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8422 else
8423 {
8424 if (arm_arch5t || arm_arch4t)
8425 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8426 else
8427 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8428 }
8429 "
8430 [(set_attr "type" "call")]
8431 )
8432
8433 (define_insn "*sibcall_value_insn"
8434 [(set (match_operand 0 "" "")
8435 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8436 (match_operand 2 "" "")))
8437 (return)
8438 (use (match_operand 3 "" ""))]
8439 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8440 "*
8441 if (which_alternative == 1)
8442 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8443 else
8444 {
8445 if (arm_arch5t || arm_arch4t)
8446 return \"bx%?\\t%1\";
8447 else
8448 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8449 }
8450 "
8451 [(set_attr "type" "call")]
8452 )
8453
8454 (define_expand "<return_str>return"
8455 [(RETURNS)]
8456 "(TARGET_ARM || (TARGET_THUMB2
8457 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8458 && !IS_STACKALIGN (arm_current_func_type ())))
8459 <return_cond_false>"
8460 "
8461 {
8462 if (TARGET_THUMB2)
8463 {
8464 thumb2_expand_return (<return_simple_p>);
8465 DONE;
8466 }
8467 }
8468 "
8469 )
8470
8471 ;; Often the return insn will be the same as loading from memory, so set attr
8472 (define_insn "*arm_return"
8473 [(return)]
8474 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8475 "*
8476 {
8477 if (arm_ccfsm_state == 2)
8478 {
8479 arm_ccfsm_state += 2;
8480 return \"\";
8481 }
8482 return output_return_instruction (const_true_rtx, true, false, false);
8483 }"
8484 [(set_attr "type" "load_4")
8485 (set_attr "length" "12")
8486 (set_attr "predicable" "yes")]
8487 )
8488
8489 (define_insn "*cond_<return_str>return"
8490 [(set (pc)
8491 (if_then_else (match_operator 0 "arm_comparison_operator"
8492 [(match_operand 1 "cc_register" "") (const_int 0)])
8493 (RETURNS)
8494 (pc)))]
8495 "TARGET_ARM <return_cond_true>"
8496 "*
8497 {
8498 if (arm_ccfsm_state == 2)
8499 {
8500 arm_ccfsm_state += 2;
8501 return \"\";
8502 }
8503 return output_return_instruction (operands[0], true, false,
8504 <return_simple_p>);
8505 }"
8506 [(set_attr "conds" "use")
8507 (set_attr "length" "12")
8508 (set_attr "type" "load_4")]
8509 )
8510
8511 (define_insn "*cond_<return_str>return_inverted"
8512 [(set (pc)
8513 (if_then_else (match_operator 0 "arm_comparison_operator"
8514 [(match_operand 1 "cc_register" "") (const_int 0)])
8515 (pc)
8516 (RETURNS)))]
8517 "TARGET_ARM <return_cond_true>"
8518 "*
8519 {
8520 if (arm_ccfsm_state == 2)
8521 {
8522 arm_ccfsm_state += 2;
8523 return \"\";
8524 }
8525 return output_return_instruction (operands[0], true, true,
8526 <return_simple_p>);
8527 }"
8528 [(set_attr "conds" "use")
8529 (set_attr "length" "12")
8530 (set_attr "type" "load_4")]
8531 )
8532
8533 (define_insn "*arm_simple_return"
8534 [(simple_return)]
8535 "TARGET_ARM"
8536 "*
8537 {
8538 if (arm_ccfsm_state == 2)
8539 {
8540 arm_ccfsm_state += 2;
8541 return \"\";
8542 }
8543 return output_return_instruction (const_true_rtx, true, false, true);
8544 }"
8545 [(set_attr "type" "branch")
8546 (set_attr "length" "4")
8547 (set_attr "predicable" "yes")]
8548 )
8549
8550 ;; Generate a sequence of instructions to determine if the processor is
8551 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8552 ;; mask.
8553
8554 (define_expand "return_addr_mask"
8555 [(set (match_dup 1)
8556 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8557 (const_int 0)))
8558 (set (match_operand:SI 0 "s_register_operand" "")
8559 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8560 (const_int -1)
8561 (const_int 67108860)))] ; 0x03fffffc
8562 "TARGET_ARM"
8563 "
8564 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8565 ")
8566
8567 (define_insn "*check_arch2"
8568 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8569 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8570 (const_int 0)))]
8571 "TARGET_ARM"
8572 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8573 [(set_attr "length" "8")
8574 (set_attr "conds" "set")
8575 (set_attr "type" "multiple")]
8576 )
8577
8578 ;; Call subroutine returning any type.
8579
8580 (define_expand "untyped_call"
8581 [(parallel [(call (match_operand 0 "" "")
8582 (const_int 0))
8583 (match_operand 1 "" "")
8584 (match_operand 2 "" "")])]
8585 "TARGET_EITHER"
8586 "
8587 {
8588 int i;
8589 rtx par = gen_rtx_PARALLEL (VOIDmode,
8590 rtvec_alloc (XVECLEN (operands[2], 0)));
8591 rtx addr = gen_reg_rtx (Pmode);
8592 rtx mem;
8593 int size = 0;
8594
8595 emit_move_insn (addr, XEXP (operands[1], 0));
8596 mem = change_address (operands[1], BLKmode, addr);
8597
8598 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8599 {
8600 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8601
8602 /* Default code only uses r0 as a return value, but we could
8603 be using anything up to 4 registers. */
8604 if (REGNO (src) == R0_REGNUM)
8605 src = gen_rtx_REG (TImode, R0_REGNUM);
8606
8607 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8608 GEN_INT (size));
8609 size += GET_MODE_SIZE (GET_MODE (src));
8610 }
8611
8612 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8613
8614 size = 0;
8615
8616 for (i = 0; i < XVECLEN (par, 0); i++)
8617 {
8618 HOST_WIDE_INT offset = 0;
8619 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8620
8621 if (size != 0)
8622 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8623
8624 mem = change_address (mem, GET_MODE (reg), NULL);
8625 if (REGNO (reg) == R0_REGNUM)
8626 {
8627 /* On thumb we have to use a write-back instruction. */
8628 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8629 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8630 size = TARGET_ARM ? 16 : 0;
8631 }
8632 else
8633 {
8634 emit_move_insn (mem, reg);
8635 size = GET_MODE_SIZE (GET_MODE (reg));
8636 }
8637 }
8638
8639 /* The optimizer does not know that the call sets the function value
8640 registers we stored in the result block. We avoid problems by
8641 claiming that all hard registers are used and clobbered at this
8642 point. */
8643 emit_insn (gen_blockage ());
8644
8645 DONE;
8646 }"
8647 )
8648
8649 (define_expand "untyped_return"
8650 [(match_operand:BLK 0 "memory_operand" "")
8651 (match_operand 1 "" "")]
8652 "TARGET_EITHER"
8653 "
8654 {
8655 int i;
8656 rtx addr = gen_reg_rtx (Pmode);
8657 rtx mem;
8658 int size = 0;
8659
8660 emit_move_insn (addr, XEXP (operands[0], 0));
8661 mem = change_address (operands[0], BLKmode, addr);
8662
8663 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8664 {
8665 HOST_WIDE_INT offset = 0;
8666 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8667
8668 if (size != 0)
8669 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8670
8671 mem = change_address (mem, GET_MODE (reg), NULL);
8672 if (REGNO (reg) == R0_REGNUM)
8673 {
8674 /* On thumb we have to use a write-back instruction. */
8675 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8676 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8677 size = TARGET_ARM ? 16 : 0;
8678 }
8679 else
8680 {
8681 emit_move_insn (reg, mem);
8682 size = GET_MODE_SIZE (GET_MODE (reg));
8683 }
8684 }
8685
8686 /* Emit USE insns before the return. */
8687 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8688 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8689
8690 /* Construct the return. */
8691 expand_naked_return ();
8692
8693 DONE;
8694 }"
8695 )
8696
8697 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8698 ;; all of memory. This blocks insns from being moved across this point.
8699
8700 (define_insn "blockage"
8701 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8702 "TARGET_EITHER"
8703 ""
8704 [(set_attr "length" "0")
8705 (set_attr "type" "block")]
8706 )
8707
8708 ;; Since we hard code r0 here use the 'o' constraint to prevent
8709 ;; provoking undefined behaviour in the hardware with putting out
8710 ;; auto-increment operations with potentially r0 as the base register.
8711 (define_insn "probe_stack"
8712 [(set (match_operand:SI 0 "memory_operand" "=o")
8713 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8714 "TARGET_32BIT"
8715 "str%?\\tr0, %0"
8716 [(set_attr "type" "store_4")
8717 (set_attr "predicable" "yes")]
8718 )
8719
8720 (define_insn "probe_stack_range"
8721 [(set (match_operand:SI 0 "register_operand" "=r")
8722 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8723 (match_operand:SI 2 "register_operand" "r")]
8724 VUNSPEC_PROBE_STACK_RANGE))]
8725 "TARGET_32BIT"
8726 {
8727 return output_probe_stack_range (operands[0], operands[2]);
8728 }
8729 [(set_attr "type" "multiple")
8730 (set_attr "conds" "clob")]
8731 )
8732
8733 ;; Named patterns for stack smashing protection.
8734 (define_expand "stack_protect_combined_set"
8735 [(parallel
8736 [(set (match_operand:SI 0 "memory_operand" "")
8737 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8738 UNSPEC_SP_SET))
8739 (clobber (match_scratch:SI 2 ""))
8740 (clobber (match_scratch:SI 3 ""))])]
8741 ""
8742 ""
8743 )
8744
8745 ;; Use a separate insn from the above expand to be able to have the mem outside
8746 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8747 ;; try to reload the guard since we need to control how PIC access is done in
8748 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8749 ;; legitimize_pic_address ()).
8750 (define_insn_and_split "*stack_protect_combined_set_insn"
8751 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8752 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8753 UNSPEC_SP_SET))
8754 (clobber (match_scratch:SI 2 "=&l,&r"))
8755 (clobber (match_scratch:SI 3 "=&l,&r"))]
8756 ""
8757 "#"
8758 "reload_completed"
8759 [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))]
8760 UNSPEC_SP_SET))
8761 (clobber (match_dup 2))])]
8762 "
8763 {
8764 if (flag_pic)
8765 {
8766 /* Forces recomputing of GOT base now. */
8767 legitimize_pic_address (operands[1], SImode, operands[2], operands[3],
8768 true /*compute_now*/);
8769 }
8770 else
8771 {
8772 if (address_operand (operands[1], SImode))
8773 operands[2] = operands[1];
8774 else
8775 {
8776 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8777 emit_move_insn (operands[2], mem);
8778 }
8779 }
8780 }"
8781 [(set_attr "arch" "t1,32")]
8782 )
8783
8784 (define_insn "*stack_protect_set_insn"
8785 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8786 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))]
8787 UNSPEC_SP_SET))
8788 (clobber (match_dup 1))]
8789 ""
8790 "@
8791 ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1,#0
8792 ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1,#0"
8793 [(set_attr "length" "8,12")
8794 (set_attr "conds" "clob,nocond")
8795 (set_attr "type" "multiple")
8796 (set_attr "arch" "t1,32")]
8797 )
8798
8799 (define_expand "stack_protect_combined_test"
8800 [(parallel
8801 [(set (pc)
8802 (if_then_else
8803 (eq (match_operand:SI 0 "memory_operand" "")
8804 (unspec:SI [(match_operand:SI 1 "guard_operand" "")]
8805 UNSPEC_SP_TEST))
8806 (label_ref (match_operand 2))
8807 (pc)))
8808 (clobber (match_scratch:SI 3 ""))
8809 (clobber (match_scratch:SI 4 ""))
8810 (clobber (reg:CC CC_REGNUM))])]
8811 ""
8812 ""
8813 )
8814
8815 ;; Use a separate insn from the above expand to be able to have the mem outside
8816 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8817 ;; try to reload the guard since we need to control how PIC access is done in
8818 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8819 ;; legitimize_pic_address ()).
8820 (define_insn_and_split "*stack_protect_combined_test_insn"
8821 [(set (pc)
8822 (if_then_else
8823 (eq (match_operand:SI 0 "memory_operand" "m,m")
8824 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8825 UNSPEC_SP_TEST))
8826 (label_ref (match_operand 2))
8827 (pc)))
8828 (clobber (match_scratch:SI 3 "=&l,&r"))
8829 (clobber (match_scratch:SI 4 "=&l,&r"))
8830 (clobber (reg:CC CC_REGNUM))]
8831 ""
8832 "#"
8833 "reload_completed"
8834 [(const_int 0)]
8835 {
8836 rtx eq;
8837
8838 if (flag_pic)
8839 {
8840 /* Forces recomputing of GOT base now. */
8841 legitimize_pic_address (operands[1], SImode, operands[3], operands[4],
8842 true /*compute_now*/);
8843 }
8844 else
8845 {
8846 if (address_operand (operands[1], SImode))
8847 operands[3] = operands[1];
8848 else
8849 {
8850 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8851 emit_move_insn (operands[3], mem);
8852 }
8853 }
8854 if (TARGET_32BIT)
8855 {
8856 emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0],
8857 operands[3]));
8858 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
8859 eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx);
8860 emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg));
8861 }
8862 else
8863 {
8864 emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0],
8865 operands[3]));
8866 eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
8867 emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx,
8868 operands[2]));
8869 }
8870 DONE;
8871 }
8872 [(set_attr "arch" "t1,32")]
8873 )
8874
8875 (define_insn "arm_stack_protect_test_insn"
8876 [(set (reg:CC_Z CC_REGNUM)
8877 (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m")
8878 (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))]
8879 UNSPEC_SP_TEST)
8880 (const_int 0)))
8881 (clobber (match_operand:SI 0 "register_operand" "=&l,&r"))
8882 (clobber (match_dup 2))]
8883 "TARGET_32BIT"
8884 "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0"
8885 [(set_attr "length" "8,12")
8886 (set_attr "conds" "set")
8887 (set_attr "type" "multiple")
8888 (set_attr "arch" "t,32")]
8889 )
8890
8891 (define_expand "casesi"
8892 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8893 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8894 (match_operand:SI 2 "const_int_operand" "") ; total range
8895 (match_operand:SI 3 "" "") ; table label
8896 (match_operand:SI 4 "" "")] ; Out of range label
8897 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8898 "
8899 {
8900 enum insn_code code;
8901 if (operands[1] != const0_rtx)
8902 {
8903 rtx reg = gen_reg_rtx (SImode);
8904
8905 emit_insn (gen_addsi3 (reg, operands[0],
8906 gen_int_mode (-INTVAL (operands[1]),
8907 SImode)));
8908 operands[0] = reg;
8909 }
8910
8911 if (TARGET_ARM)
8912 code = CODE_FOR_arm_casesi_internal;
8913 else if (TARGET_THUMB1)
8914 code = CODE_FOR_thumb1_casesi_internal_pic;
8915 else if (flag_pic)
8916 code = CODE_FOR_thumb2_casesi_internal_pic;
8917 else
8918 code = CODE_FOR_thumb2_casesi_internal;
8919
8920 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8921 operands[2] = force_reg (SImode, operands[2]);
8922
8923 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8924 operands[3], operands[4]));
8925 DONE;
8926 }"
8927 )
8928
8929 ;; The USE in this pattern is needed to tell flow analysis that this is
8930 ;; a CASESI insn. It has no other purpose.
8931 (define_expand "arm_casesi_internal"
8932 [(parallel [(set (pc)
8933 (if_then_else
8934 (leu (match_operand:SI 0 "s_register_operand")
8935 (match_operand:SI 1 "arm_rhs_operand"))
8936 (match_dup 4)
8937 (label_ref:SI (match_operand 3 ""))))
8938 (clobber (reg:CC CC_REGNUM))
8939 (use (label_ref:SI (match_operand 2 "")))])]
8940 "TARGET_ARM"
8941 {
8942 operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
8943 operands[4] = gen_rtx_PLUS (SImode, operands[4],
8944 gen_rtx_LABEL_REF (SImode, operands[2]));
8945 operands[4] = gen_rtx_MEM (SImode, operands[4]);
8946 MEM_READONLY_P (operands[4]) = 1;
8947 MEM_NOTRAP_P (operands[4]) = 1;
8948 })
8949
8950 (define_insn "*arm_casesi_internal"
8951 [(parallel [(set (pc)
8952 (if_then_else
8953 (leu (match_operand:SI 0 "s_register_operand" "r")
8954 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8955 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8956 (label_ref:SI (match_operand 2 "" ""))))
8957 (label_ref:SI (match_operand 3 "" ""))))
8958 (clobber (reg:CC CC_REGNUM))
8959 (use (label_ref:SI (match_dup 2)))])]
8960 "TARGET_ARM"
8961 "*
8962 if (flag_pic)
8963 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8964 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8965 "
8966 [(set_attr "conds" "clob")
8967 (set_attr "length" "12")
8968 (set_attr "type" "multiple")]
8969 )
8970
8971 (define_expand "indirect_jump"
8972 [(set (pc)
8973 (match_operand:SI 0 "s_register_operand" ""))]
8974 "TARGET_EITHER"
8975 "
8976 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8977 address and use bx. */
8978 if (TARGET_THUMB2)
8979 {
8980 rtx tmp;
8981 tmp = gen_reg_rtx (SImode);
8982 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8983 operands[0] = tmp;
8984 }
8985 "
8986 )
8987
8988 ;; NB Never uses BX.
8989 (define_insn "*arm_indirect_jump"
8990 [(set (pc)
8991 (match_operand:SI 0 "s_register_operand" "r"))]
8992 "TARGET_ARM"
8993 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8994 [(set_attr "predicable" "yes")
8995 (set_attr "type" "branch")]
8996 )
8997
8998 (define_insn "*load_indirect_jump"
8999 [(set (pc)
9000 (match_operand:SI 0 "memory_operand" "m"))]
9001 "TARGET_ARM"
9002 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
9003 [(set_attr "type" "load_4")
9004 (set_attr "pool_range" "4096")
9005 (set_attr "neg_pool_range" "4084")
9006 (set_attr "predicable" "yes")]
9007 )
9008
9009 \f
9010 ;; Misc insns
9011
9012 (define_insn "nop"
9013 [(const_int 0)]
9014 "TARGET_EITHER"
9015 "nop"
9016 [(set (attr "length")
9017 (if_then_else (eq_attr "is_thumb" "yes")
9018 (const_int 2)
9019 (const_int 4)))
9020 (set_attr "type" "mov_reg")]
9021 )
9022
9023 (define_insn "trap"
9024 [(trap_if (const_int 1) (const_int 0))]
9025 ""
9026 "*
9027 if (TARGET_ARM)
9028 return \".inst\\t0xe7f000f0\";
9029 else
9030 return \".inst\\t0xdeff\";
9031 "
9032 [(set (attr "length")
9033 (if_then_else (eq_attr "is_thumb" "yes")
9034 (const_int 2)
9035 (const_int 4)))
9036 (set_attr "type" "trap")
9037 (set_attr "conds" "unconditional")]
9038 )
9039
9040 \f
9041 ;; Patterns to allow combination of arithmetic, cond code and shifts
9042
9043 (define_insn "*<arith_shift_insn>_multsi"
9044 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9045 (SHIFTABLE_OPS:SI
9046 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
9047 (match_operand:SI 3 "power_of_two_operand" ""))
9048 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
9049 "TARGET_32BIT"
9050 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
9051 [(set_attr "predicable" "yes")
9052 (set_attr "shift" "2")
9053 (set_attr "arch" "a,t2")
9054 (set_attr "type" "alu_shift_imm")])
9055
9056 (define_insn "*<arith_shift_insn>_shiftsi"
9057 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9058 (SHIFTABLE_OPS:SI
9059 (match_operator:SI 2 "shift_nomul_operator"
9060 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9061 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
9062 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
9063 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
9064 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
9065 [(set_attr "predicable" "yes")
9066 (set_attr "shift" "3")
9067 (set_attr "arch" "a,t2,a")
9068 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
9069
9070 (define_split
9071 [(set (match_operand:SI 0 "s_register_operand" "")
9072 (match_operator:SI 1 "shiftable_operator"
9073 [(match_operator:SI 2 "shiftable_operator"
9074 [(match_operator:SI 3 "shift_operator"
9075 [(match_operand:SI 4 "s_register_operand" "")
9076 (match_operand:SI 5 "reg_or_int_operand" "")])
9077 (match_operand:SI 6 "s_register_operand" "")])
9078 (match_operand:SI 7 "arm_rhs_operand" "")]))
9079 (clobber (match_operand:SI 8 "s_register_operand" ""))]
9080 "TARGET_32BIT"
9081 [(set (match_dup 8)
9082 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9083 (match_dup 6)]))
9084 (set (match_dup 0)
9085 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
9086 "")
9087
9088 (define_insn "*arith_shiftsi_compare0"
9089 [(set (reg:CC_NOOV CC_REGNUM)
9090 (compare:CC_NOOV
9091 (match_operator:SI 1 "shiftable_operator"
9092 [(match_operator:SI 3 "shift_operator"
9093 [(match_operand:SI 4 "s_register_operand" "r,r")
9094 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9095 (match_operand:SI 2 "s_register_operand" "r,r")])
9096 (const_int 0)))
9097 (set (match_operand:SI 0 "s_register_operand" "=r,r")
9098 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
9099 (match_dup 2)]))]
9100 "TARGET_32BIT"
9101 "%i1s%?\\t%0, %2, %4%S3"
9102 [(set_attr "conds" "set")
9103 (set_attr "shift" "4")
9104 (set_attr "arch" "32,a")
9105 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9106
9107 (define_insn "*arith_shiftsi_compare0_scratch"
9108 [(set (reg:CC_NOOV CC_REGNUM)
9109 (compare:CC_NOOV
9110 (match_operator:SI 1 "shiftable_operator"
9111 [(match_operator:SI 3 "shift_operator"
9112 [(match_operand:SI 4 "s_register_operand" "r,r")
9113 (match_operand:SI 5 "shift_amount_operand" "M,r")])
9114 (match_operand:SI 2 "s_register_operand" "r,r")])
9115 (const_int 0)))
9116 (clobber (match_scratch:SI 0 "=r,r"))]
9117 "TARGET_32BIT"
9118 "%i1s%?\\t%0, %2, %4%S3"
9119 [(set_attr "conds" "set")
9120 (set_attr "shift" "4")
9121 (set_attr "arch" "32,a")
9122 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9123
9124 (define_insn "*sub_shiftsi"
9125 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9126 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
9127 (match_operator:SI 2 "shift_operator"
9128 [(match_operand:SI 3 "s_register_operand" "r,r")
9129 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
9130 "TARGET_32BIT"
9131 "sub%?\\t%0, %1, %3%S2"
9132 [(set_attr "predicable" "yes")
9133 (set_attr "predicable_short_it" "no")
9134 (set_attr "shift" "3")
9135 (set_attr "arch" "32,a")
9136 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
9137
9138 (define_insn "*sub_shiftsi_compare0"
9139 [(set (reg:CC_NOOV CC_REGNUM)
9140 (compare:CC_NOOV
9141 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9142 (match_operator:SI 2 "shift_operator"
9143 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9144 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9145 (const_int 0)))
9146 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9147 (minus:SI (match_dup 1)
9148 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
9149 "TARGET_32BIT"
9150 "subs%?\\t%0, %1, %3%S2"
9151 [(set_attr "conds" "set")
9152 (set_attr "shift" "3")
9153 (set_attr "arch" "32,a,a")
9154 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9155
9156 (define_insn "*sub_shiftsi_compare0_scratch"
9157 [(set (reg:CC_NOOV CC_REGNUM)
9158 (compare:CC_NOOV
9159 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
9160 (match_operator:SI 2 "shift_operator"
9161 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9162 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
9163 (const_int 0)))
9164 (clobber (match_scratch:SI 0 "=r,r,r"))]
9165 "TARGET_32BIT"
9166 "subs%?\\t%0, %1, %3%S2"
9167 [(set_attr "conds" "set")
9168 (set_attr "shift" "3")
9169 (set_attr "arch" "32,a,a")
9170 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9171 \f
9172
9173 (define_insn_and_split "*and_scc"
9174 [(set (match_operand:SI 0 "s_register_operand" "=r")
9175 (and:SI (match_operator:SI 1 "arm_comparison_operator"
9176 [(match_operand 2 "cc_register" "") (const_int 0)])
9177 (match_operand:SI 3 "s_register_operand" "r")))]
9178 "TARGET_ARM"
9179 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
9180 "&& reload_completed"
9181 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
9182 (cond_exec (match_dup 4) (set (match_dup 0)
9183 (and:SI (match_dup 3) (const_int 1))))]
9184 {
9185 machine_mode mode = GET_MODE (operands[2]);
9186 enum rtx_code rc = GET_CODE (operands[1]);
9187
9188 /* Note that operands[4] is the same as operands[1],
9189 but with VOIDmode as the result. */
9190 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9191 if (mode == CCFPmode || mode == CCFPEmode)
9192 rc = reverse_condition_maybe_unordered (rc);
9193 else
9194 rc = reverse_condition (rc);
9195 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9196 }
9197 [(set_attr "conds" "use")
9198 (set_attr "type" "multiple")
9199 (set_attr "length" "8")]
9200 )
9201
9202 (define_insn_and_split "*ior_scc"
9203 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9204 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
9205 [(match_operand 2 "cc_register" "") (const_int 0)])
9206 (match_operand:SI 3 "s_register_operand" "0,?r")))]
9207 "TARGET_ARM"
9208 "@
9209 orr%d1\\t%0, %3, #1
9210 #"
9211 "&& reload_completed
9212 && REGNO (operands [0]) != REGNO (operands[3])"
9213 ;; && which_alternative == 1
9214 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
9215 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
9216 (cond_exec (match_dup 4) (set (match_dup 0)
9217 (ior:SI (match_dup 3) (const_int 1))))]
9218 {
9219 machine_mode mode = GET_MODE (operands[2]);
9220 enum rtx_code rc = GET_CODE (operands[1]);
9221
9222 /* Note that operands[4] is the same as operands[1],
9223 but with VOIDmode as the result. */
9224 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9225 if (mode == CCFPmode || mode == CCFPEmode)
9226 rc = reverse_condition_maybe_unordered (rc);
9227 else
9228 rc = reverse_condition (rc);
9229 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9230 }
9231 [(set_attr "conds" "use")
9232 (set_attr "length" "4,8")
9233 (set_attr "type" "logic_imm,multiple")]
9234 )
9235
9236 ; A series of splitters for the compare_scc pattern below. Note that
9237 ; order is important.
9238 (define_split
9239 [(set (match_operand:SI 0 "s_register_operand" "")
9240 (lt: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) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9245
9246 (define_split
9247 [(set (match_operand:SI 0 "s_register_operand" "")
9248 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9249 (const_int 0)))
9250 (clobber (reg:CC CC_REGNUM))]
9251 "TARGET_32BIT && reload_completed"
9252 [(set (match_dup 0) (not:SI (match_dup 1)))
9253 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9254
9255 (define_split
9256 [(set (match_operand:SI 0 "s_register_operand" "")
9257 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9258 (const_int 0)))
9259 (clobber (reg:CC CC_REGNUM))]
9260 "arm_arch5t && TARGET_32BIT"
9261 [(set (match_dup 0) (clz:SI (match_dup 1)))
9262 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9263 )
9264
9265 (define_split
9266 [(set (match_operand:SI 0 "s_register_operand" "")
9267 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9268 (const_int 0)))
9269 (clobber (reg:CC CC_REGNUM))]
9270 "TARGET_32BIT && reload_completed"
9271 [(parallel
9272 [(set (reg:CC CC_REGNUM)
9273 (compare:CC (const_int 1) (match_dup 1)))
9274 (set (match_dup 0)
9275 (minus:SI (const_int 1) (match_dup 1)))])
9276 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9277 (set (match_dup 0) (const_int 0)))])
9278
9279 (define_split
9280 [(set (match_operand:SI 0 "s_register_operand" "")
9281 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9282 (match_operand:SI 2 "const_int_operand" "")))
9283 (clobber (reg:CC CC_REGNUM))]
9284 "TARGET_32BIT && reload_completed"
9285 [(parallel
9286 [(set (reg:CC CC_REGNUM)
9287 (compare:CC (match_dup 1) (match_dup 2)))
9288 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9289 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9290 (set (match_dup 0) (const_int 1)))]
9291 {
9292 operands[3] = gen_int_mode (-INTVAL (operands[2]), SImode);
9293 })
9294
9295 (define_split
9296 [(set (match_operand:SI 0 "s_register_operand" "")
9297 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9298 (match_operand:SI 2 "arm_add_operand" "")))
9299 (clobber (reg:CC CC_REGNUM))]
9300 "TARGET_32BIT && reload_completed"
9301 [(parallel
9302 [(set (reg:CC_NOOV CC_REGNUM)
9303 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9304 (const_int 0)))
9305 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9306 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9307 (set (match_dup 0) (const_int 1)))])
9308
9309 (define_insn_and_split "*compare_scc"
9310 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9311 (match_operator:SI 1 "arm_comparison_operator"
9312 [(match_operand:SI 2 "s_register_operand" "r,r")
9313 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9314 (clobber (reg:CC CC_REGNUM))]
9315 "TARGET_32BIT"
9316 "#"
9317 "&& reload_completed"
9318 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9319 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9320 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9321 {
9322 rtx tmp1;
9323 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9324 operands[2], operands[3]);
9325 enum rtx_code rc = GET_CODE (operands[1]);
9326
9327 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9328
9329 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9330 if (mode == CCFPmode || mode == CCFPEmode)
9331 rc = reverse_condition_maybe_unordered (rc);
9332 else
9333 rc = reverse_condition (rc);
9334 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9335 }
9336 [(set_attr "type" "multiple")]
9337 )
9338
9339 ;; Attempt to improve the sequence generated by the compare_scc splitters
9340 ;; not to use conditional execution.
9341
9342 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9343 ;; clz Rd, reg1
9344 ;; lsr Rd, Rd, #5
9345 (define_peephole2
9346 [(set (reg:CC CC_REGNUM)
9347 (compare:CC (match_operand:SI 1 "register_operand" "")
9348 (const_int 0)))
9349 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9350 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9351 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9352 (set (match_dup 0) (const_int 1)))]
9353 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9354 [(set (match_dup 0) (clz:SI (match_dup 1)))
9355 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9356 )
9357
9358 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9359 ;; negs Rd, reg1
9360 ;; adc Rd, Rd, reg1
9361 (define_peephole2
9362 [(set (reg:CC CC_REGNUM)
9363 (compare:CC (match_operand:SI 1 "register_operand" "")
9364 (const_int 0)))
9365 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9366 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9367 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9368 (set (match_dup 0) (const_int 1)))
9369 (match_scratch:SI 2 "r")]
9370 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9371 [(parallel
9372 [(set (reg:CC CC_REGNUM)
9373 (compare:CC (const_int 0) (match_dup 1)))
9374 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9375 (set (match_dup 0)
9376 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9377 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9378 )
9379
9380 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9381 ;; sub Rd, Reg1, reg2
9382 ;; clz Rd, Rd
9383 ;; lsr Rd, Rd, #5
9384 (define_peephole2
9385 [(set (reg:CC CC_REGNUM)
9386 (compare:CC (match_operand:SI 1 "register_operand" "")
9387 (match_operand:SI 2 "arm_rhs_operand" "")))
9388 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9389 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9390 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9391 (set (match_dup 0) (const_int 1)))]
9392 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9393 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9394 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9395 (set (match_dup 0) (clz:SI (match_dup 0)))
9396 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9397 )
9398
9399
9400 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9401 ;; sub T1, Reg1, reg2
9402 ;; negs Rd, T1
9403 ;; adc Rd, Rd, T1
9404 (define_peephole2
9405 [(set (reg:CC CC_REGNUM)
9406 (compare:CC (match_operand:SI 1 "register_operand" "")
9407 (match_operand:SI 2 "arm_rhs_operand" "")))
9408 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9409 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9410 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9411 (set (match_dup 0) (const_int 1)))
9412 (match_scratch:SI 3 "r")]
9413 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9414 [(set (match_dup 3) (match_dup 4))
9415 (parallel
9416 [(set (reg:CC CC_REGNUM)
9417 (compare:CC (const_int 0) (match_dup 3)))
9418 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9419 (set (match_dup 0)
9420 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9421 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9422 "
9423 if (CONST_INT_P (operands[2]))
9424 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9425 else
9426 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9427 ")
9428
9429 (define_insn "*cond_move"
9430 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9431 (if_then_else:SI (match_operator 3 "equality_operator"
9432 [(match_operator 4 "arm_comparison_operator"
9433 [(match_operand 5 "cc_register" "") (const_int 0)])
9434 (const_int 0)])
9435 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9436 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9437 "TARGET_ARM"
9438 "*
9439 if (GET_CODE (operands[3]) == NE)
9440 {
9441 if (which_alternative != 1)
9442 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9443 if (which_alternative != 0)
9444 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9445 return \"\";
9446 }
9447 if (which_alternative != 0)
9448 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9449 if (which_alternative != 1)
9450 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9451 return \"\";
9452 "
9453 [(set_attr "conds" "use")
9454 (set_attr_alternative "type"
9455 [(if_then_else (match_operand 2 "const_int_operand" "")
9456 (const_string "mov_imm")
9457 (const_string "mov_reg"))
9458 (if_then_else (match_operand 1 "const_int_operand" "")
9459 (const_string "mov_imm")
9460 (const_string "mov_reg"))
9461 (const_string "multiple")])
9462 (set_attr "length" "4,4,8")]
9463 )
9464
9465 (define_insn "*cond_arith"
9466 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9467 (match_operator:SI 5 "shiftable_operator"
9468 [(match_operator:SI 4 "arm_comparison_operator"
9469 [(match_operand:SI 2 "s_register_operand" "r,r")
9470 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9471 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9472 (clobber (reg:CC CC_REGNUM))]
9473 "TARGET_ARM"
9474 "*
9475 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9476 return \"%i5\\t%0, %1, %2, lsr #31\";
9477
9478 output_asm_insn (\"cmp\\t%2, %3\", operands);
9479 if (GET_CODE (operands[5]) == AND)
9480 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9481 else if (GET_CODE (operands[5]) == MINUS)
9482 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9483 else if (which_alternative != 0)
9484 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9485 return \"%i5%d4\\t%0, %1, #1\";
9486 "
9487 [(set_attr "conds" "clob")
9488 (set_attr "length" "12")
9489 (set_attr "type" "multiple")]
9490 )
9491
9492 (define_insn "*cond_sub"
9493 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9494 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9495 (match_operator:SI 4 "arm_comparison_operator"
9496 [(match_operand:SI 2 "s_register_operand" "r,r")
9497 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9498 (clobber (reg:CC CC_REGNUM))]
9499 "TARGET_ARM"
9500 "*
9501 output_asm_insn (\"cmp\\t%2, %3\", operands);
9502 if (which_alternative != 0)
9503 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9504 return \"sub%d4\\t%0, %1, #1\";
9505 "
9506 [(set_attr "conds" "clob")
9507 (set_attr "length" "8,12")
9508 (set_attr "type" "multiple")]
9509 )
9510
9511 (define_insn "*cmp_ite0"
9512 [(set (match_operand 6 "dominant_cc_register" "")
9513 (compare
9514 (if_then_else:SI
9515 (match_operator 4 "arm_comparison_operator"
9516 [(match_operand:SI 0 "s_register_operand"
9517 "l,l,l,r,r,r,r,r,r")
9518 (match_operand:SI 1 "arm_add_operand"
9519 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9520 (match_operator:SI 5 "arm_comparison_operator"
9521 [(match_operand:SI 2 "s_register_operand"
9522 "l,r,r,l,l,r,r,r,r")
9523 (match_operand:SI 3 "arm_add_operand"
9524 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9525 (const_int 0))
9526 (const_int 0)))]
9527 "TARGET_32BIT"
9528 "*
9529 {
9530 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9531 {
9532 {\"cmp%d5\\t%0, %1\",
9533 \"cmp%d4\\t%2, %3\"},
9534 {\"cmn%d5\\t%0, #%n1\",
9535 \"cmp%d4\\t%2, %3\"},
9536 {\"cmp%d5\\t%0, %1\",
9537 \"cmn%d4\\t%2, #%n3\"},
9538 {\"cmn%d5\\t%0, #%n1\",
9539 \"cmn%d4\\t%2, #%n3\"}
9540 };
9541 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9542 {
9543 {\"cmp\\t%2, %3\",
9544 \"cmp\\t%0, %1\"},
9545 {\"cmp\\t%2, %3\",
9546 \"cmn\\t%0, #%n1\"},
9547 {\"cmn\\t%2, #%n3\",
9548 \"cmp\\t%0, %1\"},
9549 {\"cmn\\t%2, #%n3\",
9550 \"cmn\\t%0, #%n1\"}
9551 };
9552 static const char * const ite[2] =
9553 {
9554 \"it\\t%d5\",
9555 \"it\\t%d4\"
9556 };
9557 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9558 CMP_CMP, CMN_CMP, CMP_CMP,
9559 CMN_CMP, CMP_CMN, CMN_CMN};
9560 int swap =
9561 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9562
9563 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9564 if (TARGET_THUMB2) {
9565 output_asm_insn (ite[swap], operands);
9566 }
9567 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9568 return \"\";
9569 }"
9570 [(set_attr "conds" "set")
9571 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9572 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9573 (set_attr "type" "multiple")
9574 (set_attr_alternative "length"
9575 [(const_int 6)
9576 (const_int 8)
9577 (const_int 8)
9578 (const_int 8)
9579 (const_int 8)
9580 (if_then_else (eq_attr "is_thumb" "no")
9581 (const_int 8)
9582 (const_int 10))
9583 (if_then_else (eq_attr "is_thumb" "no")
9584 (const_int 8)
9585 (const_int 10))
9586 (if_then_else (eq_attr "is_thumb" "no")
9587 (const_int 8)
9588 (const_int 10))
9589 (if_then_else (eq_attr "is_thumb" "no")
9590 (const_int 8)
9591 (const_int 10))])]
9592 )
9593
9594 (define_insn "*cmp_ite1"
9595 [(set (match_operand 6 "dominant_cc_register" "")
9596 (compare
9597 (if_then_else:SI
9598 (match_operator 4 "arm_comparison_operator"
9599 [(match_operand:SI 0 "s_register_operand"
9600 "l,l,l,r,r,r,r,r,r")
9601 (match_operand:SI 1 "arm_add_operand"
9602 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9603 (match_operator:SI 5 "arm_comparison_operator"
9604 [(match_operand:SI 2 "s_register_operand"
9605 "l,r,r,l,l,r,r,r,r")
9606 (match_operand:SI 3 "arm_add_operand"
9607 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9608 (const_int 1))
9609 (const_int 0)))]
9610 "TARGET_32BIT"
9611 "*
9612 {
9613 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9614 {
9615 {\"cmp\\t%0, %1\",
9616 \"cmp\\t%2, %3\"},
9617 {\"cmn\\t%0, #%n1\",
9618 \"cmp\\t%2, %3\"},
9619 {\"cmp\\t%0, %1\",
9620 \"cmn\\t%2, #%n3\"},
9621 {\"cmn\\t%0, #%n1\",
9622 \"cmn\\t%2, #%n3\"}
9623 };
9624 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9625 {
9626 {\"cmp%d4\\t%2, %3\",
9627 \"cmp%D5\\t%0, %1\"},
9628 {\"cmp%d4\\t%2, %3\",
9629 \"cmn%D5\\t%0, #%n1\"},
9630 {\"cmn%d4\\t%2, #%n3\",
9631 \"cmp%D5\\t%0, %1\"},
9632 {\"cmn%d4\\t%2, #%n3\",
9633 \"cmn%D5\\t%0, #%n1\"}
9634 };
9635 static const char * const ite[2] =
9636 {
9637 \"it\\t%d4\",
9638 \"it\\t%D5\"
9639 };
9640 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9641 CMP_CMP, CMN_CMP, CMP_CMP,
9642 CMN_CMP, CMP_CMN, CMN_CMN};
9643 int swap =
9644 comparison_dominates_p (GET_CODE (operands[5]),
9645 reverse_condition (GET_CODE (operands[4])));
9646
9647 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9648 if (TARGET_THUMB2) {
9649 output_asm_insn (ite[swap], operands);
9650 }
9651 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9652 return \"\";
9653 }"
9654 [(set_attr "conds" "set")
9655 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9656 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9657 (set_attr_alternative "length"
9658 [(const_int 6)
9659 (const_int 8)
9660 (const_int 8)
9661 (const_int 8)
9662 (const_int 8)
9663 (if_then_else (eq_attr "is_thumb" "no")
9664 (const_int 8)
9665 (const_int 10))
9666 (if_then_else (eq_attr "is_thumb" "no")
9667 (const_int 8)
9668 (const_int 10))
9669 (if_then_else (eq_attr "is_thumb" "no")
9670 (const_int 8)
9671 (const_int 10))
9672 (if_then_else (eq_attr "is_thumb" "no")
9673 (const_int 8)
9674 (const_int 10))])
9675 (set_attr "type" "multiple")]
9676 )
9677
9678 (define_insn "*cmp_and"
9679 [(set (match_operand 6 "dominant_cc_register" "")
9680 (compare
9681 (and:SI
9682 (match_operator 4 "arm_comparison_operator"
9683 [(match_operand:SI 0 "s_register_operand"
9684 "l,l,l,r,r,r,r,r,r")
9685 (match_operand:SI 1 "arm_add_operand"
9686 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9687 (match_operator:SI 5 "arm_comparison_operator"
9688 [(match_operand:SI 2 "s_register_operand"
9689 "l,r,r,l,l,r,r,r,r")
9690 (match_operand:SI 3 "arm_add_operand"
9691 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9692 (const_int 0)))]
9693 "TARGET_32BIT"
9694 "*
9695 {
9696 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9697 {
9698 {\"cmp%d5\\t%0, %1\",
9699 \"cmp%d4\\t%2, %3\"},
9700 {\"cmn%d5\\t%0, #%n1\",
9701 \"cmp%d4\\t%2, %3\"},
9702 {\"cmp%d5\\t%0, %1\",
9703 \"cmn%d4\\t%2, #%n3\"},
9704 {\"cmn%d5\\t%0, #%n1\",
9705 \"cmn%d4\\t%2, #%n3\"}
9706 };
9707 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9708 {
9709 {\"cmp\\t%2, %3\",
9710 \"cmp\\t%0, %1\"},
9711 {\"cmp\\t%2, %3\",
9712 \"cmn\\t%0, #%n1\"},
9713 {\"cmn\\t%2, #%n3\",
9714 \"cmp\\t%0, %1\"},
9715 {\"cmn\\t%2, #%n3\",
9716 \"cmn\\t%0, #%n1\"}
9717 };
9718 static const char *const ite[2] =
9719 {
9720 \"it\\t%d5\",
9721 \"it\\t%d4\"
9722 };
9723 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9724 CMP_CMP, CMN_CMP, CMP_CMP,
9725 CMN_CMP, CMP_CMN, CMN_CMN};
9726 int swap =
9727 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9728
9729 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9730 if (TARGET_THUMB2) {
9731 output_asm_insn (ite[swap], operands);
9732 }
9733 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9734 return \"\";
9735 }"
9736 [(set_attr "conds" "set")
9737 (set_attr "predicable" "no")
9738 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9739 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9740 (set_attr_alternative "length"
9741 [(const_int 6)
9742 (const_int 8)
9743 (const_int 8)
9744 (const_int 8)
9745 (const_int 8)
9746 (if_then_else (eq_attr "is_thumb" "no")
9747 (const_int 8)
9748 (const_int 10))
9749 (if_then_else (eq_attr "is_thumb" "no")
9750 (const_int 8)
9751 (const_int 10))
9752 (if_then_else (eq_attr "is_thumb" "no")
9753 (const_int 8)
9754 (const_int 10))
9755 (if_then_else (eq_attr "is_thumb" "no")
9756 (const_int 8)
9757 (const_int 10))])
9758 (set_attr "type" "multiple")]
9759 )
9760
9761 (define_insn "*cmp_ior"
9762 [(set (match_operand 6 "dominant_cc_register" "")
9763 (compare
9764 (ior:SI
9765 (match_operator 4 "arm_comparison_operator"
9766 [(match_operand:SI 0 "s_register_operand"
9767 "l,l,l,r,r,r,r,r,r")
9768 (match_operand:SI 1 "arm_add_operand"
9769 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9770 (match_operator:SI 5 "arm_comparison_operator"
9771 [(match_operand:SI 2 "s_register_operand"
9772 "l,r,r,l,l,r,r,r,r")
9773 (match_operand:SI 3 "arm_add_operand"
9774 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9775 (const_int 0)))]
9776 "TARGET_32BIT"
9777 "*
9778 {
9779 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9780 {
9781 {\"cmp\\t%0, %1\",
9782 \"cmp\\t%2, %3\"},
9783 {\"cmn\\t%0, #%n1\",
9784 \"cmp\\t%2, %3\"},
9785 {\"cmp\\t%0, %1\",
9786 \"cmn\\t%2, #%n3\"},
9787 {\"cmn\\t%0, #%n1\",
9788 \"cmn\\t%2, #%n3\"}
9789 };
9790 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9791 {
9792 {\"cmp%D4\\t%2, %3\",
9793 \"cmp%D5\\t%0, %1\"},
9794 {\"cmp%D4\\t%2, %3\",
9795 \"cmn%D5\\t%0, #%n1\"},
9796 {\"cmn%D4\\t%2, #%n3\",
9797 \"cmp%D5\\t%0, %1\"},
9798 {\"cmn%D4\\t%2, #%n3\",
9799 \"cmn%D5\\t%0, #%n1\"}
9800 };
9801 static const char *const ite[2] =
9802 {
9803 \"it\\t%D4\",
9804 \"it\\t%D5\"
9805 };
9806 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9807 CMP_CMP, CMN_CMP, CMP_CMP,
9808 CMN_CMP, CMP_CMN, CMN_CMN};
9809 int swap =
9810 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9811
9812 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9813 if (TARGET_THUMB2) {
9814 output_asm_insn (ite[swap], operands);
9815 }
9816 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9817 return \"\";
9818 }
9819 "
9820 [(set_attr "conds" "set")
9821 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9822 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9823 (set_attr_alternative "length"
9824 [(const_int 6)
9825 (const_int 8)
9826 (const_int 8)
9827 (const_int 8)
9828 (const_int 8)
9829 (if_then_else (eq_attr "is_thumb" "no")
9830 (const_int 8)
9831 (const_int 10))
9832 (if_then_else (eq_attr "is_thumb" "no")
9833 (const_int 8)
9834 (const_int 10))
9835 (if_then_else (eq_attr "is_thumb" "no")
9836 (const_int 8)
9837 (const_int 10))
9838 (if_then_else (eq_attr "is_thumb" "no")
9839 (const_int 8)
9840 (const_int 10))])
9841 (set_attr "type" "multiple")]
9842 )
9843
9844 (define_insn_and_split "*ior_scc_scc"
9845 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9846 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9847 [(match_operand:SI 1 "s_register_operand" "l,r")
9848 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9849 (match_operator:SI 6 "arm_comparison_operator"
9850 [(match_operand:SI 4 "s_register_operand" "l,r")
9851 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9852 (clobber (reg:CC CC_REGNUM))]
9853 "TARGET_32BIT
9854 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9855 != CCmode)"
9856 "#"
9857 "TARGET_32BIT && reload_completed"
9858 [(set (match_dup 7)
9859 (compare
9860 (ior:SI
9861 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9862 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9863 (const_int 0)))
9864 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9865 "operands[7]
9866 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9867 DOM_CC_X_OR_Y),
9868 CC_REGNUM);"
9869 [(set_attr "conds" "clob")
9870 (set_attr "enabled_for_short_it" "yes,no")
9871 (set_attr "length" "16")
9872 (set_attr "type" "multiple")]
9873 )
9874
9875 ; If the above pattern is followed by a CMP insn, then the compare is
9876 ; redundant, since we can rework the conditional instruction that follows.
9877 (define_insn_and_split "*ior_scc_scc_cmp"
9878 [(set (match_operand 0 "dominant_cc_register" "")
9879 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9880 [(match_operand:SI 1 "s_register_operand" "l,r")
9881 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9882 (match_operator:SI 6 "arm_comparison_operator"
9883 [(match_operand:SI 4 "s_register_operand" "l,r")
9884 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9885 (const_int 0)))
9886 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9887 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9888 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9889 "TARGET_32BIT"
9890 "#"
9891 "TARGET_32BIT && reload_completed"
9892 [(set (match_dup 0)
9893 (compare
9894 (ior:SI
9895 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9896 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9897 (const_int 0)))
9898 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9899 ""
9900 [(set_attr "conds" "set")
9901 (set_attr "enabled_for_short_it" "yes,no")
9902 (set_attr "length" "16")
9903 (set_attr "type" "multiple")]
9904 )
9905
9906 (define_insn_and_split "*and_scc_scc"
9907 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9908 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9909 [(match_operand:SI 1 "s_register_operand" "l,r")
9910 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9911 (match_operator:SI 6 "arm_comparison_operator"
9912 [(match_operand:SI 4 "s_register_operand" "l,r")
9913 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9914 (clobber (reg:CC CC_REGNUM))]
9915 "TARGET_32BIT
9916 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9917 != CCmode)"
9918 "#"
9919 "TARGET_32BIT && reload_completed
9920 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9921 != CCmode)"
9922 [(set (match_dup 7)
9923 (compare
9924 (and:SI
9925 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9926 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9927 (const_int 0)))
9928 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9929 "operands[7]
9930 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9931 DOM_CC_X_AND_Y),
9932 CC_REGNUM);"
9933 [(set_attr "conds" "clob")
9934 (set_attr "enabled_for_short_it" "yes,no")
9935 (set_attr "length" "16")
9936 (set_attr "type" "multiple")]
9937 )
9938
9939 ; If the above pattern is followed by a CMP insn, then the compare is
9940 ; redundant, since we can rework the conditional instruction that follows.
9941 (define_insn_and_split "*and_scc_scc_cmp"
9942 [(set (match_operand 0 "dominant_cc_register" "")
9943 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9944 [(match_operand:SI 1 "s_register_operand" "l,r")
9945 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9946 (match_operator:SI 6 "arm_comparison_operator"
9947 [(match_operand:SI 4 "s_register_operand" "l,r")
9948 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9949 (const_int 0)))
9950 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9951 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9952 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9953 "TARGET_32BIT"
9954 "#"
9955 "TARGET_32BIT && reload_completed"
9956 [(set (match_dup 0)
9957 (compare
9958 (and:SI
9959 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9960 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9961 (const_int 0)))
9962 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9963 ""
9964 [(set_attr "conds" "set")
9965 (set_attr "enabled_for_short_it" "yes,no")
9966 (set_attr "length" "16")
9967 (set_attr "type" "multiple")]
9968 )
9969
9970 ;; If there is no dominance in the comparison, then we can still save an
9971 ;; instruction in the AND case, since we can know that the second compare
9972 ;; need only zero the value if false (if true, then the value is already
9973 ;; correct).
9974 (define_insn_and_split "*and_scc_scc_nodom"
9975 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9976 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9977 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9978 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9979 (match_operator:SI 6 "arm_comparison_operator"
9980 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9981 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9982 (clobber (reg:CC CC_REGNUM))]
9983 "TARGET_32BIT
9984 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9985 == CCmode)"
9986 "#"
9987 "TARGET_32BIT && reload_completed"
9988 [(parallel [(set (match_dup 0)
9989 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9990 (clobber (reg:CC CC_REGNUM))])
9991 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9992 (set (match_dup 0)
9993 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9994 (match_dup 0)
9995 (const_int 0)))]
9996 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9997 operands[4], operands[5]),
9998 CC_REGNUM);
9999 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
10000 operands[5]);"
10001 [(set_attr "conds" "clob")
10002 (set_attr "length" "20")
10003 (set_attr "type" "multiple")]
10004 )
10005
10006 (define_split
10007 [(set (reg:CC_NOOV CC_REGNUM)
10008 (compare:CC_NOOV (ior:SI
10009 (and:SI (match_operand:SI 0 "s_register_operand" "")
10010 (const_int 1))
10011 (match_operator:SI 1 "arm_comparison_operator"
10012 [(match_operand:SI 2 "s_register_operand" "")
10013 (match_operand:SI 3 "arm_add_operand" "")]))
10014 (const_int 0)))
10015 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10016 "TARGET_ARM"
10017 [(set (match_dup 4)
10018 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10019 (match_dup 0)))
10020 (set (reg:CC_NOOV CC_REGNUM)
10021 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10022 (const_int 0)))]
10023 "")
10024
10025 (define_split
10026 [(set (reg:CC_NOOV CC_REGNUM)
10027 (compare:CC_NOOV (ior:SI
10028 (match_operator:SI 1 "arm_comparison_operator"
10029 [(match_operand:SI 2 "s_register_operand" "")
10030 (match_operand:SI 3 "arm_add_operand" "")])
10031 (and:SI (match_operand:SI 0 "s_register_operand" "")
10032 (const_int 1)))
10033 (const_int 0)))
10034 (clobber (match_operand:SI 4 "s_register_operand" ""))]
10035 "TARGET_ARM"
10036 [(set (match_dup 4)
10037 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
10038 (match_dup 0)))
10039 (set (reg:CC_NOOV CC_REGNUM)
10040 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
10041 (const_int 0)))]
10042 "")
10043 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
10044
10045 (define_insn_and_split "*negscc"
10046 [(set (match_operand:SI 0 "s_register_operand" "=r")
10047 (neg:SI (match_operator 3 "arm_comparison_operator"
10048 [(match_operand:SI 1 "s_register_operand" "r")
10049 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
10050 (clobber (reg:CC CC_REGNUM))]
10051 "TARGET_ARM"
10052 "#"
10053 "&& reload_completed"
10054 [(const_int 0)]
10055 {
10056 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
10057
10058 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
10059 {
10060 /* Emit mov\\t%0, %1, asr #31 */
10061 emit_insn (gen_rtx_SET (operands[0],
10062 gen_rtx_ASHIFTRT (SImode,
10063 operands[1],
10064 GEN_INT (31))));
10065 DONE;
10066 }
10067 else if (GET_CODE (operands[3]) == NE)
10068 {
10069 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
10070 if (CONST_INT_P (operands[2]))
10071 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
10072 gen_int_mode (-INTVAL (operands[2]),
10073 SImode)));
10074 else
10075 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
10076
10077 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10078 gen_rtx_NE (SImode,
10079 cc_reg,
10080 const0_rtx),
10081 gen_rtx_SET (operands[0],
10082 GEN_INT (~0))));
10083 DONE;
10084 }
10085 else
10086 {
10087 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
10088 emit_insn (gen_rtx_SET (cc_reg,
10089 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
10090 enum rtx_code rc = GET_CODE (operands[3]);
10091
10092 rc = reverse_condition (rc);
10093 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10094 gen_rtx_fmt_ee (rc,
10095 VOIDmode,
10096 cc_reg,
10097 const0_rtx),
10098 gen_rtx_SET (operands[0], const0_rtx)));
10099 rc = GET_CODE (operands[3]);
10100 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
10101 gen_rtx_fmt_ee (rc,
10102 VOIDmode,
10103 cc_reg,
10104 const0_rtx),
10105 gen_rtx_SET (operands[0],
10106 GEN_INT (~0))));
10107 DONE;
10108 }
10109 FAIL;
10110 }
10111 [(set_attr "conds" "clob")
10112 (set_attr "length" "12")
10113 (set_attr "type" "multiple")]
10114 )
10115
10116 (define_insn_and_split "movcond_addsi"
10117 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
10118 (if_then_else:SI
10119 (match_operator 5 "comparison_operator"
10120 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
10121 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
10122 (const_int 0)])
10123 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
10124 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
10125 (clobber (reg:CC CC_REGNUM))]
10126 "TARGET_32BIT"
10127 "#"
10128 "&& reload_completed"
10129 [(set (reg:CC_NOOV CC_REGNUM)
10130 (compare:CC_NOOV
10131 (plus:SI (match_dup 3)
10132 (match_dup 4))
10133 (const_int 0)))
10134 (set (match_dup 0) (match_dup 1))
10135 (cond_exec (match_dup 6)
10136 (set (match_dup 0) (match_dup 2)))]
10137 "
10138 {
10139 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
10140 operands[3], operands[4]);
10141 enum rtx_code rc = GET_CODE (operands[5]);
10142 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10143 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
10144 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
10145 rc = reverse_condition (rc);
10146 else
10147 std::swap (operands[1], operands[2]);
10148
10149 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10150 }
10151 "
10152 [(set_attr "conds" "clob")
10153 (set_attr "enabled_for_short_it" "no,yes,yes")
10154 (set_attr "type" "multiple")]
10155 )
10156
10157 (define_insn "movcond"
10158 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10159 (if_then_else:SI
10160 (match_operator 5 "arm_comparison_operator"
10161 [(match_operand:SI 3 "s_register_operand" "r,r,r")
10162 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
10163 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
10164 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
10165 (clobber (reg:CC CC_REGNUM))]
10166 "TARGET_ARM"
10167 "*
10168 if (GET_CODE (operands[5]) == LT
10169 && (operands[4] == const0_rtx))
10170 {
10171 if (which_alternative != 1 && REG_P (operands[1]))
10172 {
10173 if (operands[2] == const0_rtx)
10174 return \"and\\t%0, %1, %3, asr #31\";
10175 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
10176 }
10177 else if (which_alternative != 0 && REG_P (operands[2]))
10178 {
10179 if (operands[1] == const0_rtx)
10180 return \"bic\\t%0, %2, %3, asr #31\";
10181 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
10182 }
10183 /* The only case that falls through to here is when both ops 1 & 2
10184 are constants. */
10185 }
10186
10187 if (GET_CODE (operands[5]) == GE
10188 && (operands[4] == const0_rtx))
10189 {
10190 if (which_alternative != 1 && REG_P (operands[1]))
10191 {
10192 if (operands[2] == const0_rtx)
10193 return \"bic\\t%0, %1, %3, asr #31\";
10194 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
10195 }
10196 else if (which_alternative != 0 && REG_P (operands[2]))
10197 {
10198 if (operands[1] == const0_rtx)
10199 return \"and\\t%0, %2, %3, asr #31\";
10200 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
10201 }
10202 /* The only case that falls through to here is when both ops 1 & 2
10203 are constants. */
10204 }
10205 if (CONST_INT_P (operands[4])
10206 && !const_ok_for_arm (INTVAL (operands[4])))
10207 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
10208 else
10209 output_asm_insn (\"cmp\\t%3, %4\", operands);
10210 if (which_alternative != 0)
10211 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
10212 if (which_alternative != 1)
10213 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
10214 return \"\";
10215 "
10216 [(set_attr "conds" "clob")
10217 (set_attr "length" "8,8,12")
10218 (set_attr "type" "multiple")]
10219 )
10220
10221 ;; ??? The patterns below need checking for Thumb-2 usefulness.
10222
10223 (define_insn "*ifcompare_plus_move"
10224 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10225 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10226 [(match_operand:SI 4 "s_register_operand" "r,r")
10227 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10228 (plus:SI
10229 (match_operand:SI 2 "s_register_operand" "r,r")
10230 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10231 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10232 (clobber (reg:CC CC_REGNUM))]
10233 "TARGET_ARM"
10234 "#"
10235 [(set_attr "conds" "clob")
10236 (set_attr "length" "8,12")
10237 (set_attr "type" "multiple")]
10238 )
10239
10240 (define_insn "*if_plus_move"
10241 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10242 (if_then_else:SI
10243 (match_operator 4 "arm_comparison_operator"
10244 [(match_operand 5 "cc_register" "") (const_int 0)])
10245 (plus:SI
10246 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10247 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10248 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10249 "TARGET_ARM"
10250 "@
10251 add%d4\\t%0, %2, %3
10252 sub%d4\\t%0, %2, #%n3
10253 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10254 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10255 [(set_attr "conds" "use")
10256 (set_attr "length" "4,4,8,8")
10257 (set_attr_alternative "type"
10258 [(if_then_else (match_operand 3 "const_int_operand" "")
10259 (const_string "alu_imm" )
10260 (const_string "alu_sreg"))
10261 (const_string "alu_imm")
10262 (const_string "multiple")
10263 (const_string "multiple")])]
10264 )
10265
10266 (define_insn "*ifcompare_move_plus"
10267 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10268 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10269 [(match_operand:SI 4 "s_register_operand" "r,r")
10270 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10271 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10272 (plus:SI
10273 (match_operand:SI 2 "s_register_operand" "r,r")
10274 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10275 (clobber (reg:CC CC_REGNUM))]
10276 "TARGET_ARM"
10277 "#"
10278 [(set_attr "conds" "clob")
10279 (set_attr "length" "8,12")
10280 (set_attr "type" "multiple")]
10281 )
10282
10283 (define_insn "*if_move_plus"
10284 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10285 (if_then_else:SI
10286 (match_operator 4 "arm_comparison_operator"
10287 [(match_operand 5 "cc_register" "") (const_int 0)])
10288 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10289 (plus:SI
10290 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10291 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10292 "TARGET_ARM"
10293 "@
10294 add%D4\\t%0, %2, %3
10295 sub%D4\\t%0, %2, #%n3
10296 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10297 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10298 [(set_attr "conds" "use")
10299 (set_attr "length" "4,4,8,8")
10300 (set_attr_alternative "type"
10301 [(if_then_else (match_operand 3 "const_int_operand" "")
10302 (const_string "alu_imm" )
10303 (const_string "alu_sreg"))
10304 (const_string "alu_imm")
10305 (const_string "multiple")
10306 (const_string "multiple")])]
10307 )
10308
10309 (define_insn "*ifcompare_arith_arith"
10310 [(set (match_operand:SI 0 "s_register_operand" "=r")
10311 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10312 [(match_operand:SI 5 "s_register_operand" "r")
10313 (match_operand:SI 6 "arm_add_operand" "rIL")])
10314 (match_operator:SI 8 "shiftable_operator"
10315 [(match_operand:SI 1 "s_register_operand" "r")
10316 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10317 (match_operator:SI 7 "shiftable_operator"
10318 [(match_operand:SI 3 "s_register_operand" "r")
10319 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10320 (clobber (reg:CC CC_REGNUM))]
10321 "TARGET_ARM"
10322 "#"
10323 [(set_attr "conds" "clob")
10324 (set_attr "length" "12")
10325 (set_attr "type" "multiple")]
10326 )
10327
10328 (define_insn "*if_arith_arith"
10329 [(set (match_operand:SI 0 "s_register_operand" "=r")
10330 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10331 [(match_operand 8 "cc_register" "") (const_int 0)])
10332 (match_operator:SI 6 "shiftable_operator"
10333 [(match_operand:SI 1 "s_register_operand" "r")
10334 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10335 (match_operator:SI 7 "shiftable_operator"
10336 [(match_operand:SI 3 "s_register_operand" "r")
10337 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10338 "TARGET_ARM"
10339 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10340 [(set_attr "conds" "use")
10341 (set_attr "length" "8")
10342 (set_attr "type" "multiple")]
10343 )
10344
10345 (define_insn "*ifcompare_arith_move"
10346 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10347 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10348 [(match_operand:SI 2 "s_register_operand" "r,r")
10349 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10350 (match_operator:SI 7 "shiftable_operator"
10351 [(match_operand:SI 4 "s_register_operand" "r,r")
10352 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10353 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10354 (clobber (reg:CC CC_REGNUM))]
10355 "TARGET_ARM"
10356 "*
10357 /* If we have an operation where (op x 0) is the identity operation and
10358 the conditional operator is LT or GE and we are comparing against zero and
10359 everything is in registers then we can do this in two instructions. */
10360 if (operands[3] == const0_rtx
10361 && GET_CODE (operands[7]) != AND
10362 && REG_P (operands[5])
10363 && REG_P (operands[1])
10364 && REGNO (operands[1]) == REGNO (operands[4])
10365 && REGNO (operands[4]) != REGNO (operands[0]))
10366 {
10367 if (GET_CODE (operands[6]) == LT)
10368 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10369 else if (GET_CODE (operands[6]) == GE)
10370 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10371 }
10372 if (CONST_INT_P (operands[3])
10373 && !const_ok_for_arm (INTVAL (operands[3])))
10374 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10375 else
10376 output_asm_insn (\"cmp\\t%2, %3\", operands);
10377 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10378 if (which_alternative != 0)
10379 return \"mov%D6\\t%0, %1\";
10380 return \"\";
10381 "
10382 [(set_attr "conds" "clob")
10383 (set_attr "length" "8,12")
10384 (set_attr "type" "multiple")]
10385 )
10386
10387 (define_insn "*if_arith_move"
10388 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10389 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10390 [(match_operand 6 "cc_register" "") (const_int 0)])
10391 (match_operator:SI 5 "shiftable_operator"
10392 [(match_operand:SI 2 "s_register_operand" "r,r")
10393 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10394 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10395 "TARGET_ARM"
10396 "@
10397 %I5%d4\\t%0, %2, %3
10398 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10399 [(set_attr "conds" "use")
10400 (set_attr "length" "4,8")
10401 (set_attr_alternative "type"
10402 [(if_then_else (match_operand 3 "const_int_operand" "")
10403 (const_string "alu_shift_imm" )
10404 (const_string "alu_shift_reg"))
10405 (const_string "multiple")])]
10406 )
10407
10408 (define_insn "*ifcompare_move_arith"
10409 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10410 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10411 [(match_operand:SI 4 "s_register_operand" "r,r")
10412 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10413 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10414 (match_operator:SI 7 "shiftable_operator"
10415 [(match_operand:SI 2 "s_register_operand" "r,r")
10416 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10417 (clobber (reg:CC CC_REGNUM))]
10418 "TARGET_ARM"
10419 "*
10420 /* If we have an operation where (op x 0) is the identity operation and
10421 the conditional operator is LT or GE and we are comparing against zero and
10422 everything is in registers then we can do this in two instructions */
10423 if (operands[5] == const0_rtx
10424 && GET_CODE (operands[7]) != AND
10425 && REG_P (operands[3])
10426 && REG_P (operands[1])
10427 && REGNO (operands[1]) == REGNO (operands[2])
10428 && REGNO (operands[2]) != REGNO (operands[0]))
10429 {
10430 if (GET_CODE (operands[6]) == GE)
10431 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10432 else if (GET_CODE (operands[6]) == LT)
10433 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10434 }
10435
10436 if (CONST_INT_P (operands[5])
10437 && !const_ok_for_arm (INTVAL (operands[5])))
10438 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10439 else
10440 output_asm_insn (\"cmp\\t%4, %5\", operands);
10441
10442 if (which_alternative != 0)
10443 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10444 return \"%I7%D6\\t%0, %2, %3\";
10445 "
10446 [(set_attr "conds" "clob")
10447 (set_attr "length" "8,12")
10448 (set_attr "type" "multiple")]
10449 )
10450
10451 (define_insn "*if_move_arith"
10452 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10453 (if_then_else:SI
10454 (match_operator 4 "arm_comparison_operator"
10455 [(match_operand 6 "cc_register" "") (const_int 0)])
10456 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10457 (match_operator:SI 5 "shiftable_operator"
10458 [(match_operand:SI 2 "s_register_operand" "r,r")
10459 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10460 "TARGET_ARM"
10461 "@
10462 %I5%D4\\t%0, %2, %3
10463 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10464 [(set_attr "conds" "use")
10465 (set_attr "length" "4,8")
10466 (set_attr_alternative "type"
10467 [(if_then_else (match_operand 3 "const_int_operand" "")
10468 (const_string "alu_shift_imm" )
10469 (const_string "alu_shift_reg"))
10470 (const_string "multiple")])]
10471 )
10472
10473 (define_insn "*ifcompare_move_not"
10474 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10475 (if_then_else:SI
10476 (match_operator 5 "arm_comparison_operator"
10477 [(match_operand:SI 3 "s_register_operand" "r,r")
10478 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10479 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10480 (not:SI
10481 (match_operand:SI 2 "s_register_operand" "r,r"))))
10482 (clobber (reg:CC CC_REGNUM))]
10483 "TARGET_ARM"
10484 "#"
10485 [(set_attr "conds" "clob")
10486 (set_attr "length" "8,12")
10487 (set_attr "type" "multiple")]
10488 )
10489
10490 (define_insn "*if_move_not"
10491 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10492 (if_then_else:SI
10493 (match_operator 4 "arm_comparison_operator"
10494 [(match_operand 3 "cc_register" "") (const_int 0)])
10495 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10496 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10497 "TARGET_ARM"
10498 "@
10499 mvn%D4\\t%0, %2
10500 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10501 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10502 [(set_attr "conds" "use")
10503 (set_attr "type" "mvn_reg")
10504 (set_attr "length" "4,8,8")
10505 (set_attr "type" "mvn_reg,multiple,multiple")]
10506 )
10507
10508 (define_insn "*ifcompare_not_move"
10509 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10510 (if_then_else:SI
10511 (match_operator 5 "arm_comparison_operator"
10512 [(match_operand:SI 3 "s_register_operand" "r,r")
10513 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10514 (not:SI
10515 (match_operand:SI 2 "s_register_operand" "r,r"))
10516 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10517 (clobber (reg:CC CC_REGNUM))]
10518 "TARGET_ARM"
10519 "#"
10520 [(set_attr "conds" "clob")
10521 (set_attr "length" "8,12")
10522 (set_attr "type" "multiple")]
10523 )
10524
10525 (define_insn "*if_not_move"
10526 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10527 (if_then_else:SI
10528 (match_operator 4 "arm_comparison_operator"
10529 [(match_operand 3 "cc_register" "") (const_int 0)])
10530 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10531 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10532 "TARGET_ARM"
10533 "@
10534 mvn%d4\\t%0, %2
10535 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10536 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10537 [(set_attr "conds" "use")
10538 (set_attr "type" "mvn_reg,multiple,multiple")
10539 (set_attr "length" "4,8,8")]
10540 )
10541
10542 (define_insn "*ifcompare_shift_move"
10543 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10544 (if_then_else:SI
10545 (match_operator 6 "arm_comparison_operator"
10546 [(match_operand:SI 4 "s_register_operand" "r,r")
10547 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10548 (match_operator:SI 7 "shift_operator"
10549 [(match_operand:SI 2 "s_register_operand" "r,r")
10550 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10551 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10552 (clobber (reg:CC CC_REGNUM))]
10553 "TARGET_ARM"
10554 "#"
10555 [(set_attr "conds" "clob")
10556 (set_attr "length" "8,12")
10557 (set_attr "type" "multiple")]
10558 )
10559
10560 (define_insn "*if_shift_move"
10561 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10562 (if_then_else:SI
10563 (match_operator 5 "arm_comparison_operator"
10564 [(match_operand 6 "cc_register" "") (const_int 0)])
10565 (match_operator:SI 4 "shift_operator"
10566 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10567 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10568 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10569 "TARGET_ARM"
10570 "@
10571 mov%d5\\t%0, %2%S4
10572 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10573 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10574 [(set_attr "conds" "use")
10575 (set_attr "shift" "2")
10576 (set_attr "length" "4,8,8")
10577 (set_attr_alternative "type"
10578 [(if_then_else (match_operand 3 "const_int_operand" "")
10579 (const_string "mov_shift" )
10580 (const_string "mov_shift_reg"))
10581 (const_string "multiple")
10582 (const_string "multiple")])]
10583 )
10584
10585 (define_insn "*ifcompare_move_shift"
10586 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10587 (if_then_else:SI
10588 (match_operator 6 "arm_comparison_operator"
10589 [(match_operand:SI 4 "s_register_operand" "r,r")
10590 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10591 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10592 (match_operator:SI 7 "shift_operator"
10593 [(match_operand:SI 2 "s_register_operand" "r,r")
10594 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10595 (clobber (reg:CC CC_REGNUM))]
10596 "TARGET_ARM"
10597 "#"
10598 [(set_attr "conds" "clob")
10599 (set_attr "length" "8,12")
10600 (set_attr "type" "multiple")]
10601 )
10602
10603 (define_insn "*if_move_shift"
10604 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10605 (if_then_else:SI
10606 (match_operator 5 "arm_comparison_operator"
10607 [(match_operand 6 "cc_register" "") (const_int 0)])
10608 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10609 (match_operator:SI 4 "shift_operator"
10610 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10611 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10612 "TARGET_ARM"
10613 "@
10614 mov%D5\\t%0, %2%S4
10615 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10616 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10617 [(set_attr "conds" "use")
10618 (set_attr "shift" "2")
10619 (set_attr "length" "4,8,8")
10620 (set_attr_alternative "type"
10621 [(if_then_else (match_operand 3 "const_int_operand" "")
10622 (const_string "mov_shift" )
10623 (const_string "mov_shift_reg"))
10624 (const_string "multiple")
10625 (const_string "multiple")])]
10626 )
10627
10628 (define_insn "*ifcompare_shift_shift"
10629 [(set (match_operand:SI 0 "s_register_operand" "=r")
10630 (if_then_else:SI
10631 (match_operator 7 "arm_comparison_operator"
10632 [(match_operand:SI 5 "s_register_operand" "r")
10633 (match_operand:SI 6 "arm_add_operand" "rIL")])
10634 (match_operator:SI 8 "shift_operator"
10635 [(match_operand:SI 1 "s_register_operand" "r")
10636 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10637 (match_operator:SI 9 "shift_operator"
10638 [(match_operand:SI 3 "s_register_operand" "r")
10639 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10640 (clobber (reg:CC CC_REGNUM))]
10641 "TARGET_ARM"
10642 "#"
10643 [(set_attr "conds" "clob")
10644 (set_attr "length" "12")
10645 (set_attr "type" "multiple")]
10646 )
10647
10648 (define_insn "*if_shift_shift"
10649 [(set (match_operand:SI 0 "s_register_operand" "=r")
10650 (if_then_else:SI
10651 (match_operator 5 "arm_comparison_operator"
10652 [(match_operand 8 "cc_register" "") (const_int 0)])
10653 (match_operator:SI 6 "shift_operator"
10654 [(match_operand:SI 1 "s_register_operand" "r")
10655 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10656 (match_operator:SI 7 "shift_operator"
10657 [(match_operand:SI 3 "s_register_operand" "r")
10658 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10659 "TARGET_ARM"
10660 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10661 [(set_attr "conds" "use")
10662 (set_attr "shift" "1")
10663 (set_attr "length" "8")
10664 (set (attr "type") (if_then_else
10665 (and (match_operand 2 "const_int_operand" "")
10666 (match_operand 4 "const_int_operand" ""))
10667 (const_string "mov_shift")
10668 (const_string "mov_shift_reg")))]
10669 )
10670
10671 (define_insn "*ifcompare_not_arith"
10672 [(set (match_operand:SI 0 "s_register_operand" "=r")
10673 (if_then_else:SI
10674 (match_operator 6 "arm_comparison_operator"
10675 [(match_operand:SI 4 "s_register_operand" "r")
10676 (match_operand:SI 5 "arm_add_operand" "rIL")])
10677 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10678 (match_operator:SI 7 "shiftable_operator"
10679 [(match_operand:SI 2 "s_register_operand" "r")
10680 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10681 (clobber (reg:CC CC_REGNUM))]
10682 "TARGET_ARM"
10683 "#"
10684 [(set_attr "conds" "clob")
10685 (set_attr "length" "12")
10686 (set_attr "type" "multiple")]
10687 )
10688
10689 (define_insn "*if_not_arith"
10690 [(set (match_operand:SI 0 "s_register_operand" "=r")
10691 (if_then_else:SI
10692 (match_operator 5 "arm_comparison_operator"
10693 [(match_operand 4 "cc_register" "") (const_int 0)])
10694 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10695 (match_operator:SI 6 "shiftable_operator"
10696 [(match_operand:SI 2 "s_register_operand" "r")
10697 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10698 "TARGET_ARM"
10699 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10700 [(set_attr "conds" "use")
10701 (set_attr "type" "mvn_reg")
10702 (set_attr "length" "8")]
10703 )
10704
10705 (define_insn "*ifcompare_arith_not"
10706 [(set (match_operand:SI 0 "s_register_operand" "=r")
10707 (if_then_else:SI
10708 (match_operator 6 "arm_comparison_operator"
10709 [(match_operand:SI 4 "s_register_operand" "r")
10710 (match_operand:SI 5 "arm_add_operand" "rIL")])
10711 (match_operator:SI 7 "shiftable_operator"
10712 [(match_operand:SI 2 "s_register_operand" "r")
10713 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10714 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10715 (clobber (reg:CC CC_REGNUM))]
10716 "TARGET_ARM"
10717 "#"
10718 [(set_attr "conds" "clob")
10719 (set_attr "length" "12")
10720 (set_attr "type" "multiple")]
10721 )
10722
10723 (define_insn "*if_arith_not"
10724 [(set (match_operand:SI 0 "s_register_operand" "=r")
10725 (if_then_else:SI
10726 (match_operator 5 "arm_comparison_operator"
10727 [(match_operand 4 "cc_register" "") (const_int 0)])
10728 (match_operator:SI 6 "shiftable_operator"
10729 [(match_operand:SI 2 "s_register_operand" "r")
10730 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10731 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10732 "TARGET_ARM"
10733 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10734 [(set_attr "conds" "use")
10735 (set_attr "type" "multiple")
10736 (set_attr "length" "8")]
10737 )
10738
10739 (define_insn "*ifcompare_neg_move"
10740 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10741 (if_then_else:SI
10742 (match_operator 5 "arm_comparison_operator"
10743 [(match_operand:SI 3 "s_register_operand" "r,r")
10744 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10745 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10746 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10747 (clobber (reg:CC CC_REGNUM))]
10748 "TARGET_ARM"
10749 "#"
10750 [(set_attr "conds" "clob")
10751 (set_attr "length" "8,12")
10752 (set_attr "type" "multiple")]
10753 )
10754
10755 (define_insn_and_split "*if_neg_move"
10756 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10757 (if_then_else:SI
10758 (match_operator 4 "arm_comparison_operator"
10759 [(match_operand 3 "cc_register" "") (const_int 0)])
10760 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10761 (match_operand:SI 1 "s_register_operand" "0,0")))]
10762 "TARGET_32BIT"
10763 "#"
10764 "&& reload_completed"
10765 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10766 (set (match_dup 0) (neg:SI (match_dup 2))))]
10767 ""
10768 [(set_attr "conds" "use")
10769 (set_attr "length" "4")
10770 (set_attr "arch" "t2,32")
10771 (set_attr "enabled_for_short_it" "yes,no")
10772 (set_attr "type" "logic_shift_imm")]
10773 )
10774
10775 (define_insn "*ifcompare_move_neg"
10776 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10777 (if_then_else:SI
10778 (match_operator 5 "arm_comparison_operator"
10779 [(match_operand:SI 3 "s_register_operand" "r,r")
10780 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10781 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10782 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10783 (clobber (reg:CC CC_REGNUM))]
10784 "TARGET_ARM"
10785 "#"
10786 [(set_attr "conds" "clob")
10787 (set_attr "length" "8,12")
10788 (set_attr "type" "multiple")]
10789 )
10790
10791 (define_insn_and_split "*if_move_neg"
10792 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10793 (if_then_else:SI
10794 (match_operator 4 "arm_comparison_operator"
10795 [(match_operand 3 "cc_register" "") (const_int 0)])
10796 (match_operand:SI 1 "s_register_operand" "0,0")
10797 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10798 "TARGET_32BIT"
10799 "#"
10800 "&& reload_completed"
10801 [(cond_exec (match_dup 5)
10802 (set (match_dup 0) (neg:SI (match_dup 2))))]
10803 {
10804 machine_mode mode = GET_MODE (operands[3]);
10805 rtx_code rc = GET_CODE (operands[4]);
10806
10807 if (mode == CCFPmode || mode == CCFPEmode)
10808 rc = reverse_condition_maybe_unordered (rc);
10809 else
10810 rc = reverse_condition (rc);
10811
10812 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10813 }
10814 [(set_attr "conds" "use")
10815 (set_attr "length" "4")
10816 (set_attr "arch" "t2,32")
10817 (set_attr "enabled_for_short_it" "yes,no")
10818 (set_attr "type" "logic_shift_imm")]
10819 )
10820
10821 (define_insn "*arith_adjacentmem"
10822 [(set (match_operand:SI 0 "s_register_operand" "=r")
10823 (match_operator:SI 1 "shiftable_operator"
10824 [(match_operand:SI 2 "memory_operand" "m")
10825 (match_operand:SI 3 "memory_operand" "m")]))
10826 (clobber (match_scratch:SI 4 "=r"))]
10827 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10828 "*
10829 {
10830 rtx ldm[3];
10831 rtx arith[4];
10832 rtx base_reg;
10833 HOST_WIDE_INT val1 = 0, val2 = 0;
10834
10835 if (REGNO (operands[0]) > REGNO (operands[4]))
10836 {
10837 ldm[1] = operands[4];
10838 ldm[2] = operands[0];
10839 }
10840 else
10841 {
10842 ldm[1] = operands[0];
10843 ldm[2] = operands[4];
10844 }
10845
10846 base_reg = XEXP (operands[2], 0);
10847
10848 if (!REG_P (base_reg))
10849 {
10850 val1 = INTVAL (XEXP (base_reg, 1));
10851 base_reg = XEXP (base_reg, 0);
10852 }
10853
10854 if (!REG_P (XEXP (operands[3], 0)))
10855 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10856
10857 arith[0] = operands[0];
10858 arith[3] = operands[1];
10859
10860 if (val1 < val2)
10861 {
10862 arith[1] = ldm[1];
10863 arith[2] = ldm[2];
10864 }
10865 else
10866 {
10867 arith[1] = ldm[2];
10868 arith[2] = ldm[1];
10869 }
10870
10871 ldm[0] = base_reg;
10872 if (val1 !=0 && val2 != 0)
10873 {
10874 rtx ops[3];
10875
10876 if (val1 == 4 || val2 == 4)
10877 /* Other val must be 8, since we know they are adjacent and neither
10878 is zero. */
10879 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10880 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10881 {
10882 ldm[0] = ops[0] = operands[4];
10883 ops[1] = base_reg;
10884 ops[2] = GEN_INT (val1);
10885 output_add_immediate (ops);
10886 if (val1 < val2)
10887 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10888 else
10889 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10890 }
10891 else
10892 {
10893 /* Offset is out of range for a single add, so use two ldr. */
10894 ops[0] = ldm[1];
10895 ops[1] = base_reg;
10896 ops[2] = GEN_INT (val1);
10897 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10898 ops[0] = ldm[2];
10899 ops[2] = GEN_INT (val2);
10900 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10901 }
10902 }
10903 else if (val1 != 0)
10904 {
10905 if (val1 < val2)
10906 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10907 else
10908 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10909 }
10910 else
10911 {
10912 if (val1 < val2)
10913 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10914 else
10915 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10916 }
10917 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10918 return \"\";
10919 }"
10920 [(set_attr "length" "12")
10921 (set_attr "predicable" "yes")
10922 (set_attr "type" "load_4")]
10923 )
10924
10925 ; This pattern is never tried by combine, so do it as a peephole
10926
10927 (define_peephole2
10928 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10929 (match_operand:SI 1 "arm_general_register_operand" ""))
10930 (set (reg:CC CC_REGNUM)
10931 (compare:CC (match_dup 1) (const_int 0)))]
10932 "TARGET_ARM"
10933 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10934 (set (match_dup 0) (match_dup 1))])]
10935 ""
10936 )
10937
10938 (define_split
10939 [(set (match_operand:SI 0 "s_register_operand" "")
10940 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10941 (const_int 0))
10942 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10943 [(match_operand:SI 3 "s_register_operand" "")
10944 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10945 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10946 "TARGET_ARM"
10947 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10948 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10949 (match_dup 5)))]
10950 ""
10951 )
10952
10953 ;; This split can be used because CC_Z mode implies that the following
10954 ;; branch will be an equality, or an unsigned inequality, so the sign
10955 ;; extension is not needed.
10956
10957 (define_split
10958 [(set (reg:CC_Z CC_REGNUM)
10959 (compare:CC_Z
10960 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10961 (const_int 24))
10962 (match_operand 1 "const_int_operand" "")))
10963 (clobber (match_scratch:SI 2 ""))]
10964 "TARGET_ARM
10965 && ((UINTVAL (operands[1]))
10966 == ((UINTVAL (operands[1])) >> 24) << 24)"
10967 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10968 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10969 "
10970 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10971 "
10972 )
10973 ;; ??? Check the patterns above for Thumb-2 usefulness
10974
10975 (define_expand "prologue"
10976 [(clobber (const_int 0))]
10977 "TARGET_EITHER"
10978 "if (TARGET_32BIT)
10979 arm_expand_prologue ();
10980 else
10981 thumb1_expand_prologue ();
10982 DONE;
10983 "
10984 )
10985
10986 (define_expand "epilogue"
10987 [(clobber (const_int 0))]
10988 "TARGET_EITHER"
10989 "
10990 if (crtl->calls_eh_return)
10991 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10992 if (TARGET_THUMB1)
10993 {
10994 thumb1_expand_epilogue ();
10995 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10996 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10997 }
10998 else if (HAVE_return)
10999 {
11000 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
11001 no need for explicit testing again. */
11002 emit_jump_insn (gen_return ());
11003 }
11004 else if (TARGET_32BIT)
11005 {
11006 arm_expand_epilogue (true);
11007 }
11008 DONE;
11009 "
11010 )
11011
11012 ;; Note - although unspec_volatile's USE all hard registers,
11013 ;; USEs are ignored after relaod has completed. Thus we need
11014 ;; to add an unspec of the link register to ensure that flow
11015 ;; does not think that it is unused by the sibcall branch that
11016 ;; will replace the standard function epilogue.
11017 (define_expand "sibcall_epilogue"
11018 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
11019 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
11020 "TARGET_32BIT"
11021 "
11022 arm_expand_epilogue (false);
11023 DONE;
11024 "
11025 )
11026
11027 (define_expand "eh_epilogue"
11028 [(use (match_operand:SI 0 "register_operand" ""))
11029 (use (match_operand:SI 1 "register_operand" ""))
11030 (use (match_operand:SI 2 "register_operand" ""))]
11031 "TARGET_EITHER"
11032 "
11033 {
11034 cfun->machine->eh_epilogue_sp_ofs = operands[1];
11035 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
11036 {
11037 rtx ra = gen_rtx_REG (Pmode, 2);
11038
11039 emit_move_insn (ra, operands[2]);
11040 operands[2] = ra;
11041 }
11042 /* This is a hack -- we may have crystalized the function type too
11043 early. */
11044 cfun->machine->func_type = 0;
11045 }"
11046 )
11047
11048 ;; This split is only used during output to reduce the number of patterns
11049 ;; that need assembler instructions adding to them. We allowed the setting
11050 ;; of the conditions to be implicit during rtl generation so that
11051 ;; the conditional compare patterns would work. However this conflicts to
11052 ;; some extent with the conditional data operations, so we have to split them
11053 ;; up again here.
11054
11055 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
11056 ;; conditional execution sufficient?
11057
11058 (define_split
11059 [(set (match_operand:SI 0 "s_register_operand" "")
11060 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11061 [(match_operand 2 "" "") (match_operand 3 "" "")])
11062 (match_dup 0)
11063 (match_operand 4 "" "")))
11064 (clobber (reg:CC CC_REGNUM))]
11065 "TARGET_ARM && reload_completed"
11066 [(set (match_dup 5) (match_dup 6))
11067 (cond_exec (match_dup 7)
11068 (set (match_dup 0) (match_dup 4)))]
11069 "
11070 {
11071 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11072 operands[2], operands[3]);
11073 enum rtx_code rc = GET_CODE (operands[1]);
11074
11075 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11076 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11077 if (mode == CCFPmode || mode == CCFPEmode)
11078 rc = reverse_condition_maybe_unordered (rc);
11079 else
11080 rc = reverse_condition (rc);
11081
11082 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
11083 }"
11084 )
11085
11086 (define_split
11087 [(set (match_operand:SI 0 "s_register_operand" "")
11088 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11089 [(match_operand 2 "" "") (match_operand 3 "" "")])
11090 (match_operand 4 "" "")
11091 (match_dup 0)))
11092 (clobber (reg:CC CC_REGNUM))]
11093 "TARGET_ARM && reload_completed"
11094 [(set (match_dup 5) (match_dup 6))
11095 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
11096 (set (match_dup 0) (match_dup 4)))]
11097 "
11098 {
11099 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11100 operands[2], operands[3]);
11101
11102 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
11103 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11104 }"
11105 )
11106
11107 (define_split
11108 [(set (match_operand:SI 0 "s_register_operand" "")
11109 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11110 [(match_operand 2 "" "") (match_operand 3 "" "")])
11111 (match_operand 4 "" "")
11112 (match_operand 5 "" "")))
11113 (clobber (reg:CC CC_REGNUM))]
11114 "TARGET_ARM && reload_completed"
11115 [(set (match_dup 6) (match_dup 7))
11116 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11117 (set (match_dup 0) (match_dup 4)))
11118 (cond_exec (match_dup 8)
11119 (set (match_dup 0) (match_dup 5)))]
11120 "
11121 {
11122 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11123 operands[2], operands[3]);
11124 enum rtx_code rc = GET_CODE (operands[1]);
11125
11126 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11127 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11128 if (mode == CCFPmode || mode == CCFPEmode)
11129 rc = reverse_condition_maybe_unordered (rc);
11130 else
11131 rc = reverse_condition (rc);
11132
11133 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11134 }"
11135 )
11136
11137 (define_split
11138 [(set (match_operand:SI 0 "s_register_operand" "")
11139 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
11140 [(match_operand:SI 2 "s_register_operand" "")
11141 (match_operand:SI 3 "arm_add_operand" "")])
11142 (match_operand:SI 4 "arm_rhs_operand" "")
11143 (not:SI
11144 (match_operand:SI 5 "s_register_operand" ""))))
11145 (clobber (reg:CC CC_REGNUM))]
11146 "TARGET_ARM && reload_completed"
11147 [(set (match_dup 6) (match_dup 7))
11148 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
11149 (set (match_dup 0) (match_dup 4)))
11150 (cond_exec (match_dup 8)
11151 (set (match_dup 0) (not:SI (match_dup 5))))]
11152 "
11153 {
11154 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
11155 operands[2], operands[3]);
11156 enum rtx_code rc = GET_CODE (operands[1]);
11157
11158 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
11159 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
11160 if (mode == CCFPmode || mode == CCFPEmode)
11161 rc = reverse_condition_maybe_unordered (rc);
11162 else
11163 rc = reverse_condition (rc);
11164
11165 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
11166 }"
11167 )
11168
11169 (define_insn "*cond_move_not"
11170 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
11171 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
11172 [(match_operand 3 "cc_register" "") (const_int 0)])
11173 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
11174 (not:SI
11175 (match_operand:SI 2 "s_register_operand" "r,r"))))]
11176 "TARGET_ARM"
11177 "@
11178 mvn%D4\\t%0, %2
11179 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11180 [(set_attr "conds" "use")
11181 (set_attr "type" "mvn_reg,multiple")
11182 (set_attr "length" "4,8")]
11183 )
11184
11185 ;; The next two patterns occur when an AND operation is followed by a
11186 ;; scc insn sequence
11187
11188 (define_insn "*sign_extract_onebit"
11189 [(set (match_operand:SI 0 "s_register_operand" "=r")
11190 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11191 (const_int 1)
11192 (match_operand:SI 2 "const_int_operand" "n")))
11193 (clobber (reg:CC CC_REGNUM))]
11194 "TARGET_ARM"
11195 "*
11196 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11197 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
11198 return \"mvnne\\t%0, #0\";
11199 "
11200 [(set_attr "conds" "clob")
11201 (set_attr "length" "8")
11202 (set_attr "type" "multiple")]
11203 )
11204
11205 (define_insn "*not_signextract_onebit"
11206 [(set (match_operand:SI 0 "s_register_operand" "=r")
11207 (not:SI
11208 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11209 (const_int 1)
11210 (match_operand:SI 2 "const_int_operand" "n"))))
11211 (clobber (reg:CC CC_REGNUM))]
11212 "TARGET_ARM"
11213 "*
11214 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11215 output_asm_insn (\"tst\\t%1, %2\", operands);
11216 output_asm_insn (\"mvneq\\t%0, #0\", operands);
11217 return \"movne\\t%0, #0\";
11218 "
11219 [(set_attr "conds" "clob")
11220 (set_attr "length" "12")
11221 (set_attr "type" "multiple")]
11222 )
11223 ;; ??? The above patterns need auditing for Thumb-2
11224
11225 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
11226 ;; expressions. For simplicity, the first register is also in the unspec
11227 ;; part.
11228 ;; To avoid the usage of GNU extension, the length attribute is computed
11229 ;; in a C function arm_attr_length_push_multi.
11230 (define_insn "*push_multi"
11231 [(match_parallel 2 "multi_register_push"
11232 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11233 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11234 UNSPEC_PUSH_MULT))])]
11235 ""
11236 "*
11237 {
11238 int num_saves = XVECLEN (operands[2], 0);
11239
11240 /* For the StrongARM at least it is faster to
11241 use STR to store only a single register.
11242 In Thumb mode always use push, and the assembler will pick
11243 something appropriate. */
11244 if (num_saves == 1 && TARGET_ARM)
11245 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11246 else
11247 {
11248 int i;
11249 char pattern[100];
11250
11251 if (TARGET_32BIT)
11252 strcpy (pattern, \"push%?\\t{%1\");
11253 else
11254 strcpy (pattern, \"push\\t{%1\");
11255
11256 for (i = 1; i < num_saves; i++)
11257 {
11258 strcat (pattern, \", %|\");
11259 strcat (pattern,
11260 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11261 }
11262
11263 strcat (pattern, \"}\");
11264 output_asm_insn (pattern, operands);
11265 }
11266
11267 return \"\";
11268 }"
11269 [(set_attr "type" "store_16")
11270 (set (attr "length")
11271 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11272 )
11273
11274 (define_insn "stack_tie"
11275 [(set (mem:BLK (scratch))
11276 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11277 (match_operand:SI 1 "s_register_operand" "rk")]
11278 UNSPEC_PRLG_STK))]
11279 ""
11280 ""
11281 [(set_attr "length" "0")
11282 (set_attr "type" "block")]
11283 )
11284
11285 ;; Pop (as used in epilogue RTL)
11286 ;;
11287 (define_insn "*load_multiple_with_writeback"
11288 [(match_parallel 0 "load_multiple_operation"
11289 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11290 (plus:SI (match_dup 1)
11291 (match_operand:SI 2 "const_int_I_operand" "I")))
11292 (set (match_operand:SI 3 "s_register_operand" "=rk")
11293 (mem:SI (match_dup 1)))
11294 ])]
11295 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11296 "*
11297 {
11298 arm_output_multireg_pop (operands, /*return_pc=*/false,
11299 /*cond=*/const_true_rtx,
11300 /*reverse=*/false,
11301 /*update=*/true);
11302 return \"\";
11303 }
11304 "
11305 [(set_attr "type" "load_16")
11306 (set_attr "predicable" "yes")
11307 (set (attr "length")
11308 (symbol_ref "arm_attr_length_pop_multi (operands,
11309 /*return_pc=*/false,
11310 /*write_back_p=*/true)"))]
11311 )
11312
11313 ;; Pop with return (as used in epilogue RTL)
11314 ;;
11315 ;; This instruction is generated when the registers are popped at the end of
11316 ;; epilogue. Here, instead of popping the value into LR and then generating
11317 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11318 ;; with (return).
11319 (define_insn "*pop_multiple_with_writeback_and_return"
11320 [(match_parallel 0 "pop_multiple_return"
11321 [(return)
11322 (set (match_operand:SI 1 "s_register_operand" "+rk")
11323 (plus:SI (match_dup 1)
11324 (match_operand:SI 2 "const_int_I_operand" "I")))
11325 (set (match_operand:SI 3 "s_register_operand" "=rk")
11326 (mem:SI (match_dup 1)))
11327 ])]
11328 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11329 "*
11330 {
11331 arm_output_multireg_pop (operands, /*return_pc=*/true,
11332 /*cond=*/const_true_rtx,
11333 /*reverse=*/false,
11334 /*update=*/true);
11335 return \"\";
11336 }
11337 "
11338 [(set_attr "type" "load_16")
11339 (set_attr "predicable" "yes")
11340 (set (attr "length")
11341 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11342 /*write_back_p=*/true)"))]
11343 )
11344
11345 (define_insn "*pop_multiple_with_return"
11346 [(match_parallel 0 "pop_multiple_return"
11347 [(return)
11348 (set (match_operand:SI 2 "s_register_operand" "=rk")
11349 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11350 ])]
11351 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11352 "*
11353 {
11354 arm_output_multireg_pop (operands, /*return_pc=*/true,
11355 /*cond=*/const_true_rtx,
11356 /*reverse=*/false,
11357 /*update=*/false);
11358 return \"\";
11359 }
11360 "
11361 [(set_attr "type" "load_16")
11362 (set_attr "predicable" "yes")
11363 (set (attr "length")
11364 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11365 /*write_back_p=*/false)"))]
11366 )
11367
11368 ;; Load into PC and return
11369 (define_insn "*ldr_with_return"
11370 [(return)
11371 (set (reg:SI PC_REGNUM)
11372 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11373 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11374 "ldr%?\t%|pc, [%0], #4"
11375 [(set_attr "type" "load_4")
11376 (set_attr "predicable" "yes")]
11377 )
11378 ;; Pop for floating point registers (as used in epilogue RTL)
11379 (define_insn "*vfp_pop_multiple_with_writeback"
11380 [(match_parallel 0 "pop_multiple_fp"
11381 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11382 (plus:SI (match_dup 1)
11383 (match_operand:SI 2 "const_int_I_operand" "I")))
11384 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11385 (mem:DF (match_dup 1)))])]
11386 "TARGET_32BIT && TARGET_HARD_FLOAT"
11387 "*
11388 {
11389 int num_regs = XVECLEN (operands[0], 0);
11390 char pattern[100];
11391 rtx op_list[2];
11392 strcpy (pattern, \"vldm\\t\");
11393 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11394 strcat (pattern, \"!, {\");
11395 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11396 strcat (pattern, \"%P0\");
11397 if ((num_regs - 1) > 1)
11398 {
11399 strcat (pattern, \"-%P1\");
11400 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11401 }
11402
11403 strcat (pattern, \"}\");
11404 output_asm_insn (pattern, op_list);
11405 return \"\";
11406 }
11407 "
11408 [(set_attr "type" "load_16")
11409 (set_attr "conds" "unconditional")
11410 (set_attr "predicable" "no")]
11411 )
11412
11413 ;; Special patterns for dealing with the constant pool
11414
11415 (define_insn "align_4"
11416 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11417 "TARGET_EITHER"
11418 "*
11419 assemble_align (32);
11420 return \"\";
11421 "
11422 [(set_attr "type" "no_insn")]
11423 )
11424
11425 (define_insn "align_8"
11426 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11427 "TARGET_EITHER"
11428 "*
11429 assemble_align (64);
11430 return \"\";
11431 "
11432 [(set_attr "type" "no_insn")]
11433 )
11434
11435 (define_insn "consttable_end"
11436 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11437 "TARGET_EITHER"
11438 "*
11439 making_const_table = FALSE;
11440 return \"\";
11441 "
11442 [(set_attr "type" "no_insn")]
11443 )
11444
11445 (define_insn "consttable_1"
11446 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11447 "TARGET_EITHER"
11448 "*
11449 making_const_table = TRUE;
11450 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11451 assemble_zeros (3);
11452 return \"\";
11453 "
11454 [(set_attr "length" "4")
11455 (set_attr "type" "no_insn")]
11456 )
11457
11458 (define_insn "consttable_2"
11459 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11460 "TARGET_EITHER"
11461 "*
11462 {
11463 rtx x = operands[0];
11464 making_const_table = TRUE;
11465 switch (GET_MODE_CLASS (GET_MODE (x)))
11466 {
11467 case MODE_FLOAT:
11468 arm_emit_fp16_const (x);
11469 break;
11470 default:
11471 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11472 assemble_zeros (2);
11473 break;
11474 }
11475 return \"\";
11476 }"
11477 [(set_attr "length" "4")
11478 (set_attr "type" "no_insn")]
11479 )
11480
11481 (define_insn "consttable_4"
11482 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11483 "TARGET_EITHER"
11484 "*
11485 {
11486 rtx x = operands[0];
11487 making_const_table = TRUE;
11488 scalar_float_mode float_mode;
11489 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11490 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11491 else
11492 {
11493 /* XXX: Sometimes gcc does something really dumb and ends up with
11494 a HIGH in a constant pool entry, usually because it's trying to
11495 load into a VFP register. We know this will always be used in
11496 combination with a LO_SUM which ignores the high bits, so just
11497 strip off the HIGH. */
11498 if (GET_CODE (x) == HIGH)
11499 x = XEXP (x, 0);
11500 assemble_integer (x, 4, BITS_PER_WORD, 1);
11501 mark_symbol_refs_as_used (x);
11502 }
11503 return \"\";
11504 }"
11505 [(set_attr "length" "4")
11506 (set_attr "type" "no_insn")]
11507 )
11508
11509 (define_insn "consttable_8"
11510 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11511 "TARGET_EITHER"
11512 "*
11513 {
11514 making_const_table = TRUE;
11515 scalar_float_mode float_mode;
11516 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11517 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11518 float_mode, BITS_PER_WORD);
11519 else
11520 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11521 return \"\";
11522 }"
11523 [(set_attr "length" "8")
11524 (set_attr "type" "no_insn")]
11525 )
11526
11527 (define_insn "consttable_16"
11528 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11529 "TARGET_EITHER"
11530 "*
11531 {
11532 making_const_table = TRUE;
11533 scalar_float_mode float_mode;
11534 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11535 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11536 float_mode, BITS_PER_WORD);
11537 else
11538 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11539 return \"\";
11540 }"
11541 [(set_attr "length" "16")
11542 (set_attr "type" "no_insn")]
11543 )
11544
11545 ;; V5 Instructions,
11546
11547 (define_insn "clzsi2"
11548 [(set (match_operand:SI 0 "s_register_operand" "=r")
11549 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11550 "TARGET_32BIT && arm_arch5t"
11551 "clz%?\\t%0, %1"
11552 [(set_attr "predicable" "yes")
11553 (set_attr "type" "clz")])
11554
11555 (define_insn "rbitsi2"
11556 [(set (match_operand:SI 0 "s_register_operand" "=r")
11557 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11558 "TARGET_32BIT && arm_arch_thumb2"
11559 "rbit%?\\t%0, %1"
11560 [(set_attr "predicable" "yes")
11561 (set_attr "type" "clz")])
11562
11563 ;; Keep this as a CTZ expression until after reload and then split
11564 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11565 ;; to fold with any other expression.
11566
11567 (define_insn_and_split "ctzsi2"
11568 [(set (match_operand:SI 0 "s_register_operand" "=r")
11569 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11570 "TARGET_32BIT && arm_arch_thumb2"
11571 "#"
11572 "&& reload_completed"
11573 [(const_int 0)]
11574 "
11575 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11576 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11577 DONE;
11578 ")
11579
11580 ;; V5E instructions.
11581
11582 (define_insn "prefetch"
11583 [(prefetch (match_operand:SI 0 "address_operand" "p")
11584 (match_operand:SI 1 "" "")
11585 (match_operand:SI 2 "" ""))]
11586 "TARGET_32BIT && arm_arch5te"
11587 "pld\\t%a0"
11588 [(set_attr "type" "load_4")]
11589 )
11590
11591 ;; General predication pattern
11592
11593 (define_cond_exec
11594 [(match_operator 0 "arm_comparison_operator"
11595 [(match_operand 1 "cc_register" "")
11596 (const_int 0)])]
11597 "TARGET_32BIT
11598 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11599 ""
11600 [(set_attr "predicated" "yes")]
11601 )
11602
11603 (define_insn "force_register_use"
11604 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11605 ""
11606 "%@ %0 needed"
11607 [(set_attr "length" "0")
11608 (set_attr "type" "no_insn")]
11609 )
11610
11611
11612 ;; Patterns for exception handling
11613
11614 (define_expand "eh_return"
11615 [(use (match_operand 0 "general_operand" ""))]
11616 "TARGET_EITHER"
11617 "
11618 {
11619 if (TARGET_32BIT)
11620 emit_insn (gen_arm_eh_return (operands[0]));
11621 else
11622 emit_insn (gen_thumb_eh_return (operands[0]));
11623 DONE;
11624 }"
11625 )
11626
11627 ;; We can't expand this before we know where the link register is stored.
11628 (define_insn_and_split "arm_eh_return"
11629 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11630 VUNSPEC_EH_RETURN)
11631 (clobber (match_scratch:SI 1 "=&r"))]
11632 "TARGET_ARM"
11633 "#"
11634 "&& reload_completed"
11635 [(const_int 0)]
11636 "
11637 {
11638 arm_set_return_address (operands[0], operands[1]);
11639 DONE;
11640 }"
11641 )
11642
11643 \f
11644 ;; TLS support
11645
11646 (define_insn "load_tp_hard"
11647 [(set (match_operand:SI 0 "register_operand" "=r")
11648 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11649 "TARGET_HARD_TP"
11650 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11651 [(set_attr "predicable" "yes")
11652 (set_attr "type" "mrs")]
11653 )
11654
11655 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11656 (define_insn "load_tp_soft"
11657 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11658 (clobber (reg:SI LR_REGNUM))
11659 (clobber (reg:SI IP_REGNUM))
11660 (clobber (reg:CC CC_REGNUM))]
11661 "TARGET_SOFT_TP"
11662 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11663 [(set_attr "conds" "clob")
11664 (set_attr "type" "branch")]
11665 )
11666
11667 ;; tls descriptor call
11668 (define_insn "tlscall"
11669 [(set (reg:SI R0_REGNUM)
11670 (unspec:SI [(reg:SI R0_REGNUM)
11671 (match_operand:SI 0 "" "X")
11672 (match_operand 1 "" "")] UNSPEC_TLS))
11673 (clobber (reg:SI R1_REGNUM))
11674 (clobber (reg:SI LR_REGNUM))
11675 (clobber (reg:SI CC_REGNUM))]
11676 "TARGET_GNU2_TLS"
11677 {
11678 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11679 INTVAL (operands[1]));
11680 return "bl\\t%c0(tlscall)";
11681 }
11682 [(set_attr "conds" "clob")
11683 (set_attr "length" "4")
11684 (set_attr "type" "branch")]
11685 )
11686
11687 ;; For thread pointer builtin
11688 (define_expand "get_thread_pointersi"
11689 [(match_operand:SI 0 "s_register_operand" "=r")]
11690 ""
11691 "
11692 {
11693 arm_load_tp (operands[0]);
11694 DONE;
11695 }")
11696
11697 ;;
11698
11699 ;; We only care about the lower 16 bits of the constant
11700 ;; being inserted into the upper 16 bits of the register.
11701 (define_insn "*arm_movtas_ze"
11702 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11703 (const_int 16)
11704 (const_int 16))
11705 (match_operand:SI 1 "const_int_operand" ""))]
11706 "TARGET_HAVE_MOVT"
11707 "@
11708 movt%?\t%0, %L1
11709 movt\t%0, %L1"
11710 [(set_attr "arch" "32,v8mb")
11711 (set_attr "predicable" "yes")
11712 (set_attr "length" "4")
11713 (set_attr "type" "alu_sreg")]
11714 )
11715
11716 (define_insn "*arm_rev"
11717 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11718 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11719 "arm_arch6"
11720 "@
11721 rev\t%0, %1
11722 rev%?\t%0, %1
11723 rev%?\t%0, %1"
11724 [(set_attr "arch" "t1,t2,32")
11725 (set_attr "length" "2,2,4")
11726 (set_attr "predicable" "no,yes,yes")
11727 (set_attr "type" "rev")]
11728 )
11729
11730 (define_expand "arm_legacy_rev"
11731 [(set (match_operand:SI 2 "s_register_operand" "")
11732 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11733 (const_int 16))
11734 (match_dup 1)))
11735 (set (match_dup 2)
11736 (lshiftrt:SI (match_dup 2)
11737 (const_int 8)))
11738 (set (match_operand:SI 3 "s_register_operand" "")
11739 (rotatert:SI (match_dup 1)
11740 (const_int 8)))
11741 (set (match_dup 2)
11742 (and:SI (match_dup 2)
11743 (const_int -65281)))
11744 (set (match_operand:SI 0 "s_register_operand" "")
11745 (xor:SI (match_dup 3)
11746 (match_dup 2)))]
11747 "TARGET_32BIT"
11748 ""
11749 )
11750
11751 ;; Reuse temporaries to keep register pressure down.
11752 (define_expand "thumb_legacy_rev"
11753 [(set (match_operand:SI 2 "s_register_operand" "")
11754 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11755 (const_int 24)))
11756 (set (match_operand:SI 3 "s_register_operand" "")
11757 (lshiftrt:SI (match_dup 1)
11758 (const_int 24)))
11759 (set (match_dup 3)
11760 (ior:SI (match_dup 3)
11761 (match_dup 2)))
11762 (set (match_operand:SI 4 "s_register_operand" "")
11763 (const_int 16))
11764 (set (match_operand:SI 5 "s_register_operand" "")
11765 (rotatert:SI (match_dup 1)
11766 (match_dup 4)))
11767 (set (match_dup 2)
11768 (ashift:SI (match_dup 5)
11769 (const_int 24)))
11770 (set (match_dup 5)
11771 (lshiftrt:SI (match_dup 5)
11772 (const_int 24)))
11773 (set (match_dup 5)
11774 (ior:SI (match_dup 5)
11775 (match_dup 2)))
11776 (set (match_dup 5)
11777 (rotatert:SI (match_dup 5)
11778 (match_dup 4)))
11779 (set (match_operand:SI 0 "s_register_operand" "")
11780 (ior:SI (match_dup 5)
11781 (match_dup 3)))]
11782 "TARGET_THUMB"
11783 ""
11784 )
11785
11786 ;; ARM-specific expansion of signed mod by power of 2
11787 ;; using conditional negate.
11788 ;; For r0 % n where n is a power of 2 produce:
11789 ;; rsbs r1, r0, #0
11790 ;; and r0, r0, #(n - 1)
11791 ;; and r1, r1, #(n - 1)
11792 ;; rsbpl r0, r1, #0
11793
11794 (define_expand "modsi3"
11795 [(match_operand:SI 0 "register_operand" "")
11796 (match_operand:SI 1 "register_operand" "")
11797 (match_operand:SI 2 "const_int_operand" "")]
11798 "TARGET_32BIT"
11799 {
11800 HOST_WIDE_INT val = INTVAL (operands[2]);
11801
11802 if (val <= 0
11803 || exact_log2 (val) <= 0)
11804 FAIL;
11805
11806 rtx mask = GEN_INT (val - 1);
11807
11808 /* In the special case of x0 % 2 we can do the even shorter:
11809 cmp r0, #0
11810 and r0, r0, #1
11811 rsblt r0, r0, #0. */
11812
11813 if (val == 2)
11814 {
11815 rtx cc_reg = arm_gen_compare_reg (LT,
11816 operands[1], const0_rtx, NULL_RTX);
11817 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11818 rtx masked = gen_reg_rtx (SImode);
11819
11820 emit_insn (gen_andsi3 (masked, operands[1], mask));
11821 emit_move_insn (operands[0],
11822 gen_rtx_IF_THEN_ELSE (SImode, cond,
11823 gen_rtx_NEG (SImode,
11824 masked),
11825 masked));
11826 DONE;
11827 }
11828
11829 rtx neg_op = gen_reg_rtx (SImode);
11830 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11831 operands[1]));
11832
11833 /* Extract the condition register and mode. */
11834 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11835 rtx cc_reg = SET_DEST (cmp);
11836 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11837
11838 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11839
11840 rtx masked_neg = gen_reg_rtx (SImode);
11841 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11842
11843 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11844 during expand does not always work. Do an IF_THEN_ELSE instead. */
11845 emit_move_insn (operands[0],
11846 gen_rtx_IF_THEN_ELSE (SImode, cond,
11847 gen_rtx_NEG (SImode, masked_neg),
11848 operands[0]));
11849
11850
11851 DONE;
11852 }
11853 )
11854
11855 (define_expand "bswapsi2"
11856 [(set (match_operand:SI 0 "s_register_operand" "=r")
11857 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11858 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11859 "
11860 if (!arm_arch6)
11861 {
11862 rtx op2 = gen_reg_rtx (SImode);
11863 rtx op3 = gen_reg_rtx (SImode);
11864
11865 if (TARGET_THUMB)
11866 {
11867 rtx op4 = gen_reg_rtx (SImode);
11868 rtx op5 = gen_reg_rtx (SImode);
11869
11870 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11871 op2, op3, op4, op5));
11872 }
11873 else
11874 {
11875 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11876 op2, op3));
11877 }
11878
11879 DONE;
11880 }
11881 "
11882 )
11883
11884 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11885 ;; and unsigned variants, respectively. For rev16, expose
11886 ;; byte-swapping in the lower 16 bits only.
11887 (define_insn "*arm_revsh"
11888 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11889 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11890 "arm_arch6"
11891 "@
11892 revsh\t%0, %1
11893 revsh%?\t%0, %1
11894 revsh%?\t%0, %1"
11895 [(set_attr "arch" "t1,t2,32")
11896 (set_attr "length" "2,2,4")
11897 (set_attr "type" "rev")]
11898 )
11899
11900 (define_insn "*arm_rev16"
11901 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11902 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11903 "arm_arch6"
11904 "@
11905 rev16\t%0, %1
11906 rev16%?\t%0, %1
11907 rev16%?\t%0, %1"
11908 [(set_attr "arch" "t1,t2,32")
11909 (set_attr "length" "2,2,4")
11910 (set_attr "type" "rev")]
11911 )
11912
11913 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11914 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11915 ;; each valid permutation.
11916
11917 (define_insn "arm_rev16si2"
11918 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11919 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11920 (const_int 8))
11921 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11922 (and:SI (lshiftrt:SI (match_dup 1)
11923 (const_int 8))
11924 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11925 "arm_arch6
11926 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11927 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11928 "rev16\\t%0, %1"
11929 [(set_attr "arch" "t1,t2,32")
11930 (set_attr "length" "2,2,4")
11931 (set_attr "type" "rev")]
11932 )
11933
11934 (define_insn "arm_rev16si2_alt"
11935 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11936 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11937 (const_int 8))
11938 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11939 (and:SI (ashift:SI (match_dup 1)
11940 (const_int 8))
11941 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11942 "arm_arch6
11943 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11944 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11945 "rev16\\t%0, %1"
11946 [(set_attr "arch" "t1,t2,32")
11947 (set_attr "length" "2,2,4")
11948 (set_attr "type" "rev")]
11949 )
11950
11951 (define_expand "bswaphi2"
11952 [(set (match_operand:HI 0 "s_register_operand" "=r")
11953 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11954 "arm_arch6"
11955 ""
11956 )
11957
11958 ;; Patterns for LDRD/STRD in Thumb2 mode
11959
11960 (define_insn "*thumb2_ldrd"
11961 [(set (match_operand:SI 0 "s_register_operand" "=r")
11962 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11963 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11964 (set (match_operand:SI 3 "s_register_operand" "=r")
11965 (mem:SI (plus:SI (match_dup 1)
11966 (match_operand:SI 4 "const_int_operand" ""))))]
11967 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11968 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11969 && (operands_ok_ldrd_strd (operands[0], operands[3],
11970 operands[1], INTVAL (operands[2]),
11971 false, true))"
11972 "ldrd%?\t%0, %3, [%1, %2]"
11973 [(set_attr "type" "load_8")
11974 (set_attr "predicable" "yes")])
11975
11976 (define_insn "*thumb2_ldrd_base"
11977 [(set (match_operand:SI 0 "s_register_operand" "=r")
11978 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11979 (set (match_operand:SI 2 "s_register_operand" "=r")
11980 (mem:SI (plus:SI (match_dup 1)
11981 (const_int 4))))]
11982 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11983 && (operands_ok_ldrd_strd (operands[0], operands[2],
11984 operands[1], 0, false, true))"
11985 "ldrd%?\t%0, %2, [%1]"
11986 [(set_attr "type" "load_8")
11987 (set_attr "predicable" "yes")])
11988
11989 (define_insn "*thumb2_ldrd_base_neg"
11990 [(set (match_operand:SI 0 "s_register_operand" "=r")
11991 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11992 (const_int -4))))
11993 (set (match_operand:SI 2 "s_register_operand" "=r")
11994 (mem:SI (match_dup 1)))]
11995 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11996 && (operands_ok_ldrd_strd (operands[0], operands[2],
11997 operands[1], -4, false, true))"
11998 "ldrd%?\t%0, %2, [%1, #-4]"
11999 [(set_attr "type" "load_8")
12000 (set_attr "predicable" "yes")])
12001
12002 (define_insn "*thumb2_strd"
12003 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12004 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
12005 (match_operand:SI 2 "s_register_operand" "r"))
12006 (set (mem:SI (plus:SI (match_dup 0)
12007 (match_operand:SI 3 "const_int_operand" "")))
12008 (match_operand:SI 4 "s_register_operand" "r"))]
12009 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12010 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
12011 && (operands_ok_ldrd_strd (operands[2], operands[4],
12012 operands[0], INTVAL (operands[1]),
12013 false, false))"
12014 "strd%?\t%2, %4, [%0, %1]"
12015 [(set_attr "type" "store_8")
12016 (set_attr "predicable" "yes")])
12017
12018 (define_insn "*thumb2_strd_base"
12019 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
12020 (match_operand:SI 1 "s_register_operand" "r"))
12021 (set (mem:SI (plus:SI (match_dup 0)
12022 (const_int 4)))
12023 (match_operand:SI 2 "s_register_operand" "r"))]
12024 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12025 && (operands_ok_ldrd_strd (operands[1], operands[2],
12026 operands[0], 0, false, false))"
12027 "strd%?\t%1, %2, [%0]"
12028 [(set_attr "type" "store_8")
12029 (set_attr "predicable" "yes")])
12030
12031 (define_insn "*thumb2_strd_base_neg"
12032 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
12033 (const_int -4)))
12034 (match_operand:SI 1 "s_register_operand" "r"))
12035 (set (mem:SI (match_dup 0))
12036 (match_operand:SI 2 "s_register_operand" "r"))]
12037 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
12038 && (operands_ok_ldrd_strd (operands[1], operands[2],
12039 operands[0], -4, false, false))"
12040 "strd%?\t%1, %2, [%0, #-4]"
12041 [(set_attr "type" "store_8")
12042 (set_attr "predicable" "yes")])
12043
12044 ;; ARMv8 CRC32 instructions.
12045 (define_insn "<crc_variant>"
12046 [(set (match_operand:SI 0 "s_register_operand" "=r")
12047 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
12048 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
12049 CRC))]
12050 "TARGET_CRC32"
12051 "<crc_variant>\\t%0, %1, %2"
12052 [(set_attr "type" "crc")
12053 (set_attr "conds" "unconditional")]
12054 )
12055
12056 ;; Load the load/store double peephole optimizations.
12057 (include "ldrdstrd.md")
12058
12059 ;; Load the load/store multiple patterns
12060 (include "ldmstm.md")
12061
12062 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
12063 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
12064 ;; The operands are validated through the load_multiple_operation
12065 ;; match_parallel predicate rather than through constraints so enable it only
12066 ;; after reload.
12067 (define_insn "*load_multiple"
12068 [(match_parallel 0 "load_multiple_operation"
12069 [(set (match_operand:SI 2 "s_register_operand" "=rk")
12070 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
12071 ])]
12072 "TARGET_32BIT && reload_completed"
12073 "*
12074 {
12075 arm_output_multireg_pop (operands, /*return_pc=*/false,
12076 /*cond=*/const_true_rtx,
12077 /*reverse=*/false,
12078 /*update=*/false);
12079 return \"\";
12080 }
12081 "
12082 [(set_attr "predicable" "yes")]
12083 )
12084
12085 (define_expand "copysignsf3"
12086 [(match_operand:SF 0 "register_operand")
12087 (match_operand:SF 1 "register_operand")
12088 (match_operand:SF 2 "register_operand")]
12089 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12090 "{
12091 emit_move_insn (operands[0], operands[2]);
12092 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
12093 GEN_INT (31), GEN_INT (0),
12094 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
12095 DONE;
12096 }"
12097 )
12098
12099 (define_expand "copysigndf3"
12100 [(match_operand:DF 0 "register_operand")
12101 (match_operand:DF 1 "register_operand")
12102 (match_operand:DF 2 "register_operand")]
12103 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
12104 "{
12105 rtx op0_low = gen_lowpart (SImode, operands[0]);
12106 rtx op0_high = gen_highpart (SImode, operands[0]);
12107 rtx op1_low = gen_lowpart (SImode, operands[1]);
12108 rtx op1_high = gen_highpart (SImode, operands[1]);
12109 rtx op2_high = gen_highpart (SImode, operands[2]);
12110
12111 rtx scratch1 = gen_reg_rtx (SImode);
12112 rtx scratch2 = gen_reg_rtx (SImode);
12113 emit_move_insn (scratch1, op2_high);
12114 emit_move_insn (scratch2, op1_high);
12115
12116 emit_insn(gen_rtx_SET(scratch1,
12117 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
12118 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
12119 emit_move_insn (op0_low, op1_low);
12120 emit_move_insn (op0_high, scratch2);
12121
12122 DONE;
12123 }"
12124 )
12125
12126 ;; movmisalign patterns for HImode and SImode.
12127 (define_expand "movmisalign<mode>"
12128 [(match_operand:HSI 0 "general_operand")
12129 (match_operand:HSI 1 "general_operand")]
12130 "unaligned_access"
12131 {
12132 /* This pattern is not permitted to fail during expansion: if both arguments
12133 are non-registers (e.g. memory := constant), force operand 1 into a
12134 register. */
12135 rtx (* gen_unaligned_load)(rtx, rtx);
12136 rtx tmp_dest = operands[0];
12137 if (!s_register_operand (operands[0], <MODE>mode)
12138 && !s_register_operand (operands[1], <MODE>mode))
12139 operands[1] = force_reg (<MODE>mode, operands[1]);
12140
12141 if (<MODE>mode == HImode)
12142 {
12143 gen_unaligned_load = gen_unaligned_loadhiu;
12144 tmp_dest = gen_reg_rtx (SImode);
12145 }
12146 else
12147 gen_unaligned_load = gen_unaligned_loadsi;
12148
12149 if (MEM_P (operands[1]))
12150 {
12151 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
12152 if (<MODE>mode == HImode)
12153 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
12154 }
12155 else
12156 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
12157
12158 DONE;
12159 })
12160
12161 (define_insn "<cdp>"
12162 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12163 (match_operand:SI 1 "immediate_operand" "n")
12164 (match_operand:SI 2 "immediate_operand" "n")
12165 (match_operand:SI 3 "immediate_operand" "n")
12166 (match_operand:SI 4 "immediate_operand" "n")
12167 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
12168 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
12169 {
12170 arm_const_bounds (operands[0], 0, 16);
12171 arm_const_bounds (operands[1], 0, 16);
12172 arm_const_bounds (operands[2], 0, (1 << 5));
12173 arm_const_bounds (operands[3], 0, (1 << 5));
12174 arm_const_bounds (operands[4], 0, (1 << 5));
12175 arm_const_bounds (operands[5], 0, 8);
12176 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
12177 }
12178 [(set_attr "length" "4")
12179 (set_attr "type" "coproc")])
12180
12181 (define_insn "*ldc"
12182 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12183 (match_operand:SI 1 "immediate_operand" "n")
12184 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
12185 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
12186 {
12187 arm_const_bounds (operands[0], 0, 16);
12188 arm_const_bounds (operands[1], 0, (1 << 5));
12189 return "<ldc>\\tp%c0, CR%c1, %2";
12190 }
12191 [(set_attr "length" "4")
12192 (set_attr "type" "coproc")])
12193
12194 (define_insn "*stc"
12195 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12196 (match_operand:SI 1 "immediate_operand" "n")
12197 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
12198 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
12199 {
12200 arm_const_bounds (operands[0], 0, 16);
12201 arm_const_bounds (operands[1], 0, (1 << 5));
12202 return "<stc>\\tp%c0, CR%c1, %2";
12203 }
12204 [(set_attr "length" "4")
12205 (set_attr "type" "coproc")])
12206
12207 (define_expand "<ldc>"
12208 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12209 (match_operand:SI 1 "immediate_operand")
12210 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
12211 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
12212
12213 (define_expand "<stc>"
12214 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12215 (match_operand:SI 1 "immediate_operand")
12216 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12217 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12218
12219 (define_insn "<mcr>"
12220 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12221 (match_operand:SI 1 "immediate_operand" "n")
12222 (match_operand:SI 2 "s_register_operand" "r")
12223 (match_operand:SI 3 "immediate_operand" "n")
12224 (match_operand:SI 4 "immediate_operand" "n")
12225 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12226 (use (match_dup 2))]
12227 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12228 {
12229 arm_const_bounds (operands[0], 0, 16);
12230 arm_const_bounds (operands[1], 0, 8);
12231 arm_const_bounds (operands[3], 0, (1 << 5));
12232 arm_const_bounds (operands[4], 0, (1 << 5));
12233 arm_const_bounds (operands[5], 0, 8);
12234 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12235 }
12236 [(set_attr "length" "4")
12237 (set_attr "type" "coproc")])
12238
12239 (define_insn "<mrc>"
12240 [(set (match_operand:SI 0 "s_register_operand" "=r")
12241 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12242 (match_operand:SI 2 "immediate_operand" "n")
12243 (match_operand:SI 3 "immediate_operand" "n")
12244 (match_operand:SI 4 "immediate_operand" "n")
12245 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12246 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12247 {
12248 arm_const_bounds (operands[1], 0, 16);
12249 arm_const_bounds (operands[2], 0, 8);
12250 arm_const_bounds (operands[3], 0, (1 << 5));
12251 arm_const_bounds (operands[4], 0, (1 << 5));
12252 arm_const_bounds (operands[5], 0, 8);
12253 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12254 }
12255 [(set_attr "length" "4")
12256 (set_attr "type" "coproc")])
12257
12258 (define_insn "<mcrr>"
12259 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12260 (match_operand:SI 1 "immediate_operand" "n")
12261 (match_operand:DI 2 "s_register_operand" "r")
12262 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12263 (use (match_dup 2))]
12264 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12265 {
12266 arm_const_bounds (operands[0], 0, 16);
12267 arm_const_bounds (operands[1], 0, 8);
12268 arm_const_bounds (operands[3], 0, (1 << 5));
12269 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12270 }
12271 [(set_attr "length" "4")
12272 (set_attr "type" "coproc")])
12273
12274 (define_insn "<mrrc>"
12275 [(set (match_operand:DI 0 "s_register_operand" "=r")
12276 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12277 (match_operand:SI 2 "immediate_operand" "n")
12278 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12279 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12280 {
12281 arm_const_bounds (operands[1], 0, 16);
12282 arm_const_bounds (operands[2], 0, 8);
12283 arm_const_bounds (operands[3], 0, (1 << 5));
12284 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12285 }
12286 [(set_attr "length" "4")
12287 (set_attr "type" "coproc")])
12288
12289 (define_expand "speculation_barrier"
12290 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12291 "TARGET_EITHER"
12292 "
12293 /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
12294 have a usable barrier (and probably don't need one in practice).
12295 But to be safe if such code is run on later architectures, call a
12296 helper function in libgcc that will do the thing for the active
12297 system. */
12298 if (!(arm_arch7 || arm_arch8))
12299 {
12300 arm_emit_speculation_barrier_function ();
12301 DONE;
12302 }
12303 "
12304 )
12305
12306 ;; Generate a hard speculation barrier when we have not enabled speculation
12307 ;; tracking.
12308 (define_insn "*speculation_barrier_insn"
12309 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
12310 "arm_arch7 || arm_arch8"
12311 "isb\;dsb\\tsy"
12312 [(set_attr "type" "block")
12313 (set_attr "length" "8")]
12314 )
12315
12316 ;; Vector bits common to IWMMXT and Neon
12317 (include "vec-common.md")
12318 ;; Load the Intel Wireless Multimedia Extension patterns
12319 (include "iwmmxt.md")
12320 ;; Load the VFP co-processor patterns
12321 (include "vfp.md")
12322 ;; Thumb-1 patterns
12323 (include "thumb1.md")
12324 ;; Thumb-2 patterns
12325 (include "thumb2.md")
12326 ;; Neon patterns
12327 (include "neon.md")
12328 ;; Crypto patterns
12329 (include "crypto.md")
12330 ;; Synchronization Primitives
12331 (include "sync.md")
12332 ;; Fixed-point patterns
12333 (include "arm-fixed.md")