]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm.md
[ARM] Fix new constraints and attributes of SI/HI data movement patterns
[thirdparty/gcc.git] / gcc / config / arm / arm.md
1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2016 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
13
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 \f
26 ;;---------------------------------------------------------------------------
27 ;; Constants
28
29 ;; Register numbers -- All machine registers should be defined here
30 (define_constants
31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (IP_REGNUM 12) ; Scratch register
34 (SP_REGNUM 13) ; Stack pointer
35 (LR_REGNUM 14) ; Return address register
36 (PC_REGNUM 15) ; Program counter
37 (LAST_ARM_REGNUM 15) ;
38 (CC_REGNUM 100) ; Condition code pseudo register
39 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
40 ]
41 )
42 ;; 3rd operand to select_dominance_cc_mode
43 (define_constants
44 [(DOM_CC_X_AND_Y 0)
45 (DOM_CC_NX_OR_Y 1)
46 (DOM_CC_X_OR_Y 2)
47 ]
48 )
49 ;; conditional compare combination
50 (define_constants
51 [(CMP_CMP 0)
52 (CMN_CMP 1)
53 (CMP_CMN 2)
54 (CMN_CMN 3)
55 (NUM_OF_COND_CMP 4)
56 ]
57 )
58
59 \f
60 ;;---------------------------------------------------------------------------
61 ;; Attributes
62
63 ;; Processor type. This is created automatically from arm-cores.def.
64 (include "arm-tune.md")
65
66 ;; Instruction classification types
67 (include "types.md")
68
69 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70 ; generating ARM code. This is used to control the length of some insn
71 ; patterns that share the same RTL in both ARM and Thumb code.
72 (define_attr "is_thumb" "yes,no"
73 (const (if_then_else (symbol_ref "TARGET_THUMB")
74 (const_string "yes") (const_string "no"))))
75
76 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
78
79 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
80 (define_attr "is_thumb1" "yes,no"
81 (const (if_then_else (symbol_ref "TARGET_THUMB1")
82 (const_string "yes") (const_string "no"))))
83
84 ; We use this attribute to disable alternatives that can produce 32-bit
85 ; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
86 ; that contain 32-bit instructions.
87 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
88
89 ; This attribute is used to disable a predicated alternative when we have
90 ; arm_restrict_it.
91 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
92
93 ;; Operand number of an input operand that is shifted. Zero if the
94 ;; given instruction does not shift one of its input operands.
95 (define_attr "shift" "" (const_int 0))
96
97 ;; [For compatibility with AArch64 in pipeline models]
98 ;; Attribute that specifies whether or not the instruction touches fp
99 ;; registers.
100 (define_attr "fp" "no,yes" (const_string "no"))
101
102 ; Floating Point Unit. If we only have floating point emulation, then there
103 ; is no point in scheduling the floating point insns. (Well, for best
104 ; performance we should try and group them together).
105 (define_attr "fpu" "none,vfp"
106 (const (symbol_ref "arm_fpu_attr")))
107
108 ; Predicated means that the insn form is conditionally executed based on a
109 ; predicate. We default to 'no' because no Thumb patterns match this rule
110 ; and not all ARM insns do.
111 (define_attr "predicated" "yes,no" (const_string "no"))
112
113 ; LENGTH of an instruction (in bytes)
114 (define_attr "length" ""
115 (const_int 4))
116
117 ; The architecture which supports the instruction (or alternative).
118 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
119 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
120 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
121 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
122 ; Baseline. This attribute is used to compute attribute "enabled",
123 ; use type "any" to enable an alternative in all cases.
124 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
125 (const_string "any"))
126
127 (define_attr "arch_enabled" "no,yes"
128 (cond [(eq_attr "arch" "any")
129 (const_string "yes")
130
131 (and (eq_attr "arch" "a")
132 (match_test "TARGET_ARM"))
133 (const_string "yes")
134
135 (and (eq_attr "arch" "t")
136 (match_test "TARGET_THUMB"))
137 (const_string "yes")
138
139 (and (eq_attr "arch" "t1")
140 (match_test "TARGET_THUMB1"))
141 (const_string "yes")
142
143 (and (eq_attr "arch" "t2")
144 (match_test "TARGET_THUMB2"))
145 (const_string "yes")
146
147 (and (eq_attr "arch" "32")
148 (match_test "TARGET_32BIT"))
149 (const_string "yes")
150
151 (and (eq_attr "arch" "v6")
152 (match_test "TARGET_32BIT && arm_arch6"))
153 (const_string "yes")
154
155 (and (eq_attr "arch" "nov6")
156 (match_test "TARGET_32BIT && !arm_arch6"))
157 (const_string "yes")
158
159 (and (eq_attr "arch" "v6t2")
160 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
161 (const_string "yes")
162
163 (and (eq_attr "arch" "v8mb")
164 (match_test "TARGET_THUMB1 && arm_arch8"))
165 (const_string "yes")
166
167 (and (eq_attr "arch" "avoid_neon_for_64bits")
168 (match_test "TARGET_NEON")
169 (not (match_test "TARGET_PREFER_NEON_64BITS")))
170 (const_string "yes")
171
172 (and (eq_attr "arch" "neon_for_64bits")
173 (match_test "TARGET_NEON")
174 (match_test "TARGET_PREFER_NEON_64BITS"))
175 (const_string "yes")
176
177 (and (eq_attr "arch" "iwmmxt2")
178 (match_test "TARGET_REALLY_IWMMXT2"))
179 (const_string "yes")
180
181 (and (eq_attr "arch" "armv6_or_vfpv3")
182 (match_test "arm_arch6 || TARGET_VFP3"))
183 (const_string "yes")
184
185 (and (eq_attr "arch" "neon")
186 (match_test "TARGET_NEON"))
187 (const_string "yes")
188 ]
189
190 (const_string "no")))
191
192 (define_attr "opt" "any,speed,size"
193 (const_string "any"))
194
195 (define_attr "opt_enabled" "no,yes"
196 (cond [(eq_attr "opt" "any")
197 (const_string "yes")
198
199 (and (eq_attr "opt" "speed")
200 (match_test "optimize_function_for_speed_p (cfun)"))
201 (const_string "yes")
202
203 (and (eq_attr "opt" "size")
204 (match_test "optimize_function_for_size_p (cfun)"))
205 (const_string "yes")]
206 (const_string "no")))
207
208 (define_attr "use_literal_pool" "no,yes"
209 (cond [(and (eq_attr "type" "f_loads,f_loadd")
210 (match_test "CONSTANT_P (operands[1])"))
211 (const_string "yes")]
212 (const_string "no")))
213
214 ; Enable all alternatives that are both arch_enabled and insn_enabled.
215 ; FIXME:: opt_enabled has been temporarily removed till the time we have
216 ; an attribute that allows the use of such alternatives.
217 ; This depends on caching of speed_p, size_p on a per
218 ; alternative basis. The problem is that the enabled attribute
219 ; cannot depend on any state that is not cached or is not constant
220 ; for a compilation unit. We probably need a generic "hot/cold"
221 ; alternative which if implemented can help with this. We disable this
222 ; until such a time as this is implemented and / or the improvements or
223 ; regressions with removing this attribute are double checked.
224 ; See ashldi3_neon and <shift>di3_neon in neon.md.
225
226 (define_attr "enabled" "no,yes"
227 (cond [(and (eq_attr "predicable_short_it" "no")
228 (and (eq_attr "predicated" "yes")
229 (match_test "arm_restrict_it")))
230 (const_string "no")
231
232 (and (eq_attr "enabled_for_depr_it" "no")
233 (match_test "arm_restrict_it"))
234 (const_string "no")
235
236 (and (eq_attr "use_literal_pool" "yes")
237 (match_test "arm_disable_literal_pool"))
238 (const_string "no")
239
240 (eq_attr "arch_enabled" "no")
241 (const_string "no")]
242 (const_string "yes")))
243
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed. If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address. It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
256
257 (define_attr "pool_range" ""
258 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259 (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262 (attr "arm_neg_pool_range")))
263
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268 [(set_attr "conds" "clob")
269 (set_attr "length" "4")
270 (set_attr "pool_range" "250")])
271
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
275
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions. It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
279 ;
280 ; USE means that the condition codes are used by the insn in the process of
281 ; outputting code, this means (at present) that we can't use the insn in
282 ; inlined branches
283 ;
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ; well defined manner.
286 ;
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ; they are altered at all
289 ;
290 ; UNCONDITIONAL means the instruction can not be conditionally executed and
291 ; that the instruction does not use or alter the condition codes.
292 ;
293 ; NOCOND means that the instruction does not use or alter the condition
294 ; codes but can be converted into a conditionally exectuted instruction.
295
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
297 (if_then_else
298 (ior (eq_attr "is_thumb1" "yes")
299 (eq_attr "type" "call"))
300 (const_string "clob")
301 (if_then_else (eq_attr "is_neon_type" "no")
302 (const_string "nocond")
303 (const_string "unconditional"))))
304
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by
307 ; gen...). We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
310
311 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
312 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
316
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor. Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320 (if_then_else (eq_attr "type"
321 "block,call,load1")
322 (const_string "yes")
323 (const_string "no")))
324
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328 (if_then_else (eq_attr "type"
329 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345 (const_string "single")
346 (const_string "multi")))
347
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label. Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
351
352
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
356
357 ;;---------------------------------------------------------------------------
358 ;; Unspecs
359
360 (include "unspecs.md")
361
362 ;;---------------------------------------------------------------------------
363 ;; Mode iterators
364
365 (include "iterators.md")
366
367 ;;---------------------------------------------------------------------------
368 ;; Predicates
369
370 (include "predicates.md")
371 (include "constraints.md")
372
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
375
376 (define_attr "tune_cortexr4" "yes,no"
377 (const (if_then_else
378 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
379 (const_string "yes")
380 (const_string "no"))))
381
382 ;; True if the generic scheduling description should be used.
383
384 (define_attr "generic_sched" "yes,no"
385 (const (if_then_else
386 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
388 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389 cortexa9,cortexa12,cortexa15,cortexa17,\
390 cortexa53,cortexa57,cortexm4,cortexm7,\
391 exynosm1,marvell_pj4,xgene1")
392 (eq_attr "tune_cortexr4" "yes"))
393 (const_string "no")
394 (const_string "yes"))))
395
396 (define_attr "generic_vfp" "yes,no"
397 (const (if_then_else
398 (and (eq_attr "fpu" "vfp")
399 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
400 cortexa8,cortexa9,cortexa53,cortexm4,\
401 cortexm7,marvell_pj4,xgene1")
402 (eq_attr "tune_cortexr4" "no"))
403 (const_string "yes")
404 (const_string "no"))))
405
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
412 (include "fa526.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
431 (include "vfp11.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
434
435 \f
436 ;;---------------------------------------------------------------------------
437 ;; Insn patterns
438 ;;
439 ;; Addition insns.
440
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
444
445 (define_expand "adddi3"
446 [(parallel
447 [(set (match_operand:DI 0 "s_register_operand" "")
448 (plus:DI (match_operand:DI 1 "s_register_operand" "")
449 (match_operand:DI 2 "arm_adddi_operand" "")))
450 (clobber (reg:CC CC_REGNUM))])]
451 "TARGET_EITHER"
452 "
453 if (TARGET_THUMB1)
454 {
455 if (!REG_P (operands[1]))
456 operands[1] = force_reg (DImode, operands[1]);
457 if (!REG_P (operands[2]))
458 operands[2] = force_reg (DImode, operands[2]);
459 }
460 "
461 )
462
463 (define_insn_and_split "*arm_adddi3"
464 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
465 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
466 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
467 (clobber (reg:CC CC_REGNUM))]
468 "TARGET_32BIT && !TARGET_NEON"
469 "#"
470 "TARGET_32BIT && reload_completed
471 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
472 [(parallel [(set (reg:CC_C CC_REGNUM)
473 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
474 (match_dup 1)))
475 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
476 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
477 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
478 "
479 {
480 operands[3] = gen_highpart (SImode, operands[0]);
481 operands[0] = gen_lowpart (SImode, operands[0]);
482 operands[4] = gen_highpart (SImode, operands[1]);
483 operands[1] = gen_lowpart (SImode, operands[1]);
484 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
485 operands[2] = gen_lowpart (SImode, operands[2]);
486 }"
487 [(set_attr "conds" "clob")
488 (set_attr "length" "8")
489 (set_attr "type" "multiple")]
490 )
491
492 (define_insn_and_split "*adddi_sesidi_di"
493 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
494 (plus:DI (sign_extend:DI
495 (match_operand:SI 2 "s_register_operand" "r,r"))
496 (match_operand:DI 1 "s_register_operand" "0,r")))
497 (clobber (reg:CC CC_REGNUM))]
498 "TARGET_32BIT"
499 "#"
500 "TARGET_32BIT && reload_completed"
501 [(parallel [(set (reg:CC_C CC_REGNUM)
502 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
503 (match_dup 1)))
504 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
505 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
506 (const_int 31))
507 (match_dup 4))
508 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
509 "
510 {
511 operands[3] = gen_highpart (SImode, operands[0]);
512 operands[0] = gen_lowpart (SImode, operands[0]);
513 operands[4] = gen_highpart (SImode, operands[1]);
514 operands[1] = gen_lowpart (SImode, operands[1]);
515 operands[2] = gen_lowpart (SImode, operands[2]);
516 }"
517 [(set_attr "conds" "clob")
518 (set_attr "length" "8")
519 (set_attr "type" "multiple")]
520 )
521
522 (define_insn_and_split "*adddi_zesidi_di"
523 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
524 (plus:DI (zero_extend:DI
525 (match_operand:SI 2 "s_register_operand" "r,r"))
526 (match_operand:DI 1 "s_register_operand" "0,r")))
527 (clobber (reg:CC CC_REGNUM))]
528 "TARGET_32BIT"
529 "#"
530 "TARGET_32BIT && reload_completed"
531 [(parallel [(set (reg:CC_C CC_REGNUM)
532 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
533 (match_dup 1)))
534 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
535 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
536 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
537 "
538 {
539 operands[3] = gen_highpart (SImode, operands[0]);
540 operands[0] = gen_lowpart (SImode, operands[0]);
541 operands[4] = gen_highpart (SImode, operands[1]);
542 operands[1] = gen_lowpart (SImode, operands[1]);
543 operands[2] = gen_lowpart (SImode, operands[2]);
544 }"
545 [(set_attr "conds" "clob")
546 (set_attr "length" "8")
547 (set_attr "type" "multiple")]
548 )
549
550 (define_expand "addv<mode>4"
551 [(match_operand:SIDI 0 "register_operand")
552 (match_operand:SIDI 1 "register_operand")
553 (match_operand:SIDI 2 "register_operand")
554 (match_operand 3 "")]
555 "TARGET_32BIT"
556 {
557 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
558 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
559
560 DONE;
561 })
562
563 (define_expand "uaddv<mode>4"
564 [(match_operand:SIDI 0 "register_operand")
565 (match_operand:SIDI 1 "register_operand")
566 (match_operand:SIDI 2 "register_operand")
567 (match_operand 3 "")]
568 "TARGET_32BIT"
569 {
570 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
571 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
572
573 DONE;
574 })
575
576 (define_expand "addsi3"
577 [(set (match_operand:SI 0 "s_register_operand" "")
578 (plus:SI (match_operand:SI 1 "s_register_operand" "")
579 (match_operand:SI 2 "reg_or_int_operand" "")))]
580 "TARGET_EITHER"
581 "
582 if (TARGET_32BIT && CONST_INT_P (operands[2]))
583 {
584 arm_split_constant (PLUS, SImode, NULL_RTX,
585 INTVAL (operands[2]), operands[0], operands[1],
586 optimize && can_create_pseudo_p ());
587 DONE;
588 }
589 "
590 )
591
592 ; If there is a scratch available, this will be faster than synthesizing the
593 ; addition.
594 (define_peephole2
595 [(match_scratch:SI 3 "r")
596 (set (match_operand:SI 0 "arm_general_register_operand" "")
597 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
598 (match_operand:SI 2 "const_int_operand" "")))]
599 "TARGET_32BIT &&
600 !(const_ok_for_arm (INTVAL (operands[2]))
601 || const_ok_for_arm (-INTVAL (operands[2])))
602 && const_ok_for_arm (~INTVAL (operands[2]))"
603 [(set (match_dup 3) (match_dup 2))
604 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
605 ""
606 )
607
608 ;; The r/r/k alternative is required when reloading the address
609 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
610 ;; put the duplicated register first, and not try the commutative version.
611 (define_insn_and_split "*arm_addsi3"
612 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,r ,k ,r ,k,k,r ,k ,r")
613 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,rk,k ,rk,k,r,rk,k ,rk")
614 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
615 "TARGET_32BIT"
616 "@
617 add%?\\t%0, %0, %2
618 add%?\\t%0, %1, %2
619 add%?\\t%0, %1, %2
620 add%?\\t%0, %1, %2
621 add%?\\t%0, %1, %2
622 add%?\\t%0, %1, %2
623 add%?\\t%0, %2, %1
624 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,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")
646 (set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
647 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
648 (const_string "alu_imm")
649 (const_string "alu_sreg")))
650 ]
651 )
652
653 (define_insn_and_split "adddi3_compareV"
654 [(set (reg:CC_V CC_REGNUM)
655 (ne:CC_V
656 (plus:TI
657 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
658 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
659 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
660 (set (match_operand:DI 0 "register_operand" "=&r")
661 (plus:DI (match_dup 1) (match_dup 2)))]
662 "TARGET_32BIT"
663 "#"
664 "&& reload_completed"
665 [(parallel [(set (reg:CC_C CC_REGNUM)
666 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
667 (match_dup 1)))
668 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
669 (parallel [(set (reg:CC_V CC_REGNUM)
670 (ne:CC_V
671 (plus:DI (plus:DI
672 (sign_extend:DI (match_dup 4))
673 (sign_extend:DI (match_dup 5)))
674 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
675 (plus:DI (sign_extend:DI
676 (plus:SI (match_dup 4) (match_dup 5)))
677 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
678 (set (match_dup 3) (plus:SI (plus:SI
679 (match_dup 4) (match_dup 5))
680 (ltu:SI (reg:CC_C CC_REGNUM)
681 (const_int 0))))])]
682 "
683 {
684 operands[3] = gen_highpart (SImode, operands[0]);
685 operands[0] = gen_lowpart (SImode, operands[0]);
686 operands[4] = gen_highpart (SImode, operands[1]);
687 operands[1] = gen_lowpart (SImode, operands[1]);
688 operands[5] = gen_highpart (SImode, operands[2]);
689 operands[2] = gen_lowpart (SImode, operands[2]);
690 }"
691 [(set_attr "conds" "set")
692 (set_attr "length" "8")
693 (set_attr "type" "multiple")]
694 )
695
696 (define_insn "addsi3_compareV"
697 [(set (reg:CC_V CC_REGNUM)
698 (ne:CC_V
699 (plus:DI
700 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
701 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
702 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
703 (set (match_operand:SI 0 "register_operand" "=r")
704 (plus:SI (match_dup 1) (match_dup 2)))]
705 "TARGET_32BIT"
706 "adds%?\\t%0, %1, %2"
707 [(set_attr "conds" "set")
708 (set_attr "type" "alus_sreg")]
709 )
710
711 (define_insn "*addsi3_compareV_upper"
712 [(set (reg:CC_V CC_REGNUM)
713 (ne:CC_V
714 (plus:DI
715 (plus:DI
716 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
717 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
718 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
719 (plus:DI (sign_extend:DI
720 (plus:SI (match_dup 1) (match_dup 2)))
721 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
722 (set (match_operand:SI 0 "register_operand" "=r")
723 (plus:SI
724 (plus:SI (match_dup 1) (match_dup 2))
725 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
726 "TARGET_32BIT"
727 "adcs%?\\t%0, %1, %2"
728 [(set_attr "conds" "set")
729 (set_attr "type" "adcs_reg")]
730 )
731
732 (define_insn_and_split "adddi3_compareC"
733 [(set (reg:CC_C CC_REGNUM)
734 (ne:CC_C
735 (plus:TI
736 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
737 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
738 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
739 (set (match_operand:DI 0 "register_operand" "=&r")
740 (plus:DI (match_dup 1) (match_dup 2)))]
741 "TARGET_32BIT"
742 "#"
743 "&& reload_completed"
744 [(parallel [(set (reg:CC_C CC_REGNUM)
745 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
746 (match_dup 1)))
747 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
748 (parallel [(set (reg:CC_C CC_REGNUM)
749 (ne:CC_C
750 (plus:DI (plus:DI
751 (zero_extend:DI (match_dup 4))
752 (zero_extend:DI (match_dup 5)))
753 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
754 (plus:DI (zero_extend:DI
755 (plus:SI (match_dup 4) (match_dup 5)))
756 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
757 (set (match_dup 3) (plus:SI
758 (plus:SI (match_dup 4) (match_dup 5))
759 (ltu:SI (reg:CC_C CC_REGNUM)
760 (const_int 0))))])]
761 "
762 {
763 operands[3] = gen_highpart (SImode, operands[0]);
764 operands[0] = gen_lowpart (SImode, operands[0]);
765 operands[4] = gen_highpart (SImode, operands[1]);
766 operands[5] = gen_highpart (SImode, operands[2]);
767 operands[1] = gen_lowpart (SImode, operands[1]);
768 operands[2] = gen_lowpart (SImode, operands[2]);
769 }"
770 [(set_attr "conds" "set")
771 (set_attr "length" "8")
772 (set_attr "type" "multiple")]
773 )
774
775 (define_insn "*addsi3_compareC_upper"
776 [(set (reg:CC_C CC_REGNUM)
777 (ne:CC_C
778 (plus:DI
779 (plus:DI
780 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
781 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
782 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
783 (plus:DI (zero_extend:DI
784 (plus:SI (match_dup 1) (match_dup 2)))
785 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
786 (set (match_operand:SI 0 "register_operand" "=r")
787 (plus:SI
788 (plus:SI (match_dup 1) (match_dup 2))
789 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
790 "TARGET_32BIT"
791 "adcs%?\\t%0, %1, %2"
792 [(set_attr "conds" "set")
793 (set_attr "type" "adcs_reg")]
794 )
795
796 (define_insn "addsi3_compareC"
797 [(set (reg:CC_C CC_REGNUM)
798 (ne:CC_C
799 (plus:DI
800 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
801 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
802 (zero_extend:DI
803 (plus:SI (match_dup 1) (match_dup 2)))))
804 (set (match_operand:SI 0 "register_operand" "=r")
805 (plus:SI (match_dup 1) (match_dup 2)))]
806 "TARGET_32BIT"
807 "adds%?\\t%0, %1, %2"
808 [(set_attr "conds" "set")
809 (set_attr "type" "alus_sreg")]
810 )
811
812 (define_insn "addsi3_compare0"
813 [(set (reg:CC_NOOV CC_REGNUM)
814 (compare:CC_NOOV
815 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
816 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
817 (const_int 0)))
818 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
819 (plus:SI (match_dup 1) (match_dup 2)))]
820 "TARGET_ARM"
821 "@
822 adds%?\\t%0, %1, %2
823 subs%?\\t%0, %1, #%n2
824 adds%?\\t%0, %1, %2"
825 [(set_attr "conds" "set")
826 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
827 )
828
829 (define_insn "*addsi3_compare0_scratch"
830 [(set (reg:CC_NOOV CC_REGNUM)
831 (compare:CC_NOOV
832 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
833 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
834 (const_int 0)))]
835 "TARGET_ARM"
836 "@
837 cmn%?\\t%0, %1
838 cmp%?\\t%0, #%n1
839 cmn%?\\t%0, %1"
840 [(set_attr "conds" "set")
841 (set_attr "predicable" "yes")
842 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
843 )
844
845 (define_insn "*compare_negsi_si"
846 [(set (reg:CC_Z CC_REGNUM)
847 (compare:CC_Z
848 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
849 (match_operand:SI 1 "s_register_operand" "l,r")))]
850 "TARGET_32BIT"
851 "cmn%?\\t%1, %0"
852 [(set_attr "conds" "set")
853 (set_attr "predicable" "yes")
854 (set_attr "arch" "t2,*")
855 (set_attr "length" "2,4")
856 (set_attr "predicable_short_it" "yes,no")
857 (set_attr "type" "alus_sreg")]
858 )
859
860 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
861 ;; addend is a constant.
862 (define_insn "cmpsi2_addneg"
863 [(set (reg:CC CC_REGNUM)
864 (compare:CC
865 (match_operand:SI 1 "s_register_operand" "r,r")
866 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
867 (set (match_operand:SI 0 "s_register_operand" "=r,r")
868 (plus:SI (match_dup 1)
869 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
870 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
871 "@
872 adds%?\\t%0, %1, %3
873 subs%?\\t%0, %1, #%n3"
874 [(set_attr "conds" "set")
875 (set_attr "type" "alus_sreg")]
876 )
877
878 ;; Convert the sequence
879 ;; sub rd, rn, #1
880 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
881 ;; bne dest
882 ;; into
883 ;; subs rd, rn, #1
884 ;; bcs dest ((unsigned)rn >= 1)
885 ;; similarly for the beq variant using bcc.
886 ;; This is a common looping idiom (while (n--))
887 (define_peephole2
888 [(set (match_operand:SI 0 "arm_general_register_operand" "")
889 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
890 (const_int -1)))
891 (set (match_operand 2 "cc_register" "")
892 (compare (match_dup 0) (const_int -1)))
893 (set (pc)
894 (if_then_else (match_operator 3 "equality_operator"
895 [(match_dup 2) (const_int 0)])
896 (match_operand 4 "" "")
897 (match_operand 5 "" "")))]
898 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
899 [(parallel[
900 (set (match_dup 2)
901 (compare:CC
902 (match_dup 1) (const_int 1)))
903 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
904 (set (pc)
905 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
906 (match_dup 4)
907 (match_dup 5)))]
908 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
909 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
910 ? GEU : LTU),
911 VOIDmode,
912 operands[2], const0_rtx);"
913 )
914
915 ;; The next four insns work because they compare the result with one of
916 ;; the operands, and we know that the use of the condition code is
917 ;; either GEU or LTU, so we can use the carry flag from the addition
918 ;; instead of doing the compare a second time.
919 (define_insn "*addsi3_compare_op1"
920 [(set (reg:CC_C CC_REGNUM)
921 (compare:CC_C
922 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
923 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
924 (match_dup 1)))
925 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
926 (plus:SI (match_dup 1) (match_dup 2)))]
927 "TARGET_32BIT"
928 "@
929 adds%?\\t%0, %1, %2
930 subs%?\\t%0, %1, #%n2
931 adds%?\\t%0, %1, %2"
932 [(set_attr "conds" "set")
933 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
934 )
935
936 (define_insn "*addsi3_compare_op2"
937 [(set (reg:CC_C CC_REGNUM)
938 (compare:CC_C
939 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
940 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
941 (match_dup 2)))
942 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
943 (plus:SI (match_dup 1) (match_dup 2)))]
944 "TARGET_32BIT"
945 "@
946 adds%?\\t%0, %1, %2
947 subs%?\\t%0, %1, #%n2
948 adds%?\\t%0, %1, %2"
949 [(set_attr "conds" "set")
950 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
951 )
952
953 (define_insn "*compare_addsi2_op0"
954 [(set (reg:CC_C CC_REGNUM)
955 (compare:CC_C
956 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
957 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
958 (match_dup 0)))]
959 "TARGET_32BIT"
960 "@
961 cmp%?\\t%0, #%n1
962 cmn%?\\t%0, %1
963 cmn%?\\t%0, %1
964 cmp%?\\t%0, #%n1
965 cmn%?\\t%0, %1"
966 [(set_attr "conds" "set")
967 (set_attr "predicable" "yes")
968 (set_attr "arch" "t2,t2,*,*,*")
969 (set_attr "predicable_short_it" "yes,yes,no,no,no")
970 (set_attr "length" "2,2,4,4,4")
971 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
972 )
973
974 (define_insn "*compare_addsi2_op1"
975 [(set (reg:CC_C CC_REGNUM)
976 (compare:CC_C
977 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
978 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
979 (match_dup 1)))]
980 "TARGET_32BIT"
981 "@
982 cmp%?\\t%0, #%n1
983 cmn%?\\t%0, %1
984 cmn%?\\t%0, %1
985 cmp%?\\t%0, #%n1
986 cmn%?\\t%0, %1"
987 [(set_attr "conds" "set")
988 (set_attr "predicable" "yes")
989 (set_attr "arch" "t2,t2,*,*,*")
990 (set_attr "predicable_short_it" "yes,yes,no,no,no")
991 (set_attr "length" "2,2,4,4,4")
992 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
993 )
994
995 (define_insn "*addsi3_carryin_<optab>"
996 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
997 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
998 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
999 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1000 "TARGET_32BIT"
1001 "@
1002 adc%?\\t%0, %1, %2
1003 adc%?\\t%0, %1, %2
1004 sbc%?\\t%0, %1, #%B2"
1005 [(set_attr "conds" "use")
1006 (set_attr "predicable" "yes")
1007 (set_attr "arch" "t2,*,*")
1008 (set_attr "length" "4")
1009 (set_attr "predicable_short_it" "yes,no,no")
1010 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1011 )
1012
1013 (define_insn "*addsi3_carryin_alt2_<optab>"
1014 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1015 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1016 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1017 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1018 "TARGET_32BIT"
1019 "@
1020 adc%?\\t%0, %1, %2
1021 adc%?\\t%0, %1, %2
1022 sbc%?\\t%0, %1, #%B2"
1023 [(set_attr "conds" "use")
1024 (set_attr "predicable" "yes")
1025 (set_attr "arch" "t2,*,*")
1026 (set_attr "length" "4")
1027 (set_attr "predicable_short_it" "yes,no,no")
1028 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1029 )
1030
1031 (define_insn "*addsi3_carryin_shift_<optab>"
1032 [(set (match_operand:SI 0 "s_register_operand" "=r")
1033 (plus:SI (plus:SI
1034 (match_operator:SI 2 "shift_operator"
1035 [(match_operand:SI 3 "s_register_operand" "r")
1036 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1037 (match_operand:SI 1 "s_register_operand" "r"))
1038 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1039 "TARGET_32BIT"
1040 "adc%?\\t%0, %1, %3%S2"
1041 [(set_attr "conds" "use")
1042 (set_attr "predicable" "yes")
1043 (set_attr "predicable_short_it" "no")
1044 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1045 (const_string "alu_shift_imm")
1046 (const_string "alu_shift_reg")))]
1047 )
1048
1049 (define_insn "*addsi3_carryin_clobercc_<optab>"
1050 [(set (match_operand:SI 0 "s_register_operand" "=r")
1051 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1052 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1053 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1054 (clobber (reg:CC CC_REGNUM))]
1055 "TARGET_32BIT"
1056 "adcs%?\\t%0, %1, %2"
1057 [(set_attr "conds" "set")
1058 (set_attr "type" "adcs_reg")]
1059 )
1060
1061 (define_expand "subv<mode>4"
1062 [(match_operand:SIDI 0 "register_operand")
1063 (match_operand:SIDI 1 "register_operand")
1064 (match_operand:SIDI 2 "register_operand")
1065 (match_operand 3 "")]
1066 "TARGET_32BIT"
1067 {
1068 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1069 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1070
1071 DONE;
1072 })
1073
1074 (define_expand "usubv<mode>4"
1075 [(match_operand:SIDI 0 "register_operand")
1076 (match_operand:SIDI 1 "register_operand")
1077 (match_operand:SIDI 2 "register_operand")
1078 (match_operand 3 "")]
1079 "TARGET_32BIT"
1080 {
1081 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1082 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1083
1084 DONE;
1085 })
1086
1087 (define_insn_and_split "subdi3_compare1"
1088 [(set (reg:CC CC_REGNUM)
1089 (compare:CC
1090 (match_operand:DI 1 "register_operand" "r")
1091 (match_operand:DI 2 "register_operand" "r")))
1092 (set (match_operand:DI 0 "register_operand" "=&r")
1093 (minus:DI (match_dup 1) (match_dup 2)))]
1094 "TARGET_32BIT"
1095 "#"
1096 "&& reload_completed"
1097 [(parallel [(set (reg:CC CC_REGNUM)
1098 (compare:CC (match_dup 1) (match_dup 2)))
1099 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1100 (parallel [(set (reg:CC CC_REGNUM)
1101 (compare:CC (match_dup 4) (match_dup 5)))
1102 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1103 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1104 {
1105 operands[3] = gen_highpart (SImode, operands[0]);
1106 operands[0] = gen_lowpart (SImode, operands[0]);
1107 operands[4] = gen_highpart (SImode, operands[1]);
1108 operands[1] = gen_lowpart (SImode, operands[1]);
1109 operands[5] = gen_highpart (SImode, operands[2]);
1110 operands[2] = gen_lowpart (SImode, operands[2]);
1111 }
1112 [(set_attr "conds" "set")
1113 (set_attr "length" "8")
1114 (set_attr "type" "multiple")]
1115 )
1116
1117 (define_insn "subsi3_compare1"
1118 [(set (reg:CC CC_REGNUM)
1119 (compare:CC
1120 (match_operand:SI 1 "register_operand" "r")
1121 (match_operand:SI 2 "register_operand" "r")))
1122 (set (match_operand:SI 0 "register_operand" "=r")
1123 (minus:SI (match_dup 1) (match_dup 2)))]
1124 "TARGET_32BIT"
1125 "subs%?\\t%0, %1, %2"
1126 [(set_attr "conds" "set")
1127 (set_attr "type" "alus_sreg")]
1128 )
1129
1130 (define_insn "*subsi3_carryin"
1131 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1132 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
1133 (match_operand:SI 2 "s_register_operand" "r,r"))
1134 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1135 "TARGET_32BIT"
1136 "@
1137 sbc%?\\t%0, %1, %2
1138 rsc%?\\t%0, %2, %1"
1139 [(set_attr "conds" "use")
1140 (set_attr "arch" "*,a")
1141 (set_attr "predicable" "yes")
1142 (set_attr "predicable_short_it" "no")
1143 (set_attr "type" "adc_reg,adc_imm")]
1144 )
1145
1146 (define_insn "*subsi3_carryin_const"
1147 [(set (match_operand:SI 0 "s_register_operand" "=r")
1148 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1149 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1150 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1151 "TARGET_32BIT"
1152 "sbc\\t%0, %1, #%B2"
1153 [(set_attr "conds" "use")
1154 (set_attr "type" "adc_imm")]
1155 )
1156
1157 (define_insn "*subsi3_carryin_compare"
1158 [(set (reg:CC CC_REGNUM)
1159 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1160 (match_operand:SI 2 "s_register_operand" "r")))
1161 (set (match_operand:SI 0 "s_register_operand" "=r")
1162 (minus:SI (minus:SI (match_dup 1)
1163 (match_dup 2))
1164 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1165 "TARGET_32BIT"
1166 "sbcs\\t%0, %1, %2"
1167 [(set_attr "conds" "set")
1168 (set_attr "type" "adcs_reg")]
1169 )
1170
1171 (define_insn "*subsi3_carryin_compare_const"
1172 [(set (reg:CC CC_REGNUM)
1173 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1174 (match_operand:SI 2 "arm_not_operand" "K")))
1175 (set (match_operand:SI 0 "s_register_operand" "=r")
1176 (minus:SI (plus:SI (match_dup 1)
1177 (match_dup 2))
1178 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1179 "TARGET_32BIT"
1180 "sbcs\\t%0, %1, #%B2"
1181 [(set_attr "conds" "set")
1182 (set_attr "type" "adcs_imm")]
1183 )
1184
1185 (define_insn "*subsi3_carryin_shift"
1186 [(set (match_operand:SI 0 "s_register_operand" "=r")
1187 (minus:SI (minus:SI
1188 (match_operand:SI 1 "s_register_operand" "r")
1189 (match_operator:SI 2 "shift_operator"
1190 [(match_operand:SI 3 "s_register_operand" "r")
1191 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1192 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1193 "TARGET_32BIT"
1194 "sbc%?\\t%0, %1, %3%S2"
1195 [(set_attr "conds" "use")
1196 (set_attr "predicable" "yes")
1197 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1198 (const_string "alu_shift_imm")
1199 (const_string "alu_shift_reg")))]
1200 )
1201
1202 (define_insn "*rsbsi3_carryin_shift"
1203 [(set (match_operand:SI 0 "s_register_operand" "=r")
1204 (minus:SI (minus:SI
1205 (match_operator:SI 2 "shift_operator"
1206 [(match_operand:SI 3 "s_register_operand" "r")
1207 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1208 (match_operand:SI 1 "s_register_operand" "r"))
1209 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1210 "TARGET_ARM"
1211 "rsc%?\\t%0, %1, %3%S2"
1212 [(set_attr "conds" "use")
1213 (set_attr "predicable" "yes")
1214 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1215 (const_string "alu_shift_imm")
1216 (const_string "alu_shift_reg")))]
1217 )
1218
1219 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1220 (define_split
1221 [(set (match_operand:SI 0 "s_register_operand" "")
1222 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1223 (match_operand:SI 2 "s_register_operand" ""))
1224 (const_int -1)))
1225 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1226 "TARGET_32BIT"
1227 [(set (match_dup 3) (match_dup 1))
1228 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1229 "
1230 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1231 ")
1232
1233 (define_expand "addsf3"
1234 [(set (match_operand:SF 0 "s_register_operand" "")
1235 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1236 (match_operand:SF 2 "s_register_operand" "")))]
1237 "TARGET_32BIT && TARGET_HARD_FLOAT"
1238 "
1239 ")
1240
1241 (define_expand "adddf3"
1242 [(set (match_operand:DF 0 "s_register_operand" "")
1243 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1244 (match_operand:DF 2 "s_register_operand" "")))]
1245 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1246 "
1247 ")
1248
1249 (define_expand "subdi3"
1250 [(parallel
1251 [(set (match_operand:DI 0 "s_register_operand" "")
1252 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1253 (match_operand:DI 2 "s_register_operand" "")))
1254 (clobber (reg:CC CC_REGNUM))])]
1255 "TARGET_EITHER"
1256 "
1257 if (TARGET_THUMB1)
1258 {
1259 if (!REG_P (operands[1]))
1260 operands[1] = force_reg (DImode, operands[1]);
1261 if (!REG_P (operands[2]))
1262 operands[2] = force_reg (DImode, operands[2]);
1263 }
1264 "
1265 )
1266
1267 (define_insn_and_split "*arm_subdi3"
1268 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1269 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1270 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1271 (clobber (reg:CC CC_REGNUM))]
1272 "TARGET_32BIT && !TARGET_NEON"
1273 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1274 "&& reload_completed"
1275 [(parallel [(set (reg:CC CC_REGNUM)
1276 (compare:CC (match_dup 1) (match_dup 2)))
1277 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1278 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1279 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1280 {
1281 operands[3] = gen_highpart (SImode, operands[0]);
1282 operands[0] = gen_lowpart (SImode, operands[0]);
1283 operands[4] = gen_highpart (SImode, operands[1]);
1284 operands[1] = gen_lowpart (SImode, operands[1]);
1285 operands[5] = gen_highpart (SImode, operands[2]);
1286 operands[2] = gen_lowpart (SImode, operands[2]);
1287 }
1288 [(set_attr "conds" "clob")
1289 (set_attr "length" "8")
1290 (set_attr "type" "multiple")]
1291 )
1292
1293 (define_insn_and_split "*subdi_di_zesidi"
1294 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1295 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1296 (zero_extend:DI
1297 (match_operand:SI 2 "s_register_operand" "r,r"))))
1298 (clobber (reg:CC CC_REGNUM))]
1299 "TARGET_32BIT"
1300 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1301 "&& reload_completed"
1302 [(parallel [(set (reg:CC CC_REGNUM)
1303 (compare:CC (match_dup 1) (match_dup 2)))
1304 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1305 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1306 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1307 {
1308 operands[3] = gen_highpart (SImode, operands[0]);
1309 operands[0] = gen_lowpart (SImode, operands[0]);
1310 operands[4] = gen_highpart (SImode, operands[1]);
1311 operands[1] = gen_lowpart (SImode, operands[1]);
1312 operands[5] = GEN_INT (~0);
1313 }
1314 [(set_attr "conds" "clob")
1315 (set_attr "length" "8")
1316 (set_attr "type" "multiple")]
1317 )
1318
1319 (define_insn_and_split "*subdi_di_sesidi"
1320 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1321 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1322 (sign_extend:DI
1323 (match_operand:SI 2 "s_register_operand" "r,r"))))
1324 (clobber (reg:CC CC_REGNUM))]
1325 "TARGET_32BIT"
1326 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1327 "&& reload_completed"
1328 [(parallel [(set (reg:CC CC_REGNUM)
1329 (compare:CC (match_dup 1) (match_dup 2)))
1330 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1331 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1332 (ashiftrt:SI (match_dup 2)
1333 (const_int 31)))
1334 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1335 {
1336 operands[3] = gen_highpart (SImode, operands[0]);
1337 operands[0] = gen_lowpart (SImode, operands[0]);
1338 operands[4] = gen_highpart (SImode, operands[1]);
1339 operands[1] = gen_lowpart (SImode, operands[1]);
1340 }
1341 [(set_attr "conds" "clob")
1342 (set_attr "length" "8")
1343 (set_attr "type" "multiple")]
1344 )
1345
1346 (define_insn_and_split "*subdi_zesidi_di"
1347 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1348 (minus:DI (zero_extend:DI
1349 (match_operand:SI 2 "s_register_operand" "r,r"))
1350 (match_operand:DI 1 "s_register_operand" "0,r")))
1351 (clobber (reg:CC CC_REGNUM))]
1352 "TARGET_ARM"
1353 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1354 ; is equivalent to:
1355 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1356 "&& reload_completed"
1357 [(parallel [(set (reg:CC CC_REGNUM)
1358 (compare:CC (match_dup 2) (match_dup 1)))
1359 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1360 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1361 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1362 {
1363 operands[3] = gen_highpart (SImode, operands[0]);
1364 operands[0] = gen_lowpart (SImode, operands[0]);
1365 operands[4] = gen_highpart (SImode, operands[1]);
1366 operands[1] = gen_lowpart (SImode, operands[1]);
1367 }
1368 [(set_attr "conds" "clob")
1369 (set_attr "length" "8")
1370 (set_attr "type" "multiple")]
1371 )
1372
1373 (define_insn_and_split "*subdi_sesidi_di"
1374 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1375 (minus:DI (sign_extend:DI
1376 (match_operand:SI 2 "s_register_operand" "r,r"))
1377 (match_operand:DI 1 "s_register_operand" "0,r")))
1378 (clobber (reg:CC CC_REGNUM))]
1379 "TARGET_ARM"
1380 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1381 ; is equivalent to:
1382 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1383 "&& reload_completed"
1384 [(parallel [(set (reg:CC CC_REGNUM)
1385 (compare:CC (match_dup 2) (match_dup 1)))
1386 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1387 (set (match_dup 3) (minus:SI (minus:SI
1388 (ashiftrt:SI (match_dup 2)
1389 (const_int 31))
1390 (match_dup 4))
1391 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1392 {
1393 operands[3] = gen_highpart (SImode, operands[0]);
1394 operands[0] = gen_lowpart (SImode, operands[0]);
1395 operands[4] = gen_highpart (SImode, operands[1]);
1396 operands[1] = gen_lowpart (SImode, operands[1]);
1397 }
1398 [(set_attr "conds" "clob")
1399 (set_attr "length" "8")
1400 (set_attr "type" "multiple")]
1401 )
1402
1403 (define_insn_and_split "*subdi_zesidi_zesidi"
1404 [(set (match_operand:DI 0 "s_register_operand" "=r")
1405 (minus:DI (zero_extend:DI
1406 (match_operand:SI 1 "s_register_operand" "r"))
1407 (zero_extend:DI
1408 (match_operand:SI 2 "s_register_operand" "r"))))
1409 (clobber (reg:CC CC_REGNUM))]
1410 "TARGET_32BIT"
1411 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1412 "&& reload_completed"
1413 [(parallel [(set (reg:CC CC_REGNUM)
1414 (compare:CC (match_dup 1) (match_dup 2)))
1415 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1416 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1417 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1418 {
1419 operands[3] = gen_highpart (SImode, operands[0]);
1420 operands[0] = gen_lowpart (SImode, operands[0]);
1421 }
1422 [(set_attr "conds" "clob")
1423 (set_attr "length" "8")
1424 (set_attr "type" "multiple")]
1425 )
1426
1427 (define_expand "subsi3"
1428 [(set (match_operand:SI 0 "s_register_operand" "")
1429 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1430 (match_operand:SI 2 "s_register_operand" "")))]
1431 "TARGET_EITHER"
1432 "
1433 if (CONST_INT_P (operands[1]))
1434 {
1435 if (TARGET_32BIT)
1436 {
1437 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1438 operands[1] = force_reg (SImode, operands[1]);
1439 else
1440 {
1441 arm_split_constant (MINUS, SImode, NULL_RTX,
1442 INTVAL (operands[1]), operands[0],
1443 operands[2],
1444 optimize && can_create_pseudo_p ());
1445 DONE;
1446 }
1447 }
1448 else /* TARGET_THUMB1 */
1449 operands[1] = force_reg (SImode, operands[1]);
1450 }
1451 "
1452 )
1453
1454 ; ??? Check Thumb-2 split length
1455 (define_insn_and_split "*arm_subsi3_insn"
1456 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1457 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1458 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1459 "TARGET_32BIT"
1460 "@
1461 sub%?\\t%0, %1, %2
1462 sub%?\\t%0, %2
1463 sub%?\\t%0, %1, %2
1464 rsb%?\\t%0, %2, %1
1465 rsb%?\\t%0, %2, %1
1466 sub%?\\t%0, %1, %2
1467 sub%?\\t%0, %1, %2
1468 sub%?\\t%0, %1, %2
1469 #"
1470 "&& (CONST_INT_P (operands[1])
1471 && !const_ok_for_arm (INTVAL (operands[1])))"
1472 [(clobber (const_int 0))]
1473 "
1474 arm_split_constant (MINUS, SImode, curr_insn,
1475 INTVAL (operands[1]), operands[0], operands[2], 0);
1476 DONE;
1477 "
1478 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1479 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1480 (set_attr "predicable" "yes")
1481 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1482 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1483 )
1484
1485 (define_peephole2
1486 [(match_scratch:SI 3 "r")
1487 (set (match_operand:SI 0 "arm_general_register_operand" "")
1488 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1489 (match_operand:SI 2 "arm_general_register_operand" "")))]
1490 "TARGET_32BIT
1491 && !const_ok_for_arm (INTVAL (operands[1]))
1492 && const_ok_for_arm (~INTVAL (operands[1]))"
1493 [(set (match_dup 3) (match_dup 1))
1494 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1495 ""
1496 )
1497
1498 (define_insn "subsi3_compare0"
1499 [(set (reg:CC_NOOV CC_REGNUM)
1500 (compare:CC_NOOV
1501 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1502 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1503 (const_int 0)))
1504 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1505 (minus:SI (match_dup 1) (match_dup 2)))]
1506 "TARGET_32BIT"
1507 "@
1508 subs%?\\t%0, %1, %2
1509 subs%?\\t%0, %1, %2
1510 rsbs%?\\t%0, %2, %1"
1511 [(set_attr "conds" "set")
1512 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1513 )
1514
1515 (define_insn "subsi3_compare"
1516 [(set (reg:CC CC_REGNUM)
1517 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1518 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1519 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1520 (minus:SI (match_dup 1) (match_dup 2)))]
1521 "TARGET_32BIT"
1522 "@
1523 subs%?\\t%0, %1, %2
1524 subs%?\\t%0, %1, %2
1525 rsbs%?\\t%0, %2, %1"
1526 [(set_attr "conds" "set")
1527 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1528 )
1529
1530 (define_expand "subsf3"
1531 [(set (match_operand:SF 0 "s_register_operand" "")
1532 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1533 (match_operand:SF 2 "s_register_operand" "")))]
1534 "TARGET_32BIT && TARGET_HARD_FLOAT"
1535 "
1536 ")
1537
1538 (define_expand "subdf3"
1539 [(set (match_operand:DF 0 "s_register_operand" "")
1540 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1541 (match_operand:DF 2 "s_register_operand" "")))]
1542 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1543 "
1544 ")
1545
1546 \f
1547 ;; Multiplication insns
1548
1549 (define_expand "mulhi3"
1550 [(set (match_operand:HI 0 "s_register_operand" "")
1551 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1552 (match_operand:HI 2 "s_register_operand" "")))]
1553 "TARGET_DSP_MULTIPLY"
1554 "
1555 {
1556 rtx result = gen_reg_rtx (SImode);
1557 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1558 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1559 DONE;
1560 }"
1561 )
1562
1563 (define_expand "mulsi3"
1564 [(set (match_operand:SI 0 "s_register_operand" "")
1565 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1566 (match_operand:SI 1 "s_register_operand" "")))]
1567 "TARGET_EITHER"
1568 ""
1569 )
1570
1571 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1572 (define_insn "*arm_mulsi3"
1573 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1574 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1575 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1576 "TARGET_32BIT && !arm_arch6"
1577 "mul%?\\t%0, %2, %1"
1578 [(set_attr "type" "mul")
1579 (set_attr "predicable" "yes")]
1580 )
1581
1582 (define_insn "*arm_mulsi3_v6"
1583 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1584 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1585 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1586 "TARGET_32BIT && arm_arch6"
1587 "mul%?\\t%0, %1, %2"
1588 [(set_attr "type" "mul")
1589 (set_attr "predicable" "yes")
1590 (set_attr "arch" "t2,t2,*")
1591 (set_attr "length" "4")
1592 (set_attr "predicable_short_it" "yes,yes,no")]
1593 )
1594
1595 (define_insn "*mulsi3_compare0"
1596 [(set (reg:CC_NOOV CC_REGNUM)
1597 (compare:CC_NOOV (mult:SI
1598 (match_operand:SI 2 "s_register_operand" "r,r")
1599 (match_operand:SI 1 "s_register_operand" "%0,r"))
1600 (const_int 0)))
1601 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1602 (mult:SI (match_dup 2) (match_dup 1)))]
1603 "TARGET_ARM && !arm_arch6"
1604 "muls%?\\t%0, %2, %1"
1605 [(set_attr "conds" "set")
1606 (set_attr "type" "muls")]
1607 )
1608
1609 (define_insn "*mulsi3_compare0_v6"
1610 [(set (reg:CC_NOOV CC_REGNUM)
1611 (compare:CC_NOOV (mult:SI
1612 (match_operand:SI 2 "s_register_operand" "r")
1613 (match_operand:SI 1 "s_register_operand" "r"))
1614 (const_int 0)))
1615 (set (match_operand:SI 0 "s_register_operand" "=r")
1616 (mult:SI (match_dup 2) (match_dup 1)))]
1617 "TARGET_ARM && arm_arch6 && optimize_size"
1618 "muls%?\\t%0, %2, %1"
1619 [(set_attr "conds" "set")
1620 (set_attr "type" "muls")]
1621 )
1622
1623 (define_insn "*mulsi_compare0_scratch"
1624 [(set (reg:CC_NOOV CC_REGNUM)
1625 (compare:CC_NOOV (mult:SI
1626 (match_operand:SI 2 "s_register_operand" "r,r")
1627 (match_operand:SI 1 "s_register_operand" "%0,r"))
1628 (const_int 0)))
1629 (clobber (match_scratch:SI 0 "=&r,&r"))]
1630 "TARGET_ARM && !arm_arch6"
1631 "muls%?\\t%0, %2, %1"
1632 [(set_attr "conds" "set")
1633 (set_attr "type" "muls")]
1634 )
1635
1636 (define_insn "*mulsi_compare0_scratch_v6"
1637 [(set (reg:CC_NOOV CC_REGNUM)
1638 (compare:CC_NOOV (mult:SI
1639 (match_operand:SI 2 "s_register_operand" "r")
1640 (match_operand:SI 1 "s_register_operand" "r"))
1641 (const_int 0)))
1642 (clobber (match_scratch:SI 0 "=r"))]
1643 "TARGET_ARM && arm_arch6 && optimize_size"
1644 "muls%?\\t%0, %2, %1"
1645 [(set_attr "conds" "set")
1646 (set_attr "type" "muls")]
1647 )
1648
1649 ;; Unnamed templates to match MLA instruction.
1650
1651 (define_insn "*mulsi3addsi"
1652 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1653 (plus:SI
1654 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1655 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1656 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1657 "TARGET_32BIT && !arm_arch6"
1658 "mla%?\\t%0, %2, %1, %3"
1659 [(set_attr "type" "mla")
1660 (set_attr "predicable" "yes")]
1661 )
1662
1663 (define_insn "*mulsi3addsi_v6"
1664 [(set (match_operand:SI 0 "s_register_operand" "=r")
1665 (plus:SI
1666 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1667 (match_operand:SI 1 "s_register_operand" "r"))
1668 (match_operand:SI 3 "s_register_operand" "r")))]
1669 "TARGET_32BIT && arm_arch6"
1670 "mla%?\\t%0, %2, %1, %3"
1671 [(set_attr "type" "mla")
1672 (set_attr "predicable" "yes")
1673 (set_attr "predicable_short_it" "no")]
1674 )
1675
1676 (define_insn "*mulsi3addsi_compare0"
1677 [(set (reg:CC_NOOV CC_REGNUM)
1678 (compare:CC_NOOV
1679 (plus:SI (mult:SI
1680 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1681 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1682 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1683 (const_int 0)))
1684 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1685 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1686 (match_dup 3)))]
1687 "TARGET_ARM && arm_arch6"
1688 "mlas%?\\t%0, %2, %1, %3"
1689 [(set_attr "conds" "set")
1690 (set_attr "type" "mlas")]
1691 )
1692
1693 (define_insn "*mulsi3addsi_compare0_v6"
1694 [(set (reg:CC_NOOV CC_REGNUM)
1695 (compare:CC_NOOV
1696 (plus:SI (mult:SI
1697 (match_operand:SI 2 "s_register_operand" "r")
1698 (match_operand:SI 1 "s_register_operand" "r"))
1699 (match_operand:SI 3 "s_register_operand" "r"))
1700 (const_int 0)))
1701 (set (match_operand:SI 0 "s_register_operand" "=r")
1702 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1703 (match_dup 3)))]
1704 "TARGET_ARM && arm_arch6 && optimize_size"
1705 "mlas%?\\t%0, %2, %1, %3"
1706 [(set_attr "conds" "set")
1707 (set_attr "type" "mlas")]
1708 )
1709
1710 (define_insn "*mulsi3addsi_compare0_scratch"
1711 [(set (reg:CC_NOOV CC_REGNUM)
1712 (compare:CC_NOOV
1713 (plus:SI (mult:SI
1714 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1715 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1716 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1717 (const_int 0)))
1718 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1719 "TARGET_ARM && !arm_arch6"
1720 "mlas%?\\t%0, %2, %1, %3"
1721 [(set_attr "conds" "set")
1722 (set_attr "type" "mlas")]
1723 )
1724
1725 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1726 [(set (reg:CC_NOOV CC_REGNUM)
1727 (compare:CC_NOOV
1728 (plus:SI (mult:SI
1729 (match_operand:SI 2 "s_register_operand" "r")
1730 (match_operand:SI 1 "s_register_operand" "r"))
1731 (match_operand:SI 3 "s_register_operand" "r"))
1732 (const_int 0)))
1733 (clobber (match_scratch:SI 0 "=r"))]
1734 "TARGET_ARM && arm_arch6 && optimize_size"
1735 "mlas%?\\t%0, %2, %1, %3"
1736 [(set_attr "conds" "set")
1737 (set_attr "type" "mlas")]
1738 )
1739
1740 (define_insn "*mulsi3subsi"
1741 [(set (match_operand:SI 0 "s_register_operand" "=r")
1742 (minus:SI
1743 (match_operand:SI 3 "s_register_operand" "r")
1744 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1745 (match_operand:SI 1 "s_register_operand" "r"))))]
1746 "TARGET_32BIT && arm_arch_thumb2"
1747 "mls%?\\t%0, %2, %1, %3"
1748 [(set_attr "type" "mla")
1749 (set_attr "predicable" "yes")
1750 (set_attr "predicable_short_it" "no")]
1751 )
1752
1753 (define_expand "maddsidi4"
1754 [(set (match_operand:DI 0 "s_register_operand" "")
1755 (plus:DI
1756 (mult:DI
1757 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1758 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1759 (match_operand:DI 3 "s_register_operand" "")))]
1760 "TARGET_32BIT && arm_arch3m"
1761 "")
1762
1763 (define_insn "*mulsidi3adddi"
1764 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1765 (plus:DI
1766 (mult:DI
1767 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1768 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1769 (match_operand:DI 1 "s_register_operand" "0")))]
1770 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1771 "smlal%?\\t%Q0, %R0, %3, %2"
1772 [(set_attr "type" "smlal")
1773 (set_attr "predicable" "yes")]
1774 )
1775
1776 (define_insn "*mulsidi3adddi_v6"
1777 [(set (match_operand:DI 0 "s_register_operand" "=r")
1778 (plus:DI
1779 (mult:DI
1780 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1781 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1782 (match_operand:DI 1 "s_register_operand" "0")))]
1783 "TARGET_32BIT && arm_arch6"
1784 "smlal%?\\t%Q0, %R0, %3, %2"
1785 [(set_attr "type" "smlal")
1786 (set_attr "predicable" "yes")
1787 (set_attr "predicable_short_it" "no")]
1788 )
1789
1790 ;; 32x32->64 widening multiply.
1791 ;; As with mulsi3, the only difference between the v3-5 and v6+
1792 ;; versions of these patterns is the requirement that the output not
1793 ;; overlap the inputs, but that still means we have to have a named
1794 ;; expander and two different starred insns.
1795
1796 (define_expand "mulsidi3"
1797 [(set (match_operand:DI 0 "s_register_operand" "")
1798 (mult:DI
1799 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1800 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1801 "TARGET_32BIT && arm_arch3m"
1802 ""
1803 )
1804
1805 (define_insn "*mulsidi3_nov6"
1806 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1807 (mult:DI
1808 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1809 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1810 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1811 "smull%?\\t%Q0, %R0, %1, %2"
1812 [(set_attr "type" "smull")
1813 (set_attr "predicable" "yes")]
1814 )
1815
1816 (define_insn "*mulsidi3_v6"
1817 [(set (match_operand:DI 0 "s_register_operand" "=r")
1818 (mult:DI
1819 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1820 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1821 "TARGET_32BIT && arm_arch6"
1822 "smull%?\\t%Q0, %R0, %1, %2"
1823 [(set_attr "type" "smull")
1824 (set_attr "predicable" "yes")
1825 (set_attr "predicable_short_it" "no")]
1826 )
1827
1828 (define_expand "umulsidi3"
1829 [(set (match_operand:DI 0 "s_register_operand" "")
1830 (mult:DI
1831 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1832 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1833 "TARGET_32BIT && arm_arch3m"
1834 ""
1835 )
1836
1837 (define_insn "*umulsidi3_nov6"
1838 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1839 (mult:DI
1840 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1841 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1842 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1843 "umull%?\\t%Q0, %R0, %1, %2"
1844 [(set_attr "type" "umull")
1845 (set_attr "predicable" "yes")]
1846 )
1847
1848 (define_insn "*umulsidi3_v6"
1849 [(set (match_operand:DI 0 "s_register_operand" "=r")
1850 (mult:DI
1851 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1852 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1853 "TARGET_32BIT && arm_arch6"
1854 "umull%?\\t%Q0, %R0, %1, %2"
1855 [(set_attr "type" "umull")
1856 (set_attr "predicable" "yes")
1857 (set_attr "predicable_short_it" "no")]
1858 )
1859
1860 (define_expand "umaddsidi4"
1861 [(set (match_operand:DI 0 "s_register_operand" "")
1862 (plus:DI
1863 (mult:DI
1864 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1865 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1866 (match_operand:DI 3 "s_register_operand" "")))]
1867 "TARGET_32BIT && arm_arch3m"
1868 "")
1869
1870 (define_insn "*umulsidi3adddi"
1871 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1872 (plus:DI
1873 (mult:DI
1874 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1875 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1876 (match_operand:DI 1 "s_register_operand" "0")))]
1877 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1878 "umlal%?\\t%Q0, %R0, %3, %2"
1879 [(set_attr "type" "umlal")
1880 (set_attr "predicable" "yes")]
1881 )
1882
1883 (define_insn "*umulsidi3adddi_v6"
1884 [(set (match_operand:DI 0 "s_register_operand" "=r")
1885 (plus:DI
1886 (mult:DI
1887 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1888 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1889 (match_operand:DI 1 "s_register_operand" "0")))]
1890 "TARGET_32BIT && arm_arch6"
1891 "umlal%?\\t%Q0, %R0, %3, %2"
1892 [(set_attr "type" "umlal")
1893 (set_attr "predicable" "yes")
1894 (set_attr "predicable_short_it" "no")]
1895 )
1896
1897 (define_expand "smulsi3_highpart"
1898 [(parallel
1899 [(set (match_operand:SI 0 "s_register_operand" "")
1900 (truncate:SI
1901 (lshiftrt:DI
1902 (mult:DI
1903 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1904 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1905 (const_int 32))))
1906 (clobber (match_scratch:SI 3 ""))])]
1907 "TARGET_32BIT && arm_arch3m"
1908 ""
1909 )
1910
1911 (define_insn "*smulsi3_highpart_nov6"
1912 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1913 (truncate:SI
1914 (lshiftrt:DI
1915 (mult:DI
1916 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1917 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1918 (const_int 32))))
1919 (clobber (match_scratch:SI 3 "=&r,&r"))]
1920 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1921 "smull%?\\t%3, %0, %2, %1"
1922 [(set_attr "type" "smull")
1923 (set_attr "predicable" "yes")]
1924 )
1925
1926 (define_insn "*smulsi3_highpart_v6"
1927 [(set (match_operand:SI 0 "s_register_operand" "=r")
1928 (truncate:SI
1929 (lshiftrt:DI
1930 (mult:DI
1931 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1932 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1933 (const_int 32))))
1934 (clobber (match_scratch:SI 3 "=r"))]
1935 "TARGET_32BIT && arm_arch6"
1936 "smull%?\\t%3, %0, %2, %1"
1937 [(set_attr "type" "smull")
1938 (set_attr "predicable" "yes")
1939 (set_attr "predicable_short_it" "no")]
1940 )
1941
1942 (define_expand "umulsi3_highpart"
1943 [(parallel
1944 [(set (match_operand:SI 0 "s_register_operand" "")
1945 (truncate:SI
1946 (lshiftrt:DI
1947 (mult:DI
1948 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1949 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1950 (const_int 32))))
1951 (clobber (match_scratch:SI 3 ""))])]
1952 "TARGET_32BIT && arm_arch3m"
1953 ""
1954 )
1955
1956 (define_insn "*umulsi3_highpart_nov6"
1957 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1958 (truncate:SI
1959 (lshiftrt:DI
1960 (mult:DI
1961 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1962 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1963 (const_int 32))))
1964 (clobber (match_scratch:SI 3 "=&r,&r"))]
1965 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1966 "umull%?\\t%3, %0, %2, %1"
1967 [(set_attr "type" "umull")
1968 (set_attr "predicable" "yes")]
1969 )
1970
1971 (define_insn "*umulsi3_highpart_v6"
1972 [(set (match_operand:SI 0 "s_register_operand" "=r")
1973 (truncate:SI
1974 (lshiftrt:DI
1975 (mult:DI
1976 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1977 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1978 (const_int 32))))
1979 (clobber (match_scratch:SI 3 "=r"))]
1980 "TARGET_32BIT && arm_arch6"
1981 "umull%?\\t%3, %0, %2, %1"
1982 [(set_attr "type" "umull")
1983 (set_attr "predicable" "yes")
1984 (set_attr "predicable_short_it" "no")]
1985 )
1986
1987 (define_insn "mulhisi3"
1988 [(set (match_operand:SI 0 "s_register_operand" "=r")
1989 (mult:SI (sign_extend:SI
1990 (match_operand:HI 1 "s_register_operand" "%r"))
1991 (sign_extend:SI
1992 (match_operand:HI 2 "s_register_operand" "r"))))]
1993 "TARGET_DSP_MULTIPLY"
1994 "smulbb%?\\t%0, %1, %2"
1995 [(set_attr "type" "smulxy")
1996 (set_attr "predicable" "yes")]
1997 )
1998
1999 (define_insn "*mulhisi3tb"
2000 [(set (match_operand:SI 0 "s_register_operand" "=r")
2001 (mult:SI (ashiftrt:SI
2002 (match_operand:SI 1 "s_register_operand" "r")
2003 (const_int 16))
2004 (sign_extend:SI
2005 (match_operand:HI 2 "s_register_operand" "r"))))]
2006 "TARGET_DSP_MULTIPLY"
2007 "smultb%?\\t%0, %1, %2"
2008 [(set_attr "type" "smulxy")
2009 (set_attr "predicable" "yes")
2010 (set_attr "predicable_short_it" "no")]
2011 )
2012
2013 (define_insn "*mulhisi3bt"
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 (ashiftrt:SI
2018 (match_operand:SI 2 "s_register_operand" "r")
2019 (const_int 16))))]
2020 "TARGET_DSP_MULTIPLY"
2021 "smulbt%?\\t%0, %1, %2"
2022 [(set_attr "type" "smulxy")
2023 (set_attr "predicable" "yes")
2024 (set_attr "predicable_short_it" "no")]
2025 )
2026
2027 (define_insn "*mulhisi3tt"
2028 [(set (match_operand:SI 0 "s_register_operand" "=r")
2029 (mult:SI (ashiftrt:SI
2030 (match_operand:SI 1 "s_register_operand" "r")
2031 (const_int 16))
2032 (ashiftrt:SI
2033 (match_operand:SI 2 "s_register_operand" "r")
2034 (const_int 16))))]
2035 "TARGET_DSP_MULTIPLY"
2036 "smultt%?\\t%0, %1, %2"
2037 [(set_attr "type" "smulxy")
2038 (set_attr "predicable" "yes")
2039 (set_attr "predicable_short_it" "no")]
2040 )
2041
2042 (define_insn "maddhisi4"
2043 [(set (match_operand:SI 0 "s_register_operand" "=r")
2044 (plus:SI (mult:SI (sign_extend:SI
2045 (match_operand:HI 1 "s_register_operand" "r"))
2046 (sign_extend:SI
2047 (match_operand:HI 2 "s_register_operand" "r")))
2048 (match_operand:SI 3 "s_register_operand" "r")))]
2049 "TARGET_DSP_MULTIPLY"
2050 "smlabb%?\\t%0, %1, %2, %3"
2051 [(set_attr "type" "smlaxy")
2052 (set_attr "predicable" "yes")
2053 (set_attr "predicable_short_it" "no")]
2054 )
2055
2056 ;; Note: there is no maddhisi4ibt because this one is canonical form
2057 (define_insn "*maddhisi4tb"
2058 [(set (match_operand:SI 0 "s_register_operand" "=r")
2059 (plus:SI (mult:SI (ashiftrt:SI
2060 (match_operand:SI 1 "s_register_operand" "r")
2061 (const_int 16))
2062 (sign_extend:SI
2063 (match_operand:HI 2 "s_register_operand" "r")))
2064 (match_operand:SI 3 "s_register_operand" "r")))]
2065 "TARGET_DSP_MULTIPLY"
2066 "smlatb%?\\t%0, %1, %2, %3"
2067 [(set_attr "type" "smlaxy")
2068 (set_attr "predicable" "yes")
2069 (set_attr "predicable_short_it" "no")]
2070 )
2071
2072 (define_insn "*maddhisi4tt"
2073 [(set (match_operand:SI 0 "s_register_operand" "=r")
2074 (plus:SI (mult:SI (ashiftrt:SI
2075 (match_operand:SI 1 "s_register_operand" "r")
2076 (const_int 16))
2077 (ashiftrt:SI
2078 (match_operand:SI 2 "s_register_operand" "r")
2079 (const_int 16)))
2080 (match_operand:SI 3 "s_register_operand" "r")))]
2081 "TARGET_DSP_MULTIPLY"
2082 "smlatt%?\\t%0, %1, %2, %3"
2083 [(set_attr "type" "smlaxy")
2084 (set_attr "predicable" "yes")
2085 (set_attr "predicable_short_it" "no")]
2086 )
2087
2088 (define_insn "maddhidi4"
2089 [(set (match_operand:DI 0 "s_register_operand" "=r")
2090 (plus:DI
2091 (mult:DI (sign_extend:DI
2092 (match_operand:HI 1 "s_register_operand" "r"))
2093 (sign_extend:DI
2094 (match_operand:HI 2 "s_register_operand" "r")))
2095 (match_operand:DI 3 "s_register_operand" "0")))]
2096 "TARGET_DSP_MULTIPLY"
2097 "smlalbb%?\\t%Q0, %R0, %1, %2"
2098 [(set_attr "type" "smlalxy")
2099 (set_attr "predicable" "yes")
2100 (set_attr "predicable_short_it" "no")])
2101
2102 ;; Note: there is no maddhidi4ibt because this one is canonical form
2103 (define_insn "*maddhidi4tb"
2104 [(set (match_operand:DI 0 "s_register_operand" "=r")
2105 (plus:DI
2106 (mult:DI (sign_extend:DI
2107 (ashiftrt:SI
2108 (match_operand:SI 1 "s_register_operand" "r")
2109 (const_int 16)))
2110 (sign_extend:DI
2111 (match_operand:HI 2 "s_register_operand" "r")))
2112 (match_operand:DI 3 "s_register_operand" "0")))]
2113 "TARGET_DSP_MULTIPLY"
2114 "smlaltb%?\\t%Q0, %R0, %1, %2"
2115 [(set_attr "type" "smlalxy")
2116 (set_attr "predicable" "yes")
2117 (set_attr "predicable_short_it" "no")])
2118
2119 (define_insn "*maddhidi4tt"
2120 [(set (match_operand:DI 0 "s_register_operand" "=r")
2121 (plus:DI
2122 (mult:DI (sign_extend:DI
2123 (ashiftrt:SI
2124 (match_operand:SI 1 "s_register_operand" "r")
2125 (const_int 16)))
2126 (sign_extend:DI
2127 (ashiftrt:SI
2128 (match_operand:SI 2 "s_register_operand" "r")
2129 (const_int 16))))
2130 (match_operand:DI 3 "s_register_operand" "0")))]
2131 "TARGET_DSP_MULTIPLY"
2132 "smlaltt%?\\t%Q0, %R0, %1, %2"
2133 [(set_attr "type" "smlalxy")
2134 (set_attr "predicable" "yes")
2135 (set_attr "predicable_short_it" "no")])
2136
2137 (define_expand "mulsf3"
2138 [(set (match_operand:SF 0 "s_register_operand" "")
2139 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2140 (match_operand:SF 2 "s_register_operand" "")))]
2141 "TARGET_32BIT && TARGET_HARD_FLOAT"
2142 "
2143 ")
2144
2145 (define_expand "muldf3"
2146 [(set (match_operand:DF 0 "s_register_operand" "")
2147 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2148 (match_operand:DF 2 "s_register_operand" "")))]
2149 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2150 "
2151 ")
2152 \f
2153 ;; Division insns
2154
2155 (define_expand "divsf3"
2156 [(set (match_operand:SF 0 "s_register_operand" "")
2157 (div:SF (match_operand:SF 1 "s_register_operand" "")
2158 (match_operand:SF 2 "s_register_operand" "")))]
2159 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
2160 "")
2161
2162 (define_expand "divdf3"
2163 [(set (match_operand:DF 0 "s_register_operand" "")
2164 (div:DF (match_operand:DF 1 "s_register_operand" "")
2165 (match_operand:DF 2 "s_register_operand" "")))]
2166 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2167 "")
2168 \f
2169 ;; Boolean and,ior,xor insns
2170
2171 ;; Split up double word logical operations
2172
2173 ;; Split up simple DImode logical operations. Simply perform the logical
2174 ;; operation on the upper and lower halves of the registers.
2175 (define_split
2176 [(set (match_operand:DI 0 "s_register_operand" "")
2177 (match_operator:DI 6 "logical_binary_operator"
2178 [(match_operand:DI 1 "s_register_operand" "")
2179 (match_operand:DI 2 "s_register_operand" "")]))]
2180 "TARGET_32BIT && reload_completed
2181 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2182 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2183 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2184 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2185 "
2186 {
2187 operands[3] = gen_highpart (SImode, operands[0]);
2188 operands[0] = gen_lowpart (SImode, operands[0]);
2189 operands[4] = gen_highpart (SImode, operands[1]);
2190 operands[1] = gen_lowpart (SImode, operands[1]);
2191 operands[5] = gen_highpart (SImode, operands[2]);
2192 operands[2] = gen_lowpart (SImode, operands[2]);
2193 }"
2194 )
2195
2196 (define_split
2197 [(set (match_operand:DI 0 "s_register_operand" "")
2198 (match_operator:DI 6 "logical_binary_operator"
2199 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2200 (match_operand:DI 1 "s_register_operand" "")]))]
2201 "TARGET_32BIT && reload_completed"
2202 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2203 (set (match_dup 3) (match_op_dup:SI 6
2204 [(ashiftrt:SI (match_dup 2) (const_int 31))
2205 (match_dup 4)]))]
2206 "
2207 {
2208 operands[3] = gen_highpart (SImode, operands[0]);
2209 operands[0] = gen_lowpart (SImode, operands[0]);
2210 operands[4] = gen_highpart (SImode, operands[1]);
2211 operands[1] = gen_lowpart (SImode, operands[1]);
2212 operands[5] = gen_highpart (SImode, operands[2]);
2213 operands[2] = gen_lowpart (SImode, operands[2]);
2214 }"
2215 )
2216
2217 ;; The zero extend of operand 2 means we can just copy the high part of
2218 ;; operand1 into operand0.
2219 (define_split
2220 [(set (match_operand:DI 0 "s_register_operand" "")
2221 (ior:DI
2222 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2223 (match_operand:DI 1 "s_register_operand" "")))]
2224 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2225 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2226 (set (match_dup 3) (match_dup 4))]
2227 "
2228 {
2229 operands[4] = gen_highpart (SImode, operands[1]);
2230 operands[3] = gen_highpart (SImode, operands[0]);
2231 operands[0] = gen_lowpart (SImode, operands[0]);
2232 operands[1] = gen_lowpart (SImode, operands[1]);
2233 }"
2234 )
2235
2236 ;; The zero extend of operand 2 means we can just copy the high part of
2237 ;; operand1 into operand0.
2238 (define_split
2239 [(set (match_operand:DI 0 "s_register_operand" "")
2240 (xor:DI
2241 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2242 (match_operand:DI 1 "s_register_operand" "")))]
2243 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2244 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2245 (set (match_dup 3) (match_dup 4))]
2246 "
2247 {
2248 operands[4] = gen_highpart (SImode, operands[1]);
2249 operands[3] = gen_highpart (SImode, operands[0]);
2250 operands[0] = gen_lowpart (SImode, operands[0]);
2251 operands[1] = gen_lowpart (SImode, operands[1]);
2252 }"
2253 )
2254
2255 (define_expand "anddi3"
2256 [(set (match_operand:DI 0 "s_register_operand" "")
2257 (and:DI (match_operand:DI 1 "s_register_operand" "")
2258 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2259 "TARGET_32BIT"
2260 ""
2261 )
2262
2263 (define_insn_and_split "*anddi3_insn"
2264 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2265 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2266 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2267 "TARGET_32BIT && !TARGET_IWMMXT"
2268 {
2269 switch (which_alternative)
2270 {
2271 case 0: /* fall through */
2272 case 6: return "vand\t%P0, %P1, %P2";
2273 case 1: /* fall through */
2274 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2275 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2276 case 2:
2277 case 3:
2278 case 4:
2279 case 5: /* fall through */
2280 return "#";
2281 default: gcc_unreachable ();
2282 }
2283 }
2284 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2285 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2286 [(set (match_dup 3) (match_dup 4))
2287 (set (match_dup 5) (match_dup 6))]
2288 "
2289 {
2290 operands[3] = gen_lowpart (SImode, operands[0]);
2291 operands[5] = gen_highpart (SImode, operands[0]);
2292
2293 operands[4] = simplify_gen_binary (AND, SImode,
2294 gen_lowpart (SImode, operands[1]),
2295 gen_lowpart (SImode, operands[2]));
2296 operands[6] = simplify_gen_binary (AND, SImode,
2297 gen_highpart (SImode, operands[1]),
2298 gen_highpart_mode (SImode, DImode, operands[2]));
2299
2300 }"
2301 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2302 multiple,multiple,neon_logic,neon_logic")
2303 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2304 avoid_neon_for_64bits,avoid_neon_for_64bits")
2305 (set_attr "length" "*,*,8,8,8,8,*,*")
2306 ]
2307 )
2308
2309 (define_insn_and_split "*anddi_zesidi_di"
2310 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2311 (and:DI (zero_extend:DI
2312 (match_operand:SI 2 "s_register_operand" "r,r"))
2313 (match_operand:DI 1 "s_register_operand" "0,r")))]
2314 "TARGET_32BIT"
2315 "#"
2316 "TARGET_32BIT && reload_completed"
2317 ; The zero extend of operand 2 clears the high word of the output
2318 ; operand.
2319 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2320 (set (match_dup 3) (const_int 0))]
2321 "
2322 {
2323 operands[3] = gen_highpart (SImode, operands[0]);
2324 operands[0] = gen_lowpart (SImode, operands[0]);
2325 operands[1] = gen_lowpart (SImode, operands[1]);
2326 }"
2327 [(set_attr "length" "8")
2328 (set_attr "type" "multiple")]
2329 )
2330
2331 (define_insn "*anddi_sesdi_di"
2332 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2333 (and:DI (sign_extend:DI
2334 (match_operand:SI 2 "s_register_operand" "r,r"))
2335 (match_operand:DI 1 "s_register_operand" "0,r")))]
2336 "TARGET_32BIT"
2337 "#"
2338 [(set_attr "length" "8")
2339 (set_attr "type" "multiple")]
2340 )
2341
2342 (define_expand "andsi3"
2343 [(set (match_operand:SI 0 "s_register_operand" "")
2344 (and:SI (match_operand:SI 1 "s_register_operand" "")
2345 (match_operand:SI 2 "reg_or_int_operand" "")))]
2346 "TARGET_EITHER"
2347 "
2348 if (TARGET_32BIT)
2349 {
2350 if (CONST_INT_P (operands[2]))
2351 {
2352 if (INTVAL (operands[2]) == 255 && arm_arch6)
2353 {
2354 operands[1] = convert_to_mode (QImode, operands[1], 1);
2355 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2356 operands[1]));
2357 DONE;
2358 }
2359 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2360 operands[2] = force_reg (SImode, operands[2]);
2361 else
2362 {
2363 arm_split_constant (AND, SImode, NULL_RTX,
2364 INTVAL (operands[2]), operands[0],
2365 operands[1],
2366 optimize && can_create_pseudo_p ());
2367
2368 DONE;
2369 }
2370 }
2371 }
2372 else /* TARGET_THUMB1 */
2373 {
2374 if (!CONST_INT_P (operands[2]))
2375 {
2376 rtx tmp = force_reg (SImode, operands[2]);
2377 if (rtx_equal_p (operands[0], operands[1]))
2378 operands[2] = tmp;
2379 else
2380 {
2381 operands[2] = operands[1];
2382 operands[1] = tmp;
2383 }
2384 }
2385 else
2386 {
2387 int i;
2388
2389 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2390 {
2391 operands[2] = force_reg (SImode,
2392 GEN_INT (~INTVAL (operands[2])));
2393
2394 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2395
2396 DONE;
2397 }
2398
2399 for (i = 9; i <= 31; i++)
2400 {
2401 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2402 {
2403 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2404 const0_rtx));
2405 DONE;
2406 }
2407 else if ((HOST_WIDE_INT_1 << i) - 1
2408 == ~INTVAL (operands[2]))
2409 {
2410 rtx shift = GEN_INT (i);
2411 rtx reg = gen_reg_rtx (SImode);
2412
2413 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2414 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2415
2416 DONE;
2417 }
2418 }
2419
2420 operands[2] = force_reg (SImode, operands[2]);
2421 }
2422 }
2423 "
2424 )
2425
2426 ; ??? Check split length for Thumb-2
2427 (define_insn_and_split "*arm_andsi3_insn"
2428 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2429 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2430 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2431 "TARGET_32BIT"
2432 "@
2433 and%?\\t%0, %1, %2
2434 and%?\\t%0, %1, %2
2435 bic%?\\t%0, %1, #%B2
2436 and%?\\t%0, %1, %2
2437 #"
2438 "TARGET_32BIT
2439 && CONST_INT_P (operands[2])
2440 && !(const_ok_for_arm (INTVAL (operands[2]))
2441 || const_ok_for_arm (~INTVAL (operands[2])))"
2442 [(clobber (const_int 0))]
2443 "
2444 arm_split_constant (AND, SImode, curr_insn,
2445 INTVAL (operands[2]), operands[0], operands[1], 0);
2446 DONE;
2447 "
2448 [(set_attr "length" "4,4,4,4,16")
2449 (set_attr "predicable" "yes")
2450 (set_attr "predicable_short_it" "no,yes,no,no,no")
2451 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2452 )
2453
2454 (define_insn "*andsi3_compare0"
2455 [(set (reg:CC_NOOV CC_REGNUM)
2456 (compare:CC_NOOV
2457 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2458 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2459 (const_int 0)))
2460 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2461 (and:SI (match_dup 1) (match_dup 2)))]
2462 "TARGET_32BIT"
2463 "@
2464 ands%?\\t%0, %1, %2
2465 bics%?\\t%0, %1, #%B2
2466 ands%?\\t%0, %1, %2"
2467 [(set_attr "conds" "set")
2468 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2469 )
2470
2471 (define_insn "*andsi3_compare0_scratch"
2472 [(set (reg:CC_NOOV CC_REGNUM)
2473 (compare:CC_NOOV
2474 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2475 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2476 (const_int 0)))
2477 (clobber (match_scratch:SI 2 "=X,r,X"))]
2478 "TARGET_32BIT"
2479 "@
2480 tst%?\\t%0, %1
2481 bics%?\\t%2, %0, #%B1
2482 tst%?\\t%0, %1"
2483 [(set_attr "conds" "set")
2484 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2485 )
2486
2487 (define_insn "*zeroextractsi_compare0_scratch"
2488 [(set (reg:CC_NOOV CC_REGNUM)
2489 (compare:CC_NOOV (zero_extract:SI
2490 (match_operand:SI 0 "s_register_operand" "r")
2491 (match_operand 1 "const_int_operand" "n")
2492 (match_operand 2 "const_int_operand" "n"))
2493 (const_int 0)))]
2494 "TARGET_32BIT
2495 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2496 && INTVAL (operands[1]) > 0
2497 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2498 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2499 "*
2500 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2501 << INTVAL (operands[2]));
2502 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2503 return \"\";
2504 "
2505 [(set_attr "conds" "set")
2506 (set_attr "predicable" "yes")
2507 (set_attr "predicable_short_it" "no")
2508 (set_attr "type" "logics_imm")]
2509 )
2510
2511 (define_insn_and_split "*ne_zeroextractsi"
2512 [(set (match_operand:SI 0 "s_register_operand" "=r")
2513 (ne:SI (zero_extract:SI
2514 (match_operand:SI 1 "s_register_operand" "r")
2515 (match_operand:SI 2 "const_int_operand" "n")
2516 (match_operand:SI 3 "const_int_operand" "n"))
2517 (const_int 0)))
2518 (clobber (reg:CC CC_REGNUM))]
2519 "TARGET_32BIT
2520 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2521 && INTVAL (operands[2]) > 0
2522 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2523 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2524 "#"
2525 "TARGET_32BIT
2526 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2527 && INTVAL (operands[2]) > 0
2528 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2529 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2530 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2531 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2532 (const_int 0)))
2533 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2534 (set (match_dup 0)
2535 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2536 (match_dup 0) (const_int 1)))]
2537 "
2538 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2539 << INTVAL (operands[3]));
2540 "
2541 [(set_attr "conds" "clob")
2542 (set (attr "length")
2543 (if_then_else (eq_attr "is_thumb" "yes")
2544 (const_int 12)
2545 (const_int 8)))
2546 (set_attr "type" "multiple")]
2547 )
2548
2549 (define_insn_and_split "*ne_zeroextractsi_shifted"
2550 [(set (match_operand:SI 0 "s_register_operand" "=r")
2551 (ne:SI (zero_extract:SI
2552 (match_operand:SI 1 "s_register_operand" "r")
2553 (match_operand:SI 2 "const_int_operand" "n")
2554 (const_int 0))
2555 (const_int 0)))
2556 (clobber (reg:CC CC_REGNUM))]
2557 "TARGET_ARM"
2558 "#"
2559 "TARGET_ARM"
2560 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2561 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2562 (const_int 0)))
2563 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2564 (set (match_dup 0)
2565 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2566 (match_dup 0) (const_int 1)))]
2567 "
2568 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2569 "
2570 [(set_attr "conds" "clob")
2571 (set_attr "length" "8")
2572 (set_attr "type" "multiple")]
2573 )
2574
2575 (define_insn_and_split "*ite_ne_zeroextractsi"
2576 [(set (match_operand:SI 0 "s_register_operand" "=r")
2577 (if_then_else:SI (ne (zero_extract:SI
2578 (match_operand:SI 1 "s_register_operand" "r")
2579 (match_operand:SI 2 "const_int_operand" "n")
2580 (match_operand:SI 3 "const_int_operand" "n"))
2581 (const_int 0))
2582 (match_operand:SI 4 "arm_not_operand" "rIK")
2583 (const_int 0)))
2584 (clobber (reg:CC CC_REGNUM))]
2585 "TARGET_ARM
2586 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2587 && INTVAL (operands[2]) > 0
2588 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2589 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2590 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2591 "#"
2592 "TARGET_ARM
2593 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2594 && INTVAL (operands[2]) > 0
2595 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2596 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2597 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2598 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2599 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2600 (const_int 0)))
2601 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2602 (set (match_dup 0)
2603 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2604 (match_dup 0) (match_dup 4)))]
2605 "
2606 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2607 << INTVAL (operands[3]));
2608 "
2609 [(set_attr "conds" "clob")
2610 (set_attr "length" "8")
2611 (set_attr "type" "multiple")]
2612 )
2613
2614 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2615 [(set (match_operand:SI 0 "s_register_operand" "=r")
2616 (if_then_else:SI (ne (zero_extract:SI
2617 (match_operand:SI 1 "s_register_operand" "r")
2618 (match_operand:SI 2 "const_int_operand" "n")
2619 (const_int 0))
2620 (const_int 0))
2621 (match_operand:SI 3 "arm_not_operand" "rIK")
2622 (const_int 0)))
2623 (clobber (reg:CC CC_REGNUM))]
2624 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2625 "#"
2626 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2627 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2628 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2629 (const_int 0)))
2630 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2631 (set (match_dup 0)
2632 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2633 (match_dup 0) (match_dup 3)))]
2634 "
2635 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2636 "
2637 [(set_attr "conds" "clob")
2638 (set_attr "length" "8")
2639 (set_attr "type" "multiple")]
2640 )
2641
2642 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2643 (define_split
2644 [(set (match_operand:SI 0 "s_register_operand" "")
2645 (match_operator:SI 1 "shiftable_operator"
2646 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2647 (match_operand:SI 3 "const_int_operand" "")
2648 (match_operand:SI 4 "const_int_operand" ""))
2649 (match_operand:SI 5 "s_register_operand" "")]))
2650 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2651 "TARGET_ARM"
2652 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2653 (set (match_dup 0)
2654 (match_op_dup 1
2655 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2656 (match_dup 5)]))]
2657 "{
2658 HOST_WIDE_INT temp = INTVAL (operands[3]);
2659
2660 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2661 operands[4] = GEN_INT (32 - temp);
2662 }"
2663 )
2664
2665 (define_split
2666 [(set (match_operand:SI 0 "s_register_operand" "")
2667 (match_operator:SI 1 "shiftable_operator"
2668 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2669 (match_operand:SI 3 "const_int_operand" "")
2670 (match_operand:SI 4 "const_int_operand" ""))
2671 (match_operand:SI 5 "s_register_operand" "")]))
2672 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2673 "TARGET_ARM"
2674 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2675 (set (match_dup 0)
2676 (match_op_dup 1
2677 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2678 (match_dup 5)]))]
2679 "{
2680 HOST_WIDE_INT temp = INTVAL (operands[3]);
2681
2682 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2683 operands[4] = GEN_INT (32 - temp);
2684 }"
2685 )
2686
2687 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2688 ;;; represented by the bitfield, then this will produce incorrect results.
2689 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2690 ;;; which have a real bit-field insert instruction, the truncation happens
2691 ;;; in the bit-field insert instruction itself. Since arm does not have a
2692 ;;; bit-field insert instruction, we would have to emit code here to truncate
2693 ;;; the value before we insert. This loses some of the advantage of having
2694 ;;; this insv pattern, so this pattern needs to be reevalutated.
2695
2696 (define_expand "insv"
2697 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2698 (match_operand 1 "general_operand" "")
2699 (match_operand 2 "general_operand" ""))
2700 (match_operand 3 "reg_or_int_operand" ""))]
2701 "TARGET_ARM || arm_arch_thumb2"
2702 "
2703 {
2704 int start_bit = INTVAL (operands[2]);
2705 int width = INTVAL (operands[1]);
2706 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2707 rtx target, subtarget;
2708
2709 if (arm_arch_thumb2)
2710 {
2711 if (unaligned_access && MEM_P (operands[0])
2712 && s_register_operand (operands[3], GET_MODE (operands[3]))
2713 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2714 {
2715 rtx base_addr;
2716
2717 if (BYTES_BIG_ENDIAN)
2718 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2719 - start_bit;
2720
2721 if (width == 32)
2722 {
2723 base_addr = adjust_address (operands[0], SImode,
2724 start_bit / BITS_PER_UNIT);
2725 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2726 }
2727 else
2728 {
2729 rtx tmp = gen_reg_rtx (HImode);
2730
2731 base_addr = adjust_address (operands[0], HImode,
2732 start_bit / BITS_PER_UNIT);
2733 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2734 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2735 }
2736 DONE;
2737 }
2738 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2739 {
2740 bool use_bfi = TRUE;
2741
2742 if (CONST_INT_P (operands[3]))
2743 {
2744 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2745
2746 if (val == 0)
2747 {
2748 emit_insn (gen_insv_zero (operands[0], operands[1],
2749 operands[2]));
2750 DONE;
2751 }
2752
2753 /* See if the set can be done with a single orr instruction. */
2754 if (val == mask && const_ok_for_arm (val << start_bit))
2755 use_bfi = FALSE;
2756 }
2757
2758 if (use_bfi)
2759 {
2760 if (!REG_P (operands[3]))
2761 operands[3] = force_reg (SImode, operands[3]);
2762
2763 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2764 operands[3]));
2765 DONE;
2766 }
2767 }
2768 else
2769 FAIL;
2770 }
2771
2772 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2773 FAIL;
2774
2775 target = copy_rtx (operands[0]);
2776 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2777 subreg as the final target. */
2778 if (GET_CODE (target) == SUBREG)
2779 {
2780 subtarget = gen_reg_rtx (SImode);
2781 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2782 < GET_MODE_SIZE (SImode))
2783 target = SUBREG_REG (target);
2784 }
2785 else
2786 subtarget = target;
2787
2788 if (CONST_INT_P (operands[3]))
2789 {
2790 /* Since we are inserting a known constant, we may be able to
2791 reduce the number of bits that we have to clear so that
2792 the mask becomes simple. */
2793 /* ??? This code does not check to see if the new mask is actually
2794 simpler. It may not be. */
2795 rtx op1 = gen_reg_rtx (SImode);
2796 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2797 start of this pattern. */
2798 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2799 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2800
2801 emit_insn (gen_andsi3 (op1, operands[0],
2802 gen_int_mode (~mask2, SImode)));
2803 emit_insn (gen_iorsi3 (subtarget, op1,
2804 gen_int_mode (op3_value << start_bit, SImode)));
2805 }
2806 else if (start_bit == 0
2807 && !(const_ok_for_arm (mask)
2808 || const_ok_for_arm (~mask)))
2809 {
2810 /* A Trick, since we are setting the bottom bits in the word,
2811 we can shift operand[3] up, operand[0] down, OR them together
2812 and rotate the result back again. This takes 3 insns, and
2813 the third might be mergeable into another op. */
2814 /* The shift up copes with the possibility that operand[3] is
2815 wider than the bitfield. */
2816 rtx op0 = gen_reg_rtx (SImode);
2817 rtx op1 = gen_reg_rtx (SImode);
2818
2819 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2820 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2821 emit_insn (gen_iorsi3 (op1, op1, op0));
2822 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2823 }
2824 else if ((width + start_bit == 32)
2825 && !(const_ok_for_arm (mask)
2826 || const_ok_for_arm (~mask)))
2827 {
2828 /* Similar trick, but slightly less efficient. */
2829
2830 rtx op0 = gen_reg_rtx (SImode);
2831 rtx op1 = gen_reg_rtx (SImode);
2832
2833 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2834 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2835 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2836 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2837 }
2838 else
2839 {
2840 rtx op0 = gen_int_mode (mask, SImode);
2841 rtx op1 = gen_reg_rtx (SImode);
2842 rtx op2 = gen_reg_rtx (SImode);
2843
2844 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2845 {
2846 rtx tmp = gen_reg_rtx (SImode);
2847
2848 emit_insn (gen_movsi (tmp, op0));
2849 op0 = tmp;
2850 }
2851
2852 /* Mask out any bits in operand[3] that are not needed. */
2853 emit_insn (gen_andsi3 (op1, operands[3], op0));
2854
2855 if (CONST_INT_P (op0)
2856 && (const_ok_for_arm (mask << start_bit)
2857 || const_ok_for_arm (~(mask << start_bit))))
2858 {
2859 op0 = gen_int_mode (~(mask << start_bit), SImode);
2860 emit_insn (gen_andsi3 (op2, operands[0], op0));
2861 }
2862 else
2863 {
2864 if (CONST_INT_P (op0))
2865 {
2866 rtx tmp = gen_reg_rtx (SImode);
2867
2868 emit_insn (gen_movsi (tmp, op0));
2869 op0 = tmp;
2870 }
2871
2872 if (start_bit != 0)
2873 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2874
2875 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2876 }
2877
2878 if (start_bit != 0)
2879 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2880
2881 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2882 }
2883
2884 if (subtarget != target)
2885 {
2886 /* If TARGET is still a SUBREG, then it must be wider than a word,
2887 so we must be careful only to set the subword we were asked to. */
2888 if (GET_CODE (target) == SUBREG)
2889 emit_move_insn (target, subtarget);
2890 else
2891 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2892 }
2893
2894 DONE;
2895 }"
2896 )
2897
2898 (define_insn "insv_zero"
2899 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2900 (match_operand:SI 1 "const_int_M_operand" "M")
2901 (match_operand:SI 2 "const_int_M_operand" "M"))
2902 (const_int 0))]
2903 "arm_arch_thumb2"
2904 "bfc%?\t%0, %2, %1"
2905 [(set_attr "length" "4")
2906 (set_attr "predicable" "yes")
2907 (set_attr "predicable_short_it" "no")
2908 (set_attr "type" "bfm")]
2909 )
2910
2911 (define_insn "insv_t2"
2912 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2913 (match_operand:SI 1 "const_int_M_operand" "M")
2914 (match_operand:SI 2 "const_int_M_operand" "M"))
2915 (match_operand:SI 3 "s_register_operand" "r"))]
2916 "arm_arch_thumb2"
2917 "bfi%?\t%0, %3, %2, %1"
2918 [(set_attr "length" "4")
2919 (set_attr "predicable" "yes")
2920 (set_attr "predicable_short_it" "no")
2921 (set_attr "type" "bfm")]
2922 )
2923
2924 ; constants for op 2 will never be given to these patterns.
2925 (define_insn_and_split "*anddi_notdi_di"
2926 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2927 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2928 (match_operand:DI 2 "s_register_operand" "r,0")))]
2929 "TARGET_32BIT"
2930 "#"
2931 "TARGET_32BIT && reload_completed
2932 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2933 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2934 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2935 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2936 "
2937 {
2938 operands[3] = gen_highpart (SImode, operands[0]);
2939 operands[0] = gen_lowpart (SImode, operands[0]);
2940 operands[4] = gen_highpart (SImode, operands[1]);
2941 operands[1] = gen_lowpart (SImode, operands[1]);
2942 operands[5] = gen_highpart (SImode, operands[2]);
2943 operands[2] = gen_lowpart (SImode, operands[2]);
2944 }"
2945 [(set_attr "length" "8")
2946 (set_attr "predicable" "yes")
2947 (set_attr "type" "multiple")]
2948 )
2949
2950 (define_insn_and_split "*anddi_notzesidi_di"
2951 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2952 (and:DI (not:DI (zero_extend:DI
2953 (match_operand:SI 2 "s_register_operand" "r,r")))
2954 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2955 "TARGET_32BIT"
2956 "@
2957 bic%?\\t%Q0, %Q1, %2
2958 #"
2959 ; (not (zero_extend ...)) allows us to just copy the high word from
2960 ; operand1 to operand0.
2961 "TARGET_32BIT
2962 && reload_completed
2963 && operands[0] != operands[1]"
2964 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2965 (set (match_dup 3) (match_dup 4))]
2966 "
2967 {
2968 operands[3] = gen_highpart (SImode, operands[0]);
2969 operands[0] = gen_lowpart (SImode, operands[0]);
2970 operands[4] = gen_highpart (SImode, operands[1]);
2971 operands[1] = gen_lowpart (SImode, operands[1]);
2972 }"
2973 [(set_attr "length" "4,8")
2974 (set_attr "predicable" "yes")
2975 (set_attr "predicable_short_it" "no")
2976 (set_attr "type" "multiple")]
2977 )
2978
2979 (define_insn_and_split "*anddi_notdi_zesidi"
2980 [(set (match_operand:DI 0 "s_register_operand" "=r")
2981 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2982 (zero_extend:DI
2983 (match_operand:SI 1 "s_register_operand" "r"))))]
2984 "TARGET_32BIT"
2985 "#"
2986 "TARGET_32BIT && reload_completed"
2987 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2988 (set (match_dup 3) (const_int 0))]
2989 "
2990 {
2991 operands[3] = gen_highpart (SImode, operands[0]);
2992 operands[0] = gen_lowpart (SImode, operands[0]);
2993 operands[2] = gen_lowpart (SImode, operands[2]);
2994 }"
2995 [(set_attr "length" "8")
2996 (set_attr "predicable" "yes")
2997 (set_attr "predicable_short_it" "no")
2998 (set_attr "type" "multiple")]
2999 )
3000
3001 (define_insn_and_split "*anddi_notsesidi_di"
3002 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3003 (and:DI (not:DI (sign_extend:DI
3004 (match_operand:SI 2 "s_register_operand" "r,r")))
3005 (match_operand:DI 1 "s_register_operand" "0,r")))]
3006 "TARGET_32BIT"
3007 "#"
3008 "TARGET_32BIT && reload_completed"
3009 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3010 (set (match_dup 3) (and:SI (not:SI
3011 (ashiftrt:SI (match_dup 2) (const_int 31)))
3012 (match_dup 4)))]
3013 "
3014 {
3015 operands[3] = gen_highpart (SImode, operands[0]);
3016 operands[0] = gen_lowpart (SImode, operands[0]);
3017 operands[4] = gen_highpart (SImode, operands[1]);
3018 operands[1] = gen_lowpart (SImode, operands[1]);
3019 }"
3020 [(set_attr "length" "8")
3021 (set_attr "predicable" "yes")
3022 (set_attr "predicable_short_it" "no")
3023 (set_attr "type" "multiple")]
3024 )
3025
3026 (define_insn "andsi_notsi_si"
3027 [(set (match_operand:SI 0 "s_register_operand" "=r")
3028 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3029 (match_operand:SI 1 "s_register_operand" "r")))]
3030 "TARGET_32BIT"
3031 "bic%?\\t%0, %1, %2"
3032 [(set_attr "predicable" "yes")
3033 (set_attr "predicable_short_it" "no")
3034 (set_attr "type" "logic_reg")]
3035 )
3036
3037 (define_insn "andsi_not_shiftsi_si"
3038 [(set (match_operand:SI 0 "s_register_operand" "=r")
3039 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3040 [(match_operand:SI 2 "s_register_operand" "r")
3041 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3042 (match_operand:SI 1 "s_register_operand" "r")))]
3043 "TARGET_ARM"
3044 "bic%?\\t%0, %1, %2%S4"
3045 [(set_attr "predicable" "yes")
3046 (set_attr "shift" "2")
3047 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3048 (const_string "logic_shift_imm")
3049 (const_string "logic_shift_reg")))]
3050 )
3051
3052 ;; Shifted bics pattern used to set up CC status register and not reusing
3053 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3054 ;; does not support shift by register.
3055 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3056 [(set (reg:CC_NOOV CC_REGNUM)
3057 (compare:CC_NOOV
3058 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3059 [(match_operand:SI 1 "s_register_operand" "r")
3060 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3061 (match_operand:SI 3 "s_register_operand" "r"))
3062 (const_int 0)))
3063 (clobber (match_scratch:SI 4 "=r"))]
3064 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3065 "bics%?\\t%4, %3, %1%S0"
3066 [(set_attr "predicable" "yes")
3067 (set_attr "predicable_short_it" "no")
3068 (set_attr "conds" "set")
3069 (set_attr "shift" "1")
3070 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3071 (const_string "logic_shift_imm")
3072 (const_string "logic_shift_reg")))]
3073 )
3074
3075 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3076 ;; getting reused later.
3077 (define_insn "andsi_not_shiftsi_si_scc"
3078 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3079 (compare:CC_NOOV
3080 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3081 [(match_operand:SI 1 "s_register_operand" "r")
3082 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3083 (match_operand:SI 3 "s_register_operand" "r"))
3084 (const_int 0)))
3085 (set (match_operand:SI 4 "s_register_operand" "=r")
3086 (and:SI (not:SI (match_op_dup 0
3087 [(match_dup 1)
3088 (match_dup 2)]))
3089 (match_dup 3)))])]
3090 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3091 "bics%?\\t%4, %3, %1%S0"
3092 [(set_attr "predicable" "yes")
3093 (set_attr "predicable_short_it" "no")
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 (define_insn "*andsi_notsi_si_compare0"
3102 [(set (reg:CC_NOOV CC_REGNUM)
3103 (compare:CC_NOOV
3104 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3105 (match_operand:SI 1 "s_register_operand" "r"))
3106 (const_int 0)))
3107 (set (match_operand:SI 0 "s_register_operand" "=r")
3108 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3109 "TARGET_32BIT"
3110 "bics\\t%0, %1, %2"
3111 [(set_attr "conds" "set")
3112 (set_attr "type" "logics_shift_reg")]
3113 )
3114
3115 (define_insn "*andsi_notsi_si_compare0_scratch"
3116 [(set (reg:CC_NOOV CC_REGNUM)
3117 (compare:CC_NOOV
3118 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3119 (match_operand:SI 1 "s_register_operand" "r"))
3120 (const_int 0)))
3121 (clobber (match_scratch:SI 0 "=r"))]
3122 "TARGET_32BIT"
3123 "bics\\t%0, %1, %2"
3124 [(set_attr "conds" "set")
3125 (set_attr "type" "logics_shift_reg")]
3126 )
3127
3128 (define_expand "iordi3"
3129 [(set (match_operand:DI 0 "s_register_operand" "")
3130 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3131 (match_operand:DI 2 "neon_logic_op2" "")))]
3132 "TARGET_32BIT"
3133 ""
3134 )
3135
3136 (define_insn_and_split "*iordi3_insn"
3137 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3138 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3139 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3140 "TARGET_32BIT && !TARGET_IWMMXT"
3141 {
3142 switch (which_alternative)
3143 {
3144 case 0: /* fall through */
3145 case 6: return "vorr\t%P0, %P1, %P2";
3146 case 1: /* fall through */
3147 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3148 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3149 case 2:
3150 case 3:
3151 case 4:
3152 case 5:
3153 return "#";
3154 default: gcc_unreachable ();
3155 }
3156 }
3157 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3158 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3159 [(set (match_dup 3) (match_dup 4))
3160 (set (match_dup 5) (match_dup 6))]
3161 "
3162 {
3163 operands[3] = gen_lowpart (SImode, operands[0]);
3164 operands[5] = gen_highpart (SImode, operands[0]);
3165
3166 operands[4] = simplify_gen_binary (IOR, SImode,
3167 gen_lowpart (SImode, operands[1]),
3168 gen_lowpart (SImode, operands[2]));
3169 operands[6] = simplify_gen_binary (IOR, SImode,
3170 gen_highpart (SImode, operands[1]),
3171 gen_highpart_mode (SImode, DImode, operands[2]));
3172
3173 }"
3174 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3175 multiple,neon_logic,neon_logic")
3176 (set_attr "length" "*,*,8,8,8,8,*,*")
3177 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3178 )
3179
3180 (define_insn "*iordi_zesidi_di"
3181 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3182 (ior:DI (zero_extend:DI
3183 (match_operand:SI 2 "s_register_operand" "r,r"))
3184 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3185 "TARGET_32BIT"
3186 "@
3187 orr%?\\t%Q0, %Q1, %2
3188 #"
3189 [(set_attr "length" "4,8")
3190 (set_attr "predicable" "yes")
3191 (set_attr "predicable_short_it" "no")
3192 (set_attr "type" "logic_reg,multiple")]
3193 )
3194
3195 (define_insn "*iordi_sesidi_di"
3196 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3197 (ior:DI (sign_extend:DI
3198 (match_operand:SI 2 "s_register_operand" "r,r"))
3199 (match_operand:DI 1 "s_register_operand" "0,r")))]
3200 "TARGET_32BIT"
3201 "#"
3202 [(set_attr "length" "8")
3203 (set_attr "predicable" "yes")
3204 (set_attr "type" "multiple")]
3205 )
3206
3207 (define_expand "iorsi3"
3208 [(set (match_operand:SI 0 "s_register_operand" "")
3209 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3210 (match_operand:SI 2 "reg_or_int_operand" "")))]
3211 "TARGET_EITHER"
3212 "
3213 if (CONST_INT_P (operands[2]))
3214 {
3215 if (TARGET_32BIT)
3216 {
3217 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3218 operands[2] = force_reg (SImode, operands[2]);
3219 else
3220 {
3221 arm_split_constant (IOR, SImode, NULL_RTX,
3222 INTVAL (operands[2]), operands[0],
3223 operands[1],
3224 optimize && can_create_pseudo_p ());
3225 DONE;
3226 }
3227 }
3228 else /* TARGET_THUMB1 */
3229 {
3230 rtx tmp = force_reg (SImode, operands[2]);
3231 if (rtx_equal_p (operands[0], operands[1]))
3232 operands[2] = tmp;
3233 else
3234 {
3235 operands[2] = operands[1];
3236 operands[1] = tmp;
3237 }
3238 }
3239 }
3240 "
3241 )
3242
3243 (define_insn_and_split "*iorsi3_insn"
3244 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3245 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3246 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3247 "TARGET_32BIT"
3248 "@
3249 orr%?\\t%0, %1, %2
3250 orr%?\\t%0, %1, %2
3251 orn%?\\t%0, %1, #%B2
3252 orr%?\\t%0, %1, %2
3253 #"
3254 "TARGET_32BIT
3255 && CONST_INT_P (operands[2])
3256 && !(const_ok_for_arm (INTVAL (operands[2]))
3257 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3258 [(clobber (const_int 0))]
3259 {
3260 arm_split_constant (IOR, SImode, curr_insn,
3261 INTVAL (operands[2]), operands[0], operands[1], 0);
3262 DONE;
3263 }
3264 [(set_attr "length" "4,4,4,4,16")
3265 (set_attr "arch" "32,t2,t2,32,32")
3266 (set_attr "predicable" "yes")
3267 (set_attr "predicable_short_it" "no,yes,no,no,no")
3268 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3269 )
3270
3271 (define_peephole2
3272 [(match_scratch:SI 3 "r")
3273 (set (match_operand:SI 0 "arm_general_register_operand" "")
3274 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3275 (match_operand:SI 2 "const_int_operand" "")))]
3276 "TARGET_ARM
3277 && !const_ok_for_arm (INTVAL (operands[2]))
3278 && const_ok_for_arm (~INTVAL (operands[2]))"
3279 [(set (match_dup 3) (match_dup 2))
3280 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3281 ""
3282 )
3283
3284 (define_insn "*iorsi3_compare0"
3285 [(set (reg:CC_NOOV CC_REGNUM)
3286 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3287 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3288 (const_int 0)))
3289 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3290 (ior:SI (match_dup 1) (match_dup 2)))]
3291 "TARGET_32BIT"
3292 "orrs%?\\t%0, %1, %2"
3293 [(set_attr "conds" "set")
3294 (set_attr "type" "logics_imm,logics_reg")]
3295 )
3296
3297 (define_insn "*iorsi3_compare0_scratch"
3298 [(set (reg:CC_NOOV CC_REGNUM)
3299 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3300 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3301 (const_int 0)))
3302 (clobber (match_scratch:SI 0 "=r,r"))]
3303 "TARGET_32BIT"
3304 "orrs%?\\t%0, %1, %2"
3305 [(set_attr "conds" "set")
3306 (set_attr "type" "logics_imm,logics_reg")]
3307 )
3308
3309 (define_expand "xordi3"
3310 [(set (match_operand:DI 0 "s_register_operand" "")
3311 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3312 (match_operand:DI 2 "arm_xordi_operand" "")))]
3313 "TARGET_32BIT"
3314 ""
3315 )
3316
3317 (define_insn_and_split "*xordi3_insn"
3318 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3319 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3320 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3321 "TARGET_32BIT && !TARGET_IWMMXT"
3322 {
3323 switch (which_alternative)
3324 {
3325 case 1:
3326 case 2:
3327 case 3:
3328 case 4: /* fall through */
3329 return "#";
3330 case 0: /* fall through */
3331 case 5: return "veor\t%P0, %P1, %P2";
3332 default: gcc_unreachable ();
3333 }
3334 }
3335 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3336 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3337 [(set (match_dup 3) (match_dup 4))
3338 (set (match_dup 5) (match_dup 6))]
3339 "
3340 {
3341 operands[3] = gen_lowpart (SImode, operands[0]);
3342 operands[5] = gen_highpart (SImode, operands[0]);
3343
3344 operands[4] = simplify_gen_binary (XOR, SImode,
3345 gen_lowpart (SImode, operands[1]),
3346 gen_lowpart (SImode, operands[2]));
3347 operands[6] = simplify_gen_binary (XOR, SImode,
3348 gen_highpart (SImode, operands[1]),
3349 gen_highpart_mode (SImode, DImode, operands[2]));
3350
3351 }"
3352 [(set_attr "length" "*,8,8,8,8,*")
3353 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3354 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3355 )
3356
3357 (define_insn "*xordi_zesidi_di"
3358 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3359 (xor:DI (zero_extend:DI
3360 (match_operand:SI 2 "s_register_operand" "r,r"))
3361 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3362 "TARGET_32BIT"
3363 "@
3364 eor%?\\t%Q0, %Q1, %2
3365 #"
3366 [(set_attr "length" "4,8")
3367 (set_attr "predicable" "yes")
3368 (set_attr "predicable_short_it" "no")
3369 (set_attr "type" "logic_reg")]
3370 )
3371
3372 (define_insn "*xordi_sesidi_di"
3373 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3374 (xor:DI (sign_extend:DI
3375 (match_operand:SI 2 "s_register_operand" "r,r"))
3376 (match_operand:DI 1 "s_register_operand" "0,r")))]
3377 "TARGET_32BIT"
3378 "#"
3379 [(set_attr "length" "8")
3380 (set_attr "predicable" "yes")
3381 (set_attr "type" "multiple")]
3382 )
3383
3384 (define_expand "xorsi3"
3385 [(set (match_operand:SI 0 "s_register_operand" "")
3386 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3387 (match_operand:SI 2 "reg_or_int_operand" "")))]
3388 "TARGET_EITHER"
3389 "if (CONST_INT_P (operands[2]))
3390 {
3391 if (TARGET_32BIT)
3392 {
3393 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3394 operands[2] = force_reg (SImode, operands[2]);
3395 else
3396 {
3397 arm_split_constant (XOR, SImode, NULL_RTX,
3398 INTVAL (operands[2]), operands[0],
3399 operands[1],
3400 optimize && can_create_pseudo_p ());
3401 DONE;
3402 }
3403 }
3404 else /* TARGET_THUMB1 */
3405 {
3406 rtx tmp = force_reg (SImode, operands[2]);
3407 if (rtx_equal_p (operands[0], operands[1]))
3408 operands[2] = tmp;
3409 else
3410 {
3411 operands[2] = operands[1];
3412 operands[1] = tmp;
3413 }
3414 }
3415 }"
3416 )
3417
3418 (define_insn_and_split "*arm_xorsi3"
3419 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3420 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3421 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3422 "TARGET_32BIT"
3423 "@
3424 eor%?\\t%0, %1, %2
3425 eor%?\\t%0, %1, %2
3426 eor%?\\t%0, %1, %2
3427 #"
3428 "TARGET_32BIT
3429 && CONST_INT_P (operands[2])
3430 && !const_ok_for_arm (INTVAL (operands[2]))"
3431 [(clobber (const_int 0))]
3432 {
3433 arm_split_constant (XOR, SImode, curr_insn,
3434 INTVAL (operands[2]), operands[0], operands[1], 0);
3435 DONE;
3436 }
3437 [(set_attr "length" "4,4,4,16")
3438 (set_attr "predicable" "yes")
3439 (set_attr "predicable_short_it" "no,yes,no,no")
3440 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3441 )
3442
3443 (define_insn "*xorsi3_compare0"
3444 [(set (reg:CC_NOOV CC_REGNUM)
3445 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3446 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3447 (const_int 0)))
3448 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3449 (xor:SI (match_dup 1) (match_dup 2)))]
3450 "TARGET_32BIT"
3451 "eors%?\\t%0, %1, %2"
3452 [(set_attr "conds" "set")
3453 (set_attr "type" "logics_imm,logics_reg")]
3454 )
3455
3456 (define_insn "*xorsi3_compare0_scratch"
3457 [(set (reg:CC_NOOV CC_REGNUM)
3458 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3459 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3460 (const_int 0)))]
3461 "TARGET_32BIT"
3462 "teq%?\\t%0, %1"
3463 [(set_attr "conds" "set")
3464 (set_attr "type" "logics_imm,logics_reg")]
3465 )
3466
3467 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3468 ; (NOT D) we can sometimes merge the final NOT into one of the following
3469 ; insns.
3470
3471 (define_split
3472 [(set (match_operand:SI 0 "s_register_operand" "")
3473 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3474 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3475 (match_operand:SI 3 "arm_rhs_operand" "")))
3476 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3477 "TARGET_32BIT"
3478 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3479 (not:SI (match_dup 3))))
3480 (set (match_dup 0) (not:SI (match_dup 4)))]
3481 ""
3482 )
3483
3484 (define_insn_and_split "*andsi_iorsi3_notsi"
3485 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3486 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3487 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3488 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3489 "TARGET_32BIT"
3490 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3491 "&& reload_completed"
3492 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3493 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3494 {
3495 /* If operands[3] is a constant make sure to fold the NOT into it
3496 to avoid creating a NOT of a CONST_INT. */
3497 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3498 if (CONST_INT_P (not_rtx))
3499 {
3500 operands[4] = operands[0];
3501 operands[5] = not_rtx;
3502 }
3503 else
3504 {
3505 operands[5] = operands[0];
3506 operands[4] = not_rtx;
3507 }
3508 }
3509 [(set_attr "length" "8")
3510 (set_attr "ce_count" "2")
3511 (set_attr "predicable" "yes")
3512 (set_attr "predicable_short_it" "no")
3513 (set_attr "type" "multiple")]
3514 )
3515
3516 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3517 ; insns are available?
3518 (define_split
3519 [(set (match_operand:SI 0 "s_register_operand" "")
3520 (match_operator:SI 1 "logical_binary_operator"
3521 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3522 (match_operand:SI 3 "const_int_operand" "")
3523 (match_operand:SI 4 "const_int_operand" ""))
3524 (match_operator:SI 9 "logical_binary_operator"
3525 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3526 (match_operand:SI 6 "const_int_operand" ""))
3527 (match_operand:SI 7 "s_register_operand" "")])]))
3528 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3529 "TARGET_32BIT
3530 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3531 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3532 [(set (match_dup 8)
3533 (match_op_dup 1
3534 [(ashift:SI (match_dup 2) (match_dup 4))
3535 (match_dup 5)]))
3536 (set (match_dup 0)
3537 (match_op_dup 1
3538 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3539 (match_dup 7)]))]
3540 "
3541 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3542 ")
3543
3544 (define_split
3545 [(set (match_operand:SI 0 "s_register_operand" "")
3546 (match_operator:SI 1 "logical_binary_operator"
3547 [(match_operator:SI 9 "logical_binary_operator"
3548 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3549 (match_operand:SI 6 "const_int_operand" ""))
3550 (match_operand:SI 7 "s_register_operand" "")])
3551 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3552 (match_operand:SI 3 "const_int_operand" "")
3553 (match_operand:SI 4 "const_int_operand" ""))]))
3554 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3555 "TARGET_32BIT
3556 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3557 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3558 [(set (match_dup 8)
3559 (match_op_dup 1
3560 [(ashift:SI (match_dup 2) (match_dup 4))
3561 (match_dup 5)]))
3562 (set (match_dup 0)
3563 (match_op_dup 1
3564 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3565 (match_dup 7)]))]
3566 "
3567 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3568 ")
3569
3570 (define_split
3571 [(set (match_operand:SI 0 "s_register_operand" "")
3572 (match_operator:SI 1 "logical_binary_operator"
3573 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3574 (match_operand:SI 3 "const_int_operand" "")
3575 (match_operand:SI 4 "const_int_operand" ""))
3576 (match_operator:SI 9 "logical_binary_operator"
3577 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3578 (match_operand:SI 6 "const_int_operand" ""))
3579 (match_operand:SI 7 "s_register_operand" "")])]))
3580 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3581 "TARGET_32BIT
3582 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3583 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3584 [(set (match_dup 8)
3585 (match_op_dup 1
3586 [(ashift:SI (match_dup 2) (match_dup 4))
3587 (match_dup 5)]))
3588 (set (match_dup 0)
3589 (match_op_dup 1
3590 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3591 (match_dup 7)]))]
3592 "
3593 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3594 ")
3595
3596 (define_split
3597 [(set (match_operand:SI 0 "s_register_operand" "")
3598 (match_operator:SI 1 "logical_binary_operator"
3599 [(match_operator:SI 9 "logical_binary_operator"
3600 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3601 (match_operand:SI 6 "const_int_operand" ""))
3602 (match_operand:SI 7 "s_register_operand" "")])
3603 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3604 (match_operand:SI 3 "const_int_operand" "")
3605 (match_operand:SI 4 "const_int_operand" ""))]))
3606 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3607 "TARGET_32BIT
3608 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3609 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3610 [(set (match_dup 8)
3611 (match_op_dup 1
3612 [(ashift:SI (match_dup 2) (match_dup 4))
3613 (match_dup 5)]))
3614 (set (match_dup 0)
3615 (match_op_dup 1
3616 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3617 (match_dup 7)]))]
3618 "
3619 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3620 ")
3621 \f
3622
3623 ;; Minimum and maximum insns
3624
3625 (define_expand "smaxsi3"
3626 [(parallel [
3627 (set (match_operand:SI 0 "s_register_operand" "")
3628 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3629 (match_operand:SI 2 "arm_rhs_operand" "")))
3630 (clobber (reg:CC CC_REGNUM))])]
3631 "TARGET_32BIT"
3632 "
3633 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3634 {
3635 /* No need for a clobber of the condition code register here. */
3636 emit_insn (gen_rtx_SET (operands[0],
3637 gen_rtx_SMAX (SImode, operands[1],
3638 operands[2])));
3639 DONE;
3640 }
3641 ")
3642
3643 (define_insn "*smax_0"
3644 [(set (match_operand:SI 0 "s_register_operand" "=r")
3645 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3646 (const_int 0)))]
3647 "TARGET_32BIT"
3648 "bic%?\\t%0, %1, %1, asr #31"
3649 [(set_attr "predicable" "yes")
3650 (set_attr "predicable_short_it" "no")
3651 (set_attr "type" "logic_shift_reg")]
3652 )
3653
3654 (define_insn "*smax_m1"
3655 [(set (match_operand:SI 0 "s_register_operand" "=r")
3656 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3657 (const_int -1)))]
3658 "TARGET_32BIT"
3659 "orr%?\\t%0, %1, %1, asr #31"
3660 [(set_attr "predicable" "yes")
3661 (set_attr "predicable_short_it" "no")
3662 (set_attr "type" "logic_shift_reg")]
3663 )
3664
3665 (define_insn_and_split "*arm_smax_insn"
3666 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3667 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3668 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3669 (clobber (reg:CC CC_REGNUM))]
3670 "TARGET_ARM"
3671 "#"
3672 ; cmp\\t%1, %2\;movlt\\t%0, %2
3673 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3674 "TARGET_ARM"
3675 [(set (reg:CC CC_REGNUM)
3676 (compare:CC (match_dup 1) (match_dup 2)))
3677 (set (match_dup 0)
3678 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3679 (match_dup 1)
3680 (match_dup 2)))]
3681 ""
3682 [(set_attr "conds" "clob")
3683 (set_attr "length" "8,12")
3684 (set_attr "type" "multiple")]
3685 )
3686
3687 (define_expand "sminsi3"
3688 [(parallel [
3689 (set (match_operand:SI 0 "s_register_operand" "")
3690 (smin: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)
3696 {
3697 /* No need for a clobber of the condition code register here. */
3698 emit_insn (gen_rtx_SET (operands[0],
3699 gen_rtx_SMIN (SImode, operands[1],
3700 operands[2])));
3701 DONE;
3702 }
3703 ")
3704
3705 (define_insn "*smin_0"
3706 [(set (match_operand:SI 0 "s_register_operand" "=r")
3707 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3708 (const_int 0)))]
3709 "TARGET_32BIT"
3710 "and%?\\t%0, %1, %1, asr #31"
3711 [(set_attr "predicable" "yes")
3712 (set_attr "predicable_short_it" "no")
3713 (set_attr "type" "logic_shift_reg")]
3714 )
3715
3716 (define_insn_and_split "*arm_smin_insn"
3717 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3718 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3719 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3720 (clobber (reg:CC CC_REGNUM))]
3721 "TARGET_ARM"
3722 "#"
3723 ; cmp\\t%1, %2\;movge\\t%0, %2
3724 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3725 "TARGET_ARM"
3726 [(set (reg:CC CC_REGNUM)
3727 (compare:CC (match_dup 1) (match_dup 2)))
3728 (set (match_dup 0)
3729 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3730 (match_dup 1)
3731 (match_dup 2)))]
3732 ""
3733 [(set_attr "conds" "clob")
3734 (set_attr "length" "8,12")
3735 (set_attr "type" "multiple,multiple")]
3736 )
3737
3738 (define_expand "umaxsi3"
3739 [(parallel [
3740 (set (match_operand:SI 0 "s_register_operand" "")
3741 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3742 (match_operand:SI 2 "arm_rhs_operand" "")))
3743 (clobber (reg:CC CC_REGNUM))])]
3744 "TARGET_32BIT"
3745 ""
3746 )
3747
3748 (define_insn_and_split "*arm_umaxsi3"
3749 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3750 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3751 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3752 (clobber (reg:CC CC_REGNUM))]
3753 "TARGET_ARM"
3754 "#"
3755 ; cmp\\t%1, %2\;movcc\\t%0, %2
3756 ; cmp\\t%1, %2\;movcs\\t%0, %1
3757 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3758 "TARGET_ARM"
3759 [(set (reg:CC CC_REGNUM)
3760 (compare:CC (match_dup 1) (match_dup 2)))
3761 (set (match_dup 0)
3762 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3763 (match_dup 1)
3764 (match_dup 2)))]
3765 ""
3766 [(set_attr "conds" "clob")
3767 (set_attr "length" "8,8,12")
3768 (set_attr "type" "store1")]
3769 )
3770
3771 (define_expand "uminsi3"
3772 [(parallel [
3773 (set (match_operand:SI 0 "s_register_operand" "")
3774 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3775 (match_operand:SI 2 "arm_rhs_operand" "")))
3776 (clobber (reg:CC CC_REGNUM))])]
3777 "TARGET_32BIT"
3778 ""
3779 )
3780
3781 (define_insn_and_split "*arm_uminsi3"
3782 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3783 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3784 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3785 (clobber (reg:CC CC_REGNUM))]
3786 "TARGET_ARM"
3787 "#"
3788 ; cmp\\t%1, %2\;movcs\\t%0, %2
3789 ; cmp\\t%1, %2\;movcc\\t%0, %1
3790 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3791 "TARGET_ARM"
3792 [(set (reg:CC CC_REGNUM)
3793 (compare:CC (match_dup 1) (match_dup 2)))
3794 (set (match_dup 0)
3795 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3796 (match_dup 1)
3797 (match_dup 2)))]
3798 ""
3799 [(set_attr "conds" "clob")
3800 (set_attr "length" "8,8,12")
3801 (set_attr "type" "store1")]
3802 )
3803
3804 (define_insn "*store_minmaxsi"
3805 [(set (match_operand:SI 0 "memory_operand" "=m")
3806 (match_operator:SI 3 "minmax_operator"
3807 [(match_operand:SI 1 "s_register_operand" "r")
3808 (match_operand:SI 2 "s_register_operand" "r")]))
3809 (clobber (reg:CC CC_REGNUM))]
3810 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3811 "*
3812 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3813 operands[1], operands[2]);
3814 output_asm_insn (\"cmp\\t%1, %2\", operands);
3815 if (TARGET_THUMB2)
3816 output_asm_insn (\"ite\t%d3\", operands);
3817 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3818 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3819 return \"\";
3820 "
3821 [(set_attr "conds" "clob")
3822 (set (attr "length")
3823 (if_then_else (eq_attr "is_thumb" "yes")
3824 (const_int 14)
3825 (const_int 12)))
3826 (set_attr "type" "store1")]
3827 )
3828
3829 ; Reject the frame pointer in operand[1], since reloading this after
3830 ; it has been eliminated can cause carnage.
3831 (define_insn "*minmax_arithsi"
3832 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3833 (match_operator:SI 4 "shiftable_operator"
3834 [(match_operator:SI 5 "minmax_operator"
3835 [(match_operand:SI 2 "s_register_operand" "r,r")
3836 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3837 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3838 (clobber (reg:CC CC_REGNUM))]
3839 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3840 "*
3841 {
3842 enum rtx_code code = GET_CODE (operands[4]);
3843 bool need_else;
3844
3845 if (which_alternative != 0 || operands[3] != const0_rtx
3846 || (code != PLUS && code != IOR && code != XOR))
3847 need_else = true;
3848 else
3849 need_else = false;
3850
3851 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3852 operands[2], operands[3]);
3853 output_asm_insn (\"cmp\\t%2, %3\", operands);
3854 if (TARGET_THUMB2)
3855 {
3856 if (need_else)
3857 output_asm_insn (\"ite\\t%d5\", operands);
3858 else
3859 output_asm_insn (\"it\\t%d5\", operands);
3860 }
3861 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3862 if (need_else)
3863 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3864 return \"\";
3865 }"
3866 [(set_attr "conds" "clob")
3867 (set (attr "length")
3868 (if_then_else (eq_attr "is_thumb" "yes")
3869 (const_int 14)
3870 (const_int 12)))
3871 (set_attr "type" "multiple")]
3872 )
3873
3874 ; Reject the frame pointer in operand[1], since reloading this after
3875 ; it has been eliminated can cause carnage.
3876 (define_insn_and_split "*minmax_arithsi_non_canon"
3877 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3878 (minus:SI
3879 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3880 (match_operator:SI 4 "minmax_operator"
3881 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3882 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3883 (clobber (reg:CC CC_REGNUM))]
3884 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3885 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3886 "#"
3887 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3888 [(set (reg:CC CC_REGNUM)
3889 (compare:CC (match_dup 2) (match_dup 3)))
3890
3891 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3892 (set (match_dup 0)
3893 (minus:SI (match_dup 1)
3894 (match_dup 2))))
3895 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3896 (set (match_dup 0)
3897 (match_dup 6)))]
3898 {
3899 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3900 operands[2], operands[3]);
3901 enum rtx_code rc = minmax_code (operands[4]);
3902 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3903 operands[2], operands[3]);
3904
3905 if (mode == CCFPmode || mode == CCFPEmode)
3906 rc = reverse_condition_maybe_unordered (rc);
3907 else
3908 rc = reverse_condition (rc);
3909 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3910 if (CONST_INT_P (operands[3]))
3911 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3912 else
3913 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3914 }
3915 [(set_attr "conds" "clob")
3916 (set (attr "length")
3917 (if_then_else (eq_attr "is_thumb" "yes")
3918 (const_int 14)
3919 (const_int 12)))
3920 (set_attr "type" "multiple")]
3921 )
3922
3923 (define_code_iterator SAT [smin smax])
3924 (define_code_iterator SATrev [smin smax])
3925 (define_code_attr SATlo [(smin "1") (smax "2")])
3926 (define_code_attr SAThi [(smin "2") (smax "1")])
3927
3928 (define_insn "*satsi_<SAT:code>"
3929 [(set (match_operand:SI 0 "s_register_operand" "=r")
3930 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3931 (match_operand:SI 1 "const_int_operand" "i"))
3932 (match_operand:SI 2 "const_int_operand" "i")))]
3933 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3934 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3935 {
3936 int mask;
3937 bool signed_sat;
3938 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3939 &mask, &signed_sat))
3940 gcc_unreachable ();
3941
3942 operands[1] = GEN_INT (mask);
3943 if (signed_sat)
3944 return "ssat%?\t%0, %1, %3";
3945 else
3946 return "usat%?\t%0, %1, %3";
3947 }
3948 [(set_attr "predicable" "yes")
3949 (set_attr "predicable_short_it" "no")
3950 (set_attr "type" "alus_imm")]
3951 )
3952
3953 (define_insn "*satsi_<SAT:code>_shift"
3954 [(set (match_operand:SI 0 "s_register_operand" "=r")
3955 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3956 [(match_operand:SI 4 "s_register_operand" "r")
3957 (match_operand:SI 5 "const_int_operand" "i")])
3958 (match_operand:SI 1 "const_int_operand" "i"))
3959 (match_operand:SI 2 "const_int_operand" "i")))]
3960 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3961 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3962 {
3963 int mask;
3964 bool signed_sat;
3965 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3966 &mask, &signed_sat))
3967 gcc_unreachable ();
3968
3969 operands[1] = GEN_INT (mask);
3970 if (signed_sat)
3971 return "ssat%?\t%0, %1, %4%S3";
3972 else
3973 return "usat%?\t%0, %1, %4%S3";
3974 }
3975 [(set_attr "predicable" "yes")
3976 (set_attr "predicable_short_it" "no")
3977 (set_attr "shift" "3")
3978 (set_attr "type" "logic_shift_reg")])
3979 \f
3980 ;; Shift and rotation insns
3981
3982 (define_expand "ashldi3"
3983 [(set (match_operand:DI 0 "s_register_operand" "")
3984 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3985 (match_operand:SI 2 "general_operand" "")))]
3986 "TARGET_32BIT"
3987 "
3988 if (TARGET_NEON)
3989 {
3990 /* Delay the decision whether to use NEON or core-regs until
3991 register allocation. */
3992 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3993 DONE;
3994 }
3995 else
3996 {
3997 /* Only the NEON case can handle in-memory shift counts. */
3998 if (!reg_or_int_operand (operands[2], SImode))
3999 operands[2] = force_reg (SImode, operands[2]);
4000 }
4001
4002 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4003 ; /* No special preparation statements; expand pattern as above. */
4004 else
4005 {
4006 rtx scratch1, scratch2;
4007
4008 if (operands[2] == CONST1_RTX (SImode))
4009 {
4010 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
4011 DONE;
4012 }
4013
4014 /* Ideally we should use iwmmxt here if we could know that operands[1]
4015 ends up already living in an iwmmxt register. Otherwise it's
4016 cheaper to have the alternate code being generated than moving
4017 values to iwmmxt regs and back. */
4018
4019 /* If we're optimizing for size, we prefer the libgcc calls. */
4020 if (optimize_function_for_size_p (cfun))
4021 FAIL;
4022
4023 /* Expand operation using core-registers.
4024 'FAIL' would achieve the same thing, but this is a bit smarter. */
4025 scratch1 = gen_reg_rtx (SImode);
4026 scratch2 = gen_reg_rtx (SImode);
4027 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4028 operands[2], scratch1, scratch2);
4029 DONE;
4030 }
4031 "
4032 )
4033
4034 (define_insn "arm_ashldi3_1bit"
4035 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4036 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4037 (const_int 1)))
4038 (clobber (reg:CC CC_REGNUM))]
4039 "TARGET_32BIT"
4040 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4041 [(set_attr "conds" "clob")
4042 (set_attr "length" "8")
4043 (set_attr "type" "multiple")]
4044 )
4045
4046 (define_expand "ashlsi3"
4047 [(set (match_operand:SI 0 "s_register_operand" "")
4048 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4049 (match_operand:SI 2 "arm_rhs_operand" "")))]
4050 "TARGET_EITHER"
4051 "
4052 if (CONST_INT_P (operands[2])
4053 && (UINTVAL (operands[2])) > 31)
4054 {
4055 emit_insn (gen_movsi (operands[0], const0_rtx));
4056 DONE;
4057 }
4058 "
4059 )
4060
4061 (define_expand "ashrdi3"
4062 [(set (match_operand:DI 0 "s_register_operand" "")
4063 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4064 (match_operand:SI 2 "reg_or_int_operand" "")))]
4065 "TARGET_32BIT"
4066 "
4067 if (TARGET_NEON)
4068 {
4069 /* Delay the decision whether to use NEON or core-regs until
4070 register allocation. */
4071 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4072 DONE;
4073 }
4074
4075 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4076 ; /* No special preparation statements; expand pattern as above. */
4077 else
4078 {
4079 rtx scratch1, scratch2;
4080
4081 if (operands[2] == CONST1_RTX (SImode))
4082 {
4083 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4084 DONE;
4085 }
4086
4087 /* Ideally we should use iwmmxt here if we could know that operands[1]
4088 ends up already living in an iwmmxt register. Otherwise it's
4089 cheaper to have the alternate code being generated than moving
4090 values to iwmmxt regs and back. */
4091
4092 /* If we're optimizing for size, we prefer the libgcc calls. */
4093 if (optimize_function_for_size_p (cfun))
4094 FAIL;
4095
4096 /* Expand operation using core-registers.
4097 'FAIL' would achieve the same thing, but this is a bit smarter. */
4098 scratch1 = gen_reg_rtx (SImode);
4099 scratch2 = gen_reg_rtx (SImode);
4100 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4101 operands[2], scratch1, scratch2);
4102 DONE;
4103 }
4104 "
4105 )
4106
4107 (define_insn "arm_ashrdi3_1bit"
4108 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4109 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4110 (const_int 1)))
4111 (clobber (reg:CC CC_REGNUM))]
4112 "TARGET_32BIT"
4113 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4114 [(set_attr "conds" "clob")
4115 (set_attr "length" "8")
4116 (set_attr "type" "multiple")]
4117 )
4118
4119 (define_expand "ashrsi3"
4120 [(set (match_operand:SI 0 "s_register_operand" "")
4121 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4122 (match_operand:SI 2 "arm_rhs_operand" "")))]
4123 "TARGET_EITHER"
4124 "
4125 if (CONST_INT_P (operands[2])
4126 && UINTVAL (operands[2]) > 31)
4127 operands[2] = GEN_INT (31);
4128 "
4129 )
4130
4131 (define_expand "lshrdi3"
4132 [(set (match_operand:DI 0 "s_register_operand" "")
4133 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4134 (match_operand:SI 2 "reg_or_int_operand" "")))]
4135 "TARGET_32BIT"
4136 "
4137 if (TARGET_NEON)
4138 {
4139 /* Delay the decision whether to use NEON or core-regs until
4140 register allocation. */
4141 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4142 DONE;
4143 }
4144
4145 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4146 ; /* No special preparation statements; expand pattern as above. */
4147 else
4148 {
4149 rtx scratch1, scratch2;
4150
4151 if (operands[2] == CONST1_RTX (SImode))
4152 {
4153 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4154 DONE;
4155 }
4156
4157 /* Ideally we should use iwmmxt here if we could know that operands[1]
4158 ends up already living in an iwmmxt register. Otherwise it's
4159 cheaper to have the alternate code being generated than moving
4160 values to iwmmxt regs and back. */
4161
4162 /* If we're optimizing for size, we prefer the libgcc calls. */
4163 if (optimize_function_for_size_p (cfun))
4164 FAIL;
4165
4166 /* Expand operation using core-registers.
4167 'FAIL' would achieve the same thing, but this is a bit smarter. */
4168 scratch1 = gen_reg_rtx (SImode);
4169 scratch2 = gen_reg_rtx (SImode);
4170 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4171 operands[2], scratch1, scratch2);
4172 DONE;
4173 }
4174 "
4175 )
4176
4177 (define_insn "arm_lshrdi3_1bit"
4178 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4179 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4180 (const_int 1)))
4181 (clobber (reg:CC CC_REGNUM))]
4182 "TARGET_32BIT"
4183 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4184 [(set_attr "conds" "clob")
4185 (set_attr "length" "8")
4186 (set_attr "type" "multiple")]
4187 )
4188
4189 (define_expand "lshrsi3"
4190 [(set (match_operand:SI 0 "s_register_operand" "")
4191 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4192 (match_operand:SI 2 "arm_rhs_operand" "")))]
4193 "TARGET_EITHER"
4194 "
4195 if (CONST_INT_P (operands[2])
4196 && (UINTVAL (operands[2])) > 31)
4197 {
4198 emit_insn (gen_movsi (operands[0], const0_rtx));
4199 DONE;
4200 }
4201 "
4202 )
4203
4204 (define_expand "rotlsi3"
4205 [(set (match_operand:SI 0 "s_register_operand" "")
4206 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4207 (match_operand:SI 2 "reg_or_int_operand" "")))]
4208 "TARGET_32BIT"
4209 "
4210 if (CONST_INT_P (operands[2]))
4211 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4212 else
4213 {
4214 rtx reg = gen_reg_rtx (SImode);
4215 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4216 operands[2] = reg;
4217 }
4218 "
4219 )
4220
4221 (define_expand "rotrsi3"
4222 [(set (match_operand:SI 0 "s_register_operand" "")
4223 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4224 (match_operand:SI 2 "arm_rhs_operand" "")))]
4225 "TARGET_EITHER"
4226 "
4227 if (TARGET_32BIT)
4228 {
4229 if (CONST_INT_P (operands[2])
4230 && UINTVAL (operands[2]) > 31)
4231 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4232 }
4233 else /* TARGET_THUMB1 */
4234 {
4235 if (CONST_INT_P (operands [2]))
4236 operands [2] = force_reg (SImode, operands[2]);
4237 }
4238 "
4239 )
4240
4241 (define_insn "*arm_shiftsi3"
4242 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4243 (match_operator:SI 3 "shift_operator"
4244 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4245 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4246 "TARGET_32BIT"
4247 "* return arm_output_shift(operands, 0);"
4248 [(set_attr "predicable" "yes")
4249 (set_attr "arch" "t2,t2,*,*")
4250 (set_attr "predicable_short_it" "yes,yes,no,no")
4251 (set_attr "length" "4")
4252 (set_attr "shift" "1")
4253 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4254 )
4255
4256 (define_insn "*shiftsi3_compare0"
4257 [(set (reg:CC_NOOV CC_REGNUM)
4258 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4259 [(match_operand:SI 1 "s_register_operand" "r,r")
4260 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4261 (const_int 0)))
4262 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4263 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4264 "TARGET_32BIT"
4265 "* return arm_output_shift(operands, 1);"
4266 [(set_attr "conds" "set")
4267 (set_attr "shift" "1")
4268 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4269 )
4270
4271 (define_insn "*shiftsi3_compare0_scratch"
4272 [(set (reg:CC_NOOV CC_REGNUM)
4273 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4274 [(match_operand:SI 1 "s_register_operand" "r,r")
4275 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4276 (const_int 0)))
4277 (clobber (match_scratch:SI 0 "=r,r"))]
4278 "TARGET_32BIT"
4279 "* return arm_output_shift(operands, 1);"
4280 [(set_attr "conds" "set")
4281 (set_attr "shift" "1")
4282 (set_attr "type" "shift_imm,shift_reg")]
4283 )
4284
4285 (define_insn "*not_shiftsi"
4286 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4287 (not:SI (match_operator:SI 3 "shift_operator"
4288 [(match_operand:SI 1 "s_register_operand" "r,r")
4289 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4290 "TARGET_32BIT"
4291 "mvn%?\\t%0, %1%S3"
4292 [(set_attr "predicable" "yes")
4293 (set_attr "predicable_short_it" "no")
4294 (set_attr "shift" "1")
4295 (set_attr "arch" "32,a")
4296 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4297
4298 (define_insn "*not_shiftsi_compare0"
4299 [(set (reg:CC_NOOV CC_REGNUM)
4300 (compare:CC_NOOV
4301 (not:SI (match_operator:SI 3 "shift_operator"
4302 [(match_operand:SI 1 "s_register_operand" "r,r")
4303 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4304 (const_int 0)))
4305 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4306 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4307 "TARGET_32BIT"
4308 "mvns%?\\t%0, %1%S3"
4309 [(set_attr "conds" "set")
4310 (set_attr "shift" "1")
4311 (set_attr "arch" "32,a")
4312 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4313
4314 (define_insn "*not_shiftsi_compare0_scratch"
4315 [(set (reg:CC_NOOV CC_REGNUM)
4316 (compare:CC_NOOV
4317 (not:SI (match_operator:SI 3 "shift_operator"
4318 [(match_operand:SI 1 "s_register_operand" "r,r")
4319 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4320 (const_int 0)))
4321 (clobber (match_scratch:SI 0 "=r,r"))]
4322 "TARGET_32BIT"
4323 "mvns%?\\t%0, %1%S3"
4324 [(set_attr "conds" "set")
4325 (set_attr "shift" "1")
4326 (set_attr "arch" "32,a")
4327 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4328
4329 ;; We don't really have extzv, but defining this using shifts helps
4330 ;; to reduce register pressure later on.
4331
4332 (define_expand "extzv"
4333 [(set (match_operand 0 "s_register_operand" "")
4334 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4335 (match_operand 2 "const_int_operand" "")
4336 (match_operand 3 "const_int_operand" "")))]
4337 "TARGET_THUMB1 || arm_arch_thumb2"
4338 "
4339 {
4340 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4341 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4342
4343 if (arm_arch_thumb2)
4344 {
4345 HOST_WIDE_INT width = INTVAL (operands[2]);
4346 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4347
4348 if (unaligned_access && MEM_P (operands[1])
4349 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4350 {
4351 rtx base_addr;
4352
4353 if (BYTES_BIG_ENDIAN)
4354 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4355 - bitpos;
4356
4357 if (width == 32)
4358 {
4359 base_addr = adjust_address (operands[1], SImode,
4360 bitpos / BITS_PER_UNIT);
4361 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4362 }
4363 else
4364 {
4365 rtx dest = operands[0];
4366 rtx tmp = gen_reg_rtx (SImode);
4367
4368 /* We may get a paradoxical subreg here. Strip it off. */
4369 if (GET_CODE (dest) == SUBREG
4370 && GET_MODE (dest) == SImode
4371 && GET_MODE (SUBREG_REG (dest)) == HImode)
4372 dest = SUBREG_REG (dest);
4373
4374 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4375 FAIL;
4376
4377 base_addr = adjust_address (operands[1], HImode,
4378 bitpos / BITS_PER_UNIT);
4379 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4380 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4381 }
4382 DONE;
4383 }
4384 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4385 {
4386 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4387 operands[3]));
4388 DONE;
4389 }
4390 else
4391 FAIL;
4392 }
4393
4394 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4395 FAIL;
4396
4397 operands[3] = GEN_INT (rshift);
4398
4399 if (lshift == 0)
4400 {
4401 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4402 DONE;
4403 }
4404
4405 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4406 operands[3], gen_reg_rtx (SImode)));
4407 DONE;
4408 }"
4409 )
4410
4411 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4412
4413 (define_expand "extzv_t1"
4414 [(set (match_operand:SI 4 "s_register_operand" "")
4415 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4416 (match_operand:SI 2 "const_int_operand" "")))
4417 (set (match_operand:SI 0 "s_register_operand" "")
4418 (lshiftrt:SI (match_dup 4)
4419 (match_operand:SI 3 "const_int_operand" "")))]
4420 "TARGET_THUMB1"
4421 "")
4422
4423 (define_expand "extv"
4424 [(set (match_operand 0 "s_register_operand" "")
4425 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4426 (match_operand 2 "const_int_operand" "")
4427 (match_operand 3 "const_int_operand" "")))]
4428 "arm_arch_thumb2"
4429 {
4430 HOST_WIDE_INT width = INTVAL (operands[2]);
4431 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4432
4433 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4434 && (bitpos % BITS_PER_UNIT) == 0)
4435 {
4436 rtx base_addr;
4437
4438 if (BYTES_BIG_ENDIAN)
4439 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4440
4441 if (width == 32)
4442 {
4443 base_addr = adjust_address (operands[1], SImode,
4444 bitpos / BITS_PER_UNIT);
4445 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4446 }
4447 else
4448 {
4449 rtx dest = operands[0];
4450 rtx tmp = gen_reg_rtx (SImode);
4451
4452 /* We may get a paradoxical subreg here. Strip it off. */
4453 if (GET_CODE (dest) == SUBREG
4454 && GET_MODE (dest) == SImode
4455 && GET_MODE (SUBREG_REG (dest)) == HImode)
4456 dest = SUBREG_REG (dest);
4457
4458 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4459 FAIL;
4460
4461 base_addr = adjust_address (operands[1], HImode,
4462 bitpos / BITS_PER_UNIT);
4463 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4464 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4465 }
4466
4467 DONE;
4468 }
4469 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4470 FAIL;
4471 else if (GET_MODE (operands[0]) == SImode
4472 && GET_MODE (operands[1]) == SImode)
4473 {
4474 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4475 operands[3]));
4476 DONE;
4477 }
4478
4479 FAIL;
4480 })
4481
4482 ; Helper to expand register forms of extv with the proper modes.
4483
4484 (define_expand "extv_regsi"
4485 [(set (match_operand:SI 0 "s_register_operand" "")
4486 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4487 (match_operand 2 "const_int_operand" "")
4488 (match_operand 3 "const_int_operand" "")))]
4489 ""
4490 {
4491 })
4492
4493 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4494
4495 (define_insn "unaligned_loadsi"
4496 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4497 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4498 UNSPEC_UNALIGNED_LOAD))]
4499 "unaligned_access"
4500 "ldr%?\t%0, %1\t@ unaligned"
4501 [(set_attr "arch" "t2,any")
4502 (set_attr "length" "2,4")
4503 (set_attr "predicable" "yes")
4504 (set_attr "predicable_short_it" "yes,no")
4505 (set_attr "type" "load1")])
4506
4507 (define_insn "unaligned_loadhis"
4508 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4509 (sign_extend:SI
4510 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4511 UNSPEC_UNALIGNED_LOAD)))]
4512 "unaligned_access"
4513 "ldrsh%?\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_loadhiu"
4521 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4522 (zero_extend:SI
4523 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4524 UNSPEC_UNALIGNED_LOAD)))]
4525 "unaligned_access"
4526 "ldrh%?\t%0, %1\t@ unaligned"
4527 [(set_attr "arch" "t2,any")
4528 (set_attr "length" "2,4")
4529 (set_attr "predicable" "yes")
4530 (set_attr "predicable_short_it" "yes,no")
4531 (set_attr "type" "load_byte")])
4532
4533 (define_insn "unaligned_storesi"
4534 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4535 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4536 UNSPEC_UNALIGNED_STORE))]
4537 "unaligned_access"
4538 "str%?\t%1, %0\t@ unaligned"
4539 [(set_attr "arch" "t2,any")
4540 (set_attr "length" "2,4")
4541 (set_attr "predicable" "yes")
4542 (set_attr "predicable_short_it" "yes,no")
4543 (set_attr "type" "store1")])
4544
4545 (define_insn "unaligned_storehi"
4546 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4547 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4548 UNSPEC_UNALIGNED_STORE))]
4549 "unaligned_access"
4550 "strh%?\t%1, %0\t@ unaligned"
4551 [(set_attr "arch" "t2,any")
4552 (set_attr "length" "2,4")
4553 (set_attr "predicable" "yes")
4554 (set_attr "predicable_short_it" "yes,no")
4555 (set_attr "type" "store1")])
4556
4557
4558 (define_insn "*extv_reg"
4559 [(set (match_operand:SI 0 "s_register_operand" "=r")
4560 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4561 (match_operand:SI 2 "const_int_M_operand" "M")
4562 (match_operand:SI 3 "const_int_M_operand" "M")))]
4563 "arm_arch_thumb2"
4564 "sbfx%?\t%0, %1, %3, %2"
4565 [(set_attr "length" "4")
4566 (set_attr "predicable" "yes")
4567 (set_attr "predicable_short_it" "no")
4568 (set_attr "type" "bfm")]
4569 )
4570
4571 (define_insn "extzv_t2"
4572 [(set (match_operand:SI 0 "s_register_operand" "=r")
4573 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4574 (match_operand:SI 2 "const_int_M_operand" "M")
4575 (match_operand:SI 3 "const_int_M_operand" "M")))]
4576 "arm_arch_thumb2"
4577 "ubfx%?\t%0, %1, %3, %2"
4578 [(set_attr "length" "4")
4579 (set_attr "predicable" "yes")
4580 (set_attr "predicable_short_it" "no")
4581 (set_attr "type" "bfm")]
4582 )
4583
4584
4585 ;; Division instructions
4586 (define_insn "divsi3"
4587 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4588 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4589 (match_operand:SI 2 "s_register_operand" "r,r")))]
4590 "TARGET_IDIV"
4591 "@
4592 sdiv%?\t%0, %1, %2
4593 sdiv\t%0, %1, %2"
4594 [(set_attr "arch" "32,v8mb")
4595 (set_attr "predicable" "yes")
4596 (set_attr "predicable_short_it" "no")
4597 (set_attr "type" "sdiv")]
4598 )
4599
4600 (define_insn "udivsi3"
4601 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4602 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4603 (match_operand:SI 2 "s_register_operand" "r,r")))]
4604 "TARGET_IDIV"
4605 "@
4606 udiv%?\t%0, %1, %2
4607 udiv\t%0, %1, %2"
4608 [(set_attr "arch" "32,v8mb")
4609 (set_attr "predicable" "yes")
4610 (set_attr "predicable_short_it" "no")
4611 (set_attr "type" "udiv")]
4612 )
4613
4614 \f
4615 ;; Unary arithmetic insns
4616
4617 (define_expand "negvsi3"
4618 [(match_operand:SI 0 "register_operand")
4619 (match_operand:SI 1 "register_operand")
4620 (match_operand 2 "")]
4621 "TARGET_32BIT"
4622 {
4623 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4624 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4625
4626 DONE;
4627 })
4628
4629 (define_expand "negvdi3"
4630 [(match_operand:DI 0 "register_operand")
4631 (match_operand:DI 1 "register_operand")
4632 (match_operand 2 "")]
4633 "TARGET_ARM"
4634 {
4635 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4636 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4637
4638 DONE;
4639 })
4640
4641
4642 (define_insn_and_split "negdi2_compare"
4643 [(set (reg:CC CC_REGNUM)
4644 (compare:CC
4645 (const_int 0)
4646 (match_operand:DI 1 "register_operand" "0,r")))
4647 (set (match_operand:DI 0 "register_operand" "=r,&r")
4648 (minus:DI (const_int 0) (match_dup 1)))]
4649 "TARGET_ARM"
4650 "#"
4651 "&& reload_completed"
4652 [(parallel [(set (reg:CC CC_REGNUM)
4653 (compare:CC (const_int 0) (match_dup 1)))
4654 (set (match_dup 0) (minus:SI (const_int 0)
4655 (match_dup 1)))])
4656 (parallel [(set (reg:CC CC_REGNUM)
4657 (compare:CC (const_int 0) (match_dup 3)))
4658 (set (match_dup 2)
4659 (minus:SI
4660 (minus:SI (const_int 0) (match_dup 3))
4661 (ltu:SI (reg:CC_C CC_REGNUM)
4662 (const_int 0))))])]
4663 {
4664 operands[2] = gen_highpart (SImode, operands[0]);
4665 operands[0] = gen_lowpart (SImode, operands[0]);
4666 operands[3] = gen_highpart (SImode, operands[1]);
4667 operands[1] = gen_lowpart (SImode, operands[1]);
4668 }
4669 [(set_attr "conds" "set")
4670 (set_attr "length" "8")
4671 (set_attr "type" "multiple")]
4672 )
4673
4674 (define_expand "negdi2"
4675 [(parallel
4676 [(set (match_operand:DI 0 "s_register_operand" "")
4677 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4678 (clobber (reg:CC CC_REGNUM))])]
4679 "TARGET_EITHER"
4680 {
4681 if (TARGET_NEON)
4682 {
4683 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4684 DONE;
4685 }
4686 }
4687 )
4688
4689 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4690 ;; The first alternative allows the common case of a *full* overlap.
4691 (define_insn_and_split "*arm_negdi2"
4692 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4693 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4694 (clobber (reg:CC CC_REGNUM))]
4695 "TARGET_ARM"
4696 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4697 "&& reload_completed"
4698 [(parallel [(set (reg:CC CC_REGNUM)
4699 (compare:CC (const_int 0) (match_dup 1)))
4700 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4701 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4702 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4703 {
4704 operands[2] = gen_highpart (SImode, operands[0]);
4705 operands[0] = gen_lowpart (SImode, operands[0]);
4706 operands[3] = gen_highpart (SImode, operands[1]);
4707 operands[1] = gen_lowpart (SImode, operands[1]);
4708 }
4709 [(set_attr "conds" "clob")
4710 (set_attr "length" "8")
4711 (set_attr "type" "multiple")]
4712 )
4713
4714 (define_insn "*negsi2_carryin_compare"
4715 [(set (reg:CC CC_REGNUM)
4716 (compare:CC (const_int 0)
4717 (match_operand:SI 1 "s_register_operand" "r")))
4718 (set (match_operand:SI 0 "s_register_operand" "=r")
4719 (minus:SI (minus:SI (const_int 0)
4720 (match_dup 1))
4721 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4722 "TARGET_ARM"
4723 "rscs\\t%0, %1, #0"
4724 [(set_attr "conds" "set")
4725 (set_attr "type" "alus_imm")]
4726 )
4727
4728 (define_expand "negsi2"
4729 [(set (match_operand:SI 0 "s_register_operand" "")
4730 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4731 "TARGET_EITHER"
4732 ""
4733 )
4734
4735 (define_insn "*arm_negsi2"
4736 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4737 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4738 "TARGET_32BIT"
4739 "rsb%?\\t%0, %1, #0"
4740 [(set_attr "predicable" "yes")
4741 (set_attr "predicable_short_it" "yes,no")
4742 (set_attr "arch" "t2,*")
4743 (set_attr "length" "4")
4744 (set_attr "type" "alu_sreg")]
4745 )
4746
4747 (define_expand "negsf2"
4748 [(set (match_operand:SF 0 "s_register_operand" "")
4749 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4750 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
4751 ""
4752 )
4753
4754 (define_expand "negdf2"
4755 [(set (match_operand:DF 0 "s_register_operand" "")
4756 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4757 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4758 "")
4759
4760 (define_insn_and_split "*zextendsidi_negsi"
4761 [(set (match_operand:DI 0 "s_register_operand" "=r")
4762 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4763 "TARGET_32BIT"
4764 "#"
4765 ""
4766 [(set (match_dup 2)
4767 (neg:SI (match_dup 1)))
4768 (set (match_dup 3)
4769 (const_int 0))]
4770 {
4771 operands[2] = gen_lowpart (SImode, operands[0]);
4772 operands[3] = gen_highpart (SImode, operands[0]);
4773 }
4774 [(set_attr "length" "8")
4775 (set_attr "type" "multiple")]
4776 )
4777
4778 ;; Negate an extended 32-bit value.
4779 (define_insn_and_split "*negdi_extendsidi"
4780 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4781 (neg:DI (sign_extend:DI
4782 (match_operand:SI 1 "s_register_operand" "l,r"))))
4783 (clobber (reg:CC CC_REGNUM))]
4784 "TARGET_32BIT"
4785 "#"
4786 "&& reload_completed"
4787 [(const_int 0)]
4788 {
4789 rtx low = gen_lowpart (SImode, operands[0]);
4790 rtx high = gen_highpart (SImode, operands[0]);
4791
4792 if (reg_overlap_mentioned_p (low, operands[1]))
4793 {
4794 /* Input overlaps the low word of the output. Use:
4795 asr Rhi, Rin, #31
4796 rsbs Rlo, Rin, #0
4797 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4798 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4799
4800 emit_insn (gen_rtx_SET (high,
4801 gen_rtx_ASHIFTRT (SImode, operands[1],
4802 GEN_INT (31))));
4803
4804 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4805 if (TARGET_ARM)
4806 emit_insn (gen_rtx_SET (high,
4807 gen_rtx_MINUS (SImode,
4808 gen_rtx_MINUS (SImode,
4809 const0_rtx,
4810 high),
4811 gen_rtx_LTU (SImode,
4812 cc_reg,
4813 const0_rtx))));
4814 else
4815 {
4816 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4817 emit_insn (gen_rtx_SET (high,
4818 gen_rtx_MINUS (SImode,
4819 gen_rtx_MINUS (SImode,
4820 high,
4821 two_x),
4822 gen_rtx_LTU (SImode,
4823 cc_reg,
4824 const0_rtx))));
4825 }
4826 }
4827 else
4828 {
4829 /* No overlap, or overlap on high word. Use:
4830 rsb Rlo, Rin, #0
4831 bic Rhi, Rlo, Rin
4832 asr Rhi, Rhi, #31
4833 Flags not needed for this sequence. */
4834 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4835 emit_insn (gen_rtx_SET (high,
4836 gen_rtx_AND (SImode,
4837 gen_rtx_NOT (SImode, operands[1]),
4838 low)));
4839 emit_insn (gen_rtx_SET (high,
4840 gen_rtx_ASHIFTRT (SImode, high,
4841 GEN_INT (31))));
4842 }
4843 DONE;
4844 }
4845 [(set_attr "length" "12")
4846 (set_attr "arch" "t2,*")
4847 (set_attr "type" "multiple")]
4848 )
4849
4850 (define_insn_and_split "*negdi_zero_extendsidi"
4851 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4852 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4853 (clobber (reg:CC CC_REGNUM))]
4854 "TARGET_32BIT"
4855 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4856 ;; Don't care what register is input to sbc,
4857 ;; since we just need to propagate the carry.
4858 "&& reload_completed"
4859 [(parallel [(set (reg:CC CC_REGNUM)
4860 (compare:CC (const_int 0) (match_dup 1)))
4861 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4862 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4863 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4864 {
4865 operands[2] = gen_highpart (SImode, operands[0]);
4866 operands[0] = gen_lowpart (SImode, operands[0]);
4867 }
4868 [(set_attr "conds" "clob")
4869 (set_attr "length" "8")
4870 (set_attr "type" "multiple")] ;; length in thumb is 4
4871 )
4872
4873 ;; abssi2 doesn't really clobber the condition codes if a different register
4874 ;; is being set. To keep things simple, assume during rtl manipulations that
4875 ;; it does, but tell the final scan operator the truth. Similarly for
4876 ;; (neg (abs...))
4877
4878 (define_expand "abssi2"
4879 [(parallel
4880 [(set (match_operand:SI 0 "s_register_operand" "")
4881 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4882 (clobber (match_dup 2))])]
4883 "TARGET_EITHER"
4884 "
4885 if (TARGET_THUMB1)
4886 operands[2] = gen_rtx_SCRATCH (SImode);
4887 else
4888 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4889 ")
4890
4891 (define_insn_and_split "*arm_abssi2"
4892 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4893 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4894 (clobber (reg:CC CC_REGNUM))]
4895 "TARGET_ARM"
4896 "#"
4897 "&& reload_completed"
4898 [(const_int 0)]
4899 {
4900 /* if (which_alternative == 0) */
4901 if (REGNO(operands[0]) == REGNO(operands[1]))
4902 {
4903 /* Emit the pattern:
4904 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4905 [(set (reg:CC CC_REGNUM)
4906 (compare:CC (match_dup 0) (const_int 0)))
4907 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4908 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4909 */
4910 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4911 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4912 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4913 (gen_rtx_LT (SImode,
4914 gen_rtx_REG (CCmode, CC_REGNUM),
4915 const0_rtx)),
4916 (gen_rtx_SET (operands[0],
4917 (gen_rtx_MINUS (SImode,
4918 const0_rtx,
4919 operands[1]))))));
4920 DONE;
4921 }
4922 else
4923 {
4924 /* Emit the pattern:
4925 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4926 [(set (match_dup 0)
4927 (xor:SI (match_dup 1)
4928 (ashiftrt:SI (match_dup 1) (const_int 31))))
4929 (set (match_dup 0)
4930 (minus:SI (match_dup 0)
4931 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4932 */
4933 emit_insn (gen_rtx_SET (operands[0],
4934 gen_rtx_XOR (SImode,
4935 gen_rtx_ASHIFTRT (SImode,
4936 operands[1],
4937 GEN_INT (31)),
4938 operands[1])));
4939 emit_insn (gen_rtx_SET (operands[0],
4940 gen_rtx_MINUS (SImode,
4941 operands[0],
4942 gen_rtx_ASHIFTRT (SImode,
4943 operands[1],
4944 GEN_INT (31)))));
4945 DONE;
4946 }
4947 }
4948 [(set_attr "conds" "clob,*")
4949 (set_attr "shift" "1")
4950 (set_attr "predicable" "no, yes")
4951 (set_attr "length" "8")
4952 (set_attr "type" "multiple")]
4953 )
4954
4955 (define_insn_and_split "*arm_neg_abssi2"
4956 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4957 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4958 (clobber (reg:CC CC_REGNUM))]
4959 "TARGET_ARM"
4960 "#"
4961 "&& reload_completed"
4962 [(const_int 0)]
4963 {
4964 /* if (which_alternative == 0) */
4965 if (REGNO (operands[0]) == REGNO (operands[1]))
4966 {
4967 /* Emit the pattern:
4968 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4969 */
4970 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4971 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4972 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4973 gen_rtx_GT (SImode,
4974 gen_rtx_REG (CCmode, CC_REGNUM),
4975 const0_rtx),
4976 gen_rtx_SET (operands[0],
4977 (gen_rtx_MINUS (SImode,
4978 const0_rtx,
4979 operands[1])))));
4980 }
4981 else
4982 {
4983 /* Emit the pattern:
4984 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4985 */
4986 emit_insn (gen_rtx_SET (operands[0],
4987 gen_rtx_XOR (SImode,
4988 gen_rtx_ASHIFTRT (SImode,
4989 operands[1],
4990 GEN_INT (31)),
4991 operands[1])));
4992 emit_insn (gen_rtx_SET (operands[0],
4993 gen_rtx_MINUS (SImode,
4994 gen_rtx_ASHIFTRT (SImode,
4995 operands[1],
4996 GEN_INT (31)),
4997 operands[0])));
4998 }
4999 DONE;
5000 }
5001 [(set_attr "conds" "clob,*")
5002 (set_attr "shift" "1")
5003 (set_attr "predicable" "no, yes")
5004 (set_attr "length" "8")
5005 (set_attr "type" "multiple")]
5006 )
5007
5008 (define_expand "abssf2"
5009 [(set (match_operand:SF 0 "s_register_operand" "")
5010 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5011 "TARGET_32BIT && TARGET_HARD_FLOAT"
5012 "")
5013
5014 (define_expand "absdf2"
5015 [(set (match_operand:DF 0 "s_register_operand" "")
5016 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5017 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5018 "")
5019
5020 (define_expand "sqrtsf2"
5021 [(set (match_operand:SF 0 "s_register_operand" "")
5022 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5023 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
5024 "")
5025
5026 (define_expand "sqrtdf2"
5027 [(set (match_operand:DF 0 "s_register_operand" "")
5028 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5029 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5030 "")
5031
5032 (define_insn_and_split "one_cmpldi2"
5033 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5034 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5035 "TARGET_32BIT"
5036 "@
5037 vmvn\t%P0, %P1
5038 #
5039 #
5040 vmvn\t%P0, %P1"
5041 "TARGET_32BIT && reload_completed
5042 && arm_general_register_operand (operands[0], DImode)"
5043 [(set (match_dup 0) (not:SI (match_dup 1)))
5044 (set (match_dup 2) (not:SI (match_dup 3)))]
5045 "
5046 {
5047 operands[2] = gen_highpart (SImode, operands[0]);
5048 operands[0] = gen_lowpart (SImode, operands[0]);
5049 operands[3] = gen_highpart (SImode, operands[1]);
5050 operands[1] = gen_lowpart (SImode, operands[1]);
5051 }"
5052 [(set_attr "length" "*,8,8,*")
5053 (set_attr "predicable" "no,yes,yes,no")
5054 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5055 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5056 )
5057
5058 (define_expand "one_cmplsi2"
5059 [(set (match_operand:SI 0 "s_register_operand" "")
5060 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5061 "TARGET_EITHER"
5062 ""
5063 )
5064
5065 (define_insn "*arm_one_cmplsi2"
5066 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5067 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5068 "TARGET_32BIT"
5069 "mvn%?\\t%0, %1"
5070 [(set_attr "predicable" "yes")
5071 (set_attr "predicable_short_it" "yes,no")
5072 (set_attr "arch" "t2,*")
5073 (set_attr "length" "4")
5074 (set_attr "type" "mvn_reg")]
5075 )
5076
5077 (define_insn "*notsi_compare0"
5078 [(set (reg:CC_NOOV CC_REGNUM)
5079 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5080 (const_int 0)))
5081 (set (match_operand:SI 0 "s_register_operand" "=r")
5082 (not:SI (match_dup 1)))]
5083 "TARGET_32BIT"
5084 "mvns%?\\t%0, %1"
5085 [(set_attr "conds" "set")
5086 (set_attr "type" "mvn_reg")]
5087 )
5088
5089 (define_insn "*notsi_compare0_scratch"
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 (clobber (match_scratch:SI 0 "=r"))]
5094 "TARGET_32BIT"
5095 "mvns%?\\t%0, %1"
5096 [(set_attr "conds" "set")
5097 (set_attr "type" "mvn_reg")]
5098 )
5099 \f
5100 ;; Fixed <--> Floating conversion insns
5101
5102 (define_expand "floatsihf2"
5103 [(set (match_operand:HF 0 "general_operand" "")
5104 (float:HF (match_operand:SI 1 "general_operand" "")))]
5105 "TARGET_EITHER"
5106 "
5107 {
5108 rtx op1 = gen_reg_rtx (SFmode);
5109 expand_float (op1, operands[1], 0);
5110 op1 = convert_to_mode (HFmode, op1, 0);
5111 emit_move_insn (operands[0], op1);
5112 DONE;
5113 }"
5114 )
5115
5116 (define_expand "floatdihf2"
5117 [(set (match_operand:HF 0 "general_operand" "")
5118 (float:HF (match_operand:DI 1 "general_operand" "")))]
5119 "TARGET_EITHER"
5120 "
5121 {
5122 rtx op1 = gen_reg_rtx (SFmode);
5123 expand_float (op1, operands[1], 0);
5124 op1 = convert_to_mode (HFmode, op1, 0);
5125 emit_move_insn (operands[0], op1);
5126 DONE;
5127 }"
5128 )
5129
5130 (define_expand "floatsisf2"
5131 [(set (match_operand:SF 0 "s_register_operand" "")
5132 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5133 "TARGET_32BIT && TARGET_HARD_FLOAT"
5134 "
5135 ")
5136
5137 (define_expand "floatsidf2"
5138 [(set (match_operand:DF 0 "s_register_operand" "")
5139 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5140 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5141 "
5142 ")
5143
5144 (define_expand "fix_trunchfsi2"
5145 [(set (match_operand:SI 0 "general_operand" "")
5146 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5147 "TARGET_EITHER"
5148 "
5149 {
5150 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5151 expand_fix (operands[0], op1, 0);
5152 DONE;
5153 }"
5154 )
5155
5156 (define_expand "fix_trunchfdi2"
5157 [(set (match_operand:DI 0 "general_operand" "")
5158 (fix:DI (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_truncsfsi2"
5169 [(set (match_operand:SI 0 "s_register_operand" "")
5170 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5171 "TARGET_32BIT && TARGET_HARD_FLOAT"
5172 "
5173 ")
5174
5175 (define_expand "fix_truncdfsi2"
5176 [(set (match_operand:SI 0 "s_register_operand" "")
5177 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5178 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5179 "
5180 ")
5181
5182 ;; Truncation insns
5183
5184 (define_expand "truncdfsf2"
5185 [(set (match_operand:SF 0 "s_register_operand" "")
5186 (float_truncate:SF
5187 (match_operand:DF 1 "s_register_operand" "")))]
5188 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5189 ""
5190 )
5191
5192 ;; DFmode to HFmode conversions have to go through SFmode.
5193 (define_expand "truncdfhf2"
5194 [(set (match_operand:HF 0 "general_operand" "")
5195 (float_truncate:HF
5196 (match_operand:DF 1 "general_operand" "")))]
5197 "TARGET_EITHER"
5198 "
5199 {
5200 rtx op1;
5201 op1 = convert_to_mode (SFmode, operands[1], 0);
5202 op1 = convert_to_mode (HFmode, op1, 0);
5203 emit_move_insn (operands[0], op1);
5204 DONE;
5205 }"
5206 )
5207 \f
5208 ;; Zero and sign extension instructions.
5209
5210 (define_insn "zero_extend<mode>di2"
5211 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5212 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5213 "<qhs_zextenddi_cstr>")))]
5214 "TARGET_32BIT <qhs_zextenddi_cond>"
5215 "#"
5216 [(set_attr "length" "8,4,8,8")
5217 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5218 (set_attr "ce_count" "2")
5219 (set_attr "predicable" "yes")
5220 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5221 )
5222
5223 (define_insn "extend<mode>di2"
5224 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5225 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5226 "<qhs_extenddi_cstr>")))]
5227 "TARGET_32BIT <qhs_sextenddi_cond>"
5228 "#"
5229 [(set_attr "length" "8,4,8,8,8")
5230 (set_attr "ce_count" "2")
5231 (set_attr "shift" "1")
5232 (set_attr "predicable" "yes")
5233 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5234 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5235 )
5236
5237 ;; Splits for all extensions to DImode
5238 (define_split
5239 [(set (match_operand:DI 0 "s_register_operand" "")
5240 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5241 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5242 [(set (match_dup 0) (match_dup 1))]
5243 {
5244 rtx lo_part = gen_lowpart (SImode, operands[0]);
5245 machine_mode src_mode = GET_MODE (operands[1]);
5246
5247 if (REG_P (operands[0])
5248 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5249 emit_clobber (operands[0]);
5250 if (!REG_P (lo_part) || src_mode != SImode
5251 || !rtx_equal_p (lo_part, operands[1]))
5252 {
5253 if (src_mode == SImode)
5254 emit_move_insn (lo_part, operands[1]);
5255 else
5256 emit_insn (gen_rtx_SET (lo_part,
5257 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5258 operands[1] = lo_part;
5259 }
5260 operands[0] = gen_highpart (SImode, operands[0]);
5261 operands[1] = const0_rtx;
5262 })
5263
5264 (define_split
5265 [(set (match_operand:DI 0 "s_register_operand" "")
5266 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5267 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5268 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
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
5277 if (!REG_P (lo_part) || src_mode != SImode
5278 || !rtx_equal_p (lo_part, operands[1]))
5279 {
5280 if (src_mode == SImode)
5281 emit_move_insn (lo_part, operands[1]);
5282 else
5283 emit_insn (gen_rtx_SET (lo_part,
5284 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5285 operands[1] = lo_part;
5286 }
5287 operands[0] = gen_highpart (SImode, operands[0]);
5288 })
5289
5290 (define_expand "zero_extendhisi2"
5291 [(set (match_operand:SI 0 "s_register_operand" "")
5292 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5293 "TARGET_EITHER"
5294 {
5295 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5296 {
5297 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5298 DONE;
5299 }
5300 if (!arm_arch6 && !MEM_P (operands[1]))
5301 {
5302 rtx t = gen_lowpart (SImode, operands[1]);
5303 rtx tmp = gen_reg_rtx (SImode);
5304 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5305 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5306 DONE;
5307 }
5308 })
5309
5310 (define_split
5311 [(set (match_operand:SI 0 "s_register_operand" "")
5312 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5313 "!TARGET_THUMB2 && !arm_arch6"
5314 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5315 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5316 {
5317 operands[2] = gen_lowpart (SImode, operands[1]);
5318 })
5319
5320 (define_insn "*arm_zero_extendhisi2"
5321 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5322 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5323 "TARGET_ARM && arm_arch4 && !arm_arch6"
5324 "@
5325 #
5326 ldrh%?\\t%0, %1"
5327 [(set_attr "type" "alu_shift_reg,load_byte")
5328 (set_attr "predicable" "yes")]
5329 )
5330
5331 (define_insn "*arm_zero_extendhisi2_v6"
5332 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5333 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5334 "TARGET_ARM && arm_arch6"
5335 "@
5336 uxth%?\\t%0, %1
5337 ldrh%?\\t%0, %1"
5338 [(set_attr "predicable" "yes")
5339 (set_attr "type" "extend,load_byte")]
5340 )
5341
5342 (define_insn "*arm_zero_extendhisi2addsi"
5343 [(set (match_operand:SI 0 "s_register_operand" "=r")
5344 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5345 (match_operand:SI 2 "s_register_operand" "r")))]
5346 "TARGET_INT_SIMD"
5347 "uxtah%?\\t%0, %2, %1"
5348 [(set_attr "type" "alu_shift_reg")
5349 (set_attr "predicable" "yes")
5350 (set_attr "predicable_short_it" "no")]
5351 )
5352
5353 (define_expand "zero_extendqisi2"
5354 [(set (match_operand:SI 0 "s_register_operand" "")
5355 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5356 "TARGET_EITHER"
5357 {
5358 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5359 {
5360 emit_insn (gen_andsi3 (operands[0],
5361 gen_lowpart (SImode, operands[1]),
5362 GEN_INT (255)));
5363 DONE;
5364 }
5365 if (!arm_arch6 && !MEM_P (operands[1]))
5366 {
5367 rtx t = gen_lowpart (SImode, operands[1]);
5368 rtx tmp = gen_reg_rtx (SImode);
5369 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5370 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5371 DONE;
5372 }
5373 })
5374
5375 (define_split
5376 [(set (match_operand:SI 0 "s_register_operand" "")
5377 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5378 "!arm_arch6"
5379 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5380 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5381 {
5382 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5383 if (TARGET_ARM)
5384 {
5385 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5386 DONE;
5387 }
5388 })
5389
5390 (define_insn "*arm_zero_extendqisi2"
5391 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5392 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5393 "TARGET_ARM && !arm_arch6"
5394 "@
5395 #
5396 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5397 [(set_attr "length" "8,4")
5398 (set_attr "type" "alu_shift_reg,load_byte")
5399 (set_attr "predicable" "yes")]
5400 )
5401
5402 (define_insn "*arm_zero_extendqisi2_v6"
5403 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5404 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5405 "TARGET_ARM && arm_arch6"
5406 "@
5407 uxtb%?\\t%0, %1
5408 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5409 [(set_attr "type" "extend,load_byte")
5410 (set_attr "predicable" "yes")]
5411 )
5412
5413 (define_insn "*arm_zero_extendqisi2addsi"
5414 [(set (match_operand:SI 0 "s_register_operand" "=r")
5415 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5416 (match_operand:SI 2 "s_register_operand" "r")))]
5417 "TARGET_INT_SIMD"
5418 "uxtab%?\\t%0, %2, %1"
5419 [(set_attr "predicable" "yes")
5420 (set_attr "predicable_short_it" "no")
5421 (set_attr "type" "alu_shift_reg")]
5422 )
5423
5424 (define_split
5425 [(set (match_operand:SI 0 "s_register_operand" "")
5426 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5427 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5428 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5429 [(set (match_dup 2) (match_dup 1))
5430 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5431 ""
5432 )
5433
5434 (define_split
5435 [(set (match_operand:SI 0 "s_register_operand" "")
5436 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5437 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5438 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5439 [(set (match_dup 2) (match_dup 1))
5440 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5441 ""
5442 )
5443
5444
5445 (define_split
5446 [(set (match_operand:SI 0 "s_register_operand" "")
5447 (IOR_XOR:SI (and:SI (ashift:SI
5448 (match_operand:SI 1 "s_register_operand" "")
5449 (match_operand:SI 2 "const_int_operand" ""))
5450 (match_operand:SI 3 "const_int_operand" ""))
5451 (zero_extend:SI
5452 (match_operator 5 "subreg_lowpart_operator"
5453 [(match_operand:SI 4 "s_register_operand" "")]))))]
5454 "TARGET_32BIT
5455 && (UINTVAL (operands[3])
5456 == (GET_MODE_MASK (GET_MODE (operands[5]))
5457 & (GET_MODE_MASK (GET_MODE (operands[5]))
5458 << (INTVAL (operands[2])))))"
5459 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5460 (match_dup 4)))
5461 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5462 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5463 )
5464
5465 (define_insn "*compareqi_eq0"
5466 [(set (reg:CC_Z CC_REGNUM)
5467 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5468 (const_int 0)))]
5469 "TARGET_32BIT"
5470 "tst%?\\t%0, #255"
5471 [(set_attr "conds" "set")
5472 (set_attr "predicable" "yes")
5473 (set_attr "predicable_short_it" "no")
5474 (set_attr "type" "logic_imm")]
5475 )
5476
5477 (define_expand "extendhisi2"
5478 [(set (match_operand:SI 0 "s_register_operand" "")
5479 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5480 "TARGET_EITHER"
5481 {
5482 if (TARGET_THUMB1)
5483 {
5484 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5485 DONE;
5486 }
5487 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5488 {
5489 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5490 DONE;
5491 }
5492
5493 if (!arm_arch6 && !MEM_P (operands[1]))
5494 {
5495 rtx t = gen_lowpart (SImode, operands[1]);
5496 rtx tmp = gen_reg_rtx (SImode);
5497 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5498 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5499 DONE;
5500 }
5501 })
5502
5503 (define_split
5504 [(parallel
5505 [(set (match_operand:SI 0 "register_operand" "")
5506 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5507 (clobber (match_scratch:SI 2 ""))])]
5508 "!arm_arch6"
5509 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5510 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5511 {
5512 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5513 })
5514
5515 ;; This pattern will only be used when ldsh is not available
5516 (define_expand "extendhisi2_mem"
5517 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5518 (set (match_dup 3)
5519 (zero_extend:SI (match_dup 7)))
5520 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5521 (set (match_operand:SI 0 "" "")
5522 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5523 "TARGET_ARM"
5524 "
5525 {
5526 rtx mem1, mem2;
5527 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5528
5529 mem1 = change_address (operands[1], QImode, addr);
5530 mem2 = change_address (operands[1], QImode,
5531 plus_constant (Pmode, addr, 1));
5532 operands[0] = gen_lowpart (SImode, operands[0]);
5533 operands[1] = mem1;
5534 operands[2] = gen_reg_rtx (SImode);
5535 operands[3] = gen_reg_rtx (SImode);
5536 operands[6] = gen_reg_rtx (SImode);
5537 operands[7] = mem2;
5538
5539 if (BYTES_BIG_ENDIAN)
5540 {
5541 operands[4] = operands[2];
5542 operands[5] = operands[3];
5543 }
5544 else
5545 {
5546 operands[4] = operands[3];
5547 operands[5] = operands[2];
5548 }
5549 }"
5550 )
5551
5552 (define_split
5553 [(set (match_operand:SI 0 "register_operand" "")
5554 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5555 "!arm_arch6"
5556 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5557 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5558 {
5559 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5560 })
5561
5562 (define_insn "*arm_extendhisi2"
5563 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5564 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5565 "TARGET_ARM && arm_arch4 && !arm_arch6"
5566 "@
5567 #
5568 ldrsh%?\\t%0, %1"
5569 [(set_attr "length" "8,4")
5570 (set_attr "type" "alu_shift_reg,load_byte")
5571 (set_attr "predicable" "yes")]
5572 )
5573
5574 ;; ??? Check Thumb-2 pool range
5575 (define_insn "*arm_extendhisi2_v6"
5576 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5577 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5578 "TARGET_32BIT && arm_arch6"
5579 "@
5580 sxth%?\\t%0, %1
5581 ldrsh%?\\t%0, %1"
5582 [(set_attr "type" "extend,load_byte")
5583 (set_attr "predicable" "yes")
5584 (set_attr "predicable_short_it" "no")]
5585 )
5586
5587 (define_insn "*arm_extendhisi2addsi"
5588 [(set (match_operand:SI 0 "s_register_operand" "=r")
5589 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5590 (match_operand:SI 2 "s_register_operand" "r")))]
5591 "TARGET_INT_SIMD"
5592 "sxtah%?\\t%0, %2, %1"
5593 [(set_attr "type" "alu_shift_reg")]
5594 )
5595
5596 (define_expand "extendqihi2"
5597 [(set (match_dup 2)
5598 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5599 (const_int 24)))
5600 (set (match_operand:HI 0 "s_register_operand" "")
5601 (ashiftrt:SI (match_dup 2)
5602 (const_int 24)))]
5603 "TARGET_ARM"
5604 "
5605 {
5606 if (arm_arch4 && MEM_P (operands[1]))
5607 {
5608 emit_insn (gen_rtx_SET (operands[0],
5609 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5610 DONE;
5611 }
5612 if (!s_register_operand (operands[1], QImode))
5613 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5614 operands[0] = gen_lowpart (SImode, operands[0]);
5615 operands[1] = gen_lowpart (SImode, operands[1]);
5616 operands[2] = gen_reg_rtx (SImode);
5617 }"
5618 )
5619
5620 (define_insn "*arm_extendqihi_insn"
5621 [(set (match_operand:HI 0 "s_register_operand" "=r")
5622 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5623 "TARGET_ARM && arm_arch4"
5624 "ldrsb%?\\t%0, %1"
5625 [(set_attr "type" "load_byte")
5626 (set_attr "predicable" "yes")]
5627 )
5628
5629 (define_expand "extendqisi2"
5630 [(set (match_operand:SI 0 "s_register_operand" "")
5631 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5632 "TARGET_EITHER"
5633 {
5634 if (!arm_arch4 && MEM_P (operands[1]))
5635 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5636
5637 if (!arm_arch6 && !MEM_P (operands[1]))
5638 {
5639 rtx t = gen_lowpart (SImode, operands[1]);
5640 rtx tmp = gen_reg_rtx (SImode);
5641 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5642 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5643 DONE;
5644 }
5645 })
5646
5647 (define_split
5648 [(set (match_operand:SI 0 "register_operand" "")
5649 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5650 "!arm_arch6"
5651 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5652 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5653 {
5654 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5655 })
5656
5657 (define_insn "*arm_extendqisi"
5658 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5659 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5660 "TARGET_ARM && arm_arch4 && !arm_arch6"
5661 "@
5662 #
5663 ldrsb%?\\t%0, %1"
5664 [(set_attr "length" "8,4")
5665 (set_attr "type" "alu_shift_reg,load_byte")
5666 (set_attr "predicable" "yes")]
5667 )
5668
5669 (define_insn "*arm_extendqisi_v6"
5670 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5671 (sign_extend:SI
5672 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5673 "TARGET_ARM && arm_arch6"
5674 "@
5675 sxtb%?\\t%0, %1
5676 ldrsb%?\\t%0, %1"
5677 [(set_attr "type" "extend,load_byte")
5678 (set_attr "predicable" "yes")]
5679 )
5680
5681 (define_insn "*arm_extendqisi2addsi"
5682 [(set (match_operand:SI 0 "s_register_operand" "=r")
5683 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5684 (match_operand:SI 2 "s_register_operand" "r")))]
5685 "TARGET_INT_SIMD"
5686 "sxtab%?\\t%0, %2, %1"
5687 [(set_attr "type" "alu_shift_reg")
5688 (set_attr "predicable" "yes")
5689 (set_attr "predicable_short_it" "no")]
5690 )
5691
5692 (define_expand "extendsfdf2"
5693 [(set (match_operand:DF 0 "s_register_operand" "")
5694 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5695 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5696 ""
5697 )
5698
5699 ;; HFmode -> DFmode conversions have to go through SFmode.
5700 (define_expand "extendhfdf2"
5701 [(set (match_operand:DF 0 "general_operand" "")
5702 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5703 "TARGET_EITHER"
5704 "
5705 {
5706 rtx op1;
5707 op1 = convert_to_mode (SFmode, operands[1], 0);
5708 op1 = convert_to_mode (DFmode, op1, 0);
5709 emit_insn (gen_movdf (operands[0], op1));
5710 DONE;
5711 }"
5712 )
5713 \f
5714 ;; Move insns (including loads and stores)
5715
5716 ;; XXX Just some ideas about movti.
5717 ;; I don't think these are a good idea on the arm, there just aren't enough
5718 ;; registers
5719 ;;(define_expand "loadti"
5720 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5721 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5722 ;; "" "")
5723
5724 ;;(define_expand "storeti"
5725 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5726 ;; (match_operand:TI 1 "s_register_operand" ""))]
5727 ;; "" "")
5728
5729 ;;(define_expand "movti"
5730 ;; [(set (match_operand:TI 0 "general_operand" "")
5731 ;; (match_operand:TI 1 "general_operand" ""))]
5732 ;; ""
5733 ;; "
5734 ;;{
5735 ;; rtx insn;
5736 ;;
5737 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5738 ;; operands[1] = copy_to_reg (operands[1]);
5739 ;; if (MEM_P (operands[0]))
5740 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5741 ;; else if (MEM_P (operands[1]))
5742 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5743 ;; else
5744 ;; FAIL;
5745 ;;
5746 ;; emit_insn (insn);
5747 ;; DONE;
5748 ;;}")
5749
5750 ;; Recognize garbage generated above.
5751
5752 ;;(define_insn ""
5753 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5754 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5755 ;; ""
5756 ;; "*
5757 ;; {
5758 ;; register mem = (which_alternative < 3);
5759 ;; register const char *template;
5760 ;;
5761 ;; operands[mem] = XEXP (operands[mem], 0);
5762 ;; switch (which_alternative)
5763 ;; {
5764 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5765 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5766 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5767 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5768 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5769 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5770 ;; }
5771 ;; output_asm_insn (template, operands);
5772 ;; return \"\";
5773 ;; }")
5774
5775 (define_expand "movdi"
5776 [(set (match_operand:DI 0 "general_operand" "")
5777 (match_operand:DI 1 "general_operand" ""))]
5778 "TARGET_EITHER"
5779 "
5780 if (can_create_pseudo_p ())
5781 {
5782 if (!REG_P (operands[0]))
5783 operands[1] = force_reg (DImode, operands[1]);
5784 }
5785 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5786 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5787 {
5788 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5789 when expanding function calls. */
5790 gcc_assert (can_create_pseudo_p ());
5791 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5792 {
5793 /* Perform load into legal reg pair first, then move. */
5794 rtx reg = gen_reg_rtx (DImode);
5795 emit_insn (gen_movdi (reg, operands[1]));
5796 operands[1] = reg;
5797 }
5798 emit_move_insn (gen_lowpart (SImode, operands[0]),
5799 gen_lowpart (SImode, operands[1]));
5800 emit_move_insn (gen_highpart (SImode, operands[0]),
5801 gen_highpart (SImode, operands[1]));
5802 DONE;
5803 }
5804 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5805 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5806 {
5807 /* Avoid STRD's from an odd-numbered register pair in ARM state
5808 when expanding function prologue. */
5809 gcc_assert (can_create_pseudo_p ());
5810 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5811 ? gen_reg_rtx (DImode)
5812 : operands[0];
5813 emit_move_insn (gen_lowpart (SImode, split_dest),
5814 gen_lowpart (SImode, operands[1]));
5815 emit_move_insn (gen_highpart (SImode, split_dest),
5816 gen_highpart (SImode, operands[1]));
5817 if (split_dest != operands[0])
5818 emit_insn (gen_movdi (operands[0], split_dest));
5819 DONE;
5820 }
5821 "
5822 )
5823
5824 (define_insn "*arm_movdi"
5825 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5826 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5827 "TARGET_32BIT
5828 && !(TARGET_HARD_FLOAT && TARGET_VFP)
5829 && !TARGET_IWMMXT
5830 && ( register_operand (operands[0], DImode)
5831 || register_operand (operands[1], DImode))"
5832 "*
5833 switch (which_alternative)
5834 {
5835 case 0:
5836 case 1:
5837 case 2:
5838 return \"#\";
5839 default:
5840 return output_move_double (operands, true, NULL);
5841 }
5842 "
5843 [(set_attr "length" "8,12,16,8,8")
5844 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5845 (set_attr "arm_pool_range" "*,*,*,1020,*")
5846 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5847 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5848 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5849 )
5850
5851 (define_split
5852 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5853 (match_operand:ANY64 1 "immediate_operand" ""))]
5854 "TARGET_32BIT
5855 && reload_completed
5856 && (arm_const_double_inline_cost (operands[1])
5857 <= arm_max_const_double_inline_cost ())"
5858 [(const_int 0)]
5859 "
5860 arm_split_constant (SET, SImode, curr_insn,
5861 INTVAL (gen_lowpart (SImode, operands[1])),
5862 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5863 arm_split_constant (SET, SImode, curr_insn,
5864 INTVAL (gen_highpart_mode (SImode,
5865 GET_MODE (operands[0]),
5866 operands[1])),
5867 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5868 DONE;
5869 "
5870 )
5871
5872 ; If optimizing for size, or if we have load delay slots, then
5873 ; we want to split the constant into two separate operations.
5874 ; In both cases this may split a trivial part into a single data op
5875 ; leaving a single complex constant to load. We can also get longer
5876 ; offsets in a LDR which means we get better chances of sharing the pool
5877 ; entries. Finally, we can normally do a better job of scheduling
5878 ; LDR instructions than we can with LDM.
5879 ; This pattern will only match if the one above did not.
5880 (define_split
5881 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5882 (match_operand:ANY64 1 "const_double_operand" ""))]
5883 "TARGET_ARM && reload_completed
5884 && arm_const_double_by_parts (operands[1])"
5885 [(set (match_dup 0) (match_dup 1))
5886 (set (match_dup 2) (match_dup 3))]
5887 "
5888 operands[2] = gen_highpart (SImode, operands[0]);
5889 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5890 operands[1]);
5891 operands[0] = gen_lowpart (SImode, operands[0]);
5892 operands[1] = gen_lowpart (SImode, operands[1]);
5893 "
5894 )
5895
5896 (define_split
5897 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5898 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5899 "TARGET_EITHER && reload_completed"
5900 [(set (match_dup 0) (match_dup 1))
5901 (set (match_dup 2) (match_dup 3))]
5902 "
5903 operands[2] = gen_highpart (SImode, operands[0]);
5904 operands[3] = gen_highpart (SImode, operands[1]);
5905 operands[0] = gen_lowpart (SImode, operands[0]);
5906 operands[1] = gen_lowpart (SImode, operands[1]);
5907
5908 /* Handle a partial overlap. */
5909 if (rtx_equal_p (operands[0], operands[3]))
5910 {
5911 rtx tmp0 = operands[0];
5912 rtx tmp1 = operands[1];
5913
5914 operands[0] = operands[2];
5915 operands[1] = operands[3];
5916 operands[2] = tmp0;
5917 operands[3] = tmp1;
5918 }
5919 "
5920 )
5921
5922 ;; We can't actually do base+index doubleword loads if the index and
5923 ;; destination overlap. Split here so that we at least have chance to
5924 ;; schedule.
5925 (define_split
5926 [(set (match_operand:DI 0 "s_register_operand" "")
5927 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5928 (match_operand:SI 2 "s_register_operand" ""))))]
5929 "TARGET_LDRD
5930 && reg_overlap_mentioned_p (operands[0], operands[1])
5931 && reg_overlap_mentioned_p (operands[0], operands[2])"
5932 [(set (match_dup 4)
5933 (plus:SI (match_dup 1)
5934 (match_dup 2)))
5935 (set (match_dup 0)
5936 (mem:DI (match_dup 4)))]
5937 "
5938 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5939 "
5940 )
5941
5942 (define_expand "movsi"
5943 [(set (match_operand:SI 0 "general_operand" "")
5944 (match_operand:SI 1 "general_operand" ""))]
5945 "TARGET_EITHER"
5946 "
5947 {
5948 rtx base, offset, tmp;
5949
5950 if (TARGET_32BIT)
5951 {
5952 /* Everything except mem = const or mem = mem can be done easily. */
5953 if (MEM_P (operands[0]))
5954 operands[1] = force_reg (SImode, operands[1]);
5955 if (arm_general_register_operand (operands[0], SImode)
5956 && CONST_INT_P (operands[1])
5957 && !(const_ok_for_arm (INTVAL (operands[1]))
5958 || const_ok_for_arm (~INTVAL (operands[1]))))
5959 {
5960 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5961 {
5962 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5963 DONE;
5964 }
5965 else
5966 {
5967 arm_split_constant (SET, SImode, NULL_RTX,
5968 INTVAL (operands[1]), operands[0], NULL_RTX,
5969 optimize && can_create_pseudo_p ());
5970 DONE;
5971 }
5972 }
5973 }
5974 else /* TARGET_THUMB1... */
5975 {
5976 if (can_create_pseudo_p ())
5977 {
5978 if (!REG_P (operands[0]))
5979 operands[1] = force_reg (SImode, operands[1]);
5980 }
5981 }
5982
5983 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5984 {
5985 split_const (operands[1], &base, &offset);
5986 if (GET_CODE (base) == SYMBOL_REF
5987 && !offset_within_block_p (base, INTVAL (offset)))
5988 {
5989 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5990 emit_move_insn (tmp, base);
5991 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5992 DONE;
5993 }
5994 }
5995
5996 /* Recognize the case where operand[1] is a reference to thread-local
5997 data and load its address to a register. */
5998 if (arm_tls_referenced_p (operands[1]))
5999 {
6000 rtx tmp = operands[1];
6001 rtx addend = NULL;
6002
6003 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6004 {
6005 addend = XEXP (XEXP (tmp, 0), 1);
6006 tmp = XEXP (XEXP (tmp, 0), 0);
6007 }
6008
6009 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6010 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6011
6012 tmp = legitimize_tls_address (tmp,
6013 !can_create_pseudo_p () ? operands[0] : 0);
6014 if (addend)
6015 {
6016 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6017 tmp = force_operand (tmp, operands[0]);
6018 }
6019 operands[1] = tmp;
6020 }
6021 else if (flag_pic
6022 && (CONSTANT_P (operands[1])
6023 || symbol_mentioned_p (operands[1])
6024 || label_mentioned_p (operands[1])))
6025 operands[1] = legitimize_pic_address (operands[1], SImode,
6026 (!can_create_pseudo_p ()
6027 ? operands[0]
6028 : 0));
6029 }
6030 "
6031 )
6032
6033 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6034 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6035 ;; so this does not matter.
6036 (define_insn "*arm_movt"
6037 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6038 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6039 (match_operand:SI 2 "general_operand" "i,i")))]
6040 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6041 "@
6042 movt%?\t%0, #:upper16:%c2
6043 movt\t%0, #:upper16:%c2"
6044 [(set_attr "arch" "32,v8mb")
6045 (set_attr "predicable" "yes")
6046 (set_attr "predicable_short_it" "no")
6047 (set_attr "length" "4")
6048 (set_attr "type" "alu_sreg")]
6049 )
6050
6051 (define_insn "*arm_movsi_insn"
6052 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6053 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6054 "TARGET_ARM && ! TARGET_IWMMXT
6055 && !(TARGET_HARD_FLOAT && TARGET_VFP)
6056 && ( register_operand (operands[0], SImode)
6057 || register_operand (operands[1], SImode))"
6058 "@
6059 mov%?\\t%0, %1
6060 mov%?\\t%0, %1
6061 mvn%?\\t%0, #%B1
6062 movw%?\\t%0, %1
6063 ldr%?\\t%0, %1
6064 str%?\\t%1, %0"
6065 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6066 (set_attr "predicable" "yes")
6067 (set_attr "arch" "*,*,*,v6t2,*,*")
6068 (set_attr "pool_range" "*,*,*,*,4096,*")
6069 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6070 )
6071
6072 (define_split
6073 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6074 (match_operand:SI 1 "const_int_operand" ""))]
6075 "TARGET_32BIT
6076 && (!(const_ok_for_arm (INTVAL (operands[1]))
6077 || const_ok_for_arm (~INTVAL (operands[1]))))"
6078 [(clobber (const_int 0))]
6079 "
6080 arm_split_constant (SET, SImode, NULL_RTX,
6081 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6082 DONE;
6083 "
6084 )
6085
6086 ;; A normal way to do (symbol + offset) requires three instructions at least
6087 ;; (depends on how big the offset is) as below:
6088 ;; movw r0, #:lower16:g
6089 ;; movw r0, #:upper16:g
6090 ;; adds r0, #4
6091 ;;
6092 ;; A better way would be:
6093 ;; movw r0, #:lower16:g+4
6094 ;; movw r0, #:upper16:g+4
6095 ;;
6096 ;; The limitation of this way is that the length of offset should be a 16-bit
6097 ;; signed value, because current assembler only supports REL type relocation for
6098 ;; such case. If the more powerful RELA type is supported in future, we should
6099 ;; update this pattern to go with better way.
6100 (define_split
6101 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6102 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6103 (match_operand:SI 2 "const_int_operand" ""))))]
6104 "TARGET_THUMB
6105 && TARGET_HAVE_MOVT
6106 && arm_disable_literal_pool
6107 && reload_completed
6108 && GET_CODE (operands[1]) == SYMBOL_REF"
6109 [(clobber (const_int 0))]
6110 "
6111 int offset = INTVAL (operands[2]);
6112
6113 if (offset < -0x8000 || offset > 0x7fff)
6114 {
6115 arm_emit_movpair (operands[0], operands[1]);
6116 emit_insn (gen_rtx_SET (operands[0],
6117 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6118 }
6119 else
6120 {
6121 rtx op = gen_rtx_CONST (SImode,
6122 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6123 arm_emit_movpair (operands[0], op);
6124 }
6125 "
6126 )
6127
6128 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6129 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6130 ;; and lo_sum would be merged back into memory load at cprop. However,
6131 ;; if the default is to prefer movt/movw rather than a load from the constant
6132 ;; pool, the performance is better.
6133 (define_split
6134 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6135 (match_operand:SI 1 "general_operand" ""))]
6136 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6137 && !flag_pic && !target_word_relocations
6138 && !arm_tls_referenced_p (operands[1])"
6139 [(clobber (const_int 0))]
6140 {
6141 arm_emit_movpair (operands[0], operands[1]);
6142 DONE;
6143 })
6144
6145 ;; When generating pic, we need to load the symbol offset into a register.
6146 ;; So that the optimizer does not confuse this with a normal symbol load
6147 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6148 ;; since that is the only type of relocation we can use.
6149
6150 ;; Wrap calculation of the whole PIC address in a single pattern for the
6151 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6152 ;; a PIC address involves two loads from memory, so we want to CSE it
6153 ;; as often as possible.
6154 ;; This pattern will be split into one of the pic_load_addr_* patterns
6155 ;; and a move after GCSE optimizations.
6156 ;;
6157 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6158 (define_expand "calculate_pic_address"
6159 [(set (match_operand:SI 0 "register_operand" "")
6160 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6161 (unspec:SI [(match_operand:SI 2 "" "")]
6162 UNSPEC_PIC_SYM))))]
6163 "flag_pic"
6164 )
6165
6166 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6167 (define_split
6168 [(set (match_operand:SI 0 "register_operand" "")
6169 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6170 (unspec:SI [(match_operand:SI 2 "" "")]
6171 UNSPEC_PIC_SYM))))]
6172 "flag_pic"
6173 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6174 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6175 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6176 )
6177
6178 ;; operand1 is the memory address to go into
6179 ;; pic_load_addr_32bit.
6180 ;; operand2 is the PIC label to be emitted
6181 ;; from pic_add_dot_plus_eight.
6182 ;; We do this to allow hoisting of the entire insn.
6183 (define_insn_and_split "pic_load_addr_unified"
6184 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6185 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6186 (match_operand:SI 2 "" "")]
6187 UNSPEC_PIC_UNIFIED))]
6188 "flag_pic"
6189 "#"
6190 "&& reload_completed"
6191 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6192 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6193 (match_dup 2)] UNSPEC_PIC_BASE))]
6194 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6195 [(set_attr "type" "load1,load1,load1")
6196 (set_attr "pool_range" "4096,4094,1022")
6197 (set_attr "neg_pool_range" "4084,0,0")
6198 (set_attr "arch" "a,t2,t1")
6199 (set_attr "length" "8,6,4")]
6200 )
6201
6202 ;; The rather odd constraints on the following are to force reload to leave
6203 ;; the insn alone, and to force the minipool generation pass to then move
6204 ;; the GOT symbol to memory.
6205
6206 (define_insn "pic_load_addr_32bit"
6207 [(set (match_operand:SI 0 "s_register_operand" "=r")
6208 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6209 "TARGET_32BIT && flag_pic"
6210 "ldr%?\\t%0, %1"
6211 [(set_attr "type" "load1")
6212 (set (attr "pool_range")
6213 (if_then_else (eq_attr "is_thumb" "no")
6214 (const_int 4096)
6215 (const_int 4094)))
6216 (set (attr "neg_pool_range")
6217 (if_then_else (eq_attr "is_thumb" "no")
6218 (const_int 4084)
6219 (const_int 0)))]
6220 )
6221
6222 (define_insn "pic_load_addr_thumb1"
6223 [(set (match_operand:SI 0 "s_register_operand" "=l")
6224 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6225 "TARGET_THUMB1 && flag_pic"
6226 "ldr\\t%0, %1"
6227 [(set_attr "type" "load1")
6228 (set (attr "pool_range") (const_int 1018))]
6229 )
6230
6231 (define_insn "pic_add_dot_plus_four"
6232 [(set (match_operand:SI 0 "register_operand" "=r")
6233 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6234 (const_int 4)
6235 (match_operand 2 "" "")]
6236 UNSPEC_PIC_BASE))]
6237 "TARGET_THUMB"
6238 "*
6239 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6240 INTVAL (operands[2]));
6241 return \"add\\t%0, %|pc\";
6242 "
6243 [(set_attr "length" "2")
6244 (set_attr "type" "alu_sreg")]
6245 )
6246
6247 (define_insn "pic_add_dot_plus_eight"
6248 [(set (match_operand:SI 0 "register_operand" "=r")
6249 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6250 (const_int 8)
6251 (match_operand 2 "" "")]
6252 UNSPEC_PIC_BASE))]
6253 "TARGET_ARM"
6254 "*
6255 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6256 INTVAL (operands[2]));
6257 return \"add%?\\t%0, %|pc, %1\";
6258 "
6259 [(set_attr "predicable" "yes")
6260 (set_attr "type" "alu_sreg")]
6261 )
6262
6263 (define_insn "tls_load_dot_plus_eight"
6264 [(set (match_operand:SI 0 "register_operand" "=r")
6265 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6266 (const_int 8)
6267 (match_operand 2 "" "")]
6268 UNSPEC_PIC_BASE)))]
6269 "TARGET_ARM"
6270 "*
6271 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6272 INTVAL (operands[2]));
6273 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6274 "
6275 [(set_attr "predicable" "yes")
6276 (set_attr "type" "load1")]
6277 )
6278
6279 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6280 ;; followed by a load. These sequences can be crunched down to
6281 ;; tls_load_dot_plus_eight by a peephole.
6282
6283 (define_peephole2
6284 [(set (match_operand:SI 0 "register_operand" "")
6285 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6286 (const_int 8)
6287 (match_operand 1 "" "")]
6288 UNSPEC_PIC_BASE))
6289 (set (match_operand:SI 2 "arm_general_register_operand" "")
6290 (mem:SI (match_dup 0)))]
6291 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6292 [(set (match_dup 2)
6293 (mem:SI (unspec:SI [(match_dup 3)
6294 (const_int 8)
6295 (match_dup 1)]
6296 UNSPEC_PIC_BASE)))]
6297 ""
6298 )
6299
6300 (define_insn "pic_offset_arm"
6301 [(set (match_operand:SI 0 "register_operand" "=r")
6302 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6303 (unspec:SI [(match_operand:SI 2 "" "X")]
6304 UNSPEC_PIC_OFFSET))))]
6305 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6306 "ldr%?\\t%0, [%1,%2]"
6307 [(set_attr "type" "load1")]
6308 )
6309
6310 (define_expand "builtin_setjmp_receiver"
6311 [(label_ref (match_operand 0 "" ""))]
6312 "flag_pic"
6313 "
6314 {
6315 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6316 register. */
6317 if (arm_pic_register != INVALID_REGNUM)
6318 arm_load_pic_register (1UL << 3);
6319 DONE;
6320 }")
6321
6322 ;; If copying one reg to another we can set the condition codes according to
6323 ;; its value. Such a move is common after a return from subroutine and the
6324 ;; result is being tested against zero.
6325
6326 (define_insn "*movsi_compare0"
6327 [(set (reg:CC CC_REGNUM)
6328 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6329 (const_int 0)))
6330 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6331 (match_dup 1))]
6332 "TARGET_32BIT"
6333 "@
6334 cmp%?\\t%0, #0
6335 subs%?\\t%0, %1, #0"
6336 [(set_attr "conds" "set")
6337 (set_attr "type" "alus_imm,alus_imm")]
6338 )
6339
6340 ;; Subroutine to store a half word from a register into memory.
6341 ;; Operand 0 is the source register (HImode)
6342 ;; Operand 1 is the destination address in a register (SImode)
6343
6344 ;; In both this routine and the next, we must be careful not to spill
6345 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6346 ;; can generate unrecognizable rtl.
6347
6348 (define_expand "storehi"
6349 [;; store the low byte
6350 (set (match_operand 1 "" "") (match_dup 3))
6351 ;; extract the high byte
6352 (set (match_dup 2)
6353 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6354 ;; store the high byte
6355 (set (match_dup 4) (match_dup 5))]
6356 "TARGET_ARM"
6357 "
6358 {
6359 rtx op1 = operands[1];
6360 rtx addr = XEXP (op1, 0);
6361 enum rtx_code code = GET_CODE (addr);
6362
6363 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6364 || code == MINUS)
6365 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6366
6367 operands[4] = adjust_address (op1, QImode, 1);
6368 operands[1] = adjust_address (operands[1], QImode, 0);
6369 operands[3] = gen_lowpart (QImode, operands[0]);
6370 operands[0] = gen_lowpart (SImode, operands[0]);
6371 operands[2] = gen_reg_rtx (SImode);
6372 operands[5] = gen_lowpart (QImode, operands[2]);
6373 }"
6374 )
6375
6376 (define_expand "storehi_bigend"
6377 [(set (match_dup 4) (match_dup 3))
6378 (set (match_dup 2)
6379 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6380 (set (match_operand 1 "" "") (match_dup 5))]
6381 "TARGET_ARM"
6382 "
6383 {
6384 rtx op1 = operands[1];
6385 rtx addr = XEXP (op1, 0);
6386 enum rtx_code code = GET_CODE (addr);
6387
6388 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6389 || code == MINUS)
6390 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6391
6392 operands[4] = adjust_address (op1, QImode, 1);
6393 operands[1] = adjust_address (operands[1], QImode, 0);
6394 operands[3] = gen_lowpart (QImode, operands[0]);
6395 operands[0] = gen_lowpart (SImode, operands[0]);
6396 operands[2] = gen_reg_rtx (SImode);
6397 operands[5] = gen_lowpart (QImode, operands[2]);
6398 }"
6399 )
6400
6401 ;; Subroutine to store a half word integer constant into memory.
6402 (define_expand "storeinthi"
6403 [(set (match_operand 0 "" "")
6404 (match_operand 1 "" ""))
6405 (set (match_dup 3) (match_dup 2))]
6406 "TARGET_ARM"
6407 "
6408 {
6409 HOST_WIDE_INT value = INTVAL (operands[1]);
6410 rtx addr = XEXP (operands[0], 0);
6411 rtx op0 = operands[0];
6412 enum rtx_code code = GET_CODE (addr);
6413
6414 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6415 || code == MINUS)
6416 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6417
6418 operands[1] = gen_reg_rtx (SImode);
6419 if (BYTES_BIG_ENDIAN)
6420 {
6421 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6422 if ((value & 255) == ((value >> 8) & 255))
6423 operands[2] = operands[1];
6424 else
6425 {
6426 operands[2] = gen_reg_rtx (SImode);
6427 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6428 }
6429 }
6430 else
6431 {
6432 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6433 if ((value & 255) == ((value >> 8) & 255))
6434 operands[2] = operands[1];
6435 else
6436 {
6437 operands[2] = gen_reg_rtx (SImode);
6438 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6439 }
6440 }
6441
6442 operands[3] = adjust_address (op0, QImode, 1);
6443 operands[0] = adjust_address (operands[0], QImode, 0);
6444 operands[2] = gen_lowpart (QImode, operands[2]);
6445 operands[1] = gen_lowpart (QImode, operands[1]);
6446 }"
6447 )
6448
6449 (define_expand "storehi_single_op"
6450 [(set (match_operand:HI 0 "memory_operand" "")
6451 (match_operand:HI 1 "general_operand" ""))]
6452 "TARGET_32BIT && arm_arch4"
6453 "
6454 if (!s_register_operand (operands[1], HImode))
6455 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6456 "
6457 )
6458
6459 (define_expand "movhi"
6460 [(set (match_operand:HI 0 "general_operand" "")
6461 (match_operand:HI 1 "general_operand" ""))]
6462 "TARGET_EITHER"
6463 "
6464 if (TARGET_ARM)
6465 {
6466 if (can_create_pseudo_p ())
6467 {
6468 if (MEM_P (operands[0]))
6469 {
6470 if (arm_arch4)
6471 {
6472 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6473 DONE;
6474 }
6475 if (CONST_INT_P (operands[1]))
6476 emit_insn (gen_storeinthi (operands[0], operands[1]));
6477 else
6478 {
6479 if (MEM_P (operands[1]))
6480 operands[1] = force_reg (HImode, operands[1]);
6481 if (BYTES_BIG_ENDIAN)
6482 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6483 else
6484 emit_insn (gen_storehi (operands[1], operands[0]));
6485 }
6486 DONE;
6487 }
6488 /* Sign extend a constant, and keep it in an SImode reg. */
6489 else if (CONST_INT_P (operands[1]))
6490 {
6491 rtx reg = gen_reg_rtx (SImode);
6492 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6493
6494 /* If the constant is already valid, leave it alone. */
6495 if (!const_ok_for_arm (val))
6496 {
6497 /* If setting all the top bits will make the constant
6498 loadable in a single instruction, then set them.
6499 Otherwise, sign extend the number. */
6500
6501 if (const_ok_for_arm (~(val | ~0xffff)))
6502 val |= ~0xffff;
6503 else if (val & 0x8000)
6504 val |= ~0xffff;
6505 }
6506
6507 emit_insn (gen_movsi (reg, GEN_INT (val)));
6508 operands[1] = gen_lowpart (HImode, reg);
6509 }
6510 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6511 && MEM_P (operands[1]))
6512 {
6513 rtx reg = gen_reg_rtx (SImode);
6514
6515 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6516 operands[1] = gen_lowpart (HImode, reg);
6517 }
6518 else if (!arm_arch4)
6519 {
6520 if (MEM_P (operands[1]))
6521 {
6522 rtx base;
6523 rtx offset = const0_rtx;
6524 rtx reg = gen_reg_rtx (SImode);
6525
6526 if ((REG_P (base = XEXP (operands[1], 0))
6527 || (GET_CODE (base) == PLUS
6528 && (CONST_INT_P (offset = XEXP (base, 1)))
6529 && ((INTVAL(offset) & 1) != 1)
6530 && REG_P (base = XEXP (base, 0))))
6531 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6532 {
6533 rtx new_rtx;
6534
6535 new_rtx = widen_memory_access (operands[1], SImode,
6536 ((INTVAL (offset) & ~3)
6537 - INTVAL (offset)));
6538 emit_insn (gen_movsi (reg, new_rtx));
6539 if (((INTVAL (offset) & 2) != 0)
6540 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6541 {
6542 rtx reg2 = gen_reg_rtx (SImode);
6543
6544 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6545 reg = reg2;
6546 }
6547 }
6548 else
6549 emit_insn (gen_movhi_bytes (reg, operands[1]));
6550
6551 operands[1] = gen_lowpart (HImode, reg);
6552 }
6553 }
6554 }
6555 /* Handle loading a large integer during reload. */
6556 else if (CONST_INT_P (operands[1])
6557 && !const_ok_for_arm (INTVAL (operands[1]))
6558 && !const_ok_for_arm (~INTVAL (operands[1])))
6559 {
6560 /* Writing a constant to memory needs a scratch, which should
6561 be handled with SECONDARY_RELOADs. */
6562 gcc_assert (REG_P (operands[0]));
6563
6564 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6565 emit_insn (gen_movsi (operands[0], operands[1]));
6566 DONE;
6567 }
6568 }
6569 else if (TARGET_THUMB2)
6570 {
6571 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6572 if (can_create_pseudo_p ())
6573 {
6574 if (!REG_P (operands[0]))
6575 operands[1] = force_reg (HImode, operands[1]);
6576 /* Zero extend a constant, and keep it in an SImode reg. */
6577 else if (CONST_INT_P (operands[1]))
6578 {
6579 rtx reg = gen_reg_rtx (SImode);
6580 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6581
6582 emit_insn (gen_movsi (reg, GEN_INT (val)));
6583 operands[1] = gen_lowpart (HImode, reg);
6584 }
6585 }
6586 }
6587 else /* TARGET_THUMB1 */
6588 {
6589 if (can_create_pseudo_p ())
6590 {
6591 if (CONST_INT_P (operands[1]))
6592 {
6593 rtx reg = gen_reg_rtx (SImode);
6594
6595 emit_insn (gen_movsi (reg, operands[1]));
6596 operands[1] = gen_lowpart (HImode, reg);
6597 }
6598
6599 /* ??? We shouldn't really get invalid addresses here, but this can
6600 happen if we are passed a SP (never OK for HImode/QImode) or
6601 virtual register (also rejected as illegitimate for HImode/QImode)
6602 relative address. */
6603 /* ??? This should perhaps be fixed elsewhere, for instance, in
6604 fixup_stack_1, by checking for other kinds of invalid addresses,
6605 e.g. a bare reference to a virtual register. This may confuse the
6606 alpha though, which must handle this case differently. */
6607 if (MEM_P (operands[0])
6608 && !memory_address_p (GET_MODE (operands[0]),
6609 XEXP (operands[0], 0)))
6610 operands[0]
6611 = replace_equiv_address (operands[0],
6612 copy_to_reg (XEXP (operands[0], 0)));
6613
6614 if (MEM_P (operands[1])
6615 && !memory_address_p (GET_MODE (operands[1]),
6616 XEXP (operands[1], 0)))
6617 operands[1]
6618 = replace_equiv_address (operands[1],
6619 copy_to_reg (XEXP (operands[1], 0)));
6620
6621 if (MEM_P (operands[1]) && optimize > 0)
6622 {
6623 rtx reg = gen_reg_rtx (SImode);
6624
6625 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6626 operands[1] = gen_lowpart (HImode, reg);
6627 }
6628
6629 if (MEM_P (operands[0]))
6630 operands[1] = force_reg (HImode, operands[1]);
6631 }
6632 else if (CONST_INT_P (operands[1])
6633 && !satisfies_constraint_I (operands[1]))
6634 {
6635 /* Handle loading a large integer during reload. */
6636
6637 /* Writing a constant to memory needs a scratch, which should
6638 be handled with SECONDARY_RELOADs. */
6639 gcc_assert (REG_P (operands[0]));
6640
6641 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6642 emit_insn (gen_movsi (operands[0], operands[1]));
6643 DONE;
6644 }
6645 }
6646 "
6647 )
6648
6649 (define_expand "movhi_bytes"
6650 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6651 (set (match_dup 3)
6652 (zero_extend:SI (match_dup 6)))
6653 (set (match_operand:SI 0 "" "")
6654 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6655 "TARGET_ARM"
6656 "
6657 {
6658 rtx mem1, mem2;
6659 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6660
6661 mem1 = change_address (operands[1], QImode, addr);
6662 mem2 = change_address (operands[1], QImode,
6663 plus_constant (Pmode, addr, 1));
6664 operands[0] = gen_lowpart (SImode, operands[0]);
6665 operands[1] = mem1;
6666 operands[2] = gen_reg_rtx (SImode);
6667 operands[3] = gen_reg_rtx (SImode);
6668 operands[6] = mem2;
6669
6670 if (BYTES_BIG_ENDIAN)
6671 {
6672 operands[4] = operands[2];
6673 operands[5] = operands[3];
6674 }
6675 else
6676 {
6677 operands[4] = operands[3];
6678 operands[5] = operands[2];
6679 }
6680 }"
6681 )
6682
6683 (define_expand "movhi_bigend"
6684 [(set (match_dup 2)
6685 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6686 (const_int 16)))
6687 (set (match_dup 3)
6688 (ashiftrt:SI (match_dup 2) (const_int 16)))
6689 (set (match_operand:HI 0 "s_register_operand" "")
6690 (match_dup 4))]
6691 "TARGET_ARM"
6692 "
6693 operands[2] = gen_reg_rtx (SImode);
6694 operands[3] = gen_reg_rtx (SImode);
6695 operands[4] = gen_lowpart (HImode, operands[3]);
6696 "
6697 )
6698
6699 ;; Pattern to recognize insn generated default case above
6700 (define_insn "*movhi_insn_arch4"
6701 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6702 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6703 "TARGET_ARM
6704 && arm_arch4 && !(TARGET_HARD_FLOAT && TARGET_VFP)
6705 && (register_operand (operands[0], HImode)
6706 || register_operand (operands[1], HImode))"
6707 "@
6708 mov%?\\t%0, %1\\t%@ movhi
6709 mvn%?\\t%0, #%B1\\t%@ movhi
6710 movw%?\\t%0, %L1\\t%@ movhi
6711 strh%?\\t%1, %0\\t%@ movhi
6712 ldrh%?\\t%0, %1\\t%@ movhi"
6713 [(set_attr "predicable" "yes")
6714 (set_attr "pool_range" "*,*,*,*,256")
6715 (set_attr "neg_pool_range" "*,*,*,*,244")
6716 (set_attr "arch" "*,*,v6t2,*,*")
6717 (set_attr_alternative "type"
6718 [(if_then_else (match_operand 1 "const_int_operand" "")
6719 (const_string "mov_imm" )
6720 (const_string "mov_reg"))
6721 (const_string "mvn_imm")
6722 (const_string "mov_imm")
6723 (const_string "store1")
6724 (const_string "load1")])]
6725 )
6726
6727 (define_insn "*movhi_bytes"
6728 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6729 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6730 "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_VFP)"
6731 "@
6732 mov%?\\t%0, %1\\t%@ movhi
6733 mov%?\\t%0, %1\\t%@ movhi
6734 mvn%?\\t%0, #%B1\\t%@ movhi"
6735 [(set_attr "predicable" "yes")
6736 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6737 )
6738
6739 ;; We use a DImode scratch because we may occasionally need an additional
6740 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6741 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6742 (define_expand "reload_outhi"
6743 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6744 (match_operand:HI 1 "s_register_operand" "r")
6745 (match_operand:DI 2 "s_register_operand" "=&l")])]
6746 "TARGET_EITHER"
6747 "if (TARGET_ARM)
6748 arm_reload_out_hi (operands);
6749 else
6750 thumb_reload_out_hi (operands);
6751 DONE;
6752 "
6753 )
6754
6755 (define_expand "reload_inhi"
6756 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6757 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6758 (match_operand:DI 2 "s_register_operand" "=&r")])]
6759 "TARGET_EITHER"
6760 "
6761 if (TARGET_ARM)
6762 arm_reload_in_hi (operands);
6763 else
6764 thumb_reload_out_hi (operands);
6765 DONE;
6766 ")
6767
6768 (define_expand "movqi"
6769 [(set (match_operand:QI 0 "general_operand" "")
6770 (match_operand:QI 1 "general_operand" ""))]
6771 "TARGET_EITHER"
6772 "
6773 /* Everything except mem = const or mem = mem can be done easily */
6774
6775 if (can_create_pseudo_p ())
6776 {
6777 if (CONST_INT_P (operands[1]))
6778 {
6779 rtx reg = gen_reg_rtx (SImode);
6780
6781 /* For thumb we want an unsigned immediate, then we are more likely
6782 to be able to use a movs insn. */
6783 if (TARGET_THUMB)
6784 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6785
6786 emit_insn (gen_movsi (reg, operands[1]));
6787 operands[1] = gen_lowpart (QImode, reg);
6788 }
6789
6790 if (TARGET_THUMB)
6791 {
6792 /* ??? We shouldn't really get invalid addresses here, but this can
6793 happen if we are passed a SP (never OK for HImode/QImode) or
6794 virtual register (also rejected as illegitimate for HImode/QImode)
6795 relative address. */
6796 /* ??? This should perhaps be fixed elsewhere, for instance, in
6797 fixup_stack_1, by checking for other kinds of invalid addresses,
6798 e.g. a bare reference to a virtual register. This may confuse the
6799 alpha though, which must handle this case differently. */
6800 if (MEM_P (operands[0])
6801 && !memory_address_p (GET_MODE (operands[0]),
6802 XEXP (operands[0], 0)))
6803 operands[0]
6804 = replace_equiv_address (operands[0],
6805 copy_to_reg (XEXP (operands[0], 0)));
6806 if (MEM_P (operands[1])
6807 && !memory_address_p (GET_MODE (operands[1]),
6808 XEXP (operands[1], 0)))
6809 operands[1]
6810 = replace_equiv_address (operands[1],
6811 copy_to_reg (XEXP (operands[1], 0)));
6812 }
6813
6814 if (MEM_P (operands[1]) && optimize > 0)
6815 {
6816 rtx reg = gen_reg_rtx (SImode);
6817
6818 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6819 operands[1] = gen_lowpart (QImode, reg);
6820 }
6821
6822 if (MEM_P (operands[0]))
6823 operands[1] = force_reg (QImode, operands[1]);
6824 }
6825 else if (TARGET_THUMB
6826 && CONST_INT_P (operands[1])
6827 && !satisfies_constraint_I (operands[1]))
6828 {
6829 /* Handle loading a large integer during reload. */
6830
6831 /* Writing a constant to memory needs a scratch, which should
6832 be handled with SECONDARY_RELOADs. */
6833 gcc_assert (REG_P (operands[0]));
6834
6835 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6836 emit_insn (gen_movsi (operands[0], operands[1]));
6837 DONE;
6838 }
6839 "
6840 )
6841
6842 (define_insn "*arm_movqi_insn"
6843 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6844 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6845 "TARGET_32BIT
6846 && ( register_operand (operands[0], QImode)
6847 || register_operand (operands[1], QImode))"
6848 "@
6849 mov%?\\t%0, %1
6850 mov%?\\t%0, %1
6851 mov%?\\t%0, %1
6852 mov%?\\t%0, %1
6853 mvn%?\\t%0, #%B1
6854 ldrb%?\\t%0, %1
6855 strb%?\\t%1, %0
6856 ldrb%?\\t%0, %1
6857 strb%?\\t%1, %0"
6858 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6859 (set_attr "predicable" "yes")
6860 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6861 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6862 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6863 )
6864
6865 ;; HFmode moves
6866 (define_expand "movhf"
6867 [(set (match_operand:HF 0 "general_operand" "")
6868 (match_operand:HF 1 "general_operand" ""))]
6869 "TARGET_EITHER"
6870 "
6871 if (TARGET_32BIT)
6872 {
6873 if (MEM_P (operands[0]))
6874 operands[1] = force_reg (HFmode, operands[1]);
6875 }
6876 else /* TARGET_THUMB1 */
6877 {
6878 if (can_create_pseudo_p ())
6879 {
6880 if (!REG_P (operands[0]))
6881 operands[1] = force_reg (HFmode, operands[1]);
6882 }
6883 }
6884 "
6885 )
6886
6887 (define_insn "*arm32_movhf"
6888 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6889 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6890 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_VFP)
6891 && ( s_register_operand (operands[0], HFmode)
6892 || s_register_operand (operands[1], HFmode))"
6893 "*
6894 switch (which_alternative)
6895 {
6896 case 0: /* ARM register from memory */
6897 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6898 case 1: /* memory from ARM register */
6899 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6900 case 2: /* ARM register from ARM register */
6901 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6902 case 3: /* ARM register from constant */
6903 {
6904 long bits;
6905 rtx ops[4];
6906
6907 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6908 HFmode);
6909 ops[0] = operands[0];
6910 ops[1] = GEN_INT (bits);
6911 ops[2] = GEN_INT (bits & 0xff00);
6912 ops[3] = GEN_INT (bits & 0x00ff);
6913
6914 if (arm_arch_thumb2)
6915 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6916 else
6917 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6918 return \"\";
6919 }
6920 default:
6921 gcc_unreachable ();
6922 }
6923 "
6924 [(set_attr "conds" "unconditional")
6925 (set_attr "type" "load1,store1,mov_reg,multiple")
6926 (set_attr "length" "4,4,4,8")
6927 (set_attr "predicable" "yes")
6928 (set_attr "predicable_short_it" "no")]
6929 )
6930
6931 (define_expand "movsf"
6932 [(set (match_operand:SF 0 "general_operand" "")
6933 (match_operand:SF 1 "general_operand" ""))]
6934 "TARGET_EITHER"
6935 "
6936 if (TARGET_32BIT)
6937 {
6938 if (MEM_P (operands[0]))
6939 operands[1] = force_reg (SFmode, operands[1]);
6940 }
6941 else /* TARGET_THUMB1 */
6942 {
6943 if (can_create_pseudo_p ())
6944 {
6945 if (!REG_P (operands[0]))
6946 operands[1] = force_reg (SFmode, operands[1]);
6947 }
6948 }
6949 "
6950 )
6951
6952 ;; Transform a floating-point move of a constant into a core register into
6953 ;; an SImode operation.
6954 (define_split
6955 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6956 (match_operand:SF 1 "immediate_operand" ""))]
6957 "TARGET_EITHER
6958 && reload_completed
6959 && CONST_DOUBLE_P (operands[1])"
6960 [(set (match_dup 2) (match_dup 3))]
6961 "
6962 operands[2] = gen_lowpart (SImode, operands[0]);
6963 operands[3] = gen_lowpart (SImode, operands[1]);
6964 if (operands[2] == 0 || operands[3] == 0)
6965 FAIL;
6966 "
6967 )
6968
6969 (define_insn "*arm_movsf_soft_insn"
6970 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6971 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6972 "TARGET_32BIT
6973 && TARGET_SOFT_FLOAT
6974 && (!MEM_P (operands[0])
6975 || register_operand (operands[1], SFmode))"
6976 "@
6977 mov%?\\t%0, %1
6978 ldr%?\\t%0, %1\\t%@ float
6979 str%?\\t%1, %0\\t%@ float"
6980 [(set_attr "predicable" "yes")
6981 (set_attr "predicable_short_it" "no")
6982 (set_attr "type" "mov_reg,load1,store1")
6983 (set_attr "arm_pool_range" "*,4096,*")
6984 (set_attr "thumb2_pool_range" "*,4094,*")
6985 (set_attr "arm_neg_pool_range" "*,4084,*")
6986 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6987 )
6988
6989 (define_expand "movdf"
6990 [(set (match_operand:DF 0 "general_operand" "")
6991 (match_operand:DF 1 "general_operand" ""))]
6992 "TARGET_EITHER"
6993 "
6994 if (TARGET_32BIT)
6995 {
6996 if (MEM_P (operands[0]))
6997 operands[1] = force_reg (DFmode, operands[1]);
6998 }
6999 else /* TARGET_THUMB */
7000 {
7001 if (can_create_pseudo_p ())
7002 {
7003 if (!REG_P (operands[0]))
7004 operands[1] = force_reg (DFmode, operands[1]);
7005 }
7006 }
7007 "
7008 )
7009
7010 ;; Reloading a df mode value stored in integer regs to memory can require a
7011 ;; scratch reg.
7012 (define_expand "reload_outdf"
7013 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7014 (match_operand:DF 1 "s_register_operand" "r")
7015 (match_operand:SI 2 "s_register_operand" "=&r")]
7016 "TARGET_THUMB2"
7017 "
7018 {
7019 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7020
7021 if (code == REG)
7022 operands[2] = XEXP (operands[0], 0);
7023 else if (code == POST_INC || code == PRE_DEC)
7024 {
7025 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7026 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7027 emit_insn (gen_movdi (operands[0], operands[1]));
7028 DONE;
7029 }
7030 else if (code == PRE_INC)
7031 {
7032 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7033
7034 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7035 operands[2] = reg;
7036 }
7037 else if (code == POST_DEC)
7038 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7039 else
7040 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7041 XEXP (XEXP (operands[0], 0), 1)));
7042
7043 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7044 operands[1]));
7045
7046 if (code == POST_DEC)
7047 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7048
7049 DONE;
7050 }"
7051 )
7052
7053 (define_insn "*movdf_soft_insn"
7054 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7055 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7056 "TARGET_32BIT && TARGET_SOFT_FLOAT
7057 && ( register_operand (operands[0], DFmode)
7058 || register_operand (operands[1], DFmode))"
7059 "*
7060 switch (which_alternative)
7061 {
7062 case 0:
7063 case 1:
7064 case 2:
7065 return \"#\";
7066 default:
7067 return output_move_double (operands, true, NULL);
7068 }
7069 "
7070 [(set_attr "length" "8,12,16,8,8")
7071 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7072 (set_attr "arm_pool_range" "*,*,*,1020,*")
7073 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7074 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7075 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7076 )
7077 \f
7078
7079 ;; load- and store-multiple insns
7080 ;; The arm can load/store any set of registers, provided that they are in
7081 ;; ascending order, but these expanders assume a contiguous set.
7082
7083 (define_expand "load_multiple"
7084 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7085 (match_operand:SI 1 "" ""))
7086 (use (match_operand:SI 2 "" ""))])]
7087 "TARGET_32BIT"
7088 {
7089 HOST_WIDE_INT offset = 0;
7090
7091 /* Support only fixed point registers. */
7092 if (!CONST_INT_P (operands[2])
7093 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7094 || INTVAL (operands[2]) < 2
7095 || !MEM_P (operands[1])
7096 || !REG_P (operands[0])
7097 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7098 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7099 FAIL;
7100
7101 operands[3]
7102 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7103 INTVAL (operands[2]),
7104 force_reg (SImode, XEXP (operands[1], 0)),
7105 FALSE, operands[1], &offset);
7106 })
7107
7108 (define_expand "store_multiple"
7109 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7110 (match_operand:SI 1 "" ""))
7111 (use (match_operand:SI 2 "" ""))])]
7112 "TARGET_32BIT"
7113 {
7114 HOST_WIDE_INT offset = 0;
7115
7116 /* Support only fixed point registers. */
7117 if (!CONST_INT_P (operands[2])
7118 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7119 || INTVAL (operands[2]) < 2
7120 || !REG_P (operands[1])
7121 || !MEM_P (operands[0])
7122 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7123 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7124 FAIL;
7125
7126 operands[3]
7127 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7128 INTVAL (operands[2]),
7129 force_reg (SImode, XEXP (operands[0], 0)),
7130 FALSE, operands[0], &offset);
7131 })
7132
7133
7134 (define_expand "setmemsi"
7135 [(match_operand:BLK 0 "general_operand" "")
7136 (match_operand:SI 1 "const_int_operand" "")
7137 (match_operand:SI 2 "const_int_operand" "")
7138 (match_operand:SI 3 "const_int_operand" "")]
7139 "TARGET_32BIT"
7140 {
7141 if (arm_gen_setmem (operands))
7142 DONE;
7143
7144 FAIL;
7145 })
7146
7147
7148 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7149 ;; We could let this apply for blocks of less than this, but it clobbers so
7150 ;; many registers that there is then probably a better way.
7151
7152 (define_expand "movmemqi"
7153 [(match_operand:BLK 0 "general_operand" "")
7154 (match_operand:BLK 1 "general_operand" "")
7155 (match_operand:SI 2 "const_int_operand" "")
7156 (match_operand:SI 3 "const_int_operand" "")]
7157 ""
7158 "
7159 if (TARGET_32BIT)
7160 {
7161 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7162 && !optimize_function_for_size_p (cfun))
7163 {
7164 if (gen_movmem_ldrd_strd (operands))
7165 DONE;
7166 FAIL;
7167 }
7168
7169 if (arm_gen_movmemqi (operands))
7170 DONE;
7171 FAIL;
7172 }
7173 else /* TARGET_THUMB1 */
7174 {
7175 if ( INTVAL (operands[3]) != 4
7176 || INTVAL (operands[2]) > 48)
7177 FAIL;
7178
7179 thumb_expand_movmemqi (operands);
7180 DONE;
7181 }
7182 "
7183 )
7184 \f
7185
7186 ;; Compare & branch insns
7187 ;; The range calculations are based as follows:
7188 ;; For forward branches, the address calculation returns the address of
7189 ;; the next instruction. This is 2 beyond the branch instruction.
7190 ;; For backward branches, the address calculation returns the address of
7191 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7192 ;; instruction for the shortest sequence, and 4 before the branch instruction
7193 ;; if we have to jump around an unconditional branch.
7194 ;; To the basic branch range the PC offset must be added (this is +4).
7195 ;; So for forward branches we have
7196 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7197 ;; And for backward branches we have
7198 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7199 ;;
7200 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7201 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7202
7203 (define_expand "cbranchsi4"
7204 [(set (pc) (if_then_else
7205 (match_operator 0 "expandable_comparison_operator"
7206 [(match_operand:SI 1 "s_register_operand" "")
7207 (match_operand:SI 2 "nonmemory_operand" "")])
7208 (label_ref (match_operand 3 "" ""))
7209 (pc)))]
7210 "TARGET_EITHER"
7211 "
7212 if (!TARGET_THUMB1)
7213 {
7214 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7215 FAIL;
7216 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7217 operands[3]));
7218 DONE;
7219 }
7220 if (thumb1_cmpneg_operand (operands[2], SImode))
7221 {
7222 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7223 operands[3], operands[0]));
7224 DONE;
7225 }
7226 if (!thumb1_cmp_operand (operands[2], SImode))
7227 operands[2] = force_reg (SImode, operands[2]);
7228 ")
7229
7230 (define_expand "cbranchsf4"
7231 [(set (pc) (if_then_else
7232 (match_operator 0 "expandable_comparison_operator"
7233 [(match_operand:SF 1 "s_register_operand" "")
7234 (match_operand:SF 2 "arm_float_compare_operand" "")])
7235 (label_ref (match_operand 3 "" ""))
7236 (pc)))]
7237 "TARGET_32BIT && TARGET_HARD_FLOAT"
7238 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7239 operands[3])); DONE;"
7240 )
7241
7242 (define_expand "cbranchdf4"
7243 [(set (pc) (if_then_else
7244 (match_operator 0 "expandable_comparison_operator"
7245 [(match_operand:DF 1 "s_register_operand" "")
7246 (match_operand:DF 2 "arm_float_compare_operand" "")])
7247 (label_ref (match_operand 3 "" ""))
7248 (pc)))]
7249 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7250 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7251 operands[3])); DONE;"
7252 )
7253
7254 (define_expand "cbranchdi4"
7255 [(set (pc) (if_then_else
7256 (match_operator 0 "expandable_comparison_operator"
7257 [(match_operand:DI 1 "s_register_operand" "")
7258 (match_operand:DI 2 "cmpdi_operand" "")])
7259 (label_ref (match_operand 3 "" ""))
7260 (pc)))]
7261 "TARGET_32BIT"
7262 "{
7263 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7264 FAIL;
7265 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7266 operands[3]));
7267 DONE;
7268 }"
7269 )
7270
7271 ;; Comparison and test insns
7272
7273 (define_insn "*arm_cmpsi_insn"
7274 [(set (reg:CC CC_REGNUM)
7275 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7276 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7277 "TARGET_32BIT"
7278 "@
7279 cmp%?\\t%0, %1
7280 cmp%?\\t%0, %1
7281 cmp%?\\t%0, %1
7282 cmp%?\\t%0, %1
7283 cmn%?\\t%0, #%n1"
7284 [(set_attr "conds" "set")
7285 (set_attr "arch" "t2,t2,any,any,any")
7286 (set_attr "length" "2,2,4,4,4")
7287 (set_attr "predicable" "yes")
7288 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7289 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7290 )
7291
7292 (define_insn "*cmpsi_shiftsi"
7293 [(set (reg:CC CC_REGNUM)
7294 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7295 (match_operator:SI 3 "shift_operator"
7296 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7297 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7298 "TARGET_32BIT"
7299 "cmp\\t%0, %1%S3"
7300 [(set_attr "conds" "set")
7301 (set_attr "shift" "1")
7302 (set_attr "arch" "32,a,a")
7303 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7304
7305 (define_insn "*cmpsi_shiftsi_swp"
7306 [(set (reg:CC_SWP CC_REGNUM)
7307 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7308 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7309 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7310 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7311 "TARGET_32BIT"
7312 "cmp%?\\t%0, %1%S3"
7313 [(set_attr "conds" "set")
7314 (set_attr "shift" "1")
7315 (set_attr "arch" "32,a,a")
7316 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7317
7318 (define_insn "*arm_cmpsi_negshiftsi_si"
7319 [(set (reg:CC_Z CC_REGNUM)
7320 (compare:CC_Z
7321 (neg:SI (match_operator:SI 1 "shift_operator"
7322 [(match_operand:SI 2 "s_register_operand" "r")
7323 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7324 (match_operand:SI 0 "s_register_operand" "r")))]
7325 "TARGET_ARM"
7326 "cmn%?\\t%0, %2%S1"
7327 [(set_attr "conds" "set")
7328 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7329 (const_string "alus_shift_imm")
7330 (const_string "alus_shift_reg")))
7331 (set_attr "predicable" "yes")]
7332 )
7333
7334 ;; DImode comparisons. The generic code generates branches that
7335 ;; if-conversion can not reduce to a conditional compare, so we do
7336 ;; that directly.
7337
7338 (define_insn_and_split "*arm_cmpdi_insn"
7339 [(set (reg:CC_NCV CC_REGNUM)
7340 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7341 (match_operand:DI 1 "arm_di_operand" "rDi")))
7342 (clobber (match_scratch:SI 2 "=r"))]
7343 "TARGET_32BIT"
7344 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7345 "&& reload_completed"
7346 [(set (reg:CC CC_REGNUM)
7347 (compare:CC (match_dup 0) (match_dup 1)))
7348 (parallel [(set (reg:CC CC_REGNUM)
7349 (compare:CC (match_dup 3) (match_dup 4)))
7350 (set (match_dup 2)
7351 (minus:SI (match_dup 5)
7352 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7353 {
7354 operands[3] = gen_highpart (SImode, operands[0]);
7355 operands[0] = gen_lowpart (SImode, operands[0]);
7356 if (CONST_INT_P (operands[1]))
7357 {
7358 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7359 DImode,
7360 operands[1])));
7361 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7362 }
7363 else
7364 {
7365 operands[4] = gen_highpart (SImode, operands[1]);
7366 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7367 }
7368 operands[1] = gen_lowpart (SImode, operands[1]);
7369 operands[2] = gen_lowpart (SImode, operands[2]);
7370 }
7371 [(set_attr "conds" "set")
7372 (set_attr "length" "8")
7373 (set_attr "type" "multiple")]
7374 )
7375
7376 (define_insn_and_split "*arm_cmpdi_unsigned"
7377 [(set (reg:CC_CZ CC_REGNUM)
7378 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7379 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7380
7381 "TARGET_32BIT"
7382 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7383 "&& reload_completed"
7384 [(set (reg:CC CC_REGNUM)
7385 (compare:CC (match_dup 2) (match_dup 3)))
7386 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7387 (set (reg:CC CC_REGNUM)
7388 (compare:CC (match_dup 0) (match_dup 1))))]
7389 {
7390 operands[2] = gen_highpart (SImode, operands[0]);
7391 operands[0] = gen_lowpart (SImode, operands[0]);
7392 if (CONST_INT_P (operands[1]))
7393 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7394 else
7395 operands[3] = gen_highpart (SImode, operands[1]);
7396 operands[1] = gen_lowpart (SImode, operands[1]);
7397 }
7398 [(set_attr "conds" "set")
7399 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7400 (set_attr "arch" "t2,t2,t2,a")
7401 (set_attr "length" "6,6,10,8")
7402 (set_attr "type" "multiple")]
7403 )
7404
7405 (define_insn "*arm_cmpdi_zero"
7406 [(set (reg:CC_Z CC_REGNUM)
7407 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7408 (const_int 0)))
7409 (clobber (match_scratch:SI 1 "=r"))]
7410 "TARGET_32BIT"
7411 "orrs%?\\t%1, %Q0, %R0"
7412 [(set_attr "conds" "set")
7413 (set_attr "type" "logics_reg")]
7414 )
7415
7416 ; This insn allows redundant compares to be removed by cse, nothing should
7417 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7418 ; is deleted later on. The match_dup will match the mode here, so that
7419 ; mode changes of the condition codes aren't lost by this even though we don't
7420 ; specify what they are.
7421
7422 (define_insn "*deleted_compare"
7423 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7424 "TARGET_32BIT"
7425 "\\t%@ deleted compare"
7426 [(set_attr "conds" "set")
7427 (set_attr "length" "0")
7428 (set_attr "type" "no_insn")]
7429 )
7430
7431 \f
7432 ;; Conditional branch insns
7433
7434 (define_expand "cbranch_cc"
7435 [(set (pc)
7436 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7437 (match_operand 2 "" "")])
7438 (label_ref (match_operand 3 "" ""))
7439 (pc)))]
7440 "TARGET_32BIT"
7441 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7442 operands[1], operands[2], NULL_RTX);
7443 operands[2] = const0_rtx;"
7444 )
7445
7446 ;;
7447 ;; Patterns to match conditional branch insns.
7448 ;;
7449
7450 (define_insn "arm_cond_branch"
7451 [(set (pc)
7452 (if_then_else (match_operator 1 "arm_comparison_operator"
7453 [(match_operand 2 "cc_register" "") (const_int 0)])
7454 (label_ref (match_operand 0 "" ""))
7455 (pc)))]
7456 "TARGET_32BIT"
7457 "*
7458 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7459 {
7460 arm_ccfsm_state += 2;
7461 return \"\";
7462 }
7463 return \"b%d1\\t%l0\";
7464 "
7465 [(set_attr "conds" "use")
7466 (set_attr "type" "branch")
7467 (set (attr "length")
7468 (if_then_else
7469 (and (match_test "TARGET_THUMB2")
7470 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7471 (le (minus (match_dup 0) (pc)) (const_int 256))))
7472 (const_int 2)
7473 (const_int 4)))]
7474 )
7475
7476 (define_insn "*arm_cond_branch_reversed"
7477 [(set (pc)
7478 (if_then_else (match_operator 1 "arm_comparison_operator"
7479 [(match_operand 2 "cc_register" "") (const_int 0)])
7480 (pc)
7481 (label_ref (match_operand 0 "" ""))))]
7482 "TARGET_32BIT"
7483 "*
7484 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7485 {
7486 arm_ccfsm_state += 2;
7487 return \"\";
7488 }
7489 return \"b%D1\\t%l0\";
7490 "
7491 [(set_attr "conds" "use")
7492 (set_attr "type" "branch")
7493 (set (attr "length")
7494 (if_then_else
7495 (and (match_test "TARGET_THUMB2")
7496 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7497 (le (minus (match_dup 0) (pc)) (const_int 256))))
7498 (const_int 2)
7499 (const_int 4)))]
7500 )
7501
7502 \f
7503
7504 ; scc insns
7505
7506 (define_expand "cstore_cc"
7507 [(set (match_operand:SI 0 "s_register_operand" "")
7508 (match_operator:SI 1 "" [(match_operand 2 "" "")
7509 (match_operand 3 "" "")]))]
7510 "TARGET_32BIT"
7511 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7512 operands[2], operands[3], NULL_RTX);
7513 operands[3] = const0_rtx;"
7514 )
7515
7516 (define_insn_and_split "*mov_scc"
7517 [(set (match_operand:SI 0 "s_register_operand" "=r")
7518 (match_operator:SI 1 "arm_comparison_operator_mode"
7519 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7520 "TARGET_ARM"
7521 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7522 "TARGET_ARM"
7523 [(set (match_dup 0)
7524 (if_then_else:SI (match_dup 1)
7525 (const_int 1)
7526 (const_int 0)))]
7527 ""
7528 [(set_attr "conds" "use")
7529 (set_attr "length" "8")
7530 (set_attr "type" "multiple")]
7531 )
7532
7533 (define_insn_and_split "*mov_negscc"
7534 [(set (match_operand:SI 0 "s_register_operand" "=r")
7535 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7536 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7537 "TARGET_ARM"
7538 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7539 "TARGET_ARM"
7540 [(set (match_dup 0)
7541 (if_then_else:SI (match_dup 1)
7542 (match_dup 3)
7543 (const_int 0)))]
7544 {
7545 operands[3] = GEN_INT (~0);
7546 }
7547 [(set_attr "conds" "use")
7548 (set_attr "length" "8")
7549 (set_attr "type" "multiple")]
7550 )
7551
7552 (define_insn_and_split "*mov_notscc"
7553 [(set (match_operand:SI 0 "s_register_operand" "=r")
7554 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7555 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7556 "TARGET_ARM"
7557 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7558 "TARGET_ARM"
7559 [(set (match_dup 0)
7560 (if_then_else:SI (match_dup 1)
7561 (match_dup 3)
7562 (match_dup 4)))]
7563 {
7564 operands[3] = GEN_INT (~1);
7565 operands[4] = GEN_INT (~0);
7566 }
7567 [(set_attr "conds" "use")
7568 (set_attr "length" "8")
7569 (set_attr "type" "multiple")]
7570 )
7571
7572 (define_expand "cstoresi4"
7573 [(set (match_operand:SI 0 "s_register_operand" "")
7574 (match_operator:SI 1 "expandable_comparison_operator"
7575 [(match_operand:SI 2 "s_register_operand" "")
7576 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7577 "TARGET_32BIT || TARGET_THUMB1"
7578 "{
7579 rtx op3, scratch, scratch2;
7580
7581 if (!TARGET_THUMB1)
7582 {
7583 if (!arm_add_operand (operands[3], SImode))
7584 operands[3] = force_reg (SImode, operands[3]);
7585 emit_insn (gen_cstore_cc (operands[0], operands[1],
7586 operands[2], operands[3]));
7587 DONE;
7588 }
7589
7590 if (operands[3] == const0_rtx)
7591 {
7592 switch (GET_CODE (operands[1]))
7593 {
7594 case EQ:
7595 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7596 break;
7597
7598 case NE:
7599 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7600 break;
7601
7602 case LE:
7603 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7604 NULL_RTX, 0, OPTAB_WIDEN);
7605 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7606 NULL_RTX, 0, OPTAB_WIDEN);
7607 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7608 operands[0], 1, OPTAB_WIDEN);
7609 break;
7610
7611 case GE:
7612 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7613 NULL_RTX, 1);
7614 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7615 NULL_RTX, 1, OPTAB_WIDEN);
7616 break;
7617
7618 case GT:
7619 scratch = expand_binop (SImode, ashr_optab, operands[2],
7620 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7621 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7622 NULL_RTX, 0, OPTAB_WIDEN);
7623 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7624 0, OPTAB_WIDEN);
7625 break;
7626
7627 /* LT is handled by generic code. No need for unsigned with 0. */
7628 default:
7629 FAIL;
7630 }
7631 DONE;
7632 }
7633
7634 switch (GET_CODE (operands[1]))
7635 {
7636 case EQ:
7637 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7638 NULL_RTX, 0, OPTAB_WIDEN);
7639 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7640 break;
7641
7642 case NE:
7643 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7644 NULL_RTX, 0, OPTAB_WIDEN);
7645 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7646 break;
7647
7648 case LE:
7649 op3 = force_reg (SImode, operands[3]);
7650
7651 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7652 NULL_RTX, 1, OPTAB_WIDEN);
7653 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7654 NULL_RTX, 0, OPTAB_WIDEN);
7655 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7656 op3, operands[2]));
7657 break;
7658
7659 case GE:
7660 op3 = operands[3];
7661 if (!thumb1_cmp_operand (op3, SImode))
7662 op3 = force_reg (SImode, op3);
7663 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7664 NULL_RTX, 0, OPTAB_WIDEN);
7665 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7666 NULL_RTX, 1, OPTAB_WIDEN);
7667 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7668 operands[2], op3));
7669 break;
7670
7671 case LEU:
7672 op3 = force_reg (SImode, operands[3]);
7673 scratch = force_reg (SImode, const0_rtx);
7674 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7675 op3, operands[2]));
7676 break;
7677
7678 case GEU:
7679 op3 = operands[3];
7680 if (!thumb1_cmp_operand (op3, SImode))
7681 op3 = force_reg (SImode, op3);
7682 scratch = force_reg (SImode, const0_rtx);
7683 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7684 operands[2], op3));
7685 break;
7686
7687 case LTU:
7688 op3 = operands[3];
7689 if (!thumb1_cmp_operand (op3, SImode))
7690 op3 = force_reg (SImode, op3);
7691 scratch = gen_reg_rtx (SImode);
7692 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7693 break;
7694
7695 case GTU:
7696 op3 = force_reg (SImode, operands[3]);
7697 scratch = gen_reg_rtx (SImode);
7698 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7699 break;
7700
7701 /* No good sequences for GT, LT. */
7702 default:
7703 FAIL;
7704 }
7705 DONE;
7706 }")
7707
7708 (define_expand "cstorehf4"
7709 [(set (match_operand:SI 0 "s_register_operand")
7710 (match_operator:SI 1 "expandable_comparison_operator"
7711 [(match_operand:HF 2 "s_register_operand")
7712 (match_operand:HF 3 "arm_float_compare_operand")]))]
7713 "TARGET_VFP_FP16INST"
7714 {
7715 if (!arm_validize_comparison (&operands[1],
7716 &operands[2],
7717 &operands[3]))
7718 FAIL;
7719
7720 emit_insn (gen_cstore_cc (operands[0], operands[1],
7721 operands[2], operands[3]));
7722 DONE;
7723 }
7724 )
7725
7726 (define_expand "cstoresf4"
7727 [(set (match_operand:SI 0 "s_register_operand" "")
7728 (match_operator:SI 1 "expandable_comparison_operator"
7729 [(match_operand:SF 2 "s_register_operand" "")
7730 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7731 "TARGET_32BIT && TARGET_HARD_FLOAT"
7732 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7733 operands[2], operands[3])); DONE;"
7734 )
7735
7736 (define_expand "cstoredf4"
7737 [(set (match_operand:SI 0 "s_register_operand" "")
7738 (match_operator:SI 1 "expandable_comparison_operator"
7739 [(match_operand:DF 2 "s_register_operand" "")
7740 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7741 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7742 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7743 operands[2], operands[3])); DONE;"
7744 )
7745
7746 (define_expand "cstoredi4"
7747 [(set (match_operand:SI 0 "s_register_operand" "")
7748 (match_operator:SI 1 "expandable_comparison_operator"
7749 [(match_operand:DI 2 "s_register_operand" "")
7750 (match_operand:DI 3 "cmpdi_operand" "")]))]
7751 "TARGET_32BIT"
7752 "{
7753 if (!arm_validize_comparison (&operands[1],
7754 &operands[2],
7755 &operands[3]))
7756 FAIL;
7757 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7758 operands[3]));
7759 DONE;
7760 }"
7761 )
7762
7763 \f
7764 ;; Conditional move insns
7765
7766 (define_expand "movsicc"
7767 [(set (match_operand:SI 0 "s_register_operand" "")
7768 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7769 (match_operand:SI 2 "arm_not_operand" "")
7770 (match_operand:SI 3 "arm_not_operand" "")))]
7771 "TARGET_32BIT"
7772 "
7773 {
7774 enum rtx_code code;
7775 rtx ccreg;
7776
7777 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7778 &XEXP (operands[1], 1)))
7779 FAIL;
7780
7781 code = GET_CODE (operands[1]);
7782 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7783 XEXP (operands[1], 1), NULL_RTX);
7784 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7785 }"
7786 )
7787
7788 (define_expand "movhfcc"
7789 [(set (match_operand:HF 0 "s_register_operand")
7790 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7791 (match_operand:HF 2 "s_register_operand")
7792 (match_operand:HF 3 "s_register_operand")))]
7793 "TARGET_VFP_FP16INST"
7794 "
7795 {
7796 enum rtx_code code = GET_CODE (operands[1]);
7797 rtx ccreg;
7798
7799 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7800 &XEXP (operands[1], 1)))
7801 FAIL;
7802
7803 code = GET_CODE (operands[1]);
7804 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7805 XEXP (operands[1], 1), NULL_RTX);
7806 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7807 }"
7808 )
7809
7810 (define_expand "movsfcc"
7811 [(set (match_operand:SF 0 "s_register_operand" "")
7812 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7813 (match_operand:SF 2 "s_register_operand" "")
7814 (match_operand:SF 3 "s_register_operand" "")))]
7815 "TARGET_32BIT && TARGET_HARD_FLOAT"
7816 "
7817 {
7818 enum rtx_code code = GET_CODE (operands[1]);
7819 rtx ccreg;
7820
7821 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7822 &XEXP (operands[1], 1)))
7823 FAIL;
7824
7825 code = GET_CODE (operands[1]);
7826 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7827 XEXP (operands[1], 1), NULL_RTX);
7828 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7829 }"
7830 )
7831
7832 (define_expand "movdfcc"
7833 [(set (match_operand:DF 0 "s_register_operand" "")
7834 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7835 (match_operand:DF 2 "s_register_operand" "")
7836 (match_operand:DF 3 "s_register_operand" "")))]
7837 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7838 "
7839 {
7840 enum rtx_code code = GET_CODE (operands[1]);
7841 rtx ccreg;
7842
7843 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7844 &XEXP (operands[1], 1)))
7845 FAIL;
7846 code = GET_CODE (operands[1]);
7847 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7848 XEXP (operands[1], 1), NULL_RTX);
7849 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7850 }"
7851 )
7852
7853 (define_insn "*cmov<mode>"
7854 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7855 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7856 [(match_operand 2 "cc_register" "") (const_int 0)])
7857 (match_operand:SDF 3 "s_register_operand"
7858 "<F_constraint>")
7859 (match_operand:SDF 4 "s_register_operand"
7860 "<F_constraint>")))]
7861 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7862 "*
7863 {
7864 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7865 switch (code)
7866 {
7867 case ARM_GE:
7868 case ARM_GT:
7869 case ARM_EQ:
7870 case ARM_VS:
7871 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7872 case ARM_LT:
7873 case ARM_LE:
7874 case ARM_NE:
7875 case ARM_VC:
7876 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7877 default:
7878 gcc_unreachable ();
7879 }
7880 return \"\";
7881 }"
7882 [(set_attr "conds" "use")
7883 (set_attr "type" "fcsel")]
7884 )
7885
7886 (define_insn "*cmovhf"
7887 [(set (match_operand:HF 0 "s_register_operand" "=t")
7888 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7889 [(match_operand 2 "cc_register" "") (const_int 0)])
7890 (match_operand:HF 3 "s_register_operand" "t")
7891 (match_operand:HF 4 "s_register_operand" "t")))]
7892 "TARGET_VFP_FP16INST"
7893 "*
7894 {
7895 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7896 switch (code)
7897 {
7898 case ARM_GE:
7899 case ARM_GT:
7900 case ARM_EQ:
7901 case ARM_VS:
7902 return \"vsel%d1.f16\\t%0, %3, %4\";
7903 case ARM_LT:
7904 case ARM_LE:
7905 case ARM_NE:
7906 case ARM_VC:
7907 return \"vsel%D1.f16\\t%0, %4, %3\";
7908 default:
7909 gcc_unreachable ();
7910 }
7911 return \"\";
7912 }"
7913 [(set_attr "conds" "use")
7914 (set_attr "type" "fcsel")]
7915 )
7916
7917 (define_insn_and_split "*movsicc_insn"
7918 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7919 (if_then_else:SI
7920 (match_operator 3 "arm_comparison_operator"
7921 [(match_operand 4 "cc_register" "") (const_int 0)])
7922 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7923 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7924 "TARGET_ARM"
7925 "@
7926 mov%D3\\t%0, %2
7927 mvn%D3\\t%0, #%B2
7928 mov%d3\\t%0, %1
7929 mvn%d3\\t%0, #%B1
7930 #
7931 #
7932 #
7933 #"
7934 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7935 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7936 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7937 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7938 "&& reload_completed"
7939 [(const_int 0)]
7940 {
7941 enum rtx_code rev_code;
7942 machine_mode mode;
7943 rtx rev_cond;
7944
7945 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7946 operands[3],
7947 gen_rtx_SET (operands[0], operands[1])));
7948
7949 rev_code = GET_CODE (operands[3]);
7950 mode = GET_MODE (operands[4]);
7951 if (mode == CCFPmode || mode == CCFPEmode)
7952 rev_code = reverse_condition_maybe_unordered (rev_code);
7953 else
7954 rev_code = reverse_condition (rev_code);
7955
7956 rev_cond = gen_rtx_fmt_ee (rev_code,
7957 VOIDmode,
7958 operands[4],
7959 const0_rtx);
7960 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7961 rev_cond,
7962 gen_rtx_SET (operands[0], operands[2])));
7963 DONE;
7964 }
7965 [(set_attr "length" "4,4,4,4,8,8,8,8")
7966 (set_attr "conds" "use")
7967 (set_attr_alternative "type"
7968 [(if_then_else (match_operand 2 "const_int_operand" "")
7969 (const_string "mov_imm")
7970 (const_string "mov_reg"))
7971 (const_string "mvn_imm")
7972 (if_then_else (match_operand 1 "const_int_operand" "")
7973 (const_string "mov_imm")
7974 (const_string "mov_reg"))
7975 (const_string "mvn_imm")
7976 (const_string "multiple")
7977 (const_string "multiple")
7978 (const_string "multiple")
7979 (const_string "multiple")])]
7980 )
7981
7982 (define_insn "*movsfcc_soft_insn"
7983 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7984 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7985 [(match_operand 4 "cc_register" "") (const_int 0)])
7986 (match_operand:SF 1 "s_register_operand" "0,r")
7987 (match_operand:SF 2 "s_register_operand" "r,0")))]
7988 "TARGET_ARM && TARGET_SOFT_FLOAT"
7989 "@
7990 mov%D3\\t%0, %2
7991 mov%d3\\t%0, %1"
7992 [(set_attr "conds" "use")
7993 (set_attr "type" "mov_reg")]
7994 )
7995
7996 \f
7997 ;; Jump and linkage insns
7998
7999 (define_expand "jump"
8000 [(set (pc)
8001 (label_ref (match_operand 0 "" "")))]
8002 "TARGET_EITHER"
8003 ""
8004 )
8005
8006 (define_insn "*arm_jump"
8007 [(set (pc)
8008 (label_ref (match_operand 0 "" "")))]
8009 "TARGET_32BIT"
8010 "*
8011 {
8012 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8013 {
8014 arm_ccfsm_state += 2;
8015 return \"\";
8016 }
8017 return \"b%?\\t%l0\";
8018 }
8019 "
8020 [(set_attr "predicable" "yes")
8021 (set (attr "length")
8022 (if_then_else
8023 (and (match_test "TARGET_THUMB2")
8024 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8025 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8026 (const_int 2)
8027 (const_int 4)))
8028 (set_attr "type" "branch")]
8029 )
8030
8031 (define_expand "call"
8032 [(parallel [(call (match_operand 0 "memory_operand" "")
8033 (match_operand 1 "general_operand" ""))
8034 (use (match_operand 2 "" ""))
8035 (clobber (reg:SI LR_REGNUM))])]
8036 "TARGET_EITHER"
8037 "
8038 {
8039 rtx callee, pat;
8040
8041 /* In an untyped call, we can get NULL for operand 2. */
8042 if (operands[2] == NULL_RTX)
8043 operands[2] = const0_rtx;
8044
8045 /* Decide if we should generate indirect calls by loading the
8046 32-bit address of the callee into a register before performing the
8047 branch and link. */
8048 callee = XEXP (operands[0], 0);
8049 if (GET_CODE (callee) == SYMBOL_REF
8050 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8051 : !REG_P (callee))
8052 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8053
8054 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8055 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8056 DONE;
8057 }"
8058 )
8059
8060 (define_expand "call_internal"
8061 [(parallel [(call (match_operand 0 "memory_operand" "")
8062 (match_operand 1 "general_operand" ""))
8063 (use (match_operand 2 "" ""))
8064 (clobber (reg:SI LR_REGNUM))])])
8065
8066 (define_insn "*call_reg_armv5"
8067 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8068 (match_operand 1 "" ""))
8069 (use (match_operand 2 "" ""))
8070 (clobber (reg:SI LR_REGNUM))]
8071 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8072 "blx%?\\t%0"
8073 [(set_attr "type" "call")]
8074 )
8075
8076 (define_insn "*call_reg_arm"
8077 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8078 (match_operand 1 "" ""))
8079 (use (match_operand 2 "" ""))
8080 (clobber (reg:SI LR_REGNUM))]
8081 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8082 "*
8083 return output_call (operands);
8084 "
8085 ;; length is worst case, normally it is only two
8086 [(set_attr "length" "12")
8087 (set_attr "type" "call")]
8088 )
8089
8090
8091 (define_expand "call_value"
8092 [(parallel [(set (match_operand 0 "" "")
8093 (call (match_operand 1 "memory_operand" "")
8094 (match_operand 2 "general_operand" "")))
8095 (use (match_operand 3 "" ""))
8096 (clobber (reg:SI LR_REGNUM))])]
8097 "TARGET_EITHER"
8098 "
8099 {
8100 rtx pat, callee;
8101
8102 /* In an untyped call, we can get NULL for operand 2. */
8103 if (operands[3] == 0)
8104 operands[3] = const0_rtx;
8105
8106 /* Decide if we should generate indirect calls by loading the
8107 32-bit address of the callee into a register before performing the
8108 branch and link. */
8109 callee = XEXP (operands[1], 0);
8110 if (GET_CODE (callee) == SYMBOL_REF
8111 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8112 : !REG_P (callee))
8113 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8114
8115 pat = gen_call_value_internal (operands[0], operands[1],
8116 operands[2], operands[3]);
8117 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8118 DONE;
8119 }"
8120 )
8121
8122 (define_expand "call_value_internal"
8123 [(parallel [(set (match_operand 0 "" "")
8124 (call (match_operand 1 "memory_operand" "")
8125 (match_operand 2 "general_operand" "")))
8126 (use (match_operand 3 "" ""))
8127 (clobber (reg:SI LR_REGNUM))])])
8128
8129 (define_insn "*call_value_reg_armv5"
8130 [(set (match_operand 0 "" "")
8131 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8132 (match_operand 2 "" "")))
8133 (use (match_operand 3 "" ""))
8134 (clobber (reg:SI LR_REGNUM))]
8135 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8136 "blx%?\\t%1"
8137 [(set_attr "type" "call")]
8138 )
8139
8140 (define_insn "*call_value_reg_arm"
8141 [(set (match_operand 0 "" "")
8142 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8143 (match_operand 2 "" "")))
8144 (use (match_operand 3 "" ""))
8145 (clobber (reg:SI LR_REGNUM))]
8146 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8147 "*
8148 return output_call (&operands[1]);
8149 "
8150 [(set_attr "length" "12")
8151 (set_attr "type" "call")]
8152 )
8153
8154 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8155 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8156
8157 (define_insn "*call_symbol"
8158 [(call (mem:SI (match_operand:SI 0 "" ""))
8159 (match_operand 1 "" ""))
8160 (use (match_operand 2 "" ""))
8161 (clobber (reg:SI LR_REGNUM))]
8162 "TARGET_32BIT
8163 && !SIBLING_CALL_P (insn)
8164 && (GET_CODE (operands[0]) == SYMBOL_REF)
8165 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8166 "*
8167 {
8168 rtx op = operands[0];
8169
8170 /* Switch mode now when possible. */
8171 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8172 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8173 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8174
8175 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8176 }"
8177 [(set_attr "type" "call")]
8178 )
8179
8180 (define_insn "*call_value_symbol"
8181 [(set (match_operand 0 "" "")
8182 (call (mem:SI (match_operand:SI 1 "" ""))
8183 (match_operand:SI 2 "" "")))
8184 (use (match_operand 3 "" ""))
8185 (clobber (reg:SI LR_REGNUM))]
8186 "TARGET_32BIT
8187 && !SIBLING_CALL_P (insn)
8188 && (GET_CODE (operands[1]) == SYMBOL_REF)
8189 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8190 "*
8191 {
8192 rtx op = operands[1];
8193
8194 /* Switch mode now when possible. */
8195 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8196 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8197 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8198
8199 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8200 }"
8201 [(set_attr "type" "call")]
8202 )
8203
8204 (define_expand "sibcall_internal"
8205 [(parallel [(call (match_operand 0 "memory_operand" "")
8206 (match_operand 1 "general_operand" ""))
8207 (return)
8208 (use (match_operand 2 "" ""))])])
8209
8210 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8211 (define_expand "sibcall"
8212 [(parallel [(call (match_operand 0 "memory_operand" "")
8213 (match_operand 1 "general_operand" ""))
8214 (return)
8215 (use (match_operand 2 "" ""))])]
8216 "TARGET_32BIT"
8217 "
8218 {
8219 rtx pat;
8220
8221 if ((!REG_P (XEXP (operands[0], 0))
8222 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8223 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8224 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8225 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8226
8227 if (operands[2] == NULL_RTX)
8228 operands[2] = const0_rtx;
8229
8230 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8231 arm_emit_call_insn (pat, operands[0], true);
8232 DONE;
8233 }"
8234 )
8235
8236 (define_expand "sibcall_value_internal"
8237 [(parallel [(set (match_operand 0 "" "")
8238 (call (match_operand 1 "memory_operand" "")
8239 (match_operand 2 "general_operand" "")))
8240 (return)
8241 (use (match_operand 3 "" ""))])])
8242
8243 (define_expand "sibcall_value"
8244 [(parallel [(set (match_operand 0 "" "")
8245 (call (match_operand 1 "memory_operand" "")
8246 (match_operand 2 "general_operand" "")))
8247 (return)
8248 (use (match_operand 3 "" ""))])]
8249 "TARGET_32BIT"
8250 "
8251 {
8252 rtx pat;
8253
8254 if ((!REG_P (XEXP (operands[1], 0))
8255 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8256 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8257 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8258 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8259
8260 if (operands[3] == NULL_RTX)
8261 operands[3] = const0_rtx;
8262
8263 pat = gen_sibcall_value_internal (operands[0], operands[1],
8264 operands[2], operands[3]);
8265 arm_emit_call_insn (pat, operands[1], true);
8266 DONE;
8267 }"
8268 )
8269
8270 (define_insn "*sibcall_insn"
8271 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8272 (match_operand 1 "" ""))
8273 (return)
8274 (use (match_operand 2 "" ""))]
8275 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8276 "*
8277 if (which_alternative == 1)
8278 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8279 else
8280 {
8281 if (arm_arch5 || arm_arch4t)
8282 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8283 else
8284 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8285 }
8286 "
8287 [(set_attr "type" "call")]
8288 )
8289
8290 (define_insn "*sibcall_value_insn"
8291 [(set (match_operand 0 "" "")
8292 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8293 (match_operand 2 "" "")))
8294 (return)
8295 (use (match_operand 3 "" ""))]
8296 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8297 "*
8298 if (which_alternative == 1)
8299 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8300 else
8301 {
8302 if (arm_arch5 || arm_arch4t)
8303 return \"bx%?\\t%1\";
8304 else
8305 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8306 }
8307 "
8308 [(set_attr "type" "call")]
8309 )
8310
8311 (define_expand "<return_str>return"
8312 [(RETURNS)]
8313 "(TARGET_ARM || (TARGET_THUMB2
8314 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8315 && !IS_STACKALIGN (arm_current_func_type ())))
8316 <return_cond_false>"
8317 "
8318 {
8319 if (TARGET_THUMB2)
8320 {
8321 thumb2_expand_return (<return_simple_p>);
8322 DONE;
8323 }
8324 }
8325 "
8326 )
8327
8328 ;; Often the return insn will be the same as loading from memory, so set attr
8329 (define_insn "*arm_return"
8330 [(return)]
8331 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8332 "*
8333 {
8334 if (arm_ccfsm_state == 2)
8335 {
8336 arm_ccfsm_state += 2;
8337 return \"\";
8338 }
8339 return output_return_instruction (const_true_rtx, true, false, false);
8340 }"
8341 [(set_attr "type" "load1")
8342 (set_attr "length" "12")
8343 (set_attr "predicable" "yes")]
8344 )
8345
8346 (define_insn "*cond_<return_str>return"
8347 [(set (pc)
8348 (if_then_else (match_operator 0 "arm_comparison_operator"
8349 [(match_operand 1 "cc_register" "") (const_int 0)])
8350 (RETURNS)
8351 (pc)))]
8352 "TARGET_ARM <return_cond_true>"
8353 "*
8354 {
8355 if (arm_ccfsm_state == 2)
8356 {
8357 arm_ccfsm_state += 2;
8358 return \"\";
8359 }
8360 return output_return_instruction (operands[0], true, false,
8361 <return_simple_p>);
8362 }"
8363 [(set_attr "conds" "use")
8364 (set_attr "length" "12")
8365 (set_attr "type" "load1")]
8366 )
8367
8368 (define_insn "*cond_<return_str>return_inverted"
8369 [(set (pc)
8370 (if_then_else (match_operator 0 "arm_comparison_operator"
8371 [(match_operand 1 "cc_register" "") (const_int 0)])
8372 (pc)
8373 (RETURNS)))]
8374 "TARGET_ARM <return_cond_true>"
8375 "*
8376 {
8377 if (arm_ccfsm_state == 2)
8378 {
8379 arm_ccfsm_state += 2;
8380 return \"\";
8381 }
8382 return output_return_instruction (operands[0], true, true,
8383 <return_simple_p>);
8384 }"
8385 [(set_attr "conds" "use")
8386 (set_attr "length" "12")
8387 (set_attr "type" "load1")]
8388 )
8389
8390 (define_insn "*arm_simple_return"
8391 [(simple_return)]
8392 "TARGET_ARM"
8393 "*
8394 {
8395 if (arm_ccfsm_state == 2)
8396 {
8397 arm_ccfsm_state += 2;
8398 return \"\";
8399 }
8400 return output_return_instruction (const_true_rtx, true, false, true);
8401 }"
8402 [(set_attr "type" "branch")
8403 (set_attr "length" "4")
8404 (set_attr "predicable" "yes")]
8405 )
8406
8407 ;; Generate a sequence of instructions to determine if the processor is
8408 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8409 ;; mask.
8410
8411 (define_expand "return_addr_mask"
8412 [(set (match_dup 1)
8413 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8414 (const_int 0)))
8415 (set (match_operand:SI 0 "s_register_operand" "")
8416 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8417 (const_int -1)
8418 (const_int 67108860)))] ; 0x03fffffc
8419 "TARGET_ARM"
8420 "
8421 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8422 ")
8423
8424 (define_insn "*check_arch2"
8425 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8426 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8427 (const_int 0)))]
8428 "TARGET_ARM"
8429 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8430 [(set_attr "length" "8")
8431 (set_attr "conds" "set")
8432 (set_attr "type" "multiple")]
8433 )
8434
8435 ;; Call subroutine returning any type.
8436
8437 (define_expand "untyped_call"
8438 [(parallel [(call (match_operand 0 "" "")
8439 (const_int 0))
8440 (match_operand 1 "" "")
8441 (match_operand 2 "" "")])]
8442 "TARGET_EITHER"
8443 "
8444 {
8445 int i;
8446 rtx par = gen_rtx_PARALLEL (VOIDmode,
8447 rtvec_alloc (XVECLEN (operands[2], 0)));
8448 rtx addr = gen_reg_rtx (Pmode);
8449 rtx mem;
8450 int size = 0;
8451
8452 emit_move_insn (addr, XEXP (operands[1], 0));
8453 mem = change_address (operands[1], BLKmode, addr);
8454
8455 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8456 {
8457 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8458
8459 /* Default code only uses r0 as a return value, but we could
8460 be using anything up to 4 registers. */
8461 if (REGNO (src) == R0_REGNUM)
8462 src = gen_rtx_REG (TImode, R0_REGNUM);
8463
8464 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8465 GEN_INT (size));
8466 size += GET_MODE_SIZE (GET_MODE (src));
8467 }
8468
8469 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8470
8471 size = 0;
8472
8473 for (i = 0; i < XVECLEN (par, 0); i++)
8474 {
8475 HOST_WIDE_INT offset = 0;
8476 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8477
8478 if (size != 0)
8479 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8480
8481 mem = change_address (mem, GET_MODE (reg), NULL);
8482 if (REGNO (reg) == R0_REGNUM)
8483 {
8484 /* On thumb we have to use a write-back instruction. */
8485 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8486 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8487 size = TARGET_ARM ? 16 : 0;
8488 }
8489 else
8490 {
8491 emit_move_insn (mem, reg);
8492 size = GET_MODE_SIZE (GET_MODE (reg));
8493 }
8494 }
8495
8496 /* The optimizer does not know that the call sets the function value
8497 registers we stored in the result block. We avoid problems by
8498 claiming that all hard registers are used and clobbered at this
8499 point. */
8500 emit_insn (gen_blockage ());
8501
8502 DONE;
8503 }"
8504 )
8505
8506 (define_expand "untyped_return"
8507 [(match_operand:BLK 0 "memory_operand" "")
8508 (match_operand 1 "" "")]
8509 "TARGET_EITHER"
8510 "
8511 {
8512 int i;
8513 rtx addr = gen_reg_rtx (Pmode);
8514 rtx mem;
8515 int size = 0;
8516
8517 emit_move_insn (addr, XEXP (operands[0], 0));
8518 mem = change_address (operands[0], BLKmode, addr);
8519
8520 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8521 {
8522 HOST_WIDE_INT offset = 0;
8523 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8524
8525 if (size != 0)
8526 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8527
8528 mem = change_address (mem, GET_MODE (reg), NULL);
8529 if (REGNO (reg) == R0_REGNUM)
8530 {
8531 /* On thumb we have to use a write-back instruction. */
8532 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8533 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8534 size = TARGET_ARM ? 16 : 0;
8535 }
8536 else
8537 {
8538 emit_move_insn (reg, mem);
8539 size = GET_MODE_SIZE (GET_MODE (reg));
8540 }
8541 }
8542
8543 /* Emit USE insns before the return. */
8544 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8545 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8546
8547 /* Construct the return. */
8548 expand_naked_return ();
8549
8550 DONE;
8551 }"
8552 )
8553
8554 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8555 ;; all of memory. This blocks insns from being moved across this point.
8556
8557 (define_insn "blockage"
8558 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8559 "TARGET_EITHER"
8560 ""
8561 [(set_attr "length" "0")
8562 (set_attr "type" "block")]
8563 )
8564
8565 (define_insn "probe_stack"
8566 [(set (match_operand:SI 0 "memory_operand" "=m")
8567 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8568 "TARGET_32BIT"
8569 "str%?\\tr0, %0"
8570 [(set_attr "type" "store1")
8571 (set_attr "predicable" "yes")]
8572 )
8573
8574 (define_insn "probe_stack_range"
8575 [(set (match_operand:SI 0 "register_operand" "=r")
8576 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8577 (match_operand:SI 2 "register_operand" "r")]
8578 VUNSPEC_PROBE_STACK_RANGE))]
8579 "TARGET_32BIT"
8580 {
8581 return output_probe_stack_range (operands[0], operands[2]);
8582 }
8583 [(set_attr "type" "multiple")
8584 (set_attr "conds" "clob")]
8585 )
8586
8587 (define_expand "casesi"
8588 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8589 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8590 (match_operand:SI 2 "const_int_operand" "") ; total range
8591 (match_operand:SI 3 "" "") ; table label
8592 (match_operand:SI 4 "" "")] ; Out of range label
8593 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8594 "
8595 {
8596 enum insn_code code;
8597 if (operands[1] != const0_rtx)
8598 {
8599 rtx reg = gen_reg_rtx (SImode);
8600
8601 emit_insn (gen_addsi3 (reg, operands[0],
8602 gen_int_mode (-INTVAL (operands[1]),
8603 SImode)));
8604 operands[0] = reg;
8605 }
8606
8607 if (TARGET_ARM)
8608 code = CODE_FOR_arm_casesi_internal;
8609 else if (TARGET_THUMB1)
8610 code = CODE_FOR_thumb1_casesi_internal_pic;
8611 else if (flag_pic)
8612 code = CODE_FOR_thumb2_casesi_internal_pic;
8613 else
8614 code = CODE_FOR_thumb2_casesi_internal;
8615
8616 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8617 operands[2] = force_reg (SImode, operands[2]);
8618
8619 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8620 operands[3], operands[4]));
8621 DONE;
8622 }"
8623 )
8624
8625 ;; The USE in this pattern is needed to tell flow analysis that this is
8626 ;; a CASESI insn. It has no other purpose.
8627 (define_insn "arm_casesi_internal"
8628 [(parallel [(set (pc)
8629 (if_then_else
8630 (leu (match_operand:SI 0 "s_register_operand" "r")
8631 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8632 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8633 (label_ref (match_operand 2 "" ""))))
8634 (label_ref (match_operand 3 "" ""))))
8635 (clobber (reg:CC CC_REGNUM))
8636 (use (label_ref (match_dup 2)))])]
8637 "TARGET_ARM"
8638 "*
8639 if (flag_pic)
8640 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8641 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8642 "
8643 [(set_attr "conds" "clob")
8644 (set_attr "length" "12")
8645 (set_attr "type" "multiple")]
8646 )
8647
8648 (define_expand "indirect_jump"
8649 [(set (pc)
8650 (match_operand:SI 0 "s_register_operand" ""))]
8651 "TARGET_EITHER"
8652 "
8653 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8654 address and use bx. */
8655 if (TARGET_THUMB2)
8656 {
8657 rtx tmp;
8658 tmp = gen_reg_rtx (SImode);
8659 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8660 operands[0] = tmp;
8661 }
8662 "
8663 )
8664
8665 ;; NB Never uses BX.
8666 (define_insn "*arm_indirect_jump"
8667 [(set (pc)
8668 (match_operand:SI 0 "s_register_operand" "r"))]
8669 "TARGET_ARM"
8670 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8671 [(set_attr "predicable" "yes")
8672 (set_attr "type" "branch")]
8673 )
8674
8675 (define_insn "*load_indirect_jump"
8676 [(set (pc)
8677 (match_operand:SI 0 "memory_operand" "m"))]
8678 "TARGET_ARM"
8679 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8680 [(set_attr "type" "load1")
8681 (set_attr "pool_range" "4096")
8682 (set_attr "neg_pool_range" "4084")
8683 (set_attr "predicable" "yes")]
8684 )
8685
8686 \f
8687 ;; Misc insns
8688
8689 (define_insn "nop"
8690 [(const_int 0)]
8691 "TARGET_EITHER"
8692 "nop"
8693 [(set (attr "length")
8694 (if_then_else (eq_attr "is_thumb" "yes")
8695 (const_int 2)
8696 (const_int 4)))
8697 (set_attr "type" "mov_reg")]
8698 )
8699
8700 (define_insn "trap"
8701 [(trap_if (const_int 1) (const_int 0))]
8702 ""
8703 "*
8704 if (TARGET_ARM)
8705 return \".inst\\t0xe7f000f0\";
8706 else
8707 return \".inst\\t0xdeff\";
8708 "
8709 [(set (attr "length")
8710 (if_then_else (eq_attr "is_thumb" "yes")
8711 (const_int 2)
8712 (const_int 4)))
8713 (set_attr "type" "trap")
8714 (set_attr "conds" "unconditional")]
8715 )
8716
8717 \f
8718 ;; Patterns to allow combination of arithmetic, cond code and shifts
8719
8720 (define_insn "*<arith_shift_insn>_multsi"
8721 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8722 (SHIFTABLE_OPS:SI
8723 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8724 (match_operand:SI 3 "power_of_two_operand" ""))
8725 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8726 "TARGET_32BIT"
8727 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8728 [(set_attr "predicable" "yes")
8729 (set_attr "predicable_short_it" "no")
8730 (set_attr "shift" "2")
8731 (set_attr "arch" "a,t2")
8732 (set_attr "type" "alu_shift_imm")])
8733
8734 (define_insn "*<arith_shift_insn>_shiftsi"
8735 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8736 (SHIFTABLE_OPS:SI
8737 (match_operator:SI 2 "shift_nomul_operator"
8738 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8739 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8740 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8741 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8742 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8743 [(set_attr "predicable" "yes")
8744 (set_attr "predicable_short_it" "no")
8745 (set_attr "shift" "3")
8746 (set_attr "arch" "a,t2,a")
8747 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8748
8749 (define_split
8750 [(set (match_operand:SI 0 "s_register_operand" "")
8751 (match_operator:SI 1 "shiftable_operator"
8752 [(match_operator:SI 2 "shiftable_operator"
8753 [(match_operator:SI 3 "shift_operator"
8754 [(match_operand:SI 4 "s_register_operand" "")
8755 (match_operand:SI 5 "reg_or_int_operand" "")])
8756 (match_operand:SI 6 "s_register_operand" "")])
8757 (match_operand:SI 7 "arm_rhs_operand" "")]))
8758 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8759 "TARGET_32BIT"
8760 [(set (match_dup 8)
8761 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8762 (match_dup 6)]))
8763 (set (match_dup 0)
8764 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8765 "")
8766
8767 (define_insn "*arith_shiftsi_compare0"
8768 [(set (reg:CC_NOOV CC_REGNUM)
8769 (compare:CC_NOOV
8770 (match_operator:SI 1 "shiftable_operator"
8771 [(match_operator:SI 3 "shift_operator"
8772 [(match_operand:SI 4 "s_register_operand" "r,r")
8773 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8774 (match_operand:SI 2 "s_register_operand" "r,r")])
8775 (const_int 0)))
8776 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8777 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8778 (match_dup 2)]))]
8779 "TARGET_32BIT"
8780 "%i1s%?\\t%0, %2, %4%S3"
8781 [(set_attr "conds" "set")
8782 (set_attr "shift" "4")
8783 (set_attr "arch" "32,a")
8784 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8785
8786 (define_insn "*arith_shiftsi_compare0_scratch"
8787 [(set (reg:CC_NOOV CC_REGNUM)
8788 (compare:CC_NOOV
8789 (match_operator:SI 1 "shiftable_operator"
8790 [(match_operator:SI 3 "shift_operator"
8791 [(match_operand:SI 4 "s_register_operand" "r,r")
8792 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8793 (match_operand:SI 2 "s_register_operand" "r,r")])
8794 (const_int 0)))
8795 (clobber (match_scratch:SI 0 "=r,r"))]
8796 "TARGET_32BIT"
8797 "%i1s%?\\t%0, %2, %4%S3"
8798 [(set_attr "conds" "set")
8799 (set_attr "shift" "4")
8800 (set_attr "arch" "32,a")
8801 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8802
8803 (define_insn "*sub_shiftsi"
8804 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8805 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8806 (match_operator:SI 2 "shift_operator"
8807 [(match_operand:SI 3 "s_register_operand" "r,r")
8808 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8809 "TARGET_32BIT"
8810 "sub%?\\t%0, %1, %3%S2"
8811 [(set_attr "predicable" "yes")
8812 (set_attr "shift" "3")
8813 (set_attr "arch" "32,a")
8814 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8815
8816 (define_insn "*sub_shiftsi_compare0"
8817 [(set (reg:CC_NOOV CC_REGNUM)
8818 (compare:CC_NOOV
8819 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8820 (match_operator:SI 2 "shift_operator"
8821 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8822 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8823 (const_int 0)))
8824 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8825 (minus:SI (match_dup 1)
8826 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8827 "TARGET_32BIT"
8828 "subs%?\\t%0, %1, %3%S2"
8829 [(set_attr "conds" "set")
8830 (set_attr "shift" "3")
8831 (set_attr "arch" "32,a,a")
8832 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8833
8834 (define_insn "*sub_shiftsi_compare0_scratch"
8835 [(set (reg:CC_NOOV CC_REGNUM)
8836 (compare:CC_NOOV
8837 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8838 (match_operator:SI 2 "shift_operator"
8839 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8840 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8841 (const_int 0)))
8842 (clobber (match_scratch:SI 0 "=r,r,r"))]
8843 "TARGET_32BIT"
8844 "subs%?\\t%0, %1, %3%S2"
8845 [(set_attr "conds" "set")
8846 (set_attr "shift" "3")
8847 (set_attr "arch" "32,a,a")
8848 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8849 \f
8850
8851 (define_insn_and_split "*and_scc"
8852 [(set (match_operand:SI 0 "s_register_operand" "=r")
8853 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8854 [(match_operand 2 "cc_register" "") (const_int 0)])
8855 (match_operand:SI 3 "s_register_operand" "r")))]
8856 "TARGET_ARM"
8857 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8858 "&& reload_completed"
8859 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8860 (cond_exec (match_dup 4) (set (match_dup 0)
8861 (and:SI (match_dup 3) (const_int 1))))]
8862 {
8863 machine_mode mode = GET_MODE (operands[2]);
8864 enum rtx_code rc = GET_CODE (operands[1]);
8865
8866 /* Note that operands[4] is the same as operands[1],
8867 but with VOIDmode as the result. */
8868 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8869 if (mode == CCFPmode || mode == CCFPEmode)
8870 rc = reverse_condition_maybe_unordered (rc);
8871 else
8872 rc = reverse_condition (rc);
8873 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8874 }
8875 [(set_attr "conds" "use")
8876 (set_attr "type" "multiple")
8877 (set_attr "length" "8")]
8878 )
8879
8880 (define_insn_and_split "*ior_scc"
8881 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8882 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8883 [(match_operand 2 "cc_register" "") (const_int 0)])
8884 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8885 "TARGET_ARM"
8886 "@
8887 orr%d1\\t%0, %3, #1
8888 #"
8889 "&& reload_completed
8890 && REGNO (operands [0]) != REGNO (operands[3])"
8891 ;; && which_alternative == 1
8892 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8893 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8894 (cond_exec (match_dup 4) (set (match_dup 0)
8895 (ior:SI (match_dup 3) (const_int 1))))]
8896 {
8897 machine_mode mode = GET_MODE (operands[2]);
8898 enum rtx_code rc = GET_CODE (operands[1]);
8899
8900 /* Note that operands[4] is the same as operands[1],
8901 but with VOIDmode as the result. */
8902 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8903 if (mode == CCFPmode || mode == CCFPEmode)
8904 rc = reverse_condition_maybe_unordered (rc);
8905 else
8906 rc = reverse_condition (rc);
8907 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8908 }
8909 [(set_attr "conds" "use")
8910 (set_attr "length" "4,8")
8911 (set_attr "type" "logic_imm,multiple")]
8912 )
8913
8914 ; A series of splitters for the compare_scc pattern below. Note that
8915 ; order is important.
8916 (define_split
8917 [(set (match_operand:SI 0 "s_register_operand" "")
8918 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8919 (const_int 0)))
8920 (clobber (reg:CC CC_REGNUM))]
8921 "TARGET_32BIT && reload_completed"
8922 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8923
8924 (define_split
8925 [(set (match_operand:SI 0 "s_register_operand" "")
8926 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8927 (const_int 0)))
8928 (clobber (reg:CC CC_REGNUM))]
8929 "TARGET_32BIT && reload_completed"
8930 [(set (match_dup 0) (not:SI (match_dup 1)))
8931 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8932
8933 (define_split
8934 [(set (match_operand:SI 0 "s_register_operand" "")
8935 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8936 (const_int 0)))
8937 (clobber (reg:CC CC_REGNUM))]
8938 "arm_arch5 && TARGET_32BIT"
8939 [(set (match_dup 0) (clz:SI (match_dup 1)))
8940 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8941 )
8942
8943 (define_split
8944 [(set (match_operand:SI 0 "s_register_operand" "")
8945 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8946 (const_int 0)))
8947 (clobber (reg:CC CC_REGNUM))]
8948 "TARGET_32BIT && reload_completed"
8949 [(parallel
8950 [(set (reg:CC CC_REGNUM)
8951 (compare:CC (const_int 1) (match_dup 1)))
8952 (set (match_dup 0)
8953 (minus:SI (const_int 1) (match_dup 1)))])
8954 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8955 (set (match_dup 0) (const_int 0)))])
8956
8957 (define_split
8958 [(set (match_operand:SI 0 "s_register_operand" "")
8959 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8960 (match_operand:SI 2 "const_int_operand" "")))
8961 (clobber (reg:CC CC_REGNUM))]
8962 "TARGET_32BIT && reload_completed"
8963 [(parallel
8964 [(set (reg:CC CC_REGNUM)
8965 (compare:CC (match_dup 1) (match_dup 2)))
8966 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8967 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8968 (set (match_dup 0) (const_int 1)))]
8969 {
8970 operands[3] = GEN_INT (-INTVAL (operands[2]));
8971 })
8972
8973 (define_split
8974 [(set (match_operand:SI 0 "s_register_operand" "")
8975 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8976 (match_operand:SI 2 "arm_add_operand" "")))
8977 (clobber (reg:CC CC_REGNUM))]
8978 "TARGET_32BIT && reload_completed"
8979 [(parallel
8980 [(set (reg:CC_NOOV CC_REGNUM)
8981 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8982 (const_int 0)))
8983 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8984 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8985 (set (match_dup 0) (const_int 1)))])
8986
8987 (define_insn_and_split "*compare_scc"
8988 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8989 (match_operator:SI 1 "arm_comparison_operator"
8990 [(match_operand:SI 2 "s_register_operand" "r,r")
8991 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8992 (clobber (reg:CC CC_REGNUM))]
8993 "TARGET_32BIT"
8994 "#"
8995 "&& reload_completed"
8996 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8997 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8998 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8999 {
9000 rtx tmp1;
9001 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9002 operands[2], operands[3]);
9003 enum rtx_code rc = GET_CODE (operands[1]);
9004
9005 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9006
9007 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9008 if (mode == CCFPmode || mode == CCFPEmode)
9009 rc = reverse_condition_maybe_unordered (rc);
9010 else
9011 rc = reverse_condition (rc);
9012 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9013 }
9014 [(set_attr "type" "multiple")]
9015 )
9016
9017 ;; Attempt to improve the sequence generated by the compare_scc splitters
9018 ;; not to use conditional execution.
9019
9020 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9021 ;; clz Rd, reg1
9022 ;; lsr Rd, Rd, #5
9023 (define_peephole2
9024 [(set (reg:CC CC_REGNUM)
9025 (compare:CC (match_operand:SI 1 "register_operand" "")
9026 (const_int 0)))
9027 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9028 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9029 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9030 (set (match_dup 0) (const_int 1)))]
9031 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9032 [(set (match_dup 0) (clz:SI (match_dup 1)))
9033 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9034 )
9035
9036 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9037 ;; negs Rd, reg1
9038 ;; adc Rd, Rd, reg1
9039 (define_peephole2
9040 [(set (reg:CC CC_REGNUM)
9041 (compare:CC (match_operand:SI 1 "register_operand" "")
9042 (const_int 0)))
9043 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9044 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9045 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9046 (set (match_dup 0) (const_int 1)))
9047 (match_scratch:SI 2 "r")]
9048 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9049 [(parallel
9050 [(set (reg:CC CC_REGNUM)
9051 (compare:CC (const_int 0) (match_dup 1)))
9052 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9053 (set (match_dup 0)
9054 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9055 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9056 )
9057
9058 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9059 ;; sub Rd, Reg1, reg2
9060 ;; clz Rd, Rd
9061 ;; lsr Rd, Rd, #5
9062 (define_peephole2
9063 [(set (reg:CC CC_REGNUM)
9064 (compare:CC (match_operand:SI 1 "register_operand" "")
9065 (match_operand:SI 2 "arm_rhs_operand" "")))
9066 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9067 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9068 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9069 (set (match_dup 0) (const_int 1)))]
9070 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9071 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9072 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9073 (set (match_dup 0) (clz:SI (match_dup 0)))
9074 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9075 )
9076
9077
9078 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9079 ;; sub T1, Reg1, reg2
9080 ;; negs Rd, T1
9081 ;; adc Rd, Rd, T1
9082 (define_peephole2
9083 [(set (reg:CC CC_REGNUM)
9084 (compare:CC (match_operand:SI 1 "register_operand" "")
9085 (match_operand:SI 2 "arm_rhs_operand" "")))
9086 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9087 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9088 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9089 (set (match_dup 0) (const_int 1)))
9090 (match_scratch:SI 3 "r")]
9091 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9092 [(set (match_dup 3) (match_dup 4))
9093 (parallel
9094 [(set (reg:CC CC_REGNUM)
9095 (compare:CC (const_int 0) (match_dup 3)))
9096 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9097 (set (match_dup 0)
9098 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9099 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9100 "
9101 if (CONST_INT_P (operands[2]))
9102 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9103 else
9104 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9105 ")
9106
9107 (define_insn "*cond_move"
9108 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9109 (if_then_else:SI (match_operator 3 "equality_operator"
9110 [(match_operator 4 "arm_comparison_operator"
9111 [(match_operand 5 "cc_register" "") (const_int 0)])
9112 (const_int 0)])
9113 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9114 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9115 "TARGET_ARM"
9116 "*
9117 if (GET_CODE (operands[3]) == NE)
9118 {
9119 if (which_alternative != 1)
9120 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9121 if (which_alternative != 0)
9122 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9123 return \"\";
9124 }
9125 if (which_alternative != 0)
9126 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9127 if (which_alternative != 1)
9128 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9129 return \"\";
9130 "
9131 [(set_attr "conds" "use")
9132 (set_attr_alternative "type"
9133 [(if_then_else (match_operand 2 "const_int_operand" "")
9134 (const_string "mov_imm")
9135 (const_string "mov_reg"))
9136 (if_then_else (match_operand 1 "const_int_operand" "")
9137 (const_string "mov_imm")
9138 (const_string "mov_reg"))
9139 (const_string "multiple")])
9140 (set_attr "length" "4,4,8")]
9141 )
9142
9143 (define_insn "*cond_arith"
9144 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9145 (match_operator:SI 5 "shiftable_operator"
9146 [(match_operator:SI 4 "arm_comparison_operator"
9147 [(match_operand:SI 2 "s_register_operand" "r,r")
9148 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9149 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9150 (clobber (reg:CC CC_REGNUM))]
9151 "TARGET_ARM"
9152 "*
9153 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9154 return \"%i5\\t%0, %1, %2, lsr #31\";
9155
9156 output_asm_insn (\"cmp\\t%2, %3\", operands);
9157 if (GET_CODE (operands[5]) == AND)
9158 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9159 else if (GET_CODE (operands[5]) == MINUS)
9160 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9161 else if (which_alternative != 0)
9162 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9163 return \"%i5%d4\\t%0, %1, #1\";
9164 "
9165 [(set_attr "conds" "clob")
9166 (set_attr "length" "12")
9167 (set_attr "type" "multiple")]
9168 )
9169
9170 (define_insn "*cond_sub"
9171 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9172 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9173 (match_operator:SI 4 "arm_comparison_operator"
9174 [(match_operand:SI 2 "s_register_operand" "r,r")
9175 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9176 (clobber (reg:CC CC_REGNUM))]
9177 "TARGET_ARM"
9178 "*
9179 output_asm_insn (\"cmp\\t%2, %3\", operands);
9180 if (which_alternative != 0)
9181 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9182 return \"sub%d4\\t%0, %1, #1\";
9183 "
9184 [(set_attr "conds" "clob")
9185 (set_attr "length" "8,12")
9186 (set_attr "type" "multiple")]
9187 )
9188
9189 (define_insn "*cmp_ite0"
9190 [(set (match_operand 6 "dominant_cc_register" "")
9191 (compare
9192 (if_then_else:SI
9193 (match_operator 4 "arm_comparison_operator"
9194 [(match_operand:SI 0 "s_register_operand"
9195 "l,l,l,r,r,r,r,r,r")
9196 (match_operand:SI 1 "arm_add_operand"
9197 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9198 (match_operator:SI 5 "arm_comparison_operator"
9199 [(match_operand:SI 2 "s_register_operand"
9200 "l,r,r,l,l,r,r,r,r")
9201 (match_operand:SI 3 "arm_add_operand"
9202 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9203 (const_int 0))
9204 (const_int 0)))]
9205 "TARGET_32BIT"
9206 "*
9207 {
9208 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9209 {
9210 {\"cmp%d5\\t%0, %1\",
9211 \"cmp%d4\\t%2, %3\"},
9212 {\"cmn%d5\\t%0, #%n1\",
9213 \"cmp%d4\\t%2, %3\"},
9214 {\"cmp%d5\\t%0, %1\",
9215 \"cmn%d4\\t%2, #%n3\"},
9216 {\"cmn%d5\\t%0, #%n1\",
9217 \"cmn%d4\\t%2, #%n3\"}
9218 };
9219 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9220 {
9221 {\"cmp\\t%2, %3\",
9222 \"cmp\\t%0, %1\"},
9223 {\"cmp\\t%2, %3\",
9224 \"cmn\\t%0, #%n1\"},
9225 {\"cmn\\t%2, #%n3\",
9226 \"cmp\\t%0, %1\"},
9227 {\"cmn\\t%2, #%n3\",
9228 \"cmn\\t%0, #%n1\"}
9229 };
9230 static const char * const ite[2] =
9231 {
9232 \"it\\t%d5\",
9233 \"it\\t%d4\"
9234 };
9235 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9236 CMP_CMP, CMN_CMP, CMP_CMP,
9237 CMN_CMP, CMP_CMN, CMN_CMN};
9238 int swap =
9239 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9240
9241 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9242 if (TARGET_THUMB2) {
9243 output_asm_insn (ite[swap], operands);
9244 }
9245 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9246 return \"\";
9247 }"
9248 [(set_attr "conds" "set")
9249 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9250 (set_attr "type" "multiple")
9251 (set_attr_alternative "length"
9252 [(const_int 6)
9253 (const_int 8)
9254 (const_int 8)
9255 (const_int 8)
9256 (const_int 8)
9257 (if_then_else (eq_attr "is_thumb" "no")
9258 (const_int 8)
9259 (const_int 10))
9260 (if_then_else (eq_attr "is_thumb" "no")
9261 (const_int 8)
9262 (const_int 10))
9263 (if_then_else (eq_attr "is_thumb" "no")
9264 (const_int 8)
9265 (const_int 10))
9266 (if_then_else (eq_attr "is_thumb" "no")
9267 (const_int 8)
9268 (const_int 10))])]
9269 )
9270
9271 (define_insn "*cmp_ite1"
9272 [(set (match_operand 6 "dominant_cc_register" "")
9273 (compare
9274 (if_then_else:SI
9275 (match_operator 4 "arm_comparison_operator"
9276 [(match_operand:SI 0 "s_register_operand"
9277 "l,l,l,r,r,r,r,r,r")
9278 (match_operand:SI 1 "arm_add_operand"
9279 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9280 (match_operator:SI 5 "arm_comparison_operator"
9281 [(match_operand:SI 2 "s_register_operand"
9282 "l,r,r,l,l,r,r,r,r")
9283 (match_operand:SI 3 "arm_add_operand"
9284 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9285 (const_int 1))
9286 (const_int 0)))]
9287 "TARGET_32BIT"
9288 "*
9289 {
9290 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9291 {
9292 {\"cmp\\t%0, %1\",
9293 \"cmp\\t%2, %3\"},
9294 {\"cmn\\t%0, #%n1\",
9295 \"cmp\\t%2, %3\"},
9296 {\"cmp\\t%0, %1\",
9297 \"cmn\\t%2, #%n3\"},
9298 {\"cmn\\t%0, #%n1\",
9299 \"cmn\\t%2, #%n3\"}
9300 };
9301 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9302 {
9303 {\"cmp%d4\\t%2, %3\",
9304 \"cmp%D5\\t%0, %1\"},
9305 {\"cmp%d4\\t%2, %3\",
9306 \"cmn%D5\\t%0, #%n1\"},
9307 {\"cmn%d4\\t%2, #%n3\",
9308 \"cmp%D5\\t%0, %1\"},
9309 {\"cmn%d4\\t%2, #%n3\",
9310 \"cmn%D5\\t%0, #%n1\"}
9311 };
9312 static const char * const ite[2] =
9313 {
9314 \"it\\t%d4\",
9315 \"it\\t%D5\"
9316 };
9317 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9318 CMP_CMP, CMN_CMP, CMP_CMP,
9319 CMN_CMP, CMP_CMN, CMN_CMN};
9320 int swap =
9321 comparison_dominates_p (GET_CODE (operands[5]),
9322 reverse_condition (GET_CODE (operands[4])));
9323
9324 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9325 if (TARGET_THUMB2) {
9326 output_asm_insn (ite[swap], operands);
9327 }
9328 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9329 return \"\";
9330 }"
9331 [(set_attr "conds" "set")
9332 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9333 (set_attr_alternative "length"
9334 [(const_int 6)
9335 (const_int 8)
9336 (const_int 8)
9337 (const_int 8)
9338 (const_int 8)
9339 (if_then_else (eq_attr "is_thumb" "no")
9340 (const_int 8)
9341 (const_int 10))
9342 (if_then_else (eq_attr "is_thumb" "no")
9343 (const_int 8)
9344 (const_int 10))
9345 (if_then_else (eq_attr "is_thumb" "no")
9346 (const_int 8)
9347 (const_int 10))
9348 (if_then_else (eq_attr "is_thumb" "no")
9349 (const_int 8)
9350 (const_int 10))])
9351 (set_attr "type" "multiple")]
9352 )
9353
9354 (define_insn "*cmp_and"
9355 [(set (match_operand 6 "dominant_cc_register" "")
9356 (compare
9357 (and:SI
9358 (match_operator 4 "arm_comparison_operator"
9359 [(match_operand:SI 0 "s_register_operand"
9360 "l,l,l,r,r,r,r,r,r")
9361 (match_operand:SI 1 "arm_add_operand"
9362 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9363 (match_operator:SI 5 "arm_comparison_operator"
9364 [(match_operand:SI 2 "s_register_operand"
9365 "l,r,r,l,l,r,r,r,r")
9366 (match_operand:SI 3 "arm_add_operand"
9367 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9368 (const_int 0)))]
9369 "TARGET_32BIT"
9370 "*
9371 {
9372 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9373 {
9374 {\"cmp%d5\\t%0, %1\",
9375 \"cmp%d4\\t%2, %3\"},
9376 {\"cmn%d5\\t%0, #%n1\",
9377 \"cmp%d4\\t%2, %3\"},
9378 {\"cmp%d5\\t%0, %1\",
9379 \"cmn%d4\\t%2, #%n3\"},
9380 {\"cmn%d5\\t%0, #%n1\",
9381 \"cmn%d4\\t%2, #%n3\"}
9382 };
9383 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9384 {
9385 {\"cmp\\t%2, %3\",
9386 \"cmp\\t%0, %1\"},
9387 {\"cmp\\t%2, %3\",
9388 \"cmn\\t%0, #%n1\"},
9389 {\"cmn\\t%2, #%n3\",
9390 \"cmp\\t%0, %1\"},
9391 {\"cmn\\t%2, #%n3\",
9392 \"cmn\\t%0, #%n1\"}
9393 };
9394 static const char *const ite[2] =
9395 {
9396 \"it\\t%d5\",
9397 \"it\\t%d4\"
9398 };
9399 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9400 CMP_CMP, CMN_CMP, CMP_CMP,
9401 CMN_CMP, CMP_CMN, CMN_CMN};
9402 int swap =
9403 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9404
9405 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9406 if (TARGET_THUMB2) {
9407 output_asm_insn (ite[swap], operands);
9408 }
9409 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9410 return \"\";
9411 }"
9412 [(set_attr "conds" "set")
9413 (set_attr "predicable" "no")
9414 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9415 (set_attr_alternative "length"
9416 [(const_int 6)
9417 (const_int 8)
9418 (const_int 8)
9419 (const_int 8)
9420 (const_int 8)
9421 (if_then_else (eq_attr "is_thumb" "no")
9422 (const_int 8)
9423 (const_int 10))
9424 (if_then_else (eq_attr "is_thumb" "no")
9425 (const_int 8)
9426 (const_int 10))
9427 (if_then_else (eq_attr "is_thumb" "no")
9428 (const_int 8)
9429 (const_int 10))
9430 (if_then_else (eq_attr "is_thumb" "no")
9431 (const_int 8)
9432 (const_int 10))])
9433 (set_attr "type" "multiple")]
9434 )
9435
9436 (define_insn "*cmp_ior"
9437 [(set (match_operand 6 "dominant_cc_register" "")
9438 (compare
9439 (ior:SI
9440 (match_operator 4 "arm_comparison_operator"
9441 [(match_operand:SI 0 "s_register_operand"
9442 "l,l,l,r,r,r,r,r,r")
9443 (match_operand:SI 1 "arm_add_operand"
9444 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9445 (match_operator:SI 5 "arm_comparison_operator"
9446 [(match_operand:SI 2 "s_register_operand"
9447 "l,r,r,l,l,r,r,r,r")
9448 (match_operand:SI 3 "arm_add_operand"
9449 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9450 (const_int 0)))]
9451 "TARGET_32BIT"
9452 "*
9453 {
9454 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9455 {
9456 {\"cmp\\t%0, %1\",
9457 \"cmp\\t%2, %3\"},
9458 {\"cmn\\t%0, #%n1\",
9459 \"cmp\\t%2, %3\"},
9460 {\"cmp\\t%0, %1\",
9461 \"cmn\\t%2, #%n3\"},
9462 {\"cmn\\t%0, #%n1\",
9463 \"cmn\\t%2, #%n3\"}
9464 };
9465 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9466 {
9467 {\"cmp%D4\\t%2, %3\",
9468 \"cmp%D5\\t%0, %1\"},
9469 {\"cmp%D4\\t%2, %3\",
9470 \"cmn%D5\\t%0, #%n1\"},
9471 {\"cmn%D4\\t%2, #%n3\",
9472 \"cmp%D5\\t%0, %1\"},
9473 {\"cmn%D4\\t%2, #%n3\",
9474 \"cmn%D5\\t%0, #%n1\"}
9475 };
9476 static const char *const ite[2] =
9477 {
9478 \"it\\t%D4\",
9479 \"it\\t%D5\"
9480 };
9481 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9482 CMP_CMP, CMN_CMP, CMP_CMP,
9483 CMN_CMP, CMP_CMN, CMN_CMN};
9484 int swap =
9485 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9486
9487 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9488 if (TARGET_THUMB2) {
9489 output_asm_insn (ite[swap], operands);
9490 }
9491 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9492 return \"\";
9493 }
9494 "
9495 [(set_attr "conds" "set")
9496 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9497 (set_attr_alternative "length"
9498 [(const_int 6)
9499 (const_int 8)
9500 (const_int 8)
9501 (const_int 8)
9502 (const_int 8)
9503 (if_then_else (eq_attr "is_thumb" "no")
9504 (const_int 8)
9505 (const_int 10))
9506 (if_then_else (eq_attr "is_thumb" "no")
9507 (const_int 8)
9508 (const_int 10))
9509 (if_then_else (eq_attr "is_thumb" "no")
9510 (const_int 8)
9511 (const_int 10))
9512 (if_then_else (eq_attr "is_thumb" "no")
9513 (const_int 8)
9514 (const_int 10))])
9515 (set_attr "type" "multiple")]
9516 )
9517
9518 (define_insn_and_split "*ior_scc_scc"
9519 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9520 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9521 [(match_operand:SI 1 "s_register_operand" "r")
9522 (match_operand:SI 2 "arm_add_operand" "rIL")])
9523 (match_operator:SI 6 "arm_comparison_operator"
9524 [(match_operand:SI 4 "s_register_operand" "r")
9525 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9526 (clobber (reg:CC CC_REGNUM))]
9527 "TARGET_32BIT
9528 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9529 != CCmode)"
9530 "#"
9531 "TARGET_32BIT && reload_completed"
9532 [(set (match_dup 7)
9533 (compare
9534 (ior:SI
9535 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9536 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9537 (const_int 0)))
9538 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9539 "operands[7]
9540 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9541 DOM_CC_X_OR_Y),
9542 CC_REGNUM);"
9543 [(set_attr "conds" "clob")
9544 (set_attr "length" "16")
9545 (set_attr "type" "multiple")]
9546 )
9547
9548 ; If the above pattern is followed by a CMP insn, then the compare is
9549 ; redundant, since we can rework the conditional instruction that follows.
9550 (define_insn_and_split "*ior_scc_scc_cmp"
9551 [(set (match_operand 0 "dominant_cc_register" "")
9552 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9553 [(match_operand:SI 1 "s_register_operand" "r")
9554 (match_operand:SI 2 "arm_add_operand" "rIL")])
9555 (match_operator:SI 6 "arm_comparison_operator"
9556 [(match_operand:SI 4 "s_register_operand" "r")
9557 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9558 (const_int 0)))
9559 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9560 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9561 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9562 "TARGET_32BIT"
9563 "#"
9564 "TARGET_32BIT && reload_completed"
9565 [(set (match_dup 0)
9566 (compare
9567 (ior:SI
9568 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9569 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9570 (const_int 0)))
9571 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9572 ""
9573 [(set_attr "conds" "set")
9574 (set_attr "length" "16")
9575 (set_attr "type" "multiple")]
9576 )
9577
9578 (define_insn_and_split "*and_scc_scc"
9579 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9580 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9581 [(match_operand:SI 1 "s_register_operand" "r")
9582 (match_operand:SI 2 "arm_add_operand" "rIL")])
9583 (match_operator:SI 6 "arm_comparison_operator"
9584 [(match_operand:SI 4 "s_register_operand" "r")
9585 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9586 (clobber (reg:CC CC_REGNUM))]
9587 "TARGET_32BIT
9588 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9589 != CCmode)"
9590 "#"
9591 "TARGET_32BIT && reload_completed
9592 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9593 != CCmode)"
9594 [(set (match_dup 7)
9595 (compare
9596 (and:SI
9597 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9598 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9599 (const_int 0)))
9600 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9601 "operands[7]
9602 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9603 DOM_CC_X_AND_Y),
9604 CC_REGNUM);"
9605 [(set_attr "conds" "clob")
9606 (set_attr "length" "16")
9607 (set_attr "type" "multiple")]
9608 )
9609
9610 ; If the above pattern is followed by a CMP insn, then the compare is
9611 ; redundant, since we can rework the conditional instruction that follows.
9612 (define_insn_and_split "*and_scc_scc_cmp"
9613 [(set (match_operand 0 "dominant_cc_register" "")
9614 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9615 [(match_operand:SI 1 "s_register_operand" "r")
9616 (match_operand:SI 2 "arm_add_operand" "rIL")])
9617 (match_operator:SI 6 "arm_comparison_operator"
9618 [(match_operand:SI 4 "s_register_operand" "r")
9619 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9620 (const_int 0)))
9621 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9622 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9623 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9624 "TARGET_32BIT"
9625 "#"
9626 "TARGET_32BIT && reload_completed"
9627 [(set (match_dup 0)
9628 (compare
9629 (and:SI
9630 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9631 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9632 (const_int 0)))
9633 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9634 ""
9635 [(set_attr "conds" "set")
9636 (set_attr "length" "16")
9637 (set_attr "type" "multiple")]
9638 )
9639
9640 ;; If there is no dominance in the comparison, then we can still save an
9641 ;; instruction in the AND case, since we can know that the second compare
9642 ;; need only zero the value if false (if true, then the value is already
9643 ;; correct).
9644 (define_insn_and_split "*and_scc_scc_nodom"
9645 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9646 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9647 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9648 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9649 (match_operator:SI 6 "arm_comparison_operator"
9650 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9651 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9652 (clobber (reg:CC CC_REGNUM))]
9653 "TARGET_32BIT
9654 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9655 == CCmode)"
9656 "#"
9657 "TARGET_32BIT && reload_completed"
9658 [(parallel [(set (match_dup 0)
9659 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9660 (clobber (reg:CC CC_REGNUM))])
9661 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9662 (set (match_dup 0)
9663 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9664 (match_dup 0)
9665 (const_int 0)))]
9666 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9667 operands[4], operands[5]),
9668 CC_REGNUM);
9669 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9670 operands[5]);"
9671 [(set_attr "conds" "clob")
9672 (set_attr "length" "20")
9673 (set_attr "type" "multiple")]
9674 )
9675
9676 (define_split
9677 [(set (reg:CC_NOOV CC_REGNUM)
9678 (compare:CC_NOOV (ior:SI
9679 (and:SI (match_operand:SI 0 "s_register_operand" "")
9680 (const_int 1))
9681 (match_operator:SI 1 "arm_comparison_operator"
9682 [(match_operand:SI 2 "s_register_operand" "")
9683 (match_operand:SI 3 "arm_add_operand" "")]))
9684 (const_int 0)))
9685 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9686 "TARGET_ARM"
9687 [(set (match_dup 4)
9688 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9689 (match_dup 0)))
9690 (set (reg:CC_NOOV CC_REGNUM)
9691 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9692 (const_int 0)))]
9693 "")
9694
9695 (define_split
9696 [(set (reg:CC_NOOV CC_REGNUM)
9697 (compare:CC_NOOV (ior:SI
9698 (match_operator:SI 1 "arm_comparison_operator"
9699 [(match_operand:SI 2 "s_register_operand" "")
9700 (match_operand:SI 3 "arm_add_operand" "")])
9701 (and:SI (match_operand:SI 0 "s_register_operand" "")
9702 (const_int 1)))
9703 (const_int 0)))
9704 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9705 "TARGET_ARM"
9706 [(set (match_dup 4)
9707 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9708 (match_dup 0)))
9709 (set (reg:CC_NOOV CC_REGNUM)
9710 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9711 (const_int 0)))]
9712 "")
9713 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9714
9715 (define_insn_and_split "*negscc"
9716 [(set (match_operand:SI 0 "s_register_operand" "=r")
9717 (neg:SI (match_operator 3 "arm_comparison_operator"
9718 [(match_operand:SI 1 "s_register_operand" "r")
9719 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9720 (clobber (reg:CC CC_REGNUM))]
9721 "TARGET_ARM"
9722 "#"
9723 "&& reload_completed"
9724 [(const_int 0)]
9725 {
9726 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9727
9728 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9729 {
9730 /* Emit mov\\t%0, %1, asr #31 */
9731 emit_insn (gen_rtx_SET (operands[0],
9732 gen_rtx_ASHIFTRT (SImode,
9733 operands[1],
9734 GEN_INT (31))));
9735 DONE;
9736 }
9737 else if (GET_CODE (operands[3]) == NE)
9738 {
9739 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9740 if (CONST_INT_P (operands[2]))
9741 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9742 GEN_INT (- INTVAL (operands[2]))));
9743 else
9744 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9745
9746 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9747 gen_rtx_NE (SImode,
9748 cc_reg,
9749 const0_rtx),
9750 gen_rtx_SET (operands[0],
9751 GEN_INT (~0))));
9752 DONE;
9753 }
9754 else
9755 {
9756 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9757 emit_insn (gen_rtx_SET (cc_reg,
9758 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9759 enum rtx_code rc = GET_CODE (operands[3]);
9760
9761 rc = reverse_condition (rc);
9762 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9763 gen_rtx_fmt_ee (rc,
9764 VOIDmode,
9765 cc_reg,
9766 const0_rtx),
9767 gen_rtx_SET (operands[0], const0_rtx)));
9768 rc = GET_CODE (operands[3]);
9769 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9770 gen_rtx_fmt_ee (rc,
9771 VOIDmode,
9772 cc_reg,
9773 const0_rtx),
9774 gen_rtx_SET (operands[0],
9775 GEN_INT (~0))));
9776 DONE;
9777 }
9778 FAIL;
9779 }
9780 [(set_attr "conds" "clob")
9781 (set_attr "length" "12")
9782 (set_attr "type" "multiple")]
9783 )
9784
9785 (define_insn_and_split "movcond_addsi"
9786 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9787 (if_then_else:SI
9788 (match_operator 5 "comparison_operator"
9789 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9790 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9791 (const_int 0)])
9792 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9793 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9794 (clobber (reg:CC CC_REGNUM))]
9795 "TARGET_32BIT"
9796 "#"
9797 "&& reload_completed"
9798 [(set (reg:CC_NOOV CC_REGNUM)
9799 (compare:CC_NOOV
9800 (plus:SI (match_dup 3)
9801 (match_dup 4))
9802 (const_int 0)))
9803 (set (match_dup 0) (match_dup 1))
9804 (cond_exec (match_dup 6)
9805 (set (match_dup 0) (match_dup 2)))]
9806 "
9807 {
9808 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9809 operands[3], operands[4]);
9810 enum rtx_code rc = GET_CODE (operands[5]);
9811 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9812 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9813 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9814 rc = reverse_condition (rc);
9815 else
9816 std::swap (operands[1], operands[2]);
9817
9818 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9819 }
9820 "
9821 [(set_attr "conds" "clob")
9822 (set_attr "enabled_for_depr_it" "no,yes,yes")
9823 (set_attr "type" "multiple")]
9824 )
9825
9826 (define_insn "movcond"
9827 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9828 (if_then_else:SI
9829 (match_operator 5 "arm_comparison_operator"
9830 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9831 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9832 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9833 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9834 (clobber (reg:CC CC_REGNUM))]
9835 "TARGET_ARM"
9836 "*
9837 if (GET_CODE (operands[5]) == LT
9838 && (operands[4] == const0_rtx))
9839 {
9840 if (which_alternative != 1 && REG_P (operands[1]))
9841 {
9842 if (operands[2] == const0_rtx)
9843 return \"and\\t%0, %1, %3, asr #31\";
9844 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9845 }
9846 else if (which_alternative != 0 && REG_P (operands[2]))
9847 {
9848 if (operands[1] == const0_rtx)
9849 return \"bic\\t%0, %2, %3, asr #31\";
9850 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9851 }
9852 /* The only case that falls through to here is when both ops 1 & 2
9853 are constants. */
9854 }
9855
9856 if (GET_CODE (operands[5]) == GE
9857 && (operands[4] == const0_rtx))
9858 {
9859 if (which_alternative != 1 && REG_P (operands[1]))
9860 {
9861 if (operands[2] == const0_rtx)
9862 return \"bic\\t%0, %1, %3, asr #31\";
9863 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9864 }
9865 else if (which_alternative != 0 && REG_P (operands[2]))
9866 {
9867 if (operands[1] == const0_rtx)
9868 return \"and\\t%0, %2, %3, asr #31\";
9869 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9870 }
9871 /* The only case that falls through to here is when both ops 1 & 2
9872 are constants. */
9873 }
9874 if (CONST_INT_P (operands[4])
9875 && !const_ok_for_arm (INTVAL (operands[4])))
9876 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9877 else
9878 output_asm_insn (\"cmp\\t%3, %4\", operands);
9879 if (which_alternative != 0)
9880 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9881 if (which_alternative != 1)
9882 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9883 return \"\";
9884 "
9885 [(set_attr "conds" "clob")
9886 (set_attr "length" "8,8,12")
9887 (set_attr "type" "multiple")]
9888 )
9889
9890 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9891
9892 (define_insn "*ifcompare_plus_move"
9893 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9894 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9895 [(match_operand:SI 4 "s_register_operand" "r,r")
9896 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9897 (plus:SI
9898 (match_operand:SI 2 "s_register_operand" "r,r")
9899 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9900 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9901 (clobber (reg:CC CC_REGNUM))]
9902 "TARGET_ARM"
9903 "#"
9904 [(set_attr "conds" "clob")
9905 (set_attr "length" "8,12")
9906 (set_attr "type" "multiple")]
9907 )
9908
9909 (define_insn "*if_plus_move"
9910 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9911 (if_then_else:SI
9912 (match_operator 4 "arm_comparison_operator"
9913 [(match_operand 5 "cc_register" "") (const_int 0)])
9914 (plus:SI
9915 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9916 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9917 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9918 "TARGET_ARM"
9919 "@
9920 add%d4\\t%0, %2, %3
9921 sub%d4\\t%0, %2, #%n3
9922 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9923 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9924 [(set_attr "conds" "use")
9925 (set_attr "length" "4,4,8,8")
9926 (set_attr_alternative "type"
9927 [(if_then_else (match_operand 3 "const_int_operand" "")
9928 (const_string "alu_imm" )
9929 (const_string "alu_sreg"))
9930 (const_string "alu_imm")
9931 (const_string "multiple")
9932 (const_string "multiple")])]
9933 )
9934
9935 (define_insn "*ifcompare_move_plus"
9936 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9937 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9938 [(match_operand:SI 4 "s_register_operand" "r,r")
9939 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9940 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9941 (plus:SI
9942 (match_operand:SI 2 "s_register_operand" "r,r")
9943 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9944 (clobber (reg:CC CC_REGNUM))]
9945 "TARGET_ARM"
9946 "#"
9947 [(set_attr "conds" "clob")
9948 (set_attr "length" "8,12")
9949 (set_attr "type" "multiple")]
9950 )
9951
9952 (define_insn "*if_move_plus"
9953 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9954 (if_then_else:SI
9955 (match_operator 4 "arm_comparison_operator"
9956 [(match_operand 5 "cc_register" "") (const_int 0)])
9957 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9958 (plus:SI
9959 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9960 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9961 "TARGET_ARM"
9962 "@
9963 add%D4\\t%0, %2, %3
9964 sub%D4\\t%0, %2, #%n3
9965 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9966 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9967 [(set_attr "conds" "use")
9968 (set_attr "length" "4,4,8,8")
9969 (set_attr_alternative "type"
9970 [(if_then_else (match_operand 3 "const_int_operand" "")
9971 (const_string "alu_imm" )
9972 (const_string "alu_sreg"))
9973 (const_string "alu_imm")
9974 (const_string "multiple")
9975 (const_string "multiple")])]
9976 )
9977
9978 (define_insn "*ifcompare_arith_arith"
9979 [(set (match_operand:SI 0 "s_register_operand" "=r")
9980 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9981 [(match_operand:SI 5 "s_register_operand" "r")
9982 (match_operand:SI 6 "arm_add_operand" "rIL")])
9983 (match_operator:SI 8 "shiftable_operator"
9984 [(match_operand:SI 1 "s_register_operand" "r")
9985 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9986 (match_operator:SI 7 "shiftable_operator"
9987 [(match_operand:SI 3 "s_register_operand" "r")
9988 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9989 (clobber (reg:CC CC_REGNUM))]
9990 "TARGET_ARM"
9991 "#"
9992 [(set_attr "conds" "clob")
9993 (set_attr "length" "12")
9994 (set_attr "type" "multiple")]
9995 )
9996
9997 (define_insn "*if_arith_arith"
9998 [(set (match_operand:SI 0 "s_register_operand" "=r")
9999 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10000 [(match_operand 8 "cc_register" "") (const_int 0)])
10001 (match_operator:SI 6 "shiftable_operator"
10002 [(match_operand:SI 1 "s_register_operand" "r")
10003 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10004 (match_operator:SI 7 "shiftable_operator"
10005 [(match_operand:SI 3 "s_register_operand" "r")
10006 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10007 "TARGET_ARM"
10008 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10009 [(set_attr "conds" "use")
10010 (set_attr "length" "8")
10011 (set_attr "type" "multiple")]
10012 )
10013
10014 (define_insn "*ifcompare_arith_move"
10015 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10016 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10017 [(match_operand:SI 2 "s_register_operand" "r,r")
10018 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10019 (match_operator:SI 7 "shiftable_operator"
10020 [(match_operand:SI 4 "s_register_operand" "r,r")
10021 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10022 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10023 (clobber (reg:CC CC_REGNUM))]
10024 "TARGET_ARM"
10025 "*
10026 /* If we have an operation where (op x 0) is the identity operation and
10027 the conditional operator is LT or GE and we are comparing against zero and
10028 everything is in registers then we can do this in two instructions. */
10029 if (operands[3] == const0_rtx
10030 && GET_CODE (operands[7]) != AND
10031 && REG_P (operands[5])
10032 && REG_P (operands[1])
10033 && REGNO (operands[1]) == REGNO (operands[4])
10034 && REGNO (operands[4]) != REGNO (operands[0]))
10035 {
10036 if (GET_CODE (operands[6]) == LT)
10037 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10038 else if (GET_CODE (operands[6]) == GE)
10039 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10040 }
10041 if (CONST_INT_P (operands[3])
10042 && !const_ok_for_arm (INTVAL (operands[3])))
10043 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10044 else
10045 output_asm_insn (\"cmp\\t%2, %3\", operands);
10046 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10047 if (which_alternative != 0)
10048 return \"mov%D6\\t%0, %1\";
10049 return \"\";
10050 "
10051 [(set_attr "conds" "clob")
10052 (set_attr "length" "8,12")
10053 (set_attr "type" "multiple")]
10054 )
10055
10056 (define_insn "*if_arith_move"
10057 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10058 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10059 [(match_operand 6 "cc_register" "") (const_int 0)])
10060 (match_operator:SI 5 "shiftable_operator"
10061 [(match_operand:SI 2 "s_register_operand" "r,r")
10062 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10063 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10064 "TARGET_ARM"
10065 "@
10066 %I5%d4\\t%0, %2, %3
10067 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10068 [(set_attr "conds" "use")
10069 (set_attr "length" "4,8")
10070 (set_attr_alternative "type"
10071 [(if_then_else (match_operand 3 "const_int_operand" "")
10072 (const_string "alu_shift_imm" )
10073 (const_string "alu_shift_reg"))
10074 (const_string "multiple")])]
10075 )
10076
10077 (define_insn "*ifcompare_move_arith"
10078 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10079 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10080 [(match_operand:SI 4 "s_register_operand" "r,r")
10081 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10082 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10083 (match_operator:SI 7 "shiftable_operator"
10084 [(match_operand:SI 2 "s_register_operand" "r,r")
10085 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10086 (clobber (reg:CC CC_REGNUM))]
10087 "TARGET_ARM"
10088 "*
10089 /* If we have an operation where (op x 0) is the identity operation and
10090 the conditional operator is LT or GE and we are comparing against zero and
10091 everything is in registers then we can do this in two instructions */
10092 if (operands[5] == const0_rtx
10093 && GET_CODE (operands[7]) != AND
10094 && REG_P (operands[3])
10095 && REG_P (operands[1])
10096 && REGNO (operands[1]) == REGNO (operands[2])
10097 && REGNO (operands[2]) != REGNO (operands[0]))
10098 {
10099 if (GET_CODE (operands[6]) == GE)
10100 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10101 else if (GET_CODE (operands[6]) == LT)
10102 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10103 }
10104
10105 if (CONST_INT_P (operands[5])
10106 && !const_ok_for_arm (INTVAL (operands[5])))
10107 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10108 else
10109 output_asm_insn (\"cmp\\t%4, %5\", operands);
10110
10111 if (which_alternative != 0)
10112 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10113 return \"%I7%D6\\t%0, %2, %3\";
10114 "
10115 [(set_attr "conds" "clob")
10116 (set_attr "length" "8,12")
10117 (set_attr "type" "multiple")]
10118 )
10119
10120 (define_insn "*if_move_arith"
10121 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10122 (if_then_else:SI
10123 (match_operator 4 "arm_comparison_operator"
10124 [(match_operand 6 "cc_register" "") (const_int 0)])
10125 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10126 (match_operator:SI 5 "shiftable_operator"
10127 [(match_operand:SI 2 "s_register_operand" "r,r")
10128 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10129 "TARGET_ARM"
10130 "@
10131 %I5%D4\\t%0, %2, %3
10132 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10133 [(set_attr "conds" "use")
10134 (set_attr "length" "4,8")
10135 (set_attr_alternative "type"
10136 [(if_then_else (match_operand 3 "const_int_operand" "")
10137 (const_string "alu_shift_imm" )
10138 (const_string "alu_shift_reg"))
10139 (const_string "multiple")])]
10140 )
10141
10142 (define_insn "*ifcompare_move_not"
10143 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10144 (if_then_else:SI
10145 (match_operator 5 "arm_comparison_operator"
10146 [(match_operand:SI 3 "s_register_operand" "r,r")
10147 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10148 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10149 (not:SI
10150 (match_operand:SI 2 "s_register_operand" "r,r"))))
10151 (clobber (reg:CC CC_REGNUM))]
10152 "TARGET_ARM"
10153 "#"
10154 [(set_attr "conds" "clob")
10155 (set_attr "length" "8,12")
10156 (set_attr "type" "multiple")]
10157 )
10158
10159 (define_insn "*if_move_not"
10160 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10161 (if_then_else:SI
10162 (match_operator 4 "arm_comparison_operator"
10163 [(match_operand 3 "cc_register" "") (const_int 0)])
10164 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10165 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10166 "TARGET_ARM"
10167 "@
10168 mvn%D4\\t%0, %2
10169 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10170 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10171 [(set_attr "conds" "use")
10172 (set_attr "type" "mvn_reg")
10173 (set_attr "length" "4,8,8")
10174 (set_attr "type" "mvn_reg,multiple,multiple")]
10175 )
10176
10177 (define_insn "*ifcompare_not_move"
10178 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10179 (if_then_else:SI
10180 (match_operator 5 "arm_comparison_operator"
10181 [(match_operand:SI 3 "s_register_operand" "r,r")
10182 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10183 (not:SI
10184 (match_operand:SI 2 "s_register_operand" "r,r"))
10185 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10186 (clobber (reg:CC CC_REGNUM))]
10187 "TARGET_ARM"
10188 "#"
10189 [(set_attr "conds" "clob")
10190 (set_attr "length" "8,12")
10191 (set_attr "type" "multiple")]
10192 )
10193
10194 (define_insn "*if_not_move"
10195 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10196 (if_then_else:SI
10197 (match_operator 4 "arm_comparison_operator"
10198 [(match_operand 3 "cc_register" "") (const_int 0)])
10199 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10200 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10201 "TARGET_ARM"
10202 "@
10203 mvn%d4\\t%0, %2
10204 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10205 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10206 [(set_attr "conds" "use")
10207 (set_attr "type" "mvn_reg,multiple,multiple")
10208 (set_attr "length" "4,8,8")]
10209 )
10210
10211 (define_insn "*ifcompare_shift_move"
10212 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10213 (if_then_else:SI
10214 (match_operator 6 "arm_comparison_operator"
10215 [(match_operand:SI 4 "s_register_operand" "r,r")
10216 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10217 (match_operator:SI 7 "shift_operator"
10218 [(match_operand:SI 2 "s_register_operand" "r,r")
10219 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10220 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10221 (clobber (reg:CC CC_REGNUM))]
10222 "TARGET_ARM"
10223 "#"
10224 [(set_attr "conds" "clob")
10225 (set_attr "length" "8,12")
10226 (set_attr "type" "multiple")]
10227 )
10228
10229 (define_insn "*if_shift_move"
10230 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10231 (if_then_else:SI
10232 (match_operator 5 "arm_comparison_operator"
10233 [(match_operand 6 "cc_register" "") (const_int 0)])
10234 (match_operator:SI 4 "shift_operator"
10235 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10236 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10237 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10238 "TARGET_ARM"
10239 "@
10240 mov%d5\\t%0, %2%S4
10241 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10242 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10243 [(set_attr "conds" "use")
10244 (set_attr "shift" "2")
10245 (set_attr "length" "4,8,8")
10246 (set_attr_alternative "type"
10247 [(if_then_else (match_operand 3 "const_int_operand" "")
10248 (const_string "mov_shift" )
10249 (const_string "mov_shift_reg"))
10250 (const_string "multiple")
10251 (const_string "multiple")])]
10252 )
10253
10254 (define_insn "*ifcompare_move_shift"
10255 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10256 (if_then_else:SI
10257 (match_operator 6 "arm_comparison_operator"
10258 [(match_operand:SI 4 "s_register_operand" "r,r")
10259 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10260 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10261 (match_operator:SI 7 "shift_operator"
10262 [(match_operand:SI 2 "s_register_operand" "r,r")
10263 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10264 (clobber (reg:CC CC_REGNUM))]
10265 "TARGET_ARM"
10266 "#"
10267 [(set_attr "conds" "clob")
10268 (set_attr "length" "8,12")
10269 (set_attr "type" "multiple")]
10270 )
10271
10272 (define_insn "*if_move_shift"
10273 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10274 (if_then_else:SI
10275 (match_operator 5 "arm_comparison_operator"
10276 [(match_operand 6 "cc_register" "") (const_int 0)])
10277 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10278 (match_operator:SI 4 "shift_operator"
10279 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10280 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10281 "TARGET_ARM"
10282 "@
10283 mov%D5\\t%0, %2%S4
10284 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10285 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10286 [(set_attr "conds" "use")
10287 (set_attr "shift" "2")
10288 (set_attr "length" "4,8,8")
10289 (set_attr_alternative "type"
10290 [(if_then_else (match_operand 3 "const_int_operand" "")
10291 (const_string "mov_shift" )
10292 (const_string "mov_shift_reg"))
10293 (const_string "multiple")
10294 (const_string "multiple")])]
10295 )
10296
10297 (define_insn "*ifcompare_shift_shift"
10298 [(set (match_operand:SI 0 "s_register_operand" "=r")
10299 (if_then_else:SI
10300 (match_operator 7 "arm_comparison_operator"
10301 [(match_operand:SI 5 "s_register_operand" "r")
10302 (match_operand:SI 6 "arm_add_operand" "rIL")])
10303 (match_operator:SI 8 "shift_operator"
10304 [(match_operand:SI 1 "s_register_operand" "r")
10305 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10306 (match_operator:SI 9 "shift_operator"
10307 [(match_operand:SI 3 "s_register_operand" "r")
10308 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10309 (clobber (reg:CC CC_REGNUM))]
10310 "TARGET_ARM"
10311 "#"
10312 [(set_attr "conds" "clob")
10313 (set_attr "length" "12")
10314 (set_attr "type" "multiple")]
10315 )
10316
10317 (define_insn "*if_shift_shift"
10318 [(set (match_operand:SI 0 "s_register_operand" "=r")
10319 (if_then_else:SI
10320 (match_operator 5 "arm_comparison_operator"
10321 [(match_operand 8 "cc_register" "") (const_int 0)])
10322 (match_operator:SI 6 "shift_operator"
10323 [(match_operand:SI 1 "s_register_operand" "r")
10324 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10325 (match_operator:SI 7 "shift_operator"
10326 [(match_operand:SI 3 "s_register_operand" "r")
10327 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10328 "TARGET_ARM"
10329 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10330 [(set_attr "conds" "use")
10331 (set_attr "shift" "1")
10332 (set_attr "length" "8")
10333 (set (attr "type") (if_then_else
10334 (and (match_operand 2 "const_int_operand" "")
10335 (match_operand 4 "const_int_operand" ""))
10336 (const_string "mov_shift")
10337 (const_string "mov_shift_reg")))]
10338 )
10339
10340 (define_insn "*ifcompare_not_arith"
10341 [(set (match_operand:SI 0 "s_register_operand" "=r")
10342 (if_then_else:SI
10343 (match_operator 6 "arm_comparison_operator"
10344 [(match_operand:SI 4 "s_register_operand" "r")
10345 (match_operand:SI 5 "arm_add_operand" "rIL")])
10346 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10347 (match_operator:SI 7 "shiftable_operator"
10348 [(match_operand:SI 2 "s_register_operand" "r")
10349 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10350 (clobber (reg:CC CC_REGNUM))]
10351 "TARGET_ARM"
10352 "#"
10353 [(set_attr "conds" "clob")
10354 (set_attr "length" "12")
10355 (set_attr "type" "multiple")]
10356 )
10357
10358 (define_insn "*if_not_arith"
10359 [(set (match_operand:SI 0 "s_register_operand" "=r")
10360 (if_then_else:SI
10361 (match_operator 5 "arm_comparison_operator"
10362 [(match_operand 4 "cc_register" "") (const_int 0)])
10363 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10364 (match_operator:SI 6 "shiftable_operator"
10365 [(match_operand:SI 2 "s_register_operand" "r")
10366 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10367 "TARGET_ARM"
10368 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10369 [(set_attr "conds" "use")
10370 (set_attr "type" "mvn_reg")
10371 (set_attr "length" "8")]
10372 )
10373
10374 (define_insn "*ifcompare_arith_not"
10375 [(set (match_operand:SI 0 "s_register_operand" "=r")
10376 (if_then_else:SI
10377 (match_operator 6 "arm_comparison_operator"
10378 [(match_operand:SI 4 "s_register_operand" "r")
10379 (match_operand:SI 5 "arm_add_operand" "rIL")])
10380 (match_operator:SI 7 "shiftable_operator"
10381 [(match_operand:SI 2 "s_register_operand" "r")
10382 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10383 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10384 (clobber (reg:CC CC_REGNUM))]
10385 "TARGET_ARM"
10386 "#"
10387 [(set_attr "conds" "clob")
10388 (set_attr "length" "12")
10389 (set_attr "type" "multiple")]
10390 )
10391
10392 (define_insn "*if_arith_not"
10393 [(set (match_operand:SI 0 "s_register_operand" "=r")
10394 (if_then_else:SI
10395 (match_operator 5 "arm_comparison_operator"
10396 [(match_operand 4 "cc_register" "") (const_int 0)])
10397 (match_operator:SI 6 "shiftable_operator"
10398 [(match_operand:SI 2 "s_register_operand" "r")
10399 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10400 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10401 "TARGET_ARM"
10402 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10403 [(set_attr "conds" "use")
10404 (set_attr "type" "multiple")
10405 (set_attr "length" "8")]
10406 )
10407
10408 (define_insn "*ifcompare_neg_move"
10409 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10410 (if_then_else:SI
10411 (match_operator 5 "arm_comparison_operator"
10412 [(match_operand:SI 3 "s_register_operand" "r,r")
10413 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10414 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10415 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10416 (clobber (reg:CC CC_REGNUM))]
10417 "TARGET_ARM"
10418 "#"
10419 [(set_attr "conds" "clob")
10420 (set_attr "length" "8,12")
10421 (set_attr "type" "multiple")]
10422 )
10423
10424 (define_insn_and_split "*if_neg_move"
10425 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10426 (if_then_else:SI
10427 (match_operator 4 "arm_comparison_operator"
10428 [(match_operand 3 "cc_register" "") (const_int 0)])
10429 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10430 (match_operand:SI 1 "s_register_operand" "0,0")))]
10431 "TARGET_32BIT"
10432 "#"
10433 "&& reload_completed"
10434 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10435 (set (match_dup 0) (neg:SI (match_dup 2))))]
10436 ""
10437 [(set_attr "conds" "use")
10438 (set_attr "length" "4")
10439 (set_attr "arch" "t2,32")
10440 (set_attr "enabled_for_depr_it" "yes,no")
10441 (set_attr "type" "logic_shift_imm")]
10442 )
10443
10444 (define_insn "*ifcompare_move_neg"
10445 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10446 (if_then_else:SI
10447 (match_operator 5 "arm_comparison_operator"
10448 [(match_operand:SI 3 "s_register_operand" "r,r")
10449 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10450 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10451 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10452 (clobber (reg:CC CC_REGNUM))]
10453 "TARGET_ARM"
10454 "#"
10455 [(set_attr "conds" "clob")
10456 (set_attr "length" "8,12")
10457 (set_attr "type" "multiple")]
10458 )
10459
10460 (define_insn_and_split "*if_move_neg"
10461 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10462 (if_then_else:SI
10463 (match_operator 4 "arm_comparison_operator"
10464 [(match_operand 3 "cc_register" "") (const_int 0)])
10465 (match_operand:SI 1 "s_register_operand" "0,0")
10466 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10467 "TARGET_32BIT"
10468 "#"
10469 "&& reload_completed"
10470 [(cond_exec (match_dup 5)
10471 (set (match_dup 0) (neg:SI (match_dup 2))))]
10472 {
10473 machine_mode mode = GET_MODE (operands[3]);
10474 rtx_code rc = GET_CODE (operands[4]);
10475
10476 if (mode == CCFPmode || mode == CCFPEmode)
10477 rc = reverse_condition_maybe_unordered (rc);
10478 else
10479 rc = reverse_condition (rc);
10480
10481 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10482 }
10483 [(set_attr "conds" "use")
10484 (set_attr "length" "4")
10485 (set_attr "arch" "t2,32")
10486 (set_attr "enabled_for_depr_it" "yes,no")
10487 (set_attr "type" "logic_shift_imm")]
10488 )
10489
10490 (define_insn "*arith_adjacentmem"
10491 [(set (match_operand:SI 0 "s_register_operand" "=r")
10492 (match_operator:SI 1 "shiftable_operator"
10493 [(match_operand:SI 2 "memory_operand" "m")
10494 (match_operand:SI 3 "memory_operand" "m")]))
10495 (clobber (match_scratch:SI 4 "=r"))]
10496 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10497 "*
10498 {
10499 rtx ldm[3];
10500 rtx arith[4];
10501 rtx base_reg;
10502 HOST_WIDE_INT val1 = 0, val2 = 0;
10503
10504 if (REGNO (operands[0]) > REGNO (operands[4]))
10505 {
10506 ldm[1] = operands[4];
10507 ldm[2] = operands[0];
10508 }
10509 else
10510 {
10511 ldm[1] = operands[0];
10512 ldm[2] = operands[4];
10513 }
10514
10515 base_reg = XEXP (operands[2], 0);
10516
10517 if (!REG_P (base_reg))
10518 {
10519 val1 = INTVAL (XEXP (base_reg, 1));
10520 base_reg = XEXP (base_reg, 0);
10521 }
10522
10523 if (!REG_P (XEXP (operands[3], 0)))
10524 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10525
10526 arith[0] = operands[0];
10527 arith[3] = operands[1];
10528
10529 if (val1 < val2)
10530 {
10531 arith[1] = ldm[1];
10532 arith[2] = ldm[2];
10533 }
10534 else
10535 {
10536 arith[1] = ldm[2];
10537 arith[2] = ldm[1];
10538 }
10539
10540 ldm[0] = base_reg;
10541 if (val1 !=0 && val2 != 0)
10542 {
10543 rtx ops[3];
10544
10545 if (val1 == 4 || val2 == 4)
10546 /* Other val must be 8, since we know they are adjacent and neither
10547 is zero. */
10548 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10549 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10550 {
10551 ldm[0] = ops[0] = operands[4];
10552 ops[1] = base_reg;
10553 ops[2] = GEN_INT (val1);
10554 output_add_immediate (ops);
10555 if (val1 < val2)
10556 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10557 else
10558 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10559 }
10560 else
10561 {
10562 /* Offset is out of range for a single add, so use two ldr. */
10563 ops[0] = ldm[1];
10564 ops[1] = base_reg;
10565 ops[2] = GEN_INT (val1);
10566 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10567 ops[0] = ldm[2];
10568 ops[2] = GEN_INT (val2);
10569 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10570 }
10571 }
10572 else if (val1 != 0)
10573 {
10574 if (val1 < val2)
10575 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10576 else
10577 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10578 }
10579 else
10580 {
10581 if (val1 < val2)
10582 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10583 else
10584 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10585 }
10586 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10587 return \"\";
10588 }"
10589 [(set_attr "length" "12")
10590 (set_attr "predicable" "yes")
10591 (set_attr "type" "load1")]
10592 )
10593
10594 ; This pattern is never tried by combine, so do it as a peephole
10595
10596 (define_peephole2
10597 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10598 (match_operand:SI 1 "arm_general_register_operand" ""))
10599 (set (reg:CC CC_REGNUM)
10600 (compare:CC (match_dup 1) (const_int 0)))]
10601 "TARGET_ARM"
10602 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10603 (set (match_dup 0) (match_dup 1))])]
10604 ""
10605 )
10606
10607 (define_split
10608 [(set (match_operand:SI 0 "s_register_operand" "")
10609 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10610 (const_int 0))
10611 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10612 [(match_operand:SI 3 "s_register_operand" "")
10613 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10614 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10615 "TARGET_ARM"
10616 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10617 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10618 (match_dup 5)))]
10619 ""
10620 )
10621
10622 ;; This split can be used because CC_Z mode implies that the following
10623 ;; branch will be an equality, or an unsigned inequality, so the sign
10624 ;; extension is not needed.
10625
10626 (define_split
10627 [(set (reg:CC_Z CC_REGNUM)
10628 (compare:CC_Z
10629 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10630 (const_int 24))
10631 (match_operand 1 "const_int_operand" "")))
10632 (clobber (match_scratch:SI 2 ""))]
10633 "TARGET_ARM
10634 && ((UINTVAL (operands[1]))
10635 == ((UINTVAL (operands[1])) >> 24) << 24)"
10636 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10637 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10638 "
10639 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10640 "
10641 )
10642 ;; ??? Check the patterns above for Thumb-2 usefulness
10643
10644 (define_expand "prologue"
10645 [(clobber (const_int 0))]
10646 "TARGET_EITHER"
10647 "if (TARGET_32BIT)
10648 arm_expand_prologue ();
10649 else
10650 thumb1_expand_prologue ();
10651 DONE;
10652 "
10653 )
10654
10655 (define_expand "epilogue"
10656 [(clobber (const_int 0))]
10657 "TARGET_EITHER"
10658 "
10659 if (crtl->calls_eh_return)
10660 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10661 if (TARGET_THUMB1)
10662 {
10663 thumb1_expand_epilogue ();
10664 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10665 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10666 }
10667 else if (HAVE_return)
10668 {
10669 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10670 no need for explicit testing again. */
10671 emit_jump_insn (gen_return ());
10672 }
10673 else if (TARGET_32BIT)
10674 {
10675 arm_expand_epilogue (true);
10676 }
10677 DONE;
10678 "
10679 )
10680
10681 ;; Note - although unspec_volatile's USE all hard registers,
10682 ;; USEs are ignored after relaod has completed. Thus we need
10683 ;; to add an unspec of the link register to ensure that flow
10684 ;; does not think that it is unused by the sibcall branch that
10685 ;; will replace the standard function epilogue.
10686 (define_expand "sibcall_epilogue"
10687 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10688 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10689 "TARGET_32BIT"
10690 "
10691 arm_expand_epilogue (false);
10692 DONE;
10693 "
10694 )
10695
10696 (define_expand "eh_epilogue"
10697 [(use (match_operand:SI 0 "register_operand" ""))
10698 (use (match_operand:SI 1 "register_operand" ""))
10699 (use (match_operand:SI 2 "register_operand" ""))]
10700 "TARGET_EITHER"
10701 "
10702 {
10703 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10704 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10705 {
10706 rtx ra = gen_rtx_REG (Pmode, 2);
10707
10708 emit_move_insn (ra, operands[2]);
10709 operands[2] = ra;
10710 }
10711 /* This is a hack -- we may have crystalized the function type too
10712 early. */
10713 cfun->machine->func_type = 0;
10714 }"
10715 )
10716
10717 ;; This split is only used during output to reduce the number of patterns
10718 ;; that need assembler instructions adding to them. We allowed the setting
10719 ;; of the conditions to be implicit during rtl generation so that
10720 ;; the conditional compare patterns would work. However this conflicts to
10721 ;; some extent with the conditional data operations, so we have to split them
10722 ;; up again here.
10723
10724 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10725 ;; conditional execution sufficient?
10726
10727 (define_split
10728 [(set (match_operand:SI 0 "s_register_operand" "")
10729 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10730 [(match_operand 2 "" "") (match_operand 3 "" "")])
10731 (match_dup 0)
10732 (match_operand 4 "" "")))
10733 (clobber (reg:CC CC_REGNUM))]
10734 "TARGET_ARM && reload_completed"
10735 [(set (match_dup 5) (match_dup 6))
10736 (cond_exec (match_dup 7)
10737 (set (match_dup 0) (match_dup 4)))]
10738 "
10739 {
10740 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10741 operands[2], operands[3]);
10742 enum rtx_code rc = GET_CODE (operands[1]);
10743
10744 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10745 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10746 if (mode == CCFPmode || mode == CCFPEmode)
10747 rc = reverse_condition_maybe_unordered (rc);
10748 else
10749 rc = reverse_condition (rc);
10750
10751 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10752 }"
10753 )
10754
10755 (define_split
10756 [(set (match_operand:SI 0 "s_register_operand" "")
10757 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10758 [(match_operand 2 "" "") (match_operand 3 "" "")])
10759 (match_operand 4 "" "")
10760 (match_dup 0)))
10761 (clobber (reg:CC CC_REGNUM))]
10762 "TARGET_ARM && reload_completed"
10763 [(set (match_dup 5) (match_dup 6))
10764 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10765 (set (match_dup 0) (match_dup 4)))]
10766 "
10767 {
10768 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10769 operands[2], operands[3]);
10770
10771 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10772 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10773 }"
10774 )
10775
10776 (define_split
10777 [(set (match_operand:SI 0 "s_register_operand" "")
10778 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10779 [(match_operand 2 "" "") (match_operand 3 "" "")])
10780 (match_operand 4 "" "")
10781 (match_operand 5 "" "")))
10782 (clobber (reg:CC CC_REGNUM))]
10783 "TARGET_ARM && reload_completed"
10784 [(set (match_dup 6) (match_dup 7))
10785 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10786 (set (match_dup 0) (match_dup 4)))
10787 (cond_exec (match_dup 8)
10788 (set (match_dup 0) (match_dup 5)))]
10789 "
10790 {
10791 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10792 operands[2], operands[3]);
10793 enum rtx_code rc = GET_CODE (operands[1]);
10794
10795 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10796 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10797 if (mode == CCFPmode || mode == CCFPEmode)
10798 rc = reverse_condition_maybe_unordered (rc);
10799 else
10800 rc = reverse_condition (rc);
10801
10802 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10803 }"
10804 )
10805
10806 (define_split
10807 [(set (match_operand:SI 0 "s_register_operand" "")
10808 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10809 [(match_operand:SI 2 "s_register_operand" "")
10810 (match_operand:SI 3 "arm_add_operand" "")])
10811 (match_operand:SI 4 "arm_rhs_operand" "")
10812 (not:SI
10813 (match_operand:SI 5 "s_register_operand" ""))))
10814 (clobber (reg:CC CC_REGNUM))]
10815 "TARGET_ARM && reload_completed"
10816 [(set (match_dup 6) (match_dup 7))
10817 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10818 (set (match_dup 0) (match_dup 4)))
10819 (cond_exec (match_dup 8)
10820 (set (match_dup 0) (not:SI (match_dup 5))))]
10821 "
10822 {
10823 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10824 operands[2], operands[3]);
10825 enum rtx_code rc = GET_CODE (operands[1]);
10826
10827 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10828 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10829 if (mode == CCFPmode || mode == CCFPEmode)
10830 rc = reverse_condition_maybe_unordered (rc);
10831 else
10832 rc = reverse_condition (rc);
10833
10834 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10835 }"
10836 )
10837
10838 (define_insn "*cond_move_not"
10839 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10840 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10841 [(match_operand 3 "cc_register" "") (const_int 0)])
10842 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10843 (not:SI
10844 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10845 "TARGET_ARM"
10846 "@
10847 mvn%D4\\t%0, %2
10848 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10849 [(set_attr "conds" "use")
10850 (set_attr "type" "mvn_reg,multiple")
10851 (set_attr "length" "4,8")]
10852 )
10853
10854 ;; The next two patterns occur when an AND operation is followed by a
10855 ;; scc insn sequence
10856
10857 (define_insn "*sign_extract_onebit"
10858 [(set (match_operand:SI 0 "s_register_operand" "=r")
10859 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10860 (const_int 1)
10861 (match_operand:SI 2 "const_int_operand" "n")))
10862 (clobber (reg:CC CC_REGNUM))]
10863 "TARGET_ARM"
10864 "*
10865 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10866 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10867 return \"mvnne\\t%0, #0\";
10868 "
10869 [(set_attr "conds" "clob")
10870 (set_attr "length" "8")
10871 (set_attr "type" "multiple")]
10872 )
10873
10874 (define_insn "*not_signextract_onebit"
10875 [(set (match_operand:SI 0 "s_register_operand" "=r")
10876 (not:SI
10877 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10878 (const_int 1)
10879 (match_operand:SI 2 "const_int_operand" "n"))))
10880 (clobber (reg:CC CC_REGNUM))]
10881 "TARGET_ARM"
10882 "*
10883 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10884 output_asm_insn (\"tst\\t%1, %2\", operands);
10885 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10886 return \"movne\\t%0, #0\";
10887 "
10888 [(set_attr "conds" "clob")
10889 (set_attr "length" "12")
10890 (set_attr "type" "multiple")]
10891 )
10892 ;; ??? The above patterns need auditing for Thumb-2
10893
10894 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10895 ;; expressions. For simplicity, the first register is also in the unspec
10896 ;; part.
10897 ;; To avoid the usage of GNU extension, the length attribute is computed
10898 ;; in a C function arm_attr_length_push_multi.
10899 (define_insn "*push_multi"
10900 [(match_parallel 2 "multi_register_push"
10901 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10902 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10903 UNSPEC_PUSH_MULT))])]
10904 ""
10905 "*
10906 {
10907 int num_saves = XVECLEN (operands[2], 0);
10908
10909 /* For the StrongARM at least it is faster to
10910 use STR to store only a single register.
10911 In Thumb mode always use push, and the assembler will pick
10912 something appropriate. */
10913 if (num_saves == 1 && TARGET_ARM)
10914 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10915 else
10916 {
10917 int i;
10918 char pattern[100];
10919
10920 if (TARGET_32BIT)
10921 strcpy (pattern, \"push%?\\t{%1\");
10922 else
10923 strcpy (pattern, \"push\\t{%1\");
10924
10925 for (i = 1; i < num_saves; i++)
10926 {
10927 strcat (pattern, \", %|\");
10928 strcat (pattern,
10929 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10930 }
10931
10932 strcat (pattern, \"}\");
10933 output_asm_insn (pattern, operands);
10934 }
10935
10936 return \"\";
10937 }"
10938 [(set_attr "type" "store4")
10939 (set (attr "length")
10940 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10941 )
10942
10943 (define_insn "stack_tie"
10944 [(set (mem:BLK (scratch))
10945 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10946 (match_operand:SI 1 "s_register_operand" "rk")]
10947 UNSPEC_PRLG_STK))]
10948 ""
10949 ""
10950 [(set_attr "length" "0")
10951 (set_attr "type" "block")]
10952 )
10953
10954 ;; Pop (as used in epilogue RTL)
10955 ;;
10956 (define_insn "*load_multiple_with_writeback"
10957 [(match_parallel 0 "load_multiple_operation"
10958 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10959 (plus:SI (match_dup 1)
10960 (match_operand:SI 2 "const_int_I_operand" "I")))
10961 (set (match_operand:SI 3 "s_register_operand" "=rk")
10962 (mem:SI (match_dup 1)))
10963 ])]
10964 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10965 "*
10966 {
10967 arm_output_multireg_pop (operands, /*return_pc=*/false,
10968 /*cond=*/const_true_rtx,
10969 /*reverse=*/false,
10970 /*update=*/true);
10971 return \"\";
10972 }
10973 "
10974 [(set_attr "type" "load4")
10975 (set_attr "predicable" "yes")
10976 (set (attr "length")
10977 (symbol_ref "arm_attr_length_pop_multi (operands,
10978 /*return_pc=*/false,
10979 /*write_back_p=*/true)"))]
10980 )
10981
10982 ;; Pop with return (as used in epilogue RTL)
10983 ;;
10984 ;; This instruction is generated when the registers are popped at the end of
10985 ;; epilogue. Here, instead of popping the value into LR and then generating
10986 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10987 ;; with (return).
10988 (define_insn "*pop_multiple_with_writeback_and_return"
10989 [(match_parallel 0 "pop_multiple_return"
10990 [(return)
10991 (set (match_operand:SI 1 "s_register_operand" "+rk")
10992 (plus:SI (match_dup 1)
10993 (match_operand:SI 2 "const_int_I_operand" "I")))
10994 (set (match_operand:SI 3 "s_register_operand" "=rk")
10995 (mem:SI (match_dup 1)))
10996 ])]
10997 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10998 "*
10999 {
11000 arm_output_multireg_pop (operands, /*return_pc=*/true,
11001 /*cond=*/const_true_rtx,
11002 /*reverse=*/false,
11003 /*update=*/true);
11004 return \"\";
11005 }
11006 "
11007 [(set_attr "type" "load4")
11008 (set_attr "predicable" "yes")
11009 (set (attr "length")
11010 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11011 /*write_back_p=*/true)"))]
11012 )
11013
11014 (define_insn "*pop_multiple_with_return"
11015 [(match_parallel 0 "pop_multiple_return"
11016 [(return)
11017 (set (match_operand:SI 2 "s_register_operand" "=rk")
11018 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11019 ])]
11020 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11021 "*
11022 {
11023 arm_output_multireg_pop (operands, /*return_pc=*/true,
11024 /*cond=*/const_true_rtx,
11025 /*reverse=*/false,
11026 /*update=*/false);
11027 return \"\";
11028 }
11029 "
11030 [(set_attr "type" "load4")
11031 (set_attr "predicable" "yes")
11032 (set (attr "length")
11033 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11034 /*write_back_p=*/false)"))]
11035 )
11036
11037 ;; Load into PC and return
11038 (define_insn "*ldr_with_return"
11039 [(return)
11040 (set (reg:SI PC_REGNUM)
11041 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11042 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11043 "ldr%?\t%|pc, [%0], #4"
11044 [(set_attr "type" "load1")
11045 (set_attr "predicable" "yes")]
11046 )
11047 ;; Pop for floating point registers (as used in epilogue RTL)
11048 (define_insn "*vfp_pop_multiple_with_writeback"
11049 [(match_parallel 0 "pop_multiple_fp"
11050 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11051 (plus:SI (match_dup 1)
11052 (match_operand:SI 2 "const_int_I_operand" "I")))
11053 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11054 (mem:DF (match_dup 1)))])]
11055 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
11056 "*
11057 {
11058 int num_regs = XVECLEN (operands[0], 0);
11059 char pattern[100];
11060 rtx op_list[2];
11061 strcpy (pattern, \"vldm\\t\");
11062 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11063 strcat (pattern, \"!, {\");
11064 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11065 strcat (pattern, \"%P0\");
11066 if ((num_regs - 1) > 1)
11067 {
11068 strcat (pattern, \"-%P1\");
11069 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11070 }
11071
11072 strcat (pattern, \"}\");
11073 output_asm_insn (pattern, op_list);
11074 return \"\";
11075 }
11076 "
11077 [(set_attr "type" "load4")
11078 (set_attr "conds" "unconditional")
11079 (set_attr "predicable" "no")]
11080 )
11081
11082 ;; Special patterns for dealing with the constant pool
11083
11084 (define_insn "align_4"
11085 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11086 "TARGET_EITHER"
11087 "*
11088 assemble_align (32);
11089 return \"\";
11090 "
11091 [(set_attr "type" "no_insn")]
11092 )
11093
11094 (define_insn "align_8"
11095 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11096 "TARGET_EITHER"
11097 "*
11098 assemble_align (64);
11099 return \"\";
11100 "
11101 [(set_attr "type" "no_insn")]
11102 )
11103
11104 (define_insn "consttable_end"
11105 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11106 "TARGET_EITHER"
11107 "*
11108 making_const_table = FALSE;
11109 return \"\";
11110 "
11111 [(set_attr "type" "no_insn")]
11112 )
11113
11114 (define_insn "consttable_1"
11115 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11116 "TARGET_EITHER"
11117 "*
11118 making_const_table = TRUE;
11119 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11120 assemble_zeros (3);
11121 return \"\";
11122 "
11123 [(set_attr "length" "4")
11124 (set_attr "type" "no_insn")]
11125 )
11126
11127 (define_insn "consttable_2"
11128 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11129 "TARGET_EITHER"
11130 "*
11131 {
11132 rtx x = operands[0];
11133 making_const_table = TRUE;
11134 switch (GET_MODE_CLASS (GET_MODE (x)))
11135 {
11136 case MODE_FLOAT:
11137 arm_emit_fp16_const (x);
11138 break;
11139 default:
11140 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11141 assemble_zeros (2);
11142 break;
11143 }
11144 return \"\";
11145 }"
11146 [(set_attr "length" "4")
11147 (set_attr "type" "no_insn")]
11148 )
11149
11150 (define_insn "consttable_4"
11151 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11152 "TARGET_EITHER"
11153 "*
11154 {
11155 rtx x = operands[0];
11156 making_const_table = TRUE;
11157 switch (GET_MODE_CLASS (GET_MODE (x)))
11158 {
11159 case MODE_FLOAT:
11160 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
11161 BITS_PER_WORD);
11162 break;
11163 default:
11164 /* XXX: Sometimes gcc does something really dumb and ends up with
11165 a HIGH in a constant pool entry, usually because it's trying to
11166 load into a VFP register. We know this will always be used in
11167 combination with a LO_SUM which ignores the high bits, so just
11168 strip off the HIGH. */
11169 if (GET_CODE (x) == HIGH)
11170 x = XEXP (x, 0);
11171 assemble_integer (x, 4, BITS_PER_WORD, 1);
11172 mark_symbol_refs_as_used (x);
11173 break;
11174 }
11175 return \"\";
11176 }"
11177 [(set_attr "length" "4")
11178 (set_attr "type" "no_insn")]
11179 )
11180
11181 (define_insn "consttable_8"
11182 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11183 "TARGET_EITHER"
11184 "*
11185 {
11186 making_const_table = TRUE;
11187 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11188 {
11189 case MODE_FLOAT:
11190 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11191 GET_MODE (operands[0]), BITS_PER_WORD);
11192 break;
11193 default:
11194 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11195 break;
11196 }
11197 return \"\";
11198 }"
11199 [(set_attr "length" "8")
11200 (set_attr "type" "no_insn")]
11201 )
11202
11203 (define_insn "consttable_16"
11204 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11205 "TARGET_EITHER"
11206 "*
11207 {
11208 making_const_table = TRUE;
11209 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11210 {
11211 case MODE_FLOAT:
11212 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11213 GET_MODE (operands[0]), BITS_PER_WORD);
11214 break;
11215 default:
11216 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11217 break;
11218 }
11219 return \"\";
11220 }"
11221 [(set_attr "length" "16")
11222 (set_attr "type" "no_insn")]
11223 )
11224
11225 ;; V5 Instructions,
11226
11227 (define_insn "clzsi2"
11228 [(set (match_operand:SI 0 "s_register_operand" "=r")
11229 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11230 "TARGET_32BIT && arm_arch5"
11231 "clz%?\\t%0, %1"
11232 [(set_attr "predicable" "yes")
11233 (set_attr "predicable_short_it" "no")
11234 (set_attr "type" "clz")])
11235
11236 (define_insn "rbitsi2"
11237 [(set (match_operand:SI 0 "s_register_operand" "=r")
11238 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11239 "TARGET_32BIT && arm_arch_thumb2"
11240 "rbit%?\\t%0, %1"
11241 [(set_attr "predicable" "yes")
11242 (set_attr "predicable_short_it" "no")
11243 (set_attr "type" "clz")])
11244
11245 ;; Keep this as a CTZ expression until after reload and then split
11246 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11247 ;; to fold with any other expression.
11248
11249 (define_insn_and_split "ctzsi2"
11250 [(set (match_operand:SI 0 "s_register_operand" "=r")
11251 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11252 "TARGET_32BIT && arm_arch_thumb2"
11253 "#"
11254 "&& reload_completed"
11255 [(const_int 0)]
11256 "
11257 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11258 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11259 DONE;
11260 ")
11261
11262 ;; V5E instructions.
11263
11264 (define_insn "prefetch"
11265 [(prefetch (match_operand:SI 0 "address_operand" "p")
11266 (match_operand:SI 1 "" "")
11267 (match_operand:SI 2 "" ""))]
11268 "TARGET_32BIT && arm_arch5e"
11269 "pld\\t%a0"
11270 [(set_attr "type" "load1")]
11271 )
11272
11273 ;; General predication pattern
11274
11275 (define_cond_exec
11276 [(match_operator 0 "arm_comparison_operator"
11277 [(match_operand 1 "cc_register" "")
11278 (const_int 0)])]
11279 "TARGET_32BIT
11280 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11281 ""
11282 [(set_attr "predicated" "yes")]
11283 )
11284
11285 (define_insn "force_register_use"
11286 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11287 ""
11288 "%@ %0 needed"
11289 [(set_attr "length" "0")
11290 (set_attr "type" "no_insn")]
11291 )
11292
11293
11294 ;; Patterns for exception handling
11295
11296 (define_expand "eh_return"
11297 [(use (match_operand 0 "general_operand" ""))]
11298 "TARGET_EITHER"
11299 "
11300 {
11301 if (TARGET_32BIT)
11302 emit_insn (gen_arm_eh_return (operands[0]));
11303 else
11304 emit_insn (gen_thumb_eh_return (operands[0]));
11305 DONE;
11306 }"
11307 )
11308
11309 ;; We can't expand this before we know where the link register is stored.
11310 (define_insn_and_split "arm_eh_return"
11311 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11312 VUNSPEC_EH_RETURN)
11313 (clobber (match_scratch:SI 1 "=&r"))]
11314 "TARGET_ARM"
11315 "#"
11316 "&& reload_completed"
11317 [(const_int 0)]
11318 "
11319 {
11320 arm_set_return_address (operands[0], operands[1]);
11321 DONE;
11322 }"
11323 )
11324
11325 \f
11326 ;; TLS support
11327
11328 (define_insn "load_tp_hard"
11329 [(set (match_operand:SI 0 "register_operand" "=r")
11330 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11331 "TARGET_HARD_TP"
11332 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11333 [(set_attr "predicable" "yes")
11334 (set_attr "type" "mrs")]
11335 )
11336
11337 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11338 (define_insn "load_tp_soft"
11339 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11340 (clobber (reg:SI LR_REGNUM))
11341 (clobber (reg:SI IP_REGNUM))
11342 (clobber (reg:CC CC_REGNUM))]
11343 "TARGET_SOFT_TP"
11344 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11345 [(set_attr "conds" "clob")
11346 (set_attr "type" "branch")]
11347 )
11348
11349 ;; tls descriptor call
11350 (define_insn "tlscall"
11351 [(set (reg:SI R0_REGNUM)
11352 (unspec:SI [(reg:SI R0_REGNUM)
11353 (match_operand:SI 0 "" "X")
11354 (match_operand 1 "" "")] UNSPEC_TLS))
11355 (clobber (reg:SI R1_REGNUM))
11356 (clobber (reg:SI LR_REGNUM))
11357 (clobber (reg:SI CC_REGNUM))]
11358 "TARGET_GNU2_TLS"
11359 {
11360 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11361 INTVAL (operands[1]));
11362 return "bl\\t%c0(tlscall)";
11363 }
11364 [(set_attr "conds" "clob")
11365 (set_attr "length" "4")
11366 (set_attr "type" "branch")]
11367 )
11368
11369 ;; For thread pointer builtin
11370 (define_expand "get_thread_pointersi"
11371 [(match_operand:SI 0 "s_register_operand" "=r")]
11372 ""
11373 "
11374 {
11375 arm_load_tp (operands[0]);
11376 DONE;
11377 }")
11378
11379 ;;
11380
11381 ;; We only care about the lower 16 bits of the constant
11382 ;; being inserted into the upper 16 bits of the register.
11383 (define_insn "*arm_movtas_ze"
11384 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11385 (const_int 16)
11386 (const_int 16))
11387 (match_operand:SI 1 "const_int_operand" ""))]
11388 "TARGET_HAVE_MOVT"
11389 "@
11390 movt%?\t%0, %L1
11391 movt\t%0, %L1"
11392 [(set_attr "arch" "32,v8mb")
11393 (set_attr "predicable" "yes")
11394 (set_attr "predicable_short_it" "no")
11395 (set_attr "length" "4")
11396 (set_attr "type" "alu_sreg")]
11397 )
11398
11399 (define_insn "*arm_rev"
11400 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11401 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11402 "arm_arch6"
11403 "@
11404 rev\t%0, %1
11405 rev%?\t%0, %1
11406 rev%?\t%0, %1"
11407 [(set_attr "arch" "t1,t2,32")
11408 (set_attr "length" "2,2,4")
11409 (set_attr "predicable" "no,yes,yes")
11410 (set_attr "predicable_short_it" "no")
11411 (set_attr "type" "rev")]
11412 )
11413
11414 (define_expand "arm_legacy_rev"
11415 [(set (match_operand:SI 2 "s_register_operand" "")
11416 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11417 (const_int 16))
11418 (match_dup 1)))
11419 (set (match_dup 2)
11420 (lshiftrt:SI (match_dup 2)
11421 (const_int 8)))
11422 (set (match_operand:SI 3 "s_register_operand" "")
11423 (rotatert:SI (match_dup 1)
11424 (const_int 8)))
11425 (set (match_dup 2)
11426 (and:SI (match_dup 2)
11427 (const_int -65281)))
11428 (set (match_operand:SI 0 "s_register_operand" "")
11429 (xor:SI (match_dup 3)
11430 (match_dup 2)))]
11431 "TARGET_32BIT"
11432 ""
11433 )
11434
11435 ;; Reuse temporaries to keep register pressure down.
11436 (define_expand "thumb_legacy_rev"
11437 [(set (match_operand:SI 2 "s_register_operand" "")
11438 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11439 (const_int 24)))
11440 (set (match_operand:SI 3 "s_register_operand" "")
11441 (lshiftrt:SI (match_dup 1)
11442 (const_int 24)))
11443 (set (match_dup 3)
11444 (ior:SI (match_dup 3)
11445 (match_dup 2)))
11446 (set (match_operand:SI 4 "s_register_operand" "")
11447 (const_int 16))
11448 (set (match_operand:SI 5 "s_register_operand" "")
11449 (rotatert:SI (match_dup 1)
11450 (match_dup 4)))
11451 (set (match_dup 2)
11452 (ashift:SI (match_dup 5)
11453 (const_int 24)))
11454 (set (match_dup 5)
11455 (lshiftrt:SI (match_dup 5)
11456 (const_int 24)))
11457 (set (match_dup 5)
11458 (ior:SI (match_dup 5)
11459 (match_dup 2)))
11460 (set (match_dup 5)
11461 (rotatert:SI (match_dup 5)
11462 (match_dup 4)))
11463 (set (match_operand:SI 0 "s_register_operand" "")
11464 (ior:SI (match_dup 5)
11465 (match_dup 3)))]
11466 "TARGET_THUMB"
11467 ""
11468 )
11469
11470 ;; ARM-specific expansion of signed mod by power of 2
11471 ;; using conditional negate.
11472 ;; For r0 % n where n is a power of 2 produce:
11473 ;; rsbs r1, r0, #0
11474 ;; and r0, r0, #(n - 1)
11475 ;; and r1, r1, #(n - 1)
11476 ;; rsbpl r0, r1, #0
11477
11478 (define_expand "modsi3"
11479 [(match_operand:SI 0 "register_operand" "")
11480 (match_operand:SI 1 "register_operand" "")
11481 (match_operand:SI 2 "const_int_operand" "")]
11482 "TARGET_32BIT"
11483 {
11484 HOST_WIDE_INT val = INTVAL (operands[2]);
11485
11486 if (val <= 0
11487 || exact_log2 (val) <= 0)
11488 FAIL;
11489
11490 rtx mask = GEN_INT (val - 1);
11491
11492 /* In the special case of x0 % 2 we can do the even shorter:
11493 cmp r0, #0
11494 and r0, r0, #1
11495 rsblt r0, r0, #0. */
11496
11497 if (val == 2)
11498 {
11499 rtx cc_reg = arm_gen_compare_reg (LT,
11500 operands[1], const0_rtx, NULL_RTX);
11501 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11502 rtx masked = gen_reg_rtx (SImode);
11503
11504 emit_insn (gen_andsi3 (masked, operands[1], mask));
11505 emit_move_insn (operands[0],
11506 gen_rtx_IF_THEN_ELSE (SImode, cond,
11507 gen_rtx_NEG (SImode,
11508 masked),
11509 masked));
11510 DONE;
11511 }
11512
11513 rtx neg_op = gen_reg_rtx (SImode);
11514 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11515 operands[1]));
11516
11517 /* Extract the condition register and mode. */
11518 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11519 rtx cc_reg = SET_DEST (cmp);
11520 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11521
11522 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11523
11524 rtx masked_neg = gen_reg_rtx (SImode);
11525 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11526
11527 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11528 during expand does not always work. Do an IF_THEN_ELSE instead. */
11529 emit_move_insn (operands[0],
11530 gen_rtx_IF_THEN_ELSE (SImode, cond,
11531 gen_rtx_NEG (SImode, masked_neg),
11532 operands[0]));
11533
11534
11535 DONE;
11536 }
11537 )
11538
11539 (define_expand "bswapsi2"
11540 [(set (match_operand:SI 0 "s_register_operand" "=r")
11541 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11542 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11543 "
11544 if (!arm_arch6)
11545 {
11546 rtx op2 = gen_reg_rtx (SImode);
11547 rtx op3 = gen_reg_rtx (SImode);
11548
11549 if (TARGET_THUMB)
11550 {
11551 rtx op4 = gen_reg_rtx (SImode);
11552 rtx op5 = gen_reg_rtx (SImode);
11553
11554 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11555 op2, op3, op4, op5));
11556 }
11557 else
11558 {
11559 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11560 op2, op3));
11561 }
11562
11563 DONE;
11564 }
11565 "
11566 )
11567
11568 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11569 ;; and unsigned variants, respectively. For rev16, expose
11570 ;; byte-swapping in the lower 16 bits only.
11571 (define_insn "*arm_revsh"
11572 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11573 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11574 "arm_arch6"
11575 "@
11576 revsh\t%0, %1
11577 revsh%?\t%0, %1
11578 revsh%?\t%0, %1"
11579 [(set_attr "arch" "t1,t2,32")
11580 (set_attr "length" "2,2,4")
11581 (set_attr "type" "rev")]
11582 )
11583
11584 (define_insn "*arm_rev16"
11585 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11586 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11587 "arm_arch6"
11588 "@
11589 rev16\t%0, %1
11590 rev16%?\t%0, %1
11591 rev16%?\t%0, %1"
11592 [(set_attr "arch" "t1,t2,32")
11593 (set_attr "length" "2,2,4")
11594 (set_attr "type" "rev")]
11595 )
11596
11597 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11598 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11599 ;; each valid permutation.
11600
11601 (define_insn "arm_rev16si2"
11602 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11603 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11604 (const_int 8))
11605 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11606 (and:SI (lshiftrt:SI (match_dup 1)
11607 (const_int 8))
11608 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11609 "arm_arch6
11610 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11611 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11612 "rev16\\t%0, %1"
11613 [(set_attr "arch" "t1,t2,32")
11614 (set_attr "length" "2,2,4")
11615 (set_attr "type" "rev")]
11616 )
11617
11618 (define_insn "arm_rev16si2_alt"
11619 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11620 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11621 (const_int 8))
11622 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11623 (and:SI (ashift:SI (match_dup 1)
11624 (const_int 8))
11625 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11626 "arm_arch6
11627 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11628 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11629 "rev16\\t%0, %1"
11630 [(set_attr "arch" "t1,t2,32")
11631 (set_attr "length" "2,2,4")
11632 (set_attr "type" "rev")]
11633 )
11634
11635 (define_expand "bswaphi2"
11636 [(set (match_operand:HI 0 "s_register_operand" "=r")
11637 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11638 "arm_arch6"
11639 ""
11640 )
11641
11642 ;; Patterns for LDRD/STRD in Thumb2 mode
11643
11644 (define_insn "*thumb2_ldrd"
11645 [(set (match_operand:SI 0 "s_register_operand" "=r")
11646 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11647 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11648 (set (match_operand:SI 3 "s_register_operand" "=r")
11649 (mem:SI (plus:SI (match_dup 1)
11650 (match_operand:SI 4 "const_int_operand" ""))))]
11651 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11652 && current_tune->prefer_ldrd_strd
11653 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11654 && (operands_ok_ldrd_strd (operands[0], operands[3],
11655 operands[1], INTVAL (operands[2]),
11656 false, true))"
11657 "ldrd%?\t%0, %3, [%1, %2]"
11658 [(set_attr "type" "load2")
11659 (set_attr "predicable" "yes")
11660 (set_attr "predicable_short_it" "no")])
11661
11662 (define_insn "*thumb2_ldrd_base"
11663 [(set (match_operand:SI 0 "s_register_operand" "=r")
11664 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11665 (set (match_operand:SI 2 "s_register_operand" "=r")
11666 (mem:SI (plus:SI (match_dup 1)
11667 (const_int 4))))]
11668 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11669 && current_tune->prefer_ldrd_strd
11670 && (operands_ok_ldrd_strd (operands[0], operands[2],
11671 operands[1], 0, false, true))"
11672 "ldrd%?\t%0, %2, [%1]"
11673 [(set_attr "type" "load2")
11674 (set_attr "predicable" "yes")
11675 (set_attr "predicable_short_it" "no")])
11676
11677 (define_insn "*thumb2_ldrd_base_neg"
11678 [(set (match_operand:SI 0 "s_register_operand" "=r")
11679 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11680 (const_int -4))))
11681 (set (match_operand:SI 2 "s_register_operand" "=r")
11682 (mem:SI (match_dup 1)))]
11683 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11684 && current_tune->prefer_ldrd_strd
11685 && (operands_ok_ldrd_strd (operands[0], operands[2],
11686 operands[1], -4, false, true))"
11687 "ldrd%?\t%0, %2, [%1, #-4]"
11688 [(set_attr "type" "load2")
11689 (set_attr "predicable" "yes")
11690 (set_attr "predicable_short_it" "no")])
11691
11692 (define_insn "*thumb2_strd"
11693 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11694 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11695 (match_operand:SI 2 "s_register_operand" "r"))
11696 (set (mem:SI (plus:SI (match_dup 0)
11697 (match_operand:SI 3 "const_int_operand" "")))
11698 (match_operand:SI 4 "s_register_operand" "r"))]
11699 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11700 && current_tune->prefer_ldrd_strd
11701 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11702 && (operands_ok_ldrd_strd (operands[2], operands[4],
11703 operands[0], INTVAL (operands[1]),
11704 false, false))"
11705 "strd%?\t%2, %4, [%0, %1]"
11706 [(set_attr "type" "store2")
11707 (set_attr "predicable" "yes")
11708 (set_attr "predicable_short_it" "no")])
11709
11710 (define_insn "*thumb2_strd_base"
11711 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11712 (match_operand:SI 1 "s_register_operand" "r"))
11713 (set (mem:SI (plus:SI (match_dup 0)
11714 (const_int 4)))
11715 (match_operand:SI 2 "s_register_operand" "r"))]
11716 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11717 && current_tune->prefer_ldrd_strd
11718 && (operands_ok_ldrd_strd (operands[1], operands[2],
11719 operands[0], 0, false, false))"
11720 "strd%?\t%1, %2, [%0]"
11721 [(set_attr "type" "store2")
11722 (set_attr "predicable" "yes")
11723 (set_attr "predicable_short_it" "no")])
11724
11725 (define_insn "*thumb2_strd_base_neg"
11726 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11727 (const_int -4)))
11728 (match_operand:SI 1 "s_register_operand" "r"))
11729 (set (mem:SI (match_dup 0))
11730 (match_operand:SI 2 "s_register_operand" "r"))]
11731 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11732 && current_tune->prefer_ldrd_strd
11733 && (operands_ok_ldrd_strd (operands[1], operands[2],
11734 operands[0], -4, false, false))"
11735 "strd%?\t%1, %2, [%0, #-4]"
11736 [(set_attr "type" "store2")
11737 (set_attr "predicable" "yes")
11738 (set_attr "predicable_short_it" "no")])
11739
11740 ;; ARMv8 CRC32 instructions.
11741 (define_insn "<crc_variant>"
11742 [(set (match_operand:SI 0 "s_register_operand" "=r")
11743 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11744 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11745 CRC))]
11746 "TARGET_CRC32"
11747 "<crc_variant>\\t%0, %1, %2"
11748 [(set_attr "type" "crc")
11749 (set_attr "conds" "unconditional")]
11750 )
11751
11752 ;; Load the load/store double peephole optimizations.
11753 (include "ldrdstrd.md")
11754
11755 ;; Load the load/store multiple patterns
11756 (include "ldmstm.md")
11757
11758 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11759 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11760 (define_insn "*load_multiple"
11761 [(match_parallel 0 "load_multiple_operation"
11762 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11763 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11764 ])]
11765 "TARGET_32BIT"
11766 "*
11767 {
11768 arm_output_multireg_pop (operands, /*return_pc=*/false,
11769 /*cond=*/const_true_rtx,
11770 /*reverse=*/false,
11771 /*update=*/false);
11772 return \"\";
11773 }
11774 "
11775 [(set_attr "predicable" "yes")]
11776 )
11777
11778 (define_expand "copysignsf3"
11779 [(match_operand:SF 0 "register_operand")
11780 (match_operand:SF 1 "register_operand")
11781 (match_operand:SF 2 "register_operand")]
11782 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11783 "{
11784 emit_move_insn (operands[0], operands[2]);
11785 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11786 GEN_INT (31), GEN_INT (0),
11787 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11788 DONE;
11789 }"
11790 )
11791
11792 (define_expand "copysigndf3"
11793 [(match_operand:DF 0 "register_operand")
11794 (match_operand:DF 1 "register_operand")
11795 (match_operand:DF 2 "register_operand")]
11796 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11797 "{
11798 rtx op0_low = gen_lowpart (SImode, operands[0]);
11799 rtx op0_high = gen_highpart (SImode, operands[0]);
11800 rtx op1_low = gen_lowpart (SImode, operands[1]);
11801 rtx op1_high = gen_highpart (SImode, operands[1]);
11802 rtx op2_high = gen_highpart (SImode, operands[2]);
11803
11804 rtx scratch1 = gen_reg_rtx (SImode);
11805 rtx scratch2 = gen_reg_rtx (SImode);
11806 emit_move_insn (scratch1, op2_high);
11807 emit_move_insn (scratch2, op1_high);
11808
11809 emit_insn(gen_rtx_SET(scratch1,
11810 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11811 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11812 emit_move_insn (op0_low, op1_low);
11813 emit_move_insn (op0_high, scratch2);
11814
11815 DONE;
11816 }"
11817 )
11818
11819 ;; movmisalign patterns for HImode and SImode.
11820 (define_expand "movmisalign<mode>"
11821 [(match_operand:HSI 0 "general_operand")
11822 (match_operand:HSI 1 "general_operand")]
11823 "unaligned_access"
11824 {
11825 /* This pattern is not permitted to fail during expansion: if both arguments
11826 are non-registers (e.g. memory := constant), force operand 1 into a
11827 register. */
11828 rtx (* gen_unaligned_load)(rtx, rtx);
11829 rtx tmp_dest = operands[0];
11830 if (!s_register_operand (operands[0], <MODE>mode)
11831 && !s_register_operand (operands[1], <MODE>mode))
11832 operands[1] = force_reg (<MODE>mode, operands[1]);
11833
11834 if (<MODE>mode == HImode)
11835 {
11836 gen_unaligned_load = gen_unaligned_loadhiu;
11837 tmp_dest = gen_reg_rtx (SImode);
11838 }
11839 else
11840 gen_unaligned_load = gen_unaligned_loadsi;
11841
11842 if (MEM_P (operands[1]))
11843 {
11844 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11845 if (<MODE>mode == HImode)
11846 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11847 }
11848 else
11849 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11850
11851 DONE;
11852 })
11853
11854 ;; Vector bits common to IWMMXT and Neon
11855 (include "vec-common.md")
11856 ;; Load the Intel Wireless Multimedia Extension patterns
11857 (include "iwmmxt.md")
11858 ;; Load the VFP co-processor patterns
11859 (include "vfp.md")
11860 ;; Thumb-1 patterns
11861 (include "thumb1.md")
11862 ;; Thumb-2 patterns
11863 (include "thumb2.md")
11864 ;; Neon patterns
11865 (include "neon.md")
11866 ;; Crypto patterns
11867 (include "crypto.md")
11868 ;; Synchronization Primitives
11869 (include "sync.md")
11870 ;; Fixed-point patterns
11871 (include "arm-fixed.md")