]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm.md
Remove DImode expansions for 1-bit shifts
[thirdparty/gcc.git] / gcc / config / arm / arm.md
1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2017 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
13
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 \f
26 ;;---------------------------------------------------------------------------
27 ;; Constants
28
29 ;; Register numbers -- All machine registers should be defined here
30 (define_constants
31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (IP_REGNUM 12) ; Scratch register
34 (SP_REGNUM 13) ; Stack pointer
35 (LR_REGNUM 14) ; Return address register
36 (PC_REGNUM 15) ; Program counter
37 (LAST_ARM_REGNUM 15) ;
38 (CC_REGNUM 100) ; Condition code pseudo register
39 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
40 ]
41 )
42 ;; 3rd operand to select_dominance_cc_mode
43 (define_constants
44 [(DOM_CC_X_AND_Y 0)
45 (DOM_CC_NX_OR_Y 1)
46 (DOM_CC_X_OR_Y 2)
47 ]
48 )
49 ;; conditional compare combination
50 (define_constants
51 [(CMP_CMP 0)
52 (CMN_CMP 1)
53 (CMP_CMN 2)
54 (CMN_CMN 3)
55 (NUM_OF_COND_CMP 4)
56 ]
57 )
58
59 \f
60 ;;---------------------------------------------------------------------------
61 ;; Attributes
62
63 ;; Processor type. This is created automatically from arm-cores.def.
64 (include "arm-tune.md")
65
66 ;; Instruction classification types
67 (include "types.md")
68
69 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70 ; generating ARM code. This is used to control the length of some insn
71 ; patterns that share the same RTL in both ARM and Thumb code.
72 (define_attr "is_thumb" "yes,no"
73 (const (if_then_else (symbol_ref "TARGET_THUMB")
74 (const_string "yes") (const_string "no"))))
75
76 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
78
79 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
80 (define_attr "is_thumb1" "yes,no"
81 (const (if_then_else (symbol_ref "TARGET_THUMB1")
82 (const_string "yes") (const_string "no"))))
83
84 ; We use this attribute to disable alternatives that can produce 32-bit
85 ; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
86 ; that contain 32-bit instructions.
87 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
88
89 ; This attribute is used to disable a predicated alternative when we have
90 ; arm_restrict_it.
91 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
92
93 ;; Operand number of an input operand that is shifted. Zero if the
94 ;; given instruction does not shift one of its input operands.
95 (define_attr "shift" "" (const_int 0))
96
97 ;; [For compatibility with AArch64 in pipeline models]
98 ;; Attribute that specifies whether or not the instruction touches fp
99 ;; registers.
100 (define_attr "fp" "no,yes" (const_string "no"))
101
102 ; Floating Point Unit. If we only have floating point emulation, then there
103 ; is no point in scheduling the floating point insns. (Well, for best
104 ; performance we should try and group them together).
105 (define_attr "fpu" "none,vfp"
106 (const (symbol_ref "arm_fpu_attr")))
107
108 ; Predicated means that the insn form is conditionally executed based on a
109 ; predicate. We default to 'no' because no Thumb patterns match this rule
110 ; and not all ARM insns do.
111 (define_attr "predicated" "yes,no" (const_string "no"))
112
113 ; LENGTH of an instruction (in bytes)
114 (define_attr "length" ""
115 (const_int 4))
116
117 ; The architecture which supports the instruction (or alternative).
118 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
119 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
120 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
121 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
122 ; Baseline. This attribute is used to compute attribute "enabled",
123 ; use type "any" to enable an alternative in all cases.
124 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
125 (const_string "any"))
126
127 (define_attr "arch_enabled" "no,yes"
128 (cond [(eq_attr "arch" "any")
129 (const_string "yes")
130
131 (and (eq_attr "arch" "a")
132 (match_test "TARGET_ARM"))
133 (const_string "yes")
134
135 (and (eq_attr "arch" "t")
136 (match_test "TARGET_THUMB"))
137 (const_string "yes")
138
139 (and (eq_attr "arch" "t1")
140 (match_test "TARGET_THUMB1"))
141 (const_string "yes")
142
143 (and (eq_attr "arch" "t2")
144 (match_test "TARGET_THUMB2"))
145 (const_string "yes")
146
147 (and (eq_attr "arch" "32")
148 (match_test "TARGET_32BIT"))
149 (const_string "yes")
150
151 (and (eq_attr "arch" "v6")
152 (match_test "TARGET_32BIT && arm_arch6"))
153 (const_string "yes")
154
155 (and (eq_attr "arch" "nov6")
156 (match_test "TARGET_32BIT && !arm_arch6"))
157 (const_string "yes")
158
159 (and (eq_attr "arch" "v6t2")
160 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
161 (const_string "yes")
162
163 (and (eq_attr "arch" "v8mb")
164 (match_test "TARGET_THUMB1 && arm_arch8"))
165 (const_string "yes")
166
167 (and (eq_attr "arch" "avoid_neon_for_64bits")
168 (match_test "TARGET_NEON")
169 (not (match_test "TARGET_PREFER_NEON_64BITS")))
170 (const_string "yes")
171
172 (and (eq_attr "arch" "neon_for_64bits")
173 (match_test "TARGET_NEON")
174 (match_test "TARGET_PREFER_NEON_64BITS"))
175 (const_string "yes")
176
177 (and (eq_attr "arch" "iwmmxt2")
178 (match_test "TARGET_REALLY_IWMMXT2"))
179 (const_string "yes")
180
181 (and (eq_attr "arch" "armv6_or_vfpv3")
182 (match_test "arm_arch6 || TARGET_VFP3"))
183 (const_string "yes")
184
185 (and (eq_attr "arch" "neon")
186 (match_test "TARGET_NEON"))
187 (const_string "yes")
188 ]
189
190 (const_string "no")))
191
192 (define_attr "opt" "any,speed,size"
193 (const_string "any"))
194
195 (define_attr "opt_enabled" "no,yes"
196 (cond [(eq_attr "opt" "any")
197 (const_string "yes")
198
199 (and (eq_attr "opt" "speed")
200 (match_test "optimize_function_for_speed_p (cfun)"))
201 (const_string "yes")
202
203 (and (eq_attr "opt" "size")
204 (match_test "optimize_function_for_size_p (cfun)"))
205 (const_string "yes")]
206 (const_string "no")))
207
208 (define_attr "use_literal_pool" "no,yes"
209 (cond [(and (eq_attr "type" "f_loads,f_loadd")
210 (match_test "CONSTANT_P (operands[1])"))
211 (const_string "yes")]
212 (const_string "no")))
213
214 ; Enable all alternatives that are both arch_enabled and insn_enabled.
215 ; FIXME:: opt_enabled has been temporarily removed till the time we have
216 ; an attribute that allows the use of such alternatives.
217 ; This depends on caching of speed_p, size_p on a per
218 ; alternative basis. The problem is that the enabled attribute
219 ; cannot depend on any state that is not cached or is not constant
220 ; for a compilation unit. We probably need a generic "hot/cold"
221 ; alternative which if implemented can help with this. We disable this
222 ; until such a time as this is implemented and / or the improvements or
223 ; regressions with removing this attribute are double checked.
224 ; See ashldi3_neon and <shift>di3_neon in neon.md.
225
226 (define_attr "enabled" "no,yes"
227 (cond [(and (eq_attr "predicable_short_it" "no")
228 (and (eq_attr "predicated" "yes")
229 (match_test "arm_restrict_it")))
230 (const_string "no")
231
232 (and (eq_attr "enabled_for_depr_it" "no")
233 (match_test "arm_restrict_it"))
234 (const_string "no")
235
236 (eq_attr "arch_enabled" "no")
237 (const_string "no")]
238 (const_string "yes")))
239
240 ; POOL_RANGE is how far away from a constant pool entry that this insn
241 ; can be placed. If the distance is zero, then this insn will never
242 ; reference the pool.
243 ; Note that for Thumb constant pools the PC value is rounded down to the
244 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
245 ; Thumb insns) should be set to <max_range> - 2.
246 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
247 ; before its address. It is set to <max_range> - (8 + <data_size>).
248 (define_attr "arm_pool_range" "" (const_int 0))
249 (define_attr "thumb2_pool_range" "" (const_int 0))
250 (define_attr "arm_neg_pool_range" "" (const_int 0))
251 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
252
253 (define_attr "pool_range" ""
254 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
255 (attr "arm_pool_range")))
256 (define_attr "neg_pool_range" ""
257 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
258 (attr "arm_neg_pool_range")))
259
260 ; An assembler sequence may clobber the condition codes without us knowing.
261 ; If such an insn references the pool, then we have no way of knowing how,
262 ; so use the most conservative value for pool_range.
263 (define_asm_attributes
264 [(set_attr "conds" "clob")
265 (set_attr "length" "4")
266 (set_attr "pool_range" "250")])
267
268 ; Load scheduling, set from the arm_ld_sched variable
269 ; initialized by arm_option_override()
270 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
271
272 ; condition codes: this one is used by final_prescan_insn to speed up
273 ; conditionalizing instructions. It saves having to scan the rtl to see if
274 ; it uses or alters the condition codes.
275 ;
276 ; USE means that the condition codes are used by the insn in the process of
277 ; outputting code, this means (at present) that we can't use the insn in
278 ; inlined branches
279 ;
280 ; SET means that the purpose of the insn is to set the condition codes in a
281 ; well defined manner.
282 ;
283 ; CLOB means that the condition codes are altered in an undefined manner, if
284 ; they are altered at all
285 ;
286 ; UNCONDITIONAL means the instruction can not be conditionally executed and
287 ; that the instruction does not use or alter the condition codes.
288 ;
289 ; NOCOND means that the instruction does not use or alter the condition
290 ; codes but can be converted into a conditionally exectuted instruction.
291
292 (define_attr "conds" "use,set,clob,unconditional,nocond"
293 (if_then_else
294 (ior (eq_attr "is_thumb1" "yes")
295 (eq_attr "type" "call"))
296 (const_string "clob")
297 (if_then_else (eq_attr "is_neon_type" "no")
298 (const_string "nocond")
299 (const_string "unconditional"))))
300
301 ; Predicable means that the insn can be conditionally executed based on
302 ; an automatically added predicate (additional patterns are generated by
303 ; gen...). We default to 'no' because no Thumb patterns match this rule
304 ; and not all ARM patterns do.
305 (define_attr "predicable" "no,yes" (const_string "no"))
306
307 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
308 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
309 ; suffer blockages enough to warrant modelling this (and it can adversely
310 ; affect the schedule).
311 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
312
313 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
314 ; to stall the processor. Used with model_wbuf above.
315 (define_attr "write_conflict" "no,yes"
316 (if_then_else (eq_attr "type"
317 "block,call,load_4")
318 (const_string "yes")
319 (const_string "no")))
320
321 ; Classify the insns into those that take one cycle and those that take more
322 ; than one on the main cpu execution unit.
323 (define_attr "core_cycles" "single,multi"
324 (if_then_else (eq_attr "type"
325 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
326 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
327 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
328 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
329 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
330 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
331 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
332 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
333 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
334 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
335 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
336 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
337 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
338 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
339 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
340 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
341 (const_string "single")
342 (const_string "multi")))
343
344 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
345 ;; distant label. Only applicable to Thumb code.
346 (define_attr "far_jump" "yes,no" (const_string "no"))
347
348
349 ;; The number of machine instructions this pattern expands to.
350 ;; Used for Thumb-2 conditional execution.
351 (define_attr "ce_count" "" (const_int 1))
352
353 ;;---------------------------------------------------------------------------
354 ;; Unspecs
355
356 (include "unspecs.md")
357
358 ;;---------------------------------------------------------------------------
359 ;; Mode iterators
360
361 (include "iterators.md")
362
363 ;;---------------------------------------------------------------------------
364 ;; Predicates
365
366 (include "predicates.md")
367 (include "constraints.md")
368
369 ;;---------------------------------------------------------------------------
370 ;; Pipeline descriptions
371
372 (define_attr "tune_cortexr4" "yes,no"
373 (const (if_then_else
374 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
375 (const_string "yes")
376 (const_string "no"))))
377
378 ;; True if the generic scheduling description should be used.
379
380 (define_attr "generic_sched" "yes,no"
381 (const (if_then_else
382 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
383 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
384 arm1136jfs,cortexa5,cortexa7,cortexa8,\
385 cortexa9,cortexa12,cortexa15,cortexa17,\
386 cortexa53,cortexa57,cortexm4,cortexm7,\
387 exynosm1,marvell_pj4,xgene1")
388 (eq_attr "tune_cortexr4" "yes"))
389 (const_string "no")
390 (const_string "yes"))))
391
392 (define_attr "generic_vfp" "yes,no"
393 (const (if_then_else
394 (and (eq_attr "fpu" "vfp")
395 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
396 cortexa8,cortexa9,cortexa53,cortexm4,\
397 cortexm7,marvell_pj4,xgene1")
398 (eq_attr "tune_cortexr4" "no"))
399 (const_string "yes")
400 (const_string "no"))))
401
402 (include "marvell-f-iwmmxt.md")
403 (include "arm-generic.md")
404 (include "arm926ejs.md")
405 (include "arm1020e.md")
406 (include "arm1026ejs.md")
407 (include "arm1136jfs.md")
408 (include "fa526.md")
409 (include "fa606te.md")
410 (include "fa626te.md")
411 (include "fmp626.md")
412 (include "fa726te.md")
413 (include "cortex-a5.md")
414 (include "cortex-a7.md")
415 (include "cortex-a8.md")
416 (include "cortex-a9.md")
417 (include "cortex-a15.md")
418 (include "cortex-a17.md")
419 (include "cortex-a53.md")
420 (include "cortex-a57.md")
421 (include "cortex-r4.md")
422 (include "cortex-r4f.md")
423 (include "cortex-m7.md")
424 (include "cortex-m4.md")
425 (include "cortex-m4-fpu.md")
426 (include "exynos-m1.md")
427 (include "vfp11.md")
428 (include "marvell-pj4.md")
429 (include "xgene1.md")
430
431 \f
432 ;;---------------------------------------------------------------------------
433 ;; Insn patterns
434 ;;
435 ;; Addition insns.
436
437 ;; Note: For DImode insns, there is normally no reason why operands should
438 ;; not be in the same register, what we don't want is for something being
439 ;; written to partially overlap something that is an input.
440
441 (define_expand "adddi3"
442 [(parallel
443 [(set (match_operand:DI 0 "s_register_operand" "")
444 (plus:DI (match_operand:DI 1 "s_register_operand" "")
445 (match_operand:DI 2 "arm_adddi_operand" "")))
446 (clobber (reg:CC CC_REGNUM))])]
447 "TARGET_EITHER"
448 "
449 if (TARGET_THUMB1)
450 {
451 if (!REG_P (operands[1]))
452 operands[1] = force_reg (DImode, operands[1]);
453 if (!REG_P (operands[2]))
454 operands[2] = force_reg (DImode, operands[2]);
455 }
456 "
457 )
458
459 (define_insn_and_split "*arm_adddi3"
460 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r,&r,&r")
461 (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r")
462 (match_operand:DI 2 "arm_general_adddi_operand" "r, 0, r, Dd, Dd")))
463 (clobber (reg:CC CC_REGNUM))]
464 "TARGET_32BIT && !TARGET_NEON"
465 "#"
466 "TARGET_32BIT && ((!TARGET_NEON && !TARGET_IWMMXT) || reload_completed)"
467 [(parallel [(set (reg:CC_C CC_REGNUM)
468 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
469 (match_dup 1)))
470 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
471 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
472 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
473 "
474 {
475 operands[3] = gen_highpart (SImode, operands[0]);
476 operands[0] = gen_lowpart (SImode, operands[0]);
477 operands[4] = gen_highpart (SImode, operands[1]);
478 operands[1] = gen_lowpart (SImode, operands[1]);
479 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
480 operands[2] = gen_lowpart (SImode, operands[2]);
481 }"
482 [(set_attr "conds" "clob")
483 (set_attr "length" "8")
484 (set_attr "type" "multiple")]
485 )
486
487 (define_insn_and_split "*adddi_sesidi_di"
488 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
489 (plus:DI (sign_extend:DI
490 (match_operand:SI 2 "s_register_operand" "r,r"))
491 (match_operand:DI 1 "s_register_operand" "0,r")))
492 (clobber (reg:CC CC_REGNUM))]
493 "TARGET_32BIT"
494 "#"
495 "TARGET_32BIT && reload_completed"
496 [(parallel [(set (reg:CC_C CC_REGNUM)
497 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
498 (match_dup 1)))
499 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
500 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
501 (const_int 31))
502 (match_dup 4))
503 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
504 "
505 {
506 operands[3] = gen_highpart (SImode, operands[0]);
507 operands[0] = gen_lowpart (SImode, operands[0]);
508 operands[4] = gen_highpart (SImode, operands[1]);
509 operands[1] = gen_lowpart (SImode, operands[1]);
510 operands[2] = gen_lowpart (SImode, operands[2]);
511 }"
512 [(set_attr "conds" "clob")
513 (set_attr "length" "8")
514 (set_attr "type" "multiple")]
515 )
516
517 (define_insn_and_split "*adddi_zesidi_di"
518 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
519 (plus:DI (zero_extend:DI
520 (match_operand:SI 2 "s_register_operand" "r,r"))
521 (match_operand:DI 1 "s_register_operand" "0,r")))
522 (clobber (reg:CC CC_REGNUM))]
523 "TARGET_32BIT"
524 "#"
525 "TARGET_32BIT && reload_completed"
526 [(parallel [(set (reg:CC_C CC_REGNUM)
527 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
528 (match_dup 1)))
529 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
530 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
531 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
532 "
533 {
534 operands[3] = gen_highpart (SImode, operands[0]);
535 operands[0] = gen_lowpart (SImode, operands[0]);
536 operands[4] = gen_highpart (SImode, operands[1]);
537 operands[1] = gen_lowpart (SImode, operands[1]);
538 operands[2] = gen_lowpart (SImode, operands[2]);
539 }"
540 [(set_attr "conds" "clob")
541 (set_attr "length" "8")
542 (set_attr "type" "multiple")]
543 )
544
545 (define_expand "addv<mode>4"
546 [(match_operand:SIDI 0 "register_operand")
547 (match_operand:SIDI 1 "register_operand")
548 (match_operand:SIDI 2 "register_operand")
549 (match_operand 3 "")]
550 "TARGET_32BIT"
551 {
552 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
553 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
554
555 DONE;
556 })
557
558 (define_expand "uaddv<mode>4"
559 [(match_operand:SIDI 0 "register_operand")
560 (match_operand:SIDI 1 "register_operand")
561 (match_operand:SIDI 2 "register_operand")
562 (match_operand 3 "")]
563 "TARGET_32BIT"
564 {
565 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
566 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
567
568 DONE;
569 })
570
571 (define_expand "addsi3"
572 [(set (match_operand:SI 0 "s_register_operand" "")
573 (plus:SI (match_operand:SI 1 "s_register_operand" "")
574 (match_operand:SI 2 "reg_or_int_operand" "")))]
575 "TARGET_EITHER"
576 "
577 if (TARGET_32BIT && CONST_INT_P (operands[2]))
578 {
579 arm_split_constant (PLUS, SImode, NULL_RTX,
580 INTVAL (operands[2]), operands[0], operands[1],
581 optimize && can_create_pseudo_p ());
582 DONE;
583 }
584 "
585 )
586
587 ; If there is a scratch available, this will be faster than synthesizing the
588 ; addition.
589 (define_peephole2
590 [(match_scratch:SI 3 "r")
591 (set (match_operand:SI 0 "arm_general_register_operand" "")
592 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
593 (match_operand:SI 2 "const_int_operand" "")))]
594 "TARGET_32BIT &&
595 !(const_ok_for_arm (INTVAL (operands[2]))
596 || const_ok_for_arm (-INTVAL (operands[2])))
597 && const_ok_for_arm (~INTVAL (operands[2]))"
598 [(set (match_dup 3) (match_dup 2))
599 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
600 ""
601 )
602
603 ;; The r/r/k alternative is required when reloading the address
604 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
605 ;; put the duplicated register first, and not try the commutative version.
606 (define_insn_and_split "*arm_addsi3"
607 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
608 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,r ,rk,k ,rk,k,r,rk,k ,rk")
609 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
610 "TARGET_32BIT"
611 "@
612 add%?\\t%0, %0, %2
613 add%?\\t%0, %1, %2
614 add%?\\t%0, %1, %2
615 add%?\\t%0, %1, %2
616 add%?\\t%0, %1, %2
617 add%?\\t%0, %1, %2
618 add%?\\t%0, %2, %1
619 add%?\\t%0, %1, %2
620 addw%?\\t%0, %1, %2
621 addw%?\\t%0, %1, %2
622 sub%?\\t%0, %1, #%n2
623 sub%?\\t%0, %1, #%n2
624 sub%?\\t%0, %1, #%n2
625 subw%?\\t%0, %1, #%n2
626 subw%?\\t%0, %1, #%n2
627 #"
628 "TARGET_32BIT
629 && CONST_INT_P (operands[2])
630 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
631 && (reload_completed || !arm_eliminable_register (operands[1]))"
632 [(clobber (const_int 0))]
633 "
634 arm_split_constant (PLUS, SImode, curr_insn,
635 INTVAL (operands[2]), operands[0],
636 operands[1], 0);
637 DONE;
638 "
639 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
640 (set_attr "predicable" "yes")
641 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
642 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
643 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
644 (const_string "alu_imm")
645 (const_string "alu_sreg")))
646 ]
647 )
648
649 (define_insn_and_split "adddi3_compareV"
650 [(set (reg:CC_V CC_REGNUM)
651 (ne:CC_V
652 (plus:TI
653 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
654 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
655 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
656 (set (match_operand:DI 0 "register_operand" "=&r")
657 (plus:DI (match_dup 1) (match_dup 2)))]
658 "TARGET_32BIT"
659 "#"
660 "&& reload_completed"
661 [(parallel [(set (reg:CC_C CC_REGNUM)
662 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
663 (match_dup 1)))
664 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
665 (parallel [(set (reg:CC_V CC_REGNUM)
666 (ne:CC_V
667 (plus:DI (plus:DI
668 (sign_extend:DI (match_dup 4))
669 (sign_extend:DI (match_dup 5)))
670 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
671 (plus:DI (sign_extend:DI
672 (plus:SI (match_dup 4) (match_dup 5)))
673 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
674 (set (match_dup 3) (plus:SI (plus:SI
675 (match_dup 4) (match_dup 5))
676 (ltu:SI (reg:CC_C CC_REGNUM)
677 (const_int 0))))])]
678 "
679 {
680 operands[3] = gen_highpart (SImode, operands[0]);
681 operands[0] = gen_lowpart (SImode, operands[0]);
682 operands[4] = gen_highpart (SImode, operands[1]);
683 operands[1] = gen_lowpart (SImode, operands[1]);
684 operands[5] = gen_highpart (SImode, operands[2]);
685 operands[2] = gen_lowpart (SImode, operands[2]);
686 }"
687 [(set_attr "conds" "set")
688 (set_attr "length" "8")
689 (set_attr "type" "multiple")]
690 )
691
692 (define_insn "addsi3_compareV"
693 [(set (reg:CC_V CC_REGNUM)
694 (ne:CC_V
695 (plus:DI
696 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
697 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
698 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
699 (set (match_operand:SI 0 "register_operand" "=r")
700 (plus:SI (match_dup 1) (match_dup 2)))]
701 "TARGET_32BIT"
702 "adds%?\\t%0, %1, %2"
703 [(set_attr "conds" "set")
704 (set_attr "type" "alus_sreg")]
705 )
706
707 (define_insn "*addsi3_compareV_upper"
708 [(set (reg:CC_V CC_REGNUM)
709 (ne:CC_V
710 (plus:DI
711 (plus:DI
712 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
713 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
714 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
715 (plus:DI (sign_extend:DI
716 (plus:SI (match_dup 1) (match_dup 2)))
717 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
718 (set (match_operand:SI 0 "register_operand" "=r")
719 (plus:SI
720 (plus:SI (match_dup 1) (match_dup 2))
721 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
722 "TARGET_32BIT"
723 "adcs%?\\t%0, %1, %2"
724 [(set_attr "conds" "set")
725 (set_attr "type" "adcs_reg")]
726 )
727
728 (define_insn_and_split "adddi3_compareC"
729 [(set (reg:CC_C CC_REGNUM)
730 (ne:CC_C
731 (plus:TI
732 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
733 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
734 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
735 (set (match_operand:DI 0 "register_operand" "=&r")
736 (plus:DI (match_dup 1) (match_dup 2)))]
737 "TARGET_32BIT"
738 "#"
739 "&& reload_completed"
740 [(parallel [(set (reg:CC_C CC_REGNUM)
741 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
742 (match_dup 1)))
743 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
744 (parallel [(set (reg:CC_C CC_REGNUM)
745 (ne:CC_C
746 (plus:DI (plus:DI
747 (zero_extend:DI (match_dup 4))
748 (zero_extend:DI (match_dup 5)))
749 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
750 (plus:DI (zero_extend:DI
751 (plus:SI (match_dup 4) (match_dup 5)))
752 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
753 (set (match_dup 3) (plus:SI
754 (plus:SI (match_dup 4) (match_dup 5))
755 (ltu:SI (reg:CC_C CC_REGNUM)
756 (const_int 0))))])]
757 "
758 {
759 operands[3] = gen_highpart (SImode, operands[0]);
760 operands[0] = gen_lowpart (SImode, operands[0]);
761 operands[4] = gen_highpart (SImode, operands[1]);
762 operands[5] = gen_highpart (SImode, operands[2]);
763 operands[1] = gen_lowpart (SImode, operands[1]);
764 operands[2] = gen_lowpart (SImode, operands[2]);
765 }"
766 [(set_attr "conds" "set")
767 (set_attr "length" "8")
768 (set_attr "type" "multiple")]
769 )
770
771 (define_insn "*addsi3_compareC_upper"
772 [(set (reg:CC_C CC_REGNUM)
773 (ne:CC_C
774 (plus:DI
775 (plus:DI
776 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
777 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
778 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
779 (plus:DI (zero_extend:DI
780 (plus:SI (match_dup 1) (match_dup 2)))
781 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
782 (set (match_operand:SI 0 "register_operand" "=r")
783 (plus:SI
784 (plus:SI (match_dup 1) (match_dup 2))
785 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
786 "TARGET_32BIT"
787 "adcs%?\\t%0, %1, %2"
788 [(set_attr "conds" "set")
789 (set_attr "type" "adcs_reg")]
790 )
791
792 (define_insn "addsi3_compareC"
793 [(set (reg:CC_C CC_REGNUM)
794 (ne:CC_C
795 (plus:DI
796 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
797 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
798 (zero_extend:DI
799 (plus:SI (match_dup 1) (match_dup 2)))))
800 (set (match_operand:SI 0 "register_operand" "=r")
801 (plus:SI (match_dup 1) (match_dup 2)))]
802 "TARGET_32BIT"
803 "adds%?\\t%0, %1, %2"
804 [(set_attr "conds" "set")
805 (set_attr "type" "alus_sreg")]
806 )
807
808 (define_insn "addsi3_compare0"
809 [(set (reg:CC_NOOV CC_REGNUM)
810 (compare:CC_NOOV
811 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
812 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
813 (const_int 0)))
814 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
815 (plus:SI (match_dup 1) (match_dup 2)))]
816 "TARGET_ARM"
817 "@
818 adds%?\\t%0, %1, %2
819 subs%?\\t%0, %1, #%n2
820 adds%?\\t%0, %1, %2"
821 [(set_attr "conds" "set")
822 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
823 )
824
825 (define_insn "*addsi3_compare0_scratch"
826 [(set (reg:CC_NOOV CC_REGNUM)
827 (compare:CC_NOOV
828 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
829 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
830 (const_int 0)))]
831 "TARGET_ARM"
832 "@
833 cmn%?\\t%0, %1
834 cmp%?\\t%0, #%n1
835 cmn%?\\t%0, %1"
836 [(set_attr "conds" "set")
837 (set_attr "predicable" "yes")
838 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
839 )
840
841 (define_insn "*compare_negsi_si"
842 [(set (reg:CC_Z CC_REGNUM)
843 (compare:CC_Z
844 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
845 (match_operand:SI 1 "s_register_operand" "l,r")))]
846 "TARGET_32BIT"
847 "cmn%?\\t%1, %0"
848 [(set_attr "conds" "set")
849 (set_attr "predicable" "yes")
850 (set_attr "arch" "t2,*")
851 (set_attr "length" "2,4")
852 (set_attr "predicable_short_it" "yes,no")
853 (set_attr "type" "alus_sreg")]
854 )
855
856 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
857 ;; addend is a constant.
858 (define_insn "cmpsi2_addneg"
859 [(set (reg:CC CC_REGNUM)
860 (compare:CC
861 (match_operand:SI 1 "s_register_operand" "r,r")
862 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
863 (set (match_operand:SI 0 "s_register_operand" "=r,r")
864 (plus:SI (match_dup 1)
865 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
866 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
867 "@
868 adds%?\\t%0, %1, %3
869 subs%?\\t%0, %1, #%n3"
870 [(set_attr "conds" "set")
871 (set_attr "type" "alus_sreg")]
872 )
873
874 ;; Convert the sequence
875 ;; sub rd, rn, #1
876 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
877 ;; bne dest
878 ;; into
879 ;; subs rd, rn, #1
880 ;; bcs dest ((unsigned)rn >= 1)
881 ;; similarly for the beq variant using bcc.
882 ;; This is a common looping idiom (while (n--))
883 (define_peephole2
884 [(set (match_operand:SI 0 "arm_general_register_operand" "")
885 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
886 (const_int -1)))
887 (set (match_operand 2 "cc_register" "")
888 (compare (match_dup 0) (const_int -1)))
889 (set (pc)
890 (if_then_else (match_operator 3 "equality_operator"
891 [(match_dup 2) (const_int 0)])
892 (match_operand 4 "" "")
893 (match_operand 5 "" "")))]
894 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
895 [(parallel[
896 (set (match_dup 2)
897 (compare:CC
898 (match_dup 1) (const_int 1)))
899 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
900 (set (pc)
901 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
902 (match_dup 4)
903 (match_dup 5)))]
904 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
905 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
906 ? GEU : LTU),
907 VOIDmode,
908 operands[2], const0_rtx);"
909 )
910
911 ;; The next four insns work because they compare the result with one of
912 ;; the operands, and we know that the use of the condition code is
913 ;; either GEU or LTU, so we can use the carry flag from the addition
914 ;; instead of doing the compare a second time.
915 (define_insn "*addsi3_compare_op1"
916 [(set (reg:CC_C CC_REGNUM)
917 (compare:CC_C
918 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
919 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
920 (match_dup 1)))
921 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
922 (plus:SI (match_dup 1) (match_dup 2)))]
923 "TARGET_32BIT"
924 "@
925 adds%?\\t%0, %1, %2
926 subs%?\\t%0, %1, #%n2
927 adds%?\\t%0, %1, %2"
928 [(set_attr "conds" "set")
929 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
930 )
931
932 (define_insn "*addsi3_compare_op2"
933 [(set (reg:CC_C CC_REGNUM)
934 (compare:CC_C
935 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
936 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
937 (match_dup 2)))
938 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
939 (plus:SI (match_dup 1) (match_dup 2)))]
940 "TARGET_32BIT"
941 "@
942 adds%?\\t%0, %1, %2
943 subs%?\\t%0, %1, #%n2
944 adds%?\\t%0, %1, %2"
945 [(set_attr "conds" "set")
946 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
947 )
948
949 (define_insn "*compare_addsi2_op0"
950 [(set (reg:CC_C CC_REGNUM)
951 (compare:CC_C
952 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
953 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
954 (match_dup 0)))]
955 "TARGET_32BIT"
956 "@
957 cmp%?\\t%0, #%n1
958 cmn%?\\t%0, %1
959 cmn%?\\t%0, %1
960 cmp%?\\t%0, #%n1
961 cmn%?\\t%0, %1"
962 [(set_attr "conds" "set")
963 (set_attr "predicable" "yes")
964 (set_attr "arch" "t2,t2,*,*,*")
965 (set_attr "predicable_short_it" "yes,yes,no,no,no")
966 (set_attr "length" "2,2,4,4,4")
967 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
968 )
969
970 (define_insn "*compare_addsi2_op1"
971 [(set (reg:CC_C CC_REGNUM)
972 (compare:CC_C
973 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
974 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
975 (match_dup 1)))]
976 "TARGET_32BIT"
977 "@
978 cmp%?\\t%0, #%n1
979 cmn%?\\t%0, %1
980 cmn%?\\t%0, %1
981 cmp%?\\t%0, #%n1
982 cmn%?\\t%0, %1"
983 [(set_attr "conds" "set")
984 (set_attr "predicable" "yes")
985 (set_attr "arch" "t2,t2,*,*,*")
986 (set_attr "predicable_short_it" "yes,yes,no,no,no")
987 (set_attr "length" "2,2,4,4,4")
988 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
989 )
990
991 (define_insn "*addsi3_carryin_<optab>"
992 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
993 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
994 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
995 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
996 "TARGET_32BIT"
997 "@
998 adc%?\\t%0, %1, %2
999 adc%?\\t%0, %1, %2
1000 sbc%?\\t%0, %1, #%B2"
1001 [(set_attr "conds" "use")
1002 (set_attr "predicable" "yes")
1003 (set_attr "arch" "t2,*,*")
1004 (set_attr "length" "4")
1005 (set_attr "predicable_short_it" "yes,no,no")
1006 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1007 )
1008
1009 (define_insn "*addsi3_carryin_alt2_<optab>"
1010 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1011 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1012 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1013 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1014 "TARGET_32BIT"
1015 "@
1016 adc%?\\t%0, %1, %2
1017 adc%?\\t%0, %1, %2
1018 sbc%?\\t%0, %1, #%B2"
1019 [(set_attr "conds" "use")
1020 (set_attr "predicable" "yes")
1021 (set_attr "arch" "t2,*,*")
1022 (set_attr "length" "4")
1023 (set_attr "predicable_short_it" "yes,no,no")
1024 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1025 )
1026
1027 (define_insn "*addsi3_carryin_shift_<optab>"
1028 [(set (match_operand:SI 0 "s_register_operand" "=r")
1029 (plus:SI (plus:SI
1030 (match_operator:SI 2 "shift_operator"
1031 [(match_operand:SI 3 "s_register_operand" "r")
1032 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1033 (match_operand:SI 1 "s_register_operand" "r"))
1034 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1035 "TARGET_32BIT"
1036 "adc%?\\t%0, %1, %3%S2"
1037 [(set_attr "conds" "use")
1038 (set_attr "predicable" "yes")
1039 (set_attr "predicable_short_it" "no")
1040 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1041 (const_string "alu_shift_imm")
1042 (const_string "alu_shift_reg")))]
1043 )
1044
1045 (define_insn "*addsi3_carryin_clobercc_<optab>"
1046 [(set (match_operand:SI 0 "s_register_operand" "=r")
1047 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1048 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1049 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1050 (clobber (reg:CC CC_REGNUM))]
1051 "TARGET_32BIT"
1052 "adcs%?\\t%0, %1, %2"
1053 [(set_attr "conds" "set")
1054 (set_attr "type" "adcs_reg")]
1055 )
1056
1057 (define_expand "subv<mode>4"
1058 [(match_operand:SIDI 0 "register_operand")
1059 (match_operand:SIDI 1 "register_operand")
1060 (match_operand:SIDI 2 "register_operand")
1061 (match_operand 3 "")]
1062 "TARGET_32BIT"
1063 {
1064 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1065 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1066
1067 DONE;
1068 })
1069
1070 (define_expand "usubv<mode>4"
1071 [(match_operand:SIDI 0 "register_operand")
1072 (match_operand:SIDI 1 "register_operand")
1073 (match_operand:SIDI 2 "register_operand")
1074 (match_operand 3 "")]
1075 "TARGET_32BIT"
1076 {
1077 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1078 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1079
1080 DONE;
1081 })
1082
1083 (define_insn_and_split "subdi3_compare1"
1084 [(set (reg:CC CC_REGNUM)
1085 (compare:CC
1086 (match_operand:DI 1 "register_operand" "r")
1087 (match_operand:DI 2 "register_operand" "r")))
1088 (set (match_operand:DI 0 "register_operand" "=&r")
1089 (minus:DI (match_dup 1) (match_dup 2)))]
1090 "TARGET_32BIT"
1091 "#"
1092 "&& reload_completed"
1093 [(parallel [(set (reg:CC CC_REGNUM)
1094 (compare:CC (match_dup 1) (match_dup 2)))
1095 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1096 (parallel [(set (reg:CC CC_REGNUM)
1097 (compare:CC (match_dup 4) (match_dup 5)))
1098 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1099 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1100 {
1101 operands[3] = gen_highpart (SImode, operands[0]);
1102 operands[0] = gen_lowpart (SImode, operands[0]);
1103 operands[4] = gen_highpart (SImode, operands[1]);
1104 operands[1] = gen_lowpart (SImode, operands[1]);
1105 operands[5] = gen_highpart (SImode, operands[2]);
1106 operands[2] = gen_lowpart (SImode, operands[2]);
1107 }
1108 [(set_attr "conds" "set")
1109 (set_attr "length" "8")
1110 (set_attr "type" "multiple")]
1111 )
1112
1113 (define_insn "subsi3_compare1"
1114 [(set (reg:CC CC_REGNUM)
1115 (compare:CC
1116 (match_operand:SI 1 "register_operand" "r")
1117 (match_operand:SI 2 "register_operand" "r")))
1118 (set (match_operand:SI 0 "register_operand" "=r")
1119 (minus:SI (match_dup 1) (match_dup 2)))]
1120 "TARGET_32BIT"
1121 "subs%?\\t%0, %1, %2"
1122 [(set_attr "conds" "set")
1123 (set_attr "type" "alus_sreg")]
1124 )
1125
1126 (define_insn "*subsi3_carryin"
1127 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1128 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1129 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1130 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1131 "TARGET_32BIT"
1132 "@
1133 sbc%?\\t%0, %1, %2
1134 rsc%?\\t%0, %2, %1
1135 sbc%?\\t%0, %2, %2, lsl #1"
1136 [(set_attr "conds" "use")
1137 (set_attr "arch" "*,a,t2")
1138 (set_attr "predicable" "yes")
1139 (set_attr "predicable_short_it" "no")
1140 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1141 )
1142
1143 (define_insn "*subsi3_carryin_const"
1144 [(set (match_operand:SI 0 "s_register_operand" "=r")
1145 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1146 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1147 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1148 "TARGET_32BIT"
1149 "sbc\\t%0, %1, #%B2"
1150 [(set_attr "conds" "use")
1151 (set_attr "type" "adc_imm")]
1152 )
1153
1154 (define_insn "*subsi3_carryin_compare"
1155 [(set (reg:CC CC_REGNUM)
1156 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1157 (match_operand:SI 2 "s_register_operand" "r")))
1158 (set (match_operand:SI 0 "s_register_operand" "=r")
1159 (minus:SI (minus:SI (match_dup 1)
1160 (match_dup 2))
1161 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1162 "TARGET_32BIT"
1163 "sbcs\\t%0, %1, %2"
1164 [(set_attr "conds" "set")
1165 (set_attr "type" "adcs_reg")]
1166 )
1167
1168 (define_insn "*subsi3_carryin_compare_const"
1169 [(set (reg:CC CC_REGNUM)
1170 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1171 (match_operand:SI 2 "arm_not_operand" "K")))
1172 (set (match_operand:SI 0 "s_register_operand" "=r")
1173 (minus:SI (plus:SI (match_dup 1)
1174 (match_dup 2))
1175 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1176 "TARGET_32BIT"
1177 "sbcs\\t%0, %1, #%B2"
1178 [(set_attr "conds" "set")
1179 (set_attr "type" "adcs_imm")]
1180 )
1181
1182 (define_insn "*subsi3_carryin_shift"
1183 [(set (match_operand:SI 0 "s_register_operand" "=r")
1184 (minus:SI (minus:SI
1185 (match_operand:SI 1 "s_register_operand" "r")
1186 (match_operator:SI 2 "shift_operator"
1187 [(match_operand:SI 3 "s_register_operand" "r")
1188 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1189 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1190 "TARGET_32BIT"
1191 "sbc%?\\t%0, %1, %3%S2"
1192 [(set_attr "conds" "use")
1193 (set_attr "predicable" "yes")
1194 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1195 (const_string "alu_shift_imm")
1196 (const_string "alu_shift_reg")))]
1197 )
1198
1199 (define_insn "*rsbsi3_carryin_shift"
1200 [(set (match_operand:SI 0 "s_register_operand" "=r")
1201 (minus:SI (minus:SI
1202 (match_operator:SI 2 "shift_operator"
1203 [(match_operand:SI 3 "s_register_operand" "r")
1204 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1205 (match_operand:SI 1 "s_register_operand" "r"))
1206 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1207 "TARGET_ARM"
1208 "rsc%?\\t%0, %1, %3%S2"
1209 [(set_attr "conds" "use")
1210 (set_attr "predicable" "yes")
1211 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1212 (const_string "alu_shift_imm")
1213 (const_string "alu_shift_reg")))]
1214 )
1215
1216 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1217 (define_split
1218 [(set (match_operand:SI 0 "s_register_operand" "")
1219 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1220 (match_operand:SI 2 "s_register_operand" ""))
1221 (const_int -1)))
1222 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1223 "TARGET_32BIT"
1224 [(set (match_dup 3) (match_dup 1))
1225 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1226 "
1227 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1228 ")
1229
1230 (define_expand "addsf3"
1231 [(set (match_operand:SF 0 "s_register_operand" "")
1232 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1233 (match_operand:SF 2 "s_register_operand" "")))]
1234 "TARGET_32BIT && TARGET_HARD_FLOAT"
1235 "
1236 ")
1237
1238 (define_expand "adddf3"
1239 [(set (match_operand:DF 0 "s_register_operand" "")
1240 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1241 (match_operand:DF 2 "s_register_operand" "")))]
1242 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1243 "
1244 ")
1245
1246 (define_expand "subdi3"
1247 [(parallel
1248 [(set (match_operand:DI 0 "s_register_operand" "")
1249 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1250 (match_operand:DI 2 "s_register_operand" "")))
1251 (clobber (reg:CC CC_REGNUM))])]
1252 "TARGET_EITHER"
1253 "
1254 if (TARGET_THUMB1)
1255 {
1256 if (!REG_P (operands[1]))
1257 operands[1] = force_reg (DImode, operands[1]);
1258 if (!REG_P (operands[2]))
1259 operands[2] = force_reg (DImode, operands[2]);
1260 }
1261 "
1262 )
1263
1264 (define_insn_and_split "*arm_subdi3"
1265 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
1266 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1267 (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1268 (clobber (reg:CC CC_REGNUM))]
1269 "TARGET_32BIT && !TARGET_NEON"
1270 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1271 "&& (!TARGET_IWMMXT || reload_completed)"
1272 [(parallel [(set (reg:CC CC_REGNUM)
1273 (compare:CC (match_dup 1) (match_dup 2)))
1274 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1275 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1276 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1277 {
1278 operands[3] = gen_highpart (SImode, operands[0]);
1279 operands[0] = gen_lowpart (SImode, operands[0]);
1280 operands[4] = gen_highpart (SImode, operands[1]);
1281 operands[1] = gen_lowpart (SImode, operands[1]);
1282 operands[5] = gen_highpart (SImode, operands[2]);
1283 operands[2] = gen_lowpart (SImode, operands[2]);
1284 }
1285 [(set_attr "conds" "clob")
1286 (set_attr "length" "8")
1287 (set_attr "type" "multiple")]
1288 )
1289
1290 (define_insn_and_split "*subdi_di_zesidi"
1291 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1292 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1293 (zero_extend:DI
1294 (match_operand:SI 2 "s_register_operand" "r,r"))))
1295 (clobber (reg:CC CC_REGNUM))]
1296 "TARGET_32BIT"
1297 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1298 "&& reload_completed"
1299 [(parallel [(set (reg:CC CC_REGNUM)
1300 (compare:CC (match_dup 1) (match_dup 2)))
1301 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1302 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1303 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1304 {
1305 operands[3] = gen_highpart (SImode, operands[0]);
1306 operands[0] = gen_lowpart (SImode, operands[0]);
1307 operands[4] = gen_highpart (SImode, operands[1]);
1308 operands[1] = gen_lowpart (SImode, operands[1]);
1309 operands[5] = GEN_INT (~0);
1310 }
1311 [(set_attr "conds" "clob")
1312 (set_attr "length" "8")
1313 (set_attr "type" "multiple")]
1314 )
1315
1316 (define_insn_and_split "*subdi_di_sesidi"
1317 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1318 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1319 (sign_extend:DI
1320 (match_operand:SI 2 "s_register_operand" "r,r"))))
1321 (clobber (reg:CC CC_REGNUM))]
1322 "TARGET_32BIT"
1323 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1324 "&& reload_completed"
1325 [(parallel [(set (reg:CC CC_REGNUM)
1326 (compare:CC (match_dup 1) (match_dup 2)))
1327 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1328 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1329 (ashiftrt:SI (match_dup 2)
1330 (const_int 31)))
1331 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1332 {
1333 operands[3] = gen_highpart (SImode, operands[0]);
1334 operands[0] = gen_lowpart (SImode, operands[0]);
1335 operands[4] = gen_highpart (SImode, operands[1]);
1336 operands[1] = gen_lowpart (SImode, operands[1]);
1337 }
1338 [(set_attr "conds" "clob")
1339 (set_attr "length" "8")
1340 (set_attr "type" "multiple")]
1341 )
1342
1343 (define_insn_and_split "*subdi_zesidi_di"
1344 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1345 (minus:DI (zero_extend:DI
1346 (match_operand:SI 2 "s_register_operand" "r,r"))
1347 (match_operand:DI 1 "s_register_operand" "0,r")))
1348 (clobber (reg:CC CC_REGNUM))]
1349 "TARGET_ARM"
1350 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1351 ; is equivalent to:
1352 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1353 "&& reload_completed"
1354 [(parallel [(set (reg:CC CC_REGNUM)
1355 (compare:CC (match_dup 2) (match_dup 1)))
1356 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1357 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1358 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1359 {
1360 operands[3] = gen_highpart (SImode, operands[0]);
1361 operands[0] = gen_lowpart (SImode, operands[0]);
1362 operands[4] = gen_highpart (SImode, operands[1]);
1363 operands[1] = gen_lowpart (SImode, operands[1]);
1364 }
1365 [(set_attr "conds" "clob")
1366 (set_attr "length" "8")
1367 (set_attr "type" "multiple")]
1368 )
1369
1370 (define_insn_and_split "*subdi_sesidi_di"
1371 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1372 (minus:DI (sign_extend:DI
1373 (match_operand:SI 2 "s_register_operand" "r,r"))
1374 (match_operand:DI 1 "s_register_operand" "0,r")))
1375 (clobber (reg:CC CC_REGNUM))]
1376 "TARGET_ARM"
1377 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1378 ; is equivalent to:
1379 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1380 "&& reload_completed"
1381 [(parallel [(set (reg:CC CC_REGNUM)
1382 (compare:CC (match_dup 2) (match_dup 1)))
1383 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1384 (set (match_dup 3) (minus:SI (minus:SI
1385 (ashiftrt:SI (match_dup 2)
1386 (const_int 31))
1387 (match_dup 4))
1388 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1389 {
1390 operands[3] = gen_highpart (SImode, operands[0]);
1391 operands[0] = gen_lowpart (SImode, operands[0]);
1392 operands[4] = gen_highpart (SImode, operands[1]);
1393 operands[1] = gen_lowpart (SImode, operands[1]);
1394 }
1395 [(set_attr "conds" "clob")
1396 (set_attr "length" "8")
1397 (set_attr "type" "multiple")]
1398 )
1399
1400 (define_insn_and_split "*subdi_zesidi_zesidi"
1401 [(set (match_operand:DI 0 "s_register_operand" "=r")
1402 (minus:DI (zero_extend:DI
1403 (match_operand:SI 1 "s_register_operand" "r"))
1404 (zero_extend:DI
1405 (match_operand:SI 2 "s_register_operand" "r"))))
1406 (clobber (reg:CC CC_REGNUM))]
1407 "TARGET_32BIT"
1408 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1409 "&& reload_completed"
1410 [(parallel [(set (reg:CC CC_REGNUM)
1411 (compare:CC (match_dup 1) (match_dup 2)))
1412 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1413 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1414 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1415 {
1416 operands[3] = gen_highpart (SImode, operands[0]);
1417 operands[0] = gen_lowpart (SImode, operands[0]);
1418 }
1419 [(set_attr "conds" "clob")
1420 (set_attr "length" "8")
1421 (set_attr "type" "multiple")]
1422 )
1423
1424 (define_expand "subsi3"
1425 [(set (match_operand:SI 0 "s_register_operand" "")
1426 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1427 (match_operand:SI 2 "s_register_operand" "")))]
1428 "TARGET_EITHER"
1429 "
1430 if (CONST_INT_P (operands[1]))
1431 {
1432 if (TARGET_32BIT)
1433 {
1434 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1435 operands[1] = force_reg (SImode, operands[1]);
1436 else
1437 {
1438 arm_split_constant (MINUS, SImode, NULL_RTX,
1439 INTVAL (operands[1]), operands[0],
1440 operands[2],
1441 optimize && can_create_pseudo_p ());
1442 DONE;
1443 }
1444 }
1445 else /* TARGET_THUMB1 */
1446 operands[1] = force_reg (SImode, operands[1]);
1447 }
1448 "
1449 )
1450
1451 ; ??? Check Thumb-2 split length
1452 (define_insn_and_split "*arm_subsi3_insn"
1453 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1454 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1455 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1456 "TARGET_32BIT"
1457 "@
1458 sub%?\\t%0, %1, %2
1459 sub%?\\t%0, %2
1460 sub%?\\t%0, %1, %2
1461 rsb%?\\t%0, %2, %1
1462 rsb%?\\t%0, %2, %1
1463 sub%?\\t%0, %1, %2
1464 sub%?\\t%0, %1, %2
1465 sub%?\\t%0, %1, %2
1466 #"
1467 "&& (CONST_INT_P (operands[1])
1468 && !const_ok_for_arm (INTVAL (operands[1])))"
1469 [(clobber (const_int 0))]
1470 "
1471 arm_split_constant (MINUS, SImode, curr_insn,
1472 INTVAL (operands[1]), operands[0], operands[2], 0);
1473 DONE;
1474 "
1475 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1476 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1477 (set_attr "predicable" "yes")
1478 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1479 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1480 )
1481
1482 (define_peephole2
1483 [(match_scratch:SI 3 "r")
1484 (set (match_operand:SI 0 "arm_general_register_operand" "")
1485 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1486 (match_operand:SI 2 "arm_general_register_operand" "")))]
1487 "TARGET_32BIT
1488 && !const_ok_for_arm (INTVAL (operands[1]))
1489 && const_ok_for_arm (~INTVAL (operands[1]))"
1490 [(set (match_dup 3) (match_dup 1))
1491 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1492 ""
1493 )
1494
1495 (define_insn "subsi3_compare0"
1496 [(set (reg:CC_NOOV CC_REGNUM)
1497 (compare:CC_NOOV
1498 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1499 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1500 (const_int 0)))
1501 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1502 (minus:SI (match_dup 1) (match_dup 2)))]
1503 "TARGET_32BIT"
1504 "@
1505 subs%?\\t%0, %1, %2
1506 subs%?\\t%0, %1, %2
1507 rsbs%?\\t%0, %2, %1"
1508 [(set_attr "conds" "set")
1509 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1510 )
1511
1512 (define_insn "subsi3_compare"
1513 [(set (reg:CC CC_REGNUM)
1514 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1515 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1516 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1517 (minus:SI (match_dup 1) (match_dup 2)))]
1518 "TARGET_32BIT"
1519 "@
1520 subs%?\\t%0, %1, %2
1521 subs%?\\t%0, %1, %2
1522 rsbs%?\\t%0, %2, %1"
1523 [(set_attr "conds" "set")
1524 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1525 )
1526
1527 (define_expand "subsf3"
1528 [(set (match_operand:SF 0 "s_register_operand" "")
1529 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1530 (match_operand:SF 2 "s_register_operand" "")))]
1531 "TARGET_32BIT && TARGET_HARD_FLOAT"
1532 "
1533 ")
1534
1535 (define_expand "subdf3"
1536 [(set (match_operand:DF 0 "s_register_operand" "")
1537 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1538 (match_operand:DF 2 "s_register_operand" "")))]
1539 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1540 "
1541 ")
1542
1543 \f
1544 ;; Multiplication insns
1545
1546 (define_expand "mulhi3"
1547 [(set (match_operand:HI 0 "s_register_operand" "")
1548 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1549 (match_operand:HI 2 "s_register_operand" "")))]
1550 "TARGET_DSP_MULTIPLY"
1551 "
1552 {
1553 rtx result = gen_reg_rtx (SImode);
1554 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1555 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1556 DONE;
1557 }"
1558 )
1559
1560 (define_expand "mulsi3"
1561 [(set (match_operand:SI 0 "s_register_operand" "")
1562 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1563 (match_operand:SI 1 "s_register_operand" "")))]
1564 "TARGET_EITHER"
1565 ""
1566 )
1567
1568 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1569 (define_insn "*arm_mulsi3"
1570 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1571 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1572 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1573 "TARGET_32BIT && !arm_arch6"
1574 "mul%?\\t%0, %2, %1"
1575 [(set_attr "type" "mul")
1576 (set_attr "predicable" "yes")]
1577 )
1578
1579 (define_insn "*arm_mulsi3_v6"
1580 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1581 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1582 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1583 "TARGET_32BIT && arm_arch6"
1584 "mul%?\\t%0, %1, %2"
1585 [(set_attr "type" "mul")
1586 (set_attr "predicable" "yes")
1587 (set_attr "arch" "t2,t2,*")
1588 (set_attr "length" "4")
1589 (set_attr "predicable_short_it" "yes,yes,no")]
1590 )
1591
1592 (define_insn "*mulsi3_compare0"
1593 [(set (reg:CC_NOOV CC_REGNUM)
1594 (compare:CC_NOOV (mult:SI
1595 (match_operand:SI 2 "s_register_operand" "r,r")
1596 (match_operand:SI 1 "s_register_operand" "%0,r"))
1597 (const_int 0)))
1598 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1599 (mult:SI (match_dup 2) (match_dup 1)))]
1600 "TARGET_ARM && !arm_arch6"
1601 "muls%?\\t%0, %2, %1"
1602 [(set_attr "conds" "set")
1603 (set_attr "type" "muls")]
1604 )
1605
1606 (define_insn "*mulsi3_compare0_v6"
1607 [(set (reg:CC_NOOV CC_REGNUM)
1608 (compare:CC_NOOV (mult:SI
1609 (match_operand:SI 2 "s_register_operand" "r")
1610 (match_operand:SI 1 "s_register_operand" "r"))
1611 (const_int 0)))
1612 (set (match_operand:SI 0 "s_register_operand" "=r")
1613 (mult:SI (match_dup 2) (match_dup 1)))]
1614 "TARGET_ARM && arm_arch6 && optimize_size"
1615 "muls%?\\t%0, %2, %1"
1616 [(set_attr "conds" "set")
1617 (set_attr "type" "muls")]
1618 )
1619
1620 (define_insn "*mulsi_compare0_scratch"
1621 [(set (reg:CC_NOOV CC_REGNUM)
1622 (compare:CC_NOOV (mult:SI
1623 (match_operand:SI 2 "s_register_operand" "r,r")
1624 (match_operand:SI 1 "s_register_operand" "%0,r"))
1625 (const_int 0)))
1626 (clobber (match_scratch:SI 0 "=&r,&r"))]
1627 "TARGET_ARM && !arm_arch6"
1628 "muls%?\\t%0, %2, %1"
1629 [(set_attr "conds" "set")
1630 (set_attr "type" "muls")]
1631 )
1632
1633 (define_insn "*mulsi_compare0_scratch_v6"
1634 [(set (reg:CC_NOOV CC_REGNUM)
1635 (compare:CC_NOOV (mult:SI
1636 (match_operand:SI 2 "s_register_operand" "r")
1637 (match_operand:SI 1 "s_register_operand" "r"))
1638 (const_int 0)))
1639 (clobber (match_scratch:SI 0 "=r"))]
1640 "TARGET_ARM && arm_arch6 && optimize_size"
1641 "muls%?\\t%0, %2, %1"
1642 [(set_attr "conds" "set")
1643 (set_attr "type" "muls")]
1644 )
1645
1646 ;; Unnamed templates to match MLA instruction.
1647
1648 (define_insn "*mulsi3addsi"
1649 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1650 (plus:SI
1651 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1652 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1653 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1654 "TARGET_32BIT && !arm_arch6"
1655 "mla%?\\t%0, %2, %1, %3"
1656 [(set_attr "type" "mla")
1657 (set_attr "predicable" "yes")]
1658 )
1659
1660 (define_insn "*mulsi3addsi_v6"
1661 [(set (match_operand:SI 0 "s_register_operand" "=r")
1662 (plus:SI
1663 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1664 (match_operand:SI 1 "s_register_operand" "r"))
1665 (match_operand:SI 3 "s_register_operand" "r")))]
1666 "TARGET_32BIT && arm_arch6"
1667 "mla%?\\t%0, %2, %1, %3"
1668 [(set_attr "type" "mla")
1669 (set_attr "predicable" "yes")
1670 (set_attr "predicable_short_it" "no")]
1671 )
1672
1673 (define_insn "*mulsi3addsi_compare0"
1674 [(set (reg:CC_NOOV CC_REGNUM)
1675 (compare:CC_NOOV
1676 (plus:SI (mult:SI
1677 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1678 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1679 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1680 (const_int 0)))
1681 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1682 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1683 (match_dup 3)))]
1684 "TARGET_ARM && arm_arch6"
1685 "mlas%?\\t%0, %2, %1, %3"
1686 [(set_attr "conds" "set")
1687 (set_attr "type" "mlas")]
1688 )
1689
1690 (define_insn "*mulsi3addsi_compare0_v6"
1691 [(set (reg:CC_NOOV CC_REGNUM)
1692 (compare:CC_NOOV
1693 (plus:SI (mult:SI
1694 (match_operand:SI 2 "s_register_operand" "r")
1695 (match_operand:SI 1 "s_register_operand" "r"))
1696 (match_operand:SI 3 "s_register_operand" "r"))
1697 (const_int 0)))
1698 (set (match_operand:SI 0 "s_register_operand" "=r")
1699 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1700 (match_dup 3)))]
1701 "TARGET_ARM && arm_arch6 && optimize_size"
1702 "mlas%?\\t%0, %2, %1, %3"
1703 [(set_attr "conds" "set")
1704 (set_attr "type" "mlas")]
1705 )
1706
1707 (define_insn "*mulsi3addsi_compare0_scratch"
1708 [(set (reg:CC_NOOV CC_REGNUM)
1709 (compare:CC_NOOV
1710 (plus:SI (mult:SI
1711 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1712 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1713 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1714 (const_int 0)))
1715 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1716 "TARGET_ARM && !arm_arch6"
1717 "mlas%?\\t%0, %2, %1, %3"
1718 [(set_attr "conds" "set")
1719 (set_attr "type" "mlas")]
1720 )
1721
1722 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1723 [(set (reg:CC_NOOV CC_REGNUM)
1724 (compare:CC_NOOV
1725 (plus:SI (mult:SI
1726 (match_operand:SI 2 "s_register_operand" "r")
1727 (match_operand:SI 1 "s_register_operand" "r"))
1728 (match_operand:SI 3 "s_register_operand" "r"))
1729 (const_int 0)))
1730 (clobber (match_scratch:SI 0 "=r"))]
1731 "TARGET_ARM && arm_arch6 && optimize_size"
1732 "mlas%?\\t%0, %2, %1, %3"
1733 [(set_attr "conds" "set")
1734 (set_attr "type" "mlas")]
1735 )
1736
1737 (define_insn "*mulsi3subsi"
1738 [(set (match_operand:SI 0 "s_register_operand" "=r")
1739 (minus:SI
1740 (match_operand:SI 3 "s_register_operand" "r")
1741 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1742 (match_operand:SI 1 "s_register_operand" "r"))))]
1743 "TARGET_32BIT && arm_arch_thumb2"
1744 "mls%?\\t%0, %2, %1, %3"
1745 [(set_attr "type" "mla")
1746 (set_attr "predicable" "yes")
1747 (set_attr "predicable_short_it" "no")]
1748 )
1749
1750 (define_expand "maddsidi4"
1751 [(set (match_operand:DI 0 "s_register_operand" "")
1752 (plus:DI
1753 (mult:DI
1754 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1755 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1756 (match_operand:DI 3 "s_register_operand" "")))]
1757 "TARGET_32BIT && arm_arch3m"
1758 "")
1759
1760 (define_insn "*mulsidi3adddi"
1761 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1762 (plus:DI
1763 (mult:DI
1764 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1765 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1766 (match_operand:DI 1 "s_register_operand" "0")))]
1767 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1768 "smlal%?\\t%Q0, %R0, %3, %2"
1769 [(set_attr "type" "smlal")
1770 (set_attr "predicable" "yes")]
1771 )
1772
1773 (define_insn "*mulsidi3adddi_v6"
1774 [(set (match_operand:DI 0 "s_register_operand" "=r")
1775 (plus:DI
1776 (mult:DI
1777 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1778 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1779 (match_operand:DI 1 "s_register_operand" "0")))]
1780 "TARGET_32BIT && arm_arch6"
1781 "smlal%?\\t%Q0, %R0, %3, %2"
1782 [(set_attr "type" "smlal")
1783 (set_attr "predicable" "yes")
1784 (set_attr "predicable_short_it" "no")]
1785 )
1786
1787 ;; 32x32->64 widening multiply.
1788 ;; As with mulsi3, the only difference between the v3-5 and v6+
1789 ;; versions of these patterns is the requirement that the output not
1790 ;; overlap the inputs, but that still means we have to have a named
1791 ;; expander and two different starred insns.
1792
1793 (define_expand "mulsidi3"
1794 [(set (match_operand:DI 0 "s_register_operand" "")
1795 (mult:DI
1796 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1797 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1798 "TARGET_32BIT && arm_arch3m"
1799 ""
1800 )
1801
1802 (define_insn "*mulsidi3_nov6"
1803 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1804 (mult:DI
1805 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1806 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1807 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1808 "smull%?\\t%Q0, %R0, %1, %2"
1809 [(set_attr "type" "smull")
1810 (set_attr "predicable" "yes")]
1811 )
1812
1813 (define_insn "*mulsidi3_v6"
1814 [(set (match_operand:DI 0 "s_register_operand" "=r")
1815 (mult:DI
1816 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1817 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1818 "TARGET_32BIT && arm_arch6"
1819 "smull%?\\t%Q0, %R0, %1, %2"
1820 [(set_attr "type" "smull")
1821 (set_attr "predicable" "yes")
1822 (set_attr "predicable_short_it" "no")]
1823 )
1824
1825 (define_expand "umulsidi3"
1826 [(set (match_operand:DI 0 "s_register_operand" "")
1827 (mult:DI
1828 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1829 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1830 "TARGET_32BIT && arm_arch3m"
1831 ""
1832 )
1833
1834 (define_insn "*umulsidi3_nov6"
1835 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1836 (mult:DI
1837 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1838 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1839 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1840 "umull%?\\t%Q0, %R0, %1, %2"
1841 [(set_attr "type" "umull")
1842 (set_attr "predicable" "yes")]
1843 )
1844
1845 (define_insn "*umulsidi3_v6"
1846 [(set (match_operand:DI 0 "s_register_operand" "=r")
1847 (mult:DI
1848 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1849 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1850 "TARGET_32BIT && arm_arch6"
1851 "umull%?\\t%Q0, %R0, %1, %2"
1852 [(set_attr "type" "umull")
1853 (set_attr "predicable" "yes")
1854 (set_attr "predicable_short_it" "no")]
1855 )
1856
1857 (define_expand "umaddsidi4"
1858 [(set (match_operand:DI 0 "s_register_operand" "")
1859 (plus:DI
1860 (mult:DI
1861 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1862 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1863 (match_operand:DI 3 "s_register_operand" "")))]
1864 "TARGET_32BIT && arm_arch3m"
1865 "")
1866
1867 (define_insn "*umulsidi3adddi"
1868 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1869 (plus:DI
1870 (mult:DI
1871 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1872 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1873 (match_operand:DI 1 "s_register_operand" "0")))]
1874 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1875 "umlal%?\\t%Q0, %R0, %3, %2"
1876 [(set_attr "type" "umlal")
1877 (set_attr "predicable" "yes")]
1878 )
1879
1880 (define_insn "*umulsidi3adddi_v6"
1881 [(set (match_operand:DI 0 "s_register_operand" "=r")
1882 (plus:DI
1883 (mult:DI
1884 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1885 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1886 (match_operand:DI 1 "s_register_operand" "0")))]
1887 "TARGET_32BIT && arm_arch6"
1888 "umlal%?\\t%Q0, %R0, %3, %2"
1889 [(set_attr "type" "umlal")
1890 (set_attr "predicable" "yes")
1891 (set_attr "predicable_short_it" "no")]
1892 )
1893
1894 (define_expand "smulsi3_highpart"
1895 [(parallel
1896 [(set (match_operand:SI 0 "s_register_operand" "")
1897 (truncate:SI
1898 (lshiftrt:DI
1899 (mult:DI
1900 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1901 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1902 (const_int 32))))
1903 (clobber (match_scratch:SI 3 ""))])]
1904 "TARGET_32BIT && arm_arch3m"
1905 ""
1906 )
1907
1908 (define_insn "*smulsi3_highpart_nov6"
1909 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1910 (truncate:SI
1911 (lshiftrt:DI
1912 (mult:DI
1913 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1914 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1915 (const_int 32))))
1916 (clobber (match_scratch:SI 3 "=&r,&r"))]
1917 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1918 "smull%?\\t%3, %0, %2, %1"
1919 [(set_attr "type" "smull")
1920 (set_attr "predicable" "yes")]
1921 )
1922
1923 (define_insn "*smulsi3_highpart_v6"
1924 [(set (match_operand:SI 0 "s_register_operand" "=r")
1925 (truncate:SI
1926 (lshiftrt:DI
1927 (mult:DI
1928 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1929 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1930 (const_int 32))))
1931 (clobber (match_scratch:SI 3 "=r"))]
1932 "TARGET_32BIT && arm_arch6"
1933 "smull%?\\t%3, %0, %2, %1"
1934 [(set_attr "type" "smull")
1935 (set_attr "predicable" "yes")
1936 (set_attr "predicable_short_it" "no")]
1937 )
1938
1939 (define_expand "umulsi3_highpart"
1940 [(parallel
1941 [(set (match_operand:SI 0 "s_register_operand" "")
1942 (truncate:SI
1943 (lshiftrt:DI
1944 (mult:DI
1945 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1946 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1947 (const_int 32))))
1948 (clobber (match_scratch:SI 3 ""))])]
1949 "TARGET_32BIT && arm_arch3m"
1950 ""
1951 )
1952
1953 (define_insn "*umulsi3_highpart_nov6"
1954 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1955 (truncate:SI
1956 (lshiftrt:DI
1957 (mult:DI
1958 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1959 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1960 (const_int 32))))
1961 (clobber (match_scratch:SI 3 "=&r,&r"))]
1962 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1963 "umull%?\\t%3, %0, %2, %1"
1964 [(set_attr "type" "umull")
1965 (set_attr "predicable" "yes")]
1966 )
1967
1968 (define_insn "*umulsi3_highpart_v6"
1969 [(set (match_operand:SI 0 "s_register_operand" "=r")
1970 (truncate:SI
1971 (lshiftrt:DI
1972 (mult:DI
1973 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1974 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1975 (const_int 32))))
1976 (clobber (match_scratch:SI 3 "=r"))]
1977 "TARGET_32BIT && arm_arch6"
1978 "umull%?\\t%3, %0, %2, %1"
1979 [(set_attr "type" "umull")
1980 (set_attr "predicable" "yes")
1981 (set_attr "predicable_short_it" "no")]
1982 )
1983
1984 (define_insn "mulhisi3"
1985 [(set (match_operand:SI 0 "s_register_operand" "=r")
1986 (mult:SI (sign_extend:SI
1987 (match_operand:HI 1 "s_register_operand" "%r"))
1988 (sign_extend:SI
1989 (match_operand:HI 2 "s_register_operand" "r"))))]
1990 "TARGET_DSP_MULTIPLY"
1991 "smulbb%?\\t%0, %1, %2"
1992 [(set_attr "type" "smulxy")
1993 (set_attr "predicable" "yes")]
1994 )
1995
1996 (define_insn "*mulhisi3tb"
1997 [(set (match_operand:SI 0 "s_register_operand" "=r")
1998 (mult:SI (ashiftrt:SI
1999 (match_operand:SI 1 "s_register_operand" "r")
2000 (const_int 16))
2001 (sign_extend:SI
2002 (match_operand:HI 2 "s_register_operand" "r"))))]
2003 "TARGET_DSP_MULTIPLY"
2004 "smultb%?\\t%0, %1, %2"
2005 [(set_attr "type" "smulxy")
2006 (set_attr "predicable" "yes")
2007 (set_attr "predicable_short_it" "no")]
2008 )
2009
2010 (define_insn "*mulhisi3bt"
2011 [(set (match_operand:SI 0 "s_register_operand" "=r")
2012 (mult:SI (sign_extend:SI
2013 (match_operand:HI 1 "s_register_operand" "r"))
2014 (ashiftrt:SI
2015 (match_operand:SI 2 "s_register_operand" "r")
2016 (const_int 16))))]
2017 "TARGET_DSP_MULTIPLY"
2018 "smulbt%?\\t%0, %1, %2"
2019 [(set_attr "type" "smulxy")
2020 (set_attr "predicable" "yes")
2021 (set_attr "predicable_short_it" "no")]
2022 )
2023
2024 (define_insn "*mulhisi3tt"
2025 [(set (match_operand:SI 0 "s_register_operand" "=r")
2026 (mult:SI (ashiftrt:SI
2027 (match_operand:SI 1 "s_register_operand" "r")
2028 (const_int 16))
2029 (ashiftrt:SI
2030 (match_operand:SI 2 "s_register_operand" "r")
2031 (const_int 16))))]
2032 "TARGET_DSP_MULTIPLY"
2033 "smultt%?\\t%0, %1, %2"
2034 [(set_attr "type" "smulxy")
2035 (set_attr "predicable" "yes")
2036 (set_attr "predicable_short_it" "no")]
2037 )
2038
2039 (define_insn "maddhisi4"
2040 [(set (match_operand:SI 0 "s_register_operand" "=r")
2041 (plus:SI (mult:SI (sign_extend:SI
2042 (match_operand:HI 1 "s_register_operand" "r"))
2043 (sign_extend:SI
2044 (match_operand:HI 2 "s_register_operand" "r")))
2045 (match_operand:SI 3 "s_register_operand" "r")))]
2046 "TARGET_DSP_MULTIPLY"
2047 "smlabb%?\\t%0, %1, %2, %3"
2048 [(set_attr "type" "smlaxy")
2049 (set_attr "predicable" "yes")
2050 (set_attr "predicable_short_it" "no")]
2051 )
2052
2053 ;; Note: there is no maddhisi4ibt because this one is canonical form
2054 (define_insn "*maddhisi4tb"
2055 [(set (match_operand:SI 0 "s_register_operand" "=r")
2056 (plus:SI (mult:SI (ashiftrt:SI
2057 (match_operand:SI 1 "s_register_operand" "r")
2058 (const_int 16))
2059 (sign_extend:SI
2060 (match_operand:HI 2 "s_register_operand" "r")))
2061 (match_operand:SI 3 "s_register_operand" "r")))]
2062 "TARGET_DSP_MULTIPLY"
2063 "smlatb%?\\t%0, %1, %2, %3"
2064 [(set_attr "type" "smlaxy")
2065 (set_attr "predicable" "yes")
2066 (set_attr "predicable_short_it" "no")]
2067 )
2068
2069 (define_insn "*maddhisi4tt"
2070 [(set (match_operand:SI 0 "s_register_operand" "=r")
2071 (plus:SI (mult:SI (ashiftrt:SI
2072 (match_operand:SI 1 "s_register_operand" "r")
2073 (const_int 16))
2074 (ashiftrt:SI
2075 (match_operand:SI 2 "s_register_operand" "r")
2076 (const_int 16)))
2077 (match_operand:SI 3 "s_register_operand" "r")))]
2078 "TARGET_DSP_MULTIPLY"
2079 "smlatt%?\\t%0, %1, %2, %3"
2080 [(set_attr "type" "smlaxy")
2081 (set_attr "predicable" "yes")
2082 (set_attr "predicable_short_it" "no")]
2083 )
2084
2085 (define_insn "maddhidi4"
2086 [(set (match_operand:DI 0 "s_register_operand" "=r")
2087 (plus:DI
2088 (mult:DI (sign_extend:DI
2089 (match_operand:HI 1 "s_register_operand" "r"))
2090 (sign_extend:DI
2091 (match_operand:HI 2 "s_register_operand" "r")))
2092 (match_operand:DI 3 "s_register_operand" "0")))]
2093 "TARGET_DSP_MULTIPLY"
2094 "smlalbb%?\\t%Q0, %R0, %1, %2"
2095 [(set_attr "type" "smlalxy")
2096 (set_attr "predicable" "yes")
2097 (set_attr "predicable_short_it" "no")])
2098
2099 ;; Note: there is no maddhidi4ibt because this one is canonical form
2100 (define_insn "*maddhidi4tb"
2101 [(set (match_operand:DI 0 "s_register_operand" "=r")
2102 (plus:DI
2103 (mult:DI (sign_extend:DI
2104 (ashiftrt:SI
2105 (match_operand:SI 1 "s_register_operand" "r")
2106 (const_int 16)))
2107 (sign_extend:DI
2108 (match_operand:HI 2 "s_register_operand" "r")))
2109 (match_operand:DI 3 "s_register_operand" "0")))]
2110 "TARGET_DSP_MULTIPLY"
2111 "smlaltb%?\\t%Q0, %R0, %1, %2"
2112 [(set_attr "type" "smlalxy")
2113 (set_attr "predicable" "yes")
2114 (set_attr "predicable_short_it" "no")])
2115
2116 (define_insn "*maddhidi4tt"
2117 [(set (match_operand:DI 0 "s_register_operand" "=r")
2118 (plus:DI
2119 (mult:DI (sign_extend:DI
2120 (ashiftrt:SI
2121 (match_operand:SI 1 "s_register_operand" "r")
2122 (const_int 16)))
2123 (sign_extend:DI
2124 (ashiftrt:SI
2125 (match_operand:SI 2 "s_register_operand" "r")
2126 (const_int 16))))
2127 (match_operand:DI 3 "s_register_operand" "0")))]
2128 "TARGET_DSP_MULTIPLY"
2129 "smlaltt%?\\t%Q0, %R0, %1, %2"
2130 [(set_attr "type" "smlalxy")
2131 (set_attr "predicable" "yes")
2132 (set_attr "predicable_short_it" "no")])
2133
2134 (define_expand "mulsf3"
2135 [(set (match_operand:SF 0 "s_register_operand" "")
2136 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2137 (match_operand:SF 2 "s_register_operand" "")))]
2138 "TARGET_32BIT && TARGET_HARD_FLOAT"
2139 "
2140 ")
2141
2142 (define_expand "muldf3"
2143 [(set (match_operand:DF 0 "s_register_operand" "")
2144 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2145 (match_operand:DF 2 "s_register_operand" "")))]
2146 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2147 "
2148 ")
2149 \f
2150 ;; Division insns
2151
2152 (define_expand "divsf3"
2153 [(set (match_operand:SF 0 "s_register_operand" "")
2154 (div:SF (match_operand:SF 1 "s_register_operand" "")
2155 (match_operand:SF 2 "s_register_operand" "")))]
2156 "TARGET_32BIT && TARGET_HARD_FLOAT"
2157 "")
2158
2159 (define_expand "divdf3"
2160 [(set (match_operand:DF 0 "s_register_operand" "")
2161 (div:DF (match_operand:DF 1 "s_register_operand" "")
2162 (match_operand:DF 2 "s_register_operand" "")))]
2163 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2164 "")
2165 \f
2166 ;; Boolean and,ior,xor insns
2167
2168 ;; Split up double word logical operations
2169
2170 ;; Split up simple DImode logical operations. Simply perform the logical
2171 ;; operation on the upper and lower halves of the registers.
2172 (define_split
2173 [(set (match_operand:DI 0 "s_register_operand" "")
2174 (match_operator:DI 6 "logical_binary_operator"
2175 [(match_operand:DI 1 "s_register_operand" "")
2176 (match_operand:DI 2 "s_register_operand" "")]))]
2177 "TARGET_32BIT && reload_completed
2178 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2179 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2180 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2181 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2182 "
2183 {
2184 operands[3] = gen_highpart (SImode, operands[0]);
2185 operands[0] = gen_lowpart (SImode, operands[0]);
2186 operands[4] = gen_highpart (SImode, operands[1]);
2187 operands[1] = gen_lowpart (SImode, operands[1]);
2188 operands[5] = gen_highpart (SImode, operands[2]);
2189 operands[2] = gen_lowpart (SImode, operands[2]);
2190 }"
2191 )
2192
2193 (define_split
2194 [(set (match_operand:DI 0 "s_register_operand" "")
2195 (match_operator:DI 6 "logical_binary_operator"
2196 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2197 (match_operand:DI 1 "s_register_operand" "")]))]
2198 "TARGET_32BIT && reload_completed"
2199 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2200 (set (match_dup 3) (match_op_dup:SI 6
2201 [(ashiftrt:SI (match_dup 2) (const_int 31))
2202 (match_dup 4)]))]
2203 "
2204 {
2205 operands[3] = gen_highpart (SImode, operands[0]);
2206 operands[0] = gen_lowpart (SImode, operands[0]);
2207 operands[4] = gen_highpart (SImode, operands[1]);
2208 operands[1] = gen_lowpart (SImode, operands[1]);
2209 operands[5] = gen_highpart (SImode, operands[2]);
2210 operands[2] = gen_lowpart (SImode, operands[2]);
2211 }"
2212 )
2213
2214 ;; The zero extend of operand 2 means we can just copy the high part of
2215 ;; operand1 into operand0.
2216 (define_split
2217 [(set (match_operand:DI 0 "s_register_operand" "")
2218 (ior:DI
2219 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2220 (match_operand:DI 1 "s_register_operand" "")))]
2221 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2222 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2223 (set (match_dup 3) (match_dup 4))]
2224 "
2225 {
2226 operands[4] = gen_highpart (SImode, operands[1]);
2227 operands[3] = gen_highpart (SImode, operands[0]);
2228 operands[0] = gen_lowpart (SImode, operands[0]);
2229 operands[1] = gen_lowpart (SImode, operands[1]);
2230 }"
2231 )
2232
2233 ;; The zero extend of operand 2 means we can just copy the high part of
2234 ;; operand1 into operand0.
2235 (define_split
2236 [(set (match_operand:DI 0 "s_register_operand" "")
2237 (xor:DI
2238 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2239 (match_operand:DI 1 "s_register_operand" "")))]
2240 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2241 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2242 (set (match_dup 3) (match_dup 4))]
2243 "
2244 {
2245 operands[4] = gen_highpart (SImode, operands[1]);
2246 operands[3] = gen_highpart (SImode, operands[0]);
2247 operands[0] = gen_lowpart (SImode, operands[0]);
2248 operands[1] = gen_lowpart (SImode, operands[1]);
2249 }"
2250 )
2251
2252 (define_expand "anddi3"
2253 [(set (match_operand:DI 0 "s_register_operand" "")
2254 (and:DI (match_operand:DI 1 "s_register_operand" "")
2255 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2256 "TARGET_32BIT"
2257 "
2258 if (!TARGET_NEON && !TARGET_IWMMXT)
2259 {
2260 rtx low = simplify_gen_binary (AND, SImode,
2261 gen_lowpart (SImode, operands[1]),
2262 gen_lowpart (SImode, operands[2]));
2263 rtx high = simplify_gen_binary (AND, SImode,
2264 gen_highpart (SImode, operands[1]),
2265 gen_highpart_mode (SImode, DImode,
2266 operands[2]));
2267
2268 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
2269 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
2270
2271 DONE;
2272 }
2273 /* Otherwise expand pattern as above. */
2274 "
2275 )
2276
2277 (define_insn_and_split "*anddi3_insn"
2278 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2279 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2280 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2281 "TARGET_32BIT && !TARGET_IWMMXT"
2282 {
2283 switch (which_alternative)
2284 {
2285 case 0: /* fall through */
2286 case 6: return "vand\t%P0, %P1, %P2";
2287 case 1: /* fall through */
2288 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2289 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2290 case 2:
2291 case 3:
2292 case 4:
2293 case 5: /* fall through */
2294 return "#";
2295 default: gcc_unreachable ();
2296 }
2297 }
2298 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2299 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2300 [(set (match_dup 3) (match_dup 4))
2301 (set (match_dup 5) (match_dup 6))]
2302 "
2303 {
2304 operands[3] = gen_lowpart (SImode, operands[0]);
2305 operands[5] = gen_highpart (SImode, operands[0]);
2306
2307 operands[4] = simplify_gen_binary (AND, SImode,
2308 gen_lowpart (SImode, operands[1]),
2309 gen_lowpart (SImode, operands[2]));
2310 operands[6] = simplify_gen_binary (AND, SImode,
2311 gen_highpart (SImode, operands[1]),
2312 gen_highpart_mode (SImode, DImode, operands[2]));
2313
2314 }"
2315 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2316 multiple,multiple,neon_logic,neon_logic")
2317 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2318 avoid_neon_for_64bits,avoid_neon_for_64bits")
2319 (set_attr "length" "*,*,8,8,8,8,*,*")
2320 ]
2321 )
2322
2323 (define_insn_and_split "*anddi_zesidi_di"
2324 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2325 (and:DI (zero_extend:DI
2326 (match_operand:SI 2 "s_register_operand" "r,r"))
2327 (match_operand:DI 1 "s_register_operand" "0,r")))]
2328 "TARGET_32BIT"
2329 "#"
2330 "TARGET_32BIT && reload_completed"
2331 ; The zero extend of operand 2 clears the high word of the output
2332 ; operand.
2333 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2334 (set (match_dup 3) (const_int 0))]
2335 "
2336 {
2337 operands[3] = gen_highpart (SImode, operands[0]);
2338 operands[0] = gen_lowpart (SImode, operands[0]);
2339 operands[1] = gen_lowpart (SImode, operands[1]);
2340 }"
2341 [(set_attr "length" "8")
2342 (set_attr "type" "multiple")]
2343 )
2344
2345 (define_insn "*anddi_sesdi_di"
2346 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2347 (and:DI (sign_extend:DI
2348 (match_operand:SI 2 "s_register_operand" "r,r"))
2349 (match_operand:DI 1 "s_register_operand" "0,r")))]
2350 "TARGET_32BIT"
2351 "#"
2352 [(set_attr "length" "8")
2353 (set_attr "type" "multiple")]
2354 )
2355
2356 (define_expand "andsi3"
2357 [(set (match_operand:SI 0 "s_register_operand" "")
2358 (and:SI (match_operand:SI 1 "s_register_operand" "")
2359 (match_operand:SI 2 "reg_or_int_operand" "")))]
2360 "TARGET_EITHER"
2361 "
2362 if (TARGET_32BIT)
2363 {
2364 if (CONST_INT_P (operands[2]))
2365 {
2366 if (INTVAL (operands[2]) == 255 && arm_arch6)
2367 {
2368 operands[1] = convert_to_mode (QImode, operands[1], 1);
2369 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2370 operands[1]));
2371 DONE;
2372 }
2373 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2374 operands[2] = force_reg (SImode, operands[2]);
2375 else
2376 {
2377 arm_split_constant (AND, SImode, NULL_RTX,
2378 INTVAL (operands[2]), operands[0],
2379 operands[1],
2380 optimize && can_create_pseudo_p ());
2381
2382 DONE;
2383 }
2384 }
2385 }
2386 else /* TARGET_THUMB1 */
2387 {
2388 if (!CONST_INT_P (operands[2]))
2389 {
2390 rtx tmp = force_reg (SImode, operands[2]);
2391 if (rtx_equal_p (operands[0], operands[1]))
2392 operands[2] = tmp;
2393 else
2394 {
2395 operands[2] = operands[1];
2396 operands[1] = tmp;
2397 }
2398 }
2399 else
2400 {
2401 int i;
2402
2403 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2404 {
2405 operands[2] = force_reg (SImode,
2406 GEN_INT (~INTVAL (operands[2])));
2407
2408 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2409
2410 DONE;
2411 }
2412
2413 for (i = 9; i <= 31; i++)
2414 {
2415 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2416 {
2417 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2418 const0_rtx));
2419 DONE;
2420 }
2421 else if ((HOST_WIDE_INT_1 << i) - 1
2422 == ~INTVAL (operands[2]))
2423 {
2424 rtx shift = GEN_INT (i);
2425 rtx reg = gen_reg_rtx (SImode);
2426
2427 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2428 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2429
2430 DONE;
2431 }
2432 }
2433
2434 operands[2] = force_reg (SImode, operands[2]);
2435 }
2436 }
2437 "
2438 )
2439
2440 ; ??? Check split length for Thumb-2
2441 (define_insn_and_split "*arm_andsi3_insn"
2442 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2443 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2444 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2445 "TARGET_32BIT"
2446 "@
2447 and%?\\t%0, %1, %2
2448 and%?\\t%0, %1, %2
2449 bic%?\\t%0, %1, #%B2
2450 and%?\\t%0, %1, %2
2451 #"
2452 "TARGET_32BIT
2453 && CONST_INT_P (operands[2])
2454 && !(const_ok_for_arm (INTVAL (operands[2]))
2455 || const_ok_for_arm (~INTVAL (operands[2])))"
2456 [(clobber (const_int 0))]
2457 "
2458 arm_split_constant (AND, SImode, curr_insn,
2459 INTVAL (operands[2]), operands[0], operands[1], 0);
2460 DONE;
2461 "
2462 [(set_attr "length" "4,4,4,4,16")
2463 (set_attr "predicable" "yes")
2464 (set_attr "predicable_short_it" "no,yes,no,no,no")
2465 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2466 )
2467
2468 (define_insn "*andsi3_compare0"
2469 [(set (reg:CC_NOOV CC_REGNUM)
2470 (compare:CC_NOOV
2471 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2472 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2473 (const_int 0)))
2474 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2475 (and:SI (match_dup 1) (match_dup 2)))]
2476 "TARGET_32BIT"
2477 "@
2478 ands%?\\t%0, %1, %2
2479 bics%?\\t%0, %1, #%B2
2480 ands%?\\t%0, %1, %2"
2481 [(set_attr "conds" "set")
2482 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2483 )
2484
2485 (define_insn "*andsi3_compare0_scratch"
2486 [(set (reg:CC_NOOV CC_REGNUM)
2487 (compare:CC_NOOV
2488 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2489 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2490 (const_int 0)))
2491 (clobber (match_scratch:SI 2 "=X,r,X"))]
2492 "TARGET_32BIT"
2493 "@
2494 tst%?\\t%0, %1
2495 bics%?\\t%2, %0, #%B1
2496 tst%?\\t%0, %1"
2497 [(set_attr "conds" "set")
2498 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2499 )
2500
2501 (define_insn "*zeroextractsi_compare0_scratch"
2502 [(set (reg:CC_NOOV CC_REGNUM)
2503 (compare:CC_NOOV (zero_extract:SI
2504 (match_operand:SI 0 "s_register_operand" "r")
2505 (match_operand 1 "const_int_operand" "n")
2506 (match_operand 2 "const_int_operand" "n"))
2507 (const_int 0)))]
2508 "TARGET_32BIT
2509 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2510 && INTVAL (operands[1]) > 0
2511 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2512 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2513 "*
2514 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2515 << INTVAL (operands[2]));
2516 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2517 return \"\";
2518 "
2519 [(set_attr "conds" "set")
2520 (set_attr "predicable" "yes")
2521 (set_attr "predicable_short_it" "no")
2522 (set_attr "type" "logics_imm")]
2523 )
2524
2525 (define_insn_and_split "*ne_zeroextractsi"
2526 [(set (match_operand:SI 0 "s_register_operand" "=r")
2527 (ne:SI (zero_extract:SI
2528 (match_operand:SI 1 "s_register_operand" "r")
2529 (match_operand:SI 2 "const_int_operand" "n")
2530 (match_operand:SI 3 "const_int_operand" "n"))
2531 (const_int 0)))
2532 (clobber (reg:CC CC_REGNUM))]
2533 "TARGET_32BIT
2534 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2535 && INTVAL (operands[2]) > 0
2536 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2537 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2538 "#"
2539 "TARGET_32BIT
2540 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2541 && INTVAL (operands[2]) > 0
2542 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2543 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2544 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2545 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2546 (const_int 0)))
2547 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2548 (set (match_dup 0)
2549 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2550 (match_dup 0) (const_int 1)))]
2551 "
2552 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2553 << INTVAL (operands[3]));
2554 "
2555 [(set_attr "conds" "clob")
2556 (set (attr "length")
2557 (if_then_else (eq_attr "is_thumb" "yes")
2558 (const_int 12)
2559 (const_int 8)))
2560 (set_attr "type" "multiple")]
2561 )
2562
2563 (define_insn_and_split "*ne_zeroextractsi_shifted"
2564 [(set (match_operand:SI 0 "s_register_operand" "=r")
2565 (ne:SI (zero_extract:SI
2566 (match_operand:SI 1 "s_register_operand" "r")
2567 (match_operand:SI 2 "const_int_operand" "n")
2568 (const_int 0))
2569 (const_int 0)))
2570 (clobber (reg:CC CC_REGNUM))]
2571 "TARGET_ARM"
2572 "#"
2573 "TARGET_ARM"
2574 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2575 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2576 (const_int 0)))
2577 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2578 (set (match_dup 0)
2579 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2580 (match_dup 0) (const_int 1)))]
2581 "
2582 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2583 "
2584 [(set_attr "conds" "clob")
2585 (set_attr "length" "8")
2586 (set_attr "type" "multiple")]
2587 )
2588
2589 (define_insn_and_split "*ite_ne_zeroextractsi"
2590 [(set (match_operand:SI 0 "s_register_operand" "=r")
2591 (if_then_else:SI (ne (zero_extract:SI
2592 (match_operand:SI 1 "s_register_operand" "r")
2593 (match_operand:SI 2 "const_int_operand" "n")
2594 (match_operand:SI 3 "const_int_operand" "n"))
2595 (const_int 0))
2596 (match_operand:SI 4 "arm_not_operand" "rIK")
2597 (const_int 0)))
2598 (clobber (reg:CC CC_REGNUM))]
2599 "TARGET_ARM
2600 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2601 && INTVAL (operands[2]) > 0
2602 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2603 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2604 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2605 "#"
2606 "TARGET_ARM
2607 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2608 && INTVAL (operands[2]) > 0
2609 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2610 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2611 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2612 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2613 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2614 (const_int 0)))
2615 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2616 (set (match_dup 0)
2617 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2618 (match_dup 0) (match_dup 4)))]
2619 "
2620 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2621 << INTVAL (operands[3]));
2622 "
2623 [(set_attr "conds" "clob")
2624 (set_attr "length" "8")
2625 (set_attr "type" "multiple")]
2626 )
2627
2628 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2629 [(set (match_operand:SI 0 "s_register_operand" "=r")
2630 (if_then_else:SI (ne (zero_extract:SI
2631 (match_operand:SI 1 "s_register_operand" "r")
2632 (match_operand:SI 2 "const_int_operand" "n")
2633 (const_int 0))
2634 (const_int 0))
2635 (match_operand:SI 3 "arm_not_operand" "rIK")
2636 (const_int 0)))
2637 (clobber (reg:CC CC_REGNUM))]
2638 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2639 "#"
2640 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2641 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2642 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2643 (const_int 0)))
2644 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2645 (set (match_dup 0)
2646 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2647 (match_dup 0) (match_dup 3)))]
2648 "
2649 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2650 "
2651 [(set_attr "conds" "clob")
2652 (set_attr "length" "8")
2653 (set_attr "type" "multiple")]
2654 )
2655
2656 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2657 (define_split
2658 [(set (match_operand:SI 0 "s_register_operand" "")
2659 (match_operator:SI 1 "shiftable_operator"
2660 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2661 (match_operand:SI 3 "const_int_operand" "")
2662 (match_operand:SI 4 "const_int_operand" ""))
2663 (match_operand:SI 5 "s_register_operand" "")]))
2664 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2665 "TARGET_ARM"
2666 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2667 (set (match_dup 0)
2668 (match_op_dup 1
2669 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2670 (match_dup 5)]))]
2671 "{
2672 HOST_WIDE_INT temp = INTVAL (operands[3]);
2673
2674 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2675 operands[4] = GEN_INT (32 - temp);
2676 }"
2677 )
2678
2679 (define_split
2680 [(set (match_operand:SI 0 "s_register_operand" "")
2681 (match_operator:SI 1 "shiftable_operator"
2682 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2683 (match_operand:SI 3 "const_int_operand" "")
2684 (match_operand:SI 4 "const_int_operand" ""))
2685 (match_operand:SI 5 "s_register_operand" "")]))
2686 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2687 "TARGET_ARM"
2688 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2689 (set (match_dup 0)
2690 (match_op_dup 1
2691 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2692 (match_dup 5)]))]
2693 "{
2694 HOST_WIDE_INT temp = INTVAL (operands[3]);
2695
2696 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2697 operands[4] = GEN_INT (32 - temp);
2698 }"
2699 )
2700
2701 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2702 ;;; represented by the bitfield, then this will produce incorrect results.
2703 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2704 ;;; which have a real bit-field insert instruction, the truncation happens
2705 ;;; in the bit-field insert instruction itself. Since arm does not have a
2706 ;;; bit-field insert instruction, we would have to emit code here to truncate
2707 ;;; the value before we insert. This loses some of the advantage of having
2708 ;;; this insv pattern, so this pattern needs to be reevalutated.
2709
2710 (define_expand "insv"
2711 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2712 (match_operand 1 "general_operand" "")
2713 (match_operand 2 "general_operand" ""))
2714 (match_operand 3 "reg_or_int_operand" ""))]
2715 "TARGET_ARM || arm_arch_thumb2"
2716 "
2717 {
2718 int start_bit = INTVAL (operands[2]);
2719 int width = INTVAL (operands[1]);
2720 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2721 rtx target, subtarget;
2722
2723 if (arm_arch_thumb2)
2724 {
2725 if (unaligned_access && MEM_P (operands[0])
2726 && s_register_operand (operands[3], GET_MODE (operands[3]))
2727 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2728 {
2729 rtx base_addr;
2730
2731 if (BYTES_BIG_ENDIAN)
2732 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2733 - start_bit;
2734
2735 if (width == 32)
2736 {
2737 base_addr = adjust_address (operands[0], SImode,
2738 start_bit / BITS_PER_UNIT);
2739 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2740 }
2741 else
2742 {
2743 rtx tmp = gen_reg_rtx (HImode);
2744
2745 base_addr = adjust_address (operands[0], HImode,
2746 start_bit / BITS_PER_UNIT);
2747 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2748 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2749 }
2750 DONE;
2751 }
2752 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2753 {
2754 bool use_bfi = TRUE;
2755
2756 if (CONST_INT_P (operands[3]))
2757 {
2758 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2759
2760 if (val == 0)
2761 {
2762 emit_insn (gen_insv_zero (operands[0], operands[1],
2763 operands[2]));
2764 DONE;
2765 }
2766
2767 /* See if the set can be done with a single orr instruction. */
2768 if (val == mask && const_ok_for_arm (val << start_bit))
2769 use_bfi = FALSE;
2770 }
2771
2772 if (use_bfi)
2773 {
2774 if (!REG_P (operands[3]))
2775 operands[3] = force_reg (SImode, operands[3]);
2776
2777 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2778 operands[3]));
2779 DONE;
2780 }
2781 }
2782 else
2783 FAIL;
2784 }
2785
2786 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2787 FAIL;
2788
2789 target = copy_rtx (operands[0]);
2790 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2791 subreg as the final target. */
2792 if (GET_CODE (target) == SUBREG)
2793 {
2794 subtarget = gen_reg_rtx (SImode);
2795 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2796 < GET_MODE_SIZE (SImode))
2797 target = SUBREG_REG (target);
2798 }
2799 else
2800 subtarget = target;
2801
2802 if (CONST_INT_P (operands[3]))
2803 {
2804 /* Since we are inserting a known constant, we may be able to
2805 reduce the number of bits that we have to clear so that
2806 the mask becomes simple. */
2807 /* ??? This code does not check to see if the new mask is actually
2808 simpler. It may not be. */
2809 rtx op1 = gen_reg_rtx (SImode);
2810 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2811 start of this pattern. */
2812 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2813 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2814
2815 emit_insn (gen_andsi3 (op1, operands[0],
2816 gen_int_mode (~mask2, SImode)));
2817 emit_insn (gen_iorsi3 (subtarget, op1,
2818 gen_int_mode (op3_value << start_bit, SImode)));
2819 }
2820 else if (start_bit == 0
2821 && !(const_ok_for_arm (mask)
2822 || const_ok_for_arm (~mask)))
2823 {
2824 /* A Trick, since we are setting the bottom bits in the word,
2825 we can shift operand[3] up, operand[0] down, OR them together
2826 and rotate the result back again. This takes 3 insns, and
2827 the third might be mergeable into another op. */
2828 /* The shift up copes with the possibility that operand[3] is
2829 wider than the bitfield. */
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_lshrsi3 (op1, operands[0], operands[1]));
2835 emit_insn (gen_iorsi3 (op1, op1, op0));
2836 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2837 }
2838 else if ((width + start_bit == 32)
2839 && !(const_ok_for_arm (mask)
2840 || const_ok_for_arm (~mask)))
2841 {
2842 /* Similar trick, but slightly less efficient. */
2843
2844 rtx op0 = gen_reg_rtx (SImode);
2845 rtx op1 = gen_reg_rtx (SImode);
2846
2847 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2848 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2849 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2850 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2851 }
2852 else
2853 {
2854 rtx op0 = gen_int_mode (mask, SImode);
2855 rtx op1 = gen_reg_rtx (SImode);
2856 rtx op2 = gen_reg_rtx (SImode);
2857
2858 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2859 {
2860 rtx tmp = gen_reg_rtx (SImode);
2861
2862 emit_insn (gen_movsi (tmp, op0));
2863 op0 = tmp;
2864 }
2865
2866 /* Mask out any bits in operand[3] that are not needed. */
2867 emit_insn (gen_andsi3 (op1, operands[3], op0));
2868
2869 if (CONST_INT_P (op0)
2870 && (const_ok_for_arm (mask << start_bit)
2871 || const_ok_for_arm (~(mask << start_bit))))
2872 {
2873 op0 = gen_int_mode (~(mask << start_bit), SImode);
2874 emit_insn (gen_andsi3 (op2, operands[0], op0));
2875 }
2876 else
2877 {
2878 if (CONST_INT_P (op0))
2879 {
2880 rtx tmp = gen_reg_rtx (SImode);
2881
2882 emit_insn (gen_movsi (tmp, op0));
2883 op0 = tmp;
2884 }
2885
2886 if (start_bit != 0)
2887 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2888
2889 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2890 }
2891
2892 if (start_bit != 0)
2893 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2894
2895 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2896 }
2897
2898 if (subtarget != target)
2899 {
2900 /* If TARGET is still a SUBREG, then it must be wider than a word,
2901 so we must be careful only to set the subword we were asked to. */
2902 if (GET_CODE (target) == SUBREG)
2903 emit_move_insn (target, subtarget);
2904 else
2905 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2906 }
2907
2908 DONE;
2909 }"
2910 )
2911
2912 (define_insn "insv_zero"
2913 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2914 (match_operand:SI 1 "const_int_M_operand" "M")
2915 (match_operand:SI 2 "const_int_M_operand" "M"))
2916 (const_int 0))]
2917 "arm_arch_thumb2"
2918 "bfc%?\t%0, %2, %1"
2919 [(set_attr "length" "4")
2920 (set_attr "predicable" "yes")
2921 (set_attr "predicable_short_it" "no")
2922 (set_attr "type" "bfm")]
2923 )
2924
2925 (define_insn "insv_t2"
2926 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2927 (match_operand:SI 1 "const_int_M_operand" "M")
2928 (match_operand:SI 2 "const_int_M_operand" "M"))
2929 (match_operand:SI 3 "s_register_operand" "r"))]
2930 "arm_arch_thumb2"
2931 "bfi%?\t%0, %3, %2, %1"
2932 [(set_attr "length" "4")
2933 (set_attr "predicable" "yes")
2934 (set_attr "predicable_short_it" "no")
2935 (set_attr "type" "bfm")]
2936 )
2937
2938 ; constants for op 2 will never be given to these patterns.
2939 (define_insn_and_split "*anddi_notdi_di"
2940 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2941 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2942 (match_operand:DI 2 "s_register_operand" "r,0")))]
2943 "TARGET_32BIT"
2944 "#"
2945 "TARGET_32BIT && reload_completed
2946 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2947 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2948 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2949 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2950 "
2951 {
2952 operands[3] = gen_highpart (SImode, operands[0]);
2953 operands[0] = gen_lowpart (SImode, operands[0]);
2954 operands[4] = gen_highpart (SImode, operands[1]);
2955 operands[1] = gen_lowpart (SImode, operands[1]);
2956 operands[5] = gen_highpart (SImode, operands[2]);
2957 operands[2] = gen_lowpart (SImode, operands[2]);
2958 }"
2959 [(set_attr "length" "8")
2960 (set_attr "predicable" "yes")
2961 (set_attr "type" "multiple")]
2962 )
2963
2964 (define_insn_and_split "*anddi_notzesidi_di"
2965 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2966 (and:DI (not:DI (zero_extend:DI
2967 (match_operand:SI 2 "s_register_operand" "r,r")))
2968 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2969 "TARGET_32BIT"
2970 "@
2971 bic%?\\t%Q0, %Q1, %2
2972 #"
2973 ; (not (zero_extend ...)) allows us to just copy the high word from
2974 ; operand1 to operand0.
2975 "TARGET_32BIT
2976 && reload_completed
2977 && operands[0] != operands[1]"
2978 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2979 (set (match_dup 3) (match_dup 4))]
2980 "
2981 {
2982 operands[3] = gen_highpart (SImode, operands[0]);
2983 operands[0] = gen_lowpart (SImode, operands[0]);
2984 operands[4] = gen_highpart (SImode, operands[1]);
2985 operands[1] = gen_lowpart (SImode, operands[1]);
2986 }"
2987 [(set_attr "length" "4,8")
2988 (set_attr "predicable" "yes")
2989 (set_attr "predicable_short_it" "no")
2990 (set_attr "type" "multiple")]
2991 )
2992
2993 (define_insn_and_split "*anddi_notdi_zesidi"
2994 [(set (match_operand:DI 0 "s_register_operand" "=r")
2995 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2996 (zero_extend:DI
2997 (match_operand:SI 1 "s_register_operand" "r"))))]
2998 "TARGET_32BIT"
2999 "#"
3000 "TARGET_32BIT && reload_completed"
3001 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3002 (set (match_dup 3) (const_int 0))]
3003 "
3004 {
3005 operands[3] = gen_highpart (SImode, operands[0]);
3006 operands[0] = gen_lowpart (SImode, operands[0]);
3007 operands[2] = gen_lowpart (SImode, operands[2]);
3008 }"
3009 [(set_attr "length" "8")
3010 (set_attr "predicable" "yes")
3011 (set_attr "predicable_short_it" "no")
3012 (set_attr "type" "multiple")]
3013 )
3014
3015 (define_insn_and_split "*anddi_notsesidi_di"
3016 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3017 (and:DI (not:DI (sign_extend:DI
3018 (match_operand:SI 2 "s_register_operand" "r,r")))
3019 (match_operand:DI 1 "s_register_operand" "0,r")))]
3020 "TARGET_32BIT"
3021 "#"
3022 "TARGET_32BIT && reload_completed"
3023 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3024 (set (match_dup 3) (and:SI (not:SI
3025 (ashiftrt:SI (match_dup 2) (const_int 31)))
3026 (match_dup 4)))]
3027 "
3028 {
3029 operands[3] = gen_highpart (SImode, operands[0]);
3030 operands[0] = gen_lowpart (SImode, operands[0]);
3031 operands[4] = gen_highpart (SImode, operands[1]);
3032 operands[1] = gen_lowpart (SImode, operands[1]);
3033 }"
3034 [(set_attr "length" "8")
3035 (set_attr "predicable" "yes")
3036 (set_attr "predicable_short_it" "no")
3037 (set_attr "type" "multiple")]
3038 )
3039
3040 (define_insn "andsi_notsi_si"
3041 [(set (match_operand:SI 0 "s_register_operand" "=r")
3042 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3043 (match_operand:SI 1 "s_register_operand" "r")))]
3044 "TARGET_32BIT"
3045 "bic%?\\t%0, %1, %2"
3046 [(set_attr "predicable" "yes")
3047 (set_attr "predicable_short_it" "no")
3048 (set_attr "type" "logic_reg")]
3049 )
3050
3051 (define_insn "andsi_not_shiftsi_si"
3052 [(set (match_operand:SI 0 "s_register_operand" "=r")
3053 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3054 [(match_operand:SI 2 "s_register_operand" "r")
3055 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3056 (match_operand:SI 1 "s_register_operand" "r")))]
3057 "TARGET_ARM"
3058 "bic%?\\t%0, %1, %2%S4"
3059 [(set_attr "predicable" "yes")
3060 (set_attr "shift" "2")
3061 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3062 (const_string "logic_shift_imm")
3063 (const_string "logic_shift_reg")))]
3064 )
3065
3066 ;; Shifted bics pattern used to set up CC status register and not reusing
3067 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3068 ;; does not support shift by register.
3069 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3070 [(set (reg:CC_NOOV CC_REGNUM)
3071 (compare:CC_NOOV
3072 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3073 [(match_operand:SI 1 "s_register_operand" "r")
3074 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3075 (match_operand:SI 3 "s_register_operand" "r"))
3076 (const_int 0)))
3077 (clobber (match_scratch:SI 4 "=r"))]
3078 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3079 "bics%?\\t%4, %3, %1%S0"
3080 [(set_attr "predicable" "yes")
3081 (set_attr "predicable_short_it" "no")
3082 (set_attr "conds" "set")
3083 (set_attr "shift" "1")
3084 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3085 (const_string "logic_shift_imm")
3086 (const_string "logic_shift_reg")))]
3087 )
3088
3089 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3090 ;; getting reused later.
3091 (define_insn "andsi_not_shiftsi_si_scc"
3092 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3093 (compare:CC_NOOV
3094 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3095 [(match_operand:SI 1 "s_register_operand" "r")
3096 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3097 (match_operand:SI 3 "s_register_operand" "r"))
3098 (const_int 0)))
3099 (set (match_operand:SI 4 "s_register_operand" "=r")
3100 (and:SI (not:SI (match_op_dup 0
3101 [(match_dup 1)
3102 (match_dup 2)]))
3103 (match_dup 3)))])]
3104 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3105 "bics%?\\t%4, %3, %1%S0"
3106 [(set_attr "predicable" "yes")
3107 (set_attr "predicable_short_it" "no")
3108 (set_attr "conds" "set")
3109 (set_attr "shift" "1")
3110 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3111 (const_string "logic_shift_imm")
3112 (const_string "logic_shift_reg")))]
3113 )
3114
3115 (define_insn "*andsi_notsi_si_compare0"
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 (set (match_operand:SI 0 "s_register_operand" "=r")
3122 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3123 "TARGET_32BIT"
3124 "bics\\t%0, %1, %2"
3125 [(set_attr "conds" "set")
3126 (set_attr "type" "logics_shift_reg")]
3127 )
3128
3129 (define_insn "*andsi_notsi_si_compare0_scratch"
3130 [(set (reg:CC_NOOV CC_REGNUM)
3131 (compare:CC_NOOV
3132 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3133 (match_operand:SI 1 "s_register_operand" "r"))
3134 (const_int 0)))
3135 (clobber (match_scratch:SI 0 "=r"))]
3136 "TARGET_32BIT"
3137 "bics\\t%0, %1, %2"
3138 [(set_attr "conds" "set")
3139 (set_attr "type" "logics_shift_reg")]
3140 )
3141
3142 (define_expand "iordi3"
3143 [(set (match_operand:DI 0 "s_register_operand" "")
3144 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3145 (match_operand:DI 2 "neon_logic_op2" "")))]
3146 "TARGET_32BIT"
3147 "
3148 if (!TARGET_NEON && !TARGET_IWMMXT)
3149 {
3150 rtx low = simplify_gen_binary (IOR, SImode,
3151 gen_lowpart (SImode, operands[1]),
3152 gen_lowpart (SImode, operands[2]));
3153 rtx high = simplify_gen_binary (IOR, SImode,
3154 gen_highpart (SImode, operands[1]),
3155 gen_highpart_mode (SImode, DImode,
3156 operands[2]));
3157
3158 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3159 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3160
3161 DONE;
3162 }
3163 /* Otherwise expand pattern as above. */
3164 "
3165 )
3166
3167 (define_insn_and_split "*iordi3_insn"
3168 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3169 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3170 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3171 "TARGET_32BIT && !TARGET_IWMMXT"
3172 {
3173 switch (which_alternative)
3174 {
3175 case 0: /* fall through */
3176 case 6: return "vorr\t%P0, %P1, %P2";
3177 case 1: /* fall through */
3178 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3179 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3180 case 2:
3181 case 3:
3182 case 4:
3183 case 5:
3184 return "#";
3185 default: gcc_unreachable ();
3186 }
3187 }
3188 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3189 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3190 [(set (match_dup 3) (match_dup 4))
3191 (set (match_dup 5) (match_dup 6))]
3192 "
3193 {
3194 operands[3] = gen_lowpart (SImode, operands[0]);
3195 operands[5] = gen_highpart (SImode, operands[0]);
3196
3197 operands[4] = simplify_gen_binary (IOR, SImode,
3198 gen_lowpart (SImode, operands[1]),
3199 gen_lowpart (SImode, operands[2]));
3200 operands[6] = simplify_gen_binary (IOR, SImode,
3201 gen_highpart (SImode, operands[1]),
3202 gen_highpart_mode (SImode, DImode, operands[2]));
3203
3204 }"
3205 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3206 multiple,neon_logic,neon_logic")
3207 (set_attr "length" "*,*,8,8,8,8,*,*")
3208 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3209 )
3210
3211 (define_insn "*iordi_zesidi_di"
3212 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3213 (ior:DI (zero_extend:DI
3214 (match_operand:SI 2 "s_register_operand" "r,r"))
3215 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3216 "TARGET_32BIT"
3217 "@
3218 orr%?\\t%Q0, %Q1, %2
3219 #"
3220 [(set_attr "length" "4,8")
3221 (set_attr "predicable" "yes")
3222 (set_attr "predicable_short_it" "no")
3223 (set_attr "type" "logic_reg,multiple")]
3224 )
3225
3226 (define_insn "*iordi_sesidi_di"
3227 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3228 (ior:DI (sign_extend:DI
3229 (match_operand:SI 2 "s_register_operand" "r,r"))
3230 (match_operand:DI 1 "s_register_operand" "0,r")))]
3231 "TARGET_32BIT"
3232 "#"
3233 [(set_attr "length" "8")
3234 (set_attr "predicable" "yes")
3235 (set_attr "type" "multiple")]
3236 )
3237
3238 (define_expand "iorsi3"
3239 [(set (match_operand:SI 0 "s_register_operand" "")
3240 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3241 (match_operand:SI 2 "reg_or_int_operand" "")))]
3242 "TARGET_EITHER"
3243 "
3244 if (CONST_INT_P (operands[2]))
3245 {
3246 if (TARGET_32BIT)
3247 {
3248 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3249 operands[2] = force_reg (SImode, operands[2]);
3250 else
3251 {
3252 arm_split_constant (IOR, SImode, NULL_RTX,
3253 INTVAL (operands[2]), operands[0],
3254 operands[1],
3255 optimize && can_create_pseudo_p ());
3256 DONE;
3257 }
3258 }
3259 else /* TARGET_THUMB1 */
3260 {
3261 rtx tmp = force_reg (SImode, operands[2]);
3262 if (rtx_equal_p (operands[0], operands[1]))
3263 operands[2] = tmp;
3264 else
3265 {
3266 operands[2] = operands[1];
3267 operands[1] = tmp;
3268 }
3269 }
3270 }
3271 "
3272 )
3273
3274 (define_insn_and_split "*iorsi3_insn"
3275 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3276 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3277 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3278 "TARGET_32BIT"
3279 "@
3280 orr%?\\t%0, %1, %2
3281 orr%?\\t%0, %1, %2
3282 orn%?\\t%0, %1, #%B2
3283 orr%?\\t%0, %1, %2
3284 #"
3285 "TARGET_32BIT
3286 && CONST_INT_P (operands[2])
3287 && !(const_ok_for_arm (INTVAL (operands[2]))
3288 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3289 [(clobber (const_int 0))]
3290 {
3291 arm_split_constant (IOR, SImode, curr_insn,
3292 INTVAL (operands[2]), operands[0], operands[1], 0);
3293 DONE;
3294 }
3295 [(set_attr "length" "4,4,4,4,16")
3296 (set_attr "arch" "32,t2,t2,32,32")
3297 (set_attr "predicable" "yes")
3298 (set_attr "predicable_short_it" "no,yes,no,no,no")
3299 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3300 )
3301
3302 (define_peephole2
3303 [(match_scratch:SI 3 "r")
3304 (set (match_operand:SI 0 "arm_general_register_operand" "")
3305 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3306 (match_operand:SI 2 "const_int_operand" "")))]
3307 "TARGET_ARM
3308 && !const_ok_for_arm (INTVAL (operands[2]))
3309 && const_ok_for_arm (~INTVAL (operands[2]))"
3310 [(set (match_dup 3) (match_dup 2))
3311 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3312 ""
3313 )
3314
3315 (define_insn "*iorsi3_compare0"
3316 [(set (reg:CC_NOOV CC_REGNUM)
3317 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3318 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3319 (const_int 0)))
3320 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3321 (ior:SI (match_dup 1) (match_dup 2)))]
3322 "TARGET_32BIT"
3323 "orrs%?\\t%0, %1, %2"
3324 [(set_attr "conds" "set")
3325 (set_attr "type" "logics_imm,logics_reg")]
3326 )
3327
3328 (define_insn "*iorsi3_compare0_scratch"
3329 [(set (reg:CC_NOOV CC_REGNUM)
3330 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3331 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3332 (const_int 0)))
3333 (clobber (match_scratch:SI 0 "=r,r"))]
3334 "TARGET_32BIT"
3335 "orrs%?\\t%0, %1, %2"
3336 [(set_attr "conds" "set")
3337 (set_attr "type" "logics_imm,logics_reg")]
3338 )
3339
3340 (define_expand "xordi3"
3341 [(set (match_operand:DI 0 "s_register_operand" "")
3342 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3343 (match_operand:DI 2 "arm_xordi_operand" "")))]
3344 "TARGET_32BIT"
3345 {
3346 /* The iWMMXt pattern for xordi3 accepts only register operands but we want
3347 to reuse this expander for all TARGET_32BIT targets so just force the
3348 constants into a register. Unlike for the anddi3 and iordi3 there are
3349 no NEON instructions that take an immediate. */
3350 if (TARGET_IWMMXT && !REG_P (operands[2]))
3351 operands[2] = force_reg (DImode, operands[2]);
3352 if (!TARGET_NEON && !TARGET_IWMMXT)
3353 {
3354 rtx low = simplify_gen_binary (XOR, SImode,
3355 gen_lowpart (SImode, operands[1]),
3356 gen_lowpart (SImode, operands[2]));
3357 rtx high = simplify_gen_binary (XOR, SImode,
3358 gen_highpart (SImode, operands[1]),
3359 gen_highpart_mode (SImode, DImode,
3360 operands[2]));
3361
3362 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
3363 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
3364
3365 DONE;
3366 }
3367 /* Otherwise expand pattern as above. */
3368 }
3369 )
3370
3371 (define_insn_and_split "*xordi3_insn"
3372 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3373 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3374 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3375 "TARGET_32BIT && !TARGET_IWMMXT"
3376 {
3377 switch (which_alternative)
3378 {
3379 case 1:
3380 case 2:
3381 case 3:
3382 case 4: /* fall through */
3383 return "#";
3384 case 0: /* fall through */
3385 case 5: return "veor\t%P0, %P1, %P2";
3386 default: gcc_unreachable ();
3387 }
3388 }
3389 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3390 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3391 [(set (match_dup 3) (match_dup 4))
3392 (set (match_dup 5) (match_dup 6))]
3393 "
3394 {
3395 operands[3] = gen_lowpart (SImode, operands[0]);
3396 operands[5] = gen_highpart (SImode, operands[0]);
3397
3398 operands[4] = simplify_gen_binary (XOR, SImode,
3399 gen_lowpart (SImode, operands[1]),
3400 gen_lowpart (SImode, operands[2]));
3401 operands[6] = simplify_gen_binary (XOR, SImode,
3402 gen_highpart (SImode, operands[1]),
3403 gen_highpart_mode (SImode, DImode, operands[2]));
3404
3405 }"
3406 [(set_attr "length" "*,8,8,8,8,*")
3407 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3408 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3409 )
3410
3411 (define_insn "*xordi_zesidi_di"
3412 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3413 (xor:DI (zero_extend:DI
3414 (match_operand:SI 2 "s_register_operand" "r,r"))
3415 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3416 "TARGET_32BIT"
3417 "@
3418 eor%?\\t%Q0, %Q1, %2
3419 #"
3420 [(set_attr "length" "4,8")
3421 (set_attr "predicable" "yes")
3422 (set_attr "predicable_short_it" "no")
3423 (set_attr "type" "logic_reg")]
3424 )
3425
3426 (define_insn "*xordi_sesidi_di"
3427 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3428 (xor:DI (sign_extend:DI
3429 (match_operand:SI 2 "s_register_operand" "r,r"))
3430 (match_operand:DI 1 "s_register_operand" "0,r")))]
3431 "TARGET_32BIT"
3432 "#"
3433 [(set_attr "length" "8")
3434 (set_attr "predicable" "yes")
3435 (set_attr "type" "multiple")]
3436 )
3437
3438 (define_expand "xorsi3"
3439 [(set (match_operand:SI 0 "s_register_operand" "")
3440 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3441 (match_operand:SI 2 "reg_or_int_operand" "")))]
3442 "TARGET_EITHER"
3443 "if (CONST_INT_P (operands[2]))
3444 {
3445 if (TARGET_32BIT)
3446 {
3447 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3448 operands[2] = force_reg (SImode, operands[2]);
3449 else
3450 {
3451 arm_split_constant (XOR, SImode, NULL_RTX,
3452 INTVAL (operands[2]), operands[0],
3453 operands[1],
3454 optimize && can_create_pseudo_p ());
3455 DONE;
3456 }
3457 }
3458 else /* TARGET_THUMB1 */
3459 {
3460 rtx tmp = force_reg (SImode, operands[2]);
3461 if (rtx_equal_p (operands[0], operands[1]))
3462 operands[2] = tmp;
3463 else
3464 {
3465 operands[2] = operands[1];
3466 operands[1] = tmp;
3467 }
3468 }
3469 }"
3470 )
3471
3472 (define_insn_and_split "*arm_xorsi3"
3473 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3474 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3475 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3476 "TARGET_32BIT"
3477 "@
3478 eor%?\\t%0, %1, %2
3479 eor%?\\t%0, %1, %2
3480 eor%?\\t%0, %1, %2
3481 #"
3482 "TARGET_32BIT
3483 && CONST_INT_P (operands[2])
3484 && !const_ok_for_arm (INTVAL (operands[2]))"
3485 [(clobber (const_int 0))]
3486 {
3487 arm_split_constant (XOR, SImode, curr_insn,
3488 INTVAL (operands[2]), operands[0], operands[1], 0);
3489 DONE;
3490 }
3491 [(set_attr "length" "4,4,4,16")
3492 (set_attr "predicable" "yes")
3493 (set_attr "predicable_short_it" "no,yes,no,no")
3494 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3495 )
3496
3497 (define_insn "*xorsi3_compare0"
3498 [(set (reg:CC_NOOV CC_REGNUM)
3499 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3500 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3501 (const_int 0)))
3502 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3503 (xor:SI (match_dup 1) (match_dup 2)))]
3504 "TARGET_32BIT"
3505 "eors%?\\t%0, %1, %2"
3506 [(set_attr "conds" "set")
3507 (set_attr "type" "logics_imm,logics_reg")]
3508 )
3509
3510 (define_insn "*xorsi3_compare0_scratch"
3511 [(set (reg:CC_NOOV CC_REGNUM)
3512 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3513 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3514 (const_int 0)))]
3515 "TARGET_32BIT"
3516 "teq%?\\t%0, %1"
3517 [(set_attr "conds" "set")
3518 (set_attr "type" "logics_imm,logics_reg")]
3519 )
3520
3521 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3522 ; (NOT D) we can sometimes merge the final NOT into one of the following
3523 ; insns.
3524
3525 (define_split
3526 [(set (match_operand:SI 0 "s_register_operand" "")
3527 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3528 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3529 (match_operand:SI 3 "arm_rhs_operand" "")))
3530 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3531 "TARGET_32BIT"
3532 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3533 (not:SI (match_dup 3))))
3534 (set (match_dup 0) (not:SI (match_dup 4)))]
3535 ""
3536 )
3537
3538 (define_insn_and_split "*andsi_iorsi3_notsi"
3539 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3540 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3541 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3542 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3543 "TARGET_32BIT"
3544 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3545 "&& reload_completed"
3546 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3547 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3548 {
3549 /* If operands[3] is a constant make sure to fold the NOT into it
3550 to avoid creating a NOT of a CONST_INT. */
3551 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3552 if (CONST_INT_P (not_rtx))
3553 {
3554 operands[4] = operands[0];
3555 operands[5] = not_rtx;
3556 }
3557 else
3558 {
3559 operands[5] = operands[0];
3560 operands[4] = not_rtx;
3561 }
3562 }
3563 [(set_attr "length" "8")
3564 (set_attr "ce_count" "2")
3565 (set_attr "predicable" "yes")
3566 (set_attr "predicable_short_it" "no")
3567 (set_attr "type" "multiple")]
3568 )
3569
3570 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3571 ; insns are available?
3572 (define_split
3573 [(set (match_operand:SI 0 "s_register_operand" "")
3574 (match_operator:SI 1 "logical_binary_operator"
3575 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3576 (match_operand:SI 3 "const_int_operand" "")
3577 (match_operand:SI 4 "const_int_operand" ""))
3578 (match_operator:SI 9 "logical_binary_operator"
3579 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3580 (match_operand:SI 6 "const_int_operand" ""))
3581 (match_operand:SI 7 "s_register_operand" "")])]))
3582 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3583 "TARGET_32BIT
3584 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3585 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3586 [(set (match_dup 8)
3587 (match_op_dup 1
3588 [(ashift:SI (match_dup 2) (match_dup 4))
3589 (match_dup 5)]))
3590 (set (match_dup 0)
3591 (match_op_dup 1
3592 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3593 (match_dup 7)]))]
3594 "
3595 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3596 ")
3597
3598 (define_split
3599 [(set (match_operand:SI 0 "s_register_operand" "")
3600 (match_operator:SI 1 "logical_binary_operator"
3601 [(match_operator:SI 9 "logical_binary_operator"
3602 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3603 (match_operand:SI 6 "const_int_operand" ""))
3604 (match_operand:SI 7 "s_register_operand" "")])
3605 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3606 (match_operand:SI 3 "const_int_operand" "")
3607 (match_operand:SI 4 "const_int_operand" ""))]))
3608 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3609 "TARGET_32BIT
3610 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3611 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3612 [(set (match_dup 8)
3613 (match_op_dup 1
3614 [(ashift:SI (match_dup 2) (match_dup 4))
3615 (match_dup 5)]))
3616 (set (match_dup 0)
3617 (match_op_dup 1
3618 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3619 (match_dup 7)]))]
3620 "
3621 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3622 ")
3623
3624 (define_split
3625 [(set (match_operand:SI 0 "s_register_operand" "")
3626 (match_operator:SI 1 "logical_binary_operator"
3627 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3628 (match_operand:SI 3 "const_int_operand" "")
3629 (match_operand:SI 4 "const_int_operand" ""))
3630 (match_operator:SI 9 "logical_binary_operator"
3631 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3632 (match_operand:SI 6 "const_int_operand" ""))
3633 (match_operand:SI 7 "s_register_operand" "")])]))
3634 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3635 "TARGET_32BIT
3636 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3637 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3638 [(set (match_dup 8)
3639 (match_op_dup 1
3640 [(ashift:SI (match_dup 2) (match_dup 4))
3641 (match_dup 5)]))
3642 (set (match_dup 0)
3643 (match_op_dup 1
3644 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3645 (match_dup 7)]))]
3646 "
3647 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3648 ")
3649
3650 (define_split
3651 [(set (match_operand:SI 0 "s_register_operand" "")
3652 (match_operator:SI 1 "logical_binary_operator"
3653 [(match_operator:SI 9 "logical_binary_operator"
3654 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3655 (match_operand:SI 6 "const_int_operand" ""))
3656 (match_operand:SI 7 "s_register_operand" "")])
3657 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3658 (match_operand:SI 3 "const_int_operand" "")
3659 (match_operand:SI 4 "const_int_operand" ""))]))
3660 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3661 "TARGET_32BIT
3662 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3663 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3664 [(set (match_dup 8)
3665 (match_op_dup 1
3666 [(ashift:SI (match_dup 2) (match_dup 4))
3667 (match_dup 5)]))
3668 (set (match_dup 0)
3669 (match_op_dup 1
3670 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3671 (match_dup 7)]))]
3672 "
3673 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3674 ")
3675 \f
3676
3677 ;; Minimum and maximum insns
3678
3679 (define_expand "smaxsi3"
3680 [(parallel [
3681 (set (match_operand:SI 0 "s_register_operand" "")
3682 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3683 (match_operand:SI 2 "arm_rhs_operand" "")))
3684 (clobber (reg:CC CC_REGNUM))])]
3685 "TARGET_32BIT"
3686 "
3687 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3688 {
3689 /* No need for a clobber of the condition code register here. */
3690 emit_insn (gen_rtx_SET (operands[0],
3691 gen_rtx_SMAX (SImode, operands[1],
3692 operands[2])));
3693 DONE;
3694 }
3695 ")
3696
3697 (define_insn "*smax_0"
3698 [(set (match_operand:SI 0 "s_register_operand" "=r")
3699 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3700 (const_int 0)))]
3701 "TARGET_32BIT"
3702 "bic%?\\t%0, %1, %1, asr #31"
3703 [(set_attr "predicable" "yes")
3704 (set_attr "predicable_short_it" "no")
3705 (set_attr "type" "logic_shift_reg")]
3706 )
3707
3708 (define_insn "*smax_m1"
3709 [(set (match_operand:SI 0 "s_register_operand" "=r")
3710 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3711 (const_int -1)))]
3712 "TARGET_32BIT"
3713 "orr%?\\t%0, %1, %1, asr #31"
3714 [(set_attr "predicable" "yes")
3715 (set_attr "predicable_short_it" "no")
3716 (set_attr "type" "logic_shift_reg")]
3717 )
3718
3719 (define_insn_and_split "*arm_smax_insn"
3720 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3721 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3722 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3723 (clobber (reg:CC CC_REGNUM))]
3724 "TARGET_ARM"
3725 "#"
3726 ; cmp\\t%1, %2\;movlt\\t%0, %2
3727 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3728 "TARGET_ARM"
3729 [(set (reg:CC CC_REGNUM)
3730 (compare:CC (match_dup 1) (match_dup 2)))
3731 (set (match_dup 0)
3732 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3733 (match_dup 1)
3734 (match_dup 2)))]
3735 ""
3736 [(set_attr "conds" "clob")
3737 (set_attr "length" "8,12")
3738 (set_attr "type" "multiple")]
3739 )
3740
3741 (define_expand "sminsi3"
3742 [(parallel [
3743 (set (match_operand:SI 0 "s_register_operand" "")
3744 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3745 (match_operand:SI 2 "arm_rhs_operand" "")))
3746 (clobber (reg:CC CC_REGNUM))])]
3747 "TARGET_32BIT"
3748 "
3749 if (operands[2] == const0_rtx)
3750 {
3751 /* No need for a clobber of the condition code register here. */
3752 emit_insn (gen_rtx_SET (operands[0],
3753 gen_rtx_SMIN (SImode, operands[1],
3754 operands[2])));
3755 DONE;
3756 }
3757 ")
3758
3759 (define_insn "*smin_0"
3760 [(set (match_operand:SI 0 "s_register_operand" "=r")
3761 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3762 (const_int 0)))]
3763 "TARGET_32BIT"
3764 "and%?\\t%0, %1, %1, asr #31"
3765 [(set_attr "predicable" "yes")
3766 (set_attr "predicable_short_it" "no")
3767 (set_attr "type" "logic_shift_reg")]
3768 )
3769
3770 (define_insn_and_split "*arm_smin_insn"
3771 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3772 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3773 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3774 (clobber (reg:CC CC_REGNUM))]
3775 "TARGET_ARM"
3776 "#"
3777 ; cmp\\t%1, %2\;movge\\t%0, %2
3778 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3779 "TARGET_ARM"
3780 [(set (reg:CC CC_REGNUM)
3781 (compare:CC (match_dup 1) (match_dup 2)))
3782 (set (match_dup 0)
3783 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3784 (match_dup 1)
3785 (match_dup 2)))]
3786 ""
3787 [(set_attr "conds" "clob")
3788 (set_attr "length" "8,12")
3789 (set_attr "type" "multiple,multiple")]
3790 )
3791
3792 (define_expand "umaxsi3"
3793 [(parallel [
3794 (set (match_operand:SI 0 "s_register_operand" "")
3795 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3796 (match_operand:SI 2 "arm_rhs_operand" "")))
3797 (clobber (reg:CC CC_REGNUM))])]
3798 "TARGET_32BIT"
3799 ""
3800 )
3801
3802 (define_insn_and_split "*arm_umaxsi3"
3803 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3804 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3805 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3806 (clobber (reg:CC CC_REGNUM))]
3807 "TARGET_ARM"
3808 "#"
3809 ; cmp\\t%1, %2\;movcc\\t%0, %2
3810 ; cmp\\t%1, %2\;movcs\\t%0, %1
3811 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3812 "TARGET_ARM"
3813 [(set (reg:CC CC_REGNUM)
3814 (compare:CC (match_dup 1) (match_dup 2)))
3815 (set (match_dup 0)
3816 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3817 (match_dup 1)
3818 (match_dup 2)))]
3819 ""
3820 [(set_attr "conds" "clob")
3821 (set_attr "length" "8,8,12")
3822 (set_attr "type" "store_4")]
3823 )
3824
3825 (define_expand "uminsi3"
3826 [(parallel [
3827 (set (match_operand:SI 0 "s_register_operand" "")
3828 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3829 (match_operand:SI 2 "arm_rhs_operand" "")))
3830 (clobber (reg:CC CC_REGNUM))])]
3831 "TARGET_32BIT"
3832 ""
3833 )
3834
3835 (define_insn_and_split "*arm_uminsi3"
3836 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3837 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3838 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3839 (clobber (reg:CC CC_REGNUM))]
3840 "TARGET_ARM"
3841 "#"
3842 ; cmp\\t%1, %2\;movcs\\t%0, %2
3843 ; cmp\\t%1, %2\;movcc\\t%0, %1
3844 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3845 "TARGET_ARM"
3846 [(set (reg:CC CC_REGNUM)
3847 (compare:CC (match_dup 1) (match_dup 2)))
3848 (set (match_dup 0)
3849 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3850 (match_dup 1)
3851 (match_dup 2)))]
3852 ""
3853 [(set_attr "conds" "clob")
3854 (set_attr "length" "8,8,12")
3855 (set_attr "type" "store_4")]
3856 )
3857
3858 (define_insn "*store_minmaxsi"
3859 [(set (match_operand:SI 0 "memory_operand" "=m")
3860 (match_operator:SI 3 "minmax_operator"
3861 [(match_operand:SI 1 "s_register_operand" "r")
3862 (match_operand:SI 2 "s_register_operand" "r")]))
3863 (clobber (reg:CC CC_REGNUM))]
3864 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3865 "*
3866 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3867 operands[1], operands[2]);
3868 output_asm_insn (\"cmp\\t%1, %2\", operands);
3869 if (TARGET_THUMB2)
3870 output_asm_insn (\"ite\t%d3\", operands);
3871 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3872 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3873 return \"\";
3874 "
3875 [(set_attr "conds" "clob")
3876 (set (attr "length")
3877 (if_then_else (eq_attr "is_thumb" "yes")
3878 (const_int 14)
3879 (const_int 12)))
3880 (set_attr "type" "store_4")]
3881 )
3882
3883 ; Reject the frame pointer in operand[1], since reloading this after
3884 ; it has been eliminated can cause carnage.
3885 (define_insn "*minmax_arithsi"
3886 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3887 (match_operator:SI 4 "shiftable_operator"
3888 [(match_operator:SI 5 "minmax_operator"
3889 [(match_operand:SI 2 "s_register_operand" "r,r")
3890 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3891 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3892 (clobber (reg:CC CC_REGNUM))]
3893 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3894 "*
3895 {
3896 enum rtx_code code = GET_CODE (operands[4]);
3897 bool need_else;
3898
3899 if (which_alternative != 0 || operands[3] != const0_rtx
3900 || (code != PLUS && code != IOR && code != XOR))
3901 need_else = true;
3902 else
3903 need_else = false;
3904
3905 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3906 operands[2], operands[3]);
3907 output_asm_insn (\"cmp\\t%2, %3\", operands);
3908 if (TARGET_THUMB2)
3909 {
3910 if (need_else)
3911 output_asm_insn (\"ite\\t%d5\", operands);
3912 else
3913 output_asm_insn (\"it\\t%d5\", operands);
3914 }
3915 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3916 if (need_else)
3917 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3918 return \"\";
3919 }"
3920 [(set_attr "conds" "clob")
3921 (set (attr "length")
3922 (if_then_else (eq_attr "is_thumb" "yes")
3923 (const_int 14)
3924 (const_int 12)))
3925 (set_attr "type" "multiple")]
3926 )
3927
3928 ; Reject the frame pointer in operand[1], since reloading this after
3929 ; it has been eliminated can cause carnage.
3930 (define_insn_and_split "*minmax_arithsi_non_canon"
3931 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3932 (minus:SI
3933 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3934 (match_operator:SI 4 "minmax_operator"
3935 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3936 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3937 (clobber (reg:CC CC_REGNUM))]
3938 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3939 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3940 "#"
3941 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3942 [(set (reg:CC CC_REGNUM)
3943 (compare:CC (match_dup 2) (match_dup 3)))
3944
3945 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3946 (set (match_dup 0)
3947 (minus:SI (match_dup 1)
3948 (match_dup 2))))
3949 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3950 (set (match_dup 0)
3951 (match_dup 6)))]
3952 {
3953 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3954 operands[2], operands[3]);
3955 enum rtx_code rc = minmax_code (operands[4]);
3956 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3957 operands[2], operands[3]);
3958
3959 if (mode == CCFPmode || mode == CCFPEmode)
3960 rc = reverse_condition_maybe_unordered (rc);
3961 else
3962 rc = reverse_condition (rc);
3963 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3964 if (CONST_INT_P (operands[3]))
3965 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3966 else
3967 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3968 }
3969 [(set_attr "conds" "clob")
3970 (set (attr "length")
3971 (if_then_else (eq_attr "is_thumb" "yes")
3972 (const_int 14)
3973 (const_int 12)))
3974 (set_attr "type" "multiple")]
3975 )
3976
3977 (define_code_iterator SAT [smin smax])
3978 (define_code_iterator SATrev [smin smax])
3979 (define_code_attr SATlo [(smin "1") (smax "2")])
3980 (define_code_attr SAThi [(smin "2") (smax "1")])
3981
3982 (define_insn "*satsi_<SAT:code>"
3983 [(set (match_operand:SI 0 "s_register_operand" "=r")
3984 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3985 (match_operand:SI 1 "const_int_operand" "i"))
3986 (match_operand:SI 2 "const_int_operand" "i")))]
3987 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3988 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3989 {
3990 int mask;
3991 bool signed_sat;
3992 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3993 &mask, &signed_sat))
3994 gcc_unreachable ();
3995
3996 operands[1] = GEN_INT (mask);
3997 if (signed_sat)
3998 return "ssat%?\t%0, %1, %3";
3999 else
4000 return "usat%?\t%0, %1, %3";
4001 }
4002 [(set_attr "predicable" "yes")
4003 (set_attr "predicable_short_it" "no")
4004 (set_attr "type" "alus_imm")]
4005 )
4006
4007 (define_insn "*satsi_<SAT:code>_shift"
4008 [(set (match_operand:SI 0 "s_register_operand" "=r")
4009 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
4010 [(match_operand:SI 4 "s_register_operand" "r")
4011 (match_operand:SI 5 "const_int_operand" "i")])
4012 (match_operand:SI 1 "const_int_operand" "i"))
4013 (match_operand:SI 2 "const_int_operand" "i")))]
4014 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
4015 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
4016 {
4017 int mask;
4018 bool signed_sat;
4019 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
4020 &mask, &signed_sat))
4021 gcc_unreachable ();
4022
4023 operands[1] = GEN_INT (mask);
4024 if (signed_sat)
4025 return "ssat%?\t%0, %1, %4%S3";
4026 else
4027 return "usat%?\t%0, %1, %4%S3";
4028 }
4029 [(set_attr "predicable" "yes")
4030 (set_attr "predicable_short_it" "no")
4031 (set_attr "shift" "3")
4032 (set_attr "type" "logic_shift_reg")])
4033 \f
4034 ;; Shift and rotation insns
4035
4036 (define_expand "ashldi3"
4037 [(set (match_operand:DI 0 "s_register_operand" "")
4038 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
4039 (match_operand:SI 2 "general_operand" "")))]
4040 "TARGET_32BIT"
4041 "
4042 if (TARGET_NEON)
4043 {
4044 /* Delay the decision whether to use NEON or core-regs until
4045 register allocation. */
4046 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
4047 DONE;
4048 }
4049 else
4050 {
4051 /* Only the NEON case can handle in-memory shift counts. */
4052 if (!reg_or_int_operand (operands[2], SImode))
4053 operands[2] = force_reg (SImode, operands[2]);
4054 }
4055
4056 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4057 ; /* No special preparation statements; expand pattern as above. */
4058 else
4059 {
4060 rtx scratch1, scratch2;
4061
4062 /* Ideally we should use iwmmxt here if we could know that operands[1]
4063 ends up already living in an iwmmxt register. Otherwise it's
4064 cheaper to have the alternate code being generated than moving
4065 values to iwmmxt regs and back. */
4066
4067 /* Expand operation using core-registers.
4068 'FAIL' would achieve the same thing, but this is a bit smarter. */
4069 scratch1 = gen_reg_rtx (SImode);
4070 scratch2 = gen_reg_rtx (SImode);
4071 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4072 operands[2], scratch1, scratch2);
4073 DONE;
4074 }
4075 "
4076 )
4077
4078 (define_expand "ashlsi3"
4079 [(set (match_operand:SI 0 "s_register_operand" "")
4080 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4081 (match_operand:SI 2 "arm_rhs_operand" "")))]
4082 "TARGET_EITHER"
4083 "
4084 if (CONST_INT_P (operands[2])
4085 && (UINTVAL (operands[2])) > 31)
4086 {
4087 emit_insn (gen_movsi (operands[0], const0_rtx));
4088 DONE;
4089 }
4090 "
4091 )
4092
4093 (define_expand "ashrdi3"
4094 [(set (match_operand:DI 0 "s_register_operand" "")
4095 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4096 (match_operand:SI 2 "reg_or_int_operand" "")))]
4097 "TARGET_32BIT"
4098 "
4099 if (TARGET_NEON)
4100 {
4101 /* Delay the decision whether to use NEON or core-regs until
4102 register allocation. */
4103 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4104 DONE;
4105 }
4106
4107 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4108 ; /* No special preparation statements; expand pattern as above. */
4109 else
4110 {
4111 rtx scratch1, scratch2;
4112
4113 /* Ideally we should use iwmmxt here if we could know that operands[1]
4114 ends up already living in an iwmmxt register. Otherwise it's
4115 cheaper to have the alternate code being generated than moving
4116 values to iwmmxt regs and back. */
4117
4118 /* Expand operation using core-registers.
4119 'FAIL' would achieve the same thing, but this is a bit smarter. */
4120 scratch1 = gen_reg_rtx (SImode);
4121 scratch2 = gen_reg_rtx (SImode);
4122 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4123 operands[2], scratch1, scratch2);
4124 DONE;
4125 }
4126 "
4127 )
4128
4129 (define_expand "ashrsi3"
4130 [(set (match_operand:SI 0 "s_register_operand" "")
4131 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4132 (match_operand:SI 2 "arm_rhs_operand" "")))]
4133 "TARGET_EITHER"
4134 "
4135 if (CONST_INT_P (operands[2])
4136 && UINTVAL (operands[2]) > 31)
4137 operands[2] = GEN_INT (31);
4138 "
4139 )
4140
4141 (define_expand "lshrdi3"
4142 [(set (match_operand:DI 0 "s_register_operand" "")
4143 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4144 (match_operand:SI 2 "reg_or_int_operand" "")))]
4145 "TARGET_32BIT"
4146 "
4147 if (TARGET_NEON)
4148 {
4149 /* Delay the decision whether to use NEON or core-regs until
4150 register allocation. */
4151 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4152 DONE;
4153 }
4154
4155 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4156 ; /* No special preparation statements; expand pattern as above. */
4157 else
4158 {
4159 rtx scratch1, scratch2;
4160
4161 /* Ideally we should use iwmmxt here if we could know that operands[1]
4162 ends up already living in an iwmmxt register. Otherwise it's
4163 cheaper to have the alternate code being generated than moving
4164 values to iwmmxt regs and back. */
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_expand "lshrsi3"
4178 [(set (match_operand:SI 0 "s_register_operand" "")
4179 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4180 (match_operand:SI 2 "arm_rhs_operand" "")))]
4181 "TARGET_EITHER"
4182 "
4183 if (CONST_INT_P (operands[2])
4184 && (UINTVAL (operands[2])) > 31)
4185 {
4186 emit_insn (gen_movsi (operands[0], const0_rtx));
4187 DONE;
4188 }
4189 "
4190 )
4191
4192 (define_expand "rotlsi3"
4193 [(set (match_operand:SI 0 "s_register_operand" "")
4194 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4195 (match_operand:SI 2 "reg_or_int_operand" "")))]
4196 "TARGET_32BIT"
4197 "
4198 if (CONST_INT_P (operands[2]))
4199 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4200 else
4201 {
4202 rtx reg = gen_reg_rtx (SImode);
4203 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4204 operands[2] = reg;
4205 }
4206 "
4207 )
4208
4209 (define_expand "rotrsi3"
4210 [(set (match_operand:SI 0 "s_register_operand" "")
4211 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4212 (match_operand:SI 2 "arm_rhs_operand" "")))]
4213 "TARGET_EITHER"
4214 "
4215 if (TARGET_32BIT)
4216 {
4217 if (CONST_INT_P (operands[2])
4218 && UINTVAL (operands[2]) > 31)
4219 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4220 }
4221 else /* TARGET_THUMB1 */
4222 {
4223 if (CONST_INT_P (operands [2]))
4224 operands [2] = force_reg (SImode, operands[2]);
4225 }
4226 "
4227 )
4228
4229 (define_insn "*arm_shiftsi3"
4230 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4231 (match_operator:SI 3 "shift_operator"
4232 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4233 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4234 "TARGET_32BIT"
4235 "* return arm_output_shift(operands, 0);"
4236 [(set_attr "predicable" "yes")
4237 (set_attr "arch" "t2,t2,*,*")
4238 (set_attr "predicable_short_it" "yes,yes,no,no")
4239 (set_attr "length" "4")
4240 (set_attr "shift" "1")
4241 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4242 )
4243
4244 (define_insn "*shiftsi3_compare0"
4245 [(set (reg:CC_NOOV CC_REGNUM)
4246 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4247 [(match_operand:SI 1 "s_register_operand" "r,r")
4248 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4249 (const_int 0)))
4250 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4251 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4252 "TARGET_32BIT"
4253 "* return arm_output_shift(operands, 1);"
4254 [(set_attr "conds" "set")
4255 (set_attr "shift" "1")
4256 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4257 )
4258
4259 (define_insn "*shiftsi3_compare0_scratch"
4260 [(set (reg:CC_NOOV CC_REGNUM)
4261 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4262 [(match_operand:SI 1 "s_register_operand" "r,r")
4263 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4264 (const_int 0)))
4265 (clobber (match_scratch:SI 0 "=r,r"))]
4266 "TARGET_32BIT"
4267 "* return arm_output_shift(operands, 1);"
4268 [(set_attr "conds" "set")
4269 (set_attr "shift" "1")
4270 (set_attr "type" "shift_imm,shift_reg")]
4271 )
4272
4273 (define_insn "*not_shiftsi"
4274 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4275 (not:SI (match_operator:SI 3 "shift_operator"
4276 [(match_operand:SI 1 "s_register_operand" "r,r")
4277 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4278 "TARGET_32BIT"
4279 "mvn%?\\t%0, %1%S3"
4280 [(set_attr "predicable" "yes")
4281 (set_attr "predicable_short_it" "no")
4282 (set_attr "shift" "1")
4283 (set_attr "arch" "32,a")
4284 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4285
4286 (define_insn "*not_shiftsi_compare0"
4287 [(set (reg:CC_NOOV CC_REGNUM)
4288 (compare:CC_NOOV
4289 (not:SI (match_operator:SI 3 "shift_operator"
4290 [(match_operand:SI 1 "s_register_operand" "r,r")
4291 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4292 (const_int 0)))
4293 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4294 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4295 "TARGET_32BIT"
4296 "mvns%?\\t%0, %1%S3"
4297 [(set_attr "conds" "set")
4298 (set_attr "shift" "1")
4299 (set_attr "arch" "32,a")
4300 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4301
4302 (define_insn "*not_shiftsi_compare0_scratch"
4303 [(set (reg:CC_NOOV CC_REGNUM)
4304 (compare:CC_NOOV
4305 (not:SI (match_operator:SI 3 "shift_operator"
4306 [(match_operand:SI 1 "s_register_operand" "r,r")
4307 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4308 (const_int 0)))
4309 (clobber (match_scratch:SI 0 "=r,r"))]
4310 "TARGET_32BIT"
4311 "mvns%?\\t%0, %1%S3"
4312 [(set_attr "conds" "set")
4313 (set_attr "shift" "1")
4314 (set_attr "arch" "32,a")
4315 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4316
4317 ;; We don't really have extzv, but defining this using shifts helps
4318 ;; to reduce register pressure later on.
4319
4320 (define_expand "extzv"
4321 [(set (match_operand 0 "s_register_operand" "")
4322 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4323 (match_operand 2 "const_int_operand" "")
4324 (match_operand 3 "const_int_operand" "")))]
4325 "TARGET_THUMB1 || arm_arch_thumb2"
4326 "
4327 {
4328 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4329 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4330
4331 if (arm_arch_thumb2)
4332 {
4333 HOST_WIDE_INT width = INTVAL (operands[2]);
4334 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4335
4336 if (unaligned_access && MEM_P (operands[1])
4337 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4338 {
4339 rtx base_addr;
4340
4341 if (BYTES_BIG_ENDIAN)
4342 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4343 - bitpos;
4344
4345 if (width == 32)
4346 {
4347 base_addr = adjust_address (operands[1], SImode,
4348 bitpos / BITS_PER_UNIT);
4349 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4350 }
4351 else
4352 {
4353 rtx dest = operands[0];
4354 rtx tmp = gen_reg_rtx (SImode);
4355
4356 /* We may get a paradoxical subreg here. Strip it off. */
4357 if (GET_CODE (dest) == SUBREG
4358 && GET_MODE (dest) == SImode
4359 && GET_MODE (SUBREG_REG (dest)) == HImode)
4360 dest = SUBREG_REG (dest);
4361
4362 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4363 FAIL;
4364
4365 base_addr = adjust_address (operands[1], HImode,
4366 bitpos / BITS_PER_UNIT);
4367 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4368 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4369 }
4370 DONE;
4371 }
4372 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4373 {
4374 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4375 operands[3]));
4376 DONE;
4377 }
4378 else
4379 FAIL;
4380 }
4381
4382 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4383 FAIL;
4384
4385 operands[3] = GEN_INT (rshift);
4386
4387 if (lshift == 0)
4388 {
4389 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4390 DONE;
4391 }
4392
4393 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4394 operands[3], gen_reg_rtx (SImode)));
4395 DONE;
4396 }"
4397 )
4398
4399 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4400
4401 (define_expand "extzv_t1"
4402 [(set (match_operand:SI 4 "s_register_operand" "")
4403 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4404 (match_operand:SI 2 "const_int_operand" "")))
4405 (set (match_operand:SI 0 "s_register_operand" "")
4406 (lshiftrt:SI (match_dup 4)
4407 (match_operand:SI 3 "const_int_operand" "")))]
4408 "TARGET_THUMB1"
4409 "")
4410
4411 (define_expand "extv"
4412 [(set (match_operand 0 "s_register_operand" "")
4413 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4414 (match_operand 2 "const_int_operand" "")
4415 (match_operand 3 "const_int_operand" "")))]
4416 "arm_arch_thumb2"
4417 {
4418 HOST_WIDE_INT width = INTVAL (operands[2]);
4419 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4420
4421 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4422 && (bitpos % BITS_PER_UNIT) == 0)
4423 {
4424 rtx base_addr;
4425
4426 if (BYTES_BIG_ENDIAN)
4427 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4428
4429 if (width == 32)
4430 {
4431 base_addr = adjust_address (operands[1], SImode,
4432 bitpos / BITS_PER_UNIT);
4433 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4434 }
4435 else
4436 {
4437 rtx dest = operands[0];
4438 rtx tmp = gen_reg_rtx (SImode);
4439
4440 /* We may get a paradoxical subreg here. Strip it off. */
4441 if (GET_CODE (dest) == SUBREG
4442 && GET_MODE (dest) == SImode
4443 && GET_MODE (SUBREG_REG (dest)) == HImode)
4444 dest = SUBREG_REG (dest);
4445
4446 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4447 FAIL;
4448
4449 base_addr = adjust_address (operands[1], HImode,
4450 bitpos / BITS_PER_UNIT);
4451 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4452 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4453 }
4454
4455 DONE;
4456 }
4457 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4458 FAIL;
4459 else if (GET_MODE (operands[0]) == SImode
4460 && GET_MODE (operands[1]) == SImode)
4461 {
4462 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4463 operands[3]));
4464 DONE;
4465 }
4466
4467 FAIL;
4468 })
4469
4470 ; Helper to expand register forms of extv with the proper modes.
4471
4472 (define_expand "extv_regsi"
4473 [(set (match_operand:SI 0 "s_register_operand" "")
4474 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4475 (match_operand 2 "const_int_operand" "")
4476 (match_operand 3 "const_int_operand" "")))]
4477 ""
4478 {
4479 })
4480
4481 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4482
4483 (define_insn "unaligned_loadsi"
4484 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4485 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4486 UNSPEC_UNALIGNED_LOAD))]
4487 "unaligned_access"
4488 "ldr%?\t%0, %1\t@ unaligned"
4489 [(set_attr "arch" "t2,any")
4490 (set_attr "length" "2,4")
4491 (set_attr "predicable" "yes")
4492 (set_attr "predicable_short_it" "yes,no")
4493 (set_attr "type" "load_4")])
4494
4495 (define_insn "unaligned_loadhis"
4496 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4497 (sign_extend:SI
4498 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4499 UNSPEC_UNALIGNED_LOAD)))]
4500 "unaligned_access"
4501 "ldrsh%?\t%0, %1\t@ unaligned"
4502 [(set_attr "arch" "t2,any")
4503 (set_attr "length" "2,4")
4504 (set_attr "predicable" "yes")
4505 (set_attr "predicable_short_it" "yes,no")
4506 (set_attr "type" "load_byte")])
4507
4508 (define_insn "unaligned_loadhiu"
4509 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4510 (zero_extend:SI
4511 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4512 UNSPEC_UNALIGNED_LOAD)))]
4513 "unaligned_access"
4514 "ldrh%?\t%0, %1\t@ unaligned"
4515 [(set_attr "arch" "t2,any")
4516 (set_attr "length" "2,4")
4517 (set_attr "predicable" "yes")
4518 (set_attr "predicable_short_it" "yes,no")
4519 (set_attr "type" "load_byte")])
4520
4521 (define_insn "unaligned_storesi"
4522 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4523 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4524 UNSPEC_UNALIGNED_STORE))]
4525 "unaligned_access"
4526 "str%?\t%1, %0\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" "store_4")])
4532
4533 (define_insn "unaligned_storehi"
4534 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4535 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4536 UNSPEC_UNALIGNED_STORE))]
4537 "unaligned_access"
4538 "strh%?\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" "store_4")])
4544
4545
4546 (define_insn "*extv_reg"
4547 [(set (match_operand:SI 0 "s_register_operand" "=r")
4548 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4549 (match_operand:SI 2 "const_int_operand" "n")
4550 (match_operand:SI 3 "const_int_operand" "n")))]
4551 "arm_arch_thumb2
4552 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4553 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4554 "sbfx%?\t%0, %1, %3, %2"
4555 [(set_attr "length" "4")
4556 (set_attr "predicable" "yes")
4557 (set_attr "predicable_short_it" "no")
4558 (set_attr "type" "bfm")]
4559 )
4560
4561 (define_insn "extzv_t2"
4562 [(set (match_operand:SI 0 "s_register_operand" "=r")
4563 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4564 (match_operand:SI 2 "const_int_operand" "n")
4565 (match_operand:SI 3 "const_int_operand" "n")))]
4566 "arm_arch_thumb2
4567 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4568 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4569 "ubfx%?\t%0, %1, %3, %2"
4570 [(set_attr "length" "4")
4571 (set_attr "predicable" "yes")
4572 (set_attr "predicable_short_it" "no")
4573 (set_attr "type" "bfm")]
4574 )
4575
4576
4577 ;; Division instructions
4578 (define_insn "divsi3"
4579 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4580 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4581 (match_operand:SI 2 "s_register_operand" "r,r")))]
4582 "TARGET_IDIV"
4583 "@
4584 sdiv%?\t%0, %1, %2
4585 sdiv\t%0, %1, %2"
4586 [(set_attr "arch" "32,v8mb")
4587 (set_attr "predicable" "yes")
4588 (set_attr "predicable_short_it" "no")
4589 (set_attr "type" "sdiv")]
4590 )
4591
4592 (define_insn "udivsi3"
4593 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4594 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4595 (match_operand:SI 2 "s_register_operand" "r,r")))]
4596 "TARGET_IDIV"
4597 "@
4598 udiv%?\t%0, %1, %2
4599 udiv\t%0, %1, %2"
4600 [(set_attr "arch" "32,v8mb")
4601 (set_attr "predicable" "yes")
4602 (set_attr "predicable_short_it" "no")
4603 (set_attr "type" "udiv")]
4604 )
4605
4606 \f
4607 ;; Unary arithmetic insns
4608
4609 (define_expand "negvsi3"
4610 [(match_operand:SI 0 "register_operand")
4611 (match_operand:SI 1 "register_operand")
4612 (match_operand 2 "")]
4613 "TARGET_32BIT"
4614 {
4615 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4616 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4617
4618 DONE;
4619 })
4620
4621 (define_expand "negvdi3"
4622 [(match_operand:DI 0 "register_operand")
4623 (match_operand:DI 1 "register_operand")
4624 (match_operand 2 "")]
4625 "TARGET_ARM"
4626 {
4627 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4628 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4629
4630 DONE;
4631 })
4632
4633
4634 (define_insn_and_split "negdi2_compare"
4635 [(set (reg:CC CC_REGNUM)
4636 (compare:CC
4637 (const_int 0)
4638 (match_operand:DI 1 "register_operand" "0,r")))
4639 (set (match_operand:DI 0 "register_operand" "=r,&r")
4640 (minus:DI (const_int 0) (match_dup 1)))]
4641 "TARGET_ARM"
4642 "#"
4643 "&& reload_completed"
4644 [(parallel [(set (reg:CC CC_REGNUM)
4645 (compare:CC (const_int 0) (match_dup 1)))
4646 (set (match_dup 0) (minus:SI (const_int 0)
4647 (match_dup 1)))])
4648 (parallel [(set (reg:CC CC_REGNUM)
4649 (compare:CC (const_int 0) (match_dup 3)))
4650 (set (match_dup 2)
4651 (minus:SI
4652 (minus:SI (const_int 0) (match_dup 3))
4653 (ltu:SI (reg:CC_C CC_REGNUM)
4654 (const_int 0))))])]
4655 {
4656 operands[2] = gen_highpart (SImode, operands[0]);
4657 operands[0] = gen_lowpart (SImode, operands[0]);
4658 operands[3] = gen_highpart (SImode, operands[1]);
4659 operands[1] = gen_lowpart (SImode, operands[1]);
4660 }
4661 [(set_attr "conds" "set")
4662 (set_attr "length" "8")
4663 (set_attr "type" "multiple")]
4664 )
4665
4666 (define_expand "negdi2"
4667 [(parallel
4668 [(set (match_operand:DI 0 "s_register_operand" "")
4669 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4670 (clobber (reg:CC CC_REGNUM))])]
4671 "TARGET_EITHER"
4672 {
4673 if (TARGET_NEON)
4674 {
4675 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4676 DONE;
4677 }
4678 }
4679 )
4680
4681 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4682 ;; The first alternative allows the common case of a *full* overlap.
4683 (define_insn_and_split "*negdi2_insn"
4684 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4685 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4686 (clobber (reg:CC CC_REGNUM))]
4687 "TARGET_32BIT"
4688 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4689 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4690 "&& reload_completed"
4691 [(parallel [(set (reg:CC CC_REGNUM)
4692 (compare:CC (const_int 0) (match_dup 1)))
4693 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4694 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4695 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4696 {
4697 operands[2] = gen_highpart (SImode, operands[0]);
4698 operands[0] = gen_lowpart (SImode, operands[0]);
4699 operands[3] = gen_highpart (SImode, operands[1]);
4700 operands[1] = gen_lowpart (SImode, operands[1]);
4701 }
4702 [(set_attr "conds" "clob")
4703 (set_attr "length" "8")
4704 (set_attr "type" "multiple")]
4705 )
4706
4707 (define_insn "*negsi2_carryin_compare"
4708 [(set (reg:CC CC_REGNUM)
4709 (compare:CC (const_int 0)
4710 (match_operand:SI 1 "s_register_operand" "r")))
4711 (set (match_operand:SI 0 "s_register_operand" "=r")
4712 (minus:SI (minus:SI (const_int 0)
4713 (match_dup 1))
4714 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4715 "TARGET_ARM"
4716 "rscs\\t%0, %1, #0"
4717 [(set_attr "conds" "set")
4718 (set_attr "type" "alus_imm")]
4719 )
4720
4721 (define_expand "negsi2"
4722 [(set (match_operand:SI 0 "s_register_operand" "")
4723 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4724 "TARGET_EITHER"
4725 ""
4726 )
4727
4728 (define_insn "*arm_negsi2"
4729 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4730 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4731 "TARGET_32BIT"
4732 "rsb%?\\t%0, %1, #0"
4733 [(set_attr "predicable" "yes")
4734 (set_attr "predicable_short_it" "yes,no")
4735 (set_attr "arch" "t2,*")
4736 (set_attr "length" "4")
4737 (set_attr "type" "alu_sreg")]
4738 )
4739
4740 (define_expand "negsf2"
4741 [(set (match_operand:SF 0 "s_register_operand" "")
4742 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4743 "TARGET_32BIT && TARGET_HARD_FLOAT"
4744 ""
4745 )
4746
4747 (define_expand "negdf2"
4748 [(set (match_operand:DF 0 "s_register_operand" "")
4749 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4750 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4751 "")
4752
4753 (define_insn_and_split "*zextendsidi_negsi"
4754 [(set (match_operand:DI 0 "s_register_operand" "=r")
4755 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4756 "TARGET_32BIT"
4757 "#"
4758 ""
4759 [(set (match_dup 2)
4760 (neg:SI (match_dup 1)))
4761 (set (match_dup 3)
4762 (const_int 0))]
4763 {
4764 operands[2] = gen_lowpart (SImode, operands[0]);
4765 operands[3] = gen_highpart (SImode, operands[0]);
4766 }
4767 [(set_attr "length" "8")
4768 (set_attr "type" "multiple")]
4769 )
4770
4771 ;; Negate an extended 32-bit value.
4772 (define_insn_and_split "*negdi_extendsidi"
4773 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4774 (neg:DI (sign_extend:DI
4775 (match_operand:SI 1 "s_register_operand" "l,r"))))
4776 (clobber (reg:CC CC_REGNUM))]
4777 "TARGET_32BIT"
4778 "#"
4779 "&& reload_completed"
4780 [(const_int 0)]
4781 {
4782 rtx low = gen_lowpart (SImode, operands[0]);
4783 rtx high = gen_highpart (SImode, operands[0]);
4784
4785 if (reg_overlap_mentioned_p (low, operands[1]))
4786 {
4787 /* Input overlaps the low word of the output. Use:
4788 asr Rhi, Rin, #31
4789 rsbs Rlo, Rin, #0
4790 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4791 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4792
4793 emit_insn (gen_rtx_SET (high,
4794 gen_rtx_ASHIFTRT (SImode, operands[1],
4795 GEN_INT (31))));
4796
4797 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4798 if (TARGET_ARM)
4799 emit_insn (gen_rtx_SET (high,
4800 gen_rtx_MINUS (SImode,
4801 gen_rtx_MINUS (SImode,
4802 const0_rtx,
4803 high),
4804 gen_rtx_LTU (SImode,
4805 cc_reg,
4806 const0_rtx))));
4807 else
4808 {
4809 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4810 emit_insn (gen_rtx_SET (high,
4811 gen_rtx_MINUS (SImode,
4812 gen_rtx_MINUS (SImode,
4813 high,
4814 two_x),
4815 gen_rtx_LTU (SImode,
4816 cc_reg,
4817 const0_rtx))));
4818 }
4819 }
4820 else
4821 {
4822 /* No overlap, or overlap on high word. Use:
4823 rsb Rlo, Rin, #0
4824 bic Rhi, Rlo, Rin
4825 asr Rhi, Rhi, #31
4826 Flags not needed for this sequence. */
4827 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4828 emit_insn (gen_rtx_SET (high,
4829 gen_rtx_AND (SImode,
4830 gen_rtx_NOT (SImode, operands[1]),
4831 low)));
4832 emit_insn (gen_rtx_SET (high,
4833 gen_rtx_ASHIFTRT (SImode, high,
4834 GEN_INT (31))));
4835 }
4836 DONE;
4837 }
4838 [(set_attr "length" "12")
4839 (set_attr "arch" "t2,*")
4840 (set_attr "type" "multiple")]
4841 )
4842
4843 (define_insn_and_split "*negdi_zero_extendsidi"
4844 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4845 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4846 (clobber (reg:CC CC_REGNUM))]
4847 "TARGET_32BIT"
4848 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4849 ;; Don't care what register is input to sbc,
4850 ;; since we just need to propagate the carry.
4851 "&& reload_completed"
4852 [(parallel [(set (reg:CC CC_REGNUM)
4853 (compare:CC (const_int 0) (match_dup 1)))
4854 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4855 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4856 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4857 {
4858 operands[2] = gen_highpart (SImode, operands[0]);
4859 operands[0] = gen_lowpart (SImode, operands[0]);
4860 }
4861 [(set_attr "conds" "clob")
4862 (set_attr "length" "8")
4863 (set_attr "type" "multiple")] ;; length in thumb is 4
4864 )
4865
4866 ;; abssi2 doesn't really clobber the condition codes if a different register
4867 ;; is being set. To keep things simple, assume during rtl manipulations that
4868 ;; it does, but tell the final scan operator the truth. Similarly for
4869 ;; (neg (abs...))
4870
4871 (define_expand "abssi2"
4872 [(parallel
4873 [(set (match_operand:SI 0 "s_register_operand" "")
4874 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4875 (clobber (match_dup 2))])]
4876 "TARGET_EITHER"
4877 "
4878 if (TARGET_THUMB1)
4879 operands[2] = gen_rtx_SCRATCH (SImode);
4880 else
4881 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4882 ")
4883
4884 (define_insn_and_split "*arm_abssi2"
4885 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4886 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4887 (clobber (reg:CC CC_REGNUM))]
4888 "TARGET_ARM"
4889 "#"
4890 "&& reload_completed"
4891 [(const_int 0)]
4892 {
4893 /* if (which_alternative == 0) */
4894 if (REGNO(operands[0]) == REGNO(operands[1]))
4895 {
4896 /* Emit the pattern:
4897 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4898 [(set (reg:CC CC_REGNUM)
4899 (compare:CC (match_dup 0) (const_int 0)))
4900 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4901 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4902 */
4903 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4904 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4905 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4906 (gen_rtx_LT (SImode,
4907 gen_rtx_REG (CCmode, CC_REGNUM),
4908 const0_rtx)),
4909 (gen_rtx_SET (operands[0],
4910 (gen_rtx_MINUS (SImode,
4911 const0_rtx,
4912 operands[1]))))));
4913 DONE;
4914 }
4915 else
4916 {
4917 /* Emit the pattern:
4918 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4919 [(set (match_dup 0)
4920 (xor:SI (match_dup 1)
4921 (ashiftrt:SI (match_dup 1) (const_int 31))))
4922 (set (match_dup 0)
4923 (minus:SI (match_dup 0)
4924 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4925 */
4926 emit_insn (gen_rtx_SET (operands[0],
4927 gen_rtx_XOR (SImode,
4928 gen_rtx_ASHIFTRT (SImode,
4929 operands[1],
4930 GEN_INT (31)),
4931 operands[1])));
4932 emit_insn (gen_rtx_SET (operands[0],
4933 gen_rtx_MINUS (SImode,
4934 operands[0],
4935 gen_rtx_ASHIFTRT (SImode,
4936 operands[1],
4937 GEN_INT (31)))));
4938 DONE;
4939 }
4940 }
4941 [(set_attr "conds" "clob,*")
4942 (set_attr "shift" "1")
4943 (set_attr "predicable" "no, yes")
4944 (set_attr "length" "8")
4945 (set_attr "type" "multiple")]
4946 )
4947
4948 (define_insn_and_split "*arm_neg_abssi2"
4949 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4950 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4951 (clobber (reg:CC CC_REGNUM))]
4952 "TARGET_ARM"
4953 "#"
4954 "&& reload_completed"
4955 [(const_int 0)]
4956 {
4957 /* if (which_alternative == 0) */
4958 if (REGNO (operands[0]) == REGNO (operands[1]))
4959 {
4960 /* Emit the pattern:
4961 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4962 */
4963 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4964 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4965 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4966 gen_rtx_GT (SImode,
4967 gen_rtx_REG (CCmode, CC_REGNUM),
4968 const0_rtx),
4969 gen_rtx_SET (operands[0],
4970 (gen_rtx_MINUS (SImode,
4971 const0_rtx,
4972 operands[1])))));
4973 }
4974 else
4975 {
4976 /* Emit the pattern:
4977 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4978 */
4979 emit_insn (gen_rtx_SET (operands[0],
4980 gen_rtx_XOR (SImode,
4981 gen_rtx_ASHIFTRT (SImode,
4982 operands[1],
4983 GEN_INT (31)),
4984 operands[1])));
4985 emit_insn (gen_rtx_SET (operands[0],
4986 gen_rtx_MINUS (SImode,
4987 gen_rtx_ASHIFTRT (SImode,
4988 operands[1],
4989 GEN_INT (31)),
4990 operands[0])));
4991 }
4992 DONE;
4993 }
4994 [(set_attr "conds" "clob,*")
4995 (set_attr "shift" "1")
4996 (set_attr "predicable" "no, yes")
4997 (set_attr "length" "8")
4998 (set_attr "type" "multiple")]
4999 )
5000
5001 (define_expand "abssf2"
5002 [(set (match_operand:SF 0 "s_register_operand" "")
5003 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5004 "TARGET_32BIT && TARGET_HARD_FLOAT"
5005 "")
5006
5007 (define_expand "absdf2"
5008 [(set (match_operand:DF 0 "s_register_operand" "")
5009 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5010 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5011 "")
5012
5013 (define_expand "sqrtsf2"
5014 [(set (match_operand:SF 0 "s_register_operand" "")
5015 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5016 "TARGET_32BIT && TARGET_HARD_FLOAT"
5017 "")
5018
5019 (define_expand "sqrtdf2"
5020 [(set (match_operand:DF 0 "s_register_operand" "")
5021 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5022 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5023 "")
5024
5025 (define_expand "one_cmpldi2"
5026 [(set (match_operand:DI 0 "s_register_operand" "")
5027 (not:DI (match_operand:DI 1 "s_register_operand" "")))]
5028 "TARGET_32BIT"
5029 "
5030 if (!TARGET_NEON && !TARGET_IWMMXT)
5031 {
5032 rtx low = simplify_gen_unary (NOT, SImode,
5033 gen_lowpart (SImode, operands[1]),
5034 SImode);
5035 rtx high = simplify_gen_unary (NOT, SImode,
5036 gen_highpart_mode (SImode, DImode,
5037 operands[1]),
5038 SImode);
5039
5040 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5041 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5042
5043 DONE;
5044 }
5045 /* Otherwise expand pattern as above. */
5046 "
5047 )
5048
5049 (define_insn_and_split "*one_cmpldi2_insn"
5050 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5051 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5052 "TARGET_32BIT"
5053 "@
5054 vmvn\t%P0, %P1
5055 #
5056 #
5057 vmvn\t%P0, %P1"
5058 "TARGET_32BIT && reload_completed
5059 && arm_general_register_operand (operands[0], DImode)"
5060 [(set (match_dup 0) (not:SI (match_dup 1)))
5061 (set (match_dup 2) (not:SI (match_dup 3)))]
5062 "
5063 {
5064 operands[2] = gen_highpart (SImode, operands[0]);
5065 operands[0] = gen_lowpart (SImode, operands[0]);
5066 operands[3] = gen_highpart (SImode, operands[1]);
5067 operands[1] = gen_lowpart (SImode, operands[1]);
5068 }"
5069 [(set_attr "length" "*,8,8,*")
5070 (set_attr "predicable" "no,yes,yes,no")
5071 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5072 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5073 )
5074
5075 (define_expand "one_cmplsi2"
5076 [(set (match_operand:SI 0 "s_register_operand" "")
5077 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5078 "TARGET_EITHER"
5079 ""
5080 )
5081
5082 (define_insn "*arm_one_cmplsi2"
5083 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5084 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5085 "TARGET_32BIT"
5086 "mvn%?\\t%0, %1"
5087 [(set_attr "predicable" "yes")
5088 (set_attr "predicable_short_it" "yes,no")
5089 (set_attr "arch" "t2,*")
5090 (set_attr "length" "4")
5091 (set_attr "type" "mvn_reg")]
5092 )
5093
5094 (define_insn "*notsi_compare0"
5095 [(set (reg:CC_NOOV CC_REGNUM)
5096 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5097 (const_int 0)))
5098 (set (match_operand:SI 0 "s_register_operand" "=r")
5099 (not:SI (match_dup 1)))]
5100 "TARGET_32BIT"
5101 "mvns%?\\t%0, %1"
5102 [(set_attr "conds" "set")
5103 (set_attr "type" "mvn_reg")]
5104 )
5105
5106 (define_insn "*notsi_compare0_scratch"
5107 [(set (reg:CC_NOOV CC_REGNUM)
5108 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5109 (const_int 0)))
5110 (clobber (match_scratch:SI 0 "=r"))]
5111 "TARGET_32BIT"
5112 "mvns%?\\t%0, %1"
5113 [(set_attr "conds" "set")
5114 (set_attr "type" "mvn_reg")]
5115 )
5116 \f
5117 ;; Fixed <--> Floating conversion insns
5118
5119 (define_expand "floatsihf2"
5120 [(set (match_operand:HF 0 "general_operand" "")
5121 (float:HF (match_operand:SI 1 "general_operand" "")))]
5122 "TARGET_EITHER"
5123 "
5124 {
5125 rtx op1 = gen_reg_rtx (SFmode);
5126 expand_float (op1, operands[1], 0);
5127 op1 = convert_to_mode (HFmode, op1, 0);
5128 emit_move_insn (operands[0], op1);
5129 DONE;
5130 }"
5131 )
5132
5133 (define_expand "floatdihf2"
5134 [(set (match_operand:HF 0 "general_operand" "")
5135 (float:HF (match_operand:DI 1 "general_operand" "")))]
5136 "TARGET_EITHER"
5137 "
5138 {
5139 rtx op1 = gen_reg_rtx (SFmode);
5140 expand_float (op1, operands[1], 0);
5141 op1 = convert_to_mode (HFmode, op1, 0);
5142 emit_move_insn (operands[0], op1);
5143 DONE;
5144 }"
5145 )
5146
5147 (define_expand "floatsisf2"
5148 [(set (match_operand:SF 0 "s_register_operand" "")
5149 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5150 "TARGET_32BIT && TARGET_HARD_FLOAT"
5151 "
5152 ")
5153
5154 (define_expand "floatsidf2"
5155 [(set (match_operand:DF 0 "s_register_operand" "")
5156 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5157 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5158 "
5159 ")
5160
5161 (define_expand "fix_trunchfsi2"
5162 [(set (match_operand:SI 0 "general_operand" "")
5163 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5164 "TARGET_EITHER"
5165 "
5166 {
5167 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5168 expand_fix (operands[0], op1, 0);
5169 DONE;
5170 }"
5171 )
5172
5173 (define_expand "fix_trunchfdi2"
5174 [(set (match_operand:DI 0 "general_operand" "")
5175 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5176 "TARGET_EITHER"
5177 "
5178 {
5179 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5180 expand_fix (operands[0], op1, 0);
5181 DONE;
5182 }"
5183 )
5184
5185 (define_expand "fix_truncsfsi2"
5186 [(set (match_operand:SI 0 "s_register_operand" "")
5187 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5188 "TARGET_32BIT && TARGET_HARD_FLOAT"
5189 "
5190 ")
5191
5192 (define_expand "fix_truncdfsi2"
5193 [(set (match_operand:SI 0 "s_register_operand" "")
5194 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5195 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5196 "
5197 ")
5198
5199 ;; Truncation insns
5200
5201 (define_expand "truncdfsf2"
5202 [(set (match_operand:SF 0 "s_register_operand" "")
5203 (float_truncate:SF
5204 (match_operand:DF 1 "s_register_operand" "")))]
5205 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5206 ""
5207 )
5208
5209 ;; DFmode to HFmode conversions on targets without a single-step hardware
5210 ;; instruction for it would have to go through SFmode. This is dangerous
5211 ;; as it introduces double rounding.
5212 ;;
5213 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5214 ;; a single-step instruction.
5215
5216 (define_expand "truncdfhf2"
5217 [(set (match_operand:HF 0 "s_register_operand" "")
5218 (float_truncate:HF
5219 (match_operand:DF 1 "s_register_operand" "")))]
5220 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5221 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5222 {
5223 /* We don't have a direct instruction for this, so we must be in
5224 an unsafe math mode, and going via SFmode. */
5225
5226 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5227 {
5228 rtx op1;
5229 op1 = convert_to_mode (SFmode, operands[1], 0);
5230 op1 = convert_to_mode (HFmode, op1, 0);
5231 emit_move_insn (operands[0], op1);
5232 DONE;
5233 }
5234 /* Otherwise, we will pick this up as a single instruction with
5235 no intermediary rounding. */
5236 }
5237 )
5238 \f
5239 ;; Zero and sign extension instructions.
5240
5241 (define_insn "zero_extend<mode>di2"
5242 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5243 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5244 "<qhs_zextenddi_cstr>")))]
5245 "TARGET_32BIT <qhs_zextenddi_cond>"
5246 "#"
5247 [(set_attr "length" "8,4,8,8")
5248 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5249 (set_attr "ce_count" "2")
5250 (set_attr "predicable" "yes")
5251 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5252 )
5253
5254 (define_insn "extend<mode>di2"
5255 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5256 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5257 "<qhs_extenddi_cstr>")))]
5258 "TARGET_32BIT <qhs_sextenddi_cond>"
5259 "#"
5260 [(set_attr "length" "8,4,8,8,8")
5261 (set_attr "ce_count" "2")
5262 (set_attr "shift" "1")
5263 (set_attr "predicable" "yes")
5264 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5265 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5266 )
5267
5268 ;; Splits for all extensions to DImode
5269 (define_split
5270 [(set (match_operand:DI 0 "s_register_operand" "")
5271 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5272 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5273 [(set (match_dup 0) (match_dup 1))]
5274 {
5275 rtx lo_part = gen_lowpart (SImode, operands[0]);
5276 machine_mode src_mode = GET_MODE (operands[1]);
5277
5278 if (REG_P (operands[0])
5279 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5280 emit_clobber (operands[0]);
5281 if (!REG_P (lo_part) || src_mode != SImode
5282 || !rtx_equal_p (lo_part, operands[1]))
5283 {
5284 if (src_mode == SImode)
5285 emit_move_insn (lo_part, operands[1]);
5286 else
5287 emit_insn (gen_rtx_SET (lo_part,
5288 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5289 operands[1] = lo_part;
5290 }
5291 operands[0] = gen_highpart (SImode, operands[0]);
5292 operands[1] = const0_rtx;
5293 })
5294
5295 (define_split
5296 [(set (match_operand:DI 0 "s_register_operand" "")
5297 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5298 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5299 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5300 {
5301 rtx lo_part = gen_lowpart (SImode, operands[0]);
5302 machine_mode src_mode = GET_MODE (operands[1]);
5303
5304 if (REG_P (operands[0])
5305 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5306 emit_clobber (operands[0]);
5307
5308 if (!REG_P (lo_part) || src_mode != SImode
5309 || !rtx_equal_p (lo_part, operands[1]))
5310 {
5311 if (src_mode == SImode)
5312 emit_move_insn (lo_part, operands[1]);
5313 else
5314 emit_insn (gen_rtx_SET (lo_part,
5315 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5316 operands[1] = lo_part;
5317 }
5318 operands[0] = gen_highpart (SImode, operands[0]);
5319 })
5320
5321 (define_expand "zero_extendhisi2"
5322 [(set (match_operand:SI 0 "s_register_operand" "")
5323 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5324 "TARGET_EITHER"
5325 {
5326 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5327 {
5328 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5329 DONE;
5330 }
5331 if (!arm_arch6 && !MEM_P (operands[1]))
5332 {
5333 rtx t = gen_lowpart (SImode, operands[1]);
5334 rtx tmp = gen_reg_rtx (SImode);
5335 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5336 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5337 DONE;
5338 }
5339 })
5340
5341 (define_split
5342 [(set (match_operand:SI 0 "s_register_operand" "")
5343 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5344 "!TARGET_THUMB2 && !arm_arch6"
5345 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5346 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5347 {
5348 operands[2] = gen_lowpart (SImode, operands[1]);
5349 })
5350
5351 (define_insn "*arm_zero_extendhisi2"
5352 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5353 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5354 "TARGET_ARM && arm_arch4 && !arm_arch6"
5355 "@
5356 #
5357 ldrh%?\\t%0, %1"
5358 [(set_attr "type" "alu_shift_reg,load_byte")
5359 (set_attr "predicable" "yes")]
5360 )
5361
5362 (define_insn "*arm_zero_extendhisi2_v6"
5363 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5364 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5365 "TARGET_ARM && arm_arch6"
5366 "@
5367 uxth%?\\t%0, %1
5368 ldrh%?\\t%0, %1"
5369 [(set_attr "predicable" "yes")
5370 (set_attr "type" "extend,load_byte")]
5371 )
5372
5373 (define_insn "*arm_zero_extendhisi2addsi"
5374 [(set (match_operand:SI 0 "s_register_operand" "=r")
5375 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5376 (match_operand:SI 2 "s_register_operand" "r")))]
5377 "TARGET_INT_SIMD"
5378 "uxtah%?\\t%0, %2, %1"
5379 [(set_attr "type" "alu_shift_reg")
5380 (set_attr "predicable" "yes")
5381 (set_attr "predicable_short_it" "no")]
5382 )
5383
5384 (define_expand "zero_extendqisi2"
5385 [(set (match_operand:SI 0 "s_register_operand" "")
5386 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5387 "TARGET_EITHER"
5388 {
5389 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5390 {
5391 emit_insn (gen_andsi3 (operands[0],
5392 gen_lowpart (SImode, operands[1]),
5393 GEN_INT (255)));
5394 DONE;
5395 }
5396 if (!arm_arch6 && !MEM_P (operands[1]))
5397 {
5398 rtx t = gen_lowpart (SImode, operands[1]);
5399 rtx tmp = gen_reg_rtx (SImode);
5400 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5401 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5402 DONE;
5403 }
5404 })
5405
5406 (define_split
5407 [(set (match_operand:SI 0 "s_register_operand" "")
5408 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5409 "!arm_arch6"
5410 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5411 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5412 {
5413 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5414 if (TARGET_ARM)
5415 {
5416 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5417 DONE;
5418 }
5419 })
5420
5421 (define_insn "*arm_zero_extendqisi2"
5422 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5423 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5424 "TARGET_ARM && !arm_arch6"
5425 "@
5426 #
5427 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5428 [(set_attr "length" "8,4")
5429 (set_attr "type" "alu_shift_reg,load_byte")
5430 (set_attr "predicable" "yes")]
5431 )
5432
5433 (define_insn "*arm_zero_extendqisi2_v6"
5434 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5435 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5436 "TARGET_ARM && arm_arch6"
5437 "@
5438 uxtb%?\\t%0, %1
5439 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5440 [(set_attr "type" "extend,load_byte")
5441 (set_attr "predicable" "yes")]
5442 )
5443
5444 (define_insn "*arm_zero_extendqisi2addsi"
5445 [(set (match_operand:SI 0 "s_register_operand" "=r")
5446 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5447 (match_operand:SI 2 "s_register_operand" "r")))]
5448 "TARGET_INT_SIMD"
5449 "uxtab%?\\t%0, %2, %1"
5450 [(set_attr "predicable" "yes")
5451 (set_attr "predicable_short_it" "no")
5452 (set_attr "type" "alu_shift_reg")]
5453 )
5454
5455 (define_split
5456 [(set (match_operand:SI 0 "s_register_operand" "")
5457 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5458 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5459 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5460 [(set (match_dup 2) (match_dup 1))
5461 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5462 ""
5463 )
5464
5465 (define_split
5466 [(set (match_operand:SI 0 "s_register_operand" "")
5467 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5468 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5469 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5470 [(set (match_dup 2) (match_dup 1))
5471 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5472 ""
5473 )
5474
5475
5476 (define_split
5477 [(set (match_operand:SI 0 "s_register_operand" "")
5478 (IOR_XOR:SI (and:SI (ashift:SI
5479 (match_operand:SI 1 "s_register_operand" "")
5480 (match_operand:SI 2 "const_int_operand" ""))
5481 (match_operand:SI 3 "const_int_operand" ""))
5482 (zero_extend:SI
5483 (match_operator 5 "subreg_lowpart_operator"
5484 [(match_operand:SI 4 "s_register_operand" "")]))))]
5485 "TARGET_32BIT
5486 && (UINTVAL (operands[3])
5487 == (GET_MODE_MASK (GET_MODE (operands[5]))
5488 & (GET_MODE_MASK (GET_MODE (operands[5]))
5489 << (INTVAL (operands[2])))))"
5490 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5491 (match_dup 4)))
5492 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5493 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5494 )
5495
5496 (define_insn "*compareqi_eq0"
5497 [(set (reg:CC_Z CC_REGNUM)
5498 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5499 (const_int 0)))]
5500 "TARGET_32BIT"
5501 "tst%?\\t%0, #255"
5502 [(set_attr "conds" "set")
5503 (set_attr "predicable" "yes")
5504 (set_attr "predicable_short_it" "no")
5505 (set_attr "type" "logic_imm")]
5506 )
5507
5508 (define_expand "extendhisi2"
5509 [(set (match_operand:SI 0 "s_register_operand" "")
5510 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5511 "TARGET_EITHER"
5512 {
5513 if (TARGET_THUMB1)
5514 {
5515 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5516 DONE;
5517 }
5518 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5519 {
5520 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5521 DONE;
5522 }
5523
5524 if (!arm_arch6 && !MEM_P (operands[1]))
5525 {
5526 rtx t = gen_lowpart (SImode, operands[1]);
5527 rtx tmp = gen_reg_rtx (SImode);
5528 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5529 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5530 DONE;
5531 }
5532 })
5533
5534 (define_split
5535 [(parallel
5536 [(set (match_operand:SI 0 "register_operand" "")
5537 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5538 (clobber (match_scratch:SI 2 ""))])]
5539 "!arm_arch6"
5540 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5541 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5542 {
5543 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5544 })
5545
5546 ;; This pattern will only be used when ldsh is not available
5547 (define_expand "extendhisi2_mem"
5548 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5549 (set (match_dup 3)
5550 (zero_extend:SI (match_dup 7)))
5551 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5552 (set (match_operand:SI 0 "" "")
5553 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5554 "TARGET_ARM"
5555 "
5556 {
5557 rtx mem1, mem2;
5558 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5559
5560 mem1 = change_address (operands[1], QImode, addr);
5561 mem2 = change_address (operands[1], QImode,
5562 plus_constant (Pmode, addr, 1));
5563 operands[0] = gen_lowpart (SImode, operands[0]);
5564 operands[1] = mem1;
5565 operands[2] = gen_reg_rtx (SImode);
5566 operands[3] = gen_reg_rtx (SImode);
5567 operands[6] = gen_reg_rtx (SImode);
5568 operands[7] = mem2;
5569
5570 if (BYTES_BIG_ENDIAN)
5571 {
5572 operands[4] = operands[2];
5573 operands[5] = operands[3];
5574 }
5575 else
5576 {
5577 operands[4] = operands[3];
5578 operands[5] = operands[2];
5579 }
5580 }"
5581 )
5582
5583 (define_split
5584 [(set (match_operand:SI 0 "register_operand" "")
5585 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5586 "!arm_arch6"
5587 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5588 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5589 {
5590 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5591 })
5592
5593 (define_insn "*arm_extendhisi2"
5594 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5595 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5596 "TARGET_ARM && arm_arch4 && !arm_arch6"
5597 "@
5598 #
5599 ldrsh%?\\t%0, %1"
5600 [(set_attr "length" "8,4")
5601 (set_attr "type" "alu_shift_reg,load_byte")
5602 (set_attr "predicable" "yes")]
5603 )
5604
5605 ;; ??? Check Thumb-2 pool range
5606 (define_insn "*arm_extendhisi2_v6"
5607 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5608 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5609 "TARGET_32BIT && arm_arch6"
5610 "@
5611 sxth%?\\t%0, %1
5612 ldrsh%?\\t%0, %1"
5613 [(set_attr "type" "extend,load_byte")
5614 (set_attr "predicable" "yes")
5615 (set_attr "predicable_short_it" "no")]
5616 )
5617
5618 (define_insn "*arm_extendhisi2addsi"
5619 [(set (match_operand:SI 0 "s_register_operand" "=r")
5620 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5621 (match_operand:SI 2 "s_register_operand" "r")))]
5622 "TARGET_INT_SIMD"
5623 "sxtah%?\\t%0, %2, %1"
5624 [(set_attr "type" "alu_shift_reg")]
5625 )
5626
5627 (define_expand "extendqihi2"
5628 [(set (match_dup 2)
5629 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5630 (const_int 24)))
5631 (set (match_operand:HI 0 "s_register_operand" "")
5632 (ashiftrt:SI (match_dup 2)
5633 (const_int 24)))]
5634 "TARGET_ARM"
5635 "
5636 {
5637 if (arm_arch4 && MEM_P (operands[1]))
5638 {
5639 emit_insn (gen_rtx_SET (operands[0],
5640 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5641 DONE;
5642 }
5643 if (!s_register_operand (operands[1], QImode))
5644 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5645 operands[0] = gen_lowpart (SImode, operands[0]);
5646 operands[1] = gen_lowpart (SImode, operands[1]);
5647 operands[2] = gen_reg_rtx (SImode);
5648 }"
5649 )
5650
5651 (define_insn "*arm_extendqihi_insn"
5652 [(set (match_operand:HI 0 "s_register_operand" "=r")
5653 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5654 "TARGET_ARM && arm_arch4"
5655 "ldrsb%?\\t%0, %1"
5656 [(set_attr "type" "load_byte")
5657 (set_attr "predicable" "yes")]
5658 )
5659
5660 (define_expand "extendqisi2"
5661 [(set (match_operand:SI 0 "s_register_operand" "")
5662 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5663 "TARGET_EITHER"
5664 {
5665 if (!arm_arch4 && MEM_P (operands[1]))
5666 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5667
5668 if (!arm_arch6 && !MEM_P (operands[1]))
5669 {
5670 rtx t = gen_lowpart (SImode, operands[1]);
5671 rtx tmp = gen_reg_rtx (SImode);
5672 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5673 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5674 DONE;
5675 }
5676 })
5677
5678 (define_split
5679 [(set (match_operand:SI 0 "register_operand" "")
5680 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5681 "!arm_arch6"
5682 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5683 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5684 {
5685 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5686 })
5687
5688 (define_insn "*arm_extendqisi"
5689 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5690 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5691 "TARGET_ARM && arm_arch4 && !arm_arch6"
5692 "@
5693 #
5694 ldrsb%?\\t%0, %1"
5695 [(set_attr "length" "8,4")
5696 (set_attr "type" "alu_shift_reg,load_byte")
5697 (set_attr "predicable" "yes")]
5698 )
5699
5700 (define_insn "*arm_extendqisi_v6"
5701 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5702 (sign_extend:SI
5703 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5704 "TARGET_ARM && arm_arch6"
5705 "@
5706 sxtb%?\\t%0, %1
5707 ldrsb%?\\t%0, %1"
5708 [(set_attr "type" "extend,load_byte")
5709 (set_attr "predicable" "yes")]
5710 )
5711
5712 (define_insn "*arm_extendqisi2addsi"
5713 [(set (match_operand:SI 0 "s_register_operand" "=r")
5714 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5715 (match_operand:SI 2 "s_register_operand" "r")))]
5716 "TARGET_INT_SIMD"
5717 "sxtab%?\\t%0, %2, %1"
5718 [(set_attr "type" "alu_shift_reg")
5719 (set_attr "predicable" "yes")
5720 (set_attr "predicable_short_it" "no")]
5721 )
5722
5723 (define_expand "extendsfdf2"
5724 [(set (match_operand:DF 0 "s_register_operand" "")
5725 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5726 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5727 ""
5728 )
5729
5730 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5731 ;; must go through SFmode.
5732 ;;
5733 ;; This is always safe for an extend.
5734
5735 (define_expand "extendhfdf2"
5736 [(set (match_operand:DF 0 "s_register_operand" "")
5737 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5738 "TARGET_EITHER"
5739 {
5740 /* We don't have a direct instruction for this, so go via SFmode. */
5741 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5742 {
5743 rtx op1;
5744 op1 = convert_to_mode (SFmode, operands[1], 0);
5745 op1 = convert_to_mode (DFmode, op1, 0);
5746 emit_insn (gen_movdf (operands[0], op1));
5747 DONE;
5748 }
5749 /* Otherwise, we're done producing RTL and will pick up the correct
5750 pattern to do this with one rounding-step in a single instruction. */
5751 }
5752 )
5753 \f
5754 ;; Move insns (including loads and stores)
5755
5756 ;; XXX Just some ideas about movti.
5757 ;; I don't think these are a good idea on the arm, there just aren't enough
5758 ;; registers
5759 ;;(define_expand "loadti"
5760 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5761 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5762 ;; "" "")
5763
5764 ;;(define_expand "storeti"
5765 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5766 ;; (match_operand:TI 1 "s_register_operand" ""))]
5767 ;; "" "")
5768
5769 ;;(define_expand "movti"
5770 ;; [(set (match_operand:TI 0 "general_operand" "")
5771 ;; (match_operand:TI 1 "general_operand" ""))]
5772 ;; ""
5773 ;; "
5774 ;;{
5775 ;; rtx insn;
5776 ;;
5777 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5778 ;; operands[1] = copy_to_reg (operands[1]);
5779 ;; if (MEM_P (operands[0]))
5780 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5781 ;; else if (MEM_P (operands[1]))
5782 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5783 ;; else
5784 ;; FAIL;
5785 ;;
5786 ;; emit_insn (insn);
5787 ;; DONE;
5788 ;;}")
5789
5790 ;; Recognize garbage generated above.
5791
5792 ;;(define_insn ""
5793 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5794 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5795 ;; ""
5796 ;; "*
5797 ;; {
5798 ;; register mem = (which_alternative < 3);
5799 ;; register const char *template;
5800 ;;
5801 ;; operands[mem] = XEXP (operands[mem], 0);
5802 ;; switch (which_alternative)
5803 ;; {
5804 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5805 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5806 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5807 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5808 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5809 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5810 ;; }
5811 ;; output_asm_insn (template, operands);
5812 ;; return \"\";
5813 ;; }")
5814
5815 (define_expand "movdi"
5816 [(set (match_operand:DI 0 "general_operand" "")
5817 (match_operand:DI 1 "general_operand" ""))]
5818 "TARGET_EITHER"
5819 "
5820 if (can_create_pseudo_p ())
5821 {
5822 if (!REG_P (operands[0]))
5823 operands[1] = force_reg (DImode, operands[1]);
5824 }
5825 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5826 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5827 {
5828 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5829 when expanding function calls. */
5830 gcc_assert (can_create_pseudo_p ());
5831 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5832 {
5833 /* Perform load into legal reg pair first, then move. */
5834 rtx reg = gen_reg_rtx (DImode);
5835 emit_insn (gen_movdi (reg, operands[1]));
5836 operands[1] = reg;
5837 }
5838 emit_move_insn (gen_lowpart (SImode, operands[0]),
5839 gen_lowpart (SImode, operands[1]));
5840 emit_move_insn (gen_highpart (SImode, operands[0]),
5841 gen_highpart (SImode, operands[1]));
5842 DONE;
5843 }
5844 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5845 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5846 {
5847 /* Avoid STRD's from an odd-numbered register pair in ARM state
5848 when expanding function prologue. */
5849 gcc_assert (can_create_pseudo_p ());
5850 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5851 ? gen_reg_rtx (DImode)
5852 : operands[0];
5853 emit_move_insn (gen_lowpart (SImode, split_dest),
5854 gen_lowpart (SImode, operands[1]));
5855 emit_move_insn (gen_highpart (SImode, split_dest),
5856 gen_highpart (SImode, operands[1]));
5857 if (split_dest != operands[0])
5858 emit_insn (gen_movdi (operands[0], split_dest));
5859 DONE;
5860 }
5861 "
5862 )
5863
5864 (define_insn "*arm_movdi"
5865 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5866 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5867 "TARGET_32BIT
5868 && !(TARGET_HARD_FLOAT)
5869 && !TARGET_IWMMXT
5870 && ( register_operand (operands[0], DImode)
5871 || register_operand (operands[1], DImode))"
5872 "*
5873 switch (which_alternative)
5874 {
5875 case 0:
5876 case 1:
5877 case 2:
5878 return \"#\";
5879 default:
5880 return output_move_double (operands, true, NULL);
5881 }
5882 "
5883 [(set_attr "length" "8,12,16,8,8")
5884 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5885 (set_attr "arm_pool_range" "*,*,*,1020,*")
5886 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5887 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5888 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5889 )
5890
5891 (define_split
5892 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5893 (match_operand:ANY64 1 "immediate_operand" ""))]
5894 "TARGET_32BIT
5895 && reload_completed
5896 && (arm_disable_literal_pool
5897 || (arm_const_double_inline_cost (operands[1])
5898 <= arm_max_const_double_inline_cost ()))"
5899 [(const_int 0)]
5900 "
5901 arm_split_constant (SET, SImode, curr_insn,
5902 INTVAL (gen_lowpart (SImode, operands[1])),
5903 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5904 arm_split_constant (SET, SImode, curr_insn,
5905 INTVAL (gen_highpart_mode (SImode,
5906 GET_MODE (operands[0]),
5907 operands[1])),
5908 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5909 DONE;
5910 "
5911 )
5912
5913 ; If optimizing for size, or if we have load delay slots, then
5914 ; we want to split the constant into two separate operations.
5915 ; In both cases this may split a trivial part into a single data op
5916 ; leaving a single complex constant to load. We can also get longer
5917 ; offsets in a LDR which means we get better chances of sharing the pool
5918 ; entries. Finally, we can normally do a better job of scheduling
5919 ; LDR instructions than we can with LDM.
5920 ; This pattern will only match if the one above did not.
5921 (define_split
5922 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5923 (match_operand:ANY64 1 "const_double_operand" ""))]
5924 "TARGET_ARM && reload_completed
5925 && arm_const_double_by_parts (operands[1])"
5926 [(set (match_dup 0) (match_dup 1))
5927 (set (match_dup 2) (match_dup 3))]
5928 "
5929 operands[2] = gen_highpart (SImode, operands[0]);
5930 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5931 operands[1]);
5932 operands[0] = gen_lowpart (SImode, operands[0]);
5933 operands[1] = gen_lowpart (SImode, operands[1]);
5934 "
5935 )
5936
5937 (define_split
5938 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5939 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5940 "TARGET_EITHER && reload_completed"
5941 [(set (match_dup 0) (match_dup 1))
5942 (set (match_dup 2) (match_dup 3))]
5943 "
5944 operands[2] = gen_highpart (SImode, operands[0]);
5945 operands[3] = gen_highpart (SImode, operands[1]);
5946 operands[0] = gen_lowpart (SImode, operands[0]);
5947 operands[1] = gen_lowpart (SImode, operands[1]);
5948
5949 /* Handle a partial overlap. */
5950 if (rtx_equal_p (operands[0], operands[3]))
5951 {
5952 rtx tmp0 = operands[0];
5953 rtx tmp1 = operands[1];
5954
5955 operands[0] = operands[2];
5956 operands[1] = operands[3];
5957 operands[2] = tmp0;
5958 operands[3] = tmp1;
5959 }
5960 "
5961 )
5962
5963 ;; We can't actually do base+index doubleword loads if the index and
5964 ;; destination overlap. Split here so that we at least have chance to
5965 ;; schedule.
5966 (define_split
5967 [(set (match_operand:DI 0 "s_register_operand" "")
5968 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5969 (match_operand:SI 2 "s_register_operand" ""))))]
5970 "TARGET_LDRD
5971 && reg_overlap_mentioned_p (operands[0], operands[1])
5972 && reg_overlap_mentioned_p (operands[0], operands[2])"
5973 [(set (match_dup 4)
5974 (plus:SI (match_dup 1)
5975 (match_dup 2)))
5976 (set (match_dup 0)
5977 (mem:DI (match_dup 4)))]
5978 "
5979 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5980 "
5981 )
5982
5983 (define_expand "movsi"
5984 [(set (match_operand:SI 0 "general_operand" "")
5985 (match_operand:SI 1 "general_operand" ""))]
5986 "TARGET_EITHER"
5987 "
5988 {
5989 rtx base, offset, tmp;
5990
5991 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5992 {
5993 /* Everything except mem = const or mem = mem can be done easily. */
5994 if (MEM_P (operands[0]))
5995 operands[1] = force_reg (SImode, operands[1]);
5996 if (arm_general_register_operand (operands[0], SImode)
5997 && CONST_INT_P (operands[1])
5998 && !(const_ok_for_arm (INTVAL (operands[1]))
5999 || const_ok_for_arm (~INTVAL (operands[1]))))
6000 {
6001 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
6002 {
6003 emit_insn (gen_rtx_SET (operands[0], operands[1]));
6004 DONE;
6005 }
6006 else
6007 {
6008 arm_split_constant (SET, SImode, NULL_RTX,
6009 INTVAL (operands[1]), operands[0], NULL_RTX,
6010 optimize && can_create_pseudo_p ());
6011 DONE;
6012 }
6013 }
6014 }
6015 else /* Target doesn't have MOVT... */
6016 {
6017 if (can_create_pseudo_p ())
6018 {
6019 if (!REG_P (operands[0]))
6020 operands[1] = force_reg (SImode, operands[1]);
6021 }
6022 }
6023
6024 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6025 {
6026 split_const (operands[1], &base, &offset);
6027 if (GET_CODE (base) == SYMBOL_REF
6028 && !offset_within_block_p (base, INTVAL (offset)))
6029 {
6030 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6031 emit_move_insn (tmp, base);
6032 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6033 DONE;
6034 }
6035 }
6036
6037 /* Recognize the case where operand[1] is a reference to thread-local
6038 data and load its address to a register. */
6039 if (arm_tls_referenced_p (operands[1]))
6040 {
6041 rtx tmp = operands[1];
6042 rtx addend = NULL;
6043
6044 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6045 {
6046 addend = XEXP (XEXP (tmp, 0), 1);
6047 tmp = XEXP (XEXP (tmp, 0), 0);
6048 }
6049
6050 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6051 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6052
6053 tmp = legitimize_tls_address (tmp,
6054 !can_create_pseudo_p () ? operands[0] : 0);
6055 if (addend)
6056 {
6057 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6058 tmp = force_operand (tmp, operands[0]);
6059 }
6060 operands[1] = tmp;
6061 }
6062 else if (flag_pic
6063 && (CONSTANT_P (operands[1])
6064 || symbol_mentioned_p (operands[1])
6065 || label_mentioned_p (operands[1])))
6066 operands[1] = legitimize_pic_address (operands[1], SImode,
6067 (!can_create_pseudo_p ()
6068 ? operands[0]
6069 : 0));
6070 }
6071 "
6072 )
6073
6074 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6075 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6076 ;; so this does not matter.
6077 (define_insn "*arm_movt"
6078 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6079 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6080 (match_operand:SI 2 "general_operand" "i,i")))]
6081 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6082 "@
6083 movt%?\t%0, #:upper16:%c2
6084 movt\t%0, #:upper16:%c2"
6085 [(set_attr "arch" "32,v8mb")
6086 (set_attr "predicable" "yes")
6087 (set_attr "predicable_short_it" "no")
6088 (set_attr "length" "4")
6089 (set_attr "type" "alu_sreg")]
6090 )
6091
6092 (define_insn "*arm_movsi_insn"
6093 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6094 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6095 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6096 && ( register_operand (operands[0], SImode)
6097 || register_operand (operands[1], SImode))"
6098 "@
6099 mov%?\\t%0, %1
6100 mov%?\\t%0, %1
6101 mvn%?\\t%0, #%B1
6102 movw%?\\t%0, %1
6103 ldr%?\\t%0, %1
6104 str%?\\t%1, %0"
6105 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6106 (set_attr "predicable" "yes")
6107 (set_attr "arch" "*,*,*,v6t2,*,*")
6108 (set_attr "pool_range" "*,*,*,*,4096,*")
6109 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6110 )
6111
6112 (define_split
6113 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6114 (match_operand:SI 1 "const_int_operand" ""))]
6115 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6116 && (!(const_ok_for_arm (INTVAL (operands[1]))
6117 || const_ok_for_arm (~INTVAL (operands[1]))))"
6118 [(clobber (const_int 0))]
6119 "
6120 arm_split_constant (SET, SImode, NULL_RTX,
6121 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6122 DONE;
6123 "
6124 )
6125
6126 ;; A normal way to do (symbol + offset) requires three instructions at least
6127 ;; (depends on how big the offset is) as below:
6128 ;; movw r0, #:lower16:g
6129 ;; movw r0, #:upper16:g
6130 ;; adds r0, #4
6131 ;;
6132 ;; A better way would be:
6133 ;; movw r0, #:lower16:g+4
6134 ;; movw r0, #:upper16:g+4
6135 ;;
6136 ;; The limitation of this way is that the length of offset should be a 16-bit
6137 ;; signed value, because current assembler only supports REL type relocation for
6138 ;; such case. If the more powerful RELA type is supported in future, we should
6139 ;; update this pattern to go with better way.
6140 (define_split
6141 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6142 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6143 (match_operand:SI 2 "const_int_operand" ""))))]
6144 "TARGET_THUMB
6145 && TARGET_HAVE_MOVT
6146 && arm_disable_literal_pool
6147 && reload_completed
6148 && GET_CODE (operands[1]) == SYMBOL_REF"
6149 [(clobber (const_int 0))]
6150 "
6151 int offset = INTVAL (operands[2]);
6152
6153 if (offset < -0x8000 || offset > 0x7fff)
6154 {
6155 arm_emit_movpair (operands[0], operands[1]);
6156 emit_insn (gen_rtx_SET (operands[0],
6157 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6158 }
6159 else
6160 {
6161 rtx op = gen_rtx_CONST (SImode,
6162 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6163 arm_emit_movpair (operands[0], op);
6164 }
6165 "
6166 )
6167
6168 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6169 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6170 ;; and lo_sum would be merged back into memory load at cprop. However,
6171 ;; if the default is to prefer movt/movw rather than a load from the constant
6172 ;; pool, the performance is better.
6173 (define_split
6174 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6175 (match_operand:SI 1 "general_operand" ""))]
6176 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6177 && !flag_pic && !target_word_relocations
6178 && !arm_tls_referenced_p (operands[1])"
6179 [(clobber (const_int 0))]
6180 {
6181 arm_emit_movpair (operands[0], operands[1]);
6182 DONE;
6183 })
6184
6185 ;; When generating pic, we need to load the symbol offset into a register.
6186 ;; So that the optimizer does not confuse this with a normal symbol load
6187 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6188 ;; since that is the only type of relocation we can use.
6189
6190 ;; Wrap calculation of the whole PIC address in a single pattern for the
6191 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6192 ;; a PIC address involves two loads from memory, so we want to CSE it
6193 ;; as often as possible.
6194 ;; This pattern will be split into one of the pic_load_addr_* patterns
6195 ;; and a move after GCSE optimizations.
6196 ;;
6197 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6198 (define_expand "calculate_pic_address"
6199 [(set (match_operand:SI 0 "register_operand" "")
6200 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6201 (unspec:SI [(match_operand:SI 2 "" "")]
6202 UNSPEC_PIC_SYM))))]
6203 "flag_pic"
6204 )
6205
6206 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6207 (define_split
6208 [(set (match_operand:SI 0 "register_operand" "")
6209 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6210 (unspec:SI [(match_operand:SI 2 "" "")]
6211 UNSPEC_PIC_SYM))))]
6212 "flag_pic"
6213 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6214 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6215 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6216 )
6217
6218 ;; operand1 is the memory address to go into
6219 ;; pic_load_addr_32bit.
6220 ;; operand2 is the PIC label to be emitted
6221 ;; from pic_add_dot_plus_eight.
6222 ;; We do this to allow hoisting of the entire insn.
6223 (define_insn_and_split "pic_load_addr_unified"
6224 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6225 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6226 (match_operand:SI 2 "" "")]
6227 UNSPEC_PIC_UNIFIED))]
6228 "flag_pic"
6229 "#"
6230 "&& reload_completed"
6231 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6232 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6233 (match_dup 2)] UNSPEC_PIC_BASE))]
6234 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6235 [(set_attr "type" "load_4,load_4,load_4")
6236 (set_attr "pool_range" "4096,4094,1022")
6237 (set_attr "neg_pool_range" "4084,0,0")
6238 (set_attr "arch" "a,t2,t1")
6239 (set_attr "length" "8,6,4")]
6240 )
6241
6242 ;; The rather odd constraints on the following are to force reload to leave
6243 ;; the insn alone, and to force the minipool generation pass to then move
6244 ;; the GOT symbol to memory.
6245
6246 (define_insn "pic_load_addr_32bit"
6247 [(set (match_operand:SI 0 "s_register_operand" "=r")
6248 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6249 "TARGET_32BIT && flag_pic"
6250 "ldr%?\\t%0, %1"
6251 [(set_attr "type" "load_4")
6252 (set (attr "pool_range")
6253 (if_then_else (eq_attr "is_thumb" "no")
6254 (const_int 4096)
6255 (const_int 4094)))
6256 (set (attr "neg_pool_range")
6257 (if_then_else (eq_attr "is_thumb" "no")
6258 (const_int 4084)
6259 (const_int 0)))]
6260 )
6261
6262 (define_insn "pic_load_addr_thumb1"
6263 [(set (match_operand:SI 0 "s_register_operand" "=l")
6264 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6265 "TARGET_THUMB1 && flag_pic"
6266 "ldr\\t%0, %1"
6267 [(set_attr "type" "load_4")
6268 (set (attr "pool_range") (const_int 1018))]
6269 )
6270
6271 (define_insn "pic_add_dot_plus_four"
6272 [(set (match_operand:SI 0 "register_operand" "=r")
6273 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6274 (const_int 4)
6275 (match_operand 2 "" "")]
6276 UNSPEC_PIC_BASE))]
6277 "TARGET_THUMB"
6278 "*
6279 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6280 INTVAL (operands[2]));
6281 return \"add\\t%0, %|pc\";
6282 "
6283 [(set_attr "length" "2")
6284 (set_attr "type" "alu_sreg")]
6285 )
6286
6287 (define_insn "pic_add_dot_plus_eight"
6288 [(set (match_operand:SI 0 "register_operand" "=r")
6289 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6290 (const_int 8)
6291 (match_operand 2 "" "")]
6292 UNSPEC_PIC_BASE))]
6293 "TARGET_ARM"
6294 "*
6295 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6296 INTVAL (operands[2]));
6297 return \"add%?\\t%0, %|pc, %1\";
6298 "
6299 [(set_attr "predicable" "yes")
6300 (set_attr "type" "alu_sreg")]
6301 )
6302
6303 (define_insn "tls_load_dot_plus_eight"
6304 [(set (match_operand:SI 0 "register_operand" "=r")
6305 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6306 (const_int 8)
6307 (match_operand 2 "" "")]
6308 UNSPEC_PIC_BASE)))]
6309 "TARGET_ARM"
6310 "*
6311 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6312 INTVAL (operands[2]));
6313 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6314 "
6315 [(set_attr "predicable" "yes")
6316 (set_attr "type" "load_4")]
6317 )
6318
6319 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6320 ;; followed by a load. These sequences can be crunched down to
6321 ;; tls_load_dot_plus_eight by a peephole.
6322
6323 (define_peephole2
6324 [(set (match_operand:SI 0 "register_operand" "")
6325 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6326 (const_int 8)
6327 (match_operand 1 "" "")]
6328 UNSPEC_PIC_BASE))
6329 (set (match_operand:SI 2 "arm_general_register_operand" "")
6330 (mem:SI (match_dup 0)))]
6331 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6332 [(set (match_dup 2)
6333 (mem:SI (unspec:SI [(match_dup 3)
6334 (const_int 8)
6335 (match_dup 1)]
6336 UNSPEC_PIC_BASE)))]
6337 ""
6338 )
6339
6340 (define_insn "pic_offset_arm"
6341 [(set (match_operand:SI 0 "register_operand" "=r")
6342 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6343 (unspec:SI [(match_operand:SI 2 "" "X")]
6344 UNSPEC_PIC_OFFSET))))]
6345 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6346 "ldr%?\\t%0, [%1,%2]"
6347 [(set_attr "type" "load_4")]
6348 )
6349
6350 (define_expand "builtin_setjmp_receiver"
6351 [(label_ref (match_operand 0 "" ""))]
6352 "flag_pic"
6353 "
6354 {
6355 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6356 register. */
6357 if (arm_pic_register != INVALID_REGNUM)
6358 arm_load_pic_register (1UL << 3);
6359 DONE;
6360 }")
6361
6362 ;; If copying one reg to another we can set the condition codes according to
6363 ;; its value. Such a move is common after a return from subroutine and the
6364 ;; result is being tested against zero.
6365
6366 (define_insn "*movsi_compare0"
6367 [(set (reg:CC CC_REGNUM)
6368 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6369 (const_int 0)))
6370 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6371 (match_dup 1))]
6372 "TARGET_32BIT"
6373 "@
6374 cmp%?\\t%0, #0
6375 subs%?\\t%0, %1, #0"
6376 [(set_attr "conds" "set")
6377 (set_attr "type" "alus_imm,alus_imm")]
6378 )
6379
6380 ;; Subroutine to store a half word from a register into memory.
6381 ;; Operand 0 is the source register (HImode)
6382 ;; Operand 1 is the destination address in a register (SImode)
6383
6384 ;; In both this routine and the next, we must be careful not to spill
6385 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6386 ;; can generate unrecognizable rtl.
6387
6388 (define_expand "storehi"
6389 [;; store the low byte
6390 (set (match_operand 1 "" "") (match_dup 3))
6391 ;; extract the high byte
6392 (set (match_dup 2)
6393 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6394 ;; store the high byte
6395 (set (match_dup 4) (match_dup 5))]
6396 "TARGET_ARM"
6397 "
6398 {
6399 rtx op1 = operands[1];
6400 rtx addr = XEXP (op1, 0);
6401 enum rtx_code code = GET_CODE (addr);
6402
6403 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6404 || code == MINUS)
6405 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6406
6407 operands[4] = adjust_address (op1, QImode, 1);
6408 operands[1] = adjust_address (operands[1], QImode, 0);
6409 operands[3] = gen_lowpart (QImode, operands[0]);
6410 operands[0] = gen_lowpart (SImode, operands[0]);
6411 operands[2] = gen_reg_rtx (SImode);
6412 operands[5] = gen_lowpart (QImode, operands[2]);
6413 }"
6414 )
6415
6416 (define_expand "storehi_bigend"
6417 [(set (match_dup 4) (match_dup 3))
6418 (set (match_dup 2)
6419 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6420 (set (match_operand 1 "" "") (match_dup 5))]
6421 "TARGET_ARM"
6422 "
6423 {
6424 rtx op1 = operands[1];
6425 rtx addr = XEXP (op1, 0);
6426 enum rtx_code code = GET_CODE (addr);
6427
6428 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6429 || code == MINUS)
6430 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6431
6432 operands[4] = adjust_address (op1, QImode, 1);
6433 operands[1] = adjust_address (operands[1], QImode, 0);
6434 operands[3] = gen_lowpart (QImode, operands[0]);
6435 operands[0] = gen_lowpart (SImode, operands[0]);
6436 operands[2] = gen_reg_rtx (SImode);
6437 operands[5] = gen_lowpart (QImode, operands[2]);
6438 }"
6439 )
6440
6441 ;; Subroutine to store a half word integer constant into memory.
6442 (define_expand "storeinthi"
6443 [(set (match_operand 0 "" "")
6444 (match_operand 1 "" ""))
6445 (set (match_dup 3) (match_dup 2))]
6446 "TARGET_ARM"
6447 "
6448 {
6449 HOST_WIDE_INT value = INTVAL (operands[1]);
6450 rtx addr = XEXP (operands[0], 0);
6451 rtx op0 = operands[0];
6452 enum rtx_code code = GET_CODE (addr);
6453
6454 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6455 || code == MINUS)
6456 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6457
6458 operands[1] = gen_reg_rtx (SImode);
6459 if (BYTES_BIG_ENDIAN)
6460 {
6461 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6462 if ((value & 255) == ((value >> 8) & 255))
6463 operands[2] = operands[1];
6464 else
6465 {
6466 operands[2] = gen_reg_rtx (SImode);
6467 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6468 }
6469 }
6470 else
6471 {
6472 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6473 if ((value & 255) == ((value >> 8) & 255))
6474 operands[2] = operands[1];
6475 else
6476 {
6477 operands[2] = gen_reg_rtx (SImode);
6478 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6479 }
6480 }
6481
6482 operands[3] = adjust_address (op0, QImode, 1);
6483 operands[0] = adjust_address (operands[0], QImode, 0);
6484 operands[2] = gen_lowpart (QImode, operands[2]);
6485 operands[1] = gen_lowpart (QImode, operands[1]);
6486 }"
6487 )
6488
6489 (define_expand "storehi_single_op"
6490 [(set (match_operand:HI 0 "memory_operand" "")
6491 (match_operand:HI 1 "general_operand" ""))]
6492 "TARGET_32BIT && arm_arch4"
6493 "
6494 if (!s_register_operand (operands[1], HImode))
6495 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6496 "
6497 )
6498
6499 (define_expand "movhi"
6500 [(set (match_operand:HI 0 "general_operand" "")
6501 (match_operand:HI 1 "general_operand" ""))]
6502 "TARGET_EITHER"
6503 "
6504 if (TARGET_ARM)
6505 {
6506 if (can_create_pseudo_p ())
6507 {
6508 if (MEM_P (operands[0]))
6509 {
6510 if (arm_arch4)
6511 {
6512 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6513 DONE;
6514 }
6515 if (CONST_INT_P (operands[1]))
6516 emit_insn (gen_storeinthi (operands[0], operands[1]));
6517 else
6518 {
6519 if (MEM_P (operands[1]))
6520 operands[1] = force_reg (HImode, operands[1]);
6521 if (BYTES_BIG_ENDIAN)
6522 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6523 else
6524 emit_insn (gen_storehi (operands[1], operands[0]));
6525 }
6526 DONE;
6527 }
6528 /* Sign extend a constant, and keep it in an SImode reg. */
6529 else if (CONST_INT_P (operands[1]))
6530 {
6531 rtx reg = gen_reg_rtx (SImode);
6532 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6533
6534 /* If the constant is already valid, leave it alone. */
6535 if (!const_ok_for_arm (val))
6536 {
6537 /* If setting all the top bits will make the constant
6538 loadable in a single instruction, then set them.
6539 Otherwise, sign extend the number. */
6540
6541 if (const_ok_for_arm (~(val | ~0xffff)))
6542 val |= ~0xffff;
6543 else if (val & 0x8000)
6544 val |= ~0xffff;
6545 }
6546
6547 emit_insn (gen_movsi (reg, GEN_INT (val)));
6548 operands[1] = gen_lowpart (HImode, reg);
6549 }
6550 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6551 && MEM_P (operands[1]))
6552 {
6553 rtx reg = gen_reg_rtx (SImode);
6554
6555 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6556 operands[1] = gen_lowpart (HImode, reg);
6557 }
6558 else if (!arm_arch4)
6559 {
6560 if (MEM_P (operands[1]))
6561 {
6562 rtx base;
6563 rtx offset = const0_rtx;
6564 rtx reg = gen_reg_rtx (SImode);
6565
6566 if ((REG_P (base = XEXP (operands[1], 0))
6567 || (GET_CODE (base) == PLUS
6568 && (CONST_INT_P (offset = XEXP (base, 1)))
6569 && ((INTVAL(offset) & 1) != 1)
6570 && REG_P (base = XEXP (base, 0))))
6571 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6572 {
6573 rtx new_rtx;
6574
6575 new_rtx = widen_memory_access (operands[1], SImode,
6576 ((INTVAL (offset) & ~3)
6577 - INTVAL (offset)));
6578 emit_insn (gen_movsi (reg, new_rtx));
6579 if (((INTVAL (offset) & 2) != 0)
6580 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6581 {
6582 rtx reg2 = gen_reg_rtx (SImode);
6583
6584 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6585 reg = reg2;
6586 }
6587 }
6588 else
6589 emit_insn (gen_movhi_bytes (reg, operands[1]));
6590
6591 operands[1] = gen_lowpart (HImode, reg);
6592 }
6593 }
6594 }
6595 /* Handle loading a large integer during reload. */
6596 else if (CONST_INT_P (operands[1])
6597 && !const_ok_for_arm (INTVAL (operands[1]))
6598 && !const_ok_for_arm (~INTVAL (operands[1])))
6599 {
6600 /* Writing a constant to memory needs a scratch, which should
6601 be handled with SECONDARY_RELOADs. */
6602 gcc_assert (REG_P (operands[0]));
6603
6604 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6605 emit_insn (gen_movsi (operands[0], operands[1]));
6606 DONE;
6607 }
6608 }
6609 else if (TARGET_THUMB2)
6610 {
6611 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6612 if (can_create_pseudo_p ())
6613 {
6614 if (!REG_P (operands[0]))
6615 operands[1] = force_reg (HImode, operands[1]);
6616 /* Zero extend a constant, and keep it in an SImode reg. */
6617 else if (CONST_INT_P (operands[1]))
6618 {
6619 rtx reg = gen_reg_rtx (SImode);
6620 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6621
6622 emit_insn (gen_movsi (reg, GEN_INT (val)));
6623 operands[1] = gen_lowpart (HImode, reg);
6624 }
6625 }
6626 }
6627 else /* TARGET_THUMB1 */
6628 {
6629 if (can_create_pseudo_p ())
6630 {
6631 if (CONST_INT_P (operands[1]))
6632 {
6633 rtx reg = gen_reg_rtx (SImode);
6634
6635 emit_insn (gen_movsi (reg, operands[1]));
6636 operands[1] = gen_lowpart (HImode, reg);
6637 }
6638
6639 /* ??? We shouldn't really get invalid addresses here, but this can
6640 happen if we are passed a SP (never OK for HImode/QImode) or
6641 virtual register (also rejected as illegitimate for HImode/QImode)
6642 relative address. */
6643 /* ??? This should perhaps be fixed elsewhere, for instance, in
6644 fixup_stack_1, by checking for other kinds of invalid addresses,
6645 e.g. a bare reference to a virtual register. This may confuse the
6646 alpha though, which must handle this case differently. */
6647 if (MEM_P (operands[0])
6648 && !memory_address_p (GET_MODE (operands[0]),
6649 XEXP (operands[0], 0)))
6650 operands[0]
6651 = replace_equiv_address (operands[0],
6652 copy_to_reg (XEXP (operands[0], 0)));
6653
6654 if (MEM_P (operands[1])
6655 && !memory_address_p (GET_MODE (operands[1]),
6656 XEXP (operands[1], 0)))
6657 operands[1]
6658 = replace_equiv_address (operands[1],
6659 copy_to_reg (XEXP (operands[1], 0)));
6660
6661 if (MEM_P (operands[1]) && optimize > 0)
6662 {
6663 rtx reg = gen_reg_rtx (SImode);
6664
6665 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6666 operands[1] = gen_lowpart (HImode, reg);
6667 }
6668
6669 if (MEM_P (operands[0]))
6670 operands[1] = force_reg (HImode, operands[1]);
6671 }
6672 else if (CONST_INT_P (operands[1])
6673 && !satisfies_constraint_I (operands[1]))
6674 {
6675 /* Handle loading a large integer during reload. */
6676
6677 /* Writing a constant to memory needs a scratch, which should
6678 be handled with SECONDARY_RELOADs. */
6679 gcc_assert (REG_P (operands[0]));
6680
6681 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6682 emit_insn (gen_movsi (operands[0], operands[1]));
6683 DONE;
6684 }
6685 }
6686 "
6687 )
6688
6689 (define_expand "movhi_bytes"
6690 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6691 (set (match_dup 3)
6692 (zero_extend:SI (match_dup 6)))
6693 (set (match_operand:SI 0 "" "")
6694 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6695 "TARGET_ARM"
6696 "
6697 {
6698 rtx mem1, mem2;
6699 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6700
6701 mem1 = change_address (operands[1], QImode, addr);
6702 mem2 = change_address (operands[1], QImode,
6703 plus_constant (Pmode, addr, 1));
6704 operands[0] = gen_lowpart (SImode, operands[0]);
6705 operands[1] = mem1;
6706 operands[2] = gen_reg_rtx (SImode);
6707 operands[3] = gen_reg_rtx (SImode);
6708 operands[6] = mem2;
6709
6710 if (BYTES_BIG_ENDIAN)
6711 {
6712 operands[4] = operands[2];
6713 operands[5] = operands[3];
6714 }
6715 else
6716 {
6717 operands[4] = operands[3];
6718 operands[5] = operands[2];
6719 }
6720 }"
6721 )
6722
6723 (define_expand "movhi_bigend"
6724 [(set (match_dup 2)
6725 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6726 (const_int 16)))
6727 (set (match_dup 3)
6728 (ashiftrt:SI (match_dup 2) (const_int 16)))
6729 (set (match_operand:HI 0 "s_register_operand" "")
6730 (match_dup 4))]
6731 "TARGET_ARM"
6732 "
6733 operands[2] = gen_reg_rtx (SImode);
6734 operands[3] = gen_reg_rtx (SImode);
6735 operands[4] = gen_lowpart (HImode, operands[3]);
6736 "
6737 )
6738
6739 ;; Pattern to recognize insn generated default case above
6740 (define_insn "*movhi_insn_arch4"
6741 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6742 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6743 "TARGET_ARM
6744 && arm_arch4 && !TARGET_HARD_FLOAT
6745 && (register_operand (operands[0], HImode)
6746 || register_operand (operands[1], HImode))"
6747 "@
6748 mov%?\\t%0, %1\\t%@ movhi
6749 mvn%?\\t%0, #%B1\\t%@ movhi
6750 movw%?\\t%0, %L1\\t%@ movhi
6751 strh%?\\t%1, %0\\t%@ movhi
6752 ldrh%?\\t%0, %1\\t%@ movhi"
6753 [(set_attr "predicable" "yes")
6754 (set_attr "pool_range" "*,*,*,*,256")
6755 (set_attr "neg_pool_range" "*,*,*,*,244")
6756 (set_attr "arch" "*,*,v6t2,*,*")
6757 (set_attr_alternative "type"
6758 [(if_then_else (match_operand 1 "const_int_operand" "")
6759 (const_string "mov_imm" )
6760 (const_string "mov_reg"))
6761 (const_string "mvn_imm")
6762 (const_string "mov_imm")
6763 (const_string "store_4")
6764 (const_string "load_4")])]
6765 )
6766
6767 (define_insn "*movhi_bytes"
6768 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6769 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6770 "TARGET_ARM && !TARGET_HARD_FLOAT"
6771 "@
6772 mov%?\\t%0, %1\\t%@ movhi
6773 mov%?\\t%0, %1\\t%@ movhi
6774 mvn%?\\t%0, #%B1\\t%@ movhi"
6775 [(set_attr "predicable" "yes")
6776 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6777 )
6778
6779 ;; We use a DImode scratch because we may occasionally need an additional
6780 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6781 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6782 (define_expand "reload_outhi"
6783 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6784 (match_operand:HI 1 "s_register_operand" "r")
6785 (match_operand:DI 2 "s_register_operand" "=&l")])]
6786 "TARGET_EITHER"
6787 "if (TARGET_ARM)
6788 arm_reload_out_hi (operands);
6789 else
6790 thumb_reload_out_hi (operands);
6791 DONE;
6792 "
6793 )
6794
6795 (define_expand "reload_inhi"
6796 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6797 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6798 (match_operand:DI 2 "s_register_operand" "=&r")])]
6799 "TARGET_EITHER"
6800 "
6801 if (TARGET_ARM)
6802 arm_reload_in_hi (operands);
6803 else
6804 thumb_reload_out_hi (operands);
6805 DONE;
6806 ")
6807
6808 (define_expand "movqi"
6809 [(set (match_operand:QI 0 "general_operand" "")
6810 (match_operand:QI 1 "general_operand" ""))]
6811 "TARGET_EITHER"
6812 "
6813 /* Everything except mem = const or mem = mem can be done easily */
6814
6815 if (can_create_pseudo_p ())
6816 {
6817 if (CONST_INT_P (operands[1]))
6818 {
6819 rtx reg = gen_reg_rtx (SImode);
6820
6821 /* For thumb we want an unsigned immediate, then we are more likely
6822 to be able to use a movs insn. */
6823 if (TARGET_THUMB)
6824 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6825
6826 emit_insn (gen_movsi (reg, operands[1]));
6827 operands[1] = gen_lowpart (QImode, reg);
6828 }
6829
6830 if (TARGET_THUMB)
6831 {
6832 /* ??? We shouldn't really get invalid addresses here, but this can
6833 happen if we are passed a SP (never OK for HImode/QImode) or
6834 virtual register (also rejected as illegitimate for HImode/QImode)
6835 relative address. */
6836 /* ??? This should perhaps be fixed elsewhere, for instance, in
6837 fixup_stack_1, by checking for other kinds of invalid addresses,
6838 e.g. a bare reference to a virtual register. This may confuse the
6839 alpha though, which must handle this case differently. */
6840 if (MEM_P (operands[0])
6841 && !memory_address_p (GET_MODE (operands[0]),
6842 XEXP (operands[0], 0)))
6843 operands[0]
6844 = replace_equiv_address (operands[0],
6845 copy_to_reg (XEXP (operands[0], 0)));
6846 if (MEM_P (operands[1])
6847 && !memory_address_p (GET_MODE (operands[1]),
6848 XEXP (operands[1], 0)))
6849 operands[1]
6850 = replace_equiv_address (operands[1],
6851 copy_to_reg (XEXP (operands[1], 0)));
6852 }
6853
6854 if (MEM_P (operands[1]) && optimize > 0)
6855 {
6856 rtx reg = gen_reg_rtx (SImode);
6857
6858 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6859 operands[1] = gen_lowpart (QImode, reg);
6860 }
6861
6862 if (MEM_P (operands[0]))
6863 operands[1] = force_reg (QImode, operands[1]);
6864 }
6865 else if (TARGET_THUMB
6866 && CONST_INT_P (operands[1])
6867 && !satisfies_constraint_I (operands[1]))
6868 {
6869 /* Handle loading a large integer during reload. */
6870
6871 /* Writing a constant to memory needs a scratch, which should
6872 be handled with SECONDARY_RELOADs. */
6873 gcc_assert (REG_P (operands[0]));
6874
6875 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6876 emit_insn (gen_movsi (operands[0], operands[1]));
6877 DONE;
6878 }
6879 "
6880 )
6881
6882 (define_insn "*arm_movqi_insn"
6883 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6884 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6885 "TARGET_32BIT
6886 && ( register_operand (operands[0], QImode)
6887 || register_operand (operands[1], QImode))"
6888 "@
6889 mov%?\\t%0, %1
6890 mov%?\\t%0, %1
6891 mov%?\\t%0, %1
6892 mov%?\\t%0, %1
6893 mvn%?\\t%0, #%B1
6894 ldrb%?\\t%0, %1
6895 strb%?\\t%1, %0
6896 ldrb%?\\t%0, %1
6897 strb%?\\t%1, %0"
6898 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6899 (set_attr "predicable" "yes")
6900 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6901 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6902 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6903 )
6904
6905 ;; HFmode moves
6906 (define_expand "movhf"
6907 [(set (match_operand:HF 0 "general_operand" "")
6908 (match_operand:HF 1 "general_operand" ""))]
6909 "TARGET_EITHER"
6910 "
6911 if (TARGET_32BIT)
6912 {
6913 if (MEM_P (operands[0]))
6914 operands[1] = force_reg (HFmode, operands[1]);
6915 }
6916 else /* TARGET_THUMB1 */
6917 {
6918 if (can_create_pseudo_p ())
6919 {
6920 if (!REG_P (operands[0]))
6921 operands[1] = force_reg (HFmode, operands[1]);
6922 }
6923 }
6924 "
6925 )
6926
6927 (define_insn "*arm32_movhf"
6928 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6929 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6930 "TARGET_32BIT && !TARGET_HARD_FLOAT
6931 && ( s_register_operand (operands[0], HFmode)
6932 || s_register_operand (operands[1], HFmode))"
6933 "*
6934 switch (which_alternative)
6935 {
6936 case 0: /* ARM register from memory */
6937 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6938 case 1: /* memory from ARM register */
6939 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6940 case 2: /* ARM register from ARM register */
6941 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6942 case 3: /* ARM register from constant */
6943 {
6944 long bits;
6945 rtx ops[4];
6946
6947 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6948 HFmode);
6949 ops[0] = operands[0];
6950 ops[1] = GEN_INT (bits);
6951 ops[2] = GEN_INT (bits & 0xff00);
6952 ops[3] = GEN_INT (bits & 0x00ff);
6953
6954 if (arm_arch_thumb2)
6955 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6956 else
6957 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6958 return \"\";
6959 }
6960 default:
6961 gcc_unreachable ();
6962 }
6963 "
6964 [(set_attr "conds" "unconditional")
6965 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6966 (set_attr "length" "4,4,4,8")
6967 (set_attr "predicable" "yes")
6968 (set_attr "predicable_short_it" "no")]
6969 )
6970
6971 (define_expand "movsf"
6972 [(set (match_operand:SF 0 "general_operand" "")
6973 (match_operand:SF 1 "general_operand" ""))]
6974 "TARGET_EITHER"
6975 "
6976 if (TARGET_32BIT)
6977 {
6978 if (MEM_P (operands[0]))
6979 operands[1] = force_reg (SFmode, operands[1]);
6980 }
6981 else /* TARGET_THUMB1 */
6982 {
6983 if (can_create_pseudo_p ())
6984 {
6985 if (!REG_P (operands[0]))
6986 operands[1] = force_reg (SFmode, operands[1]);
6987 }
6988 }
6989 "
6990 )
6991
6992 ;; Transform a floating-point move of a constant into a core register into
6993 ;; an SImode operation.
6994 (define_split
6995 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6996 (match_operand:SF 1 "immediate_operand" ""))]
6997 "TARGET_EITHER
6998 && reload_completed
6999 && CONST_DOUBLE_P (operands[1])"
7000 [(set (match_dup 2) (match_dup 3))]
7001 "
7002 operands[2] = gen_lowpart (SImode, operands[0]);
7003 operands[3] = gen_lowpart (SImode, operands[1]);
7004 if (operands[2] == 0 || operands[3] == 0)
7005 FAIL;
7006 "
7007 )
7008
7009 (define_insn "*arm_movsf_soft_insn"
7010 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7011 (match_operand:SF 1 "general_operand" "r,mE,r"))]
7012 "TARGET_32BIT
7013 && TARGET_SOFT_FLOAT
7014 && (!MEM_P (operands[0])
7015 || register_operand (operands[1], SFmode))"
7016 "@
7017 mov%?\\t%0, %1
7018 ldr%?\\t%0, %1\\t%@ float
7019 str%?\\t%1, %0\\t%@ float"
7020 [(set_attr "predicable" "yes")
7021 (set_attr "predicable_short_it" "no")
7022 (set_attr "type" "mov_reg,load_4,store_4")
7023 (set_attr "arm_pool_range" "*,4096,*")
7024 (set_attr "thumb2_pool_range" "*,4094,*")
7025 (set_attr "arm_neg_pool_range" "*,4084,*")
7026 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7027 )
7028
7029 (define_expand "movdf"
7030 [(set (match_operand:DF 0 "general_operand" "")
7031 (match_operand:DF 1 "general_operand" ""))]
7032 "TARGET_EITHER"
7033 "
7034 if (TARGET_32BIT)
7035 {
7036 if (MEM_P (operands[0]))
7037 operands[1] = force_reg (DFmode, operands[1]);
7038 }
7039 else /* TARGET_THUMB */
7040 {
7041 if (can_create_pseudo_p ())
7042 {
7043 if (!REG_P (operands[0]))
7044 operands[1] = force_reg (DFmode, operands[1]);
7045 }
7046 }
7047 "
7048 )
7049
7050 ;; Reloading a df mode value stored in integer regs to memory can require a
7051 ;; scratch reg.
7052 (define_expand "reload_outdf"
7053 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7054 (match_operand:DF 1 "s_register_operand" "r")
7055 (match_operand:SI 2 "s_register_operand" "=&r")]
7056 "TARGET_THUMB2"
7057 "
7058 {
7059 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7060
7061 if (code == REG)
7062 operands[2] = XEXP (operands[0], 0);
7063 else if (code == POST_INC || code == PRE_DEC)
7064 {
7065 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7066 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7067 emit_insn (gen_movdi (operands[0], operands[1]));
7068 DONE;
7069 }
7070 else if (code == PRE_INC)
7071 {
7072 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7073
7074 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7075 operands[2] = reg;
7076 }
7077 else if (code == POST_DEC)
7078 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7079 else
7080 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7081 XEXP (XEXP (operands[0], 0), 1)));
7082
7083 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7084 operands[1]));
7085
7086 if (code == POST_DEC)
7087 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7088
7089 DONE;
7090 }"
7091 )
7092
7093 (define_insn "*movdf_soft_insn"
7094 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7095 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7096 "TARGET_32BIT && TARGET_SOFT_FLOAT
7097 && ( register_operand (operands[0], DFmode)
7098 || register_operand (operands[1], DFmode))"
7099 "*
7100 switch (which_alternative)
7101 {
7102 case 0:
7103 case 1:
7104 case 2:
7105 return \"#\";
7106 default:
7107 return output_move_double (operands, true, NULL);
7108 }
7109 "
7110 [(set_attr "length" "8,12,16,8,8")
7111 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7112 (set_attr "arm_pool_range" "*,*,*,1020,*")
7113 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7114 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7115 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7116 )
7117 \f
7118
7119 ;; load- and store-multiple insns
7120 ;; The arm can load/store any set of registers, provided that they are in
7121 ;; ascending order, but these expanders assume a contiguous set.
7122
7123 (define_expand "load_multiple"
7124 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7125 (match_operand:SI 1 "" ""))
7126 (use (match_operand:SI 2 "" ""))])]
7127 "TARGET_32BIT"
7128 {
7129 HOST_WIDE_INT offset = 0;
7130
7131 /* Support only fixed point registers. */
7132 if (!CONST_INT_P (operands[2])
7133 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7134 || INTVAL (operands[2]) < 2
7135 || !MEM_P (operands[1])
7136 || !REG_P (operands[0])
7137 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7138 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7139 FAIL;
7140
7141 operands[3]
7142 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7143 INTVAL (operands[2]),
7144 force_reg (SImode, XEXP (operands[1], 0)),
7145 FALSE, operands[1], &offset);
7146 })
7147
7148 (define_expand "store_multiple"
7149 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7150 (match_operand:SI 1 "" ""))
7151 (use (match_operand:SI 2 "" ""))])]
7152 "TARGET_32BIT"
7153 {
7154 HOST_WIDE_INT offset = 0;
7155
7156 /* Support only fixed point registers. */
7157 if (!CONST_INT_P (operands[2])
7158 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7159 || INTVAL (operands[2]) < 2
7160 || !REG_P (operands[1])
7161 || !MEM_P (operands[0])
7162 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7163 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7164 FAIL;
7165
7166 operands[3]
7167 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7168 INTVAL (operands[2]),
7169 force_reg (SImode, XEXP (operands[0], 0)),
7170 FALSE, operands[0], &offset);
7171 })
7172
7173
7174 (define_expand "setmemsi"
7175 [(match_operand:BLK 0 "general_operand" "")
7176 (match_operand:SI 1 "const_int_operand" "")
7177 (match_operand:SI 2 "const_int_operand" "")
7178 (match_operand:SI 3 "const_int_operand" "")]
7179 "TARGET_32BIT"
7180 {
7181 if (arm_gen_setmem (operands))
7182 DONE;
7183
7184 FAIL;
7185 })
7186
7187
7188 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7189 ;; We could let this apply for blocks of less than this, but it clobbers so
7190 ;; many registers that there is then probably a better way.
7191
7192 (define_expand "movmemqi"
7193 [(match_operand:BLK 0 "general_operand" "")
7194 (match_operand:BLK 1 "general_operand" "")
7195 (match_operand:SI 2 "const_int_operand" "")
7196 (match_operand:SI 3 "const_int_operand" "")]
7197 ""
7198 "
7199 if (TARGET_32BIT)
7200 {
7201 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7202 && !optimize_function_for_size_p (cfun))
7203 {
7204 if (gen_movmem_ldrd_strd (operands))
7205 DONE;
7206 FAIL;
7207 }
7208
7209 if (arm_gen_movmemqi (operands))
7210 DONE;
7211 FAIL;
7212 }
7213 else /* TARGET_THUMB1 */
7214 {
7215 if ( INTVAL (operands[3]) != 4
7216 || INTVAL (operands[2]) > 48)
7217 FAIL;
7218
7219 thumb_expand_movmemqi (operands);
7220 DONE;
7221 }
7222 "
7223 )
7224 \f
7225
7226 ;; Compare & branch insns
7227 ;; The range calculations are based as follows:
7228 ;; For forward branches, the address calculation returns the address of
7229 ;; the next instruction. This is 2 beyond the branch instruction.
7230 ;; For backward branches, the address calculation returns the address of
7231 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7232 ;; instruction for the shortest sequence, and 4 before the branch instruction
7233 ;; if we have to jump around an unconditional branch.
7234 ;; To the basic branch range the PC offset must be added (this is +4).
7235 ;; So for forward branches we have
7236 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7237 ;; And for backward branches we have
7238 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7239 ;;
7240 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7241 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7242
7243 (define_expand "cbranchsi4"
7244 [(set (pc) (if_then_else
7245 (match_operator 0 "expandable_comparison_operator"
7246 [(match_operand:SI 1 "s_register_operand" "")
7247 (match_operand:SI 2 "nonmemory_operand" "")])
7248 (label_ref (match_operand 3 "" ""))
7249 (pc)))]
7250 "TARGET_EITHER"
7251 "
7252 if (!TARGET_THUMB1)
7253 {
7254 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7255 FAIL;
7256 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7257 operands[3]));
7258 DONE;
7259 }
7260 if (thumb1_cmpneg_operand (operands[2], SImode))
7261 {
7262 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7263 operands[3], operands[0]));
7264 DONE;
7265 }
7266 if (!thumb1_cmp_operand (operands[2], SImode))
7267 operands[2] = force_reg (SImode, operands[2]);
7268 ")
7269
7270 (define_expand "cbranchsf4"
7271 [(set (pc) (if_then_else
7272 (match_operator 0 "expandable_comparison_operator"
7273 [(match_operand:SF 1 "s_register_operand" "")
7274 (match_operand:SF 2 "vfp_compare_operand" "")])
7275 (label_ref (match_operand 3 "" ""))
7276 (pc)))]
7277 "TARGET_32BIT && TARGET_HARD_FLOAT"
7278 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7279 operands[3])); DONE;"
7280 )
7281
7282 (define_expand "cbranchdf4"
7283 [(set (pc) (if_then_else
7284 (match_operator 0 "expandable_comparison_operator"
7285 [(match_operand:DF 1 "s_register_operand" "")
7286 (match_operand:DF 2 "vfp_compare_operand" "")])
7287 (label_ref (match_operand 3 "" ""))
7288 (pc)))]
7289 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7290 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7291 operands[3])); DONE;"
7292 )
7293
7294 (define_expand "cbranchdi4"
7295 [(set (pc) (if_then_else
7296 (match_operator 0 "expandable_comparison_operator"
7297 [(match_operand:DI 1 "s_register_operand" "")
7298 (match_operand:DI 2 "cmpdi_operand" "")])
7299 (label_ref (match_operand 3 "" ""))
7300 (pc)))]
7301 "TARGET_32BIT"
7302 "{
7303 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7304 FAIL;
7305 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7306 operands[3]));
7307 DONE;
7308 }"
7309 )
7310
7311 ;; Comparison and test insns
7312
7313 (define_insn "*arm_cmpsi_insn"
7314 [(set (reg:CC CC_REGNUM)
7315 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7316 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7317 "TARGET_32BIT"
7318 "@
7319 cmp%?\\t%0, %1
7320 cmp%?\\t%0, %1
7321 cmp%?\\t%0, %1
7322 cmp%?\\t%0, %1
7323 cmn%?\\t%0, #%n1"
7324 [(set_attr "conds" "set")
7325 (set_attr "arch" "t2,t2,any,any,any")
7326 (set_attr "length" "2,2,4,4,4")
7327 (set_attr "predicable" "yes")
7328 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7329 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7330 )
7331
7332 (define_insn "*cmpsi_shiftsi"
7333 [(set (reg:CC CC_REGNUM)
7334 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7335 (match_operator:SI 3 "shift_operator"
7336 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7337 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7338 "TARGET_32BIT"
7339 "cmp\\t%0, %1%S3"
7340 [(set_attr "conds" "set")
7341 (set_attr "shift" "1")
7342 (set_attr "arch" "32,a,a")
7343 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7344
7345 (define_insn "*cmpsi_shiftsi_swp"
7346 [(set (reg:CC_SWP CC_REGNUM)
7347 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7348 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7349 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7350 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7351 "TARGET_32BIT"
7352 "cmp%?\\t%0, %1%S3"
7353 [(set_attr "conds" "set")
7354 (set_attr "shift" "1")
7355 (set_attr "arch" "32,a,a")
7356 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7357
7358 (define_insn "*arm_cmpsi_negshiftsi_si"
7359 [(set (reg:CC_Z CC_REGNUM)
7360 (compare:CC_Z
7361 (neg:SI (match_operator:SI 1 "shift_operator"
7362 [(match_operand:SI 2 "s_register_operand" "r")
7363 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7364 (match_operand:SI 0 "s_register_operand" "r")))]
7365 "TARGET_ARM"
7366 "cmn%?\\t%0, %2%S1"
7367 [(set_attr "conds" "set")
7368 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7369 (const_string "alus_shift_imm")
7370 (const_string "alus_shift_reg")))
7371 (set_attr "predicable" "yes")]
7372 )
7373
7374 ;; DImode comparisons. The generic code generates branches that
7375 ;; if-conversion can not reduce to a conditional compare, so we do
7376 ;; that directly.
7377
7378 (define_insn_and_split "*arm_cmpdi_insn"
7379 [(set (reg:CC_NCV CC_REGNUM)
7380 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7381 (match_operand:DI 1 "arm_di_operand" "rDi")))
7382 (clobber (match_scratch:SI 2 "=r"))]
7383 "TARGET_32BIT"
7384 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7385 "&& reload_completed"
7386 [(set (reg:CC CC_REGNUM)
7387 (compare:CC (match_dup 0) (match_dup 1)))
7388 (parallel [(set (reg:CC CC_REGNUM)
7389 (compare:CC (match_dup 3) (match_dup 4)))
7390 (set (match_dup 2)
7391 (minus:SI (match_dup 5)
7392 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7393 {
7394 operands[3] = gen_highpart (SImode, operands[0]);
7395 operands[0] = gen_lowpart (SImode, operands[0]);
7396 if (CONST_INT_P (operands[1]))
7397 {
7398 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7399 DImode,
7400 operands[1])));
7401 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7402 }
7403 else
7404 {
7405 operands[4] = gen_highpart (SImode, operands[1]);
7406 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7407 }
7408 operands[1] = gen_lowpart (SImode, operands[1]);
7409 operands[2] = gen_lowpart (SImode, operands[2]);
7410 }
7411 [(set_attr "conds" "set")
7412 (set_attr "length" "8")
7413 (set_attr "type" "multiple")]
7414 )
7415
7416 (define_insn_and_split "*arm_cmpdi_unsigned"
7417 [(set (reg:CC_CZ CC_REGNUM)
7418 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7419 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7420
7421 "TARGET_32BIT"
7422 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7423 "&& reload_completed"
7424 [(set (reg:CC CC_REGNUM)
7425 (compare:CC (match_dup 2) (match_dup 3)))
7426 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7427 (set (reg:CC CC_REGNUM)
7428 (compare:CC (match_dup 0) (match_dup 1))))]
7429 {
7430 operands[2] = gen_highpart (SImode, operands[0]);
7431 operands[0] = gen_lowpart (SImode, operands[0]);
7432 if (CONST_INT_P (operands[1]))
7433 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7434 else
7435 operands[3] = gen_highpart (SImode, operands[1]);
7436 operands[1] = gen_lowpart (SImode, operands[1]);
7437 }
7438 [(set_attr "conds" "set")
7439 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7440 (set_attr "arch" "t2,t2,t2,a")
7441 (set_attr "length" "6,6,10,8")
7442 (set_attr "type" "multiple")]
7443 )
7444
7445 (define_insn "*arm_cmpdi_zero"
7446 [(set (reg:CC_Z CC_REGNUM)
7447 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7448 (const_int 0)))
7449 (clobber (match_scratch:SI 1 "=r"))]
7450 "TARGET_32BIT"
7451 "orrs%?\\t%1, %Q0, %R0"
7452 [(set_attr "conds" "set")
7453 (set_attr "type" "logics_reg")]
7454 )
7455
7456 ; This insn allows redundant compares to be removed by cse, nothing should
7457 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7458 ; is deleted later on. The match_dup will match the mode here, so that
7459 ; mode changes of the condition codes aren't lost by this even though we don't
7460 ; specify what they are.
7461
7462 (define_insn "*deleted_compare"
7463 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7464 "TARGET_32BIT"
7465 "\\t%@ deleted compare"
7466 [(set_attr "conds" "set")
7467 (set_attr "length" "0")
7468 (set_attr "type" "no_insn")]
7469 )
7470
7471 \f
7472 ;; Conditional branch insns
7473
7474 (define_expand "cbranch_cc"
7475 [(set (pc)
7476 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7477 (match_operand 2 "" "")])
7478 (label_ref (match_operand 3 "" ""))
7479 (pc)))]
7480 "TARGET_32BIT"
7481 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7482 operands[1], operands[2], NULL_RTX);
7483 operands[2] = const0_rtx;"
7484 )
7485
7486 ;;
7487 ;; Patterns to match conditional branch insns.
7488 ;;
7489
7490 (define_insn "arm_cond_branch"
7491 [(set (pc)
7492 (if_then_else (match_operator 1 "arm_comparison_operator"
7493 [(match_operand 2 "cc_register" "") (const_int 0)])
7494 (label_ref (match_operand 0 "" ""))
7495 (pc)))]
7496 "TARGET_32BIT"
7497 "*
7498 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7499 {
7500 arm_ccfsm_state += 2;
7501 return \"\";
7502 }
7503 return \"b%d1\\t%l0\";
7504 "
7505 [(set_attr "conds" "use")
7506 (set_attr "type" "branch")
7507 (set (attr "length")
7508 (if_then_else
7509 (and (match_test "TARGET_THUMB2")
7510 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7511 (le (minus (match_dup 0) (pc)) (const_int 256))))
7512 (const_int 2)
7513 (const_int 4)))]
7514 )
7515
7516 (define_insn "*arm_cond_branch_reversed"
7517 [(set (pc)
7518 (if_then_else (match_operator 1 "arm_comparison_operator"
7519 [(match_operand 2 "cc_register" "") (const_int 0)])
7520 (pc)
7521 (label_ref (match_operand 0 "" ""))))]
7522 "TARGET_32BIT"
7523 "*
7524 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7525 {
7526 arm_ccfsm_state += 2;
7527 return \"\";
7528 }
7529 return \"b%D1\\t%l0\";
7530 "
7531 [(set_attr "conds" "use")
7532 (set_attr "type" "branch")
7533 (set (attr "length")
7534 (if_then_else
7535 (and (match_test "TARGET_THUMB2")
7536 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7537 (le (minus (match_dup 0) (pc)) (const_int 256))))
7538 (const_int 2)
7539 (const_int 4)))]
7540 )
7541
7542 \f
7543
7544 ; scc insns
7545
7546 (define_expand "cstore_cc"
7547 [(set (match_operand:SI 0 "s_register_operand" "")
7548 (match_operator:SI 1 "" [(match_operand 2 "" "")
7549 (match_operand 3 "" "")]))]
7550 "TARGET_32BIT"
7551 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7552 operands[2], operands[3], NULL_RTX);
7553 operands[3] = const0_rtx;"
7554 )
7555
7556 (define_insn_and_split "*mov_scc"
7557 [(set (match_operand:SI 0 "s_register_operand" "=r")
7558 (match_operator:SI 1 "arm_comparison_operator_mode"
7559 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7560 "TARGET_ARM"
7561 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7562 "TARGET_ARM"
7563 [(set (match_dup 0)
7564 (if_then_else:SI (match_dup 1)
7565 (const_int 1)
7566 (const_int 0)))]
7567 ""
7568 [(set_attr "conds" "use")
7569 (set_attr "length" "8")
7570 (set_attr "type" "multiple")]
7571 )
7572
7573 (define_insn_and_split "*mov_negscc"
7574 [(set (match_operand:SI 0 "s_register_operand" "=r")
7575 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7576 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7577 "TARGET_ARM"
7578 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7579 "TARGET_ARM"
7580 [(set (match_dup 0)
7581 (if_then_else:SI (match_dup 1)
7582 (match_dup 3)
7583 (const_int 0)))]
7584 {
7585 operands[3] = GEN_INT (~0);
7586 }
7587 [(set_attr "conds" "use")
7588 (set_attr "length" "8")
7589 (set_attr "type" "multiple")]
7590 )
7591
7592 (define_insn_and_split "*mov_notscc"
7593 [(set (match_operand:SI 0 "s_register_operand" "=r")
7594 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7595 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7596 "TARGET_ARM"
7597 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7598 "TARGET_ARM"
7599 [(set (match_dup 0)
7600 (if_then_else:SI (match_dup 1)
7601 (match_dup 3)
7602 (match_dup 4)))]
7603 {
7604 operands[3] = GEN_INT (~1);
7605 operands[4] = GEN_INT (~0);
7606 }
7607 [(set_attr "conds" "use")
7608 (set_attr "length" "8")
7609 (set_attr "type" "multiple")]
7610 )
7611
7612 (define_expand "cstoresi4"
7613 [(set (match_operand:SI 0 "s_register_operand" "")
7614 (match_operator:SI 1 "expandable_comparison_operator"
7615 [(match_operand:SI 2 "s_register_operand" "")
7616 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7617 "TARGET_32BIT || TARGET_THUMB1"
7618 "{
7619 rtx op3, scratch, scratch2;
7620
7621 if (!TARGET_THUMB1)
7622 {
7623 if (!arm_add_operand (operands[3], SImode))
7624 operands[3] = force_reg (SImode, operands[3]);
7625 emit_insn (gen_cstore_cc (operands[0], operands[1],
7626 operands[2], operands[3]));
7627 DONE;
7628 }
7629
7630 if (operands[3] == const0_rtx)
7631 {
7632 switch (GET_CODE (operands[1]))
7633 {
7634 case EQ:
7635 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7636 break;
7637
7638 case NE:
7639 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7640 break;
7641
7642 case LE:
7643 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7644 NULL_RTX, 0, OPTAB_WIDEN);
7645 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7646 NULL_RTX, 0, OPTAB_WIDEN);
7647 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7648 operands[0], 1, OPTAB_WIDEN);
7649 break;
7650
7651 case GE:
7652 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7653 NULL_RTX, 1);
7654 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7655 NULL_RTX, 1, OPTAB_WIDEN);
7656 break;
7657
7658 case GT:
7659 scratch = expand_binop (SImode, ashr_optab, operands[2],
7660 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7661 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7662 NULL_RTX, 0, OPTAB_WIDEN);
7663 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7664 0, OPTAB_WIDEN);
7665 break;
7666
7667 /* LT is handled by generic code. No need for unsigned with 0. */
7668 default:
7669 FAIL;
7670 }
7671 DONE;
7672 }
7673
7674 switch (GET_CODE (operands[1]))
7675 {
7676 case EQ:
7677 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7678 NULL_RTX, 0, OPTAB_WIDEN);
7679 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7680 break;
7681
7682 case NE:
7683 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7684 NULL_RTX, 0, OPTAB_WIDEN);
7685 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7686 break;
7687
7688 case LE:
7689 op3 = force_reg (SImode, operands[3]);
7690
7691 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7692 NULL_RTX, 1, OPTAB_WIDEN);
7693 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7694 NULL_RTX, 0, OPTAB_WIDEN);
7695 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7696 op3, operands[2]));
7697 break;
7698
7699 case GE:
7700 op3 = operands[3];
7701 if (!thumb1_cmp_operand (op3, SImode))
7702 op3 = force_reg (SImode, op3);
7703 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7704 NULL_RTX, 0, OPTAB_WIDEN);
7705 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7706 NULL_RTX, 1, OPTAB_WIDEN);
7707 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7708 operands[2], op3));
7709 break;
7710
7711 case LEU:
7712 op3 = force_reg (SImode, operands[3]);
7713 scratch = force_reg (SImode, const0_rtx);
7714 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7715 op3, operands[2]));
7716 break;
7717
7718 case GEU:
7719 op3 = operands[3];
7720 if (!thumb1_cmp_operand (op3, SImode))
7721 op3 = force_reg (SImode, op3);
7722 scratch = force_reg (SImode, const0_rtx);
7723 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7724 operands[2], op3));
7725 break;
7726
7727 case LTU:
7728 op3 = operands[3];
7729 if (!thumb1_cmp_operand (op3, SImode))
7730 op3 = force_reg (SImode, op3);
7731 scratch = gen_reg_rtx (SImode);
7732 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7733 break;
7734
7735 case GTU:
7736 op3 = force_reg (SImode, operands[3]);
7737 scratch = gen_reg_rtx (SImode);
7738 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7739 break;
7740
7741 /* No good sequences for GT, LT. */
7742 default:
7743 FAIL;
7744 }
7745 DONE;
7746 }")
7747
7748 (define_expand "cstorehf4"
7749 [(set (match_operand:SI 0 "s_register_operand")
7750 (match_operator:SI 1 "expandable_comparison_operator"
7751 [(match_operand:HF 2 "s_register_operand")
7752 (match_operand:HF 3 "vfp_compare_operand")]))]
7753 "TARGET_VFP_FP16INST"
7754 {
7755 if (!arm_validize_comparison (&operands[1],
7756 &operands[2],
7757 &operands[3]))
7758 FAIL;
7759
7760 emit_insn (gen_cstore_cc (operands[0], operands[1],
7761 operands[2], operands[3]));
7762 DONE;
7763 }
7764 )
7765
7766 (define_expand "cstoresf4"
7767 [(set (match_operand:SI 0 "s_register_operand" "")
7768 (match_operator:SI 1 "expandable_comparison_operator"
7769 [(match_operand:SF 2 "s_register_operand" "")
7770 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7771 "TARGET_32BIT && TARGET_HARD_FLOAT"
7772 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7773 operands[2], operands[3])); DONE;"
7774 )
7775
7776 (define_expand "cstoredf4"
7777 [(set (match_operand:SI 0 "s_register_operand" "")
7778 (match_operator:SI 1 "expandable_comparison_operator"
7779 [(match_operand:DF 2 "s_register_operand" "")
7780 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7781 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7782 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7783 operands[2], operands[3])); DONE;"
7784 )
7785
7786 (define_expand "cstoredi4"
7787 [(set (match_operand:SI 0 "s_register_operand" "")
7788 (match_operator:SI 1 "expandable_comparison_operator"
7789 [(match_operand:DI 2 "s_register_operand" "")
7790 (match_operand:DI 3 "cmpdi_operand" "")]))]
7791 "TARGET_32BIT"
7792 "{
7793 if (!arm_validize_comparison (&operands[1],
7794 &operands[2],
7795 &operands[3]))
7796 FAIL;
7797 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7798 operands[3]));
7799 DONE;
7800 }"
7801 )
7802
7803 \f
7804 ;; Conditional move insns
7805
7806 (define_expand "movsicc"
7807 [(set (match_operand:SI 0 "s_register_operand" "")
7808 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7809 (match_operand:SI 2 "arm_not_operand" "")
7810 (match_operand:SI 3 "arm_not_operand" "")))]
7811 "TARGET_32BIT"
7812 "
7813 {
7814 enum rtx_code code;
7815 rtx ccreg;
7816
7817 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7818 &XEXP (operands[1], 1)))
7819 FAIL;
7820
7821 code = GET_CODE (operands[1]);
7822 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7823 XEXP (operands[1], 1), NULL_RTX);
7824 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7825 }"
7826 )
7827
7828 (define_expand "movhfcc"
7829 [(set (match_operand:HF 0 "s_register_operand")
7830 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7831 (match_operand:HF 2 "s_register_operand")
7832 (match_operand:HF 3 "s_register_operand")))]
7833 "TARGET_VFP_FP16INST"
7834 "
7835 {
7836 enum rtx_code code = GET_CODE (operands[1]);
7837 rtx ccreg;
7838
7839 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7840 &XEXP (operands[1], 1)))
7841 FAIL;
7842
7843 code = GET_CODE (operands[1]);
7844 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7845 XEXP (operands[1], 1), NULL_RTX);
7846 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7847 }"
7848 )
7849
7850 (define_expand "movsfcc"
7851 [(set (match_operand:SF 0 "s_register_operand" "")
7852 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7853 (match_operand:SF 2 "s_register_operand" "")
7854 (match_operand:SF 3 "s_register_operand" "")))]
7855 "TARGET_32BIT && TARGET_HARD_FLOAT"
7856 "
7857 {
7858 enum rtx_code code = GET_CODE (operands[1]);
7859 rtx ccreg;
7860
7861 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7862 &XEXP (operands[1], 1)))
7863 FAIL;
7864
7865 code = GET_CODE (operands[1]);
7866 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7867 XEXP (operands[1], 1), NULL_RTX);
7868 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7869 }"
7870 )
7871
7872 (define_expand "movdfcc"
7873 [(set (match_operand:DF 0 "s_register_operand" "")
7874 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7875 (match_operand:DF 2 "s_register_operand" "")
7876 (match_operand:DF 3 "s_register_operand" "")))]
7877 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7878 "
7879 {
7880 enum rtx_code code = GET_CODE (operands[1]);
7881 rtx ccreg;
7882
7883 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7884 &XEXP (operands[1], 1)))
7885 FAIL;
7886 code = GET_CODE (operands[1]);
7887 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7888 XEXP (operands[1], 1), NULL_RTX);
7889 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7890 }"
7891 )
7892
7893 (define_insn "*cmov<mode>"
7894 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7895 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7896 [(match_operand 2 "cc_register" "") (const_int 0)])
7897 (match_operand:SDF 3 "s_register_operand"
7898 "<F_constraint>")
7899 (match_operand:SDF 4 "s_register_operand"
7900 "<F_constraint>")))]
7901 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7902 "*
7903 {
7904 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7905 switch (code)
7906 {
7907 case ARM_GE:
7908 case ARM_GT:
7909 case ARM_EQ:
7910 case ARM_VS:
7911 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7912 case ARM_LT:
7913 case ARM_LE:
7914 case ARM_NE:
7915 case ARM_VC:
7916 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7917 default:
7918 gcc_unreachable ();
7919 }
7920 return \"\";
7921 }"
7922 [(set_attr "conds" "use")
7923 (set_attr "type" "fcsel")]
7924 )
7925
7926 (define_insn "*cmovhf"
7927 [(set (match_operand:HF 0 "s_register_operand" "=t")
7928 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7929 [(match_operand 2 "cc_register" "") (const_int 0)])
7930 (match_operand:HF 3 "s_register_operand" "t")
7931 (match_operand:HF 4 "s_register_operand" "t")))]
7932 "TARGET_VFP_FP16INST"
7933 "*
7934 {
7935 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7936 switch (code)
7937 {
7938 case ARM_GE:
7939 case ARM_GT:
7940 case ARM_EQ:
7941 case ARM_VS:
7942 return \"vsel%d1.f16\\t%0, %3, %4\";
7943 case ARM_LT:
7944 case ARM_LE:
7945 case ARM_NE:
7946 case ARM_VC:
7947 return \"vsel%D1.f16\\t%0, %4, %3\";
7948 default:
7949 gcc_unreachable ();
7950 }
7951 return \"\";
7952 }"
7953 [(set_attr "conds" "use")
7954 (set_attr "type" "fcsel")]
7955 )
7956
7957 (define_insn_and_split "*movsicc_insn"
7958 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7959 (if_then_else:SI
7960 (match_operator 3 "arm_comparison_operator"
7961 [(match_operand 4 "cc_register" "") (const_int 0)])
7962 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7963 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7964 "TARGET_ARM"
7965 "@
7966 mov%D3\\t%0, %2
7967 mvn%D3\\t%0, #%B2
7968 mov%d3\\t%0, %1
7969 mvn%d3\\t%0, #%B1
7970 #
7971 #
7972 #
7973 #"
7974 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7975 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7976 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7977 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7978 "&& reload_completed"
7979 [(const_int 0)]
7980 {
7981 enum rtx_code rev_code;
7982 machine_mode mode;
7983 rtx rev_cond;
7984
7985 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7986 operands[3],
7987 gen_rtx_SET (operands[0], operands[1])));
7988
7989 rev_code = GET_CODE (operands[3]);
7990 mode = GET_MODE (operands[4]);
7991 if (mode == CCFPmode || mode == CCFPEmode)
7992 rev_code = reverse_condition_maybe_unordered (rev_code);
7993 else
7994 rev_code = reverse_condition (rev_code);
7995
7996 rev_cond = gen_rtx_fmt_ee (rev_code,
7997 VOIDmode,
7998 operands[4],
7999 const0_rtx);
8000 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8001 rev_cond,
8002 gen_rtx_SET (operands[0], operands[2])));
8003 DONE;
8004 }
8005 [(set_attr "length" "4,4,4,4,8,8,8,8")
8006 (set_attr "conds" "use")
8007 (set_attr_alternative "type"
8008 [(if_then_else (match_operand 2 "const_int_operand" "")
8009 (const_string "mov_imm")
8010 (const_string "mov_reg"))
8011 (const_string "mvn_imm")
8012 (if_then_else (match_operand 1 "const_int_operand" "")
8013 (const_string "mov_imm")
8014 (const_string "mov_reg"))
8015 (const_string "mvn_imm")
8016 (const_string "multiple")
8017 (const_string "multiple")
8018 (const_string "multiple")
8019 (const_string "multiple")])]
8020 )
8021
8022 (define_insn "*movsfcc_soft_insn"
8023 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8024 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8025 [(match_operand 4 "cc_register" "") (const_int 0)])
8026 (match_operand:SF 1 "s_register_operand" "0,r")
8027 (match_operand:SF 2 "s_register_operand" "r,0")))]
8028 "TARGET_ARM && TARGET_SOFT_FLOAT"
8029 "@
8030 mov%D3\\t%0, %2
8031 mov%d3\\t%0, %1"
8032 [(set_attr "conds" "use")
8033 (set_attr "type" "mov_reg")]
8034 )
8035
8036 \f
8037 ;; Jump and linkage insns
8038
8039 (define_expand "jump"
8040 [(set (pc)
8041 (label_ref (match_operand 0 "" "")))]
8042 "TARGET_EITHER"
8043 ""
8044 )
8045
8046 (define_insn "*arm_jump"
8047 [(set (pc)
8048 (label_ref (match_operand 0 "" "")))]
8049 "TARGET_32BIT"
8050 "*
8051 {
8052 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8053 {
8054 arm_ccfsm_state += 2;
8055 return \"\";
8056 }
8057 return \"b%?\\t%l0\";
8058 }
8059 "
8060 [(set_attr "predicable" "yes")
8061 (set (attr "length")
8062 (if_then_else
8063 (and (match_test "TARGET_THUMB2")
8064 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8065 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8066 (const_int 2)
8067 (const_int 4)))
8068 (set_attr "type" "branch")]
8069 )
8070
8071 (define_expand "call"
8072 [(parallel [(call (match_operand 0 "memory_operand" "")
8073 (match_operand 1 "general_operand" ""))
8074 (use (match_operand 2 "" ""))
8075 (clobber (reg:SI LR_REGNUM))])]
8076 "TARGET_EITHER"
8077 "
8078 {
8079 rtx callee, pat;
8080 tree addr = MEM_EXPR (operands[0]);
8081
8082 /* In an untyped call, we can get NULL for operand 2. */
8083 if (operands[2] == NULL_RTX)
8084 operands[2] = const0_rtx;
8085
8086 /* Decide if we should generate indirect calls by loading the
8087 32-bit address of the callee into a register before performing the
8088 branch and link. */
8089 callee = XEXP (operands[0], 0);
8090 if (GET_CODE (callee) == SYMBOL_REF
8091 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8092 : !REG_P (callee))
8093 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8094
8095 if (detect_cmse_nonsecure_call (addr))
8096 {
8097 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8098 operands[2]);
8099 emit_call_insn (pat);
8100 }
8101 else
8102 {
8103 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8104 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8105 }
8106 DONE;
8107 }"
8108 )
8109
8110 (define_expand "call_internal"
8111 [(parallel [(call (match_operand 0 "memory_operand" "")
8112 (match_operand 1 "general_operand" ""))
8113 (use (match_operand 2 "" ""))
8114 (clobber (reg:SI LR_REGNUM))])])
8115
8116 (define_expand "nonsecure_call_internal"
8117 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8118 UNSPEC_NONSECURE_MEM)
8119 (match_operand 1 "general_operand" ""))
8120 (use (match_operand 2 "" ""))
8121 (clobber (reg:SI LR_REGNUM))
8122 (clobber (reg:SI 4))])]
8123 "use_cmse"
8124 "
8125 {
8126 rtx tmp;
8127 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8128 gen_rtx_REG (SImode, 4),
8129 SImode);
8130
8131 operands[0] = replace_equiv_address (operands[0], tmp);
8132 }")
8133
8134 (define_insn "*call_reg_armv5"
8135 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8136 (match_operand 1 "" ""))
8137 (use (match_operand 2 "" ""))
8138 (clobber (reg:SI LR_REGNUM))]
8139 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8140 "blx%?\\t%0"
8141 [(set_attr "type" "call")]
8142 )
8143
8144 (define_insn "*call_reg_arm"
8145 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8146 (match_operand 1 "" ""))
8147 (use (match_operand 2 "" ""))
8148 (clobber (reg:SI LR_REGNUM))]
8149 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8150 "*
8151 return output_call (operands);
8152 "
8153 ;; length is worst case, normally it is only two
8154 [(set_attr "length" "12")
8155 (set_attr "type" "call")]
8156 )
8157
8158
8159 (define_expand "call_value"
8160 [(parallel [(set (match_operand 0 "" "")
8161 (call (match_operand 1 "memory_operand" "")
8162 (match_operand 2 "general_operand" "")))
8163 (use (match_operand 3 "" ""))
8164 (clobber (reg:SI LR_REGNUM))])]
8165 "TARGET_EITHER"
8166 "
8167 {
8168 rtx pat, callee;
8169 tree addr = MEM_EXPR (operands[1]);
8170
8171 /* In an untyped call, we can get NULL for operand 2. */
8172 if (operands[3] == 0)
8173 operands[3] = const0_rtx;
8174
8175 /* Decide if we should generate indirect calls by loading the
8176 32-bit address of the callee into a register before performing the
8177 branch and link. */
8178 callee = XEXP (operands[1], 0);
8179 if (GET_CODE (callee) == SYMBOL_REF
8180 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8181 : !REG_P (callee))
8182 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8183
8184 if (detect_cmse_nonsecure_call (addr))
8185 {
8186 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8187 operands[2], operands[3]);
8188 emit_call_insn (pat);
8189 }
8190 else
8191 {
8192 pat = gen_call_value_internal (operands[0], operands[1],
8193 operands[2], operands[3]);
8194 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8195 }
8196 DONE;
8197 }"
8198 )
8199
8200 (define_expand "call_value_internal"
8201 [(parallel [(set (match_operand 0 "" "")
8202 (call (match_operand 1 "memory_operand" "")
8203 (match_operand 2 "general_operand" "")))
8204 (use (match_operand 3 "" ""))
8205 (clobber (reg:SI LR_REGNUM))])])
8206
8207 (define_expand "nonsecure_call_value_internal"
8208 [(parallel [(set (match_operand 0 "" "")
8209 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8210 UNSPEC_NONSECURE_MEM)
8211 (match_operand 2 "general_operand" "")))
8212 (use (match_operand 3 "" ""))
8213 (clobber (reg:SI LR_REGNUM))
8214 (clobber (reg:SI 4))])]
8215 "use_cmse"
8216 "
8217 {
8218 rtx tmp;
8219 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8220 gen_rtx_REG (SImode, 4),
8221 SImode);
8222
8223 operands[1] = replace_equiv_address (operands[1], tmp);
8224 }")
8225
8226 (define_insn "*call_value_reg_armv5"
8227 [(set (match_operand 0 "" "")
8228 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8229 (match_operand 2 "" "")))
8230 (use (match_operand 3 "" ""))
8231 (clobber (reg:SI LR_REGNUM))]
8232 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8233 "blx%?\\t%1"
8234 [(set_attr "type" "call")]
8235 )
8236
8237 (define_insn "*call_value_reg_arm"
8238 [(set (match_operand 0 "" "")
8239 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8240 (match_operand 2 "" "")))
8241 (use (match_operand 3 "" ""))
8242 (clobber (reg:SI LR_REGNUM))]
8243 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8244 "*
8245 return output_call (&operands[1]);
8246 "
8247 [(set_attr "length" "12")
8248 (set_attr "type" "call")]
8249 )
8250
8251 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8252 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8253
8254 (define_insn "*call_symbol"
8255 [(call (mem:SI (match_operand:SI 0 "" ""))
8256 (match_operand 1 "" ""))
8257 (use (match_operand 2 "" ""))
8258 (clobber (reg:SI LR_REGNUM))]
8259 "TARGET_32BIT
8260 && !SIBLING_CALL_P (insn)
8261 && (GET_CODE (operands[0]) == SYMBOL_REF)
8262 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8263 "*
8264 {
8265 rtx op = operands[0];
8266
8267 /* Switch mode now when possible. */
8268 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8269 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8270 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8271
8272 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8273 }"
8274 [(set_attr "type" "call")]
8275 )
8276
8277 (define_insn "*call_value_symbol"
8278 [(set (match_operand 0 "" "")
8279 (call (mem:SI (match_operand:SI 1 "" ""))
8280 (match_operand:SI 2 "" "")))
8281 (use (match_operand 3 "" ""))
8282 (clobber (reg:SI LR_REGNUM))]
8283 "TARGET_32BIT
8284 && !SIBLING_CALL_P (insn)
8285 && (GET_CODE (operands[1]) == SYMBOL_REF)
8286 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8287 "*
8288 {
8289 rtx op = operands[1];
8290
8291 /* Switch mode now when possible. */
8292 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8293 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8294 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8295
8296 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8297 }"
8298 [(set_attr "type" "call")]
8299 )
8300
8301 (define_expand "sibcall_internal"
8302 [(parallel [(call (match_operand 0 "memory_operand" "")
8303 (match_operand 1 "general_operand" ""))
8304 (return)
8305 (use (match_operand 2 "" ""))])])
8306
8307 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8308 (define_expand "sibcall"
8309 [(parallel [(call (match_operand 0 "memory_operand" "")
8310 (match_operand 1 "general_operand" ""))
8311 (return)
8312 (use (match_operand 2 "" ""))])]
8313 "TARGET_32BIT"
8314 "
8315 {
8316 rtx pat;
8317
8318 if ((!REG_P (XEXP (operands[0], 0))
8319 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8320 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8321 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8322 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8323
8324 if (operands[2] == NULL_RTX)
8325 operands[2] = const0_rtx;
8326
8327 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8328 arm_emit_call_insn (pat, operands[0], true);
8329 DONE;
8330 }"
8331 )
8332
8333 (define_expand "sibcall_value_internal"
8334 [(parallel [(set (match_operand 0 "" "")
8335 (call (match_operand 1 "memory_operand" "")
8336 (match_operand 2 "general_operand" "")))
8337 (return)
8338 (use (match_operand 3 "" ""))])])
8339
8340 (define_expand "sibcall_value"
8341 [(parallel [(set (match_operand 0 "" "")
8342 (call (match_operand 1 "memory_operand" "")
8343 (match_operand 2 "general_operand" "")))
8344 (return)
8345 (use (match_operand 3 "" ""))])]
8346 "TARGET_32BIT"
8347 "
8348 {
8349 rtx pat;
8350
8351 if ((!REG_P (XEXP (operands[1], 0))
8352 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8353 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8354 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8355 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8356
8357 if (operands[3] == NULL_RTX)
8358 operands[3] = const0_rtx;
8359
8360 pat = gen_sibcall_value_internal (operands[0], operands[1],
8361 operands[2], operands[3]);
8362 arm_emit_call_insn (pat, operands[1], true);
8363 DONE;
8364 }"
8365 )
8366
8367 (define_insn "*sibcall_insn"
8368 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8369 (match_operand 1 "" ""))
8370 (return)
8371 (use (match_operand 2 "" ""))]
8372 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8373 "*
8374 if (which_alternative == 1)
8375 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8376 else
8377 {
8378 if (arm_arch5 || arm_arch4t)
8379 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8380 else
8381 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8382 }
8383 "
8384 [(set_attr "type" "call")]
8385 )
8386
8387 (define_insn "*sibcall_value_insn"
8388 [(set (match_operand 0 "" "")
8389 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8390 (match_operand 2 "" "")))
8391 (return)
8392 (use (match_operand 3 "" ""))]
8393 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8394 "*
8395 if (which_alternative == 1)
8396 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8397 else
8398 {
8399 if (arm_arch5 || arm_arch4t)
8400 return \"bx%?\\t%1\";
8401 else
8402 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8403 }
8404 "
8405 [(set_attr "type" "call")]
8406 )
8407
8408 (define_expand "<return_str>return"
8409 [(RETURNS)]
8410 "(TARGET_ARM || (TARGET_THUMB2
8411 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8412 && !IS_STACKALIGN (arm_current_func_type ())))
8413 <return_cond_false>"
8414 "
8415 {
8416 if (TARGET_THUMB2)
8417 {
8418 thumb2_expand_return (<return_simple_p>);
8419 DONE;
8420 }
8421 }
8422 "
8423 )
8424
8425 ;; Often the return insn will be the same as loading from memory, so set attr
8426 (define_insn "*arm_return"
8427 [(return)]
8428 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8429 "*
8430 {
8431 if (arm_ccfsm_state == 2)
8432 {
8433 arm_ccfsm_state += 2;
8434 return \"\";
8435 }
8436 return output_return_instruction (const_true_rtx, true, false, false);
8437 }"
8438 [(set_attr "type" "load_4")
8439 (set_attr "length" "12")
8440 (set_attr "predicable" "yes")]
8441 )
8442
8443 (define_insn "*cond_<return_str>return"
8444 [(set (pc)
8445 (if_then_else (match_operator 0 "arm_comparison_operator"
8446 [(match_operand 1 "cc_register" "") (const_int 0)])
8447 (RETURNS)
8448 (pc)))]
8449 "TARGET_ARM <return_cond_true>"
8450 "*
8451 {
8452 if (arm_ccfsm_state == 2)
8453 {
8454 arm_ccfsm_state += 2;
8455 return \"\";
8456 }
8457 return output_return_instruction (operands[0], true, false,
8458 <return_simple_p>);
8459 }"
8460 [(set_attr "conds" "use")
8461 (set_attr "length" "12")
8462 (set_attr "type" "load_4")]
8463 )
8464
8465 (define_insn "*cond_<return_str>return_inverted"
8466 [(set (pc)
8467 (if_then_else (match_operator 0 "arm_comparison_operator"
8468 [(match_operand 1 "cc_register" "") (const_int 0)])
8469 (pc)
8470 (RETURNS)))]
8471 "TARGET_ARM <return_cond_true>"
8472 "*
8473 {
8474 if (arm_ccfsm_state == 2)
8475 {
8476 arm_ccfsm_state += 2;
8477 return \"\";
8478 }
8479 return output_return_instruction (operands[0], true, true,
8480 <return_simple_p>);
8481 }"
8482 [(set_attr "conds" "use")
8483 (set_attr "length" "12")
8484 (set_attr "type" "load_4")]
8485 )
8486
8487 (define_insn "*arm_simple_return"
8488 [(simple_return)]
8489 "TARGET_ARM"
8490 "*
8491 {
8492 if (arm_ccfsm_state == 2)
8493 {
8494 arm_ccfsm_state += 2;
8495 return \"\";
8496 }
8497 return output_return_instruction (const_true_rtx, true, false, true);
8498 }"
8499 [(set_attr "type" "branch")
8500 (set_attr "length" "4")
8501 (set_attr "predicable" "yes")]
8502 )
8503
8504 ;; Generate a sequence of instructions to determine if the processor is
8505 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8506 ;; mask.
8507
8508 (define_expand "return_addr_mask"
8509 [(set (match_dup 1)
8510 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8511 (const_int 0)))
8512 (set (match_operand:SI 0 "s_register_operand" "")
8513 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8514 (const_int -1)
8515 (const_int 67108860)))] ; 0x03fffffc
8516 "TARGET_ARM"
8517 "
8518 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8519 ")
8520
8521 (define_insn "*check_arch2"
8522 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8523 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8524 (const_int 0)))]
8525 "TARGET_ARM"
8526 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8527 [(set_attr "length" "8")
8528 (set_attr "conds" "set")
8529 (set_attr "type" "multiple")]
8530 )
8531
8532 ;; Call subroutine returning any type.
8533
8534 (define_expand "untyped_call"
8535 [(parallel [(call (match_operand 0 "" "")
8536 (const_int 0))
8537 (match_operand 1 "" "")
8538 (match_operand 2 "" "")])]
8539 "TARGET_EITHER"
8540 "
8541 {
8542 int i;
8543 rtx par = gen_rtx_PARALLEL (VOIDmode,
8544 rtvec_alloc (XVECLEN (operands[2], 0)));
8545 rtx addr = gen_reg_rtx (Pmode);
8546 rtx mem;
8547 int size = 0;
8548
8549 emit_move_insn (addr, XEXP (operands[1], 0));
8550 mem = change_address (operands[1], BLKmode, addr);
8551
8552 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8553 {
8554 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8555
8556 /* Default code only uses r0 as a return value, but we could
8557 be using anything up to 4 registers. */
8558 if (REGNO (src) == R0_REGNUM)
8559 src = gen_rtx_REG (TImode, R0_REGNUM);
8560
8561 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8562 GEN_INT (size));
8563 size += GET_MODE_SIZE (GET_MODE (src));
8564 }
8565
8566 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8567
8568 size = 0;
8569
8570 for (i = 0; i < XVECLEN (par, 0); i++)
8571 {
8572 HOST_WIDE_INT offset = 0;
8573 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8574
8575 if (size != 0)
8576 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8577
8578 mem = change_address (mem, GET_MODE (reg), NULL);
8579 if (REGNO (reg) == R0_REGNUM)
8580 {
8581 /* On thumb we have to use a write-back instruction. */
8582 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8583 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8584 size = TARGET_ARM ? 16 : 0;
8585 }
8586 else
8587 {
8588 emit_move_insn (mem, reg);
8589 size = GET_MODE_SIZE (GET_MODE (reg));
8590 }
8591 }
8592
8593 /* The optimizer does not know that the call sets the function value
8594 registers we stored in the result block. We avoid problems by
8595 claiming that all hard registers are used and clobbered at this
8596 point. */
8597 emit_insn (gen_blockage ());
8598
8599 DONE;
8600 }"
8601 )
8602
8603 (define_expand "untyped_return"
8604 [(match_operand:BLK 0 "memory_operand" "")
8605 (match_operand 1 "" "")]
8606 "TARGET_EITHER"
8607 "
8608 {
8609 int i;
8610 rtx addr = gen_reg_rtx (Pmode);
8611 rtx mem;
8612 int size = 0;
8613
8614 emit_move_insn (addr, XEXP (operands[0], 0));
8615 mem = change_address (operands[0], BLKmode, addr);
8616
8617 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8618 {
8619 HOST_WIDE_INT offset = 0;
8620 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8621
8622 if (size != 0)
8623 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8624
8625 mem = change_address (mem, GET_MODE (reg), NULL);
8626 if (REGNO (reg) == R0_REGNUM)
8627 {
8628 /* On thumb we have to use a write-back instruction. */
8629 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8630 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8631 size = TARGET_ARM ? 16 : 0;
8632 }
8633 else
8634 {
8635 emit_move_insn (reg, mem);
8636 size = GET_MODE_SIZE (GET_MODE (reg));
8637 }
8638 }
8639
8640 /* Emit USE insns before the return. */
8641 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8642 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8643
8644 /* Construct the return. */
8645 expand_naked_return ();
8646
8647 DONE;
8648 }"
8649 )
8650
8651 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8652 ;; all of memory. This blocks insns from being moved across this point.
8653
8654 (define_insn "blockage"
8655 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8656 "TARGET_EITHER"
8657 ""
8658 [(set_attr "length" "0")
8659 (set_attr "type" "block")]
8660 )
8661
8662 (define_insn "probe_stack"
8663 [(set (match_operand:SI 0 "memory_operand" "=m")
8664 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8665 "TARGET_32BIT"
8666 "str%?\\tr0, %0"
8667 [(set_attr "type" "store_4")
8668 (set_attr "predicable" "yes")]
8669 )
8670
8671 (define_insn "probe_stack_range"
8672 [(set (match_operand:SI 0 "register_operand" "=r")
8673 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8674 (match_operand:SI 2 "register_operand" "r")]
8675 VUNSPEC_PROBE_STACK_RANGE))]
8676 "TARGET_32BIT"
8677 {
8678 return output_probe_stack_range (operands[0], operands[2]);
8679 }
8680 [(set_attr "type" "multiple")
8681 (set_attr "conds" "clob")]
8682 )
8683
8684 (define_expand "casesi"
8685 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8686 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8687 (match_operand:SI 2 "const_int_operand" "") ; total range
8688 (match_operand:SI 3 "" "") ; table label
8689 (match_operand:SI 4 "" "")] ; Out of range label
8690 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8691 "
8692 {
8693 enum insn_code code;
8694 if (operands[1] != const0_rtx)
8695 {
8696 rtx reg = gen_reg_rtx (SImode);
8697
8698 emit_insn (gen_addsi3 (reg, operands[0],
8699 gen_int_mode (-INTVAL (operands[1]),
8700 SImode)));
8701 operands[0] = reg;
8702 }
8703
8704 if (TARGET_ARM)
8705 code = CODE_FOR_arm_casesi_internal;
8706 else if (TARGET_THUMB1)
8707 code = CODE_FOR_thumb1_casesi_internal_pic;
8708 else if (flag_pic)
8709 code = CODE_FOR_thumb2_casesi_internal_pic;
8710 else
8711 code = CODE_FOR_thumb2_casesi_internal;
8712
8713 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8714 operands[2] = force_reg (SImode, operands[2]);
8715
8716 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8717 operands[3], operands[4]));
8718 DONE;
8719 }"
8720 )
8721
8722 ;; The USE in this pattern is needed to tell flow analysis that this is
8723 ;; a CASESI insn. It has no other purpose.
8724 (define_insn "arm_casesi_internal"
8725 [(parallel [(set (pc)
8726 (if_then_else
8727 (leu (match_operand:SI 0 "s_register_operand" "r")
8728 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8729 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8730 (label_ref (match_operand 2 "" ""))))
8731 (label_ref (match_operand 3 "" ""))))
8732 (clobber (reg:CC CC_REGNUM))
8733 (use (label_ref (match_dup 2)))])]
8734 "TARGET_ARM"
8735 "*
8736 if (flag_pic)
8737 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8738 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8739 "
8740 [(set_attr "conds" "clob")
8741 (set_attr "length" "12")
8742 (set_attr "type" "multiple")]
8743 )
8744
8745 (define_expand "indirect_jump"
8746 [(set (pc)
8747 (match_operand:SI 0 "s_register_operand" ""))]
8748 "TARGET_EITHER"
8749 "
8750 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8751 address and use bx. */
8752 if (TARGET_THUMB2)
8753 {
8754 rtx tmp;
8755 tmp = gen_reg_rtx (SImode);
8756 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8757 operands[0] = tmp;
8758 }
8759 "
8760 )
8761
8762 ;; NB Never uses BX.
8763 (define_insn "*arm_indirect_jump"
8764 [(set (pc)
8765 (match_operand:SI 0 "s_register_operand" "r"))]
8766 "TARGET_ARM"
8767 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8768 [(set_attr "predicable" "yes")
8769 (set_attr "type" "branch")]
8770 )
8771
8772 (define_insn "*load_indirect_jump"
8773 [(set (pc)
8774 (match_operand:SI 0 "memory_operand" "m"))]
8775 "TARGET_ARM"
8776 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8777 [(set_attr "type" "load_4")
8778 (set_attr "pool_range" "4096")
8779 (set_attr "neg_pool_range" "4084")
8780 (set_attr "predicable" "yes")]
8781 )
8782
8783 \f
8784 ;; Misc insns
8785
8786 (define_insn "nop"
8787 [(const_int 0)]
8788 "TARGET_EITHER"
8789 "nop"
8790 [(set (attr "length")
8791 (if_then_else (eq_attr "is_thumb" "yes")
8792 (const_int 2)
8793 (const_int 4)))
8794 (set_attr "type" "mov_reg")]
8795 )
8796
8797 (define_insn "trap"
8798 [(trap_if (const_int 1) (const_int 0))]
8799 ""
8800 "*
8801 if (TARGET_ARM)
8802 return \".inst\\t0xe7f000f0\";
8803 else
8804 return \".inst\\t0xdeff\";
8805 "
8806 [(set (attr "length")
8807 (if_then_else (eq_attr "is_thumb" "yes")
8808 (const_int 2)
8809 (const_int 4)))
8810 (set_attr "type" "trap")
8811 (set_attr "conds" "unconditional")]
8812 )
8813
8814 \f
8815 ;; Patterns to allow combination of arithmetic, cond code and shifts
8816
8817 (define_insn "*<arith_shift_insn>_multsi"
8818 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8819 (SHIFTABLE_OPS:SI
8820 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8821 (match_operand:SI 3 "power_of_two_operand" ""))
8822 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8823 "TARGET_32BIT"
8824 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8825 [(set_attr "predicable" "yes")
8826 (set_attr "predicable_short_it" "no")
8827 (set_attr "shift" "2")
8828 (set_attr "arch" "a,t2")
8829 (set_attr "type" "alu_shift_imm")])
8830
8831 (define_insn "*<arith_shift_insn>_shiftsi"
8832 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8833 (SHIFTABLE_OPS:SI
8834 (match_operator:SI 2 "shift_nomul_operator"
8835 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8836 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8837 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8838 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8839 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8840 [(set_attr "predicable" "yes")
8841 (set_attr "predicable_short_it" "no")
8842 (set_attr "shift" "3")
8843 (set_attr "arch" "a,t2,a")
8844 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8845
8846 (define_split
8847 [(set (match_operand:SI 0 "s_register_operand" "")
8848 (match_operator:SI 1 "shiftable_operator"
8849 [(match_operator:SI 2 "shiftable_operator"
8850 [(match_operator:SI 3 "shift_operator"
8851 [(match_operand:SI 4 "s_register_operand" "")
8852 (match_operand:SI 5 "reg_or_int_operand" "")])
8853 (match_operand:SI 6 "s_register_operand" "")])
8854 (match_operand:SI 7 "arm_rhs_operand" "")]))
8855 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8856 "TARGET_32BIT"
8857 [(set (match_dup 8)
8858 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8859 (match_dup 6)]))
8860 (set (match_dup 0)
8861 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8862 "")
8863
8864 (define_insn "*arith_shiftsi_compare0"
8865 [(set (reg:CC_NOOV CC_REGNUM)
8866 (compare:CC_NOOV
8867 (match_operator:SI 1 "shiftable_operator"
8868 [(match_operator:SI 3 "shift_operator"
8869 [(match_operand:SI 4 "s_register_operand" "r,r")
8870 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8871 (match_operand:SI 2 "s_register_operand" "r,r")])
8872 (const_int 0)))
8873 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8874 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8875 (match_dup 2)]))]
8876 "TARGET_32BIT"
8877 "%i1s%?\\t%0, %2, %4%S3"
8878 [(set_attr "conds" "set")
8879 (set_attr "shift" "4")
8880 (set_attr "arch" "32,a")
8881 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8882
8883 (define_insn "*arith_shiftsi_compare0_scratch"
8884 [(set (reg:CC_NOOV CC_REGNUM)
8885 (compare:CC_NOOV
8886 (match_operator:SI 1 "shiftable_operator"
8887 [(match_operator:SI 3 "shift_operator"
8888 [(match_operand:SI 4 "s_register_operand" "r,r")
8889 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8890 (match_operand:SI 2 "s_register_operand" "r,r")])
8891 (const_int 0)))
8892 (clobber (match_scratch:SI 0 "=r,r"))]
8893 "TARGET_32BIT"
8894 "%i1s%?\\t%0, %2, %4%S3"
8895 [(set_attr "conds" "set")
8896 (set_attr "shift" "4")
8897 (set_attr "arch" "32,a")
8898 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8899
8900 (define_insn "*sub_shiftsi"
8901 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8902 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8903 (match_operator:SI 2 "shift_operator"
8904 [(match_operand:SI 3 "s_register_operand" "r,r")
8905 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8906 "TARGET_32BIT"
8907 "sub%?\\t%0, %1, %3%S2"
8908 [(set_attr "predicable" "yes")
8909 (set_attr "shift" "3")
8910 (set_attr "arch" "32,a")
8911 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8912
8913 (define_insn "*sub_shiftsi_compare0"
8914 [(set (reg:CC_NOOV CC_REGNUM)
8915 (compare:CC_NOOV
8916 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8917 (match_operator:SI 2 "shift_operator"
8918 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8919 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8920 (const_int 0)))
8921 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8922 (minus:SI (match_dup 1)
8923 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8924 "TARGET_32BIT"
8925 "subs%?\\t%0, %1, %3%S2"
8926 [(set_attr "conds" "set")
8927 (set_attr "shift" "3")
8928 (set_attr "arch" "32,a,a")
8929 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8930
8931 (define_insn "*sub_shiftsi_compare0_scratch"
8932 [(set (reg:CC_NOOV CC_REGNUM)
8933 (compare:CC_NOOV
8934 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8935 (match_operator:SI 2 "shift_operator"
8936 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8937 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8938 (const_int 0)))
8939 (clobber (match_scratch:SI 0 "=r,r,r"))]
8940 "TARGET_32BIT"
8941 "subs%?\\t%0, %1, %3%S2"
8942 [(set_attr "conds" "set")
8943 (set_attr "shift" "3")
8944 (set_attr "arch" "32,a,a")
8945 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8946 \f
8947
8948 (define_insn_and_split "*and_scc"
8949 [(set (match_operand:SI 0 "s_register_operand" "=r")
8950 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8951 [(match_operand 2 "cc_register" "") (const_int 0)])
8952 (match_operand:SI 3 "s_register_operand" "r")))]
8953 "TARGET_ARM"
8954 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8955 "&& reload_completed"
8956 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8957 (cond_exec (match_dup 4) (set (match_dup 0)
8958 (and:SI (match_dup 3) (const_int 1))))]
8959 {
8960 machine_mode mode = GET_MODE (operands[2]);
8961 enum rtx_code rc = GET_CODE (operands[1]);
8962
8963 /* Note that operands[4] is the same as operands[1],
8964 but with VOIDmode as the result. */
8965 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8966 if (mode == CCFPmode || mode == CCFPEmode)
8967 rc = reverse_condition_maybe_unordered (rc);
8968 else
8969 rc = reverse_condition (rc);
8970 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8971 }
8972 [(set_attr "conds" "use")
8973 (set_attr "type" "multiple")
8974 (set_attr "length" "8")]
8975 )
8976
8977 (define_insn_and_split "*ior_scc"
8978 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8979 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8980 [(match_operand 2 "cc_register" "") (const_int 0)])
8981 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8982 "TARGET_ARM"
8983 "@
8984 orr%d1\\t%0, %3, #1
8985 #"
8986 "&& reload_completed
8987 && REGNO (operands [0]) != REGNO (operands[3])"
8988 ;; && which_alternative == 1
8989 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8990 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8991 (cond_exec (match_dup 4) (set (match_dup 0)
8992 (ior:SI (match_dup 3) (const_int 1))))]
8993 {
8994 machine_mode mode = GET_MODE (operands[2]);
8995 enum rtx_code rc = GET_CODE (operands[1]);
8996
8997 /* Note that operands[4] is the same as operands[1],
8998 but with VOIDmode as the result. */
8999 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9000 if (mode == CCFPmode || mode == CCFPEmode)
9001 rc = reverse_condition_maybe_unordered (rc);
9002 else
9003 rc = reverse_condition (rc);
9004 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9005 }
9006 [(set_attr "conds" "use")
9007 (set_attr "length" "4,8")
9008 (set_attr "type" "logic_imm,multiple")]
9009 )
9010
9011 ; A series of splitters for the compare_scc pattern below. Note that
9012 ; order is important.
9013 (define_split
9014 [(set (match_operand:SI 0 "s_register_operand" "")
9015 (lt:SI (match_operand:SI 1 "s_register_operand" "")
9016 (const_int 0)))
9017 (clobber (reg:CC CC_REGNUM))]
9018 "TARGET_32BIT && reload_completed"
9019 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9020
9021 (define_split
9022 [(set (match_operand:SI 0 "s_register_operand" "")
9023 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9024 (const_int 0)))
9025 (clobber (reg:CC CC_REGNUM))]
9026 "TARGET_32BIT && reload_completed"
9027 [(set (match_dup 0) (not:SI (match_dup 1)))
9028 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9029
9030 (define_split
9031 [(set (match_operand:SI 0 "s_register_operand" "")
9032 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9033 (const_int 0)))
9034 (clobber (reg:CC CC_REGNUM))]
9035 "arm_arch5 && TARGET_32BIT"
9036 [(set (match_dup 0) (clz:SI (match_dup 1)))
9037 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9038 )
9039
9040 (define_split
9041 [(set (match_operand:SI 0 "s_register_operand" "")
9042 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9043 (const_int 0)))
9044 (clobber (reg:CC CC_REGNUM))]
9045 "TARGET_32BIT && reload_completed"
9046 [(parallel
9047 [(set (reg:CC CC_REGNUM)
9048 (compare:CC (const_int 1) (match_dup 1)))
9049 (set (match_dup 0)
9050 (minus:SI (const_int 1) (match_dup 1)))])
9051 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9052 (set (match_dup 0) (const_int 0)))])
9053
9054 (define_split
9055 [(set (match_operand:SI 0 "s_register_operand" "")
9056 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9057 (match_operand:SI 2 "const_int_operand" "")))
9058 (clobber (reg:CC CC_REGNUM))]
9059 "TARGET_32BIT && reload_completed"
9060 [(parallel
9061 [(set (reg:CC CC_REGNUM)
9062 (compare:CC (match_dup 1) (match_dup 2)))
9063 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9064 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9065 (set (match_dup 0) (const_int 1)))]
9066 {
9067 operands[3] = GEN_INT (-INTVAL (operands[2]));
9068 })
9069
9070 (define_split
9071 [(set (match_operand:SI 0 "s_register_operand" "")
9072 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9073 (match_operand:SI 2 "arm_add_operand" "")))
9074 (clobber (reg:CC CC_REGNUM))]
9075 "TARGET_32BIT && reload_completed"
9076 [(parallel
9077 [(set (reg:CC_NOOV CC_REGNUM)
9078 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9079 (const_int 0)))
9080 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9081 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9082 (set (match_dup 0) (const_int 1)))])
9083
9084 (define_insn_and_split "*compare_scc"
9085 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9086 (match_operator:SI 1 "arm_comparison_operator"
9087 [(match_operand:SI 2 "s_register_operand" "r,r")
9088 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9089 (clobber (reg:CC CC_REGNUM))]
9090 "TARGET_32BIT"
9091 "#"
9092 "&& reload_completed"
9093 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9094 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9095 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9096 {
9097 rtx tmp1;
9098 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9099 operands[2], operands[3]);
9100 enum rtx_code rc = GET_CODE (operands[1]);
9101
9102 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9103
9104 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9105 if (mode == CCFPmode || mode == CCFPEmode)
9106 rc = reverse_condition_maybe_unordered (rc);
9107 else
9108 rc = reverse_condition (rc);
9109 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9110 }
9111 [(set_attr "type" "multiple")]
9112 )
9113
9114 ;; Attempt to improve the sequence generated by the compare_scc splitters
9115 ;; not to use conditional execution.
9116
9117 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9118 ;; clz Rd, reg1
9119 ;; lsr Rd, Rd, #5
9120 (define_peephole2
9121 [(set (reg:CC CC_REGNUM)
9122 (compare:CC (match_operand:SI 1 "register_operand" "")
9123 (const_int 0)))
9124 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9125 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9126 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9127 (set (match_dup 0) (const_int 1)))]
9128 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9129 [(set (match_dup 0) (clz:SI (match_dup 1)))
9130 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9131 )
9132
9133 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9134 ;; negs Rd, reg1
9135 ;; adc Rd, Rd, reg1
9136 (define_peephole2
9137 [(set (reg:CC CC_REGNUM)
9138 (compare:CC (match_operand:SI 1 "register_operand" "")
9139 (const_int 0)))
9140 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9141 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9142 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9143 (set (match_dup 0) (const_int 1)))
9144 (match_scratch:SI 2 "r")]
9145 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9146 [(parallel
9147 [(set (reg:CC CC_REGNUM)
9148 (compare:CC (const_int 0) (match_dup 1)))
9149 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9150 (set (match_dup 0)
9151 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9152 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9153 )
9154
9155 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9156 ;; sub Rd, Reg1, reg2
9157 ;; clz Rd, Rd
9158 ;; lsr Rd, Rd, #5
9159 (define_peephole2
9160 [(set (reg:CC CC_REGNUM)
9161 (compare:CC (match_operand:SI 1 "register_operand" "")
9162 (match_operand:SI 2 "arm_rhs_operand" "")))
9163 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9164 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9165 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9166 (set (match_dup 0) (const_int 1)))]
9167 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9168 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9169 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9170 (set (match_dup 0) (clz:SI (match_dup 0)))
9171 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9172 )
9173
9174
9175 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9176 ;; sub T1, Reg1, reg2
9177 ;; negs Rd, T1
9178 ;; adc Rd, Rd, T1
9179 (define_peephole2
9180 [(set (reg:CC CC_REGNUM)
9181 (compare:CC (match_operand:SI 1 "register_operand" "")
9182 (match_operand:SI 2 "arm_rhs_operand" "")))
9183 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9184 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9185 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9186 (set (match_dup 0) (const_int 1)))
9187 (match_scratch:SI 3 "r")]
9188 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9189 [(set (match_dup 3) (match_dup 4))
9190 (parallel
9191 [(set (reg:CC CC_REGNUM)
9192 (compare:CC (const_int 0) (match_dup 3)))
9193 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9194 (set (match_dup 0)
9195 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9196 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9197 "
9198 if (CONST_INT_P (operands[2]))
9199 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9200 else
9201 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9202 ")
9203
9204 (define_insn "*cond_move"
9205 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9206 (if_then_else:SI (match_operator 3 "equality_operator"
9207 [(match_operator 4 "arm_comparison_operator"
9208 [(match_operand 5 "cc_register" "") (const_int 0)])
9209 (const_int 0)])
9210 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9211 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9212 "TARGET_ARM"
9213 "*
9214 if (GET_CODE (operands[3]) == NE)
9215 {
9216 if (which_alternative != 1)
9217 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9218 if (which_alternative != 0)
9219 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9220 return \"\";
9221 }
9222 if (which_alternative != 0)
9223 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9224 if (which_alternative != 1)
9225 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9226 return \"\";
9227 "
9228 [(set_attr "conds" "use")
9229 (set_attr_alternative "type"
9230 [(if_then_else (match_operand 2 "const_int_operand" "")
9231 (const_string "mov_imm")
9232 (const_string "mov_reg"))
9233 (if_then_else (match_operand 1 "const_int_operand" "")
9234 (const_string "mov_imm")
9235 (const_string "mov_reg"))
9236 (const_string "multiple")])
9237 (set_attr "length" "4,4,8")]
9238 )
9239
9240 (define_insn "*cond_arith"
9241 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9242 (match_operator:SI 5 "shiftable_operator"
9243 [(match_operator:SI 4 "arm_comparison_operator"
9244 [(match_operand:SI 2 "s_register_operand" "r,r")
9245 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9246 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9247 (clobber (reg:CC CC_REGNUM))]
9248 "TARGET_ARM"
9249 "*
9250 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9251 return \"%i5\\t%0, %1, %2, lsr #31\";
9252
9253 output_asm_insn (\"cmp\\t%2, %3\", operands);
9254 if (GET_CODE (operands[5]) == AND)
9255 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9256 else if (GET_CODE (operands[5]) == MINUS)
9257 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9258 else if (which_alternative != 0)
9259 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9260 return \"%i5%d4\\t%0, %1, #1\";
9261 "
9262 [(set_attr "conds" "clob")
9263 (set_attr "length" "12")
9264 (set_attr "type" "multiple")]
9265 )
9266
9267 (define_insn "*cond_sub"
9268 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9269 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9270 (match_operator:SI 4 "arm_comparison_operator"
9271 [(match_operand:SI 2 "s_register_operand" "r,r")
9272 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9273 (clobber (reg:CC CC_REGNUM))]
9274 "TARGET_ARM"
9275 "*
9276 output_asm_insn (\"cmp\\t%2, %3\", operands);
9277 if (which_alternative != 0)
9278 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9279 return \"sub%d4\\t%0, %1, #1\";
9280 "
9281 [(set_attr "conds" "clob")
9282 (set_attr "length" "8,12")
9283 (set_attr "type" "multiple")]
9284 )
9285
9286 (define_insn "*cmp_ite0"
9287 [(set (match_operand 6 "dominant_cc_register" "")
9288 (compare
9289 (if_then_else:SI
9290 (match_operator 4 "arm_comparison_operator"
9291 [(match_operand:SI 0 "s_register_operand"
9292 "l,l,l,r,r,r,r,r,r")
9293 (match_operand:SI 1 "arm_add_operand"
9294 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9295 (match_operator:SI 5 "arm_comparison_operator"
9296 [(match_operand:SI 2 "s_register_operand"
9297 "l,r,r,l,l,r,r,r,r")
9298 (match_operand:SI 3 "arm_add_operand"
9299 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9300 (const_int 0))
9301 (const_int 0)))]
9302 "TARGET_32BIT"
9303 "*
9304 {
9305 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9306 {
9307 {\"cmp%d5\\t%0, %1\",
9308 \"cmp%d4\\t%2, %3\"},
9309 {\"cmn%d5\\t%0, #%n1\",
9310 \"cmp%d4\\t%2, %3\"},
9311 {\"cmp%d5\\t%0, %1\",
9312 \"cmn%d4\\t%2, #%n3\"},
9313 {\"cmn%d5\\t%0, #%n1\",
9314 \"cmn%d4\\t%2, #%n3\"}
9315 };
9316 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9317 {
9318 {\"cmp\\t%2, %3\",
9319 \"cmp\\t%0, %1\"},
9320 {\"cmp\\t%2, %3\",
9321 \"cmn\\t%0, #%n1\"},
9322 {\"cmn\\t%2, #%n3\",
9323 \"cmp\\t%0, %1\"},
9324 {\"cmn\\t%2, #%n3\",
9325 \"cmn\\t%0, #%n1\"}
9326 };
9327 static const char * const ite[2] =
9328 {
9329 \"it\\t%d5\",
9330 \"it\\t%d4\"
9331 };
9332 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9333 CMP_CMP, CMN_CMP, CMP_CMP,
9334 CMN_CMP, CMP_CMN, CMN_CMN};
9335 int swap =
9336 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9337
9338 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9339 if (TARGET_THUMB2) {
9340 output_asm_insn (ite[swap], operands);
9341 }
9342 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9343 return \"\";
9344 }"
9345 [(set_attr "conds" "set")
9346 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9347 (set_attr "type" "multiple")
9348 (set_attr_alternative "length"
9349 [(const_int 6)
9350 (const_int 8)
9351 (const_int 8)
9352 (const_int 8)
9353 (const_int 8)
9354 (if_then_else (eq_attr "is_thumb" "no")
9355 (const_int 8)
9356 (const_int 10))
9357 (if_then_else (eq_attr "is_thumb" "no")
9358 (const_int 8)
9359 (const_int 10))
9360 (if_then_else (eq_attr "is_thumb" "no")
9361 (const_int 8)
9362 (const_int 10))
9363 (if_then_else (eq_attr "is_thumb" "no")
9364 (const_int 8)
9365 (const_int 10))])]
9366 )
9367
9368 (define_insn "*cmp_ite1"
9369 [(set (match_operand 6 "dominant_cc_register" "")
9370 (compare
9371 (if_then_else:SI
9372 (match_operator 4 "arm_comparison_operator"
9373 [(match_operand:SI 0 "s_register_operand"
9374 "l,l,l,r,r,r,r,r,r")
9375 (match_operand:SI 1 "arm_add_operand"
9376 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9377 (match_operator:SI 5 "arm_comparison_operator"
9378 [(match_operand:SI 2 "s_register_operand"
9379 "l,r,r,l,l,r,r,r,r")
9380 (match_operand:SI 3 "arm_add_operand"
9381 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9382 (const_int 1))
9383 (const_int 0)))]
9384 "TARGET_32BIT"
9385 "*
9386 {
9387 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9388 {
9389 {\"cmp\\t%0, %1\",
9390 \"cmp\\t%2, %3\"},
9391 {\"cmn\\t%0, #%n1\",
9392 \"cmp\\t%2, %3\"},
9393 {\"cmp\\t%0, %1\",
9394 \"cmn\\t%2, #%n3\"},
9395 {\"cmn\\t%0, #%n1\",
9396 \"cmn\\t%2, #%n3\"}
9397 };
9398 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9399 {
9400 {\"cmp%d4\\t%2, %3\",
9401 \"cmp%D5\\t%0, %1\"},
9402 {\"cmp%d4\\t%2, %3\",
9403 \"cmn%D5\\t%0, #%n1\"},
9404 {\"cmn%d4\\t%2, #%n3\",
9405 \"cmp%D5\\t%0, %1\"},
9406 {\"cmn%d4\\t%2, #%n3\",
9407 \"cmn%D5\\t%0, #%n1\"}
9408 };
9409 static const char * const ite[2] =
9410 {
9411 \"it\\t%d4\",
9412 \"it\\t%D5\"
9413 };
9414 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9415 CMP_CMP, CMN_CMP, CMP_CMP,
9416 CMN_CMP, CMP_CMN, CMN_CMN};
9417 int swap =
9418 comparison_dominates_p (GET_CODE (operands[5]),
9419 reverse_condition (GET_CODE (operands[4])));
9420
9421 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9422 if (TARGET_THUMB2) {
9423 output_asm_insn (ite[swap], operands);
9424 }
9425 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9426 return \"\";
9427 }"
9428 [(set_attr "conds" "set")
9429 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9430 (set_attr_alternative "length"
9431 [(const_int 6)
9432 (const_int 8)
9433 (const_int 8)
9434 (const_int 8)
9435 (const_int 8)
9436 (if_then_else (eq_attr "is_thumb" "no")
9437 (const_int 8)
9438 (const_int 10))
9439 (if_then_else (eq_attr "is_thumb" "no")
9440 (const_int 8)
9441 (const_int 10))
9442 (if_then_else (eq_attr "is_thumb" "no")
9443 (const_int 8)
9444 (const_int 10))
9445 (if_then_else (eq_attr "is_thumb" "no")
9446 (const_int 8)
9447 (const_int 10))])
9448 (set_attr "type" "multiple")]
9449 )
9450
9451 (define_insn "*cmp_and"
9452 [(set (match_operand 6 "dominant_cc_register" "")
9453 (compare
9454 (and:SI
9455 (match_operator 4 "arm_comparison_operator"
9456 [(match_operand:SI 0 "s_register_operand"
9457 "l,l,l,r,r,r,r,r,r")
9458 (match_operand:SI 1 "arm_add_operand"
9459 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9460 (match_operator:SI 5 "arm_comparison_operator"
9461 [(match_operand:SI 2 "s_register_operand"
9462 "l,r,r,l,l,r,r,r,r")
9463 (match_operand:SI 3 "arm_add_operand"
9464 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9465 (const_int 0)))]
9466 "TARGET_32BIT"
9467 "*
9468 {
9469 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9470 {
9471 {\"cmp%d5\\t%0, %1\",
9472 \"cmp%d4\\t%2, %3\"},
9473 {\"cmn%d5\\t%0, #%n1\",
9474 \"cmp%d4\\t%2, %3\"},
9475 {\"cmp%d5\\t%0, %1\",
9476 \"cmn%d4\\t%2, #%n3\"},
9477 {\"cmn%d5\\t%0, #%n1\",
9478 \"cmn%d4\\t%2, #%n3\"}
9479 };
9480 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9481 {
9482 {\"cmp\\t%2, %3\",
9483 \"cmp\\t%0, %1\"},
9484 {\"cmp\\t%2, %3\",
9485 \"cmn\\t%0, #%n1\"},
9486 {\"cmn\\t%2, #%n3\",
9487 \"cmp\\t%0, %1\"},
9488 {\"cmn\\t%2, #%n3\",
9489 \"cmn\\t%0, #%n1\"}
9490 };
9491 static const char *const ite[2] =
9492 {
9493 \"it\\t%d5\",
9494 \"it\\t%d4\"
9495 };
9496 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9497 CMP_CMP, CMN_CMP, CMP_CMP,
9498 CMN_CMP, CMP_CMN, CMN_CMN};
9499 int swap =
9500 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9501
9502 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9503 if (TARGET_THUMB2) {
9504 output_asm_insn (ite[swap], operands);
9505 }
9506 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9507 return \"\";
9508 }"
9509 [(set_attr "conds" "set")
9510 (set_attr "predicable" "no")
9511 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9512 (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9513 (set_attr_alternative "length"
9514 [(const_int 6)
9515 (const_int 8)
9516 (const_int 8)
9517 (const_int 8)
9518 (const_int 8)
9519 (if_then_else (eq_attr "is_thumb" "no")
9520 (const_int 8)
9521 (const_int 10))
9522 (if_then_else (eq_attr "is_thumb" "no")
9523 (const_int 8)
9524 (const_int 10))
9525 (if_then_else (eq_attr "is_thumb" "no")
9526 (const_int 8)
9527 (const_int 10))
9528 (if_then_else (eq_attr "is_thumb" "no")
9529 (const_int 8)
9530 (const_int 10))])
9531 (set_attr "type" "multiple")]
9532 )
9533
9534 (define_insn "*cmp_ior"
9535 [(set (match_operand 6 "dominant_cc_register" "")
9536 (compare
9537 (ior:SI
9538 (match_operator 4 "arm_comparison_operator"
9539 [(match_operand:SI 0 "s_register_operand"
9540 "l,l,l,r,r,r,r,r,r")
9541 (match_operand:SI 1 "arm_add_operand"
9542 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9543 (match_operator:SI 5 "arm_comparison_operator"
9544 [(match_operand:SI 2 "s_register_operand"
9545 "l,r,r,l,l,r,r,r,r")
9546 (match_operand:SI 3 "arm_add_operand"
9547 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9548 (const_int 0)))]
9549 "TARGET_32BIT"
9550 "*
9551 {
9552 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9553 {
9554 {\"cmp\\t%0, %1\",
9555 \"cmp\\t%2, %3\"},
9556 {\"cmn\\t%0, #%n1\",
9557 \"cmp\\t%2, %3\"},
9558 {\"cmp\\t%0, %1\",
9559 \"cmn\\t%2, #%n3\"},
9560 {\"cmn\\t%0, #%n1\",
9561 \"cmn\\t%2, #%n3\"}
9562 };
9563 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9564 {
9565 {\"cmp%D4\\t%2, %3\",
9566 \"cmp%D5\\t%0, %1\"},
9567 {\"cmp%D4\\t%2, %3\",
9568 \"cmn%D5\\t%0, #%n1\"},
9569 {\"cmn%D4\\t%2, #%n3\",
9570 \"cmp%D5\\t%0, %1\"},
9571 {\"cmn%D4\\t%2, #%n3\",
9572 \"cmn%D5\\t%0, #%n1\"}
9573 };
9574 static const char *const ite[2] =
9575 {
9576 \"it\\t%D4\",
9577 \"it\\t%D5\"
9578 };
9579 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9580 CMP_CMP, CMN_CMP, CMP_CMP,
9581 CMN_CMP, CMP_CMN, CMN_CMN};
9582 int swap =
9583 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9584
9585 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9586 if (TARGET_THUMB2) {
9587 output_asm_insn (ite[swap], operands);
9588 }
9589 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9590 return \"\";
9591 }
9592 "
9593 [(set_attr "conds" "set")
9594 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9595 (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9596 (set_attr_alternative "length"
9597 [(const_int 6)
9598 (const_int 8)
9599 (const_int 8)
9600 (const_int 8)
9601 (const_int 8)
9602 (if_then_else (eq_attr "is_thumb" "no")
9603 (const_int 8)
9604 (const_int 10))
9605 (if_then_else (eq_attr "is_thumb" "no")
9606 (const_int 8)
9607 (const_int 10))
9608 (if_then_else (eq_attr "is_thumb" "no")
9609 (const_int 8)
9610 (const_int 10))
9611 (if_then_else (eq_attr "is_thumb" "no")
9612 (const_int 8)
9613 (const_int 10))])
9614 (set_attr "type" "multiple")]
9615 )
9616
9617 (define_insn_and_split "*ior_scc_scc"
9618 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9619 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9620 [(match_operand:SI 1 "s_register_operand" "l,r")
9621 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9622 (match_operator:SI 6 "arm_comparison_operator"
9623 [(match_operand:SI 4 "s_register_operand" "l,r")
9624 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9625 (clobber (reg:CC CC_REGNUM))]
9626 "TARGET_32BIT
9627 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9628 != CCmode)"
9629 "#"
9630 "TARGET_32BIT && reload_completed"
9631 [(set (match_dup 7)
9632 (compare
9633 (ior:SI
9634 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9635 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9636 (const_int 0)))
9637 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9638 "operands[7]
9639 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9640 DOM_CC_X_OR_Y),
9641 CC_REGNUM);"
9642 [(set_attr "conds" "clob")
9643 (set_attr "enabled_for_depr_it" "yes,no")
9644 (set_attr "length" "16")
9645 (set_attr "type" "multiple")]
9646 )
9647
9648 ; If the above pattern is followed by a CMP insn, then the compare is
9649 ; redundant, since we can rework the conditional instruction that follows.
9650 (define_insn_and_split "*ior_scc_scc_cmp"
9651 [(set (match_operand 0 "dominant_cc_register" "")
9652 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9653 [(match_operand:SI 1 "s_register_operand" "l,r")
9654 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9655 (match_operator:SI 6 "arm_comparison_operator"
9656 [(match_operand:SI 4 "s_register_operand" "l,r")
9657 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9658 (const_int 0)))
9659 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9660 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9661 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9662 "TARGET_32BIT"
9663 "#"
9664 "TARGET_32BIT && reload_completed"
9665 [(set (match_dup 0)
9666 (compare
9667 (ior:SI
9668 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9669 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9670 (const_int 0)))
9671 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9672 ""
9673 [(set_attr "conds" "set")
9674 (set_attr "enabled_for_depr_it" "yes,no")
9675 (set_attr "length" "16")
9676 (set_attr "type" "multiple")]
9677 )
9678
9679 (define_insn_and_split "*and_scc_scc"
9680 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9681 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9682 [(match_operand:SI 1 "s_register_operand" "l,r")
9683 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9684 (match_operator:SI 6 "arm_comparison_operator"
9685 [(match_operand:SI 4 "s_register_operand" "l,r")
9686 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9687 (clobber (reg:CC CC_REGNUM))]
9688 "TARGET_32BIT
9689 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9690 != CCmode)"
9691 "#"
9692 "TARGET_32BIT && reload_completed
9693 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9694 != CCmode)"
9695 [(set (match_dup 7)
9696 (compare
9697 (and:SI
9698 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9699 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9700 (const_int 0)))
9701 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9702 "operands[7]
9703 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9704 DOM_CC_X_AND_Y),
9705 CC_REGNUM);"
9706 [(set_attr "conds" "clob")
9707 (set_attr "enabled_for_depr_it" "yes,no")
9708 (set_attr "length" "16")
9709 (set_attr "type" "multiple")]
9710 )
9711
9712 ; If the above pattern is followed by a CMP insn, then the compare is
9713 ; redundant, since we can rework the conditional instruction that follows.
9714 (define_insn_and_split "*and_scc_scc_cmp"
9715 [(set (match_operand 0 "dominant_cc_register" "")
9716 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9717 [(match_operand:SI 1 "s_register_operand" "l,r")
9718 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9719 (match_operator:SI 6 "arm_comparison_operator"
9720 [(match_operand:SI 4 "s_register_operand" "l,r")
9721 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9722 (const_int 0)))
9723 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9724 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9725 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9726 "TARGET_32BIT"
9727 "#"
9728 "TARGET_32BIT && reload_completed"
9729 [(set (match_dup 0)
9730 (compare
9731 (and:SI
9732 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9733 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9734 (const_int 0)))
9735 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9736 ""
9737 [(set_attr "conds" "set")
9738 (set_attr "enabled_for_depr_it" "yes,no")
9739 (set_attr "length" "16")
9740 (set_attr "type" "multiple")]
9741 )
9742
9743 ;; If there is no dominance in the comparison, then we can still save an
9744 ;; instruction in the AND case, since we can know that the second compare
9745 ;; need only zero the value if false (if true, then the value is already
9746 ;; correct).
9747 (define_insn_and_split "*and_scc_scc_nodom"
9748 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9749 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9750 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9751 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9752 (match_operator:SI 6 "arm_comparison_operator"
9753 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9754 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9755 (clobber (reg:CC CC_REGNUM))]
9756 "TARGET_32BIT
9757 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9758 == CCmode)"
9759 "#"
9760 "TARGET_32BIT && reload_completed"
9761 [(parallel [(set (match_dup 0)
9762 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9763 (clobber (reg:CC CC_REGNUM))])
9764 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9765 (set (match_dup 0)
9766 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9767 (match_dup 0)
9768 (const_int 0)))]
9769 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9770 operands[4], operands[5]),
9771 CC_REGNUM);
9772 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9773 operands[5]);"
9774 [(set_attr "conds" "clob")
9775 (set_attr "length" "20")
9776 (set_attr "type" "multiple")]
9777 )
9778
9779 (define_split
9780 [(set (reg:CC_NOOV CC_REGNUM)
9781 (compare:CC_NOOV (ior:SI
9782 (and:SI (match_operand:SI 0 "s_register_operand" "")
9783 (const_int 1))
9784 (match_operator:SI 1 "arm_comparison_operator"
9785 [(match_operand:SI 2 "s_register_operand" "")
9786 (match_operand:SI 3 "arm_add_operand" "")]))
9787 (const_int 0)))
9788 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9789 "TARGET_ARM"
9790 [(set (match_dup 4)
9791 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9792 (match_dup 0)))
9793 (set (reg:CC_NOOV CC_REGNUM)
9794 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9795 (const_int 0)))]
9796 "")
9797
9798 (define_split
9799 [(set (reg:CC_NOOV CC_REGNUM)
9800 (compare:CC_NOOV (ior:SI
9801 (match_operator:SI 1 "arm_comparison_operator"
9802 [(match_operand:SI 2 "s_register_operand" "")
9803 (match_operand:SI 3 "arm_add_operand" "")])
9804 (and:SI (match_operand:SI 0 "s_register_operand" "")
9805 (const_int 1)))
9806 (const_int 0)))
9807 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9808 "TARGET_ARM"
9809 [(set (match_dup 4)
9810 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9811 (match_dup 0)))
9812 (set (reg:CC_NOOV CC_REGNUM)
9813 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9814 (const_int 0)))]
9815 "")
9816 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9817
9818 (define_insn_and_split "*negscc"
9819 [(set (match_operand:SI 0 "s_register_operand" "=r")
9820 (neg:SI (match_operator 3 "arm_comparison_operator"
9821 [(match_operand:SI 1 "s_register_operand" "r")
9822 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9823 (clobber (reg:CC CC_REGNUM))]
9824 "TARGET_ARM"
9825 "#"
9826 "&& reload_completed"
9827 [(const_int 0)]
9828 {
9829 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9830
9831 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9832 {
9833 /* Emit mov\\t%0, %1, asr #31 */
9834 emit_insn (gen_rtx_SET (operands[0],
9835 gen_rtx_ASHIFTRT (SImode,
9836 operands[1],
9837 GEN_INT (31))));
9838 DONE;
9839 }
9840 else if (GET_CODE (operands[3]) == NE)
9841 {
9842 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9843 if (CONST_INT_P (operands[2]))
9844 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9845 GEN_INT (- INTVAL (operands[2]))));
9846 else
9847 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9848
9849 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9850 gen_rtx_NE (SImode,
9851 cc_reg,
9852 const0_rtx),
9853 gen_rtx_SET (operands[0],
9854 GEN_INT (~0))));
9855 DONE;
9856 }
9857 else
9858 {
9859 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9860 emit_insn (gen_rtx_SET (cc_reg,
9861 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9862 enum rtx_code rc = GET_CODE (operands[3]);
9863
9864 rc = reverse_condition (rc);
9865 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9866 gen_rtx_fmt_ee (rc,
9867 VOIDmode,
9868 cc_reg,
9869 const0_rtx),
9870 gen_rtx_SET (operands[0], const0_rtx)));
9871 rc = GET_CODE (operands[3]);
9872 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9873 gen_rtx_fmt_ee (rc,
9874 VOIDmode,
9875 cc_reg,
9876 const0_rtx),
9877 gen_rtx_SET (operands[0],
9878 GEN_INT (~0))));
9879 DONE;
9880 }
9881 FAIL;
9882 }
9883 [(set_attr "conds" "clob")
9884 (set_attr "length" "12")
9885 (set_attr "type" "multiple")]
9886 )
9887
9888 (define_insn_and_split "movcond_addsi"
9889 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9890 (if_then_else:SI
9891 (match_operator 5 "comparison_operator"
9892 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9893 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9894 (const_int 0)])
9895 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9896 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9897 (clobber (reg:CC CC_REGNUM))]
9898 "TARGET_32BIT"
9899 "#"
9900 "&& reload_completed"
9901 [(set (reg:CC_NOOV CC_REGNUM)
9902 (compare:CC_NOOV
9903 (plus:SI (match_dup 3)
9904 (match_dup 4))
9905 (const_int 0)))
9906 (set (match_dup 0) (match_dup 1))
9907 (cond_exec (match_dup 6)
9908 (set (match_dup 0) (match_dup 2)))]
9909 "
9910 {
9911 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9912 operands[3], operands[4]);
9913 enum rtx_code rc = GET_CODE (operands[5]);
9914 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9915 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9916 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9917 rc = reverse_condition (rc);
9918 else
9919 std::swap (operands[1], operands[2]);
9920
9921 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9922 }
9923 "
9924 [(set_attr "conds" "clob")
9925 (set_attr "enabled_for_depr_it" "no,yes,yes")
9926 (set_attr "type" "multiple")]
9927 )
9928
9929 (define_insn "movcond"
9930 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9931 (if_then_else:SI
9932 (match_operator 5 "arm_comparison_operator"
9933 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9934 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9935 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9936 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9937 (clobber (reg:CC CC_REGNUM))]
9938 "TARGET_ARM"
9939 "*
9940 if (GET_CODE (operands[5]) == LT
9941 && (operands[4] == const0_rtx))
9942 {
9943 if (which_alternative != 1 && REG_P (operands[1]))
9944 {
9945 if (operands[2] == const0_rtx)
9946 return \"and\\t%0, %1, %3, asr #31\";
9947 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9948 }
9949 else if (which_alternative != 0 && REG_P (operands[2]))
9950 {
9951 if (operands[1] == const0_rtx)
9952 return \"bic\\t%0, %2, %3, asr #31\";
9953 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9954 }
9955 /* The only case that falls through to here is when both ops 1 & 2
9956 are constants. */
9957 }
9958
9959 if (GET_CODE (operands[5]) == GE
9960 && (operands[4] == const0_rtx))
9961 {
9962 if (which_alternative != 1 && REG_P (operands[1]))
9963 {
9964 if (operands[2] == const0_rtx)
9965 return \"bic\\t%0, %1, %3, asr #31\";
9966 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9967 }
9968 else if (which_alternative != 0 && REG_P (operands[2]))
9969 {
9970 if (operands[1] == const0_rtx)
9971 return \"and\\t%0, %2, %3, asr #31\";
9972 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9973 }
9974 /* The only case that falls through to here is when both ops 1 & 2
9975 are constants. */
9976 }
9977 if (CONST_INT_P (operands[4])
9978 && !const_ok_for_arm (INTVAL (operands[4])))
9979 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9980 else
9981 output_asm_insn (\"cmp\\t%3, %4\", operands);
9982 if (which_alternative != 0)
9983 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9984 if (which_alternative != 1)
9985 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9986 return \"\";
9987 "
9988 [(set_attr "conds" "clob")
9989 (set_attr "length" "8,8,12")
9990 (set_attr "type" "multiple")]
9991 )
9992
9993 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9994
9995 (define_insn "*ifcompare_plus_move"
9996 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9997 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9998 [(match_operand:SI 4 "s_register_operand" "r,r")
9999 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10000 (plus:SI
10001 (match_operand:SI 2 "s_register_operand" "r,r")
10002 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10003 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10004 (clobber (reg:CC CC_REGNUM))]
10005 "TARGET_ARM"
10006 "#"
10007 [(set_attr "conds" "clob")
10008 (set_attr "length" "8,12")
10009 (set_attr "type" "multiple")]
10010 )
10011
10012 (define_insn "*if_plus_move"
10013 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10014 (if_then_else:SI
10015 (match_operator 4 "arm_comparison_operator"
10016 [(match_operand 5 "cc_register" "") (const_int 0)])
10017 (plus:SI
10018 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10019 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10020 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10021 "TARGET_ARM"
10022 "@
10023 add%d4\\t%0, %2, %3
10024 sub%d4\\t%0, %2, #%n3
10025 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10026 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10027 [(set_attr "conds" "use")
10028 (set_attr "length" "4,4,8,8")
10029 (set_attr_alternative "type"
10030 [(if_then_else (match_operand 3 "const_int_operand" "")
10031 (const_string "alu_imm" )
10032 (const_string "alu_sreg"))
10033 (const_string "alu_imm")
10034 (const_string "multiple")
10035 (const_string "multiple")])]
10036 )
10037
10038 (define_insn "*ifcompare_move_plus"
10039 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10040 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10041 [(match_operand:SI 4 "s_register_operand" "r,r")
10042 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10043 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10044 (plus:SI
10045 (match_operand:SI 2 "s_register_operand" "r,r")
10046 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10047 (clobber (reg:CC CC_REGNUM))]
10048 "TARGET_ARM"
10049 "#"
10050 [(set_attr "conds" "clob")
10051 (set_attr "length" "8,12")
10052 (set_attr "type" "multiple")]
10053 )
10054
10055 (define_insn "*if_move_plus"
10056 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10057 (if_then_else:SI
10058 (match_operator 4 "arm_comparison_operator"
10059 [(match_operand 5 "cc_register" "") (const_int 0)])
10060 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10061 (plus:SI
10062 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10063 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10064 "TARGET_ARM"
10065 "@
10066 add%D4\\t%0, %2, %3
10067 sub%D4\\t%0, %2, #%n3
10068 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10069 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10070 [(set_attr "conds" "use")
10071 (set_attr "length" "4,4,8,8")
10072 (set_attr_alternative "type"
10073 [(if_then_else (match_operand 3 "const_int_operand" "")
10074 (const_string "alu_imm" )
10075 (const_string "alu_sreg"))
10076 (const_string "alu_imm")
10077 (const_string "multiple")
10078 (const_string "multiple")])]
10079 )
10080
10081 (define_insn "*ifcompare_arith_arith"
10082 [(set (match_operand:SI 0 "s_register_operand" "=r")
10083 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10084 [(match_operand:SI 5 "s_register_operand" "r")
10085 (match_operand:SI 6 "arm_add_operand" "rIL")])
10086 (match_operator:SI 8 "shiftable_operator"
10087 [(match_operand:SI 1 "s_register_operand" "r")
10088 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10089 (match_operator:SI 7 "shiftable_operator"
10090 [(match_operand:SI 3 "s_register_operand" "r")
10091 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10092 (clobber (reg:CC CC_REGNUM))]
10093 "TARGET_ARM"
10094 "#"
10095 [(set_attr "conds" "clob")
10096 (set_attr "length" "12")
10097 (set_attr "type" "multiple")]
10098 )
10099
10100 (define_insn "*if_arith_arith"
10101 [(set (match_operand:SI 0 "s_register_operand" "=r")
10102 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10103 [(match_operand 8 "cc_register" "") (const_int 0)])
10104 (match_operator:SI 6 "shiftable_operator"
10105 [(match_operand:SI 1 "s_register_operand" "r")
10106 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10107 (match_operator:SI 7 "shiftable_operator"
10108 [(match_operand:SI 3 "s_register_operand" "r")
10109 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10110 "TARGET_ARM"
10111 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10112 [(set_attr "conds" "use")
10113 (set_attr "length" "8")
10114 (set_attr "type" "multiple")]
10115 )
10116
10117 (define_insn "*ifcompare_arith_move"
10118 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10119 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10120 [(match_operand:SI 2 "s_register_operand" "r,r")
10121 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10122 (match_operator:SI 7 "shiftable_operator"
10123 [(match_operand:SI 4 "s_register_operand" "r,r")
10124 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10125 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10126 (clobber (reg:CC CC_REGNUM))]
10127 "TARGET_ARM"
10128 "*
10129 /* If we have an operation where (op x 0) is the identity operation and
10130 the conditional operator is LT or GE and we are comparing against zero and
10131 everything is in registers then we can do this in two instructions. */
10132 if (operands[3] == const0_rtx
10133 && GET_CODE (operands[7]) != AND
10134 && REG_P (operands[5])
10135 && REG_P (operands[1])
10136 && REGNO (operands[1]) == REGNO (operands[4])
10137 && REGNO (operands[4]) != REGNO (operands[0]))
10138 {
10139 if (GET_CODE (operands[6]) == LT)
10140 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10141 else if (GET_CODE (operands[6]) == GE)
10142 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10143 }
10144 if (CONST_INT_P (operands[3])
10145 && !const_ok_for_arm (INTVAL (operands[3])))
10146 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10147 else
10148 output_asm_insn (\"cmp\\t%2, %3\", operands);
10149 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10150 if (which_alternative != 0)
10151 return \"mov%D6\\t%0, %1\";
10152 return \"\";
10153 "
10154 [(set_attr "conds" "clob")
10155 (set_attr "length" "8,12")
10156 (set_attr "type" "multiple")]
10157 )
10158
10159 (define_insn "*if_arith_move"
10160 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10161 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10162 [(match_operand 6 "cc_register" "") (const_int 0)])
10163 (match_operator:SI 5 "shiftable_operator"
10164 [(match_operand:SI 2 "s_register_operand" "r,r")
10165 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10166 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10167 "TARGET_ARM"
10168 "@
10169 %I5%d4\\t%0, %2, %3
10170 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10171 [(set_attr "conds" "use")
10172 (set_attr "length" "4,8")
10173 (set_attr_alternative "type"
10174 [(if_then_else (match_operand 3 "const_int_operand" "")
10175 (const_string "alu_shift_imm" )
10176 (const_string "alu_shift_reg"))
10177 (const_string "multiple")])]
10178 )
10179
10180 (define_insn "*ifcompare_move_arith"
10181 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10182 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10183 [(match_operand:SI 4 "s_register_operand" "r,r")
10184 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10185 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10186 (match_operator:SI 7 "shiftable_operator"
10187 [(match_operand:SI 2 "s_register_operand" "r,r")
10188 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10189 (clobber (reg:CC CC_REGNUM))]
10190 "TARGET_ARM"
10191 "*
10192 /* If we have an operation where (op x 0) is the identity operation and
10193 the conditional operator is LT or GE and we are comparing against zero and
10194 everything is in registers then we can do this in two instructions */
10195 if (operands[5] == const0_rtx
10196 && GET_CODE (operands[7]) != AND
10197 && REG_P (operands[3])
10198 && REG_P (operands[1])
10199 && REGNO (operands[1]) == REGNO (operands[2])
10200 && REGNO (operands[2]) != REGNO (operands[0]))
10201 {
10202 if (GET_CODE (operands[6]) == GE)
10203 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10204 else if (GET_CODE (operands[6]) == LT)
10205 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10206 }
10207
10208 if (CONST_INT_P (operands[5])
10209 && !const_ok_for_arm (INTVAL (operands[5])))
10210 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10211 else
10212 output_asm_insn (\"cmp\\t%4, %5\", operands);
10213
10214 if (which_alternative != 0)
10215 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10216 return \"%I7%D6\\t%0, %2, %3\";
10217 "
10218 [(set_attr "conds" "clob")
10219 (set_attr "length" "8,12")
10220 (set_attr "type" "multiple")]
10221 )
10222
10223 (define_insn "*if_move_arith"
10224 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10225 (if_then_else:SI
10226 (match_operator 4 "arm_comparison_operator"
10227 [(match_operand 6 "cc_register" "") (const_int 0)])
10228 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10229 (match_operator:SI 5 "shiftable_operator"
10230 [(match_operand:SI 2 "s_register_operand" "r,r")
10231 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10232 "TARGET_ARM"
10233 "@
10234 %I5%D4\\t%0, %2, %3
10235 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10236 [(set_attr "conds" "use")
10237 (set_attr "length" "4,8")
10238 (set_attr_alternative "type"
10239 [(if_then_else (match_operand 3 "const_int_operand" "")
10240 (const_string "alu_shift_imm" )
10241 (const_string "alu_shift_reg"))
10242 (const_string "multiple")])]
10243 )
10244
10245 (define_insn "*ifcompare_move_not"
10246 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10247 (if_then_else:SI
10248 (match_operator 5 "arm_comparison_operator"
10249 [(match_operand:SI 3 "s_register_operand" "r,r")
10250 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10251 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10252 (not:SI
10253 (match_operand:SI 2 "s_register_operand" "r,r"))))
10254 (clobber (reg:CC CC_REGNUM))]
10255 "TARGET_ARM"
10256 "#"
10257 [(set_attr "conds" "clob")
10258 (set_attr "length" "8,12")
10259 (set_attr "type" "multiple")]
10260 )
10261
10262 (define_insn "*if_move_not"
10263 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10264 (if_then_else:SI
10265 (match_operator 4 "arm_comparison_operator"
10266 [(match_operand 3 "cc_register" "") (const_int 0)])
10267 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10268 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10269 "TARGET_ARM"
10270 "@
10271 mvn%D4\\t%0, %2
10272 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10273 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10274 [(set_attr "conds" "use")
10275 (set_attr "type" "mvn_reg")
10276 (set_attr "length" "4,8,8")
10277 (set_attr "type" "mvn_reg,multiple,multiple")]
10278 )
10279
10280 (define_insn "*ifcompare_not_move"
10281 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10282 (if_then_else:SI
10283 (match_operator 5 "arm_comparison_operator"
10284 [(match_operand:SI 3 "s_register_operand" "r,r")
10285 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10286 (not:SI
10287 (match_operand:SI 2 "s_register_operand" "r,r"))
10288 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10289 (clobber (reg:CC CC_REGNUM))]
10290 "TARGET_ARM"
10291 "#"
10292 [(set_attr "conds" "clob")
10293 (set_attr "length" "8,12")
10294 (set_attr "type" "multiple")]
10295 )
10296
10297 (define_insn "*if_not_move"
10298 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10299 (if_then_else:SI
10300 (match_operator 4 "arm_comparison_operator"
10301 [(match_operand 3 "cc_register" "") (const_int 0)])
10302 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10303 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10304 "TARGET_ARM"
10305 "@
10306 mvn%d4\\t%0, %2
10307 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10308 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10309 [(set_attr "conds" "use")
10310 (set_attr "type" "mvn_reg,multiple,multiple")
10311 (set_attr "length" "4,8,8")]
10312 )
10313
10314 (define_insn "*ifcompare_shift_move"
10315 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10316 (if_then_else:SI
10317 (match_operator 6 "arm_comparison_operator"
10318 [(match_operand:SI 4 "s_register_operand" "r,r")
10319 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10320 (match_operator:SI 7 "shift_operator"
10321 [(match_operand:SI 2 "s_register_operand" "r,r")
10322 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10323 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10324 (clobber (reg:CC CC_REGNUM))]
10325 "TARGET_ARM"
10326 "#"
10327 [(set_attr "conds" "clob")
10328 (set_attr "length" "8,12")
10329 (set_attr "type" "multiple")]
10330 )
10331
10332 (define_insn "*if_shift_move"
10333 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10334 (if_then_else:SI
10335 (match_operator 5 "arm_comparison_operator"
10336 [(match_operand 6 "cc_register" "") (const_int 0)])
10337 (match_operator:SI 4 "shift_operator"
10338 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10339 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10340 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10341 "TARGET_ARM"
10342 "@
10343 mov%d5\\t%0, %2%S4
10344 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10345 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10346 [(set_attr "conds" "use")
10347 (set_attr "shift" "2")
10348 (set_attr "length" "4,8,8")
10349 (set_attr_alternative "type"
10350 [(if_then_else (match_operand 3 "const_int_operand" "")
10351 (const_string "mov_shift" )
10352 (const_string "mov_shift_reg"))
10353 (const_string "multiple")
10354 (const_string "multiple")])]
10355 )
10356
10357 (define_insn "*ifcompare_move_shift"
10358 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10359 (if_then_else:SI
10360 (match_operator 6 "arm_comparison_operator"
10361 [(match_operand:SI 4 "s_register_operand" "r,r")
10362 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10363 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10364 (match_operator:SI 7 "shift_operator"
10365 [(match_operand:SI 2 "s_register_operand" "r,r")
10366 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10367 (clobber (reg:CC CC_REGNUM))]
10368 "TARGET_ARM"
10369 "#"
10370 [(set_attr "conds" "clob")
10371 (set_attr "length" "8,12")
10372 (set_attr "type" "multiple")]
10373 )
10374
10375 (define_insn "*if_move_shift"
10376 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10377 (if_then_else:SI
10378 (match_operator 5 "arm_comparison_operator"
10379 [(match_operand 6 "cc_register" "") (const_int 0)])
10380 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10381 (match_operator:SI 4 "shift_operator"
10382 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10383 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10384 "TARGET_ARM"
10385 "@
10386 mov%D5\\t%0, %2%S4
10387 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10388 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10389 [(set_attr "conds" "use")
10390 (set_attr "shift" "2")
10391 (set_attr "length" "4,8,8")
10392 (set_attr_alternative "type"
10393 [(if_then_else (match_operand 3 "const_int_operand" "")
10394 (const_string "mov_shift" )
10395 (const_string "mov_shift_reg"))
10396 (const_string "multiple")
10397 (const_string "multiple")])]
10398 )
10399
10400 (define_insn "*ifcompare_shift_shift"
10401 [(set (match_operand:SI 0 "s_register_operand" "=r")
10402 (if_then_else:SI
10403 (match_operator 7 "arm_comparison_operator"
10404 [(match_operand:SI 5 "s_register_operand" "r")
10405 (match_operand:SI 6 "arm_add_operand" "rIL")])
10406 (match_operator:SI 8 "shift_operator"
10407 [(match_operand:SI 1 "s_register_operand" "r")
10408 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10409 (match_operator:SI 9 "shift_operator"
10410 [(match_operand:SI 3 "s_register_operand" "r")
10411 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10412 (clobber (reg:CC CC_REGNUM))]
10413 "TARGET_ARM"
10414 "#"
10415 [(set_attr "conds" "clob")
10416 (set_attr "length" "12")
10417 (set_attr "type" "multiple")]
10418 )
10419
10420 (define_insn "*if_shift_shift"
10421 [(set (match_operand:SI 0 "s_register_operand" "=r")
10422 (if_then_else:SI
10423 (match_operator 5 "arm_comparison_operator"
10424 [(match_operand 8 "cc_register" "") (const_int 0)])
10425 (match_operator:SI 6 "shift_operator"
10426 [(match_operand:SI 1 "s_register_operand" "r")
10427 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10428 (match_operator:SI 7 "shift_operator"
10429 [(match_operand:SI 3 "s_register_operand" "r")
10430 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10431 "TARGET_ARM"
10432 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10433 [(set_attr "conds" "use")
10434 (set_attr "shift" "1")
10435 (set_attr "length" "8")
10436 (set (attr "type") (if_then_else
10437 (and (match_operand 2 "const_int_operand" "")
10438 (match_operand 4 "const_int_operand" ""))
10439 (const_string "mov_shift")
10440 (const_string "mov_shift_reg")))]
10441 )
10442
10443 (define_insn "*ifcompare_not_arith"
10444 [(set (match_operand:SI 0 "s_register_operand" "=r")
10445 (if_then_else:SI
10446 (match_operator 6 "arm_comparison_operator"
10447 [(match_operand:SI 4 "s_register_operand" "r")
10448 (match_operand:SI 5 "arm_add_operand" "rIL")])
10449 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10450 (match_operator:SI 7 "shiftable_operator"
10451 [(match_operand:SI 2 "s_register_operand" "r")
10452 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10453 (clobber (reg:CC CC_REGNUM))]
10454 "TARGET_ARM"
10455 "#"
10456 [(set_attr "conds" "clob")
10457 (set_attr "length" "12")
10458 (set_attr "type" "multiple")]
10459 )
10460
10461 (define_insn "*if_not_arith"
10462 [(set (match_operand:SI 0 "s_register_operand" "=r")
10463 (if_then_else:SI
10464 (match_operator 5 "arm_comparison_operator"
10465 [(match_operand 4 "cc_register" "") (const_int 0)])
10466 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10467 (match_operator:SI 6 "shiftable_operator"
10468 [(match_operand:SI 2 "s_register_operand" "r")
10469 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10470 "TARGET_ARM"
10471 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10472 [(set_attr "conds" "use")
10473 (set_attr "type" "mvn_reg")
10474 (set_attr "length" "8")]
10475 )
10476
10477 (define_insn "*ifcompare_arith_not"
10478 [(set (match_operand:SI 0 "s_register_operand" "=r")
10479 (if_then_else:SI
10480 (match_operator 6 "arm_comparison_operator"
10481 [(match_operand:SI 4 "s_register_operand" "r")
10482 (match_operand:SI 5 "arm_add_operand" "rIL")])
10483 (match_operator:SI 7 "shiftable_operator"
10484 [(match_operand:SI 2 "s_register_operand" "r")
10485 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10486 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10487 (clobber (reg:CC CC_REGNUM))]
10488 "TARGET_ARM"
10489 "#"
10490 [(set_attr "conds" "clob")
10491 (set_attr "length" "12")
10492 (set_attr "type" "multiple")]
10493 )
10494
10495 (define_insn "*if_arith_not"
10496 [(set (match_operand:SI 0 "s_register_operand" "=r")
10497 (if_then_else:SI
10498 (match_operator 5 "arm_comparison_operator"
10499 [(match_operand 4 "cc_register" "") (const_int 0)])
10500 (match_operator:SI 6 "shiftable_operator"
10501 [(match_operand:SI 2 "s_register_operand" "r")
10502 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10503 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10504 "TARGET_ARM"
10505 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10506 [(set_attr "conds" "use")
10507 (set_attr "type" "multiple")
10508 (set_attr "length" "8")]
10509 )
10510
10511 (define_insn "*ifcompare_neg_move"
10512 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10513 (if_then_else:SI
10514 (match_operator 5 "arm_comparison_operator"
10515 [(match_operand:SI 3 "s_register_operand" "r,r")
10516 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10517 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10518 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10519 (clobber (reg:CC CC_REGNUM))]
10520 "TARGET_ARM"
10521 "#"
10522 [(set_attr "conds" "clob")
10523 (set_attr "length" "8,12")
10524 (set_attr "type" "multiple")]
10525 )
10526
10527 (define_insn_and_split "*if_neg_move"
10528 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10529 (if_then_else:SI
10530 (match_operator 4 "arm_comparison_operator"
10531 [(match_operand 3 "cc_register" "") (const_int 0)])
10532 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10533 (match_operand:SI 1 "s_register_operand" "0,0")))]
10534 "TARGET_32BIT"
10535 "#"
10536 "&& reload_completed"
10537 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10538 (set (match_dup 0) (neg:SI (match_dup 2))))]
10539 ""
10540 [(set_attr "conds" "use")
10541 (set_attr "length" "4")
10542 (set_attr "arch" "t2,32")
10543 (set_attr "enabled_for_depr_it" "yes,no")
10544 (set_attr "type" "logic_shift_imm")]
10545 )
10546
10547 (define_insn "*ifcompare_move_neg"
10548 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10549 (if_then_else:SI
10550 (match_operator 5 "arm_comparison_operator"
10551 [(match_operand:SI 3 "s_register_operand" "r,r")
10552 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10553 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10554 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10555 (clobber (reg:CC CC_REGNUM))]
10556 "TARGET_ARM"
10557 "#"
10558 [(set_attr "conds" "clob")
10559 (set_attr "length" "8,12")
10560 (set_attr "type" "multiple")]
10561 )
10562
10563 (define_insn_and_split "*if_move_neg"
10564 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10565 (if_then_else:SI
10566 (match_operator 4 "arm_comparison_operator"
10567 [(match_operand 3 "cc_register" "") (const_int 0)])
10568 (match_operand:SI 1 "s_register_operand" "0,0")
10569 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10570 "TARGET_32BIT"
10571 "#"
10572 "&& reload_completed"
10573 [(cond_exec (match_dup 5)
10574 (set (match_dup 0) (neg:SI (match_dup 2))))]
10575 {
10576 machine_mode mode = GET_MODE (operands[3]);
10577 rtx_code rc = GET_CODE (operands[4]);
10578
10579 if (mode == CCFPmode || mode == CCFPEmode)
10580 rc = reverse_condition_maybe_unordered (rc);
10581 else
10582 rc = reverse_condition (rc);
10583
10584 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10585 }
10586 [(set_attr "conds" "use")
10587 (set_attr "length" "4")
10588 (set_attr "arch" "t2,32")
10589 (set_attr "enabled_for_depr_it" "yes,no")
10590 (set_attr "type" "logic_shift_imm")]
10591 )
10592
10593 (define_insn "*arith_adjacentmem"
10594 [(set (match_operand:SI 0 "s_register_operand" "=r")
10595 (match_operator:SI 1 "shiftable_operator"
10596 [(match_operand:SI 2 "memory_operand" "m")
10597 (match_operand:SI 3 "memory_operand" "m")]))
10598 (clobber (match_scratch:SI 4 "=r"))]
10599 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10600 "*
10601 {
10602 rtx ldm[3];
10603 rtx arith[4];
10604 rtx base_reg;
10605 HOST_WIDE_INT val1 = 0, val2 = 0;
10606
10607 if (REGNO (operands[0]) > REGNO (operands[4]))
10608 {
10609 ldm[1] = operands[4];
10610 ldm[2] = operands[0];
10611 }
10612 else
10613 {
10614 ldm[1] = operands[0];
10615 ldm[2] = operands[4];
10616 }
10617
10618 base_reg = XEXP (operands[2], 0);
10619
10620 if (!REG_P (base_reg))
10621 {
10622 val1 = INTVAL (XEXP (base_reg, 1));
10623 base_reg = XEXP (base_reg, 0);
10624 }
10625
10626 if (!REG_P (XEXP (operands[3], 0)))
10627 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10628
10629 arith[0] = operands[0];
10630 arith[3] = operands[1];
10631
10632 if (val1 < val2)
10633 {
10634 arith[1] = ldm[1];
10635 arith[2] = ldm[2];
10636 }
10637 else
10638 {
10639 arith[1] = ldm[2];
10640 arith[2] = ldm[1];
10641 }
10642
10643 ldm[0] = base_reg;
10644 if (val1 !=0 && val2 != 0)
10645 {
10646 rtx ops[3];
10647
10648 if (val1 == 4 || val2 == 4)
10649 /* Other val must be 8, since we know they are adjacent and neither
10650 is zero. */
10651 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10652 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10653 {
10654 ldm[0] = ops[0] = operands[4];
10655 ops[1] = base_reg;
10656 ops[2] = GEN_INT (val1);
10657 output_add_immediate (ops);
10658 if (val1 < val2)
10659 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10660 else
10661 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10662 }
10663 else
10664 {
10665 /* Offset is out of range for a single add, so use two ldr. */
10666 ops[0] = ldm[1];
10667 ops[1] = base_reg;
10668 ops[2] = GEN_INT (val1);
10669 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10670 ops[0] = ldm[2];
10671 ops[2] = GEN_INT (val2);
10672 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10673 }
10674 }
10675 else if (val1 != 0)
10676 {
10677 if (val1 < val2)
10678 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10679 else
10680 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10681 }
10682 else
10683 {
10684 if (val1 < val2)
10685 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10686 else
10687 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10688 }
10689 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10690 return \"\";
10691 }"
10692 [(set_attr "length" "12")
10693 (set_attr "predicable" "yes")
10694 (set_attr "type" "load_4")]
10695 )
10696
10697 ; This pattern is never tried by combine, so do it as a peephole
10698
10699 (define_peephole2
10700 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10701 (match_operand:SI 1 "arm_general_register_operand" ""))
10702 (set (reg:CC CC_REGNUM)
10703 (compare:CC (match_dup 1) (const_int 0)))]
10704 "TARGET_ARM"
10705 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10706 (set (match_dup 0) (match_dup 1))])]
10707 ""
10708 )
10709
10710 (define_split
10711 [(set (match_operand:SI 0 "s_register_operand" "")
10712 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10713 (const_int 0))
10714 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10715 [(match_operand:SI 3 "s_register_operand" "")
10716 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10717 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10718 "TARGET_ARM"
10719 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10720 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10721 (match_dup 5)))]
10722 ""
10723 )
10724
10725 ;; This split can be used because CC_Z mode implies that the following
10726 ;; branch will be an equality, or an unsigned inequality, so the sign
10727 ;; extension is not needed.
10728
10729 (define_split
10730 [(set (reg:CC_Z CC_REGNUM)
10731 (compare:CC_Z
10732 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10733 (const_int 24))
10734 (match_operand 1 "const_int_operand" "")))
10735 (clobber (match_scratch:SI 2 ""))]
10736 "TARGET_ARM
10737 && ((UINTVAL (operands[1]))
10738 == ((UINTVAL (operands[1])) >> 24) << 24)"
10739 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10740 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10741 "
10742 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10743 "
10744 )
10745 ;; ??? Check the patterns above for Thumb-2 usefulness
10746
10747 (define_expand "prologue"
10748 [(clobber (const_int 0))]
10749 "TARGET_EITHER"
10750 "if (TARGET_32BIT)
10751 arm_expand_prologue ();
10752 else
10753 thumb1_expand_prologue ();
10754 DONE;
10755 "
10756 )
10757
10758 (define_expand "epilogue"
10759 [(clobber (const_int 0))]
10760 "TARGET_EITHER"
10761 "
10762 if (crtl->calls_eh_return)
10763 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10764 if (TARGET_THUMB1)
10765 {
10766 thumb1_expand_epilogue ();
10767 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10768 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10769 }
10770 else if (HAVE_return)
10771 {
10772 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10773 no need for explicit testing again. */
10774 emit_jump_insn (gen_return ());
10775 }
10776 else if (TARGET_32BIT)
10777 {
10778 arm_expand_epilogue (true);
10779 }
10780 DONE;
10781 "
10782 )
10783
10784 ;; Note - although unspec_volatile's USE all hard registers,
10785 ;; USEs are ignored after relaod has completed. Thus we need
10786 ;; to add an unspec of the link register to ensure that flow
10787 ;; does not think that it is unused by the sibcall branch that
10788 ;; will replace the standard function epilogue.
10789 (define_expand "sibcall_epilogue"
10790 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10791 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10792 "TARGET_32BIT"
10793 "
10794 arm_expand_epilogue (false);
10795 DONE;
10796 "
10797 )
10798
10799 (define_expand "eh_epilogue"
10800 [(use (match_operand:SI 0 "register_operand" ""))
10801 (use (match_operand:SI 1 "register_operand" ""))
10802 (use (match_operand:SI 2 "register_operand" ""))]
10803 "TARGET_EITHER"
10804 "
10805 {
10806 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10807 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10808 {
10809 rtx ra = gen_rtx_REG (Pmode, 2);
10810
10811 emit_move_insn (ra, operands[2]);
10812 operands[2] = ra;
10813 }
10814 /* This is a hack -- we may have crystalized the function type too
10815 early. */
10816 cfun->machine->func_type = 0;
10817 }"
10818 )
10819
10820 ;; This split is only used during output to reduce the number of patterns
10821 ;; that need assembler instructions adding to them. We allowed the setting
10822 ;; of the conditions to be implicit during rtl generation so that
10823 ;; the conditional compare patterns would work. However this conflicts to
10824 ;; some extent with the conditional data operations, so we have to split them
10825 ;; up again here.
10826
10827 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10828 ;; conditional execution sufficient?
10829
10830 (define_split
10831 [(set (match_operand:SI 0 "s_register_operand" "")
10832 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10833 [(match_operand 2 "" "") (match_operand 3 "" "")])
10834 (match_dup 0)
10835 (match_operand 4 "" "")))
10836 (clobber (reg:CC CC_REGNUM))]
10837 "TARGET_ARM && reload_completed"
10838 [(set (match_dup 5) (match_dup 6))
10839 (cond_exec (match_dup 7)
10840 (set (match_dup 0) (match_dup 4)))]
10841 "
10842 {
10843 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10844 operands[2], operands[3]);
10845 enum rtx_code rc = GET_CODE (operands[1]);
10846
10847 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10848 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10849 if (mode == CCFPmode || mode == CCFPEmode)
10850 rc = reverse_condition_maybe_unordered (rc);
10851 else
10852 rc = reverse_condition (rc);
10853
10854 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10855 }"
10856 )
10857
10858 (define_split
10859 [(set (match_operand:SI 0 "s_register_operand" "")
10860 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10861 [(match_operand 2 "" "") (match_operand 3 "" "")])
10862 (match_operand 4 "" "")
10863 (match_dup 0)))
10864 (clobber (reg:CC CC_REGNUM))]
10865 "TARGET_ARM && reload_completed"
10866 [(set (match_dup 5) (match_dup 6))
10867 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10868 (set (match_dup 0) (match_dup 4)))]
10869 "
10870 {
10871 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10872 operands[2], operands[3]);
10873
10874 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10875 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10876 }"
10877 )
10878
10879 (define_split
10880 [(set (match_operand:SI 0 "s_register_operand" "")
10881 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10882 [(match_operand 2 "" "") (match_operand 3 "" "")])
10883 (match_operand 4 "" "")
10884 (match_operand 5 "" "")))
10885 (clobber (reg:CC CC_REGNUM))]
10886 "TARGET_ARM && reload_completed"
10887 [(set (match_dup 6) (match_dup 7))
10888 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10889 (set (match_dup 0) (match_dup 4)))
10890 (cond_exec (match_dup 8)
10891 (set (match_dup 0) (match_dup 5)))]
10892 "
10893 {
10894 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10895 operands[2], operands[3]);
10896 enum rtx_code rc = GET_CODE (operands[1]);
10897
10898 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10899 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10900 if (mode == CCFPmode || mode == CCFPEmode)
10901 rc = reverse_condition_maybe_unordered (rc);
10902 else
10903 rc = reverse_condition (rc);
10904
10905 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10906 }"
10907 )
10908
10909 (define_split
10910 [(set (match_operand:SI 0 "s_register_operand" "")
10911 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10912 [(match_operand:SI 2 "s_register_operand" "")
10913 (match_operand:SI 3 "arm_add_operand" "")])
10914 (match_operand:SI 4 "arm_rhs_operand" "")
10915 (not:SI
10916 (match_operand:SI 5 "s_register_operand" ""))))
10917 (clobber (reg:CC CC_REGNUM))]
10918 "TARGET_ARM && reload_completed"
10919 [(set (match_dup 6) (match_dup 7))
10920 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10921 (set (match_dup 0) (match_dup 4)))
10922 (cond_exec (match_dup 8)
10923 (set (match_dup 0) (not:SI (match_dup 5))))]
10924 "
10925 {
10926 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10927 operands[2], operands[3]);
10928 enum rtx_code rc = GET_CODE (operands[1]);
10929
10930 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10931 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10932 if (mode == CCFPmode || mode == CCFPEmode)
10933 rc = reverse_condition_maybe_unordered (rc);
10934 else
10935 rc = reverse_condition (rc);
10936
10937 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10938 }"
10939 )
10940
10941 (define_insn "*cond_move_not"
10942 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10943 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10944 [(match_operand 3 "cc_register" "") (const_int 0)])
10945 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10946 (not:SI
10947 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10948 "TARGET_ARM"
10949 "@
10950 mvn%D4\\t%0, %2
10951 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10952 [(set_attr "conds" "use")
10953 (set_attr "type" "mvn_reg,multiple")
10954 (set_attr "length" "4,8")]
10955 )
10956
10957 ;; The next two patterns occur when an AND operation is followed by a
10958 ;; scc insn sequence
10959
10960 (define_insn "*sign_extract_onebit"
10961 [(set (match_operand:SI 0 "s_register_operand" "=r")
10962 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10963 (const_int 1)
10964 (match_operand:SI 2 "const_int_operand" "n")))
10965 (clobber (reg:CC CC_REGNUM))]
10966 "TARGET_ARM"
10967 "*
10968 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10969 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10970 return \"mvnne\\t%0, #0\";
10971 "
10972 [(set_attr "conds" "clob")
10973 (set_attr "length" "8")
10974 (set_attr "type" "multiple")]
10975 )
10976
10977 (define_insn "*not_signextract_onebit"
10978 [(set (match_operand:SI 0 "s_register_operand" "=r")
10979 (not:SI
10980 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10981 (const_int 1)
10982 (match_operand:SI 2 "const_int_operand" "n"))))
10983 (clobber (reg:CC CC_REGNUM))]
10984 "TARGET_ARM"
10985 "*
10986 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10987 output_asm_insn (\"tst\\t%1, %2\", operands);
10988 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10989 return \"movne\\t%0, #0\";
10990 "
10991 [(set_attr "conds" "clob")
10992 (set_attr "length" "12")
10993 (set_attr "type" "multiple")]
10994 )
10995 ;; ??? The above patterns need auditing for Thumb-2
10996
10997 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10998 ;; expressions. For simplicity, the first register is also in the unspec
10999 ;; part.
11000 ;; To avoid the usage of GNU extension, the length attribute is computed
11001 ;; in a C function arm_attr_length_push_multi.
11002 (define_insn "*push_multi"
11003 [(match_parallel 2 "multi_register_push"
11004 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11005 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11006 UNSPEC_PUSH_MULT))])]
11007 ""
11008 "*
11009 {
11010 int num_saves = XVECLEN (operands[2], 0);
11011
11012 /* For the StrongARM at least it is faster to
11013 use STR to store only a single register.
11014 In Thumb mode always use push, and the assembler will pick
11015 something appropriate. */
11016 if (num_saves == 1 && TARGET_ARM)
11017 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11018 else
11019 {
11020 int i;
11021 char pattern[100];
11022
11023 if (TARGET_32BIT)
11024 strcpy (pattern, \"push%?\\t{%1\");
11025 else
11026 strcpy (pattern, \"push\\t{%1\");
11027
11028 for (i = 1; i < num_saves; i++)
11029 {
11030 strcat (pattern, \", %|\");
11031 strcat (pattern,
11032 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11033 }
11034
11035 strcat (pattern, \"}\");
11036 output_asm_insn (pattern, operands);
11037 }
11038
11039 return \"\";
11040 }"
11041 [(set_attr "type" "store_16")
11042 (set (attr "length")
11043 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11044 )
11045
11046 (define_insn "stack_tie"
11047 [(set (mem:BLK (scratch))
11048 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11049 (match_operand:SI 1 "s_register_operand" "rk")]
11050 UNSPEC_PRLG_STK))]
11051 ""
11052 ""
11053 [(set_attr "length" "0")
11054 (set_attr "type" "block")]
11055 )
11056
11057 ;; Pop (as used in epilogue RTL)
11058 ;;
11059 (define_insn "*load_multiple_with_writeback"
11060 [(match_parallel 0 "load_multiple_operation"
11061 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11062 (plus:SI (match_dup 1)
11063 (match_operand:SI 2 "const_int_I_operand" "I")))
11064 (set (match_operand:SI 3 "s_register_operand" "=rk")
11065 (mem:SI (match_dup 1)))
11066 ])]
11067 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11068 "*
11069 {
11070 arm_output_multireg_pop (operands, /*return_pc=*/false,
11071 /*cond=*/const_true_rtx,
11072 /*reverse=*/false,
11073 /*update=*/true);
11074 return \"\";
11075 }
11076 "
11077 [(set_attr "type" "load_16")
11078 (set_attr "predicable" "yes")
11079 (set (attr "length")
11080 (symbol_ref "arm_attr_length_pop_multi (operands,
11081 /*return_pc=*/false,
11082 /*write_back_p=*/true)"))]
11083 )
11084
11085 ;; Pop with return (as used in epilogue RTL)
11086 ;;
11087 ;; This instruction is generated when the registers are popped at the end of
11088 ;; epilogue. Here, instead of popping the value into LR and then generating
11089 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11090 ;; with (return).
11091 (define_insn "*pop_multiple_with_writeback_and_return"
11092 [(match_parallel 0 "pop_multiple_return"
11093 [(return)
11094 (set (match_operand:SI 1 "s_register_operand" "+rk")
11095 (plus:SI (match_dup 1)
11096 (match_operand:SI 2 "const_int_I_operand" "I")))
11097 (set (match_operand:SI 3 "s_register_operand" "=rk")
11098 (mem:SI (match_dup 1)))
11099 ])]
11100 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11101 "*
11102 {
11103 arm_output_multireg_pop (operands, /*return_pc=*/true,
11104 /*cond=*/const_true_rtx,
11105 /*reverse=*/false,
11106 /*update=*/true);
11107 return \"\";
11108 }
11109 "
11110 [(set_attr "type" "load_16")
11111 (set_attr "predicable" "yes")
11112 (set (attr "length")
11113 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11114 /*write_back_p=*/true)"))]
11115 )
11116
11117 (define_insn "*pop_multiple_with_return"
11118 [(match_parallel 0 "pop_multiple_return"
11119 [(return)
11120 (set (match_operand:SI 2 "s_register_operand" "=rk")
11121 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11122 ])]
11123 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11124 "*
11125 {
11126 arm_output_multireg_pop (operands, /*return_pc=*/true,
11127 /*cond=*/const_true_rtx,
11128 /*reverse=*/false,
11129 /*update=*/false);
11130 return \"\";
11131 }
11132 "
11133 [(set_attr "type" "load_16")
11134 (set_attr "predicable" "yes")
11135 (set (attr "length")
11136 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11137 /*write_back_p=*/false)"))]
11138 )
11139
11140 ;; Load into PC and return
11141 (define_insn "*ldr_with_return"
11142 [(return)
11143 (set (reg:SI PC_REGNUM)
11144 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11145 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11146 "ldr%?\t%|pc, [%0], #4"
11147 [(set_attr "type" "load_4")
11148 (set_attr "predicable" "yes")]
11149 )
11150 ;; Pop for floating point registers (as used in epilogue RTL)
11151 (define_insn "*vfp_pop_multiple_with_writeback"
11152 [(match_parallel 0 "pop_multiple_fp"
11153 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11154 (plus:SI (match_dup 1)
11155 (match_operand:SI 2 "const_int_I_operand" "I")))
11156 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11157 (mem:DF (match_dup 1)))])]
11158 "TARGET_32BIT && TARGET_HARD_FLOAT"
11159 "*
11160 {
11161 int num_regs = XVECLEN (operands[0], 0);
11162 char pattern[100];
11163 rtx op_list[2];
11164 strcpy (pattern, \"vldm\\t\");
11165 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11166 strcat (pattern, \"!, {\");
11167 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11168 strcat (pattern, \"%P0\");
11169 if ((num_regs - 1) > 1)
11170 {
11171 strcat (pattern, \"-%P1\");
11172 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11173 }
11174
11175 strcat (pattern, \"}\");
11176 output_asm_insn (pattern, op_list);
11177 return \"\";
11178 }
11179 "
11180 [(set_attr "type" "load_16")
11181 (set_attr "conds" "unconditional")
11182 (set_attr "predicable" "no")]
11183 )
11184
11185 ;; Special patterns for dealing with the constant pool
11186
11187 (define_insn "align_4"
11188 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11189 "TARGET_EITHER"
11190 "*
11191 assemble_align (32);
11192 return \"\";
11193 "
11194 [(set_attr "type" "no_insn")]
11195 )
11196
11197 (define_insn "align_8"
11198 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11199 "TARGET_EITHER"
11200 "*
11201 assemble_align (64);
11202 return \"\";
11203 "
11204 [(set_attr "type" "no_insn")]
11205 )
11206
11207 (define_insn "consttable_end"
11208 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11209 "TARGET_EITHER"
11210 "*
11211 making_const_table = FALSE;
11212 return \"\";
11213 "
11214 [(set_attr "type" "no_insn")]
11215 )
11216
11217 (define_insn "consttable_1"
11218 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11219 "TARGET_EITHER"
11220 "*
11221 making_const_table = TRUE;
11222 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11223 assemble_zeros (3);
11224 return \"\";
11225 "
11226 [(set_attr "length" "4")
11227 (set_attr "type" "no_insn")]
11228 )
11229
11230 (define_insn "consttable_2"
11231 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11232 "TARGET_EITHER"
11233 "*
11234 {
11235 rtx x = operands[0];
11236 making_const_table = TRUE;
11237 switch (GET_MODE_CLASS (GET_MODE (x)))
11238 {
11239 case MODE_FLOAT:
11240 arm_emit_fp16_const (x);
11241 break;
11242 default:
11243 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11244 assemble_zeros (2);
11245 break;
11246 }
11247 return \"\";
11248 }"
11249 [(set_attr "length" "4")
11250 (set_attr "type" "no_insn")]
11251 )
11252
11253 (define_insn "consttable_4"
11254 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11255 "TARGET_EITHER"
11256 "*
11257 {
11258 rtx x = operands[0];
11259 making_const_table = TRUE;
11260 scalar_float_mode float_mode;
11261 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11262 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11263 else
11264 {
11265 /* XXX: Sometimes gcc does something really dumb and ends up with
11266 a HIGH in a constant pool entry, usually because it's trying to
11267 load into a VFP register. We know this will always be used in
11268 combination with a LO_SUM which ignores the high bits, so just
11269 strip off the HIGH. */
11270 if (GET_CODE (x) == HIGH)
11271 x = XEXP (x, 0);
11272 assemble_integer (x, 4, BITS_PER_WORD, 1);
11273 mark_symbol_refs_as_used (x);
11274 }
11275 return \"\";
11276 }"
11277 [(set_attr "length" "4")
11278 (set_attr "type" "no_insn")]
11279 )
11280
11281 (define_insn "consttable_8"
11282 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11283 "TARGET_EITHER"
11284 "*
11285 {
11286 making_const_table = TRUE;
11287 scalar_float_mode float_mode;
11288 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11289 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11290 float_mode, BITS_PER_WORD);
11291 else
11292 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11293 return \"\";
11294 }"
11295 [(set_attr "length" "8")
11296 (set_attr "type" "no_insn")]
11297 )
11298
11299 (define_insn "consttable_16"
11300 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11301 "TARGET_EITHER"
11302 "*
11303 {
11304 making_const_table = TRUE;
11305 scalar_float_mode float_mode;
11306 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11307 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11308 float_mode, BITS_PER_WORD);
11309 else
11310 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11311 return \"\";
11312 }"
11313 [(set_attr "length" "16")
11314 (set_attr "type" "no_insn")]
11315 )
11316
11317 ;; V5 Instructions,
11318
11319 (define_insn "clzsi2"
11320 [(set (match_operand:SI 0 "s_register_operand" "=r")
11321 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11322 "TARGET_32BIT && arm_arch5"
11323 "clz%?\\t%0, %1"
11324 [(set_attr "predicable" "yes")
11325 (set_attr "predicable_short_it" "no")
11326 (set_attr "type" "clz")])
11327
11328 (define_insn "rbitsi2"
11329 [(set (match_operand:SI 0 "s_register_operand" "=r")
11330 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11331 "TARGET_32BIT && arm_arch_thumb2"
11332 "rbit%?\\t%0, %1"
11333 [(set_attr "predicable" "yes")
11334 (set_attr "predicable_short_it" "no")
11335 (set_attr "type" "clz")])
11336
11337 ;; Keep this as a CTZ expression until after reload and then split
11338 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11339 ;; to fold with any other expression.
11340
11341 (define_insn_and_split "ctzsi2"
11342 [(set (match_operand:SI 0 "s_register_operand" "=r")
11343 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11344 "TARGET_32BIT && arm_arch_thumb2"
11345 "#"
11346 "&& reload_completed"
11347 [(const_int 0)]
11348 "
11349 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11350 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11351 DONE;
11352 ")
11353
11354 ;; V5E instructions.
11355
11356 (define_insn "prefetch"
11357 [(prefetch (match_operand:SI 0 "address_operand" "p")
11358 (match_operand:SI 1 "" "")
11359 (match_operand:SI 2 "" ""))]
11360 "TARGET_32BIT && arm_arch5e"
11361 "pld\\t%a0"
11362 [(set_attr "type" "load_4")]
11363 )
11364
11365 ;; General predication pattern
11366
11367 (define_cond_exec
11368 [(match_operator 0 "arm_comparison_operator"
11369 [(match_operand 1 "cc_register" "")
11370 (const_int 0)])]
11371 "TARGET_32BIT
11372 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11373 ""
11374 [(set_attr "predicated" "yes")]
11375 )
11376
11377 (define_insn "force_register_use"
11378 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11379 ""
11380 "%@ %0 needed"
11381 [(set_attr "length" "0")
11382 (set_attr "type" "no_insn")]
11383 )
11384
11385
11386 ;; Patterns for exception handling
11387
11388 (define_expand "eh_return"
11389 [(use (match_operand 0 "general_operand" ""))]
11390 "TARGET_EITHER"
11391 "
11392 {
11393 if (TARGET_32BIT)
11394 emit_insn (gen_arm_eh_return (operands[0]));
11395 else
11396 emit_insn (gen_thumb_eh_return (operands[0]));
11397 DONE;
11398 }"
11399 )
11400
11401 ;; We can't expand this before we know where the link register is stored.
11402 (define_insn_and_split "arm_eh_return"
11403 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11404 VUNSPEC_EH_RETURN)
11405 (clobber (match_scratch:SI 1 "=&r"))]
11406 "TARGET_ARM"
11407 "#"
11408 "&& reload_completed"
11409 [(const_int 0)]
11410 "
11411 {
11412 arm_set_return_address (operands[0], operands[1]);
11413 DONE;
11414 }"
11415 )
11416
11417 \f
11418 ;; TLS support
11419
11420 (define_insn "load_tp_hard"
11421 [(set (match_operand:SI 0 "register_operand" "=r")
11422 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11423 "TARGET_HARD_TP"
11424 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11425 [(set_attr "predicable" "yes")
11426 (set_attr "type" "mrs")]
11427 )
11428
11429 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11430 (define_insn "load_tp_soft"
11431 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11432 (clobber (reg:SI LR_REGNUM))
11433 (clobber (reg:SI IP_REGNUM))
11434 (clobber (reg:CC CC_REGNUM))]
11435 "TARGET_SOFT_TP"
11436 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11437 [(set_attr "conds" "clob")
11438 (set_attr "type" "branch")]
11439 )
11440
11441 ;; tls descriptor call
11442 (define_insn "tlscall"
11443 [(set (reg:SI R0_REGNUM)
11444 (unspec:SI [(reg:SI R0_REGNUM)
11445 (match_operand:SI 0 "" "X")
11446 (match_operand 1 "" "")] UNSPEC_TLS))
11447 (clobber (reg:SI R1_REGNUM))
11448 (clobber (reg:SI LR_REGNUM))
11449 (clobber (reg:SI CC_REGNUM))]
11450 "TARGET_GNU2_TLS"
11451 {
11452 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11453 INTVAL (operands[1]));
11454 return "bl\\t%c0(tlscall)";
11455 }
11456 [(set_attr "conds" "clob")
11457 (set_attr "length" "4")
11458 (set_attr "type" "branch")]
11459 )
11460
11461 ;; For thread pointer builtin
11462 (define_expand "get_thread_pointersi"
11463 [(match_operand:SI 0 "s_register_operand" "=r")]
11464 ""
11465 "
11466 {
11467 arm_load_tp (operands[0]);
11468 DONE;
11469 }")
11470
11471 ;;
11472
11473 ;; We only care about the lower 16 bits of the constant
11474 ;; being inserted into the upper 16 bits of the register.
11475 (define_insn "*arm_movtas_ze"
11476 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11477 (const_int 16)
11478 (const_int 16))
11479 (match_operand:SI 1 "const_int_operand" ""))]
11480 "TARGET_HAVE_MOVT"
11481 "@
11482 movt%?\t%0, %L1
11483 movt\t%0, %L1"
11484 [(set_attr "arch" "32,v8mb")
11485 (set_attr "predicable" "yes")
11486 (set_attr "predicable_short_it" "no")
11487 (set_attr "length" "4")
11488 (set_attr "type" "alu_sreg")]
11489 )
11490
11491 (define_insn "*arm_rev"
11492 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11493 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11494 "arm_arch6"
11495 "@
11496 rev\t%0, %1
11497 rev%?\t%0, %1
11498 rev%?\t%0, %1"
11499 [(set_attr "arch" "t1,t2,32")
11500 (set_attr "length" "2,2,4")
11501 (set_attr "predicable" "no,yes,yes")
11502 (set_attr "predicable_short_it" "no")
11503 (set_attr "type" "rev")]
11504 )
11505
11506 (define_expand "arm_legacy_rev"
11507 [(set (match_operand:SI 2 "s_register_operand" "")
11508 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11509 (const_int 16))
11510 (match_dup 1)))
11511 (set (match_dup 2)
11512 (lshiftrt:SI (match_dup 2)
11513 (const_int 8)))
11514 (set (match_operand:SI 3 "s_register_operand" "")
11515 (rotatert:SI (match_dup 1)
11516 (const_int 8)))
11517 (set (match_dup 2)
11518 (and:SI (match_dup 2)
11519 (const_int -65281)))
11520 (set (match_operand:SI 0 "s_register_operand" "")
11521 (xor:SI (match_dup 3)
11522 (match_dup 2)))]
11523 "TARGET_32BIT"
11524 ""
11525 )
11526
11527 ;; Reuse temporaries to keep register pressure down.
11528 (define_expand "thumb_legacy_rev"
11529 [(set (match_operand:SI 2 "s_register_operand" "")
11530 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11531 (const_int 24)))
11532 (set (match_operand:SI 3 "s_register_operand" "")
11533 (lshiftrt:SI (match_dup 1)
11534 (const_int 24)))
11535 (set (match_dup 3)
11536 (ior:SI (match_dup 3)
11537 (match_dup 2)))
11538 (set (match_operand:SI 4 "s_register_operand" "")
11539 (const_int 16))
11540 (set (match_operand:SI 5 "s_register_operand" "")
11541 (rotatert:SI (match_dup 1)
11542 (match_dup 4)))
11543 (set (match_dup 2)
11544 (ashift:SI (match_dup 5)
11545 (const_int 24)))
11546 (set (match_dup 5)
11547 (lshiftrt:SI (match_dup 5)
11548 (const_int 24)))
11549 (set (match_dup 5)
11550 (ior:SI (match_dup 5)
11551 (match_dup 2)))
11552 (set (match_dup 5)
11553 (rotatert:SI (match_dup 5)
11554 (match_dup 4)))
11555 (set (match_operand:SI 0 "s_register_operand" "")
11556 (ior:SI (match_dup 5)
11557 (match_dup 3)))]
11558 "TARGET_THUMB"
11559 ""
11560 )
11561
11562 ;; ARM-specific expansion of signed mod by power of 2
11563 ;; using conditional negate.
11564 ;; For r0 % n where n is a power of 2 produce:
11565 ;; rsbs r1, r0, #0
11566 ;; and r0, r0, #(n - 1)
11567 ;; and r1, r1, #(n - 1)
11568 ;; rsbpl r0, r1, #0
11569
11570 (define_expand "modsi3"
11571 [(match_operand:SI 0 "register_operand" "")
11572 (match_operand:SI 1 "register_operand" "")
11573 (match_operand:SI 2 "const_int_operand" "")]
11574 "TARGET_32BIT"
11575 {
11576 HOST_WIDE_INT val = INTVAL (operands[2]);
11577
11578 if (val <= 0
11579 || exact_log2 (val) <= 0)
11580 FAIL;
11581
11582 rtx mask = GEN_INT (val - 1);
11583
11584 /* In the special case of x0 % 2 we can do the even shorter:
11585 cmp r0, #0
11586 and r0, r0, #1
11587 rsblt r0, r0, #0. */
11588
11589 if (val == 2)
11590 {
11591 rtx cc_reg = arm_gen_compare_reg (LT,
11592 operands[1], const0_rtx, NULL_RTX);
11593 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11594 rtx masked = gen_reg_rtx (SImode);
11595
11596 emit_insn (gen_andsi3 (masked, operands[1], mask));
11597 emit_move_insn (operands[0],
11598 gen_rtx_IF_THEN_ELSE (SImode, cond,
11599 gen_rtx_NEG (SImode,
11600 masked),
11601 masked));
11602 DONE;
11603 }
11604
11605 rtx neg_op = gen_reg_rtx (SImode);
11606 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11607 operands[1]));
11608
11609 /* Extract the condition register and mode. */
11610 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11611 rtx cc_reg = SET_DEST (cmp);
11612 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11613
11614 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11615
11616 rtx masked_neg = gen_reg_rtx (SImode);
11617 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11618
11619 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11620 during expand does not always work. Do an IF_THEN_ELSE instead. */
11621 emit_move_insn (operands[0],
11622 gen_rtx_IF_THEN_ELSE (SImode, cond,
11623 gen_rtx_NEG (SImode, masked_neg),
11624 operands[0]));
11625
11626
11627 DONE;
11628 }
11629 )
11630
11631 (define_expand "bswapsi2"
11632 [(set (match_operand:SI 0 "s_register_operand" "=r")
11633 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11634 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11635 "
11636 if (!arm_arch6)
11637 {
11638 rtx op2 = gen_reg_rtx (SImode);
11639 rtx op3 = gen_reg_rtx (SImode);
11640
11641 if (TARGET_THUMB)
11642 {
11643 rtx op4 = gen_reg_rtx (SImode);
11644 rtx op5 = gen_reg_rtx (SImode);
11645
11646 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11647 op2, op3, op4, op5));
11648 }
11649 else
11650 {
11651 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11652 op2, op3));
11653 }
11654
11655 DONE;
11656 }
11657 "
11658 )
11659
11660 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11661 ;; and unsigned variants, respectively. For rev16, expose
11662 ;; byte-swapping in the lower 16 bits only.
11663 (define_insn "*arm_revsh"
11664 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11665 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11666 "arm_arch6"
11667 "@
11668 revsh\t%0, %1
11669 revsh%?\t%0, %1
11670 revsh%?\t%0, %1"
11671 [(set_attr "arch" "t1,t2,32")
11672 (set_attr "length" "2,2,4")
11673 (set_attr "type" "rev")]
11674 )
11675
11676 (define_insn "*arm_rev16"
11677 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11678 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11679 "arm_arch6"
11680 "@
11681 rev16\t%0, %1
11682 rev16%?\t%0, %1
11683 rev16%?\t%0, %1"
11684 [(set_attr "arch" "t1,t2,32")
11685 (set_attr "length" "2,2,4")
11686 (set_attr "type" "rev")]
11687 )
11688
11689 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11690 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11691 ;; each valid permutation.
11692
11693 (define_insn "arm_rev16si2"
11694 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11695 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11696 (const_int 8))
11697 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11698 (and:SI (lshiftrt:SI (match_dup 1)
11699 (const_int 8))
11700 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11701 "arm_arch6
11702 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11703 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11704 "rev16\\t%0, %1"
11705 [(set_attr "arch" "t1,t2,32")
11706 (set_attr "length" "2,2,4")
11707 (set_attr "type" "rev")]
11708 )
11709
11710 (define_insn "arm_rev16si2_alt"
11711 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11712 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11713 (const_int 8))
11714 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11715 (and:SI (ashift:SI (match_dup 1)
11716 (const_int 8))
11717 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11718 "arm_arch6
11719 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11720 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11721 "rev16\\t%0, %1"
11722 [(set_attr "arch" "t1,t2,32")
11723 (set_attr "length" "2,2,4")
11724 (set_attr "type" "rev")]
11725 )
11726
11727 (define_expand "bswaphi2"
11728 [(set (match_operand:HI 0 "s_register_operand" "=r")
11729 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11730 "arm_arch6"
11731 ""
11732 )
11733
11734 ;; Patterns for LDRD/STRD in Thumb2 mode
11735
11736 (define_insn "*thumb2_ldrd"
11737 [(set (match_operand:SI 0 "s_register_operand" "=r")
11738 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11739 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11740 (set (match_operand:SI 3 "s_register_operand" "=r")
11741 (mem:SI (plus:SI (match_dup 1)
11742 (match_operand:SI 4 "const_int_operand" ""))))]
11743 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11744 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11745 && (operands_ok_ldrd_strd (operands[0], operands[3],
11746 operands[1], INTVAL (operands[2]),
11747 false, true))"
11748 "ldrd%?\t%0, %3, [%1, %2]"
11749 [(set_attr "type" "load_8")
11750 (set_attr "predicable" "yes")
11751 (set_attr "predicable_short_it" "no")])
11752
11753 (define_insn "*thumb2_ldrd_base"
11754 [(set (match_operand:SI 0 "s_register_operand" "=r")
11755 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11756 (set (match_operand:SI 2 "s_register_operand" "=r")
11757 (mem:SI (plus:SI (match_dup 1)
11758 (const_int 4))))]
11759 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11760 && (operands_ok_ldrd_strd (operands[0], operands[2],
11761 operands[1], 0, false, true))"
11762 "ldrd%?\t%0, %2, [%1]"
11763 [(set_attr "type" "load_8")
11764 (set_attr "predicable" "yes")
11765 (set_attr "predicable_short_it" "no")])
11766
11767 (define_insn "*thumb2_ldrd_base_neg"
11768 [(set (match_operand:SI 0 "s_register_operand" "=r")
11769 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11770 (const_int -4))))
11771 (set (match_operand:SI 2 "s_register_operand" "=r")
11772 (mem:SI (match_dup 1)))]
11773 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11774 && (operands_ok_ldrd_strd (operands[0], operands[2],
11775 operands[1], -4, false, true))"
11776 "ldrd%?\t%0, %2, [%1, #-4]"
11777 [(set_attr "type" "load_8")
11778 (set_attr "predicable" "yes")
11779 (set_attr "predicable_short_it" "no")])
11780
11781 (define_insn "*thumb2_strd"
11782 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11783 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11784 (match_operand:SI 2 "s_register_operand" "r"))
11785 (set (mem:SI (plus:SI (match_dup 0)
11786 (match_operand:SI 3 "const_int_operand" "")))
11787 (match_operand:SI 4 "s_register_operand" "r"))]
11788 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11789 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11790 && (operands_ok_ldrd_strd (operands[2], operands[4],
11791 operands[0], INTVAL (operands[1]),
11792 false, false))"
11793 "strd%?\t%2, %4, [%0, %1]"
11794 [(set_attr "type" "store_8")
11795 (set_attr "predicable" "yes")
11796 (set_attr "predicable_short_it" "no")])
11797
11798 (define_insn "*thumb2_strd_base"
11799 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11800 (match_operand:SI 1 "s_register_operand" "r"))
11801 (set (mem:SI (plus:SI (match_dup 0)
11802 (const_int 4)))
11803 (match_operand:SI 2 "s_register_operand" "r"))]
11804 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11805 && (operands_ok_ldrd_strd (operands[1], operands[2],
11806 operands[0], 0, false, false))"
11807 "strd%?\t%1, %2, [%0]"
11808 [(set_attr "type" "store_8")
11809 (set_attr "predicable" "yes")
11810 (set_attr "predicable_short_it" "no")])
11811
11812 (define_insn "*thumb2_strd_base_neg"
11813 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11814 (const_int -4)))
11815 (match_operand:SI 1 "s_register_operand" "r"))
11816 (set (mem:SI (match_dup 0))
11817 (match_operand:SI 2 "s_register_operand" "r"))]
11818 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11819 && (operands_ok_ldrd_strd (operands[1], operands[2],
11820 operands[0], -4, false, false))"
11821 "strd%?\t%1, %2, [%0, #-4]"
11822 [(set_attr "type" "store_8")
11823 (set_attr "predicable" "yes")
11824 (set_attr "predicable_short_it" "no")])
11825
11826 ;; ARMv8 CRC32 instructions.
11827 (define_insn "<crc_variant>"
11828 [(set (match_operand:SI 0 "s_register_operand" "=r")
11829 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11830 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11831 CRC))]
11832 "TARGET_CRC32"
11833 "<crc_variant>\\t%0, %1, %2"
11834 [(set_attr "type" "crc")
11835 (set_attr "conds" "unconditional")]
11836 )
11837
11838 ;; Load the load/store double peephole optimizations.
11839 (include "ldrdstrd.md")
11840
11841 ;; Load the load/store multiple patterns
11842 (include "ldmstm.md")
11843
11844 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11845 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11846 ;; The operands are validated through the load_multiple_operation
11847 ;; match_parallel predicate rather than through constraints so enable it only
11848 ;; after reload.
11849 (define_insn "*load_multiple"
11850 [(match_parallel 0 "load_multiple_operation"
11851 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11852 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11853 ])]
11854 "TARGET_32BIT && reload_completed"
11855 "*
11856 {
11857 arm_output_multireg_pop (operands, /*return_pc=*/false,
11858 /*cond=*/const_true_rtx,
11859 /*reverse=*/false,
11860 /*update=*/false);
11861 return \"\";
11862 }
11863 "
11864 [(set_attr "predicable" "yes")]
11865 )
11866
11867 (define_expand "copysignsf3"
11868 [(match_operand:SF 0 "register_operand")
11869 (match_operand:SF 1 "register_operand")
11870 (match_operand:SF 2 "register_operand")]
11871 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11872 "{
11873 emit_move_insn (operands[0], operands[2]);
11874 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11875 GEN_INT (31), GEN_INT (0),
11876 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11877 DONE;
11878 }"
11879 )
11880
11881 (define_expand "copysigndf3"
11882 [(match_operand:DF 0 "register_operand")
11883 (match_operand:DF 1 "register_operand")
11884 (match_operand:DF 2 "register_operand")]
11885 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11886 "{
11887 rtx op0_low = gen_lowpart (SImode, operands[0]);
11888 rtx op0_high = gen_highpart (SImode, operands[0]);
11889 rtx op1_low = gen_lowpart (SImode, operands[1]);
11890 rtx op1_high = gen_highpart (SImode, operands[1]);
11891 rtx op2_high = gen_highpart (SImode, operands[2]);
11892
11893 rtx scratch1 = gen_reg_rtx (SImode);
11894 rtx scratch2 = gen_reg_rtx (SImode);
11895 emit_move_insn (scratch1, op2_high);
11896 emit_move_insn (scratch2, op1_high);
11897
11898 emit_insn(gen_rtx_SET(scratch1,
11899 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11900 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11901 emit_move_insn (op0_low, op1_low);
11902 emit_move_insn (op0_high, scratch2);
11903
11904 DONE;
11905 }"
11906 )
11907
11908 ;; movmisalign patterns for HImode and SImode.
11909 (define_expand "movmisalign<mode>"
11910 [(match_operand:HSI 0 "general_operand")
11911 (match_operand:HSI 1 "general_operand")]
11912 "unaligned_access"
11913 {
11914 /* This pattern is not permitted to fail during expansion: if both arguments
11915 are non-registers (e.g. memory := constant), force operand 1 into a
11916 register. */
11917 rtx (* gen_unaligned_load)(rtx, rtx);
11918 rtx tmp_dest = operands[0];
11919 if (!s_register_operand (operands[0], <MODE>mode)
11920 && !s_register_operand (operands[1], <MODE>mode))
11921 operands[1] = force_reg (<MODE>mode, operands[1]);
11922
11923 if (<MODE>mode == HImode)
11924 {
11925 gen_unaligned_load = gen_unaligned_loadhiu;
11926 tmp_dest = gen_reg_rtx (SImode);
11927 }
11928 else
11929 gen_unaligned_load = gen_unaligned_loadsi;
11930
11931 if (MEM_P (operands[1]))
11932 {
11933 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11934 if (<MODE>mode == HImode)
11935 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11936 }
11937 else
11938 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11939
11940 DONE;
11941 })
11942
11943 (define_insn "<cdp>"
11944 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11945 (match_operand:SI 1 "immediate_operand" "n")
11946 (match_operand:SI 2 "immediate_operand" "n")
11947 (match_operand:SI 3 "immediate_operand" "n")
11948 (match_operand:SI 4 "immediate_operand" "n")
11949 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11950 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11951 {
11952 arm_const_bounds (operands[0], 0, 16);
11953 arm_const_bounds (operands[1], 0, 16);
11954 arm_const_bounds (operands[2], 0, (1 << 5));
11955 arm_const_bounds (operands[3], 0, (1 << 5));
11956 arm_const_bounds (operands[4], 0, (1 << 5));
11957 arm_const_bounds (operands[5], 0, 8);
11958 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11959 }
11960 [(set_attr "length" "4")
11961 (set_attr "type" "coproc")])
11962
11963 (define_insn "*ldc"
11964 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11965 (match_operand:SI 1 "immediate_operand" "n")
11966 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11967 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11968 {
11969 arm_const_bounds (operands[0], 0, 16);
11970 arm_const_bounds (operands[1], 0, (1 << 5));
11971 return "<ldc>\\tp%c0, CR%c1, %2";
11972 }
11973 [(set_attr "length" "4")
11974 (set_attr "type" "coproc")])
11975
11976 (define_insn "*stc"
11977 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11978 (match_operand:SI 1 "immediate_operand" "n")
11979 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11980 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11981 {
11982 arm_const_bounds (operands[0], 0, 16);
11983 arm_const_bounds (operands[1], 0, (1 << 5));
11984 return "<stc>\\tp%c0, CR%c1, %2";
11985 }
11986 [(set_attr "length" "4")
11987 (set_attr "type" "coproc")])
11988
11989 (define_expand "<ldc>"
11990 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11991 (match_operand:SI 1 "immediate_operand")
11992 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11993 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11994
11995 (define_expand "<stc>"
11996 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11997 (match_operand:SI 1 "immediate_operand")
11998 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11999 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12000
12001 (define_insn "<mcr>"
12002 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12003 (match_operand:SI 1 "immediate_operand" "n")
12004 (match_operand:SI 2 "s_register_operand" "r")
12005 (match_operand:SI 3 "immediate_operand" "n")
12006 (match_operand:SI 4 "immediate_operand" "n")
12007 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12008 (use (match_dup 2))]
12009 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12010 {
12011 arm_const_bounds (operands[0], 0, 16);
12012 arm_const_bounds (operands[1], 0, 8);
12013 arm_const_bounds (operands[3], 0, (1 << 5));
12014 arm_const_bounds (operands[4], 0, (1 << 5));
12015 arm_const_bounds (operands[5], 0, 8);
12016 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12017 }
12018 [(set_attr "length" "4")
12019 (set_attr "type" "coproc")])
12020
12021 (define_insn "<mrc>"
12022 [(set (match_operand:SI 0 "s_register_operand" "=r")
12023 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12024 (match_operand:SI 2 "immediate_operand" "n")
12025 (match_operand:SI 3 "immediate_operand" "n")
12026 (match_operand:SI 4 "immediate_operand" "n")
12027 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12028 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12029 {
12030 arm_const_bounds (operands[1], 0, 16);
12031 arm_const_bounds (operands[2], 0, 8);
12032 arm_const_bounds (operands[3], 0, (1 << 5));
12033 arm_const_bounds (operands[4], 0, (1 << 5));
12034 arm_const_bounds (operands[5], 0, 8);
12035 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12036 }
12037 [(set_attr "length" "4")
12038 (set_attr "type" "coproc")])
12039
12040 (define_insn "<mcrr>"
12041 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12042 (match_operand:SI 1 "immediate_operand" "n")
12043 (match_operand:DI 2 "s_register_operand" "r")
12044 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12045 (use (match_dup 2))]
12046 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12047 {
12048 arm_const_bounds (operands[0], 0, 16);
12049 arm_const_bounds (operands[1], 0, 8);
12050 arm_const_bounds (operands[3], 0, (1 << 5));
12051 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12052 }
12053 [(set_attr "length" "4")
12054 (set_attr "type" "coproc")])
12055
12056 (define_insn "<mrrc>"
12057 [(set (match_operand:DI 0 "s_register_operand" "=r")
12058 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12059 (match_operand:SI 2 "immediate_operand" "n")
12060 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12061 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12062 {
12063 arm_const_bounds (operands[1], 0, 16);
12064 arm_const_bounds (operands[2], 0, 8);
12065 arm_const_bounds (operands[3], 0, (1 << 5));
12066 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12067 }
12068 [(set_attr "length" "4")
12069 (set_attr "type" "coproc")])
12070
12071 ;; Vector bits common to IWMMXT and Neon
12072 (include "vec-common.md")
12073 ;; Load the Intel Wireless Multimedia Extension patterns
12074 (include "iwmmxt.md")
12075 ;; Load the VFP co-processor patterns
12076 (include "vfp.md")
12077 ;; Thumb-1 patterns
12078 (include "thumb1.md")
12079 ;; Thumb-2 patterns
12080 (include "thumb2.md")
12081 ;; Neon patterns
12082 (include "neon.md")
12083 ;; Crypto patterns
12084 (include "crypto.md")
12085 ;; Synchronization Primitives
12086 (include "sync.md")
12087 ;; Fixed-point patterns
12088 (include "arm-fixed.md")