]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm.md
[ARM] Add support for -mpure-code option
[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 -> 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 "pool_range" "*,*,*,*,4096,*")
6068 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6069 )
6070
6071 (define_split
6072 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6073 (match_operand:SI 1 "const_int_operand" ""))]
6074 "TARGET_32BIT
6075 && (!(const_ok_for_arm (INTVAL (operands[1]))
6076 || const_ok_for_arm (~INTVAL (operands[1]))))"
6077 [(clobber (const_int 0))]
6078 "
6079 arm_split_constant (SET, SImode, NULL_RTX,
6080 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6081 DONE;
6082 "
6083 )
6084
6085 ;; A normal way to do (symbol + offset) requires three instructions at least
6086 ;; (depends on how big the offset is) as below:
6087 ;; movw r0, #:lower16:g
6088 ;; movw r0, #:upper16:g
6089 ;; adds r0, #4
6090 ;;
6091 ;; A better way would be:
6092 ;; movw r0, #:lower16:g+4
6093 ;; movw r0, #:upper16:g+4
6094 ;;
6095 ;; The limitation of this way is that the length of offset should be a 16-bit
6096 ;; signed value, because current assembler only supports REL type relocation for
6097 ;; such case. If the more powerful RELA type is supported in future, we should
6098 ;; update this pattern to go with better way.
6099 (define_split
6100 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6101 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6102 (match_operand:SI 2 "const_int_operand" ""))))]
6103 "TARGET_THUMB
6104 && TARGET_HAVE_MOVT
6105 && arm_disable_literal_pool
6106 && reload_completed
6107 && GET_CODE (operands[1]) == SYMBOL_REF"
6108 [(clobber (const_int 0))]
6109 "
6110 int offset = INTVAL (operands[2]);
6111
6112 if (offset < -0x8000 || offset > 0x7fff)
6113 {
6114 arm_emit_movpair (operands[0], operands[1]);
6115 emit_insn (gen_rtx_SET (operands[0],
6116 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6117 }
6118 else
6119 {
6120 rtx op = gen_rtx_CONST (SImode,
6121 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6122 arm_emit_movpair (operands[0], op);
6123 }
6124 "
6125 )
6126
6127 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6128 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6129 ;; and lo_sum would be merged back into memory load at cprop. However,
6130 ;; if the default is to prefer movt/movw rather than a load from the constant
6131 ;; pool, the performance is better.
6132 (define_split
6133 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6134 (match_operand:SI 1 "general_operand" ""))]
6135 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6136 && !flag_pic && !target_word_relocations
6137 && !arm_tls_referenced_p (operands[1])"
6138 [(clobber (const_int 0))]
6139 {
6140 arm_emit_movpair (operands[0], operands[1]);
6141 DONE;
6142 })
6143
6144 ;; When generating pic, we need to load the symbol offset into a register.
6145 ;; So that the optimizer does not confuse this with a normal symbol load
6146 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6147 ;; since that is the only type of relocation we can use.
6148
6149 ;; Wrap calculation of the whole PIC address in a single pattern for the
6150 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6151 ;; a PIC address involves two loads from memory, so we want to CSE it
6152 ;; as often as possible.
6153 ;; This pattern will be split into one of the pic_load_addr_* patterns
6154 ;; and a move after GCSE optimizations.
6155 ;;
6156 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6157 (define_expand "calculate_pic_address"
6158 [(set (match_operand:SI 0 "register_operand" "")
6159 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6160 (unspec:SI [(match_operand:SI 2 "" "")]
6161 UNSPEC_PIC_SYM))))]
6162 "flag_pic"
6163 )
6164
6165 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6166 (define_split
6167 [(set (match_operand:SI 0 "register_operand" "")
6168 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6169 (unspec:SI [(match_operand:SI 2 "" "")]
6170 UNSPEC_PIC_SYM))))]
6171 "flag_pic"
6172 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6173 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6174 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6175 )
6176
6177 ;; operand1 is the memory address to go into
6178 ;; pic_load_addr_32bit.
6179 ;; operand2 is the PIC label to be emitted
6180 ;; from pic_add_dot_plus_eight.
6181 ;; We do this to allow hoisting of the entire insn.
6182 (define_insn_and_split "pic_load_addr_unified"
6183 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6184 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6185 (match_operand:SI 2 "" "")]
6186 UNSPEC_PIC_UNIFIED))]
6187 "flag_pic"
6188 "#"
6189 "&& reload_completed"
6190 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6191 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6192 (match_dup 2)] UNSPEC_PIC_BASE))]
6193 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6194 [(set_attr "type" "load1,load1,load1")
6195 (set_attr "pool_range" "4096,4094,1022")
6196 (set_attr "neg_pool_range" "4084,0,0")
6197 (set_attr "arch" "a,t2,t1")
6198 (set_attr "length" "8,6,4")]
6199 )
6200
6201 ;; The rather odd constraints on the following are to force reload to leave
6202 ;; the insn alone, and to force the minipool generation pass to then move
6203 ;; the GOT symbol to memory.
6204
6205 (define_insn "pic_load_addr_32bit"
6206 [(set (match_operand:SI 0 "s_register_operand" "=r")
6207 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6208 "TARGET_32BIT && flag_pic"
6209 "ldr%?\\t%0, %1"
6210 [(set_attr "type" "load1")
6211 (set (attr "pool_range")
6212 (if_then_else (eq_attr "is_thumb" "no")
6213 (const_int 4096)
6214 (const_int 4094)))
6215 (set (attr "neg_pool_range")
6216 (if_then_else (eq_attr "is_thumb" "no")
6217 (const_int 4084)
6218 (const_int 0)))]
6219 )
6220
6221 (define_insn "pic_load_addr_thumb1"
6222 [(set (match_operand:SI 0 "s_register_operand" "=l")
6223 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6224 "TARGET_THUMB1 && flag_pic"
6225 "ldr\\t%0, %1"
6226 [(set_attr "type" "load1")
6227 (set (attr "pool_range") (const_int 1018))]
6228 )
6229
6230 (define_insn "pic_add_dot_plus_four"
6231 [(set (match_operand:SI 0 "register_operand" "=r")
6232 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6233 (const_int 4)
6234 (match_operand 2 "" "")]
6235 UNSPEC_PIC_BASE))]
6236 "TARGET_THUMB"
6237 "*
6238 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6239 INTVAL (operands[2]));
6240 return \"add\\t%0, %|pc\";
6241 "
6242 [(set_attr "length" "2")
6243 (set_attr "type" "alu_sreg")]
6244 )
6245
6246 (define_insn "pic_add_dot_plus_eight"
6247 [(set (match_operand:SI 0 "register_operand" "=r")
6248 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6249 (const_int 8)
6250 (match_operand 2 "" "")]
6251 UNSPEC_PIC_BASE))]
6252 "TARGET_ARM"
6253 "*
6254 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6255 INTVAL (operands[2]));
6256 return \"add%?\\t%0, %|pc, %1\";
6257 "
6258 [(set_attr "predicable" "yes")
6259 (set_attr "type" "alu_sreg")]
6260 )
6261
6262 (define_insn "tls_load_dot_plus_eight"
6263 [(set (match_operand:SI 0 "register_operand" "=r")
6264 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6265 (const_int 8)
6266 (match_operand 2 "" "")]
6267 UNSPEC_PIC_BASE)))]
6268 "TARGET_ARM"
6269 "*
6270 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6271 INTVAL (operands[2]));
6272 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6273 "
6274 [(set_attr "predicable" "yes")
6275 (set_attr "type" "load1")]
6276 )
6277
6278 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6279 ;; followed by a load. These sequences can be crunched down to
6280 ;; tls_load_dot_plus_eight by a peephole.
6281
6282 (define_peephole2
6283 [(set (match_operand:SI 0 "register_operand" "")
6284 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6285 (const_int 8)
6286 (match_operand 1 "" "")]
6287 UNSPEC_PIC_BASE))
6288 (set (match_operand:SI 2 "arm_general_register_operand" "")
6289 (mem:SI (match_dup 0)))]
6290 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6291 [(set (match_dup 2)
6292 (mem:SI (unspec:SI [(match_dup 3)
6293 (const_int 8)
6294 (match_dup 1)]
6295 UNSPEC_PIC_BASE)))]
6296 ""
6297 )
6298
6299 (define_insn "pic_offset_arm"
6300 [(set (match_operand:SI 0 "register_operand" "=r")
6301 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6302 (unspec:SI [(match_operand:SI 2 "" "X")]
6303 UNSPEC_PIC_OFFSET))))]
6304 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6305 "ldr%?\\t%0, [%1,%2]"
6306 [(set_attr "type" "load1")]
6307 )
6308
6309 (define_expand "builtin_setjmp_receiver"
6310 [(label_ref (match_operand 0 "" ""))]
6311 "flag_pic"
6312 "
6313 {
6314 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6315 register. */
6316 if (arm_pic_register != INVALID_REGNUM)
6317 arm_load_pic_register (1UL << 3);
6318 DONE;
6319 }")
6320
6321 ;; If copying one reg to another we can set the condition codes according to
6322 ;; its value. Such a move is common after a return from subroutine and the
6323 ;; result is being tested against zero.
6324
6325 (define_insn "*movsi_compare0"
6326 [(set (reg:CC CC_REGNUM)
6327 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6328 (const_int 0)))
6329 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6330 (match_dup 1))]
6331 "TARGET_32BIT"
6332 "@
6333 cmp%?\\t%0, #0
6334 subs%?\\t%0, %1, #0"
6335 [(set_attr "conds" "set")
6336 (set_attr "type" "alus_imm,alus_imm")]
6337 )
6338
6339 ;; Subroutine to store a half word from a register into memory.
6340 ;; Operand 0 is the source register (HImode)
6341 ;; Operand 1 is the destination address in a register (SImode)
6342
6343 ;; In both this routine and the next, we must be careful not to spill
6344 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6345 ;; can generate unrecognizable rtl.
6346
6347 (define_expand "storehi"
6348 [;; store the low byte
6349 (set (match_operand 1 "" "") (match_dup 3))
6350 ;; extract the high byte
6351 (set (match_dup 2)
6352 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6353 ;; store the high byte
6354 (set (match_dup 4) (match_dup 5))]
6355 "TARGET_ARM"
6356 "
6357 {
6358 rtx op1 = operands[1];
6359 rtx addr = XEXP (op1, 0);
6360 enum rtx_code code = GET_CODE (addr);
6361
6362 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6363 || code == MINUS)
6364 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6365
6366 operands[4] = adjust_address (op1, QImode, 1);
6367 operands[1] = adjust_address (operands[1], QImode, 0);
6368 operands[3] = gen_lowpart (QImode, operands[0]);
6369 operands[0] = gen_lowpart (SImode, operands[0]);
6370 operands[2] = gen_reg_rtx (SImode);
6371 operands[5] = gen_lowpart (QImode, operands[2]);
6372 }"
6373 )
6374
6375 (define_expand "storehi_bigend"
6376 [(set (match_dup 4) (match_dup 3))
6377 (set (match_dup 2)
6378 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6379 (set (match_operand 1 "" "") (match_dup 5))]
6380 "TARGET_ARM"
6381 "
6382 {
6383 rtx op1 = operands[1];
6384 rtx addr = XEXP (op1, 0);
6385 enum rtx_code code = GET_CODE (addr);
6386
6387 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6388 || code == MINUS)
6389 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6390
6391 operands[4] = adjust_address (op1, QImode, 1);
6392 operands[1] = adjust_address (operands[1], QImode, 0);
6393 operands[3] = gen_lowpart (QImode, operands[0]);
6394 operands[0] = gen_lowpart (SImode, operands[0]);
6395 operands[2] = gen_reg_rtx (SImode);
6396 operands[5] = gen_lowpart (QImode, operands[2]);
6397 }"
6398 )
6399
6400 ;; Subroutine to store a half word integer constant into memory.
6401 (define_expand "storeinthi"
6402 [(set (match_operand 0 "" "")
6403 (match_operand 1 "" ""))
6404 (set (match_dup 3) (match_dup 2))]
6405 "TARGET_ARM"
6406 "
6407 {
6408 HOST_WIDE_INT value = INTVAL (operands[1]);
6409 rtx addr = XEXP (operands[0], 0);
6410 rtx op0 = operands[0];
6411 enum rtx_code code = GET_CODE (addr);
6412
6413 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6414 || code == MINUS)
6415 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6416
6417 operands[1] = gen_reg_rtx (SImode);
6418 if (BYTES_BIG_ENDIAN)
6419 {
6420 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6421 if ((value & 255) == ((value >> 8) & 255))
6422 operands[2] = operands[1];
6423 else
6424 {
6425 operands[2] = gen_reg_rtx (SImode);
6426 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6427 }
6428 }
6429 else
6430 {
6431 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6432 if ((value & 255) == ((value >> 8) & 255))
6433 operands[2] = operands[1];
6434 else
6435 {
6436 operands[2] = gen_reg_rtx (SImode);
6437 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6438 }
6439 }
6440
6441 operands[3] = adjust_address (op0, QImode, 1);
6442 operands[0] = adjust_address (operands[0], QImode, 0);
6443 operands[2] = gen_lowpart (QImode, operands[2]);
6444 operands[1] = gen_lowpart (QImode, operands[1]);
6445 }"
6446 )
6447
6448 (define_expand "storehi_single_op"
6449 [(set (match_operand:HI 0 "memory_operand" "")
6450 (match_operand:HI 1 "general_operand" ""))]
6451 "TARGET_32BIT && arm_arch4"
6452 "
6453 if (!s_register_operand (operands[1], HImode))
6454 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6455 "
6456 )
6457
6458 (define_expand "movhi"
6459 [(set (match_operand:HI 0 "general_operand" "")
6460 (match_operand:HI 1 "general_operand" ""))]
6461 "TARGET_EITHER"
6462 "
6463 if (TARGET_ARM)
6464 {
6465 if (can_create_pseudo_p ())
6466 {
6467 if (MEM_P (operands[0]))
6468 {
6469 if (arm_arch4)
6470 {
6471 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6472 DONE;
6473 }
6474 if (CONST_INT_P (operands[1]))
6475 emit_insn (gen_storeinthi (operands[0], operands[1]));
6476 else
6477 {
6478 if (MEM_P (operands[1]))
6479 operands[1] = force_reg (HImode, operands[1]);
6480 if (BYTES_BIG_ENDIAN)
6481 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6482 else
6483 emit_insn (gen_storehi (operands[1], operands[0]));
6484 }
6485 DONE;
6486 }
6487 /* Sign extend a constant, and keep it in an SImode reg. */
6488 else if (CONST_INT_P (operands[1]))
6489 {
6490 rtx reg = gen_reg_rtx (SImode);
6491 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6492
6493 /* If the constant is already valid, leave it alone. */
6494 if (!const_ok_for_arm (val))
6495 {
6496 /* If setting all the top bits will make the constant
6497 loadable in a single instruction, then set them.
6498 Otherwise, sign extend the number. */
6499
6500 if (const_ok_for_arm (~(val | ~0xffff)))
6501 val |= ~0xffff;
6502 else if (val & 0x8000)
6503 val |= ~0xffff;
6504 }
6505
6506 emit_insn (gen_movsi (reg, GEN_INT (val)));
6507 operands[1] = gen_lowpart (HImode, reg);
6508 }
6509 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6510 && MEM_P (operands[1]))
6511 {
6512 rtx reg = gen_reg_rtx (SImode);
6513
6514 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6515 operands[1] = gen_lowpart (HImode, reg);
6516 }
6517 else if (!arm_arch4)
6518 {
6519 if (MEM_P (operands[1]))
6520 {
6521 rtx base;
6522 rtx offset = const0_rtx;
6523 rtx reg = gen_reg_rtx (SImode);
6524
6525 if ((REG_P (base = XEXP (operands[1], 0))
6526 || (GET_CODE (base) == PLUS
6527 && (CONST_INT_P (offset = XEXP (base, 1)))
6528 && ((INTVAL(offset) & 1) != 1)
6529 && REG_P (base = XEXP (base, 0))))
6530 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6531 {
6532 rtx new_rtx;
6533
6534 new_rtx = widen_memory_access (operands[1], SImode,
6535 ((INTVAL (offset) & ~3)
6536 - INTVAL (offset)));
6537 emit_insn (gen_movsi (reg, new_rtx));
6538 if (((INTVAL (offset) & 2) != 0)
6539 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6540 {
6541 rtx reg2 = gen_reg_rtx (SImode);
6542
6543 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6544 reg = reg2;
6545 }
6546 }
6547 else
6548 emit_insn (gen_movhi_bytes (reg, operands[1]));
6549
6550 operands[1] = gen_lowpart (HImode, reg);
6551 }
6552 }
6553 }
6554 /* Handle loading a large integer during reload. */
6555 else if (CONST_INT_P (operands[1])
6556 && !const_ok_for_arm (INTVAL (operands[1]))
6557 && !const_ok_for_arm (~INTVAL (operands[1])))
6558 {
6559 /* Writing a constant to memory needs a scratch, which should
6560 be handled with SECONDARY_RELOADs. */
6561 gcc_assert (REG_P (operands[0]));
6562
6563 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6564 emit_insn (gen_movsi (operands[0], operands[1]));
6565 DONE;
6566 }
6567 }
6568 else if (TARGET_THUMB2)
6569 {
6570 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6571 if (can_create_pseudo_p ())
6572 {
6573 if (!REG_P (operands[0]))
6574 operands[1] = force_reg (HImode, operands[1]);
6575 /* Zero extend a constant, and keep it in an SImode reg. */
6576 else if (CONST_INT_P (operands[1]))
6577 {
6578 rtx reg = gen_reg_rtx (SImode);
6579 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6580
6581 emit_insn (gen_movsi (reg, GEN_INT (val)));
6582 operands[1] = gen_lowpart (HImode, reg);
6583 }
6584 }
6585 }
6586 else /* TARGET_THUMB1 */
6587 {
6588 if (can_create_pseudo_p ())
6589 {
6590 if (CONST_INT_P (operands[1]))
6591 {
6592 rtx reg = gen_reg_rtx (SImode);
6593
6594 emit_insn (gen_movsi (reg, operands[1]));
6595 operands[1] = gen_lowpart (HImode, reg);
6596 }
6597
6598 /* ??? We shouldn't really get invalid addresses here, but this can
6599 happen if we are passed a SP (never OK for HImode/QImode) or
6600 virtual register (also rejected as illegitimate for HImode/QImode)
6601 relative address. */
6602 /* ??? This should perhaps be fixed elsewhere, for instance, in
6603 fixup_stack_1, by checking for other kinds of invalid addresses,
6604 e.g. a bare reference to a virtual register. This may confuse the
6605 alpha though, which must handle this case differently. */
6606 if (MEM_P (operands[0])
6607 && !memory_address_p (GET_MODE (operands[0]),
6608 XEXP (operands[0], 0)))
6609 operands[0]
6610 = replace_equiv_address (operands[0],
6611 copy_to_reg (XEXP (operands[0], 0)));
6612
6613 if (MEM_P (operands[1])
6614 && !memory_address_p (GET_MODE (operands[1]),
6615 XEXP (operands[1], 0)))
6616 operands[1]
6617 = replace_equiv_address (operands[1],
6618 copy_to_reg (XEXP (operands[1], 0)));
6619
6620 if (MEM_P (operands[1]) && optimize > 0)
6621 {
6622 rtx reg = gen_reg_rtx (SImode);
6623
6624 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6625 operands[1] = gen_lowpart (HImode, reg);
6626 }
6627
6628 if (MEM_P (operands[0]))
6629 operands[1] = force_reg (HImode, operands[1]);
6630 }
6631 else if (CONST_INT_P (operands[1])
6632 && !satisfies_constraint_I (operands[1]))
6633 {
6634 /* Handle loading a large integer during reload. */
6635
6636 /* Writing a constant to memory needs a scratch, which should
6637 be handled with SECONDARY_RELOADs. */
6638 gcc_assert (REG_P (operands[0]));
6639
6640 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6641 emit_insn (gen_movsi (operands[0], operands[1]));
6642 DONE;
6643 }
6644 }
6645 "
6646 )
6647
6648 (define_expand "movhi_bytes"
6649 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6650 (set (match_dup 3)
6651 (zero_extend:SI (match_dup 6)))
6652 (set (match_operand:SI 0 "" "")
6653 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6654 "TARGET_ARM"
6655 "
6656 {
6657 rtx mem1, mem2;
6658 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6659
6660 mem1 = change_address (operands[1], QImode, addr);
6661 mem2 = change_address (operands[1], QImode,
6662 plus_constant (Pmode, addr, 1));
6663 operands[0] = gen_lowpart (SImode, operands[0]);
6664 operands[1] = mem1;
6665 operands[2] = gen_reg_rtx (SImode);
6666 operands[3] = gen_reg_rtx (SImode);
6667 operands[6] = mem2;
6668
6669 if (BYTES_BIG_ENDIAN)
6670 {
6671 operands[4] = operands[2];
6672 operands[5] = operands[3];
6673 }
6674 else
6675 {
6676 operands[4] = operands[3];
6677 operands[5] = operands[2];
6678 }
6679 }"
6680 )
6681
6682 (define_expand "movhi_bigend"
6683 [(set (match_dup 2)
6684 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6685 (const_int 16)))
6686 (set (match_dup 3)
6687 (ashiftrt:SI (match_dup 2) (const_int 16)))
6688 (set (match_operand:HI 0 "s_register_operand" "")
6689 (match_dup 4))]
6690 "TARGET_ARM"
6691 "
6692 operands[2] = gen_reg_rtx (SImode);
6693 operands[3] = gen_reg_rtx (SImode);
6694 operands[4] = gen_lowpart (HImode, operands[3]);
6695 "
6696 )
6697
6698 ;; Pattern to recognize insn generated default case above
6699 (define_insn "*movhi_insn_arch4"
6700 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6701 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6702 "TARGET_ARM
6703 && arm_arch4
6704 && (register_operand (operands[0], HImode)
6705 || register_operand (operands[1], HImode))"
6706 "@
6707 mov%?\\t%0, %1\\t%@ movhi
6708 mvn%?\\t%0, #%B1\\t%@ movhi
6709 movw%?\\t%0, %L1\\t%@ movhi
6710 strh%?\\t%1, %0\\t%@ movhi
6711 ldrh%?\\t%0, %1\\t%@ movhi"
6712 [(set_attr "predicable" "yes")
6713 (set_attr "pool_range" "*,*,*,*,256")
6714 (set_attr "neg_pool_range" "*,*,*,*,244")
6715 (set_attr "arch" "*,*,v6t2,*,*")
6716 (set_attr_alternative "type"
6717 [(if_then_else (match_operand 1 "const_int_operand" "")
6718 (const_string "mov_imm" )
6719 (const_string "mov_reg"))
6720 (const_string "mvn_imm")
6721 (const_string "mov_imm")
6722 (const_string "store1")
6723 (const_string "load1")])]
6724 )
6725
6726 (define_insn "*movhi_bytes"
6727 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6728 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6729 "TARGET_ARM"
6730 "@
6731 mov%?\\t%0, %1\\t%@ movhi
6732 mov%?\\t%0, %1\\t%@ movhi
6733 mvn%?\\t%0, #%B1\\t%@ movhi"
6734 [(set_attr "predicable" "yes")
6735 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6736 )
6737
6738 ;; We use a DImode scratch because we may occasionally need an additional
6739 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6740 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6741 (define_expand "reload_outhi"
6742 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6743 (match_operand:HI 1 "s_register_operand" "r")
6744 (match_operand:DI 2 "s_register_operand" "=&l")])]
6745 "TARGET_EITHER"
6746 "if (TARGET_ARM)
6747 arm_reload_out_hi (operands);
6748 else
6749 thumb_reload_out_hi (operands);
6750 DONE;
6751 "
6752 )
6753
6754 (define_expand "reload_inhi"
6755 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6756 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6757 (match_operand:DI 2 "s_register_operand" "=&r")])]
6758 "TARGET_EITHER"
6759 "
6760 if (TARGET_ARM)
6761 arm_reload_in_hi (operands);
6762 else
6763 thumb_reload_out_hi (operands);
6764 DONE;
6765 ")
6766
6767 (define_expand "movqi"
6768 [(set (match_operand:QI 0 "general_operand" "")
6769 (match_operand:QI 1 "general_operand" ""))]
6770 "TARGET_EITHER"
6771 "
6772 /* Everything except mem = const or mem = mem can be done easily */
6773
6774 if (can_create_pseudo_p ())
6775 {
6776 if (CONST_INT_P (operands[1]))
6777 {
6778 rtx reg = gen_reg_rtx (SImode);
6779
6780 /* For thumb we want an unsigned immediate, then we are more likely
6781 to be able to use a movs insn. */
6782 if (TARGET_THUMB)
6783 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6784
6785 emit_insn (gen_movsi (reg, operands[1]));
6786 operands[1] = gen_lowpart (QImode, reg);
6787 }
6788
6789 if (TARGET_THUMB)
6790 {
6791 /* ??? We shouldn't really get invalid addresses here, but this can
6792 happen if we are passed a SP (never OK for HImode/QImode) or
6793 virtual register (also rejected as illegitimate for HImode/QImode)
6794 relative address. */
6795 /* ??? This should perhaps be fixed elsewhere, for instance, in
6796 fixup_stack_1, by checking for other kinds of invalid addresses,
6797 e.g. a bare reference to a virtual register. This may confuse the
6798 alpha though, which must handle this case differently. */
6799 if (MEM_P (operands[0])
6800 && !memory_address_p (GET_MODE (operands[0]),
6801 XEXP (operands[0], 0)))
6802 operands[0]
6803 = replace_equiv_address (operands[0],
6804 copy_to_reg (XEXP (operands[0], 0)));
6805 if (MEM_P (operands[1])
6806 && !memory_address_p (GET_MODE (operands[1]),
6807 XEXP (operands[1], 0)))
6808 operands[1]
6809 = replace_equiv_address (operands[1],
6810 copy_to_reg (XEXP (operands[1], 0)));
6811 }
6812
6813 if (MEM_P (operands[1]) && optimize > 0)
6814 {
6815 rtx reg = gen_reg_rtx (SImode);
6816
6817 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6818 operands[1] = gen_lowpart (QImode, reg);
6819 }
6820
6821 if (MEM_P (operands[0]))
6822 operands[1] = force_reg (QImode, operands[1]);
6823 }
6824 else if (TARGET_THUMB
6825 && CONST_INT_P (operands[1])
6826 && !satisfies_constraint_I (operands[1]))
6827 {
6828 /* Handle loading a large integer during reload. */
6829
6830 /* Writing a constant to memory needs a scratch, which should
6831 be handled with SECONDARY_RELOADs. */
6832 gcc_assert (REG_P (operands[0]));
6833
6834 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6835 emit_insn (gen_movsi (operands[0], operands[1]));
6836 DONE;
6837 }
6838 "
6839 )
6840
6841 (define_insn "*arm_movqi_insn"
6842 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6843 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6844 "TARGET_32BIT
6845 && ( register_operand (operands[0], QImode)
6846 || register_operand (operands[1], QImode))"
6847 "@
6848 mov%?\\t%0, %1
6849 mov%?\\t%0, %1
6850 mov%?\\t%0, %1
6851 mov%?\\t%0, %1
6852 mvn%?\\t%0, #%B1
6853 ldrb%?\\t%0, %1
6854 strb%?\\t%1, %0
6855 ldrb%?\\t%0, %1
6856 strb%?\\t%1, %0"
6857 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6858 (set_attr "predicable" "yes")
6859 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6860 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6861 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6862 )
6863
6864 ;; HFmode moves
6865 (define_expand "movhf"
6866 [(set (match_operand:HF 0 "general_operand" "")
6867 (match_operand:HF 1 "general_operand" ""))]
6868 "TARGET_EITHER"
6869 "
6870 if (TARGET_32BIT)
6871 {
6872 if (MEM_P (operands[0]))
6873 operands[1] = force_reg (HFmode, operands[1]);
6874 }
6875 else /* TARGET_THUMB1 */
6876 {
6877 if (can_create_pseudo_p ())
6878 {
6879 if (!REG_P (operands[0]))
6880 operands[1] = force_reg (HFmode, operands[1]);
6881 }
6882 }
6883 "
6884 )
6885
6886 (define_insn "*arm32_movhf"
6887 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6888 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6889 "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_VFP)
6890 && ( s_register_operand (operands[0], HFmode)
6891 || s_register_operand (operands[1], HFmode))"
6892 "*
6893 switch (which_alternative)
6894 {
6895 case 0: /* ARM register from memory */
6896 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6897 case 1: /* memory from ARM register */
6898 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6899 case 2: /* ARM register from ARM register */
6900 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6901 case 3: /* ARM register from constant */
6902 {
6903 long bits;
6904 rtx ops[4];
6905
6906 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6907 HFmode);
6908 ops[0] = operands[0];
6909 ops[1] = GEN_INT (bits);
6910 ops[2] = GEN_INT (bits & 0xff00);
6911 ops[3] = GEN_INT (bits & 0x00ff);
6912
6913 if (arm_arch_thumb2)
6914 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6915 else
6916 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6917 return \"\";
6918 }
6919 default:
6920 gcc_unreachable ();
6921 }
6922 "
6923 [(set_attr "conds" "unconditional")
6924 (set_attr "type" "load1,store1,mov_reg,multiple")
6925 (set_attr "length" "4,4,4,8")
6926 (set_attr "predicable" "yes")
6927 (set_attr "predicable_short_it" "no")]
6928 )
6929
6930 (define_expand "movsf"
6931 [(set (match_operand:SF 0 "general_operand" "")
6932 (match_operand:SF 1 "general_operand" ""))]
6933 "TARGET_EITHER"
6934 "
6935 if (TARGET_32BIT)
6936 {
6937 if (MEM_P (operands[0]))
6938 operands[1] = force_reg (SFmode, operands[1]);
6939 }
6940 else /* TARGET_THUMB1 */
6941 {
6942 if (can_create_pseudo_p ())
6943 {
6944 if (!REG_P (operands[0]))
6945 operands[1] = force_reg (SFmode, operands[1]);
6946 }
6947 }
6948 "
6949 )
6950
6951 ;; Transform a floating-point move of a constant into a core register into
6952 ;; an SImode operation.
6953 (define_split
6954 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6955 (match_operand:SF 1 "immediate_operand" ""))]
6956 "TARGET_EITHER
6957 && reload_completed
6958 && CONST_DOUBLE_P (operands[1])"
6959 [(set (match_dup 2) (match_dup 3))]
6960 "
6961 operands[2] = gen_lowpart (SImode, operands[0]);
6962 operands[3] = gen_lowpart (SImode, operands[1]);
6963 if (operands[2] == 0 || operands[3] == 0)
6964 FAIL;
6965 "
6966 )
6967
6968 (define_insn "*arm_movsf_soft_insn"
6969 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6970 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6971 "TARGET_32BIT
6972 && TARGET_SOFT_FLOAT
6973 && (!MEM_P (operands[0])
6974 || register_operand (operands[1], SFmode))"
6975 "@
6976 mov%?\\t%0, %1
6977 ldr%?\\t%0, %1\\t%@ float
6978 str%?\\t%1, %0\\t%@ float"
6979 [(set_attr "predicable" "yes")
6980 (set_attr "predicable_short_it" "no")
6981 (set_attr "type" "mov_reg,load1,store1")
6982 (set_attr "arm_pool_range" "*,4096,*")
6983 (set_attr "thumb2_pool_range" "*,4094,*")
6984 (set_attr "arm_neg_pool_range" "*,4084,*")
6985 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6986 )
6987
6988 (define_expand "movdf"
6989 [(set (match_operand:DF 0 "general_operand" "")
6990 (match_operand:DF 1 "general_operand" ""))]
6991 "TARGET_EITHER"
6992 "
6993 if (TARGET_32BIT)
6994 {
6995 if (MEM_P (operands[0]))
6996 operands[1] = force_reg (DFmode, operands[1]);
6997 }
6998 else /* TARGET_THUMB */
6999 {
7000 if (can_create_pseudo_p ())
7001 {
7002 if (!REG_P (operands[0]))
7003 operands[1] = force_reg (DFmode, operands[1]);
7004 }
7005 }
7006 "
7007 )
7008
7009 ;; Reloading a df mode value stored in integer regs to memory can require a
7010 ;; scratch reg.
7011 (define_expand "reload_outdf"
7012 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7013 (match_operand:DF 1 "s_register_operand" "r")
7014 (match_operand:SI 2 "s_register_operand" "=&r")]
7015 "TARGET_THUMB2"
7016 "
7017 {
7018 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7019
7020 if (code == REG)
7021 operands[2] = XEXP (operands[0], 0);
7022 else if (code == POST_INC || code == PRE_DEC)
7023 {
7024 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7025 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7026 emit_insn (gen_movdi (operands[0], operands[1]));
7027 DONE;
7028 }
7029 else if (code == PRE_INC)
7030 {
7031 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7032
7033 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7034 operands[2] = reg;
7035 }
7036 else if (code == POST_DEC)
7037 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7038 else
7039 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7040 XEXP (XEXP (operands[0], 0), 1)));
7041
7042 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7043 operands[1]));
7044
7045 if (code == POST_DEC)
7046 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7047
7048 DONE;
7049 }"
7050 )
7051
7052 (define_insn "*movdf_soft_insn"
7053 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7054 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7055 "TARGET_32BIT && TARGET_SOFT_FLOAT
7056 && ( register_operand (operands[0], DFmode)
7057 || register_operand (operands[1], DFmode))"
7058 "*
7059 switch (which_alternative)
7060 {
7061 case 0:
7062 case 1:
7063 case 2:
7064 return \"#\";
7065 default:
7066 return output_move_double (operands, true, NULL);
7067 }
7068 "
7069 [(set_attr "length" "8,12,16,8,8")
7070 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7071 (set_attr "arm_pool_range" "*,*,*,1020,*")
7072 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7073 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7074 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7075 )
7076 \f
7077
7078 ;; load- and store-multiple insns
7079 ;; The arm can load/store any set of registers, provided that they are in
7080 ;; ascending order, but these expanders assume a contiguous set.
7081
7082 (define_expand "load_multiple"
7083 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7084 (match_operand:SI 1 "" ""))
7085 (use (match_operand:SI 2 "" ""))])]
7086 "TARGET_32BIT"
7087 {
7088 HOST_WIDE_INT offset = 0;
7089
7090 /* Support only fixed point registers. */
7091 if (!CONST_INT_P (operands[2])
7092 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7093 || INTVAL (operands[2]) < 2
7094 || !MEM_P (operands[1])
7095 || !REG_P (operands[0])
7096 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7097 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7098 FAIL;
7099
7100 operands[3]
7101 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7102 INTVAL (operands[2]),
7103 force_reg (SImode, XEXP (operands[1], 0)),
7104 FALSE, operands[1], &offset);
7105 })
7106
7107 (define_expand "store_multiple"
7108 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7109 (match_operand:SI 1 "" ""))
7110 (use (match_operand:SI 2 "" ""))])]
7111 "TARGET_32BIT"
7112 {
7113 HOST_WIDE_INT offset = 0;
7114
7115 /* Support only fixed point registers. */
7116 if (!CONST_INT_P (operands[2])
7117 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7118 || INTVAL (operands[2]) < 2
7119 || !REG_P (operands[1])
7120 || !MEM_P (operands[0])
7121 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7122 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7123 FAIL;
7124
7125 operands[3]
7126 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7127 INTVAL (operands[2]),
7128 force_reg (SImode, XEXP (operands[0], 0)),
7129 FALSE, operands[0], &offset);
7130 })
7131
7132
7133 (define_expand "setmemsi"
7134 [(match_operand:BLK 0 "general_operand" "")
7135 (match_operand:SI 1 "const_int_operand" "")
7136 (match_operand:SI 2 "const_int_operand" "")
7137 (match_operand:SI 3 "const_int_operand" "")]
7138 "TARGET_32BIT"
7139 {
7140 if (arm_gen_setmem (operands))
7141 DONE;
7142
7143 FAIL;
7144 })
7145
7146
7147 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7148 ;; We could let this apply for blocks of less than this, but it clobbers so
7149 ;; many registers that there is then probably a better way.
7150
7151 (define_expand "movmemqi"
7152 [(match_operand:BLK 0 "general_operand" "")
7153 (match_operand:BLK 1 "general_operand" "")
7154 (match_operand:SI 2 "const_int_operand" "")
7155 (match_operand:SI 3 "const_int_operand" "")]
7156 ""
7157 "
7158 if (TARGET_32BIT)
7159 {
7160 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7161 && !optimize_function_for_size_p (cfun))
7162 {
7163 if (gen_movmem_ldrd_strd (operands))
7164 DONE;
7165 FAIL;
7166 }
7167
7168 if (arm_gen_movmemqi (operands))
7169 DONE;
7170 FAIL;
7171 }
7172 else /* TARGET_THUMB1 */
7173 {
7174 if ( INTVAL (operands[3]) != 4
7175 || INTVAL (operands[2]) > 48)
7176 FAIL;
7177
7178 thumb_expand_movmemqi (operands);
7179 DONE;
7180 }
7181 "
7182 )
7183 \f
7184
7185 ;; Compare & branch insns
7186 ;; The range calculations are based as follows:
7187 ;; For forward branches, the address calculation returns the address of
7188 ;; the next instruction. This is 2 beyond the branch instruction.
7189 ;; For backward branches, the address calculation returns the address of
7190 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7191 ;; instruction for the shortest sequence, and 4 before the branch instruction
7192 ;; if we have to jump around an unconditional branch.
7193 ;; To the basic branch range the PC offset must be added (this is +4).
7194 ;; So for forward branches we have
7195 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7196 ;; And for backward branches we have
7197 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7198 ;;
7199 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7200 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7201
7202 (define_expand "cbranchsi4"
7203 [(set (pc) (if_then_else
7204 (match_operator 0 "expandable_comparison_operator"
7205 [(match_operand:SI 1 "s_register_operand" "")
7206 (match_operand:SI 2 "nonmemory_operand" "")])
7207 (label_ref (match_operand 3 "" ""))
7208 (pc)))]
7209 "TARGET_EITHER"
7210 "
7211 if (!TARGET_THUMB1)
7212 {
7213 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7214 FAIL;
7215 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7216 operands[3]));
7217 DONE;
7218 }
7219 if (thumb1_cmpneg_operand (operands[2], SImode))
7220 {
7221 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7222 operands[3], operands[0]));
7223 DONE;
7224 }
7225 if (!thumb1_cmp_operand (operands[2], SImode))
7226 operands[2] = force_reg (SImode, operands[2]);
7227 ")
7228
7229 (define_expand "cbranchsf4"
7230 [(set (pc) (if_then_else
7231 (match_operator 0 "expandable_comparison_operator"
7232 [(match_operand:SF 1 "s_register_operand" "")
7233 (match_operand:SF 2 "arm_float_compare_operand" "")])
7234 (label_ref (match_operand 3 "" ""))
7235 (pc)))]
7236 "TARGET_32BIT && TARGET_HARD_FLOAT"
7237 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7238 operands[3])); DONE;"
7239 )
7240
7241 (define_expand "cbranchdf4"
7242 [(set (pc) (if_then_else
7243 (match_operator 0 "expandable_comparison_operator"
7244 [(match_operand:DF 1 "s_register_operand" "")
7245 (match_operand:DF 2 "arm_float_compare_operand" "")])
7246 (label_ref (match_operand 3 "" ""))
7247 (pc)))]
7248 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7249 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7250 operands[3])); DONE;"
7251 )
7252
7253 (define_expand "cbranchdi4"
7254 [(set (pc) (if_then_else
7255 (match_operator 0 "expandable_comparison_operator"
7256 [(match_operand:DI 1 "s_register_operand" "")
7257 (match_operand:DI 2 "cmpdi_operand" "")])
7258 (label_ref (match_operand 3 "" ""))
7259 (pc)))]
7260 "TARGET_32BIT"
7261 "{
7262 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7263 FAIL;
7264 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7265 operands[3]));
7266 DONE;
7267 }"
7268 )
7269
7270 ;; Comparison and test insns
7271
7272 (define_insn "*arm_cmpsi_insn"
7273 [(set (reg:CC CC_REGNUM)
7274 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7275 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7276 "TARGET_32BIT"
7277 "@
7278 cmp%?\\t%0, %1
7279 cmp%?\\t%0, %1
7280 cmp%?\\t%0, %1
7281 cmp%?\\t%0, %1
7282 cmn%?\\t%0, #%n1"
7283 [(set_attr "conds" "set")
7284 (set_attr "arch" "t2,t2,any,any,any")
7285 (set_attr "length" "2,2,4,4,4")
7286 (set_attr "predicable" "yes")
7287 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7288 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7289 )
7290
7291 (define_insn "*cmpsi_shiftsi"
7292 [(set (reg:CC CC_REGNUM)
7293 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7294 (match_operator:SI 3 "shift_operator"
7295 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7296 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7297 "TARGET_32BIT"
7298 "cmp\\t%0, %1%S3"
7299 [(set_attr "conds" "set")
7300 (set_attr "shift" "1")
7301 (set_attr "arch" "32,a,a")
7302 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7303
7304 (define_insn "*cmpsi_shiftsi_swp"
7305 [(set (reg:CC_SWP CC_REGNUM)
7306 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7307 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7308 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7309 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7310 "TARGET_32BIT"
7311 "cmp%?\\t%0, %1%S3"
7312 [(set_attr "conds" "set")
7313 (set_attr "shift" "1")
7314 (set_attr "arch" "32,a,a")
7315 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7316
7317 (define_insn "*arm_cmpsi_negshiftsi_si"
7318 [(set (reg:CC_Z CC_REGNUM)
7319 (compare:CC_Z
7320 (neg:SI (match_operator:SI 1 "shift_operator"
7321 [(match_operand:SI 2 "s_register_operand" "r")
7322 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7323 (match_operand:SI 0 "s_register_operand" "r")))]
7324 "TARGET_ARM"
7325 "cmn%?\\t%0, %2%S1"
7326 [(set_attr "conds" "set")
7327 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7328 (const_string "alus_shift_imm")
7329 (const_string "alus_shift_reg")))
7330 (set_attr "predicable" "yes")]
7331 )
7332
7333 ;; DImode comparisons. The generic code generates branches that
7334 ;; if-conversion can not reduce to a conditional compare, so we do
7335 ;; that directly.
7336
7337 (define_insn_and_split "*arm_cmpdi_insn"
7338 [(set (reg:CC_NCV CC_REGNUM)
7339 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7340 (match_operand:DI 1 "arm_di_operand" "rDi")))
7341 (clobber (match_scratch:SI 2 "=r"))]
7342 "TARGET_32BIT"
7343 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7344 "&& reload_completed"
7345 [(set (reg:CC CC_REGNUM)
7346 (compare:CC (match_dup 0) (match_dup 1)))
7347 (parallel [(set (reg:CC CC_REGNUM)
7348 (compare:CC (match_dup 3) (match_dup 4)))
7349 (set (match_dup 2)
7350 (minus:SI (match_dup 5)
7351 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7352 {
7353 operands[3] = gen_highpart (SImode, operands[0]);
7354 operands[0] = gen_lowpart (SImode, operands[0]);
7355 if (CONST_INT_P (operands[1]))
7356 {
7357 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7358 DImode,
7359 operands[1])));
7360 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7361 }
7362 else
7363 {
7364 operands[4] = gen_highpart (SImode, operands[1]);
7365 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7366 }
7367 operands[1] = gen_lowpart (SImode, operands[1]);
7368 operands[2] = gen_lowpart (SImode, operands[2]);
7369 }
7370 [(set_attr "conds" "set")
7371 (set_attr "length" "8")
7372 (set_attr "type" "multiple")]
7373 )
7374
7375 (define_insn_and_split "*arm_cmpdi_unsigned"
7376 [(set (reg:CC_CZ CC_REGNUM)
7377 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7378 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7379
7380 "TARGET_32BIT"
7381 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7382 "&& reload_completed"
7383 [(set (reg:CC CC_REGNUM)
7384 (compare:CC (match_dup 2) (match_dup 3)))
7385 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7386 (set (reg:CC CC_REGNUM)
7387 (compare:CC (match_dup 0) (match_dup 1))))]
7388 {
7389 operands[2] = gen_highpart (SImode, operands[0]);
7390 operands[0] = gen_lowpart (SImode, operands[0]);
7391 if (CONST_INT_P (operands[1]))
7392 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7393 else
7394 operands[3] = gen_highpart (SImode, operands[1]);
7395 operands[1] = gen_lowpart (SImode, operands[1]);
7396 }
7397 [(set_attr "conds" "set")
7398 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7399 (set_attr "arch" "t2,t2,t2,a")
7400 (set_attr "length" "6,6,10,8")
7401 (set_attr "type" "multiple")]
7402 )
7403
7404 (define_insn "*arm_cmpdi_zero"
7405 [(set (reg:CC_Z CC_REGNUM)
7406 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7407 (const_int 0)))
7408 (clobber (match_scratch:SI 1 "=r"))]
7409 "TARGET_32BIT"
7410 "orrs%?\\t%1, %Q0, %R0"
7411 [(set_attr "conds" "set")
7412 (set_attr "type" "logics_reg")]
7413 )
7414
7415 ; This insn allows redundant compares to be removed by cse, nothing should
7416 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7417 ; is deleted later on. The match_dup will match the mode here, so that
7418 ; mode changes of the condition codes aren't lost by this even though we don't
7419 ; specify what they are.
7420
7421 (define_insn "*deleted_compare"
7422 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7423 "TARGET_32BIT"
7424 "\\t%@ deleted compare"
7425 [(set_attr "conds" "set")
7426 (set_attr "length" "0")
7427 (set_attr "type" "no_insn")]
7428 )
7429
7430 \f
7431 ;; Conditional branch insns
7432
7433 (define_expand "cbranch_cc"
7434 [(set (pc)
7435 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7436 (match_operand 2 "" "")])
7437 (label_ref (match_operand 3 "" ""))
7438 (pc)))]
7439 "TARGET_32BIT"
7440 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7441 operands[1], operands[2], NULL_RTX);
7442 operands[2] = const0_rtx;"
7443 )
7444
7445 ;;
7446 ;; Patterns to match conditional branch insns.
7447 ;;
7448
7449 (define_insn "arm_cond_branch"
7450 [(set (pc)
7451 (if_then_else (match_operator 1 "arm_comparison_operator"
7452 [(match_operand 2 "cc_register" "") (const_int 0)])
7453 (label_ref (match_operand 0 "" ""))
7454 (pc)))]
7455 "TARGET_32BIT"
7456 "*
7457 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7458 {
7459 arm_ccfsm_state += 2;
7460 return \"\";
7461 }
7462 return \"b%d1\\t%l0\";
7463 "
7464 [(set_attr "conds" "use")
7465 (set_attr "type" "branch")
7466 (set (attr "length")
7467 (if_then_else
7468 (and (match_test "TARGET_THUMB2")
7469 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7470 (le (minus (match_dup 0) (pc)) (const_int 256))))
7471 (const_int 2)
7472 (const_int 4)))]
7473 )
7474
7475 (define_insn "*arm_cond_branch_reversed"
7476 [(set (pc)
7477 (if_then_else (match_operator 1 "arm_comparison_operator"
7478 [(match_operand 2 "cc_register" "") (const_int 0)])
7479 (pc)
7480 (label_ref (match_operand 0 "" ""))))]
7481 "TARGET_32BIT"
7482 "*
7483 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7484 {
7485 arm_ccfsm_state += 2;
7486 return \"\";
7487 }
7488 return \"b%D1\\t%l0\";
7489 "
7490 [(set_attr "conds" "use")
7491 (set_attr "type" "branch")
7492 (set (attr "length")
7493 (if_then_else
7494 (and (match_test "TARGET_THUMB2")
7495 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7496 (le (minus (match_dup 0) (pc)) (const_int 256))))
7497 (const_int 2)
7498 (const_int 4)))]
7499 )
7500
7501 \f
7502
7503 ; scc insns
7504
7505 (define_expand "cstore_cc"
7506 [(set (match_operand:SI 0 "s_register_operand" "")
7507 (match_operator:SI 1 "" [(match_operand 2 "" "")
7508 (match_operand 3 "" "")]))]
7509 "TARGET_32BIT"
7510 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7511 operands[2], operands[3], NULL_RTX);
7512 operands[3] = const0_rtx;"
7513 )
7514
7515 (define_insn_and_split "*mov_scc"
7516 [(set (match_operand:SI 0 "s_register_operand" "=r")
7517 (match_operator:SI 1 "arm_comparison_operator_mode"
7518 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7519 "TARGET_ARM"
7520 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7521 "TARGET_ARM"
7522 [(set (match_dup 0)
7523 (if_then_else:SI (match_dup 1)
7524 (const_int 1)
7525 (const_int 0)))]
7526 ""
7527 [(set_attr "conds" "use")
7528 (set_attr "length" "8")
7529 (set_attr "type" "multiple")]
7530 )
7531
7532 (define_insn_and_split "*mov_negscc"
7533 [(set (match_operand:SI 0 "s_register_operand" "=r")
7534 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7535 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7536 "TARGET_ARM"
7537 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7538 "TARGET_ARM"
7539 [(set (match_dup 0)
7540 (if_then_else:SI (match_dup 1)
7541 (match_dup 3)
7542 (const_int 0)))]
7543 {
7544 operands[3] = GEN_INT (~0);
7545 }
7546 [(set_attr "conds" "use")
7547 (set_attr "length" "8")
7548 (set_attr "type" "multiple")]
7549 )
7550
7551 (define_insn_and_split "*mov_notscc"
7552 [(set (match_operand:SI 0 "s_register_operand" "=r")
7553 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7554 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7555 "TARGET_ARM"
7556 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7557 "TARGET_ARM"
7558 [(set (match_dup 0)
7559 (if_then_else:SI (match_dup 1)
7560 (match_dup 3)
7561 (match_dup 4)))]
7562 {
7563 operands[3] = GEN_INT (~1);
7564 operands[4] = GEN_INT (~0);
7565 }
7566 [(set_attr "conds" "use")
7567 (set_attr "length" "8")
7568 (set_attr "type" "multiple")]
7569 )
7570
7571 (define_expand "cstoresi4"
7572 [(set (match_operand:SI 0 "s_register_operand" "")
7573 (match_operator:SI 1 "expandable_comparison_operator"
7574 [(match_operand:SI 2 "s_register_operand" "")
7575 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7576 "TARGET_32BIT || TARGET_THUMB1"
7577 "{
7578 rtx op3, scratch, scratch2;
7579
7580 if (!TARGET_THUMB1)
7581 {
7582 if (!arm_add_operand (operands[3], SImode))
7583 operands[3] = force_reg (SImode, operands[3]);
7584 emit_insn (gen_cstore_cc (operands[0], operands[1],
7585 operands[2], operands[3]));
7586 DONE;
7587 }
7588
7589 if (operands[3] == const0_rtx)
7590 {
7591 switch (GET_CODE (operands[1]))
7592 {
7593 case EQ:
7594 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7595 break;
7596
7597 case NE:
7598 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7599 break;
7600
7601 case LE:
7602 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7603 NULL_RTX, 0, OPTAB_WIDEN);
7604 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7605 NULL_RTX, 0, OPTAB_WIDEN);
7606 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7607 operands[0], 1, OPTAB_WIDEN);
7608 break;
7609
7610 case GE:
7611 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7612 NULL_RTX, 1);
7613 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7614 NULL_RTX, 1, OPTAB_WIDEN);
7615 break;
7616
7617 case GT:
7618 scratch = expand_binop (SImode, ashr_optab, operands[2],
7619 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7620 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7621 NULL_RTX, 0, OPTAB_WIDEN);
7622 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7623 0, OPTAB_WIDEN);
7624 break;
7625
7626 /* LT is handled by generic code. No need for unsigned with 0. */
7627 default:
7628 FAIL;
7629 }
7630 DONE;
7631 }
7632
7633 switch (GET_CODE (operands[1]))
7634 {
7635 case EQ:
7636 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7637 NULL_RTX, 0, OPTAB_WIDEN);
7638 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7639 break;
7640
7641 case NE:
7642 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7643 NULL_RTX, 0, OPTAB_WIDEN);
7644 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7645 break;
7646
7647 case LE:
7648 op3 = force_reg (SImode, operands[3]);
7649
7650 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7651 NULL_RTX, 1, OPTAB_WIDEN);
7652 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7653 NULL_RTX, 0, OPTAB_WIDEN);
7654 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7655 op3, operands[2]));
7656 break;
7657
7658 case GE:
7659 op3 = operands[3];
7660 if (!thumb1_cmp_operand (op3, SImode))
7661 op3 = force_reg (SImode, op3);
7662 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7663 NULL_RTX, 0, OPTAB_WIDEN);
7664 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7665 NULL_RTX, 1, OPTAB_WIDEN);
7666 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7667 operands[2], op3));
7668 break;
7669
7670 case LEU:
7671 op3 = force_reg (SImode, operands[3]);
7672 scratch = force_reg (SImode, const0_rtx);
7673 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7674 op3, operands[2]));
7675 break;
7676
7677 case GEU:
7678 op3 = operands[3];
7679 if (!thumb1_cmp_operand (op3, SImode))
7680 op3 = force_reg (SImode, op3);
7681 scratch = force_reg (SImode, const0_rtx);
7682 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7683 operands[2], op3));
7684 break;
7685
7686 case LTU:
7687 op3 = operands[3];
7688 if (!thumb1_cmp_operand (op3, SImode))
7689 op3 = force_reg (SImode, op3);
7690 scratch = gen_reg_rtx (SImode);
7691 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7692 break;
7693
7694 case GTU:
7695 op3 = force_reg (SImode, operands[3]);
7696 scratch = gen_reg_rtx (SImode);
7697 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7698 break;
7699
7700 /* No good sequences for GT, LT. */
7701 default:
7702 FAIL;
7703 }
7704 DONE;
7705 }")
7706
7707 (define_expand "cstoresf4"
7708 [(set (match_operand:SI 0 "s_register_operand" "")
7709 (match_operator:SI 1 "expandable_comparison_operator"
7710 [(match_operand:SF 2 "s_register_operand" "")
7711 (match_operand:SF 3 "arm_float_compare_operand" "")]))]
7712 "TARGET_32BIT && TARGET_HARD_FLOAT"
7713 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7714 operands[2], operands[3])); DONE;"
7715 )
7716
7717 (define_expand "cstoredf4"
7718 [(set (match_operand:SI 0 "s_register_operand" "")
7719 (match_operator:SI 1 "expandable_comparison_operator"
7720 [(match_operand:DF 2 "s_register_operand" "")
7721 (match_operand:DF 3 "arm_float_compare_operand" "")]))]
7722 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7723 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7724 operands[2], operands[3])); DONE;"
7725 )
7726
7727 (define_expand "cstoredi4"
7728 [(set (match_operand:SI 0 "s_register_operand" "")
7729 (match_operator:SI 1 "expandable_comparison_operator"
7730 [(match_operand:DI 2 "s_register_operand" "")
7731 (match_operand:DI 3 "cmpdi_operand" "")]))]
7732 "TARGET_32BIT"
7733 "{
7734 if (!arm_validize_comparison (&operands[1],
7735 &operands[2],
7736 &operands[3]))
7737 FAIL;
7738 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7739 operands[3]));
7740 DONE;
7741 }"
7742 )
7743
7744 \f
7745 ;; Conditional move insns
7746
7747 (define_expand "movsicc"
7748 [(set (match_operand:SI 0 "s_register_operand" "")
7749 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7750 (match_operand:SI 2 "arm_not_operand" "")
7751 (match_operand:SI 3 "arm_not_operand" "")))]
7752 "TARGET_32BIT"
7753 "
7754 {
7755 enum rtx_code code;
7756 rtx ccreg;
7757
7758 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7759 &XEXP (operands[1], 1)))
7760 FAIL;
7761
7762 code = GET_CODE (operands[1]);
7763 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7764 XEXP (operands[1], 1), NULL_RTX);
7765 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7766 }"
7767 )
7768
7769 (define_expand "movsfcc"
7770 [(set (match_operand:SF 0 "s_register_operand" "")
7771 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7772 (match_operand:SF 2 "s_register_operand" "")
7773 (match_operand:SF 3 "s_register_operand" "")))]
7774 "TARGET_32BIT && TARGET_HARD_FLOAT"
7775 "
7776 {
7777 enum rtx_code code = GET_CODE (operands[1]);
7778 rtx ccreg;
7779
7780 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7781 &XEXP (operands[1], 1)))
7782 FAIL;
7783
7784 code = GET_CODE (operands[1]);
7785 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7786 XEXP (operands[1], 1), NULL_RTX);
7787 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7788 }"
7789 )
7790
7791 (define_expand "movdfcc"
7792 [(set (match_operand:DF 0 "s_register_operand" "")
7793 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7794 (match_operand:DF 2 "s_register_operand" "")
7795 (match_operand:DF 3 "s_register_operand" "")))]
7796 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7797 "
7798 {
7799 enum rtx_code code = GET_CODE (operands[1]);
7800 rtx ccreg;
7801
7802 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7803 &XEXP (operands[1], 1)))
7804 FAIL;
7805 code = GET_CODE (operands[1]);
7806 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7807 XEXP (operands[1], 1), NULL_RTX);
7808 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7809 }"
7810 )
7811
7812 (define_insn "*cmov<mode>"
7813 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7814 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7815 [(match_operand 2 "cc_register" "") (const_int 0)])
7816 (match_operand:SDF 3 "s_register_operand"
7817 "<F_constraint>")
7818 (match_operand:SDF 4 "s_register_operand"
7819 "<F_constraint>")))]
7820 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7821 "*
7822 {
7823 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7824 switch (code)
7825 {
7826 case ARM_GE:
7827 case ARM_GT:
7828 case ARM_EQ:
7829 case ARM_VS:
7830 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7831 case ARM_LT:
7832 case ARM_LE:
7833 case ARM_NE:
7834 case ARM_VC:
7835 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7836 default:
7837 gcc_unreachable ();
7838 }
7839 return \"\";
7840 }"
7841 [(set_attr "conds" "use")
7842 (set_attr "type" "fcsel")]
7843 )
7844
7845 (define_insn_and_split "*movsicc_insn"
7846 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7847 (if_then_else:SI
7848 (match_operator 3 "arm_comparison_operator"
7849 [(match_operand 4 "cc_register" "") (const_int 0)])
7850 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7851 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7852 "TARGET_ARM"
7853 "@
7854 mov%D3\\t%0, %2
7855 mvn%D3\\t%0, #%B2
7856 mov%d3\\t%0, %1
7857 mvn%d3\\t%0, #%B1
7858 #
7859 #
7860 #
7861 #"
7862 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7863 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7864 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7865 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7866 "&& reload_completed"
7867 [(const_int 0)]
7868 {
7869 enum rtx_code rev_code;
7870 machine_mode mode;
7871 rtx rev_cond;
7872
7873 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7874 operands[3],
7875 gen_rtx_SET (operands[0], operands[1])));
7876
7877 rev_code = GET_CODE (operands[3]);
7878 mode = GET_MODE (operands[4]);
7879 if (mode == CCFPmode || mode == CCFPEmode)
7880 rev_code = reverse_condition_maybe_unordered (rev_code);
7881 else
7882 rev_code = reverse_condition (rev_code);
7883
7884 rev_cond = gen_rtx_fmt_ee (rev_code,
7885 VOIDmode,
7886 operands[4],
7887 const0_rtx);
7888 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7889 rev_cond,
7890 gen_rtx_SET (operands[0], operands[2])));
7891 DONE;
7892 }
7893 [(set_attr "length" "4,4,4,4,8,8,8,8")
7894 (set_attr "conds" "use")
7895 (set_attr_alternative "type"
7896 [(if_then_else (match_operand 2 "const_int_operand" "")
7897 (const_string "mov_imm")
7898 (const_string "mov_reg"))
7899 (const_string "mvn_imm")
7900 (if_then_else (match_operand 1 "const_int_operand" "")
7901 (const_string "mov_imm")
7902 (const_string "mov_reg"))
7903 (const_string "mvn_imm")
7904 (const_string "multiple")
7905 (const_string "multiple")
7906 (const_string "multiple")
7907 (const_string "multiple")])]
7908 )
7909
7910 (define_insn "*movsfcc_soft_insn"
7911 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7912 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7913 [(match_operand 4 "cc_register" "") (const_int 0)])
7914 (match_operand:SF 1 "s_register_operand" "0,r")
7915 (match_operand:SF 2 "s_register_operand" "r,0")))]
7916 "TARGET_ARM && TARGET_SOFT_FLOAT"
7917 "@
7918 mov%D3\\t%0, %2
7919 mov%d3\\t%0, %1"
7920 [(set_attr "conds" "use")
7921 (set_attr "type" "mov_reg")]
7922 )
7923
7924 \f
7925 ;; Jump and linkage insns
7926
7927 (define_expand "jump"
7928 [(set (pc)
7929 (label_ref (match_operand 0 "" "")))]
7930 "TARGET_EITHER"
7931 ""
7932 )
7933
7934 (define_insn "*arm_jump"
7935 [(set (pc)
7936 (label_ref (match_operand 0 "" "")))]
7937 "TARGET_32BIT"
7938 "*
7939 {
7940 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7941 {
7942 arm_ccfsm_state += 2;
7943 return \"\";
7944 }
7945 return \"b%?\\t%l0\";
7946 }
7947 "
7948 [(set_attr "predicable" "yes")
7949 (set (attr "length")
7950 (if_then_else
7951 (and (match_test "TARGET_THUMB2")
7952 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7953 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7954 (const_int 2)
7955 (const_int 4)))
7956 (set_attr "type" "branch")]
7957 )
7958
7959 (define_expand "call"
7960 [(parallel [(call (match_operand 0 "memory_operand" "")
7961 (match_operand 1 "general_operand" ""))
7962 (use (match_operand 2 "" ""))
7963 (clobber (reg:SI LR_REGNUM))])]
7964 "TARGET_EITHER"
7965 "
7966 {
7967 rtx callee, pat;
7968
7969 /* In an untyped call, we can get NULL for operand 2. */
7970 if (operands[2] == NULL_RTX)
7971 operands[2] = const0_rtx;
7972
7973 /* Decide if we should generate indirect calls by loading the
7974 32-bit address of the callee into a register before performing the
7975 branch and link. */
7976 callee = XEXP (operands[0], 0);
7977 if (GET_CODE (callee) == SYMBOL_REF
7978 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7979 : !REG_P (callee))
7980 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7981
7982 pat = gen_call_internal (operands[0], operands[1], operands[2]);
7983 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7984 DONE;
7985 }"
7986 )
7987
7988 (define_expand "call_internal"
7989 [(parallel [(call (match_operand 0 "memory_operand" "")
7990 (match_operand 1 "general_operand" ""))
7991 (use (match_operand 2 "" ""))
7992 (clobber (reg:SI LR_REGNUM))])])
7993
7994 (define_insn "*call_reg_armv5"
7995 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7996 (match_operand 1 "" ""))
7997 (use (match_operand 2 "" ""))
7998 (clobber (reg:SI LR_REGNUM))]
7999 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8000 "blx%?\\t%0"
8001 [(set_attr "type" "call")]
8002 )
8003
8004 (define_insn "*call_reg_arm"
8005 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8006 (match_operand 1 "" ""))
8007 (use (match_operand 2 "" ""))
8008 (clobber (reg:SI LR_REGNUM))]
8009 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8010 "*
8011 return output_call (operands);
8012 "
8013 ;; length is worst case, normally it is only two
8014 [(set_attr "length" "12")
8015 (set_attr "type" "call")]
8016 )
8017
8018
8019 (define_expand "call_value"
8020 [(parallel [(set (match_operand 0 "" "")
8021 (call (match_operand 1 "memory_operand" "")
8022 (match_operand 2 "general_operand" "")))
8023 (use (match_operand 3 "" ""))
8024 (clobber (reg:SI LR_REGNUM))])]
8025 "TARGET_EITHER"
8026 "
8027 {
8028 rtx pat, callee;
8029
8030 /* In an untyped call, we can get NULL for operand 2. */
8031 if (operands[3] == 0)
8032 operands[3] = const0_rtx;
8033
8034 /* Decide if we should generate indirect calls by loading the
8035 32-bit address of the callee into a register before performing the
8036 branch and link. */
8037 callee = XEXP (operands[1], 0);
8038 if (GET_CODE (callee) == SYMBOL_REF
8039 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8040 : !REG_P (callee))
8041 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8042
8043 pat = gen_call_value_internal (operands[0], operands[1],
8044 operands[2], operands[3]);
8045 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8046 DONE;
8047 }"
8048 )
8049
8050 (define_expand "call_value_internal"
8051 [(parallel [(set (match_operand 0 "" "")
8052 (call (match_operand 1 "memory_operand" "")
8053 (match_operand 2 "general_operand" "")))
8054 (use (match_operand 3 "" ""))
8055 (clobber (reg:SI LR_REGNUM))])])
8056
8057 (define_insn "*call_value_reg_armv5"
8058 [(set (match_operand 0 "" "")
8059 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8060 (match_operand 2 "" "")))
8061 (use (match_operand 3 "" ""))
8062 (clobber (reg:SI LR_REGNUM))]
8063 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8064 "blx%?\\t%1"
8065 [(set_attr "type" "call")]
8066 )
8067
8068 (define_insn "*call_value_reg_arm"
8069 [(set (match_operand 0 "" "")
8070 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8071 (match_operand 2 "" "")))
8072 (use (match_operand 3 "" ""))
8073 (clobber (reg:SI LR_REGNUM))]
8074 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8075 "*
8076 return output_call (&operands[1]);
8077 "
8078 [(set_attr "length" "12")
8079 (set_attr "type" "call")]
8080 )
8081
8082 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8083 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8084
8085 (define_insn "*call_symbol"
8086 [(call (mem:SI (match_operand:SI 0 "" ""))
8087 (match_operand 1 "" ""))
8088 (use (match_operand 2 "" ""))
8089 (clobber (reg:SI LR_REGNUM))]
8090 "TARGET_32BIT
8091 && !SIBLING_CALL_P (insn)
8092 && (GET_CODE (operands[0]) == SYMBOL_REF)
8093 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8094 "*
8095 {
8096 rtx op = operands[0];
8097
8098 /* Switch mode now when possible. */
8099 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8100 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8101 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8102
8103 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8104 }"
8105 [(set_attr "type" "call")]
8106 )
8107
8108 (define_insn "*call_value_symbol"
8109 [(set (match_operand 0 "" "")
8110 (call (mem:SI (match_operand:SI 1 "" ""))
8111 (match_operand:SI 2 "" "")))
8112 (use (match_operand 3 "" ""))
8113 (clobber (reg:SI LR_REGNUM))]
8114 "TARGET_32BIT
8115 && !SIBLING_CALL_P (insn)
8116 && (GET_CODE (operands[1]) == SYMBOL_REF)
8117 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8118 "*
8119 {
8120 rtx op = operands[1];
8121
8122 /* Switch mode now when possible. */
8123 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8124 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8125 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8126
8127 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8128 }"
8129 [(set_attr "type" "call")]
8130 )
8131
8132 (define_expand "sibcall_internal"
8133 [(parallel [(call (match_operand 0 "memory_operand" "")
8134 (match_operand 1 "general_operand" ""))
8135 (return)
8136 (use (match_operand 2 "" ""))])])
8137
8138 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8139 (define_expand "sibcall"
8140 [(parallel [(call (match_operand 0 "memory_operand" "")
8141 (match_operand 1 "general_operand" ""))
8142 (return)
8143 (use (match_operand 2 "" ""))])]
8144 "TARGET_32BIT"
8145 "
8146 {
8147 rtx pat;
8148
8149 if ((!REG_P (XEXP (operands[0], 0))
8150 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8151 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8152 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8153 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8154
8155 if (operands[2] == NULL_RTX)
8156 operands[2] = const0_rtx;
8157
8158 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8159 arm_emit_call_insn (pat, operands[0], true);
8160 DONE;
8161 }"
8162 )
8163
8164 (define_expand "sibcall_value_internal"
8165 [(parallel [(set (match_operand 0 "" "")
8166 (call (match_operand 1 "memory_operand" "")
8167 (match_operand 2 "general_operand" "")))
8168 (return)
8169 (use (match_operand 3 "" ""))])])
8170
8171 (define_expand "sibcall_value"
8172 [(parallel [(set (match_operand 0 "" "")
8173 (call (match_operand 1 "memory_operand" "")
8174 (match_operand 2 "general_operand" "")))
8175 (return)
8176 (use (match_operand 3 "" ""))])]
8177 "TARGET_32BIT"
8178 "
8179 {
8180 rtx pat;
8181
8182 if ((!REG_P (XEXP (operands[1], 0))
8183 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8184 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8185 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8186 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8187
8188 if (operands[3] == NULL_RTX)
8189 operands[3] = const0_rtx;
8190
8191 pat = gen_sibcall_value_internal (operands[0], operands[1],
8192 operands[2], operands[3]);
8193 arm_emit_call_insn (pat, operands[1], true);
8194 DONE;
8195 }"
8196 )
8197
8198 (define_insn "*sibcall_insn"
8199 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8200 (match_operand 1 "" ""))
8201 (return)
8202 (use (match_operand 2 "" ""))]
8203 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8204 "*
8205 if (which_alternative == 1)
8206 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8207 else
8208 {
8209 if (arm_arch5 || arm_arch4t)
8210 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8211 else
8212 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8213 }
8214 "
8215 [(set_attr "type" "call")]
8216 )
8217
8218 (define_insn "*sibcall_value_insn"
8219 [(set (match_operand 0 "" "")
8220 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8221 (match_operand 2 "" "")))
8222 (return)
8223 (use (match_operand 3 "" ""))]
8224 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8225 "*
8226 if (which_alternative == 1)
8227 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8228 else
8229 {
8230 if (arm_arch5 || arm_arch4t)
8231 return \"bx%?\\t%1\";
8232 else
8233 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8234 }
8235 "
8236 [(set_attr "type" "call")]
8237 )
8238
8239 (define_expand "<return_str>return"
8240 [(RETURNS)]
8241 "(TARGET_ARM || (TARGET_THUMB2
8242 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8243 && !IS_STACKALIGN (arm_current_func_type ())))
8244 <return_cond_false>"
8245 "
8246 {
8247 if (TARGET_THUMB2)
8248 {
8249 thumb2_expand_return (<return_simple_p>);
8250 DONE;
8251 }
8252 }
8253 "
8254 )
8255
8256 ;; Often the return insn will be the same as loading from memory, so set attr
8257 (define_insn "*arm_return"
8258 [(return)]
8259 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8260 "*
8261 {
8262 if (arm_ccfsm_state == 2)
8263 {
8264 arm_ccfsm_state += 2;
8265 return \"\";
8266 }
8267 return output_return_instruction (const_true_rtx, true, false, false);
8268 }"
8269 [(set_attr "type" "load1")
8270 (set_attr "length" "12")
8271 (set_attr "predicable" "yes")]
8272 )
8273
8274 (define_insn "*cond_<return_str>return"
8275 [(set (pc)
8276 (if_then_else (match_operator 0 "arm_comparison_operator"
8277 [(match_operand 1 "cc_register" "") (const_int 0)])
8278 (RETURNS)
8279 (pc)))]
8280 "TARGET_ARM <return_cond_true>"
8281 "*
8282 {
8283 if (arm_ccfsm_state == 2)
8284 {
8285 arm_ccfsm_state += 2;
8286 return \"\";
8287 }
8288 return output_return_instruction (operands[0], true, false,
8289 <return_simple_p>);
8290 }"
8291 [(set_attr "conds" "use")
8292 (set_attr "length" "12")
8293 (set_attr "type" "load1")]
8294 )
8295
8296 (define_insn "*cond_<return_str>return_inverted"
8297 [(set (pc)
8298 (if_then_else (match_operator 0 "arm_comparison_operator"
8299 [(match_operand 1 "cc_register" "") (const_int 0)])
8300 (pc)
8301 (RETURNS)))]
8302 "TARGET_ARM <return_cond_true>"
8303 "*
8304 {
8305 if (arm_ccfsm_state == 2)
8306 {
8307 arm_ccfsm_state += 2;
8308 return \"\";
8309 }
8310 return output_return_instruction (operands[0], true, true,
8311 <return_simple_p>);
8312 }"
8313 [(set_attr "conds" "use")
8314 (set_attr "length" "12")
8315 (set_attr "type" "load1")]
8316 )
8317
8318 (define_insn "*arm_simple_return"
8319 [(simple_return)]
8320 "TARGET_ARM"
8321 "*
8322 {
8323 if (arm_ccfsm_state == 2)
8324 {
8325 arm_ccfsm_state += 2;
8326 return \"\";
8327 }
8328 return output_return_instruction (const_true_rtx, true, false, true);
8329 }"
8330 [(set_attr "type" "branch")
8331 (set_attr "length" "4")
8332 (set_attr "predicable" "yes")]
8333 )
8334
8335 ;; Generate a sequence of instructions to determine if the processor is
8336 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8337 ;; mask.
8338
8339 (define_expand "return_addr_mask"
8340 [(set (match_dup 1)
8341 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8342 (const_int 0)))
8343 (set (match_operand:SI 0 "s_register_operand" "")
8344 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8345 (const_int -1)
8346 (const_int 67108860)))] ; 0x03fffffc
8347 "TARGET_ARM"
8348 "
8349 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8350 ")
8351
8352 (define_insn "*check_arch2"
8353 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8354 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8355 (const_int 0)))]
8356 "TARGET_ARM"
8357 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8358 [(set_attr "length" "8")
8359 (set_attr "conds" "set")
8360 (set_attr "type" "multiple")]
8361 )
8362
8363 ;; Call subroutine returning any type.
8364
8365 (define_expand "untyped_call"
8366 [(parallel [(call (match_operand 0 "" "")
8367 (const_int 0))
8368 (match_operand 1 "" "")
8369 (match_operand 2 "" "")])]
8370 "TARGET_EITHER"
8371 "
8372 {
8373 int i;
8374 rtx par = gen_rtx_PARALLEL (VOIDmode,
8375 rtvec_alloc (XVECLEN (operands[2], 0)));
8376 rtx addr = gen_reg_rtx (Pmode);
8377 rtx mem;
8378 int size = 0;
8379
8380 emit_move_insn (addr, XEXP (operands[1], 0));
8381 mem = change_address (operands[1], BLKmode, addr);
8382
8383 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8384 {
8385 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8386
8387 /* Default code only uses r0 as a return value, but we could
8388 be using anything up to 4 registers. */
8389 if (REGNO (src) == R0_REGNUM)
8390 src = gen_rtx_REG (TImode, R0_REGNUM);
8391
8392 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8393 GEN_INT (size));
8394 size += GET_MODE_SIZE (GET_MODE (src));
8395 }
8396
8397 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8398
8399 size = 0;
8400
8401 for (i = 0; i < XVECLEN (par, 0); i++)
8402 {
8403 HOST_WIDE_INT offset = 0;
8404 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8405
8406 if (size != 0)
8407 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8408
8409 mem = change_address (mem, GET_MODE (reg), NULL);
8410 if (REGNO (reg) == R0_REGNUM)
8411 {
8412 /* On thumb we have to use a write-back instruction. */
8413 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8414 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8415 size = TARGET_ARM ? 16 : 0;
8416 }
8417 else
8418 {
8419 emit_move_insn (mem, reg);
8420 size = GET_MODE_SIZE (GET_MODE (reg));
8421 }
8422 }
8423
8424 /* The optimizer does not know that the call sets the function value
8425 registers we stored in the result block. We avoid problems by
8426 claiming that all hard registers are used and clobbered at this
8427 point. */
8428 emit_insn (gen_blockage ());
8429
8430 DONE;
8431 }"
8432 )
8433
8434 (define_expand "untyped_return"
8435 [(match_operand:BLK 0 "memory_operand" "")
8436 (match_operand 1 "" "")]
8437 "TARGET_EITHER"
8438 "
8439 {
8440 int i;
8441 rtx addr = gen_reg_rtx (Pmode);
8442 rtx mem;
8443 int size = 0;
8444
8445 emit_move_insn (addr, XEXP (operands[0], 0));
8446 mem = change_address (operands[0], BLKmode, addr);
8447
8448 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8449 {
8450 HOST_WIDE_INT offset = 0;
8451 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8452
8453 if (size != 0)
8454 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8455
8456 mem = change_address (mem, GET_MODE (reg), NULL);
8457 if (REGNO (reg) == R0_REGNUM)
8458 {
8459 /* On thumb we have to use a write-back instruction. */
8460 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8461 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8462 size = TARGET_ARM ? 16 : 0;
8463 }
8464 else
8465 {
8466 emit_move_insn (reg, mem);
8467 size = GET_MODE_SIZE (GET_MODE (reg));
8468 }
8469 }
8470
8471 /* Emit USE insns before the return. */
8472 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8473 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8474
8475 /* Construct the return. */
8476 expand_naked_return ();
8477
8478 DONE;
8479 }"
8480 )
8481
8482 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8483 ;; all of memory. This blocks insns from being moved across this point.
8484
8485 (define_insn "blockage"
8486 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8487 "TARGET_EITHER"
8488 ""
8489 [(set_attr "length" "0")
8490 (set_attr "type" "block")]
8491 )
8492
8493 (define_insn "probe_stack"
8494 [(set (match_operand:SI 0 "memory_operand" "=m")
8495 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8496 "TARGET_32BIT"
8497 "str%?\\tr0, %0"
8498 [(set_attr "type" "store1")
8499 (set_attr "predicable" "yes")]
8500 )
8501
8502 (define_insn "probe_stack_range"
8503 [(set (match_operand:SI 0 "register_operand" "=r")
8504 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8505 (match_operand:SI 2 "register_operand" "r")]
8506 VUNSPEC_PROBE_STACK_RANGE))]
8507 "TARGET_32BIT"
8508 {
8509 return output_probe_stack_range (operands[0], operands[2]);
8510 }
8511 [(set_attr "type" "multiple")
8512 (set_attr "conds" "clob")]
8513 )
8514
8515 (define_expand "casesi"
8516 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8517 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8518 (match_operand:SI 2 "const_int_operand" "") ; total range
8519 (match_operand:SI 3 "" "") ; table label
8520 (match_operand:SI 4 "" "")] ; Out of range label
8521 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8522 "
8523 {
8524 enum insn_code code;
8525 if (operands[1] != const0_rtx)
8526 {
8527 rtx reg = gen_reg_rtx (SImode);
8528
8529 emit_insn (gen_addsi3 (reg, operands[0],
8530 gen_int_mode (-INTVAL (operands[1]),
8531 SImode)));
8532 operands[0] = reg;
8533 }
8534
8535 if (TARGET_ARM)
8536 code = CODE_FOR_arm_casesi_internal;
8537 else if (TARGET_THUMB1)
8538 code = CODE_FOR_thumb1_casesi_internal_pic;
8539 else if (flag_pic)
8540 code = CODE_FOR_thumb2_casesi_internal_pic;
8541 else
8542 code = CODE_FOR_thumb2_casesi_internal;
8543
8544 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8545 operands[2] = force_reg (SImode, operands[2]);
8546
8547 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8548 operands[3], operands[4]));
8549 DONE;
8550 }"
8551 )
8552
8553 ;; The USE in this pattern is needed to tell flow analysis that this is
8554 ;; a CASESI insn. It has no other purpose.
8555 (define_insn "arm_casesi_internal"
8556 [(parallel [(set (pc)
8557 (if_then_else
8558 (leu (match_operand:SI 0 "s_register_operand" "r")
8559 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8560 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8561 (label_ref (match_operand 2 "" ""))))
8562 (label_ref (match_operand 3 "" ""))))
8563 (clobber (reg:CC CC_REGNUM))
8564 (use (label_ref (match_dup 2)))])]
8565 "TARGET_ARM"
8566 "*
8567 if (flag_pic)
8568 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8569 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8570 "
8571 [(set_attr "conds" "clob")
8572 (set_attr "length" "12")
8573 (set_attr "type" "multiple")]
8574 )
8575
8576 (define_expand "indirect_jump"
8577 [(set (pc)
8578 (match_operand:SI 0 "s_register_operand" ""))]
8579 "TARGET_EITHER"
8580 "
8581 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8582 address and use bx. */
8583 if (TARGET_THUMB2)
8584 {
8585 rtx tmp;
8586 tmp = gen_reg_rtx (SImode);
8587 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8588 operands[0] = tmp;
8589 }
8590 "
8591 )
8592
8593 ;; NB Never uses BX.
8594 (define_insn "*arm_indirect_jump"
8595 [(set (pc)
8596 (match_operand:SI 0 "s_register_operand" "r"))]
8597 "TARGET_ARM"
8598 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8599 [(set_attr "predicable" "yes")
8600 (set_attr "type" "branch")]
8601 )
8602
8603 (define_insn "*load_indirect_jump"
8604 [(set (pc)
8605 (match_operand:SI 0 "memory_operand" "m"))]
8606 "TARGET_ARM"
8607 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8608 [(set_attr "type" "load1")
8609 (set_attr "pool_range" "4096")
8610 (set_attr "neg_pool_range" "4084")
8611 (set_attr "predicable" "yes")]
8612 )
8613
8614 \f
8615 ;; Misc insns
8616
8617 (define_insn "nop"
8618 [(const_int 0)]
8619 "TARGET_EITHER"
8620 "nop"
8621 [(set (attr "length")
8622 (if_then_else (eq_attr "is_thumb" "yes")
8623 (const_int 2)
8624 (const_int 4)))
8625 (set_attr "type" "mov_reg")]
8626 )
8627
8628 (define_insn "trap"
8629 [(trap_if (const_int 1) (const_int 0))]
8630 ""
8631 "*
8632 if (TARGET_ARM)
8633 return \".inst\\t0xe7f000f0\";
8634 else
8635 return \".inst\\t0xdeff\";
8636 "
8637 [(set (attr "length")
8638 (if_then_else (eq_attr "is_thumb" "yes")
8639 (const_int 2)
8640 (const_int 4)))
8641 (set_attr "type" "trap")
8642 (set_attr "conds" "unconditional")]
8643 )
8644
8645 \f
8646 ;; Patterns to allow combination of arithmetic, cond code and shifts
8647
8648 (define_insn "*<arith_shift_insn>_multsi"
8649 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8650 (SHIFTABLE_OPS:SI
8651 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8652 (match_operand:SI 3 "power_of_two_operand" ""))
8653 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8654 "TARGET_32BIT"
8655 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8656 [(set_attr "predicable" "yes")
8657 (set_attr "predicable_short_it" "no")
8658 (set_attr "shift" "2")
8659 (set_attr "arch" "a,t2")
8660 (set_attr "type" "alu_shift_imm")])
8661
8662 (define_insn "*<arith_shift_insn>_shiftsi"
8663 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8664 (SHIFTABLE_OPS:SI
8665 (match_operator:SI 2 "shift_nomul_operator"
8666 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8667 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8668 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8669 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8670 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8671 [(set_attr "predicable" "yes")
8672 (set_attr "predicable_short_it" "no")
8673 (set_attr "shift" "3")
8674 (set_attr "arch" "a,t2,a")
8675 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8676
8677 (define_split
8678 [(set (match_operand:SI 0 "s_register_operand" "")
8679 (match_operator:SI 1 "shiftable_operator"
8680 [(match_operator:SI 2 "shiftable_operator"
8681 [(match_operator:SI 3 "shift_operator"
8682 [(match_operand:SI 4 "s_register_operand" "")
8683 (match_operand:SI 5 "reg_or_int_operand" "")])
8684 (match_operand:SI 6 "s_register_operand" "")])
8685 (match_operand:SI 7 "arm_rhs_operand" "")]))
8686 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8687 "TARGET_32BIT"
8688 [(set (match_dup 8)
8689 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8690 (match_dup 6)]))
8691 (set (match_dup 0)
8692 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8693 "")
8694
8695 (define_insn "*arith_shiftsi_compare0"
8696 [(set (reg:CC_NOOV CC_REGNUM)
8697 (compare:CC_NOOV
8698 (match_operator:SI 1 "shiftable_operator"
8699 [(match_operator:SI 3 "shift_operator"
8700 [(match_operand:SI 4 "s_register_operand" "r,r")
8701 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8702 (match_operand:SI 2 "s_register_operand" "r,r")])
8703 (const_int 0)))
8704 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8705 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8706 (match_dup 2)]))]
8707 "TARGET_32BIT"
8708 "%i1s%?\\t%0, %2, %4%S3"
8709 [(set_attr "conds" "set")
8710 (set_attr "shift" "4")
8711 (set_attr "arch" "32,a")
8712 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8713
8714 (define_insn "*arith_shiftsi_compare0_scratch"
8715 [(set (reg:CC_NOOV CC_REGNUM)
8716 (compare:CC_NOOV
8717 (match_operator:SI 1 "shiftable_operator"
8718 [(match_operator:SI 3 "shift_operator"
8719 [(match_operand:SI 4 "s_register_operand" "r,r")
8720 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8721 (match_operand:SI 2 "s_register_operand" "r,r")])
8722 (const_int 0)))
8723 (clobber (match_scratch:SI 0 "=r,r"))]
8724 "TARGET_32BIT"
8725 "%i1s%?\\t%0, %2, %4%S3"
8726 [(set_attr "conds" "set")
8727 (set_attr "shift" "4")
8728 (set_attr "arch" "32,a")
8729 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8730
8731 (define_insn "*sub_shiftsi"
8732 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8733 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8734 (match_operator:SI 2 "shift_operator"
8735 [(match_operand:SI 3 "s_register_operand" "r,r")
8736 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8737 "TARGET_32BIT"
8738 "sub%?\\t%0, %1, %3%S2"
8739 [(set_attr "predicable" "yes")
8740 (set_attr "shift" "3")
8741 (set_attr "arch" "32,a")
8742 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8743
8744 (define_insn "*sub_shiftsi_compare0"
8745 [(set (reg:CC_NOOV CC_REGNUM)
8746 (compare:CC_NOOV
8747 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8748 (match_operator:SI 2 "shift_operator"
8749 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8750 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8751 (const_int 0)))
8752 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8753 (minus:SI (match_dup 1)
8754 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8755 "TARGET_32BIT"
8756 "subs%?\\t%0, %1, %3%S2"
8757 [(set_attr "conds" "set")
8758 (set_attr "shift" "3")
8759 (set_attr "arch" "32,a,a")
8760 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8761
8762 (define_insn "*sub_shiftsi_compare0_scratch"
8763 [(set (reg:CC_NOOV CC_REGNUM)
8764 (compare:CC_NOOV
8765 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8766 (match_operator:SI 2 "shift_operator"
8767 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8768 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8769 (const_int 0)))
8770 (clobber (match_scratch:SI 0 "=r,r,r"))]
8771 "TARGET_32BIT"
8772 "subs%?\\t%0, %1, %3%S2"
8773 [(set_attr "conds" "set")
8774 (set_attr "shift" "3")
8775 (set_attr "arch" "32,a,a")
8776 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8777 \f
8778
8779 (define_insn_and_split "*and_scc"
8780 [(set (match_operand:SI 0 "s_register_operand" "=r")
8781 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8782 [(match_operand 2 "cc_register" "") (const_int 0)])
8783 (match_operand:SI 3 "s_register_operand" "r")))]
8784 "TARGET_ARM"
8785 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8786 "&& reload_completed"
8787 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8788 (cond_exec (match_dup 4) (set (match_dup 0)
8789 (and:SI (match_dup 3) (const_int 1))))]
8790 {
8791 machine_mode mode = GET_MODE (operands[2]);
8792 enum rtx_code rc = GET_CODE (operands[1]);
8793
8794 /* Note that operands[4] is the same as operands[1],
8795 but with VOIDmode as the result. */
8796 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8797 if (mode == CCFPmode || mode == CCFPEmode)
8798 rc = reverse_condition_maybe_unordered (rc);
8799 else
8800 rc = reverse_condition (rc);
8801 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8802 }
8803 [(set_attr "conds" "use")
8804 (set_attr "type" "multiple")
8805 (set_attr "length" "8")]
8806 )
8807
8808 (define_insn_and_split "*ior_scc"
8809 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8810 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8811 [(match_operand 2 "cc_register" "") (const_int 0)])
8812 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8813 "TARGET_ARM"
8814 "@
8815 orr%d1\\t%0, %3, #1
8816 #"
8817 "&& reload_completed
8818 && REGNO (operands [0]) != REGNO (operands[3])"
8819 ;; && which_alternative == 1
8820 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8821 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8822 (cond_exec (match_dup 4) (set (match_dup 0)
8823 (ior:SI (match_dup 3) (const_int 1))))]
8824 {
8825 machine_mode mode = GET_MODE (operands[2]);
8826 enum rtx_code rc = GET_CODE (operands[1]);
8827
8828 /* Note that operands[4] is the same as operands[1],
8829 but with VOIDmode as the result. */
8830 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8831 if (mode == CCFPmode || mode == CCFPEmode)
8832 rc = reverse_condition_maybe_unordered (rc);
8833 else
8834 rc = reverse_condition (rc);
8835 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8836 }
8837 [(set_attr "conds" "use")
8838 (set_attr "length" "4,8")
8839 (set_attr "type" "logic_imm,multiple")]
8840 )
8841
8842 ; A series of splitters for the compare_scc pattern below. Note that
8843 ; order is important.
8844 (define_split
8845 [(set (match_operand:SI 0 "s_register_operand" "")
8846 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8847 (const_int 0)))
8848 (clobber (reg:CC CC_REGNUM))]
8849 "TARGET_32BIT && reload_completed"
8850 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8851
8852 (define_split
8853 [(set (match_operand:SI 0 "s_register_operand" "")
8854 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8855 (const_int 0)))
8856 (clobber (reg:CC CC_REGNUM))]
8857 "TARGET_32BIT && reload_completed"
8858 [(set (match_dup 0) (not:SI (match_dup 1)))
8859 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8860
8861 (define_split
8862 [(set (match_operand:SI 0 "s_register_operand" "")
8863 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8864 (const_int 0)))
8865 (clobber (reg:CC CC_REGNUM))]
8866 "arm_arch5 && TARGET_32BIT"
8867 [(set (match_dup 0) (clz:SI (match_dup 1)))
8868 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8869 )
8870
8871 (define_split
8872 [(set (match_operand:SI 0 "s_register_operand" "")
8873 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8874 (const_int 0)))
8875 (clobber (reg:CC CC_REGNUM))]
8876 "TARGET_32BIT && reload_completed"
8877 [(parallel
8878 [(set (reg:CC CC_REGNUM)
8879 (compare:CC (const_int 1) (match_dup 1)))
8880 (set (match_dup 0)
8881 (minus:SI (const_int 1) (match_dup 1)))])
8882 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8883 (set (match_dup 0) (const_int 0)))])
8884
8885 (define_split
8886 [(set (match_operand:SI 0 "s_register_operand" "")
8887 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8888 (match_operand:SI 2 "const_int_operand" "")))
8889 (clobber (reg:CC CC_REGNUM))]
8890 "TARGET_32BIT && reload_completed"
8891 [(parallel
8892 [(set (reg:CC CC_REGNUM)
8893 (compare:CC (match_dup 1) (match_dup 2)))
8894 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8895 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8896 (set (match_dup 0) (const_int 1)))]
8897 {
8898 operands[3] = GEN_INT (-INTVAL (operands[2]));
8899 })
8900
8901 (define_split
8902 [(set (match_operand:SI 0 "s_register_operand" "")
8903 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8904 (match_operand:SI 2 "arm_add_operand" "")))
8905 (clobber (reg:CC CC_REGNUM))]
8906 "TARGET_32BIT && reload_completed"
8907 [(parallel
8908 [(set (reg:CC_NOOV CC_REGNUM)
8909 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8910 (const_int 0)))
8911 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8912 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8913 (set (match_dup 0) (const_int 1)))])
8914
8915 (define_insn_and_split "*compare_scc"
8916 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8917 (match_operator:SI 1 "arm_comparison_operator"
8918 [(match_operand:SI 2 "s_register_operand" "r,r")
8919 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8920 (clobber (reg:CC CC_REGNUM))]
8921 "TARGET_32BIT"
8922 "#"
8923 "&& reload_completed"
8924 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8925 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8926 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8927 {
8928 rtx tmp1;
8929 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8930 operands[2], operands[3]);
8931 enum rtx_code rc = GET_CODE (operands[1]);
8932
8933 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8934
8935 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8936 if (mode == CCFPmode || mode == CCFPEmode)
8937 rc = reverse_condition_maybe_unordered (rc);
8938 else
8939 rc = reverse_condition (rc);
8940 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8941 }
8942 [(set_attr "type" "multiple")]
8943 )
8944
8945 ;; Attempt to improve the sequence generated by the compare_scc splitters
8946 ;; not to use conditional execution.
8947
8948 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
8949 ;; clz Rd, reg1
8950 ;; lsr Rd, Rd, #5
8951 (define_peephole2
8952 [(set (reg:CC CC_REGNUM)
8953 (compare:CC (match_operand:SI 1 "register_operand" "")
8954 (const_int 0)))
8955 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8956 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8957 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8958 (set (match_dup 0) (const_int 1)))]
8959 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8960 [(set (match_dup 0) (clz:SI (match_dup 1)))
8961 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8962 )
8963
8964 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8965 ;; negs Rd, reg1
8966 ;; adc Rd, Rd, reg1
8967 (define_peephole2
8968 [(set (reg:CC CC_REGNUM)
8969 (compare:CC (match_operand:SI 1 "register_operand" "")
8970 (const_int 0)))
8971 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8972 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8973 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8974 (set (match_dup 0) (const_int 1)))
8975 (match_scratch:SI 2 "r")]
8976 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8977 [(parallel
8978 [(set (reg:CC CC_REGNUM)
8979 (compare:CC (const_int 0) (match_dup 1)))
8980 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8981 (set (match_dup 0)
8982 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8983 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8984 )
8985
8986 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
8987 ;; sub Rd, Reg1, reg2
8988 ;; clz Rd, Rd
8989 ;; lsr Rd, Rd, #5
8990 (define_peephole2
8991 [(set (reg:CC CC_REGNUM)
8992 (compare:CC (match_operand:SI 1 "register_operand" "")
8993 (match_operand:SI 2 "arm_rhs_operand" "")))
8994 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8995 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8996 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8997 (set (match_dup 0) (const_int 1)))]
8998 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8999 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9000 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9001 (set (match_dup 0) (clz:SI (match_dup 0)))
9002 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9003 )
9004
9005
9006 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9007 ;; sub T1, Reg1, reg2
9008 ;; negs Rd, T1
9009 ;; adc Rd, Rd, T1
9010 (define_peephole2
9011 [(set (reg:CC CC_REGNUM)
9012 (compare:CC (match_operand:SI 1 "register_operand" "")
9013 (match_operand:SI 2 "arm_rhs_operand" "")))
9014 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9015 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9016 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9017 (set (match_dup 0) (const_int 1)))
9018 (match_scratch:SI 3 "r")]
9019 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9020 [(set (match_dup 3) (match_dup 4))
9021 (parallel
9022 [(set (reg:CC CC_REGNUM)
9023 (compare:CC (const_int 0) (match_dup 3)))
9024 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9025 (set (match_dup 0)
9026 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9027 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9028 "
9029 if (CONST_INT_P (operands[2]))
9030 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9031 else
9032 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9033 ")
9034
9035 (define_insn "*cond_move"
9036 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9037 (if_then_else:SI (match_operator 3 "equality_operator"
9038 [(match_operator 4 "arm_comparison_operator"
9039 [(match_operand 5 "cc_register" "") (const_int 0)])
9040 (const_int 0)])
9041 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9042 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9043 "TARGET_ARM"
9044 "*
9045 if (GET_CODE (operands[3]) == NE)
9046 {
9047 if (which_alternative != 1)
9048 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9049 if (which_alternative != 0)
9050 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9051 return \"\";
9052 }
9053 if (which_alternative != 0)
9054 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9055 if (which_alternative != 1)
9056 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9057 return \"\";
9058 "
9059 [(set_attr "conds" "use")
9060 (set_attr_alternative "type"
9061 [(if_then_else (match_operand 2 "const_int_operand" "")
9062 (const_string "mov_imm")
9063 (const_string "mov_reg"))
9064 (if_then_else (match_operand 1 "const_int_operand" "")
9065 (const_string "mov_imm")
9066 (const_string "mov_reg"))
9067 (const_string "multiple")])
9068 (set_attr "length" "4,4,8")]
9069 )
9070
9071 (define_insn "*cond_arith"
9072 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9073 (match_operator:SI 5 "shiftable_operator"
9074 [(match_operator:SI 4 "arm_comparison_operator"
9075 [(match_operand:SI 2 "s_register_operand" "r,r")
9076 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9077 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9078 (clobber (reg:CC CC_REGNUM))]
9079 "TARGET_ARM"
9080 "*
9081 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9082 return \"%i5\\t%0, %1, %2, lsr #31\";
9083
9084 output_asm_insn (\"cmp\\t%2, %3\", operands);
9085 if (GET_CODE (operands[5]) == AND)
9086 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9087 else if (GET_CODE (operands[5]) == MINUS)
9088 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9089 else if (which_alternative != 0)
9090 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9091 return \"%i5%d4\\t%0, %1, #1\";
9092 "
9093 [(set_attr "conds" "clob")
9094 (set_attr "length" "12")
9095 (set_attr "type" "multiple")]
9096 )
9097
9098 (define_insn "*cond_sub"
9099 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9100 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9101 (match_operator:SI 4 "arm_comparison_operator"
9102 [(match_operand:SI 2 "s_register_operand" "r,r")
9103 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9104 (clobber (reg:CC CC_REGNUM))]
9105 "TARGET_ARM"
9106 "*
9107 output_asm_insn (\"cmp\\t%2, %3\", operands);
9108 if (which_alternative != 0)
9109 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9110 return \"sub%d4\\t%0, %1, #1\";
9111 "
9112 [(set_attr "conds" "clob")
9113 (set_attr "length" "8,12")
9114 (set_attr "type" "multiple")]
9115 )
9116
9117 (define_insn "*cmp_ite0"
9118 [(set (match_operand 6 "dominant_cc_register" "")
9119 (compare
9120 (if_then_else:SI
9121 (match_operator 4 "arm_comparison_operator"
9122 [(match_operand:SI 0 "s_register_operand"
9123 "l,l,l,r,r,r,r,r,r")
9124 (match_operand:SI 1 "arm_add_operand"
9125 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9126 (match_operator:SI 5 "arm_comparison_operator"
9127 [(match_operand:SI 2 "s_register_operand"
9128 "l,r,r,l,l,r,r,r,r")
9129 (match_operand:SI 3 "arm_add_operand"
9130 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9131 (const_int 0))
9132 (const_int 0)))]
9133 "TARGET_32BIT"
9134 "*
9135 {
9136 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9137 {
9138 {\"cmp%d5\\t%0, %1\",
9139 \"cmp%d4\\t%2, %3\"},
9140 {\"cmn%d5\\t%0, #%n1\",
9141 \"cmp%d4\\t%2, %3\"},
9142 {\"cmp%d5\\t%0, %1\",
9143 \"cmn%d4\\t%2, #%n3\"},
9144 {\"cmn%d5\\t%0, #%n1\",
9145 \"cmn%d4\\t%2, #%n3\"}
9146 };
9147 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9148 {
9149 {\"cmp\\t%2, %3\",
9150 \"cmp\\t%0, %1\"},
9151 {\"cmp\\t%2, %3\",
9152 \"cmn\\t%0, #%n1\"},
9153 {\"cmn\\t%2, #%n3\",
9154 \"cmp\\t%0, %1\"},
9155 {\"cmn\\t%2, #%n3\",
9156 \"cmn\\t%0, #%n1\"}
9157 };
9158 static const char * const ite[2] =
9159 {
9160 \"it\\t%d5\",
9161 \"it\\t%d4\"
9162 };
9163 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9164 CMP_CMP, CMN_CMP, CMP_CMP,
9165 CMN_CMP, CMP_CMN, CMN_CMN};
9166 int swap =
9167 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9168
9169 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9170 if (TARGET_THUMB2) {
9171 output_asm_insn (ite[swap], operands);
9172 }
9173 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9174 return \"\";
9175 }"
9176 [(set_attr "conds" "set")
9177 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9178 (set_attr "type" "multiple")
9179 (set_attr_alternative "length"
9180 [(const_int 6)
9181 (const_int 8)
9182 (const_int 8)
9183 (const_int 8)
9184 (const_int 8)
9185 (if_then_else (eq_attr "is_thumb" "no")
9186 (const_int 8)
9187 (const_int 10))
9188 (if_then_else (eq_attr "is_thumb" "no")
9189 (const_int 8)
9190 (const_int 10))
9191 (if_then_else (eq_attr "is_thumb" "no")
9192 (const_int 8)
9193 (const_int 10))
9194 (if_then_else (eq_attr "is_thumb" "no")
9195 (const_int 8)
9196 (const_int 10))])]
9197 )
9198
9199 (define_insn "*cmp_ite1"
9200 [(set (match_operand 6 "dominant_cc_register" "")
9201 (compare
9202 (if_then_else:SI
9203 (match_operator 4 "arm_comparison_operator"
9204 [(match_operand:SI 0 "s_register_operand"
9205 "l,l,l,r,r,r,r,r,r")
9206 (match_operand:SI 1 "arm_add_operand"
9207 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9208 (match_operator:SI 5 "arm_comparison_operator"
9209 [(match_operand:SI 2 "s_register_operand"
9210 "l,r,r,l,l,r,r,r,r")
9211 (match_operand:SI 3 "arm_add_operand"
9212 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9213 (const_int 1))
9214 (const_int 0)))]
9215 "TARGET_32BIT"
9216 "*
9217 {
9218 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9219 {
9220 {\"cmp\\t%0, %1\",
9221 \"cmp\\t%2, %3\"},
9222 {\"cmn\\t%0, #%n1\",
9223 \"cmp\\t%2, %3\"},
9224 {\"cmp\\t%0, %1\",
9225 \"cmn\\t%2, #%n3\"},
9226 {\"cmn\\t%0, #%n1\",
9227 \"cmn\\t%2, #%n3\"}
9228 };
9229 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9230 {
9231 {\"cmp%d4\\t%2, %3\",
9232 \"cmp%D5\\t%0, %1\"},
9233 {\"cmp%d4\\t%2, %3\",
9234 \"cmn%D5\\t%0, #%n1\"},
9235 {\"cmn%d4\\t%2, #%n3\",
9236 \"cmp%D5\\t%0, %1\"},
9237 {\"cmn%d4\\t%2, #%n3\",
9238 \"cmn%D5\\t%0, #%n1\"}
9239 };
9240 static const char * const ite[2] =
9241 {
9242 \"it\\t%d4\",
9243 \"it\\t%D5\"
9244 };
9245 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9246 CMP_CMP, CMN_CMP, CMP_CMP,
9247 CMN_CMP, CMP_CMN, CMN_CMN};
9248 int swap =
9249 comparison_dominates_p (GET_CODE (operands[5]),
9250 reverse_condition (GET_CODE (operands[4])));
9251
9252 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9253 if (TARGET_THUMB2) {
9254 output_asm_insn (ite[swap], operands);
9255 }
9256 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9257 return \"\";
9258 }"
9259 [(set_attr "conds" "set")
9260 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9261 (set_attr_alternative "length"
9262 [(const_int 6)
9263 (const_int 8)
9264 (const_int 8)
9265 (const_int 8)
9266 (const_int 8)
9267 (if_then_else (eq_attr "is_thumb" "no")
9268 (const_int 8)
9269 (const_int 10))
9270 (if_then_else (eq_attr "is_thumb" "no")
9271 (const_int 8)
9272 (const_int 10))
9273 (if_then_else (eq_attr "is_thumb" "no")
9274 (const_int 8)
9275 (const_int 10))
9276 (if_then_else (eq_attr "is_thumb" "no")
9277 (const_int 8)
9278 (const_int 10))])
9279 (set_attr "type" "multiple")]
9280 )
9281
9282 (define_insn "*cmp_and"
9283 [(set (match_operand 6 "dominant_cc_register" "")
9284 (compare
9285 (and:SI
9286 (match_operator 4 "arm_comparison_operator"
9287 [(match_operand:SI 0 "s_register_operand"
9288 "l,l,l,r,r,r,r,r,r")
9289 (match_operand:SI 1 "arm_add_operand"
9290 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9291 (match_operator:SI 5 "arm_comparison_operator"
9292 [(match_operand:SI 2 "s_register_operand"
9293 "l,r,r,l,l,r,r,r,r")
9294 (match_operand:SI 3 "arm_add_operand"
9295 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9296 (const_int 0)))]
9297 "TARGET_32BIT"
9298 "*
9299 {
9300 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9301 {
9302 {\"cmp%d5\\t%0, %1\",
9303 \"cmp%d4\\t%2, %3\"},
9304 {\"cmn%d5\\t%0, #%n1\",
9305 \"cmp%d4\\t%2, %3\"},
9306 {\"cmp%d5\\t%0, %1\",
9307 \"cmn%d4\\t%2, #%n3\"},
9308 {\"cmn%d5\\t%0, #%n1\",
9309 \"cmn%d4\\t%2, #%n3\"}
9310 };
9311 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9312 {
9313 {\"cmp\\t%2, %3\",
9314 \"cmp\\t%0, %1\"},
9315 {\"cmp\\t%2, %3\",
9316 \"cmn\\t%0, #%n1\"},
9317 {\"cmn\\t%2, #%n3\",
9318 \"cmp\\t%0, %1\"},
9319 {\"cmn\\t%2, #%n3\",
9320 \"cmn\\t%0, #%n1\"}
9321 };
9322 static const char *const ite[2] =
9323 {
9324 \"it\\t%d5\",
9325 \"it\\t%d4\"
9326 };
9327 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9328 CMP_CMP, CMN_CMP, CMP_CMP,
9329 CMN_CMP, CMP_CMN, CMN_CMN};
9330 int swap =
9331 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9332
9333 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9334 if (TARGET_THUMB2) {
9335 output_asm_insn (ite[swap], operands);
9336 }
9337 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9338 return \"\";
9339 }"
9340 [(set_attr "conds" "set")
9341 (set_attr "predicable" "no")
9342 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9343 (set_attr_alternative "length"
9344 [(const_int 6)
9345 (const_int 8)
9346 (const_int 8)
9347 (const_int 8)
9348 (const_int 8)
9349 (if_then_else (eq_attr "is_thumb" "no")
9350 (const_int 8)
9351 (const_int 10))
9352 (if_then_else (eq_attr "is_thumb" "no")
9353 (const_int 8)
9354 (const_int 10))
9355 (if_then_else (eq_attr "is_thumb" "no")
9356 (const_int 8)
9357 (const_int 10))
9358 (if_then_else (eq_attr "is_thumb" "no")
9359 (const_int 8)
9360 (const_int 10))])
9361 (set_attr "type" "multiple")]
9362 )
9363
9364 (define_insn "*cmp_ior"
9365 [(set (match_operand 6 "dominant_cc_register" "")
9366 (compare
9367 (ior:SI
9368 (match_operator 4 "arm_comparison_operator"
9369 [(match_operand:SI 0 "s_register_operand"
9370 "l,l,l,r,r,r,r,r,r")
9371 (match_operand:SI 1 "arm_add_operand"
9372 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9373 (match_operator:SI 5 "arm_comparison_operator"
9374 [(match_operand:SI 2 "s_register_operand"
9375 "l,r,r,l,l,r,r,r,r")
9376 (match_operand:SI 3 "arm_add_operand"
9377 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9378 (const_int 0)))]
9379 "TARGET_32BIT"
9380 "*
9381 {
9382 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9383 {
9384 {\"cmp\\t%0, %1\",
9385 \"cmp\\t%2, %3\"},
9386 {\"cmn\\t%0, #%n1\",
9387 \"cmp\\t%2, %3\"},
9388 {\"cmp\\t%0, %1\",
9389 \"cmn\\t%2, #%n3\"},
9390 {\"cmn\\t%0, #%n1\",
9391 \"cmn\\t%2, #%n3\"}
9392 };
9393 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9394 {
9395 {\"cmp%D4\\t%2, %3\",
9396 \"cmp%D5\\t%0, %1\"},
9397 {\"cmp%D4\\t%2, %3\",
9398 \"cmn%D5\\t%0, #%n1\"},
9399 {\"cmn%D4\\t%2, #%n3\",
9400 \"cmp%D5\\t%0, %1\"},
9401 {\"cmn%D4\\t%2, #%n3\",
9402 \"cmn%D5\\t%0, #%n1\"}
9403 };
9404 static const char *const ite[2] =
9405 {
9406 \"it\\t%D4\",
9407 \"it\\t%D5\"
9408 };
9409 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9410 CMP_CMP, CMN_CMP, CMP_CMP,
9411 CMN_CMP, CMP_CMN, CMN_CMN};
9412 int swap =
9413 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9414
9415 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9416 if (TARGET_THUMB2) {
9417 output_asm_insn (ite[swap], operands);
9418 }
9419 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9420 return \"\";
9421 }
9422 "
9423 [(set_attr "conds" "set")
9424 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9425 (set_attr_alternative "length"
9426 [(const_int 6)
9427 (const_int 8)
9428 (const_int 8)
9429 (const_int 8)
9430 (const_int 8)
9431 (if_then_else (eq_attr "is_thumb" "no")
9432 (const_int 8)
9433 (const_int 10))
9434 (if_then_else (eq_attr "is_thumb" "no")
9435 (const_int 8)
9436 (const_int 10))
9437 (if_then_else (eq_attr "is_thumb" "no")
9438 (const_int 8)
9439 (const_int 10))
9440 (if_then_else (eq_attr "is_thumb" "no")
9441 (const_int 8)
9442 (const_int 10))])
9443 (set_attr "type" "multiple")]
9444 )
9445
9446 (define_insn_and_split "*ior_scc_scc"
9447 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9448 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9449 [(match_operand:SI 1 "s_register_operand" "r")
9450 (match_operand:SI 2 "arm_add_operand" "rIL")])
9451 (match_operator:SI 6 "arm_comparison_operator"
9452 [(match_operand:SI 4 "s_register_operand" "r")
9453 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9454 (clobber (reg:CC CC_REGNUM))]
9455 "TARGET_32BIT
9456 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9457 != CCmode)"
9458 "#"
9459 "TARGET_32BIT && reload_completed"
9460 [(set (match_dup 7)
9461 (compare
9462 (ior:SI
9463 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9464 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9465 (const_int 0)))
9466 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9467 "operands[7]
9468 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9469 DOM_CC_X_OR_Y),
9470 CC_REGNUM);"
9471 [(set_attr "conds" "clob")
9472 (set_attr "length" "16")
9473 (set_attr "type" "multiple")]
9474 )
9475
9476 ; If the above pattern is followed by a CMP insn, then the compare is
9477 ; redundant, since we can rework the conditional instruction that follows.
9478 (define_insn_and_split "*ior_scc_scc_cmp"
9479 [(set (match_operand 0 "dominant_cc_register" "")
9480 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9481 [(match_operand:SI 1 "s_register_operand" "r")
9482 (match_operand:SI 2 "arm_add_operand" "rIL")])
9483 (match_operator:SI 6 "arm_comparison_operator"
9484 [(match_operand:SI 4 "s_register_operand" "r")
9485 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9486 (const_int 0)))
9487 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9488 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9489 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9490 "TARGET_32BIT"
9491 "#"
9492 "TARGET_32BIT && reload_completed"
9493 [(set (match_dup 0)
9494 (compare
9495 (ior:SI
9496 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9497 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9498 (const_int 0)))
9499 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9500 ""
9501 [(set_attr "conds" "set")
9502 (set_attr "length" "16")
9503 (set_attr "type" "multiple")]
9504 )
9505
9506 (define_insn_and_split "*and_scc_scc"
9507 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9508 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9509 [(match_operand:SI 1 "s_register_operand" "r")
9510 (match_operand:SI 2 "arm_add_operand" "rIL")])
9511 (match_operator:SI 6 "arm_comparison_operator"
9512 [(match_operand:SI 4 "s_register_operand" "r")
9513 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9514 (clobber (reg:CC CC_REGNUM))]
9515 "TARGET_32BIT
9516 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9517 != CCmode)"
9518 "#"
9519 "TARGET_32BIT && reload_completed
9520 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9521 != CCmode)"
9522 [(set (match_dup 7)
9523 (compare
9524 (and:SI
9525 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9526 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9527 (const_int 0)))
9528 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9529 "operands[7]
9530 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9531 DOM_CC_X_AND_Y),
9532 CC_REGNUM);"
9533 [(set_attr "conds" "clob")
9534 (set_attr "length" "16")
9535 (set_attr "type" "multiple")]
9536 )
9537
9538 ; If the above pattern is followed by a CMP insn, then the compare is
9539 ; redundant, since we can rework the conditional instruction that follows.
9540 (define_insn_and_split "*and_scc_scc_cmp"
9541 [(set (match_operand 0 "dominant_cc_register" "")
9542 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9543 [(match_operand:SI 1 "s_register_operand" "r")
9544 (match_operand:SI 2 "arm_add_operand" "rIL")])
9545 (match_operator:SI 6 "arm_comparison_operator"
9546 [(match_operand:SI 4 "s_register_operand" "r")
9547 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9548 (const_int 0)))
9549 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9550 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9551 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9552 "TARGET_32BIT"
9553 "#"
9554 "TARGET_32BIT && reload_completed"
9555 [(set (match_dup 0)
9556 (compare
9557 (and:SI
9558 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9559 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9560 (const_int 0)))
9561 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9562 ""
9563 [(set_attr "conds" "set")
9564 (set_attr "length" "16")
9565 (set_attr "type" "multiple")]
9566 )
9567
9568 ;; If there is no dominance in the comparison, then we can still save an
9569 ;; instruction in the AND case, since we can know that the second compare
9570 ;; need only zero the value if false (if true, then the value is already
9571 ;; correct).
9572 (define_insn_and_split "*and_scc_scc_nodom"
9573 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9574 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9575 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9576 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9577 (match_operator:SI 6 "arm_comparison_operator"
9578 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9579 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9580 (clobber (reg:CC CC_REGNUM))]
9581 "TARGET_32BIT
9582 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9583 == CCmode)"
9584 "#"
9585 "TARGET_32BIT && reload_completed"
9586 [(parallel [(set (match_dup 0)
9587 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9588 (clobber (reg:CC CC_REGNUM))])
9589 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9590 (set (match_dup 0)
9591 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9592 (match_dup 0)
9593 (const_int 0)))]
9594 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9595 operands[4], operands[5]),
9596 CC_REGNUM);
9597 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9598 operands[5]);"
9599 [(set_attr "conds" "clob")
9600 (set_attr "length" "20")
9601 (set_attr "type" "multiple")]
9602 )
9603
9604 (define_split
9605 [(set (reg:CC_NOOV CC_REGNUM)
9606 (compare:CC_NOOV (ior:SI
9607 (and:SI (match_operand:SI 0 "s_register_operand" "")
9608 (const_int 1))
9609 (match_operator:SI 1 "arm_comparison_operator"
9610 [(match_operand:SI 2 "s_register_operand" "")
9611 (match_operand:SI 3 "arm_add_operand" "")]))
9612 (const_int 0)))
9613 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9614 "TARGET_ARM"
9615 [(set (match_dup 4)
9616 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9617 (match_dup 0)))
9618 (set (reg:CC_NOOV CC_REGNUM)
9619 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9620 (const_int 0)))]
9621 "")
9622
9623 (define_split
9624 [(set (reg:CC_NOOV CC_REGNUM)
9625 (compare:CC_NOOV (ior:SI
9626 (match_operator:SI 1 "arm_comparison_operator"
9627 [(match_operand:SI 2 "s_register_operand" "")
9628 (match_operand:SI 3 "arm_add_operand" "")])
9629 (and:SI (match_operand:SI 0 "s_register_operand" "")
9630 (const_int 1)))
9631 (const_int 0)))
9632 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9633 "TARGET_ARM"
9634 [(set (match_dup 4)
9635 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9636 (match_dup 0)))
9637 (set (reg:CC_NOOV CC_REGNUM)
9638 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9639 (const_int 0)))]
9640 "")
9641 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9642
9643 (define_insn_and_split "*negscc"
9644 [(set (match_operand:SI 0 "s_register_operand" "=r")
9645 (neg:SI (match_operator 3 "arm_comparison_operator"
9646 [(match_operand:SI 1 "s_register_operand" "r")
9647 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9648 (clobber (reg:CC CC_REGNUM))]
9649 "TARGET_ARM"
9650 "#"
9651 "&& reload_completed"
9652 [(const_int 0)]
9653 {
9654 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9655
9656 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9657 {
9658 /* Emit mov\\t%0, %1, asr #31 */
9659 emit_insn (gen_rtx_SET (operands[0],
9660 gen_rtx_ASHIFTRT (SImode,
9661 operands[1],
9662 GEN_INT (31))));
9663 DONE;
9664 }
9665 else if (GET_CODE (operands[3]) == NE)
9666 {
9667 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9668 if (CONST_INT_P (operands[2]))
9669 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9670 GEN_INT (- INTVAL (operands[2]))));
9671 else
9672 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9673
9674 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9675 gen_rtx_NE (SImode,
9676 cc_reg,
9677 const0_rtx),
9678 gen_rtx_SET (operands[0],
9679 GEN_INT (~0))));
9680 DONE;
9681 }
9682 else
9683 {
9684 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9685 emit_insn (gen_rtx_SET (cc_reg,
9686 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9687 enum rtx_code rc = GET_CODE (operands[3]);
9688
9689 rc = reverse_condition (rc);
9690 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9691 gen_rtx_fmt_ee (rc,
9692 VOIDmode,
9693 cc_reg,
9694 const0_rtx),
9695 gen_rtx_SET (operands[0], const0_rtx)));
9696 rc = GET_CODE (operands[3]);
9697 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9698 gen_rtx_fmt_ee (rc,
9699 VOIDmode,
9700 cc_reg,
9701 const0_rtx),
9702 gen_rtx_SET (operands[0],
9703 GEN_INT (~0))));
9704 DONE;
9705 }
9706 FAIL;
9707 }
9708 [(set_attr "conds" "clob")
9709 (set_attr "length" "12")
9710 (set_attr "type" "multiple")]
9711 )
9712
9713 (define_insn_and_split "movcond_addsi"
9714 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9715 (if_then_else:SI
9716 (match_operator 5 "comparison_operator"
9717 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9718 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9719 (const_int 0)])
9720 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9721 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9722 (clobber (reg:CC CC_REGNUM))]
9723 "TARGET_32BIT"
9724 "#"
9725 "&& reload_completed"
9726 [(set (reg:CC_NOOV CC_REGNUM)
9727 (compare:CC_NOOV
9728 (plus:SI (match_dup 3)
9729 (match_dup 4))
9730 (const_int 0)))
9731 (set (match_dup 0) (match_dup 1))
9732 (cond_exec (match_dup 6)
9733 (set (match_dup 0) (match_dup 2)))]
9734 "
9735 {
9736 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9737 operands[3], operands[4]);
9738 enum rtx_code rc = GET_CODE (operands[5]);
9739 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9740 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9741 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9742 rc = reverse_condition (rc);
9743 else
9744 std::swap (operands[1], operands[2]);
9745
9746 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9747 }
9748 "
9749 [(set_attr "conds" "clob")
9750 (set_attr "enabled_for_depr_it" "no,yes,yes")
9751 (set_attr "type" "multiple")]
9752 )
9753
9754 (define_insn "movcond"
9755 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9756 (if_then_else:SI
9757 (match_operator 5 "arm_comparison_operator"
9758 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9759 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9760 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9761 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9762 (clobber (reg:CC CC_REGNUM))]
9763 "TARGET_ARM"
9764 "*
9765 if (GET_CODE (operands[5]) == LT
9766 && (operands[4] == const0_rtx))
9767 {
9768 if (which_alternative != 1 && REG_P (operands[1]))
9769 {
9770 if (operands[2] == const0_rtx)
9771 return \"and\\t%0, %1, %3, asr #31\";
9772 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9773 }
9774 else if (which_alternative != 0 && REG_P (operands[2]))
9775 {
9776 if (operands[1] == const0_rtx)
9777 return \"bic\\t%0, %2, %3, asr #31\";
9778 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9779 }
9780 /* The only case that falls through to here is when both ops 1 & 2
9781 are constants. */
9782 }
9783
9784 if (GET_CODE (operands[5]) == GE
9785 && (operands[4] == const0_rtx))
9786 {
9787 if (which_alternative != 1 && REG_P (operands[1]))
9788 {
9789 if (operands[2] == const0_rtx)
9790 return \"bic\\t%0, %1, %3, asr #31\";
9791 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9792 }
9793 else if (which_alternative != 0 && REG_P (operands[2]))
9794 {
9795 if (operands[1] == const0_rtx)
9796 return \"and\\t%0, %2, %3, asr #31\";
9797 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9798 }
9799 /* The only case that falls through to here is when both ops 1 & 2
9800 are constants. */
9801 }
9802 if (CONST_INT_P (operands[4])
9803 && !const_ok_for_arm (INTVAL (operands[4])))
9804 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9805 else
9806 output_asm_insn (\"cmp\\t%3, %4\", operands);
9807 if (which_alternative != 0)
9808 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9809 if (which_alternative != 1)
9810 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9811 return \"\";
9812 "
9813 [(set_attr "conds" "clob")
9814 (set_attr "length" "8,8,12")
9815 (set_attr "type" "multiple")]
9816 )
9817
9818 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9819
9820 (define_insn "*ifcompare_plus_move"
9821 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9822 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9823 [(match_operand:SI 4 "s_register_operand" "r,r")
9824 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9825 (plus:SI
9826 (match_operand:SI 2 "s_register_operand" "r,r")
9827 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9828 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9829 (clobber (reg:CC CC_REGNUM))]
9830 "TARGET_ARM"
9831 "#"
9832 [(set_attr "conds" "clob")
9833 (set_attr "length" "8,12")
9834 (set_attr "type" "multiple")]
9835 )
9836
9837 (define_insn "*if_plus_move"
9838 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9839 (if_then_else:SI
9840 (match_operator 4 "arm_comparison_operator"
9841 [(match_operand 5 "cc_register" "") (const_int 0)])
9842 (plus:SI
9843 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9844 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9845 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9846 "TARGET_ARM"
9847 "@
9848 add%d4\\t%0, %2, %3
9849 sub%d4\\t%0, %2, #%n3
9850 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9851 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9852 [(set_attr "conds" "use")
9853 (set_attr "length" "4,4,8,8")
9854 (set_attr_alternative "type"
9855 [(if_then_else (match_operand 3 "const_int_operand" "")
9856 (const_string "alu_imm" )
9857 (const_string "alu_sreg"))
9858 (const_string "alu_imm")
9859 (const_string "multiple")
9860 (const_string "multiple")])]
9861 )
9862
9863 (define_insn "*ifcompare_move_plus"
9864 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9865 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9866 [(match_operand:SI 4 "s_register_operand" "r,r")
9867 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9868 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9869 (plus:SI
9870 (match_operand:SI 2 "s_register_operand" "r,r")
9871 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9872 (clobber (reg:CC CC_REGNUM))]
9873 "TARGET_ARM"
9874 "#"
9875 [(set_attr "conds" "clob")
9876 (set_attr "length" "8,12")
9877 (set_attr "type" "multiple")]
9878 )
9879
9880 (define_insn "*if_move_plus"
9881 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9882 (if_then_else:SI
9883 (match_operator 4 "arm_comparison_operator"
9884 [(match_operand 5 "cc_register" "") (const_int 0)])
9885 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9886 (plus:SI
9887 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9888 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9889 "TARGET_ARM"
9890 "@
9891 add%D4\\t%0, %2, %3
9892 sub%D4\\t%0, %2, #%n3
9893 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9894 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9895 [(set_attr "conds" "use")
9896 (set_attr "length" "4,4,8,8")
9897 (set_attr_alternative "type"
9898 [(if_then_else (match_operand 3 "const_int_operand" "")
9899 (const_string "alu_imm" )
9900 (const_string "alu_sreg"))
9901 (const_string "alu_imm")
9902 (const_string "multiple")
9903 (const_string "multiple")])]
9904 )
9905
9906 (define_insn "*ifcompare_arith_arith"
9907 [(set (match_operand:SI 0 "s_register_operand" "=r")
9908 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9909 [(match_operand:SI 5 "s_register_operand" "r")
9910 (match_operand:SI 6 "arm_add_operand" "rIL")])
9911 (match_operator:SI 8 "shiftable_operator"
9912 [(match_operand:SI 1 "s_register_operand" "r")
9913 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9914 (match_operator:SI 7 "shiftable_operator"
9915 [(match_operand:SI 3 "s_register_operand" "r")
9916 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9917 (clobber (reg:CC CC_REGNUM))]
9918 "TARGET_ARM"
9919 "#"
9920 [(set_attr "conds" "clob")
9921 (set_attr "length" "12")
9922 (set_attr "type" "multiple")]
9923 )
9924
9925 (define_insn "*if_arith_arith"
9926 [(set (match_operand:SI 0 "s_register_operand" "=r")
9927 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9928 [(match_operand 8 "cc_register" "") (const_int 0)])
9929 (match_operator:SI 6 "shiftable_operator"
9930 [(match_operand:SI 1 "s_register_operand" "r")
9931 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9932 (match_operator:SI 7 "shiftable_operator"
9933 [(match_operand:SI 3 "s_register_operand" "r")
9934 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9935 "TARGET_ARM"
9936 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9937 [(set_attr "conds" "use")
9938 (set_attr "length" "8")
9939 (set_attr "type" "multiple")]
9940 )
9941
9942 (define_insn "*ifcompare_arith_move"
9943 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9944 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9945 [(match_operand:SI 2 "s_register_operand" "r,r")
9946 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9947 (match_operator:SI 7 "shiftable_operator"
9948 [(match_operand:SI 4 "s_register_operand" "r,r")
9949 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9950 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9951 (clobber (reg:CC CC_REGNUM))]
9952 "TARGET_ARM"
9953 "*
9954 /* If we have an operation where (op x 0) is the identity operation and
9955 the conditional operator is LT or GE and we are comparing against zero and
9956 everything is in registers then we can do this in two instructions. */
9957 if (operands[3] == const0_rtx
9958 && GET_CODE (operands[7]) != AND
9959 && REG_P (operands[5])
9960 && REG_P (operands[1])
9961 && REGNO (operands[1]) == REGNO (operands[4])
9962 && REGNO (operands[4]) != REGNO (operands[0]))
9963 {
9964 if (GET_CODE (operands[6]) == LT)
9965 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9966 else if (GET_CODE (operands[6]) == GE)
9967 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9968 }
9969 if (CONST_INT_P (operands[3])
9970 && !const_ok_for_arm (INTVAL (operands[3])))
9971 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9972 else
9973 output_asm_insn (\"cmp\\t%2, %3\", operands);
9974 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9975 if (which_alternative != 0)
9976 return \"mov%D6\\t%0, %1\";
9977 return \"\";
9978 "
9979 [(set_attr "conds" "clob")
9980 (set_attr "length" "8,12")
9981 (set_attr "type" "multiple")]
9982 )
9983
9984 (define_insn "*if_arith_move"
9985 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9986 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9987 [(match_operand 6 "cc_register" "") (const_int 0)])
9988 (match_operator:SI 5 "shiftable_operator"
9989 [(match_operand:SI 2 "s_register_operand" "r,r")
9990 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9991 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9992 "TARGET_ARM"
9993 "@
9994 %I5%d4\\t%0, %2, %3
9995 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9996 [(set_attr "conds" "use")
9997 (set_attr "length" "4,8")
9998 (set_attr_alternative "type"
9999 [(if_then_else (match_operand 3 "const_int_operand" "")
10000 (const_string "alu_shift_imm" )
10001 (const_string "alu_shift_reg"))
10002 (const_string "multiple")])]
10003 )
10004
10005 (define_insn "*ifcompare_move_arith"
10006 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10007 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10008 [(match_operand:SI 4 "s_register_operand" "r,r")
10009 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10010 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10011 (match_operator:SI 7 "shiftable_operator"
10012 [(match_operand:SI 2 "s_register_operand" "r,r")
10013 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10014 (clobber (reg:CC CC_REGNUM))]
10015 "TARGET_ARM"
10016 "*
10017 /* If we have an operation where (op x 0) is the identity operation and
10018 the conditional operator is LT or GE and we are comparing against zero and
10019 everything is in registers then we can do this in two instructions */
10020 if (operands[5] == const0_rtx
10021 && GET_CODE (operands[7]) != AND
10022 && REG_P (operands[3])
10023 && REG_P (operands[1])
10024 && REGNO (operands[1]) == REGNO (operands[2])
10025 && REGNO (operands[2]) != REGNO (operands[0]))
10026 {
10027 if (GET_CODE (operands[6]) == GE)
10028 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10029 else if (GET_CODE (operands[6]) == LT)
10030 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10031 }
10032
10033 if (CONST_INT_P (operands[5])
10034 && !const_ok_for_arm (INTVAL (operands[5])))
10035 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10036 else
10037 output_asm_insn (\"cmp\\t%4, %5\", operands);
10038
10039 if (which_alternative != 0)
10040 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10041 return \"%I7%D6\\t%0, %2, %3\";
10042 "
10043 [(set_attr "conds" "clob")
10044 (set_attr "length" "8,12")
10045 (set_attr "type" "multiple")]
10046 )
10047
10048 (define_insn "*if_move_arith"
10049 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10050 (if_then_else:SI
10051 (match_operator 4 "arm_comparison_operator"
10052 [(match_operand 6 "cc_register" "") (const_int 0)])
10053 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10054 (match_operator:SI 5 "shiftable_operator"
10055 [(match_operand:SI 2 "s_register_operand" "r,r")
10056 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10057 "TARGET_ARM"
10058 "@
10059 %I5%D4\\t%0, %2, %3
10060 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10061 [(set_attr "conds" "use")
10062 (set_attr "length" "4,8")
10063 (set_attr_alternative "type"
10064 [(if_then_else (match_operand 3 "const_int_operand" "")
10065 (const_string "alu_shift_imm" )
10066 (const_string "alu_shift_reg"))
10067 (const_string "multiple")])]
10068 )
10069
10070 (define_insn "*ifcompare_move_not"
10071 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10072 (if_then_else:SI
10073 (match_operator 5 "arm_comparison_operator"
10074 [(match_operand:SI 3 "s_register_operand" "r,r")
10075 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10076 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10077 (not:SI
10078 (match_operand:SI 2 "s_register_operand" "r,r"))))
10079 (clobber (reg:CC CC_REGNUM))]
10080 "TARGET_ARM"
10081 "#"
10082 [(set_attr "conds" "clob")
10083 (set_attr "length" "8,12")
10084 (set_attr "type" "multiple")]
10085 )
10086
10087 (define_insn "*if_move_not"
10088 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10089 (if_then_else:SI
10090 (match_operator 4 "arm_comparison_operator"
10091 [(match_operand 3 "cc_register" "") (const_int 0)])
10092 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10093 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10094 "TARGET_ARM"
10095 "@
10096 mvn%D4\\t%0, %2
10097 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10098 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10099 [(set_attr "conds" "use")
10100 (set_attr "type" "mvn_reg")
10101 (set_attr "length" "4,8,8")
10102 (set_attr "type" "mvn_reg,multiple,multiple")]
10103 )
10104
10105 (define_insn "*ifcompare_not_move"
10106 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10107 (if_then_else:SI
10108 (match_operator 5 "arm_comparison_operator"
10109 [(match_operand:SI 3 "s_register_operand" "r,r")
10110 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10111 (not:SI
10112 (match_operand:SI 2 "s_register_operand" "r,r"))
10113 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10114 (clobber (reg:CC CC_REGNUM))]
10115 "TARGET_ARM"
10116 "#"
10117 [(set_attr "conds" "clob")
10118 (set_attr "length" "8,12")
10119 (set_attr "type" "multiple")]
10120 )
10121
10122 (define_insn "*if_not_move"
10123 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10124 (if_then_else:SI
10125 (match_operator 4 "arm_comparison_operator"
10126 [(match_operand 3 "cc_register" "") (const_int 0)])
10127 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10128 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10129 "TARGET_ARM"
10130 "@
10131 mvn%d4\\t%0, %2
10132 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10133 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10134 [(set_attr "conds" "use")
10135 (set_attr "type" "mvn_reg,multiple,multiple")
10136 (set_attr "length" "4,8,8")]
10137 )
10138
10139 (define_insn "*ifcompare_shift_move"
10140 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10141 (if_then_else:SI
10142 (match_operator 6 "arm_comparison_operator"
10143 [(match_operand:SI 4 "s_register_operand" "r,r")
10144 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10145 (match_operator:SI 7 "shift_operator"
10146 [(match_operand:SI 2 "s_register_operand" "r,r")
10147 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10148 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10149 (clobber (reg:CC CC_REGNUM))]
10150 "TARGET_ARM"
10151 "#"
10152 [(set_attr "conds" "clob")
10153 (set_attr "length" "8,12")
10154 (set_attr "type" "multiple")]
10155 )
10156
10157 (define_insn "*if_shift_move"
10158 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10159 (if_then_else:SI
10160 (match_operator 5 "arm_comparison_operator"
10161 [(match_operand 6 "cc_register" "") (const_int 0)])
10162 (match_operator:SI 4 "shift_operator"
10163 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10164 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10165 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10166 "TARGET_ARM"
10167 "@
10168 mov%d5\\t%0, %2%S4
10169 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10170 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10171 [(set_attr "conds" "use")
10172 (set_attr "shift" "2")
10173 (set_attr "length" "4,8,8")
10174 (set_attr_alternative "type"
10175 [(if_then_else (match_operand 3 "const_int_operand" "")
10176 (const_string "mov_shift" )
10177 (const_string "mov_shift_reg"))
10178 (const_string "multiple")
10179 (const_string "multiple")])]
10180 )
10181
10182 (define_insn "*ifcompare_move_shift"
10183 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10184 (if_then_else:SI
10185 (match_operator 6 "arm_comparison_operator"
10186 [(match_operand:SI 4 "s_register_operand" "r,r")
10187 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10188 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10189 (match_operator:SI 7 "shift_operator"
10190 [(match_operand:SI 2 "s_register_operand" "r,r")
10191 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10192 (clobber (reg:CC CC_REGNUM))]
10193 "TARGET_ARM"
10194 "#"
10195 [(set_attr "conds" "clob")
10196 (set_attr "length" "8,12")
10197 (set_attr "type" "multiple")]
10198 )
10199
10200 (define_insn "*if_move_shift"
10201 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10202 (if_then_else:SI
10203 (match_operator 5 "arm_comparison_operator"
10204 [(match_operand 6 "cc_register" "") (const_int 0)])
10205 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10206 (match_operator:SI 4 "shift_operator"
10207 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10208 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10209 "TARGET_ARM"
10210 "@
10211 mov%D5\\t%0, %2%S4
10212 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10213 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10214 [(set_attr "conds" "use")
10215 (set_attr "shift" "2")
10216 (set_attr "length" "4,8,8")
10217 (set_attr_alternative "type"
10218 [(if_then_else (match_operand 3 "const_int_operand" "")
10219 (const_string "mov_shift" )
10220 (const_string "mov_shift_reg"))
10221 (const_string "multiple")
10222 (const_string "multiple")])]
10223 )
10224
10225 (define_insn "*ifcompare_shift_shift"
10226 [(set (match_operand:SI 0 "s_register_operand" "=r")
10227 (if_then_else:SI
10228 (match_operator 7 "arm_comparison_operator"
10229 [(match_operand:SI 5 "s_register_operand" "r")
10230 (match_operand:SI 6 "arm_add_operand" "rIL")])
10231 (match_operator:SI 8 "shift_operator"
10232 [(match_operand:SI 1 "s_register_operand" "r")
10233 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10234 (match_operator:SI 9 "shift_operator"
10235 [(match_operand:SI 3 "s_register_operand" "r")
10236 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10237 (clobber (reg:CC CC_REGNUM))]
10238 "TARGET_ARM"
10239 "#"
10240 [(set_attr "conds" "clob")
10241 (set_attr "length" "12")
10242 (set_attr "type" "multiple")]
10243 )
10244
10245 (define_insn "*if_shift_shift"
10246 [(set (match_operand:SI 0 "s_register_operand" "=r")
10247 (if_then_else:SI
10248 (match_operator 5 "arm_comparison_operator"
10249 [(match_operand 8 "cc_register" "") (const_int 0)])
10250 (match_operator:SI 6 "shift_operator"
10251 [(match_operand:SI 1 "s_register_operand" "r")
10252 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10253 (match_operator:SI 7 "shift_operator"
10254 [(match_operand:SI 3 "s_register_operand" "r")
10255 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10256 "TARGET_ARM"
10257 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10258 [(set_attr "conds" "use")
10259 (set_attr "shift" "1")
10260 (set_attr "length" "8")
10261 (set (attr "type") (if_then_else
10262 (and (match_operand 2 "const_int_operand" "")
10263 (match_operand 4 "const_int_operand" ""))
10264 (const_string "mov_shift")
10265 (const_string "mov_shift_reg")))]
10266 )
10267
10268 (define_insn "*ifcompare_not_arith"
10269 [(set (match_operand:SI 0 "s_register_operand" "=r")
10270 (if_then_else:SI
10271 (match_operator 6 "arm_comparison_operator"
10272 [(match_operand:SI 4 "s_register_operand" "r")
10273 (match_operand:SI 5 "arm_add_operand" "rIL")])
10274 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10275 (match_operator:SI 7 "shiftable_operator"
10276 [(match_operand:SI 2 "s_register_operand" "r")
10277 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10278 (clobber (reg:CC CC_REGNUM))]
10279 "TARGET_ARM"
10280 "#"
10281 [(set_attr "conds" "clob")
10282 (set_attr "length" "12")
10283 (set_attr "type" "multiple")]
10284 )
10285
10286 (define_insn "*if_not_arith"
10287 [(set (match_operand:SI 0 "s_register_operand" "=r")
10288 (if_then_else:SI
10289 (match_operator 5 "arm_comparison_operator"
10290 [(match_operand 4 "cc_register" "") (const_int 0)])
10291 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10292 (match_operator:SI 6 "shiftable_operator"
10293 [(match_operand:SI 2 "s_register_operand" "r")
10294 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10295 "TARGET_ARM"
10296 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10297 [(set_attr "conds" "use")
10298 (set_attr "type" "mvn_reg")
10299 (set_attr "length" "8")]
10300 )
10301
10302 (define_insn "*ifcompare_arith_not"
10303 [(set (match_operand:SI 0 "s_register_operand" "=r")
10304 (if_then_else:SI
10305 (match_operator 6 "arm_comparison_operator"
10306 [(match_operand:SI 4 "s_register_operand" "r")
10307 (match_operand:SI 5 "arm_add_operand" "rIL")])
10308 (match_operator:SI 7 "shiftable_operator"
10309 [(match_operand:SI 2 "s_register_operand" "r")
10310 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10311 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10312 (clobber (reg:CC CC_REGNUM))]
10313 "TARGET_ARM"
10314 "#"
10315 [(set_attr "conds" "clob")
10316 (set_attr "length" "12")
10317 (set_attr "type" "multiple")]
10318 )
10319
10320 (define_insn "*if_arith_not"
10321 [(set (match_operand:SI 0 "s_register_operand" "=r")
10322 (if_then_else:SI
10323 (match_operator 5 "arm_comparison_operator"
10324 [(match_operand 4 "cc_register" "") (const_int 0)])
10325 (match_operator:SI 6 "shiftable_operator"
10326 [(match_operand:SI 2 "s_register_operand" "r")
10327 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10328 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10329 "TARGET_ARM"
10330 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10331 [(set_attr "conds" "use")
10332 (set_attr "type" "multiple")
10333 (set_attr "length" "8")]
10334 )
10335
10336 (define_insn "*ifcompare_neg_move"
10337 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10338 (if_then_else:SI
10339 (match_operator 5 "arm_comparison_operator"
10340 [(match_operand:SI 3 "s_register_operand" "r,r")
10341 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10342 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10343 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10344 (clobber (reg:CC CC_REGNUM))]
10345 "TARGET_ARM"
10346 "#"
10347 [(set_attr "conds" "clob")
10348 (set_attr "length" "8,12")
10349 (set_attr "type" "multiple")]
10350 )
10351
10352 (define_insn_and_split "*if_neg_move"
10353 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10354 (if_then_else:SI
10355 (match_operator 4 "arm_comparison_operator"
10356 [(match_operand 3 "cc_register" "") (const_int 0)])
10357 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10358 (match_operand:SI 1 "s_register_operand" "0,0")))]
10359 "TARGET_32BIT"
10360 "#"
10361 "&& reload_completed"
10362 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10363 (set (match_dup 0) (neg:SI (match_dup 2))))]
10364 ""
10365 [(set_attr "conds" "use")
10366 (set_attr "length" "4")
10367 (set_attr "arch" "t2,32")
10368 (set_attr "enabled_for_depr_it" "yes,no")
10369 (set_attr "type" "logic_shift_imm")]
10370 )
10371
10372 (define_insn "*ifcompare_move_neg"
10373 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10374 (if_then_else:SI
10375 (match_operator 5 "arm_comparison_operator"
10376 [(match_operand:SI 3 "s_register_operand" "r,r")
10377 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10378 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10379 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10380 (clobber (reg:CC CC_REGNUM))]
10381 "TARGET_ARM"
10382 "#"
10383 [(set_attr "conds" "clob")
10384 (set_attr "length" "8,12")
10385 (set_attr "type" "multiple")]
10386 )
10387
10388 (define_insn_and_split "*if_move_neg"
10389 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10390 (if_then_else:SI
10391 (match_operator 4 "arm_comparison_operator"
10392 [(match_operand 3 "cc_register" "") (const_int 0)])
10393 (match_operand:SI 1 "s_register_operand" "0,0")
10394 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10395 "TARGET_32BIT"
10396 "#"
10397 "&& reload_completed"
10398 [(cond_exec (match_dup 5)
10399 (set (match_dup 0) (neg:SI (match_dup 2))))]
10400 {
10401 machine_mode mode = GET_MODE (operands[3]);
10402 rtx_code rc = GET_CODE (operands[4]);
10403
10404 if (mode == CCFPmode || mode == CCFPEmode)
10405 rc = reverse_condition_maybe_unordered (rc);
10406 else
10407 rc = reverse_condition (rc);
10408
10409 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10410 }
10411 [(set_attr "conds" "use")
10412 (set_attr "length" "4")
10413 (set_attr "arch" "t2,32")
10414 (set_attr "enabled_for_depr_it" "yes,no")
10415 (set_attr "type" "logic_shift_imm")]
10416 )
10417
10418 (define_insn "*arith_adjacentmem"
10419 [(set (match_operand:SI 0 "s_register_operand" "=r")
10420 (match_operator:SI 1 "shiftable_operator"
10421 [(match_operand:SI 2 "memory_operand" "m")
10422 (match_operand:SI 3 "memory_operand" "m")]))
10423 (clobber (match_scratch:SI 4 "=r"))]
10424 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10425 "*
10426 {
10427 rtx ldm[3];
10428 rtx arith[4];
10429 rtx base_reg;
10430 HOST_WIDE_INT val1 = 0, val2 = 0;
10431
10432 if (REGNO (operands[0]) > REGNO (operands[4]))
10433 {
10434 ldm[1] = operands[4];
10435 ldm[2] = operands[0];
10436 }
10437 else
10438 {
10439 ldm[1] = operands[0];
10440 ldm[2] = operands[4];
10441 }
10442
10443 base_reg = XEXP (operands[2], 0);
10444
10445 if (!REG_P (base_reg))
10446 {
10447 val1 = INTVAL (XEXP (base_reg, 1));
10448 base_reg = XEXP (base_reg, 0);
10449 }
10450
10451 if (!REG_P (XEXP (operands[3], 0)))
10452 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10453
10454 arith[0] = operands[0];
10455 arith[3] = operands[1];
10456
10457 if (val1 < val2)
10458 {
10459 arith[1] = ldm[1];
10460 arith[2] = ldm[2];
10461 }
10462 else
10463 {
10464 arith[1] = ldm[2];
10465 arith[2] = ldm[1];
10466 }
10467
10468 ldm[0] = base_reg;
10469 if (val1 !=0 && val2 != 0)
10470 {
10471 rtx ops[3];
10472
10473 if (val1 == 4 || val2 == 4)
10474 /* Other val must be 8, since we know they are adjacent and neither
10475 is zero. */
10476 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10477 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10478 {
10479 ldm[0] = ops[0] = operands[4];
10480 ops[1] = base_reg;
10481 ops[2] = GEN_INT (val1);
10482 output_add_immediate (ops);
10483 if (val1 < val2)
10484 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10485 else
10486 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10487 }
10488 else
10489 {
10490 /* Offset is out of range for a single add, so use two ldr. */
10491 ops[0] = ldm[1];
10492 ops[1] = base_reg;
10493 ops[2] = GEN_INT (val1);
10494 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10495 ops[0] = ldm[2];
10496 ops[2] = GEN_INT (val2);
10497 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10498 }
10499 }
10500 else if (val1 != 0)
10501 {
10502 if (val1 < val2)
10503 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10504 else
10505 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10506 }
10507 else
10508 {
10509 if (val1 < val2)
10510 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10511 else
10512 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10513 }
10514 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10515 return \"\";
10516 }"
10517 [(set_attr "length" "12")
10518 (set_attr "predicable" "yes")
10519 (set_attr "type" "load1")]
10520 )
10521
10522 ; This pattern is never tried by combine, so do it as a peephole
10523
10524 (define_peephole2
10525 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10526 (match_operand:SI 1 "arm_general_register_operand" ""))
10527 (set (reg:CC CC_REGNUM)
10528 (compare:CC (match_dup 1) (const_int 0)))]
10529 "TARGET_ARM"
10530 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10531 (set (match_dup 0) (match_dup 1))])]
10532 ""
10533 )
10534
10535 (define_split
10536 [(set (match_operand:SI 0 "s_register_operand" "")
10537 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10538 (const_int 0))
10539 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10540 [(match_operand:SI 3 "s_register_operand" "")
10541 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10542 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10543 "TARGET_ARM"
10544 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10545 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10546 (match_dup 5)))]
10547 ""
10548 )
10549
10550 ;; This split can be used because CC_Z mode implies that the following
10551 ;; branch will be an equality, or an unsigned inequality, so the sign
10552 ;; extension is not needed.
10553
10554 (define_split
10555 [(set (reg:CC_Z CC_REGNUM)
10556 (compare:CC_Z
10557 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10558 (const_int 24))
10559 (match_operand 1 "const_int_operand" "")))
10560 (clobber (match_scratch:SI 2 ""))]
10561 "TARGET_ARM
10562 && ((UINTVAL (operands[1]))
10563 == ((UINTVAL (operands[1])) >> 24) << 24)"
10564 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10565 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10566 "
10567 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10568 "
10569 )
10570 ;; ??? Check the patterns above for Thumb-2 usefulness
10571
10572 (define_expand "prologue"
10573 [(clobber (const_int 0))]
10574 "TARGET_EITHER"
10575 "if (TARGET_32BIT)
10576 arm_expand_prologue ();
10577 else
10578 thumb1_expand_prologue ();
10579 DONE;
10580 "
10581 )
10582
10583 (define_expand "epilogue"
10584 [(clobber (const_int 0))]
10585 "TARGET_EITHER"
10586 "
10587 if (crtl->calls_eh_return)
10588 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10589 if (TARGET_THUMB1)
10590 {
10591 thumb1_expand_epilogue ();
10592 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10593 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10594 }
10595 else if (HAVE_return)
10596 {
10597 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10598 no need for explicit testing again. */
10599 emit_jump_insn (gen_return ());
10600 }
10601 else if (TARGET_32BIT)
10602 {
10603 arm_expand_epilogue (true);
10604 }
10605 DONE;
10606 "
10607 )
10608
10609 ;; Note - although unspec_volatile's USE all hard registers,
10610 ;; USEs are ignored after relaod has completed. Thus we need
10611 ;; to add an unspec of the link register to ensure that flow
10612 ;; does not think that it is unused by the sibcall branch that
10613 ;; will replace the standard function epilogue.
10614 (define_expand "sibcall_epilogue"
10615 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10616 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10617 "TARGET_32BIT"
10618 "
10619 arm_expand_epilogue (false);
10620 DONE;
10621 "
10622 )
10623
10624 (define_expand "eh_epilogue"
10625 [(use (match_operand:SI 0 "register_operand" ""))
10626 (use (match_operand:SI 1 "register_operand" ""))
10627 (use (match_operand:SI 2 "register_operand" ""))]
10628 "TARGET_EITHER"
10629 "
10630 {
10631 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10632 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10633 {
10634 rtx ra = gen_rtx_REG (Pmode, 2);
10635
10636 emit_move_insn (ra, operands[2]);
10637 operands[2] = ra;
10638 }
10639 /* This is a hack -- we may have crystalized the function type too
10640 early. */
10641 cfun->machine->func_type = 0;
10642 }"
10643 )
10644
10645 ;; This split is only used during output to reduce the number of patterns
10646 ;; that need assembler instructions adding to them. We allowed the setting
10647 ;; of the conditions to be implicit during rtl generation so that
10648 ;; the conditional compare patterns would work. However this conflicts to
10649 ;; some extent with the conditional data operations, so we have to split them
10650 ;; up again here.
10651
10652 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10653 ;; conditional execution sufficient?
10654
10655 (define_split
10656 [(set (match_operand:SI 0 "s_register_operand" "")
10657 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10658 [(match_operand 2 "" "") (match_operand 3 "" "")])
10659 (match_dup 0)
10660 (match_operand 4 "" "")))
10661 (clobber (reg:CC CC_REGNUM))]
10662 "TARGET_ARM && reload_completed"
10663 [(set (match_dup 5) (match_dup 6))
10664 (cond_exec (match_dup 7)
10665 (set (match_dup 0) (match_dup 4)))]
10666 "
10667 {
10668 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10669 operands[2], operands[3]);
10670 enum rtx_code rc = GET_CODE (operands[1]);
10671
10672 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10673 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10674 if (mode == CCFPmode || mode == CCFPEmode)
10675 rc = reverse_condition_maybe_unordered (rc);
10676 else
10677 rc = reverse_condition (rc);
10678
10679 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10680 }"
10681 )
10682
10683 (define_split
10684 [(set (match_operand:SI 0 "s_register_operand" "")
10685 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10686 [(match_operand 2 "" "") (match_operand 3 "" "")])
10687 (match_operand 4 "" "")
10688 (match_dup 0)))
10689 (clobber (reg:CC CC_REGNUM))]
10690 "TARGET_ARM && reload_completed"
10691 [(set (match_dup 5) (match_dup 6))
10692 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10693 (set (match_dup 0) (match_dup 4)))]
10694 "
10695 {
10696 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10697 operands[2], operands[3]);
10698
10699 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10700 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10701 }"
10702 )
10703
10704 (define_split
10705 [(set (match_operand:SI 0 "s_register_operand" "")
10706 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10707 [(match_operand 2 "" "") (match_operand 3 "" "")])
10708 (match_operand 4 "" "")
10709 (match_operand 5 "" "")))
10710 (clobber (reg:CC CC_REGNUM))]
10711 "TARGET_ARM && reload_completed"
10712 [(set (match_dup 6) (match_dup 7))
10713 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10714 (set (match_dup 0) (match_dup 4)))
10715 (cond_exec (match_dup 8)
10716 (set (match_dup 0) (match_dup 5)))]
10717 "
10718 {
10719 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10720 operands[2], operands[3]);
10721 enum rtx_code rc = GET_CODE (operands[1]);
10722
10723 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10724 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10725 if (mode == CCFPmode || mode == CCFPEmode)
10726 rc = reverse_condition_maybe_unordered (rc);
10727 else
10728 rc = reverse_condition (rc);
10729
10730 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10731 }"
10732 )
10733
10734 (define_split
10735 [(set (match_operand:SI 0 "s_register_operand" "")
10736 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10737 [(match_operand:SI 2 "s_register_operand" "")
10738 (match_operand:SI 3 "arm_add_operand" "")])
10739 (match_operand:SI 4 "arm_rhs_operand" "")
10740 (not:SI
10741 (match_operand:SI 5 "s_register_operand" ""))))
10742 (clobber (reg:CC CC_REGNUM))]
10743 "TARGET_ARM && reload_completed"
10744 [(set (match_dup 6) (match_dup 7))
10745 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10746 (set (match_dup 0) (match_dup 4)))
10747 (cond_exec (match_dup 8)
10748 (set (match_dup 0) (not:SI (match_dup 5))))]
10749 "
10750 {
10751 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10752 operands[2], operands[3]);
10753 enum rtx_code rc = GET_CODE (operands[1]);
10754
10755 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10756 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10757 if (mode == CCFPmode || mode == CCFPEmode)
10758 rc = reverse_condition_maybe_unordered (rc);
10759 else
10760 rc = reverse_condition (rc);
10761
10762 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10763 }"
10764 )
10765
10766 (define_insn "*cond_move_not"
10767 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10768 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10769 [(match_operand 3 "cc_register" "") (const_int 0)])
10770 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10771 (not:SI
10772 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10773 "TARGET_ARM"
10774 "@
10775 mvn%D4\\t%0, %2
10776 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10777 [(set_attr "conds" "use")
10778 (set_attr "type" "mvn_reg,multiple")
10779 (set_attr "length" "4,8")]
10780 )
10781
10782 ;; The next two patterns occur when an AND operation is followed by a
10783 ;; scc insn sequence
10784
10785 (define_insn "*sign_extract_onebit"
10786 [(set (match_operand:SI 0 "s_register_operand" "=r")
10787 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10788 (const_int 1)
10789 (match_operand:SI 2 "const_int_operand" "n")))
10790 (clobber (reg:CC CC_REGNUM))]
10791 "TARGET_ARM"
10792 "*
10793 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10794 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10795 return \"mvnne\\t%0, #0\";
10796 "
10797 [(set_attr "conds" "clob")
10798 (set_attr "length" "8")
10799 (set_attr "type" "multiple")]
10800 )
10801
10802 (define_insn "*not_signextract_onebit"
10803 [(set (match_operand:SI 0 "s_register_operand" "=r")
10804 (not:SI
10805 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10806 (const_int 1)
10807 (match_operand:SI 2 "const_int_operand" "n"))))
10808 (clobber (reg:CC CC_REGNUM))]
10809 "TARGET_ARM"
10810 "*
10811 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10812 output_asm_insn (\"tst\\t%1, %2\", operands);
10813 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10814 return \"movne\\t%0, #0\";
10815 "
10816 [(set_attr "conds" "clob")
10817 (set_attr "length" "12")
10818 (set_attr "type" "multiple")]
10819 )
10820 ;; ??? The above patterns need auditing for Thumb-2
10821
10822 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10823 ;; expressions. For simplicity, the first register is also in the unspec
10824 ;; part.
10825 ;; To avoid the usage of GNU extension, the length attribute is computed
10826 ;; in a C function arm_attr_length_push_multi.
10827 (define_insn "*push_multi"
10828 [(match_parallel 2 "multi_register_push"
10829 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10830 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10831 UNSPEC_PUSH_MULT))])]
10832 ""
10833 "*
10834 {
10835 int num_saves = XVECLEN (operands[2], 0);
10836
10837 /* For the StrongARM at least it is faster to
10838 use STR to store only a single register.
10839 In Thumb mode always use push, and the assembler will pick
10840 something appropriate. */
10841 if (num_saves == 1 && TARGET_ARM)
10842 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10843 else
10844 {
10845 int i;
10846 char pattern[100];
10847
10848 if (TARGET_32BIT)
10849 strcpy (pattern, \"push%?\\t{%1\");
10850 else
10851 strcpy (pattern, \"push\\t{%1\");
10852
10853 for (i = 1; i < num_saves; i++)
10854 {
10855 strcat (pattern, \", %|\");
10856 strcat (pattern,
10857 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10858 }
10859
10860 strcat (pattern, \"}\");
10861 output_asm_insn (pattern, operands);
10862 }
10863
10864 return \"\";
10865 }"
10866 [(set_attr "type" "store4")
10867 (set (attr "length")
10868 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10869 )
10870
10871 (define_insn "stack_tie"
10872 [(set (mem:BLK (scratch))
10873 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10874 (match_operand:SI 1 "s_register_operand" "rk")]
10875 UNSPEC_PRLG_STK))]
10876 ""
10877 ""
10878 [(set_attr "length" "0")
10879 (set_attr "type" "block")]
10880 )
10881
10882 ;; Pop (as used in epilogue RTL)
10883 ;;
10884 (define_insn "*load_multiple_with_writeback"
10885 [(match_parallel 0 "load_multiple_operation"
10886 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10887 (plus:SI (match_dup 1)
10888 (match_operand:SI 2 "const_int_I_operand" "I")))
10889 (set (match_operand:SI 3 "s_register_operand" "=rk")
10890 (mem:SI (match_dup 1)))
10891 ])]
10892 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10893 "*
10894 {
10895 arm_output_multireg_pop (operands, /*return_pc=*/false,
10896 /*cond=*/const_true_rtx,
10897 /*reverse=*/false,
10898 /*update=*/true);
10899 return \"\";
10900 }
10901 "
10902 [(set_attr "type" "load4")
10903 (set_attr "predicable" "yes")
10904 (set (attr "length")
10905 (symbol_ref "arm_attr_length_pop_multi (operands,
10906 /*return_pc=*/false,
10907 /*write_back_p=*/true)"))]
10908 )
10909
10910 ;; Pop with return (as used in epilogue RTL)
10911 ;;
10912 ;; This instruction is generated when the registers are popped at the end of
10913 ;; epilogue. Here, instead of popping the value into LR and then generating
10914 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10915 ;; with (return).
10916 (define_insn "*pop_multiple_with_writeback_and_return"
10917 [(match_parallel 0 "pop_multiple_return"
10918 [(return)
10919 (set (match_operand:SI 1 "s_register_operand" "+rk")
10920 (plus:SI (match_dup 1)
10921 (match_operand:SI 2 "const_int_I_operand" "I")))
10922 (set (match_operand:SI 3 "s_register_operand" "=rk")
10923 (mem:SI (match_dup 1)))
10924 ])]
10925 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10926 "*
10927 {
10928 arm_output_multireg_pop (operands, /*return_pc=*/true,
10929 /*cond=*/const_true_rtx,
10930 /*reverse=*/false,
10931 /*update=*/true);
10932 return \"\";
10933 }
10934 "
10935 [(set_attr "type" "load4")
10936 (set_attr "predicable" "yes")
10937 (set (attr "length")
10938 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10939 /*write_back_p=*/true)"))]
10940 )
10941
10942 (define_insn "*pop_multiple_with_return"
10943 [(match_parallel 0 "pop_multiple_return"
10944 [(return)
10945 (set (match_operand:SI 2 "s_register_operand" "=rk")
10946 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10947 ])]
10948 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10949 "*
10950 {
10951 arm_output_multireg_pop (operands, /*return_pc=*/true,
10952 /*cond=*/const_true_rtx,
10953 /*reverse=*/false,
10954 /*update=*/false);
10955 return \"\";
10956 }
10957 "
10958 [(set_attr "type" "load4")
10959 (set_attr "predicable" "yes")
10960 (set (attr "length")
10961 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10962 /*write_back_p=*/false)"))]
10963 )
10964
10965 ;; Load into PC and return
10966 (define_insn "*ldr_with_return"
10967 [(return)
10968 (set (reg:SI PC_REGNUM)
10969 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10970 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10971 "ldr%?\t%|pc, [%0], #4"
10972 [(set_attr "type" "load1")
10973 (set_attr "predicable" "yes")]
10974 )
10975 ;; Pop for floating point registers (as used in epilogue RTL)
10976 (define_insn "*vfp_pop_multiple_with_writeback"
10977 [(match_parallel 0 "pop_multiple_fp"
10978 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10979 (plus:SI (match_dup 1)
10980 (match_operand:SI 2 "const_int_I_operand" "I")))
10981 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10982 (mem:DF (match_dup 1)))])]
10983 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
10984 "*
10985 {
10986 int num_regs = XVECLEN (operands[0], 0);
10987 char pattern[100];
10988 rtx op_list[2];
10989 strcpy (pattern, \"vldm\\t\");
10990 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10991 strcat (pattern, \"!, {\");
10992 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10993 strcat (pattern, \"%P0\");
10994 if ((num_regs - 1) > 1)
10995 {
10996 strcat (pattern, \"-%P1\");
10997 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10998 }
10999
11000 strcat (pattern, \"}\");
11001 output_asm_insn (pattern, op_list);
11002 return \"\";
11003 }
11004 "
11005 [(set_attr "type" "load4")
11006 (set_attr "conds" "unconditional")
11007 (set_attr "predicable" "no")]
11008 )
11009
11010 ;; Special patterns for dealing with the constant pool
11011
11012 (define_insn "align_4"
11013 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11014 "TARGET_EITHER"
11015 "*
11016 assemble_align (32);
11017 return \"\";
11018 "
11019 [(set_attr "type" "no_insn")]
11020 )
11021
11022 (define_insn "align_8"
11023 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11024 "TARGET_EITHER"
11025 "*
11026 assemble_align (64);
11027 return \"\";
11028 "
11029 [(set_attr "type" "no_insn")]
11030 )
11031
11032 (define_insn "consttable_end"
11033 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11034 "TARGET_EITHER"
11035 "*
11036 making_const_table = FALSE;
11037 return \"\";
11038 "
11039 [(set_attr "type" "no_insn")]
11040 )
11041
11042 (define_insn "consttable_1"
11043 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11044 "TARGET_EITHER"
11045 "*
11046 making_const_table = TRUE;
11047 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11048 assemble_zeros (3);
11049 return \"\";
11050 "
11051 [(set_attr "length" "4")
11052 (set_attr "type" "no_insn")]
11053 )
11054
11055 (define_insn "consttable_2"
11056 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11057 "TARGET_EITHER"
11058 "*
11059 {
11060 rtx x = operands[0];
11061 making_const_table = TRUE;
11062 switch (GET_MODE_CLASS (GET_MODE (x)))
11063 {
11064 case MODE_FLOAT:
11065 arm_emit_fp16_const (x);
11066 break;
11067 default:
11068 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11069 assemble_zeros (2);
11070 break;
11071 }
11072 return \"\";
11073 }"
11074 [(set_attr "length" "4")
11075 (set_attr "type" "no_insn")]
11076 )
11077
11078 (define_insn "consttable_4"
11079 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11080 "TARGET_EITHER"
11081 "*
11082 {
11083 rtx x = operands[0];
11084 making_const_table = TRUE;
11085 switch (GET_MODE_CLASS (GET_MODE (x)))
11086 {
11087 case MODE_FLOAT:
11088 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
11089 BITS_PER_WORD);
11090 break;
11091 default:
11092 /* XXX: Sometimes gcc does something really dumb and ends up with
11093 a HIGH in a constant pool entry, usually because it's trying to
11094 load into a VFP register. We know this will always be used in
11095 combination with a LO_SUM which ignores the high bits, so just
11096 strip off the HIGH. */
11097 if (GET_CODE (x) == HIGH)
11098 x = XEXP (x, 0);
11099 assemble_integer (x, 4, BITS_PER_WORD, 1);
11100 mark_symbol_refs_as_used (x);
11101 break;
11102 }
11103 return \"\";
11104 }"
11105 [(set_attr "length" "4")
11106 (set_attr "type" "no_insn")]
11107 )
11108
11109 (define_insn "consttable_8"
11110 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11111 "TARGET_EITHER"
11112 "*
11113 {
11114 making_const_table = TRUE;
11115 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11116 {
11117 case MODE_FLOAT:
11118 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11119 GET_MODE (operands[0]), BITS_PER_WORD);
11120 break;
11121 default:
11122 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11123 break;
11124 }
11125 return \"\";
11126 }"
11127 [(set_attr "length" "8")
11128 (set_attr "type" "no_insn")]
11129 )
11130
11131 (define_insn "consttable_16"
11132 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11133 "TARGET_EITHER"
11134 "*
11135 {
11136 making_const_table = TRUE;
11137 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11138 {
11139 case MODE_FLOAT:
11140 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11141 GET_MODE (operands[0]), BITS_PER_WORD);
11142 break;
11143 default:
11144 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11145 break;
11146 }
11147 return \"\";
11148 }"
11149 [(set_attr "length" "16")
11150 (set_attr "type" "no_insn")]
11151 )
11152
11153 ;; V5 Instructions,
11154
11155 (define_insn "clzsi2"
11156 [(set (match_operand:SI 0 "s_register_operand" "=r")
11157 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11158 "TARGET_32BIT && arm_arch5"
11159 "clz%?\\t%0, %1"
11160 [(set_attr "predicable" "yes")
11161 (set_attr "predicable_short_it" "no")
11162 (set_attr "type" "clz")])
11163
11164 (define_insn "rbitsi2"
11165 [(set (match_operand:SI 0 "s_register_operand" "=r")
11166 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11167 "TARGET_32BIT && arm_arch_thumb2"
11168 "rbit%?\\t%0, %1"
11169 [(set_attr "predicable" "yes")
11170 (set_attr "predicable_short_it" "no")
11171 (set_attr "type" "clz")])
11172
11173 ;; Keep this as a CTZ expression until after reload and then split
11174 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11175 ;; to fold with any other expression.
11176
11177 (define_insn_and_split "ctzsi2"
11178 [(set (match_operand:SI 0 "s_register_operand" "=r")
11179 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11180 "TARGET_32BIT && arm_arch_thumb2"
11181 "#"
11182 "&& reload_completed"
11183 [(const_int 0)]
11184 "
11185 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11186 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11187 DONE;
11188 ")
11189
11190 ;; V5E instructions.
11191
11192 (define_insn "prefetch"
11193 [(prefetch (match_operand:SI 0 "address_operand" "p")
11194 (match_operand:SI 1 "" "")
11195 (match_operand:SI 2 "" ""))]
11196 "TARGET_32BIT && arm_arch5e"
11197 "pld\\t%a0"
11198 [(set_attr "type" "load1")]
11199 )
11200
11201 ;; General predication pattern
11202
11203 (define_cond_exec
11204 [(match_operator 0 "arm_comparison_operator"
11205 [(match_operand 1 "cc_register" "")
11206 (const_int 0)])]
11207 "TARGET_32BIT
11208 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11209 ""
11210 [(set_attr "predicated" "yes")]
11211 )
11212
11213 (define_insn "force_register_use"
11214 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11215 ""
11216 "%@ %0 needed"
11217 [(set_attr "length" "0")
11218 (set_attr "type" "no_insn")]
11219 )
11220
11221
11222 ;; Patterns for exception handling
11223
11224 (define_expand "eh_return"
11225 [(use (match_operand 0 "general_operand" ""))]
11226 "TARGET_EITHER"
11227 "
11228 {
11229 if (TARGET_32BIT)
11230 emit_insn (gen_arm_eh_return (operands[0]));
11231 else
11232 emit_insn (gen_thumb_eh_return (operands[0]));
11233 DONE;
11234 }"
11235 )
11236
11237 ;; We can't expand this before we know where the link register is stored.
11238 (define_insn_and_split "arm_eh_return"
11239 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11240 VUNSPEC_EH_RETURN)
11241 (clobber (match_scratch:SI 1 "=&r"))]
11242 "TARGET_ARM"
11243 "#"
11244 "&& reload_completed"
11245 [(const_int 0)]
11246 "
11247 {
11248 arm_set_return_address (operands[0], operands[1]);
11249 DONE;
11250 }"
11251 )
11252
11253 \f
11254 ;; TLS support
11255
11256 (define_insn "load_tp_hard"
11257 [(set (match_operand:SI 0 "register_operand" "=r")
11258 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11259 "TARGET_HARD_TP"
11260 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11261 [(set_attr "predicable" "yes")
11262 (set_attr "type" "mrs")]
11263 )
11264
11265 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11266 (define_insn "load_tp_soft"
11267 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11268 (clobber (reg:SI LR_REGNUM))
11269 (clobber (reg:SI IP_REGNUM))
11270 (clobber (reg:CC CC_REGNUM))]
11271 "TARGET_SOFT_TP"
11272 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11273 [(set_attr "conds" "clob")
11274 (set_attr "type" "branch")]
11275 )
11276
11277 ;; tls descriptor call
11278 (define_insn "tlscall"
11279 [(set (reg:SI R0_REGNUM)
11280 (unspec:SI [(reg:SI R0_REGNUM)
11281 (match_operand:SI 0 "" "X")
11282 (match_operand 1 "" "")] UNSPEC_TLS))
11283 (clobber (reg:SI R1_REGNUM))
11284 (clobber (reg:SI LR_REGNUM))
11285 (clobber (reg:SI CC_REGNUM))]
11286 "TARGET_GNU2_TLS"
11287 {
11288 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11289 INTVAL (operands[1]));
11290 return "bl\\t%c0(tlscall)";
11291 }
11292 [(set_attr "conds" "clob")
11293 (set_attr "length" "4")
11294 (set_attr "type" "branch")]
11295 )
11296
11297 ;; For thread pointer builtin
11298 (define_expand "get_thread_pointersi"
11299 [(match_operand:SI 0 "s_register_operand" "=r")]
11300 ""
11301 "
11302 {
11303 arm_load_tp (operands[0]);
11304 DONE;
11305 }")
11306
11307 ;;
11308
11309 ;; We only care about the lower 16 bits of the constant
11310 ;; being inserted into the upper 16 bits of the register.
11311 (define_insn "*arm_movtas_ze"
11312 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11313 (const_int 16)
11314 (const_int 16))
11315 (match_operand:SI 1 "const_int_operand" ""))]
11316 "TARGET_HAVE_MOVT"
11317 "@
11318 movt%?\t%0, %L1
11319 movt\t%0, %L1"
11320 [(set_attr "arch" "32,v8mb")
11321 (set_attr "predicable" "yes")
11322 (set_attr "predicable_short_it" "no")
11323 (set_attr "length" "4")
11324 (set_attr "type" "alu_sreg")]
11325 )
11326
11327 (define_insn "*arm_rev"
11328 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11329 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11330 "arm_arch6"
11331 "@
11332 rev\t%0, %1
11333 rev%?\t%0, %1
11334 rev%?\t%0, %1"
11335 [(set_attr "arch" "t1,t2,32")
11336 (set_attr "length" "2,2,4")
11337 (set_attr "predicable" "no,yes,yes")
11338 (set_attr "predicable_short_it" "no")
11339 (set_attr "type" "rev")]
11340 )
11341
11342 (define_expand "arm_legacy_rev"
11343 [(set (match_operand:SI 2 "s_register_operand" "")
11344 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11345 (const_int 16))
11346 (match_dup 1)))
11347 (set (match_dup 2)
11348 (lshiftrt:SI (match_dup 2)
11349 (const_int 8)))
11350 (set (match_operand:SI 3 "s_register_operand" "")
11351 (rotatert:SI (match_dup 1)
11352 (const_int 8)))
11353 (set (match_dup 2)
11354 (and:SI (match_dup 2)
11355 (const_int -65281)))
11356 (set (match_operand:SI 0 "s_register_operand" "")
11357 (xor:SI (match_dup 3)
11358 (match_dup 2)))]
11359 "TARGET_32BIT"
11360 ""
11361 )
11362
11363 ;; Reuse temporaries to keep register pressure down.
11364 (define_expand "thumb_legacy_rev"
11365 [(set (match_operand:SI 2 "s_register_operand" "")
11366 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11367 (const_int 24)))
11368 (set (match_operand:SI 3 "s_register_operand" "")
11369 (lshiftrt:SI (match_dup 1)
11370 (const_int 24)))
11371 (set (match_dup 3)
11372 (ior:SI (match_dup 3)
11373 (match_dup 2)))
11374 (set (match_operand:SI 4 "s_register_operand" "")
11375 (const_int 16))
11376 (set (match_operand:SI 5 "s_register_operand" "")
11377 (rotatert:SI (match_dup 1)
11378 (match_dup 4)))
11379 (set (match_dup 2)
11380 (ashift:SI (match_dup 5)
11381 (const_int 24)))
11382 (set (match_dup 5)
11383 (lshiftrt:SI (match_dup 5)
11384 (const_int 24)))
11385 (set (match_dup 5)
11386 (ior:SI (match_dup 5)
11387 (match_dup 2)))
11388 (set (match_dup 5)
11389 (rotatert:SI (match_dup 5)
11390 (match_dup 4)))
11391 (set (match_operand:SI 0 "s_register_operand" "")
11392 (ior:SI (match_dup 5)
11393 (match_dup 3)))]
11394 "TARGET_THUMB"
11395 ""
11396 )
11397
11398 ;; ARM-specific expansion of signed mod by power of 2
11399 ;; using conditional negate.
11400 ;; For r0 % n where n is a power of 2 produce:
11401 ;; rsbs r1, r0, #0
11402 ;; and r0, r0, #(n - 1)
11403 ;; and r1, r1, #(n - 1)
11404 ;; rsbpl r0, r1, #0
11405
11406 (define_expand "modsi3"
11407 [(match_operand:SI 0 "register_operand" "")
11408 (match_operand:SI 1 "register_operand" "")
11409 (match_operand:SI 2 "const_int_operand" "")]
11410 "TARGET_32BIT"
11411 {
11412 HOST_WIDE_INT val = INTVAL (operands[2]);
11413
11414 if (val <= 0
11415 || exact_log2 (val) <= 0)
11416 FAIL;
11417
11418 rtx mask = GEN_INT (val - 1);
11419
11420 /* In the special case of x0 % 2 we can do the even shorter:
11421 cmp r0, #0
11422 and r0, r0, #1
11423 rsblt r0, r0, #0. */
11424
11425 if (val == 2)
11426 {
11427 rtx cc_reg = arm_gen_compare_reg (LT,
11428 operands[1], const0_rtx, NULL_RTX);
11429 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11430 rtx masked = gen_reg_rtx (SImode);
11431
11432 emit_insn (gen_andsi3 (masked, operands[1], mask));
11433 emit_move_insn (operands[0],
11434 gen_rtx_IF_THEN_ELSE (SImode, cond,
11435 gen_rtx_NEG (SImode,
11436 masked),
11437 masked));
11438 DONE;
11439 }
11440
11441 rtx neg_op = gen_reg_rtx (SImode);
11442 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11443 operands[1]));
11444
11445 /* Extract the condition register and mode. */
11446 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11447 rtx cc_reg = SET_DEST (cmp);
11448 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11449
11450 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11451
11452 rtx masked_neg = gen_reg_rtx (SImode);
11453 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11454
11455 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11456 during expand does not always work. Do an IF_THEN_ELSE instead. */
11457 emit_move_insn (operands[0],
11458 gen_rtx_IF_THEN_ELSE (SImode, cond,
11459 gen_rtx_NEG (SImode, masked_neg),
11460 operands[0]));
11461
11462
11463 DONE;
11464 }
11465 )
11466
11467 (define_expand "bswapsi2"
11468 [(set (match_operand:SI 0 "s_register_operand" "=r")
11469 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11470 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11471 "
11472 if (!arm_arch6)
11473 {
11474 rtx op2 = gen_reg_rtx (SImode);
11475 rtx op3 = gen_reg_rtx (SImode);
11476
11477 if (TARGET_THUMB)
11478 {
11479 rtx op4 = gen_reg_rtx (SImode);
11480 rtx op5 = gen_reg_rtx (SImode);
11481
11482 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11483 op2, op3, op4, op5));
11484 }
11485 else
11486 {
11487 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11488 op2, op3));
11489 }
11490
11491 DONE;
11492 }
11493 "
11494 )
11495
11496 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11497 ;; and unsigned variants, respectively. For rev16, expose
11498 ;; byte-swapping in the lower 16 bits only.
11499 (define_insn "*arm_revsh"
11500 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11501 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11502 "arm_arch6"
11503 "@
11504 revsh\t%0, %1
11505 revsh%?\t%0, %1
11506 revsh%?\t%0, %1"
11507 [(set_attr "arch" "t1,t2,32")
11508 (set_attr "length" "2,2,4")
11509 (set_attr "type" "rev")]
11510 )
11511
11512 (define_insn "*arm_rev16"
11513 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11514 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11515 "arm_arch6"
11516 "@
11517 rev16\t%0, %1
11518 rev16%?\t%0, %1
11519 rev16%?\t%0, %1"
11520 [(set_attr "arch" "t1,t2,32")
11521 (set_attr "length" "2,2,4")
11522 (set_attr "type" "rev")]
11523 )
11524
11525 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11526 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11527 ;; each valid permutation.
11528
11529 (define_insn "arm_rev16si2"
11530 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11531 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11532 (const_int 8))
11533 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11534 (and:SI (lshiftrt:SI (match_dup 1)
11535 (const_int 8))
11536 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11537 "arm_arch6
11538 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11539 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11540 "rev16\\t%0, %1"
11541 [(set_attr "arch" "t1,t2,32")
11542 (set_attr "length" "2,2,4")
11543 (set_attr "type" "rev")]
11544 )
11545
11546 (define_insn "arm_rev16si2_alt"
11547 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11548 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11549 (const_int 8))
11550 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11551 (and:SI (ashift:SI (match_dup 1)
11552 (const_int 8))
11553 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11554 "arm_arch6
11555 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11556 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11557 "rev16\\t%0, %1"
11558 [(set_attr "arch" "t1,t2,32")
11559 (set_attr "length" "2,2,4")
11560 (set_attr "type" "rev")]
11561 )
11562
11563 (define_expand "bswaphi2"
11564 [(set (match_operand:HI 0 "s_register_operand" "=r")
11565 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11566 "arm_arch6"
11567 ""
11568 )
11569
11570 ;; Patterns for LDRD/STRD in Thumb2 mode
11571
11572 (define_insn "*thumb2_ldrd"
11573 [(set (match_operand:SI 0 "s_register_operand" "=r")
11574 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11575 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11576 (set (match_operand:SI 3 "s_register_operand" "=r")
11577 (mem:SI (plus:SI (match_dup 1)
11578 (match_operand:SI 4 "const_int_operand" ""))))]
11579 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11580 && current_tune->prefer_ldrd_strd
11581 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11582 && (operands_ok_ldrd_strd (operands[0], operands[3],
11583 operands[1], INTVAL (operands[2]),
11584 false, true))"
11585 "ldrd%?\t%0, %3, [%1, %2]"
11586 [(set_attr "type" "load2")
11587 (set_attr "predicable" "yes")
11588 (set_attr "predicable_short_it" "no")])
11589
11590 (define_insn "*thumb2_ldrd_base"
11591 [(set (match_operand:SI 0 "s_register_operand" "=r")
11592 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11593 (set (match_operand:SI 2 "s_register_operand" "=r")
11594 (mem:SI (plus:SI (match_dup 1)
11595 (const_int 4))))]
11596 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11597 && current_tune->prefer_ldrd_strd
11598 && (operands_ok_ldrd_strd (operands[0], operands[2],
11599 operands[1], 0, false, true))"
11600 "ldrd%?\t%0, %2, [%1]"
11601 [(set_attr "type" "load2")
11602 (set_attr "predicable" "yes")
11603 (set_attr "predicable_short_it" "no")])
11604
11605 (define_insn "*thumb2_ldrd_base_neg"
11606 [(set (match_operand:SI 0 "s_register_operand" "=r")
11607 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11608 (const_int -4))))
11609 (set (match_operand:SI 2 "s_register_operand" "=r")
11610 (mem:SI (match_dup 1)))]
11611 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11612 && current_tune->prefer_ldrd_strd
11613 && (operands_ok_ldrd_strd (operands[0], operands[2],
11614 operands[1], -4, false, true))"
11615 "ldrd%?\t%0, %2, [%1, #-4]"
11616 [(set_attr "type" "load2")
11617 (set_attr "predicable" "yes")
11618 (set_attr "predicable_short_it" "no")])
11619
11620 (define_insn "*thumb2_strd"
11621 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11622 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11623 (match_operand:SI 2 "s_register_operand" "r"))
11624 (set (mem:SI (plus:SI (match_dup 0)
11625 (match_operand:SI 3 "const_int_operand" "")))
11626 (match_operand:SI 4 "s_register_operand" "r"))]
11627 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11628 && current_tune->prefer_ldrd_strd
11629 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11630 && (operands_ok_ldrd_strd (operands[2], operands[4],
11631 operands[0], INTVAL (operands[1]),
11632 false, false))"
11633 "strd%?\t%2, %4, [%0, %1]"
11634 [(set_attr "type" "store2")
11635 (set_attr "predicable" "yes")
11636 (set_attr "predicable_short_it" "no")])
11637
11638 (define_insn "*thumb2_strd_base"
11639 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11640 (match_operand:SI 1 "s_register_operand" "r"))
11641 (set (mem:SI (plus:SI (match_dup 0)
11642 (const_int 4)))
11643 (match_operand:SI 2 "s_register_operand" "r"))]
11644 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11645 && current_tune->prefer_ldrd_strd
11646 && (operands_ok_ldrd_strd (operands[1], operands[2],
11647 operands[0], 0, false, false))"
11648 "strd%?\t%1, %2, [%0]"
11649 [(set_attr "type" "store2")
11650 (set_attr "predicable" "yes")
11651 (set_attr "predicable_short_it" "no")])
11652
11653 (define_insn "*thumb2_strd_base_neg"
11654 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11655 (const_int -4)))
11656 (match_operand:SI 1 "s_register_operand" "r"))
11657 (set (mem:SI (match_dup 0))
11658 (match_operand:SI 2 "s_register_operand" "r"))]
11659 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11660 && current_tune->prefer_ldrd_strd
11661 && (operands_ok_ldrd_strd (operands[1], operands[2],
11662 operands[0], -4, false, false))"
11663 "strd%?\t%1, %2, [%0, #-4]"
11664 [(set_attr "type" "store2")
11665 (set_attr "predicable" "yes")
11666 (set_attr "predicable_short_it" "no")])
11667
11668 ;; ARMv8 CRC32 instructions.
11669 (define_insn "<crc_variant>"
11670 [(set (match_operand:SI 0 "s_register_operand" "=r")
11671 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11672 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11673 CRC))]
11674 "TARGET_CRC32"
11675 "<crc_variant>\\t%0, %1, %2"
11676 [(set_attr "type" "crc")
11677 (set_attr "conds" "unconditional")]
11678 )
11679
11680 ;; Load the load/store double peephole optimizations.
11681 (include "ldrdstrd.md")
11682
11683 ;; Load the load/store multiple patterns
11684 (include "ldmstm.md")
11685
11686 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11687 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11688 (define_insn "*load_multiple"
11689 [(match_parallel 0 "load_multiple_operation"
11690 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11691 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11692 ])]
11693 "TARGET_32BIT"
11694 "*
11695 {
11696 arm_output_multireg_pop (operands, /*return_pc=*/false,
11697 /*cond=*/const_true_rtx,
11698 /*reverse=*/false,
11699 /*update=*/false);
11700 return \"\";
11701 }
11702 "
11703 [(set_attr "predicable" "yes")]
11704 )
11705
11706 (define_expand "copysignsf3"
11707 [(match_operand:SF 0 "register_operand")
11708 (match_operand:SF 1 "register_operand")
11709 (match_operand:SF 2 "register_operand")]
11710 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11711 "{
11712 emit_move_insn (operands[0], operands[2]);
11713 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11714 GEN_INT (31), GEN_INT (0),
11715 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11716 DONE;
11717 }"
11718 )
11719
11720 (define_expand "copysigndf3"
11721 [(match_operand:DF 0 "register_operand")
11722 (match_operand:DF 1 "register_operand")
11723 (match_operand:DF 2 "register_operand")]
11724 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11725 "{
11726 rtx op0_low = gen_lowpart (SImode, operands[0]);
11727 rtx op0_high = gen_highpart (SImode, operands[0]);
11728 rtx op1_low = gen_lowpart (SImode, operands[1]);
11729 rtx op1_high = gen_highpart (SImode, operands[1]);
11730 rtx op2_high = gen_highpart (SImode, operands[2]);
11731
11732 rtx scratch1 = gen_reg_rtx (SImode);
11733 rtx scratch2 = gen_reg_rtx (SImode);
11734 emit_move_insn (scratch1, op2_high);
11735 emit_move_insn (scratch2, op1_high);
11736
11737 emit_insn(gen_rtx_SET(scratch1,
11738 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11739 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11740 emit_move_insn (op0_low, op1_low);
11741 emit_move_insn (op0_high, scratch2);
11742
11743 DONE;
11744 }"
11745 )
11746
11747 ;; movmisalign patterns for HImode and SImode.
11748 (define_expand "movmisalign<mode>"
11749 [(match_operand:HSI 0 "general_operand")
11750 (match_operand:HSI 1 "general_operand")]
11751 "unaligned_access"
11752 {
11753 /* This pattern is not permitted to fail during expansion: if both arguments
11754 are non-registers (e.g. memory := constant), force operand 1 into a
11755 register. */
11756 rtx (* gen_unaligned_load)(rtx, rtx);
11757 rtx tmp_dest = operands[0];
11758 if (!s_register_operand (operands[0], <MODE>mode)
11759 && !s_register_operand (operands[1], <MODE>mode))
11760 operands[1] = force_reg (<MODE>mode, operands[1]);
11761
11762 if (<MODE>mode == HImode)
11763 {
11764 gen_unaligned_load = gen_unaligned_loadhiu;
11765 tmp_dest = gen_reg_rtx (SImode);
11766 }
11767 else
11768 gen_unaligned_load = gen_unaligned_loadsi;
11769
11770 if (MEM_P (operands[1]))
11771 {
11772 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11773 if (<MODE>mode == HImode)
11774 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11775 }
11776 else
11777 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11778
11779 DONE;
11780 })
11781
11782 ;; Vector bits common to IWMMXT and Neon
11783 (include "vec-common.md")
11784 ;; Load the Intel Wireless Multimedia Extension patterns
11785 (include "iwmmxt.md")
11786 ;; Load the VFP co-processor patterns
11787 (include "vfp.md")
11788 ;; Thumb-1 patterns
11789 (include "thumb1.md")
11790 ;; Thumb-2 patterns
11791 (include "thumb2.md")
11792 ;; Neon patterns
11793 (include "neon.md")
11794 ;; Crypto patterns
11795 (include "crypto.md")
11796 ;; Synchronization Primitives
11797 (include "sync.md")
11798 ;; Fixed-point patterns
11799 (include "arm-fixed.md")