]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm.md
[gcc]
[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 "predicable_short_it" "no")
8910 (set_attr "shift" "3")
8911 (set_attr "arch" "32,a")
8912 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8913
8914 (define_insn "*sub_shiftsi_compare0"
8915 [(set (reg:CC_NOOV CC_REGNUM)
8916 (compare:CC_NOOV
8917 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8918 (match_operator:SI 2 "shift_operator"
8919 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8920 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8921 (const_int 0)))
8922 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8923 (minus:SI (match_dup 1)
8924 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8925 "TARGET_32BIT"
8926 "subs%?\\t%0, %1, %3%S2"
8927 [(set_attr "conds" "set")
8928 (set_attr "shift" "3")
8929 (set_attr "arch" "32,a,a")
8930 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8931
8932 (define_insn "*sub_shiftsi_compare0_scratch"
8933 [(set (reg:CC_NOOV CC_REGNUM)
8934 (compare:CC_NOOV
8935 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8936 (match_operator:SI 2 "shift_operator"
8937 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8938 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8939 (const_int 0)))
8940 (clobber (match_scratch:SI 0 "=r,r,r"))]
8941 "TARGET_32BIT"
8942 "subs%?\\t%0, %1, %3%S2"
8943 [(set_attr "conds" "set")
8944 (set_attr "shift" "3")
8945 (set_attr "arch" "32,a,a")
8946 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8947 \f
8948
8949 (define_insn_and_split "*and_scc"
8950 [(set (match_operand:SI 0 "s_register_operand" "=r")
8951 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8952 [(match_operand 2 "cc_register" "") (const_int 0)])
8953 (match_operand:SI 3 "s_register_operand" "r")))]
8954 "TARGET_ARM"
8955 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8956 "&& reload_completed"
8957 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8958 (cond_exec (match_dup 4) (set (match_dup 0)
8959 (and:SI (match_dup 3) (const_int 1))))]
8960 {
8961 machine_mode mode = GET_MODE (operands[2]);
8962 enum rtx_code rc = GET_CODE (operands[1]);
8963
8964 /* Note that operands[4] is the same as operands[1],
8965 but with VOIDmode as the result. */
8966 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8967 if (mode == CCFPmode || mode == CCFPEmode)
8968 rc = reverse_condition_maybe_unordered (rc);
8969 else
8970 rc = reverse_condition (rc);
8971 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8972 }
8973 [(set_attr "conds" "use")
8974 (set_attr "type" "multiple")
8975 (set_attr "length" "8")]
8976 )
8977
8978 (define_insn_and_split "*ior_scc"
8979 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8980 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8981 [(match_operand 2 "cc_register" "") (const_int 0)])
8982 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8983 "TARGET_ARM"
8984 "@
8985 orr%d1\\t%0, %3, #1
8986 #"
8987 "&& reload_completed
8988 && REGNO (operands [0]) != REGNO (operands[3])"
8989 ;; && which_alternative == 1
8990 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8991 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8992 (cond_exec (match_dup 4) (set (match_dup 0)
8993 (ior:SI (match_dup 3) (const_int 1))))]
8994 {
8995 machine_mode mode = GET_MODE (operands[2]);
8996 enum rtx_code rc = GET_CODE (operands[1]);
8997
8998 /* Note that operands[4] is the same as operands[1],
8999 but with VOIDmode as the result. */
9000 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9001 if (mode == CCFPmode || mode == CCFPEmode)
9002 rc = reverse_condition_maybe_unordered (rc);
9003 else
9004 rc = reverse_condition (rc);
9005 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9006 }
9007 [(set_attr "conds" "use")
9008 (set_attr "length" "4,8")
9009 (set_attr "type" "logic_imm,multiple")]
9010 )
9011
9012 ; A series of splitters for the compare_scc pattern below. Note that
9013 ; order is important.
9014 (define_split
9015 [(set (match_operand:SI 0 "s_register_operand" "")
9016 (lt:SI (match_operand:SI 1 "s_register_operand" "")
9017 (const_int 0)))
9018 (clobber (reg:CC CC_REGNUM))]
9019 "TARGET_32BIT && reload_completed"
9020 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9021
9022 (define_split
9023 [(set (match_operand:SI 0 "s_register_operand" "")
9024 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9025 (const_int 0)))
9026 (clobber (reg:CC CC_REGNUM))]
9027 "TARGET_32BIT && reload_completed"
9028 [(set (match_dup 0) (not:SI (match_dup 1)))
9029 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9030
9031 (define_split
9032 [(set (match_operand:SI 0 "s_register_operand" "")
9033 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9034 (const_int 0)))
9035 (clobber (reg:CC CC_REGNUM))]
9036 "arm_arch5 && TARGET_32BIT"
9037 [(set (match_dup 0) (clz:SI (match_dup 1)))
9038 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9039 )
9040
9041 (define_split
9042 [(set (match_operand:SI 0 "s_register_operand" "")
9043 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9044 (const_int 0)))
9045 (clobber (reg:CC CC_REGNUM))]
9046 "TARGET_32BIT && reload_completed"
9047 [(parallel
9048 [(set (reg:CC CC_REGNUM)
9049 (compare:CC (const_int 1) (match_dup 1)))
9050 (set (match_dup 0)
9051 (minus:SI (const_int 1) (match_dup 1)))])
9052 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9053 (set (match_dup 0) (const_int 0)))])
9054
9055 (define_split
9056 [(set (match_operand:SI 0 "s_register_operand" "")
9057 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9058 (match_operand:SI 2 "const_int_operand" "")))
9059 (clobber (reg:CC CC_REGNUM))]
9060 "TARGET_32BIT && reload_completed"
9061 [(parallel
9062 [(set (reg:CC CC_REGNUM)
9063 (compare:CC (match_dup 1) (match_dup 2)))
9064 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9065 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9066 (set (match_dup 0) (const_int 1)))]
9067 {
9068 operands[3] = GEN_INT (-INTVAL (operands[2]));
9069 })
9070
9071 (define_split
9072 [(set (match_operand:SI 0 "s_register_operand" "")
9073 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9074 (match_operand:SI 2 "arm_add_operand" "")))
9075 (clobber (reg:CC CC_REGNUM))]
9076 "TARGET_32BIT && reload_completed"
9077 [(parallel
9078 [(set (reg:CC_NOOV CC_REGNUM)
9079 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9080 (const_int 0)))
9081 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9082 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9083 (set (match_dup 0) (const_int 1)))])
9084
9085 (define_insn_and_split "*compare_scc"
9086 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9087 (match_operator:SI 1 "arm_comparison_operator"
9088 [(match_operand:SI 2 "s_register_operand" "r,r")
9089 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9090 (clobber (reg:CC CC_REGNUM))]
9091 "TARGET_32BIT"
9092 "#"
9093 "&& reload_completed"
9094 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9095 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9096 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9097 {
9098 rtx tmp1;
9099 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9100 operands[2], operands[3]);
9101 enum rtx_code rc = GET_CODE (operands[1]);
9102
9103 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9104
9105 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9106 if (mode == CCFPmode || mode == CCFPEmode)
9107 rc = reverse_condition_maybe_unordered (rc);
9108 else
9109 rc = reverse_condition (rc);
9110 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9111 }
9112 [(set_attr "type" "multiple")]
9113 )
9114
9115 ;; Attempt to improve the sequence generated by the compare_scc splitters
9116 ;; not to use conditional execution.
9117
9118 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9119 ;; clz Rd, reg1
9120 ;; lsr Rd, Rd, #5
9121 (define_peephole2
9122 [(set (reg:CC CC_REGNUM)
9123 (compare:CC (match_operand:SI 1 "register_operand" "")
9124 (const_int 0)))
9125 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9126 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9127 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9128 (set (match_dup 0) (const_int 1)))]
9129 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9130 [(set (match_dup 0) (clz:SI (match_dup 1)))
9131 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9132 )
9133
9134 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9135 ;; negs Rd, reg1
9136 ;; adc Rd, Rd, reg1
9137 (define_peephole2
9138 [(set (reg:CC CC_REGNUM)
9139 (compare:CC (match_operand:SI 1 "register_operand" "")
9140 (const_int 0)))
9141 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9142 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9143 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9144 (set (match_dup 0) (const_int 1)))
9145 (match_scratch:SI 2 "r")]
9146 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9147 [(parallel
9148 [(set (reg:CC CC_REGNUM)
9149 (compare:CC (const_int 0) (match_dup 1)))
9150 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9151 (set (match_dup 0)
9152 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9153 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9154 )
9155
9156 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9157 ;; sub Rd, Reg1, reg2
9158 ;; clz Rd, Rd
9159 ;; lsr Rd, Rd, #5
9160 (define_peephole2
9161 [(set (reg:CC CC_REGNUM)
9162 (compare:CC (match_operand:SI 1 "register_operand" "")
9163 (match_operand:SI 2 "arm_rhs_operand" "")))
9164 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9165 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9166 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9167 (set (match_dup 0) (const_int 1)))]
9168 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9169 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9170 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9171 (set (match_dup 0) (clz:SI (match_dup 0)))
9172 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9173 )
9174
9175
9176 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9177 ;; sub T1, Reg1, reg2
9178 ;; negs Rd, T1
9179 ;; adc Rd, Rd, T1
9180 (define_peephole2
9181 [(set (reg:CC CC_REGNUM)
9182 (compare:CC (match_operand:SI 1 "register_operand" "")
9183 (match_operand:SI 2 "arm_rhs_operand" "")))
9184 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9185 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9186 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9187 (set (match_dup 0) (const_int 1)))
9188 (match_scratch:SI 3 "r")]
9189 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9190 [(set (match_dup 3) (match_dup 4))
9191 (parallel
9192 [(set (reg:CC CC_REGNUM)
9193 (compare:CC (const_int 0) (match_dup 3)))
9194 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9195 (set (match_dup 0)
9196 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9197 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9198 "
9199 if (CONST_INT_P (operands[2]))
9200 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9201 else
9202 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9203 ")
9204
9205 (define_insn "*cond_move"
9206 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9207 (if_then_else:SI (match_operator 3 "equality_operator"
9208 [(match_operator 4 "arm_comparison_operator"
9209 [(match_operand 5 "cc_register" "") (const_int 0)])
9210 (const_int 0)])
9211 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9212 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9213 "TARGET_ARM"
9214 "*
9215 if (GET_CODE (operands[3]) == NE)
9216 {
9217 if (which_alternative != 1)
9218 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9219 if (which_alternative != 0)
9220 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9221 return \"\";
9222 }
9223 if (which_alternative != 0)
9224 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9225 if (which_alternative != 1)
9226 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9227 return \"\";
9228 "
9229 [(set_attr "conds" "use")
9230 (set_attr_alternative "type"
9231 [(if_then_else (match_operand 2 "const_int_operand" "")
9232 (const_string "mov_imm")
9233 (const_string "mov_reg"))
9234 (if_then_else (match_operand 1 "const_int_operand" "")
9235 (const_string "mov_imm")
9236 (const_string "mov_reg"))
9237 (const_string "multiple")])
9238 (set_attr "length" "4,4,8")]
9239 )
9240
9241 (define_insn "*cond_arith"
9242 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9243 (match_operator:SI 5 "shiftable_operator"
9244 [(match_operator:SI 4 "arm_comparison_operator"
9245 [(match_operand:SI 2 "s_register_operand" "r,r")
9246 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9247 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9248 (clobber (reg:CC CC_REGNUM))]
9249 "TARGET_ARM"
9250 "*
9251 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9252 return \"%i5\\t%0, %1, %2, lsr #31\";
9253
9254 output_asm_insn (\"cmp\\t%2, %3\", operands);
9255 if (GET_CODE (operands[5]) == AND)
9256 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9257 else if (GET_CODE (operands[5]) == MINUS)
9258 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9259 else if (which_alternative != 0)
9260 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9261 return \"%i5%d4\\t%0, %1, #1\";
9262 "
9263 [(set_attr "conds" "clob")
9264 (set_attr "length" "12")
9265 (set_attr "type" "multiple")]
9266 )
9267
9268 (define_insn "*cond_sub"
9269 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9270 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9271 (match_operator:SI 4 "arm_comparison_operator"
9272 [(match_operand:SI 2 "s_register_operand" "r,r")
9273 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9274 (clobber (reg:CC CC_REGNUM))]
9275 "TARGET_ARM"
9276 "*
9277 output_asm_insn (\"cmp\\t%2, %3\", operands);
9278 if (which_alternative != 0)
9279 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9280 return \"sub%d4\\t%0, %1, #1\";
9281 "
9282 [(set_attr "conds" "clob")
9283 (set_attr "length" "8,12")
9284 (set_attr "type" "multiple")]
9285 )
9286
9287 (define_insn "*cmp_ite0"
9288 [(set (match_operand 6 "dominant_cc_register" "")
9289 (compare
9290 (if_then_else:SI
9291 (match_operator 4 "arm_comparison_operator"
9292 [(match_operand:SI 0 "s_register_operand"
9293 "l,l,l,r,r,r,r,r,r")
9294 (match_operand:SI 1 "arm_add_operand"
9295 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9296 (match_operator:SI 5 "arm_comparison_operator"
9297 [(match_operand:SI 2 "s_register_operand"
9298 "l,r,r,l,l,r,r,r,r")
9299 (match_operand:SI 3 "arm_add_operand"
9300 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9301 (const_int 0))
9302 (const_int 0)))]
9303 "TARGET_32BIT"
9304 "*
9305 {
9306 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9307 {
9308 {\"cmp%d5\\t%0, %1\",
9309 \"cmp%d4\\t%2, %3\"},
9310 {\"cmn%d5\\t%0, #%n1\",
9311 \"cmp%d4\\t%2, %3\"},
9312 {\"cmp%d5\\t%0, %1\",
9313 \"cmn%d4\\t%2, #%n3\"},
9314 {\"cmn%d5\\t%0, #%n1\",
9315 \"cmn%d4\\t%2, #%n3\"}
9316 };
9317 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9318 {
9319 {\"cmp\\t%2, %3\",
9320 \"cmp\\t%0, %1\"},
9321 {\"cmp\\t%2, %3\",
9322 \"cmn\\t%0, #%n1\"},
9323 {\"cmn\\t%2, #%n3\",
9324 \"cmp\\t%0, %1\"},
9325 {\"cmn\\t%2, #%n3\",
9326 \"cmn\\t%0, #%n1\"}
9327 };
9328 static const char * const ite[2] =
9329 {
9330 \"it\\t%d5\",
9331 \"it\\t%d4\"
9332 };
9333 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9334 CMP_CMP, CMN_CMP, CMP_CMP,
9335 CMN_CMP, CMP_CMN, CMN_CMN};
9336 int swap =
9337 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9338
9339 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9340 if (TARGET_THUMB2) {
9341 output_asm_insn (ite[swap], operands);
9342 }
9343 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9344 return \"\";
9345 }"
9346 [(set_attr "conds" "set")
9347 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9348 (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9349 (set_attr "type" "multiple")
9350 (set_attr_alternative "length"
9351 [(const_int 6)
9352 (const_int 8)
9353 (const_int 8)
9354 (const_int 8)
9355 (const_int 8)
9356 (if_then_else (eq_attr "is_thumb" "no")
9357 (const_int 8)
9358 (const_int 10))
9359 (if_then_else (eq_attr "is_thumb" "no")
9360 (const_int 8)
9361 (const_int 10))
9362 (if_then_else (eq_attr "is_thumb" "no")
9363 (const_int 8)
9364 (const_int 10))
9365 (if_then_else (eq_attr "is_thumb" "no")
9366 (const_int 8)
9367 (const_int 10))])]
9368 )
9369
9370 (define_insn "*cmp_ite1"
9371 [(set (match_operand 6 "dominant_cc_register" "")
9372 (compare
9373 (if_then_else:SI
9374 (match_operator 4 "arm_comparison_operator"
9375 [(match_operand:SI 0 "s_register_operand"
9376 "l,l,l,r,r,r,r,r,r")
9377 (match_operand:SI 1 "arm_add_operand"
9378 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9379 (match_operator:SI 5 "arm_comparison_operator"
9380 [(match_operand:SI 2 "s_register_operand"
9381 "l,r,r,l,l,r,r,r,r")
9382 (match_operand:SI 3 "arm_add_operand"
9383 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9384 (const_int 1))
9385 (const_int 0)))]
9386 "TARGET_32BIT"
9387 "*
9388 {
9389 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9390 {
9391 {\"cmp\\t%0, %1\",
9392 \"cmp\\t%2, %3\"},
9393 {\"cmn\\t%0, #%n1\",
9394 \"cmp\\t%2, %3\"},
9395 {\"cmp\\t%0, %1\",
9396 \"cmn\\t%2, #%n3\"},
9397 {\"cmn\\t%0, #%n1\",
9398 \"cmn\\t%2, #%n3\"}
9399 };
9400 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9401 {
9402 {\"cmp%d4\\t%2, %3\",
9403 \"cmp%D5\\t%0, %1\"},
9404 {\"cmp%d4\\t%2, %3\",
9405 \"cmn%D5\\t%0, #%n1\"},
9406 {\"cmn%d4\\t%2, #%n3\",
9407 \"cmp%D5\\t%0, %1\"},
9408 {\"cmn%d4\\t%2, #%n3\",
9409 \"cmn%D5\\t%0, #%n1\"}
9410 };
9411 static const char * const ite[2] =
9412 {
9413 \"it\\t%d4\",
9414 \"it\\t%D5\"
9415 };
9416 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9417 CMP_CMP, CMN_CMP, CMP_CMP,
9418 CMN_CMP, CMP_CMN, CMN_CMN};
9419 int swap =
9420 comparison_dominates_p (GET_CODE (operands[5]),
9421 reverse_condition (GET_CODE (operands[4])));
9422
9423 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9424 if (TARGET_THUMB2) {
9425 output_asm_insn (ite[swap], operands);
9426 }
9427 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9428 return \"\";
9429 }"
9430 [(set_attr "conds" "set")
9431 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9432 (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9433 (set_attr_alternative "length"
9434 [(const_int 6)
9435 (const_int 8)
9436 (const_int 8)
9437 (const_int 8)
9438 (const_int 8)
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 (if_then_else (eq_attr "is_thumb" "no")
9449 (const_int 8)
9450 (const_int 10))])
9451 (set_attr "type" "multiple")]
9452 )
9453
9454 (define_insn "*cmp_and"
9455 [(set (match_operand 6 "dominant_cc_register" "")
9456 (compare
9457 (and:SI
9458 (match_operator 4 "arm_comparison_operator"
9459 [(match_operand:SI 0 "s_register_operand"
9460 "l,l,l,r,r,r,r,r,r")
9461 (match_operand:SI 1 "arm_add_operand"
9462 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9463 (match_operator:SI 5 "arm_comparison_operator"
9464 [(match_operand:SI 2 "s_register_operand"
9465 "l,r,r,l,l,r,r,r,r")
9466 (match_operand:SI 3 "arm_add_operand"
9467 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9468 (const_int 0)))]
9469 "TARGET_32BIT"
9470 "*
9471 {
9472 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9473 {
9474 {\"cmp%d5\\t%0, %1\",
9475 \"cmp%d4\\t%2, %3\"},
9476 {\"cmn%d5\\t%0, #%n1\",
9477 \"cmp%d4\\t%2, %3\"},
9478 {\"cmp%d5\\t%0, %1\",
9479 \"cmn%d4\\t%2, #%n3\"},
9480 {\"cmn%d5\\t%0, #%n1\",
9481 \"cmn%d4\\t%2, #%n3\"}
9482 };
9483 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9484 {
9485 {\"cmp\\t%2, %3\",
9486 \"cmp\\t%0, %1\"},
9487 {\"cmp\\t%2, %3\",
9488 \"cmn\\t%0, #%n1\"},
9489 {\"cmn\\t%2, #%n3\",
9490 \"cmp\\t%0, %1\"},
9491 {\"cmn\\t%2, #%n3\",
9492 \"cmn\\t%0, #%n1\"}
9493 };
9494 static const char *const ite[2] =
9495 {
9496 \"it\\t%d5\",
9497 \"it\\t%d4\"
9498 };
9499 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9500 CMP_CMP, CMN_CMP, CMP_CMP,
9501 CMN_CMP, CMP_CMN, CMN_CMN};
9502 int swap =
9503 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9504
9505 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9506 if (TARGET_THUMB2) {
9507 output_asm_insn (ite[swap], operands);
9508 }
9509 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9510 return \"\";
9511 }"
9512 [(set_attr "conds" "set")
9513 (set_attr "predicable" "no")
9514 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9515 (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9516 (set_attr_alternative "length"
9517 [(const_int 6)
9518 (const_int 8)
9519 (const_int 8)
9520 (const_int 8)
9521 (const_int 8)
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 (if_then_else (eq_attr "is_thumb" "no")
9532 (const_int 8)
9533 (const_int 10))])
9534 (set_attr "type" "multiple")]
9535 )
9536
9537 (define_insn "*cmp_ior"
9538 [(set (match_operand 6 "dominant_cc_register" "")
9539 (compare
9540 (ior:SI
9541 (match_operator 4 "arm_comparison_operator"
9542 [(match_operand:SI 0 "s_register_operand"
9543 "l,l,l,r,r,r,r,r,r")
9544 (match_operand:SI 1 "arm_add_operand"
9545 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9546 (match_operator:SI 5 "arm_comparison_operator"
9547 [(match_operand:SI 2 "s_register_operand"
9548 "l,r,r,l,l,r,r,r,r")
9549 (match_operand:SI 3 "arm_add_operand"
9550 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9551 (const_int 0)))]
9552 "TARGET_32BIT"
9553 "*
9554 {
9555 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9556 {
9557 {\"cmp\\t%0, %1\",
9558 \"cmp\\t%2, %3\"},
9559 {\"cmn\\t%0, #%n1\",
9560 \"cmp\\t%2, %3\"},
9561 {\"cmp\\t%0, %1\",
9562 \"cmn\\t%2, #%n3\"},
9563 {\"cmn\\t%0, #%n1\",
9564 \"cmn\\t%2, #%n3\"}
9565 };
9566 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9567 {
9568 {\"cmp%D4\\t%2, %3\",
9569 \"cmp%D5\\t%0, %1\"},
9570 {\"cmp%D4\\t%2, %3\",
9571 \"cmn%D5\\t%0, #%n1\"},
9572 {\"cmn%D4\\t%2, #%n3\",
9573 \"cmp%D5\\t%0, %1\"},
9574 {\"cmn%D4\\t%2, #%n3\",
9575 \"cmn%D5\\t%0, #%n1\"}
9576 };
9577 static const char *const ite[2] =
9578 {
9579 \"it\\t%D4\",
9580 \"it\\t%D5\"
9581 };
9582 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9583 CMP_CMP, CMN_CMP, CMP_CMP,
9584 CMN_CMP, CMP_CMN, CMN_CMN};
9585 int swap =
9586 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9587
9588 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9589 if (TARGET_THUMB2) {
9590 output_asm_insn (ite[swap], operands);
9591 }
9592 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9593 return \"\";
9594 }
9595 "
9596 [(set_attr "conds" "set")
9597 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9598 (set_attr "enabled_for_depr_it" "yes,no,no,no,no,no,no,no,no")
9599 (set_attr_alternative "length"
9600 [(const_int 6)
9601 (const_int 8)
9602 (const_int 8)
9603 (const_int 8)
9604 (const_int 8)
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 (if_then_else (eq_attr "is_thumb" "no")
9615 (const_int 8)
9616 (const_int 10))])
9617 (set_attr "type" "multiple")]
9618 )
9619
9620 (define_insn_and_split "*ior_scc_scc"
9621 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9622 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9623 [(match_operand:SI 1 "s_register_operand" "l,r")
9624 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9625 (match_operator:SI 6 "arm_comparison_operator"
9626 [(match_operand:SI 4 "s_register_operand" "l,r")
9627 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9628 (clobber (reg:CC CC_REGNUM))]
9629 "TARGET_32BIT
9630 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9631 != CCmode)"
9632 "#"
9633 "TARGET_32BIT && reload_completed"
9634 [(set (match_dup 7)
9635 (compare
9636 (ior:SI
9637 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9638 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9639 (const_int 0)))
9640 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9641 "operands[7]
9642 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9643 DOM_CC_X_OR_Y),
9644 CC_REGNUM);"
9645 [(set_attr "conds" "clob")
9646 (set_attr "enabled_for_depr_it" "yes,no")
9647 (set_attr "length" "16")
9648 (set_attr "type" "multiple")]
9649 )
9650
9651 ; If the above pattern is followed by a CMP insn, then the compare is
9652 ; redundant, since we can rework the conditional instruction that follows.
9653 (define_insn_and_split "*ior_scc_scc_cmp"
9654 [(set (match_operand 0 "dominant_cc_register" "")
9655 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9656 [(match_operand:SI 1 "s_register_operand" "l,r")
9657 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9658 (match_operator:SI 6 "arm_comparison_operator"
9659 [(match_operand:SI 4 "s_register_operand" "l,r")
9660 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9661 (const_int 0)))
9662 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9663 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9664 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9665 "TARGET_32BIT"
9666 "#"
9667 "TARGET_32BIT && reload_completed"
9668 [(set (match_dup 0)
9669 (compare
9670 (ior:SI
9671 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9672 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9673 (const_int 0)))
9674 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9675 ""
9676 [(set_attr "conds" "set")
9677 (set_attr "enabled_for_depr_it" "yes,no")
9678 (set_attr "length" "16")
9679 (set_attr "type" "multiple")]
9680 )
9681
9682 (define_insn_and_split "*and_scc_scc"
9683 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9684 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9685 [(match_operand:SI 1 "s_register_operand" "l,r")
9686 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9687 (match_operator:SI 6 "arm_comparison_operator"
9688 [(match_operand:SI 4 "s_register_operand" "l,r")
9689 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9690 (clobber (reg:CC CC_REGNUM))]
9691 "TARGET_32BIT
9692 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9693 != CCmode)"
9694 "#"
9695 "TARGET_32BIT && reload_completed
9696 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9697 != CCmode)"
9698 [(set (match_dup 7)
9699 (compare
9700 (and:SI
9701 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9702 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9703 (const_int 0)))
9704 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9705 "operands[7]
9706 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9707 DOM_CC_X_AND_Y),
9708 CC_REGNUM);"
9709 [(set_attr "conds" "clob")
9710 (set_attr "enabled_for_depr_it" "yes,no")
9711 (set_attr "length" "16")
9712 (set_attr "type" "multiple")]
9713 )
9714
9715 ; If the above pattern is followed by a CMP insn, then the compare is
9716 ; redundant, since we can rework the conditional instruction that follows.
9717 (define_insn_and_split "*and_scc_scc_cmp"
9718 [(set (match_operand 0 "dominant_cc_register" "")
9719 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9720 [(match_operand:SI 1 "s_register_operand" "l,r")
9721 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9722 (match_operator:SI 6 "arm_comparison_operator"
9723 [(match_operand:SI 4 "s_register_operand" "l,r")
9724 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9725 (const_int 0)))
9726 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9727 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9728 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9729 "TARGET_32BIT"
9730 "#"
9731 "TARGET_32BIT && reload_completed"
9732 [(set (match_dup 0)
9733 (compare
9734 (and:SI
9735 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9736 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9737 (const_int 0)))
9738 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9739 ""
9740 [(set_attr "conds" "set")
9741 (set_attr "enabled_for_depr_it" "yes,no")
9742 (set_attr "length" "16")
9743 (set_attr "type" "multiple")]
9744 )
9745
9746 ;; If there is no dominance in the comparison, then we can still save an
9747 ;; instruction in the AND case, since we can know that the second compare
9748 ;; need only zero the value if false (if true, then the value is already
9749 ;; correct).
9750 (define_insn_and_split "*and_scc_scc_nodom"
9751 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9752 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9753 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9754 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9755 (match_operator:SI 6 "arm_comparison_operator"
9756 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9757 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9758 (clobber (reg:CC CC_REGNUM))]
9759 "TARGET_32BIT
9760 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9761 == CCmode)"
9762 "#"
9763 "TARGET_32BIT && reload_completed"
9764 [(parallel [(set (match_dup 0)
9765 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9766 (clobber (reg:CC CC_REGNUM))])
9767 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9768 (set (match_dup 0)
9769 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9770 (match_dup 0)
9771 (const_int 0)))]
9772 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9773 operands[4], operands[5]),
9774 CC_REGNUM);
9775 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9776 operands[5]);"
9777 [(set_attr "conds" "clob")
9778 (set_attr "length" "20")
9779 (set_attr "type" "multiple")]
9780 )
9781
9782 (define_split
9783 [(set (reg:CC_NOOV CC_REGNUM)
9784 (compare:CC_NOOV (ior:SI
9785 (and:SI (match_operand:SI 0 "s_register_operand" "")
9786 (const_int 1))
9787 (match_operator:SI 1 "arm_comparison_operator"
9788 [(match_operand:SI 2 "s_register_operand" "")
9789 (match_operand:SI 3 "arm_add_operand" "")]))
9790 (const_int 0)))
9791 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9792 "TARGET_ARM"
9793 [(set (match_dup 4)
9794 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9795 (match_dup 0)))
9796 (set (reg:CC_NOOV CC_REGNUM)
9797 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9798 (const_int 0)))]
9799 "")
9800
9801 (define_split
9802 [(set (reg:CC_NOOV CC_REGNUM)
9803 (compare:CC_NOOV (ior:SI
9804 (match_operator:SI 1 "arm_comparison_operator"
9805 [(match_operand:SI 2 "s_register_operand" "")
9806 (match_operand:SI 3 "arm_add_operand" "")])
9807 (and:SI (match_operand:SI 0 "s_register_operand" "")
9808 (const_int 1)))
9809 (const_int 0)))
9810 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9811 "TARGET_ARM"
9812 [(set (match_dup 4)
9813 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9814 (match_dup 0)))
9815 (set (reg:CC_NOOV CC_REGNUM)
9816 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9817 (const_int 0)))]
9818 "")
9819 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9820
9821 (define_insn_and_split "*negscc"
9822 [(set (match_operand:SI 0 "s_register_operand" "=r")
9823 (neg:SI (match_operator 3 "arm_comparison_operator"
9824 [(match_operand:SI 1 "s_register_operand" "r")
9825 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9826 (clobber (reg:CC CC_REGNUM))]
9827 "TARGET_ARM"
9828 "#"
9829 "&& reload_completed"
9830 [(const_int 0)]
9831 {
9832 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9833
9834 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9835 {
9836 /* Emit mov\\t%0, %1, asr #31 */
9837 emit_insn (gen_rtx_SET (operands[0],
9838 gen_rtx_ASHIFTRT (SImode,
9839 operands[1],
9840 GEN_INT (31))));
9841 DONE;
9842 }
9843 else if (GET_CODE (operands[3]) == NE)
9844 {
9845 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9846 if (CONST_INT_P (operands[2]))
9847 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9848 GEN_INT (- INTVAL (operands[2]))));
9849 else
9850 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9851
9852 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9853 gen_rtx_NE (SImode,
9854 cc_reg,
9855 const0_rtx),
9856 gen_rtx_SET (operands[0],
9857 GEN_INT (~0))));
9858 DONE;
9859 }
9860 else
9861 {
9862 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9863 emit_insn (gen_rtx_SET (cc_reg,
9864 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9865 enum rtx_code rc = GET_CODE (operands[3]);
9866
9867 rc = reverse_condition (rc);
9868 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9869 gen_rtx_fmt_ee (rc,
9870 VOIDmode,
9871 cc_reg,
9872 const0_rtx),
9873 gen_rtx_SET (operands[0], const0_rtx)));
9874 rc = GET_CODE (operands[3]);
9875 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9876 gen_rtx_fmt_ee (rc,
9877 VOIDmode,
9878 cc_reg,
9879 const0_rtx),
9880 gen_rtx_SET (operands[0],
9881 GEN_INT (~0))));
9882 DONE;
9883 }
9884 FAIL;
9885 }
9886 [(set_attr "conds" "clob")
9887 (set_attr "length" "12")
9888 (set_attr "type" "multiple")]
9889 )
9890
9891 (define_insn_and_split "movcond_addsi"
9892 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9893 (if_then_else:SI
9894 (match_operator 5 "comparison_operator"
9895 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9896 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9897 (const_int 0)])
9898 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9899 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9900 (clobber (reg:CC CC_REGNUM))]
9901 "TARGET_32BIT"
9902 "#"
9903 "&& reload_completed"
9904 [(set (reg:CC_NOOV CC_REGNUM)
9905 (compare:CC_NOOV
9906 (plus:SI (match_dup 3)
9907 (match_dup 4))
9908 (const_int 0)))
9909 (set (match_dup 0) (match_dup 1))
9910 (cond_exec (match_dup 6)
9911 (set (match_dup 0) (match_dup 2)))]
9912 "
9913 {
9914 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9915 operands[3], operands[4]);
9916 enum rtx_code rc = GET_CODE (operands[5]);
9917 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9918 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9919 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9920 rc = reverse_condition (rc);
9921 else
9922 std::swap (operands[1], operands[2]);
9923
9924 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9925 }
9926 "
9927 [(set_attr "conds" "clob")
9928 (set_attr "enabled_for_depr_it" "no,yes,yes")
9929 (set_attr "type" "multiple")]
9930 )
9931
9932 (define_insn "movcond"
9933 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9934 (if_then_else:SI
9935 (match_operator 5 "arm_comparison_operator"
9936 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9937 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9938 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9939 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9940 (clobber (reg:CC CC_REGNUM))]
9941 "TARGET_ARM"
9942 "*
9943 if (GET_CODE (operands[5]) == LT
9944 && (operands[4] == const0_rtx))
9945 {
9946 if (which_alternative != 1 && REG_P (operands[1]))
9947 {
9948 if (operands[2] == const0_rtx)
9949 return \"and\\t%0, %1, %3, asr #31\";
9950 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9951 }
9952 else if (which_alternative != 0 && REG_P (operands[2]))
9953 {
9954 if (operands[1] == const0_rtx)
9955 return \"bic\\t%0, %2, %3, asr #31\";
9956 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9957 }
9958 /* The only case that falls through to here is when both ops 1 & 2
9959 are constants. */
9960 }
9961
9962 if (GET_CODE (operands[5]) == GE
9963 && (operands[4] == const0_rtx))
9964 {
9965 if (which_alternative != 1 && REG_P (operands[1]))
9966 {
9967 if (operands[2] == const0_rtx)
9968 return \"bic\\t%0, %1, %3, asr #31\";
9969 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9970 }
9971 else if (which_alternative != 0 && REG_P (operands[2]))
9972 {
9973 if (operands[1] == const0_rtx)
9974 return \"and\\t%0, %2, %3, asr #31\";
9975 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9976 }
9977 /* The only case that falls through to here is when both ops 1 & 2
9978 are constants. */
9979 }
9980 if (CONST_INT_P (operands[4])
9981 && !const_ok_for_arm (INTVAL (operands[4])))
9982 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9983 else
9984 output_asm_insn (\"cmp\\t%3, %4\", operands);
9985 if (which_alternative != 0)
9986 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9987 if (which_alternative != 1)
9988 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9989 return \"\";
9990 "
9991 [(set_attr "conds" "clob")
9992 (set_attr "length" "8,8,12")
9993 (set_attr "type" "multiple")]
9994 )
9995
9996 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9997
9998 (define_insn "*ifcompare_plus_move"
9999 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10000 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10001 [(match_operand:SI 4 "s_register_operand" "r,r")
10002 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10003 (plus:SI
10004 (match_operand:SI 2 "s_register_operand" "r,r")
10005 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10006 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10007 (clobber (reg:CC CC_REGNUM))]
10008 "TARGET_ARM"
10009 "#"
10010 [(set_attr "conds" "clob")
10011 (set_attr "length" "8,12")
10012 (set_attr "type" "multiple")]
10013 )
10014
10015 (define_insn "*if_plus_move"
10016 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10017 (if_then_else:SI
10018 (match_operator 4 "arm_comparison_operator"
10019 [(match_operand 5 "cc_register" "") (const_int 0)])
10020 (plus:SI
10021 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10022 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10023 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10024 "TARGET_ARM"
10025 "@
10026 add%d4\\t%0, %2, %3
10027 sub%d4\\t%0, %2, #%n3
10028 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10029 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10030 [(set_attr "conds" "use")
10031 (set_attr "length" "4,4,8,8")
10032 (set_attr_alternative "type"
10033 [(if_then_else (match_operand 3 "const_int_operand" "")
10034 (const_string "alu_imm" )
10035 (const_string "alu_sreg"))
10036 (const_string "alu_imm")
10037 (const_string "multiple")
10038 (const_string "multiple")])]
10039 )
10040
10041 (define_insn "*ifcompare_move_plus"
10042 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10043 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10044 [(match_operand:SI 4 "s_register_operand" "r,r")
10045 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10046 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10047 (plus:SI
10048 (match_operand:SI 2 "s_register_operand" "r,r")
10049 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10050 (clobber (reg:CC CC_REGNUM))]
10051 "TARGET_ARM"
10052 "#"
10053 [(set_attr "conds" "clob")
10054 (set_attr "length" "8,12")
10055 (set_attr "type" "multiple")]
10056 )
10057
10058 (define_insn "*if_move_plus"
10059 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10060 (if_then_else:SI
10061 (match_operator 4 "arm_comparison_operator"
10062 [(match_operand 5 "cc_register" "") (const_int 0)])
10063 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10064 (plus:SI
10065 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10066 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10067 "TARGET_ARM"
10068 "@
10069 add%D4\\t%0, %2, %3
10070 sub%D4\\t%0, %2, #%n3
10071 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10072 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10073 [(set_attr "conds" "use")
10074 (set_attr "length" "4,4,8,8")
10075 (set_attr_alternative "type"
10076 [(if_then_else (match_operand 3 "const_int_operand" "")
10077 (const_string "alu_imm" )
10078 (const_string "alu_sreg"))
10079 (const_string "alu_imm")
10080 (const_string "multiple")
10081 (const_string "multiple")])]
10082 )
10083
10084 (define_insn "*ifcompare_arith_arith"
10085 [(set (match_operand:SI 0 "s_register_operand" "=r")
10086 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10087 [(match_operand:SI 5 "s_register_operand" "r")
10088 (match_operand:SI 6 "arm_add_operand" "rIL")])
10089 (match_operator:SI 8 "shiftable_operator"
10090 [(match_operand:SI 1 "s_register_operand" "r")
10091 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10092 (match_operator:SI 7 "shiftable_operator"
10093 [(match_operand:SI 3 "s_register_operand" "r")
10094 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10095 (clobber (reg:CC CC_REGNUM))]
10096 "TARGET_ARM"
10097 "#"
10098 [(set_attr "conds" "clob")
10099 (set_attr "length" "12")
10100 (set_attr "type" "multiple")]
10101 )
10102
10103 (define_insn "*if_arith_arith"
10104 [(set (match_operand:SI 0 "s_register_operand" "=r")
10105 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10106 [(match_operand 8 "cc_register" "") (const_int 0)])
10107 (match_operator:SI 6 "shiftable_operator"
10108 [(match_operand:SI 1 "s_register_operand" "r")
10109 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10110 (match_operator:SI 7 "shiftable_operator"
10111 [(match_operand:SI 3 "s_register_operand" "r")
10112 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10113 "TARGET_ARM"
10114 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10115 [(set_attr "conds" "use")
10116 (set_attr "length" "8")
10117 (set_attr "type" "multiple")]
10118 )
10119
10120 (define_insn "*ifcompare_arith_move"
10121 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10122 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10123 [(match_operand:SI 2 "s_register_operand" "r,r")
10124 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10125 (match_operator:SI 7 "shiftable_operator"
10126 [(match_operand:SI 4 "s_register_operand" "r,r")
10127 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10128 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10129 (clobber (reg:CC CC_REGNUM))]
10130 "TARGET_ARM"
10131 "*
10132 /* If we have an operation where (op x 0) is the identity operation and
10133 the conditional operator is LT or GE and we are comparing against zero and
10134 everything is in registers then we can do this in two instructions. */
10135 if (operands[3] == const0_rtx
10136 && GET_CODE (operands[7]) != AND
10137 && REG_P (operands[5])
10138 && REG_P (operands[1])
10139 && REGNO (operands[1]) == REGNO (operands[4])
10140 && REGNO (operands[4]) != REGNO (operands[0]))
10141 {
10142 if (GET_CODE (operands[6]) == LT)
10143 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10144 else if (GET_CODE (operands[6]) == GE)
10145 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10146 }
10147 if (CONST_INT_P (operands[3])
10148 && !const_ok_for_arm (INTVAL (operands[3])))
10149 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10150 else
10151 output_asm_insn (\"cmp\\t%2, %3\", operands);
10152 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10153 if (which_alternative != 0)
10154 return \"mov%D6\\t%0, %1\";
10155 return \"\";
10156 "
10157 [(set_attr "conds" "clob")
10158 (set_attr "length" "8,12")
10159 (set_attr "type" "multiple")]
10160 )
10161
10162 (define_insn "*if_arith_move"
10163 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10164 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10165 [(match_operand 6 "cc_register" "") (const_int 0)])
10166 (match_operator:SI 5 "shiftable_operator"
10167 [(match_operand:SI 2 "s_register_operand" "r,r")
10168 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10169 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10170 "TARGET_ARM"
10171 "@
10172 %I5%d4\\t%0, %2, %3
10173 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10174 [(set_attr "conds" "use")
10175 (set_attr "length" "4,8")
10176 (set_attr_alternative "type"
10177 [(if_then_else (match_operand 3 "const_int_operand" "")
10178 (const_string "alu_shift_imm" )
10179 (const_string "alu_shift_reg"))
10180 (const_string "multiple")])]
10181 )
10182
10183 (define_insn "*ifcompare_move_arith"
10184 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10185 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10186 [(match_operand:SI 4 "s_register_operand" "r,r")
10187 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10188 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10189 (match_operator:SI 7 "shiftable_operator"
10190 [(match_operand:SI 2 "s_register_operand" "r,r")
10191 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10192 (clobber (reg:CC CC_REGNUM))]
10193 "TARGET_ARM"
10194 "*
10195 /* If we have an operation where (op x 0) is the identity operation and
10196 the conditional operator is LT or GE and we are comparing against zero and
10197 everything is in registers then we can do this in two instructions */
10198 if (operands[5] == const0_rtx
10199 && GET_CODE (operands[7]) != AND
10200 && REG_P (operands[3])
10201 && REG_P (operands[1])
10202 && REGNO (operands[1]) == REGNO (operands[2])
10203 && REGNO (operands[2]) != REGNO (operands[0]))
10204 {
10205 if (GET_CODE (operands[6]) == GE)
10206 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10207 else if (GET_CODE (operands[6]) == LT)
10208 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10209 }
10210
10211 if (CONST_INT_P (operands[5])
10212 && !const_ok_for_arm (INTVAL (operands[5])))
10213 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10214 else
10215 output_asm_insn (\"cmp\\t%4, %5\", operands);
10216
10217 if (which_alternative != 0)
10218 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10219 return \"%I7%D6\\t%0, %2, %3\";
10220 "
10221 [(set_attr "conds" "clob")
10222 (set_attr "length" "8,12")
10223 (set_attr "type" "multiple")]
10224 )
10225
10226 (define_insn "*if_move_arith"
10227 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10228 (if_then_else:SI
10229 (match_operator 4 "arm_comparison_operator"
10230 [(match_operand 6 "cc_register" "") (const_int 0)])
10231 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10232 (match_operator:SI 5 "shiftable_operator"
10233 [(match_operand:SI 2 "s_register_operand" "r,r")
10234 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10235 "TARGET_ARM"
10236 "@
10237 %I5%D4\\t%0, %2, %3
10238 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10239 [(set_attr "conds" "use")
10240 (set_attr "length" "4,8")
10241 (set_attr_alternative "type"
10242 [(if_then_else (match_operand 3 "const_int_operand" "")
10243 (const_string "alu_shift_imm" )
10244 (const_string "alu_shift_reg"))
10245 (const_string "multiple")])]
10246 )
10247
10248 (define_insn "*ifcompare_move_not"
10249 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10250 (if_then_else:SI
10251 (match_operator 5 "arm_comparison_operator"
10252 [(match_operand:SI 3 "s_register_operand" "r,r")
10253 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10254 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10255 (not:SI
10256 (match_operand:SI 2 "s_register_operand" "r,r"))))
10257 (clobber (reg:CC CC_REGNUM))]
10258 "TARGET_ARM"
10259 "#"
10260 [(set_attr "conds" "clob")
10261 (set_attr "length" "8,12")
10262 (set_attr "type" "multiple")]
10263 )
10264
10265 (define_insn "*if_move_not"
10266 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10267 (if_then_else:SI
10268 (match_operator 4 "arm_comparison_operator"
10269 [(match_operand 3 "cc_register" "") (const_int 0)])
10270 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10271 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10272 "TARGET_ARM"
10273 "@
10274 mvn%D4\\t%0, %2
10275 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10276 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10277 [(set_attr "conds" "use")
10278 (set_attr "type" "mvn_reg")
10279 (set_attr "length" "4,8,8")
10280 (set_attr "type" "mvn_reg,multiple,multiple")]
10281 )
10282
10283 (define_insn "*ifcompare_not_move"
10284 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10285 (if_then_else:SI
10286 (match_operator 5 "arm_comparison_operator"
10287 [(match_operand:SI 3 "s_register_operand" "r,r")
10288 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10289 (not:SI
10290 (match_operand:SI 2 "s_register_operand" "r,r"))
10291 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10292 (clobber (reg:CC CC_REGNUM))]
10293 "TARGET_ARM"
10294 "#"
10295 [(set_attr "conds" "clob")
10296 (set_attr "length" "8,12")
10297 (set_attr "type" "multiple")]
10298 )
10299
10300 (define_insn "*if_not_move"
10301 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10302 (if_then_else:SI
10303 (match_operator 4 "arm_comparison_operator"
10304 [(match_operand 3 "cc_register" "") (const_int 0)])
10305 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10306 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10307 "TARGET_ARM"
10308 "@
10309 mvn%d4\\t%0, %2
10310 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10311 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10312 [(set_attr "conds" "use")
10313 (set_attr "type" "mvn_reg,multiple,multiple")
10314 (set_attr "length" "4,8,8")]
10315 )
10316
10317 (define_insn "*ifcompare_shift_move"
10318 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10319 (if_then_else:SI
10320 (match_operator 6 "arm_comparison_operator"
10321 [(match_operand:SI 4 "s_register_operand" "r,r")
10322 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10323 (match_operator:SI 7 "shift_operator"
10324 [(match_operand:SI 2 "s_register_operand" "r,r")
10325 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10326 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10327 (clobber (reg:CC CC_REGNUM))]
10328 "TARGET_ARM"
10329 "#"
10330 [(set_attr "conds" "clob")
10331 (set_attr "length" "8,12")
10332 (set_attr "type" "multiple")]
10333 )
10334
10335 (define_insn "*if_shift_move"
10336 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10337 (if_then_else:SI
10338 (match_operator 5 "arm_comparison_operator"
10339 [(match_operand 6 "cc_register" "") (const_int 0)])
10340 (match_operator:SI 4 "shift_operator"
10341 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10342 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10343 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10344 "TARGET_ARM"
10345 "@
10346 mov%d5\\t%0, %2%S4
10347 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10348 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10349 [(set_attr "conds" "use")
10350 (set_attr "shift" "2")
10351 (set_attr "length" "4,8,8")
10352 (set_attr_alternative "type"
10353 [(if_then_else (match_operand 3 "const_int_operand" "")
10354 (const_string "mov_shift" )
10355 (const_string "mov_shift_reg"))
10356 (const_string "multiple")
10357 (const_string "multiple")])]
10358 )
10359
10360 (define_insn "*ifcompare_move_shift"
10361 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10362 (if_then_else:SI
10363 (match_operator 6 "arm_comparison_operator"
10364 [(match_operand:SI 4 "s_register_operand" "r,r")
10365 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10366 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10367 (match_operator:SI 7 "shift_operator"
10368 [(match_operand:SI 2 "s_register_operand" "r,r")
10369 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10370 (clobber (reg:CC CC_REGNUM))]
10371 "TARGET_ARM"
10372 "#"
10373 [(set_attr "conds" "clob")
10374 (set_attr "length" "8,12")
10375 (set_attr "type" "multiple")]
10376 )
10377
10378 (define_insn "*if_move_shift"
10379 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10380 (if_then_else:SI
10381 (match_operator 5 "arm_comparison_operator"
10382 [(match_operand 6 "cc_register" "") (const_int 0)])
10383 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10384 (match_operator:SI 4 "shift_operator"
10385 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10386 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10387 "TARGET_ARM"
10388 "@
10389 mov%D5\\t%0, %2%S4
10390 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10391 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10392 [(set_attr "conds" "use")
10393 (set_attr "shift" "2")
10394 (set_attr "length" "4,8,8")
10395 (set_attr_alternative "type"
10396 [(if_then_else (match_operand 3 "const_int_operand" "")
10397 (const_string "mov_shift" )
10398 (const_string "mov_shift_reg"))
10399 (const_string "multiple")
10400 (const_string "multiple")])]
10401 )
10402
10403 (define_insn "*ifcompare_shift_shift"
10404 [(set (match_operand:SI 0 "s_register_operand" "=r")
10405 (if_then_else:SI
10406 (match_operator 7 "arm_comparison_operator"
10407 [(match_operand:SI 5 "s_register_operand" "r")
10408 (match_operand:SI 6 "arm_add_operand" "rIL")])
10409 (match_operator:SI 8 "shift_operator"
10410 [(match_operand:SI 1 "s_register_operand" "r")
10411 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10412 (match_operator:SI 9 "shift_operator"
10413 [(match_operand:SI 3 "s_register_operand" "r")
10414 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10415 (clobber (reg:CC CC_REGNUM))]
10416 "TARGET_ARM"
10417 "#"
10418 [(set_attr "conds" "clob")
10419 (set_attr "length" "12")
10420 (set_attr "type" "multiple")]
10421 )
10422
10423 (define_insn "*if_shift_shift"
10424 [(set (match_operand:SI 0 "s_register_operand" "=r")
10425 (if_then_else:SI
10426 (match_operator 5 "arm_comparison_operator"
10427 [(match_operand 8 "cc_register" "") (const_int 0)])
10428 (match_operator:SI 6 "shift_operator"
10429 [(match_operand:SI 1 "s_register_operand" "r")
10430 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10431 (match_operator:SI 7 "shift_operator"
10432 [(match_operand:SI 3 "s_register_operand" "r")
10433 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10434 "TARGET_ARM"
10435 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10436 [(set_attr "conds" "use")
10437 (set_attr "shift" "1")
10438 (set_attr "length" "8")
10439 (set (attr "type") (if_then_else
10440 (and (match_operand 2 "const_int_operand" "")
10441 (match_operand 4 "const_int_operand" ""))
10442 (const_string "mov_shift")
10443 (const_string "mov_shift_reg")))]
10444 )
10445
10446 (define_insn "*ifcompare_not_arith"
10447 [(set (match_operand:SI 0 "s_register_operand" "=r")
10448 (if_then_else:SI
10449 (match_operator 6 "arm_comparison_operator"
10450 [(match_operand:SI 4 "s_register_operand" "r")
10451 (match_operand:SI 5 "arm_add_operand" "rIL")])
10452 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10453 (match_operator:SI 7 "shiftable_operator"
10454 [(match_operand:SI 2 "s_register_operand" "r")
10455 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10456 (clobber (reg:CC CC_REGNUM))]
10457 "TARGET_ARM"
10458 "#"
10459 [(set_attr "conds" "clob")
10460 (set_attr "length" "12")
10461 (set_attr "type" "multiple")]
10462 )
10463
10464 (define_insn "*if_not_arith"
10465 [(set (match_operand:SI 0 "s_register_operand" "=r")
10466 (if_then_else:SI
10467 (match_operator 5 "arm_comparison_operator"
10468 [(match_operand 4 "cc_register" "") (const_int 0)])
10469 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10470 (match_operator:SI 6 "shiftable_operator"
10471 [(match_operand:SI 2 "s_register_operand" "r")
10472 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10473 "TARGET_ARM"
10474 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10475 [(set_attr "conds" "use")
10476 (set_attr "type" "mvn_reg")
10477 (set_attr "length" "8")]
10478 )
10479
10480 (define_insn "*ifcompare_arith_not"
10481 [(set (match_operand:SI 0 "s_register_operand" "=r")
10482 (if_then_else:SI
10483 (match_operator 6 "arm_comparison_operator"
10484 [(match_operand:SI 4 "s_register_operand" "r")
10485 (match_operand:SI 5 "arm_add_operand" "rIL")])
10486 (match_operator:SI 7 "shiftable_operator"
10487 [(match_operand:SI 2 "s_register_operand" "r")
10488 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10489 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10490 (clobber (reg:CC CC_REGNUM))]
10491 "TARGET_ARM"
10492 "#"
10493 [(set_attr "conds" "clob")
10494 (set_attr "length" "12")
10495 (set_attr "type" "multiple")]
10496 )
10497
10498 (define_insn "*if_arith_not"
10499 [(set (match_operand:SI 0 "s_register_operand" "=r")
10500 (if_then_else:SI
10501 (match_operator 5 "arm_comparison_operator"
10502 [(match_operand 4 "cc_register" "") (const_int 0)])
10503 (match_operator:SI 6 "shiftable_operator"
10504 [(match_operand:SI 2 "s_register_operand" "r")
10505 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10506 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10507 "TARGET_ARM"
10508 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10509 [(set_attr "conds" "use")
10510 (set_attr "type" "multiple")
10511 (set_attr "length" "8")]
10512 )
10513
10514 (define_insn "*ifcompare_neg_move"
10515 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10516 (if_then_else:SI
10517 (match_operator 5 "arm_comparison_operator"
10518 [(match_operand:SI 3 "s_register_operand" "r,r")
10519 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10520 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10521 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10522 (clobber (reg:CC CC_REGNUM))]
10523 "TARGET_ARM"
10524 "#"
10525 [(set_attr "conds" "clob")
10526 (set_attr "length" "8,12")
10527 (set_attr "type" "multiple")]
10528 )
10529
10530 (define_insn_and_split "*if_neg_move"
10531 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10532 (if_then_else:SI
10533 (match_operator 4 "arm_comparison_operator"
10534 [(match_operand 3 "cc_register" "") (const_int 0)])
10535 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10536 (match_operand:SI 1 "s_register_operand" "0,0")))]
10537 "TARGET_32BIT"
10538 "#"
10539 "&& reload_completed"
10540 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10541 (set (match_dup 0) (neg:SI (match_dup 2))))]
10542 ""
10543 [(set_attr "conds" "use")
10544 (set_attr "length" "4")
10545 (set_attr "arch" "t2,32")
10546 (set_attr "enabled_for_depr_it" "yes,no")
10547 (set_attr "type" "logic_shift_imm")]
10548 )
10549
10550 (define_insn "*ifcompare_move_neg"
10551 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10552 (if_then_else:SI
10553 (match_operator 5 "arm_comparison_operator"
10554 [(match_operand:SI 3 "s_register_operand" "r,r")
10555 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10556 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10557 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10558 (clobber (reg:CC CC_REGNUM))]
10559 "TARGET_ARM"
10560 "#"
10561 [(set_attr "conds" "clob")
10562 (set_attr "length" "8,12")
10563 (set_attr "type" "multiple")]
10564 )
10565
10566 (define_insn_and_split "*if_move_neg"
10567 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10568 (if_then_else:SI
10569 (match_operator 4 "arm_comparison_operator"
10570 [(match_operand 3 "cc_register" "") (const_int 0)])
10571 (match_operand:SI 1 "s_register_operand" "0,0")
10572 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10573 "TARGET_32BIT"
10574 "#"
10575 "&& reload_completed"
10576 [(cond_exec (match_dup 5)
10577 (set (match_dup 0) (neg:SI (match_dup 2))))]
10578 {
10579 machine_mode mode = GET_MODE (operands[3]);
10580 rtx_code rc = GET_CODE (operands[4]);
10581
10582 if (mode == CCFPmode || mode == CCFPEmode)
10583 rc = reverse_condition_maybe_unordered (rc);
10584 else
10585 rc = reverse_condition (rc);
10586
10587 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10588 }
10589 [(set_attr "conds" "use")
10590 (set_attr "length" "4")
10591 (set_attr "arch" "t2,32")
10592 (set_attr "enabled_for_depr_it" "yes,no")
10593 (set_attr "type" "logic_shift_imm")]
10594 )
10595
10596 (define_insn "*arith_adjacentmem"
10597 [(set (match_operand:SI 0 "s_register_operand" "=r")
10598 (match_operator:SI 1 "shiftable_operator"
10599 [(match_operand:SI 2 "memory_operand" "m")
10600 (match_operand:SI 3 "memory_operand" "m")]))
10601 (clobber (match_scratch:SI 4 "=r"))]
10602 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10603 "*
10604 {
10605 rtx ldm[3];
10606 rtx arith[4];
10607 rtx base_reg;
10608 HOST_WIDE_INT val1 = 0, val2 = 0;
10609
10610 if (REGNO (operands[0]) > REGNO (operands[4]))
10611 {
10612 ldm[1] = operands[4];
10613 ldm[2] = operands[0];
10614 }
10615 else
10616 {
10617 ldm[1] = operands[0];
10618 ldm[2] = operands[4];
10619 }
10620
10621 base_reg = XEXP (operands[2], 0);
10622
10623 if (!REG_P (base_reg))
10624 {
10625 val1 = INTVAL (XEXP (base_reg, 1));
10626 base_reg = XEXP (base_reg, 0);
10627 }
10628
10629 if (!REG_P (XEXP (operands[3], 0)))
10630 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10631
10632 arith[0] = operands[0];
10633 arith[3] = operands[1];
10634
10635 if (val1 < val2)
10636 {
10637 arith[1] = ldm[1];
10638 arith[2] = ldm[2];
10639 }
10640 else
10641 {
10642 arith[1] = ldm[2];
10643 arith[2] = ldm[1];
10644 }
10645
10646 ldm[0] = base_reg;
10647 if (val1 !=0 && val2 != 0)
10648 {
10649 rtx ops[3];
10650
10651 if (val1 == 4 || val2 == 4)
10652 /* Other val must be 8, since we know they are adjacent and neither
10653 is zero. */
10654 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10655 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10656 {
10657 ldm[0] = ops[0] = operands[4];
10658 ops[1] = base_reg;
10659 ops[2] = GEN_INT (val1);
10660 output_add_immediate (ops);
10661 if (val1 < val2)
10662 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10663 else
10664 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10665 }
10666 else
10667 {
10668 /* Offset is out of range for a single add, so use two ldr. */
10669 ops[0] = ldm[1];
10670 ops[1] = base_reg;
10671 ops[2] = GEN_INT (val1);
10672 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10673 ops[0] = ldm[2];
10674 ops[2] = GEN_INT (val2);
10675 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10676 }
10677 }
10678 else if (val1 != 0)
10679 {
10680 if (val1 < val2)
10681 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10682 else
10683 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10684 }
10685 else
10686 {
10687 if (val1 < val2)
10688 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10689 else
10690 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10691 }
10692 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10693 return \"\";
10694 }"
10695 [(set_attr "length" "12")
10696 (set_attr "predicable" "yes")
10697 (set_attr "type" "load_4")]
10698 )
10699
10700 ; This pattern is never tried by combine, so do it as a peephole
10701
10702 (define_peephole2
10703 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10704 (match_operand:SI 1 "arm_general_register_operand" ""))
10705 (set (reg:CC CC_REGNUM)
10706 (compare:CC (match_dup 1) (const_int 0)))]
10707 "TARGET_ARM"
10708 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10709 (set (match_dup 0) (match_dup 1))])]
10710 ""
10711 )
10712
10713 (define_split
10714 [(set (match_operand:SI 0 "s_register_operand" "")
10715 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10716 (const_int 0))
10717 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10718 [(match_operand:SI 3 "s_register_operand" "")
10719 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10720 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10721 "TARGET_ARM"
10722 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10723 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10724 (match_dup 5)))]
10725 ""
10726 )
10727
10728 ;; This split can be used because CC_Z mode implies that the following
10729 ;; branch will be an equality, or an unsigned inequality, so the sign
10730 ;; extension is not needed.
10731
10732 (define_split
10733 [(set (reg:CC_Z CC_REGNUM)
10734 (compare:CC_Z
10735 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10736 (const_int 24))
10737 (match_operand 1 "const_int_operand" "")))
10738 (clobber (match_scratch:SI 2 ""))]
10739 "TARGET_ARM
10740 && ((UINTVAL (operands[1]))
10741 == ((UINTVAL (operands[1])) >> 24) << 24)"
10742 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10743 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10744 "
10745 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10746 "
10747 )
10748 ;; ??? Check the patterns above for Thumb-2 usefulness
10749
10750 (define_expand "prologue"
10751 [(clobber (const_int 0))]
10752 "TARGET_EITHER"
10753 "if (TARGET_32BIT)
10754 arm_expand_prologue ();
10755 else
10756 thumb1_expand_prologue ();
10757 DONE;
10758 "
10759 )
10760
10761 (define_expand "epilogue"
10762 [(clobber (const_int 0))]
10763 "TARGET_EITHER"
10764 "
10765 if (crtl->calls_eh_return)
10766 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10767 if (TARGET_THUMB1)
10768 {
10769 thumb1_expand_epilogue ();
10770 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10771 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10772 }
10773 else if (HAVE_return)
10774 {
10775 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10776 no need for explicit testing again. */
10777 emit_jump_insn (gen_return ());
10778 }
10779 else if (TARGET_32BIT)
10780 {
10781 arm_expand_epilogue (true);
10782 }
10783 DONE;
10784 "
10785 )
10786
10787 ;; Note - although unspec_volatile's USE all hard registers,
10788 ;; USEs are ignored after relaod has completed. Thus we need
10789 ;; to add an unspec of the link register to ensure that flow
10790 ;; does not think that it is unused by the sibcall branch that
10791 ;; will replace the standard function epilogue.
10792 (define_expand "sibcall_epilogue"
10793 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10794 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10795 "TARGET_32BIT"
10796 "
10797 arm_expand_epilogue (false);
10798 DONE;
10799 "
10800 )
10801
10802 (define_expand "eh_epilogue"
10803 [(use (match_operand:SI 0 "register_operand" ""))
10804 (use (match_operand:SI 1 "register_operand" ""))
10805 (use (match_operand:SI 2 "register_operand" ""))]
10806 "TARGET_EITHER"
10807 "
10808 {
10809 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10810 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10811 {
10812 rtx ra = gen_rtx_REG (Pmode, 2);
10813
10814 emit_move_insn (ra, operands[2]);
10815 operands[2] = ra;
10816 }
10817 /* This is a hack -- we may have crystalized the function type too
10818 early. */
10819 cfun->machine->func_type = 0;
10820 }"
10821 )
10822
10823 ;; This split is only used during output to reduce the number of patterns
10824 ;; that need assembler instructions adding to them. We allowed the setting
10825 ;; of the conditions to be implicit during rtl generation so that
10826 ;; the conditional compare patterns would work. However this conflicts to
10827 ;; some extent with the conditional data operations, so we have to split them
10828 ;; up again here.
10829
10830 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10831 ;; conditional execution sufficient?
10832
10833 (define_split
10834 [(set (match_operand:SI 0 "s_register_operand" "")
10835 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10836 [(match_operand 2 "" "") (match_operand 3 "" "")])
10837 (match_dup 0)
10838 (match_operand 4 "" "")))
10839 (clobber (reg:CC CC_REGNUM))]
10840 "TARGET_ARM && reload_completed"
10841 [(set (match_dup 5) (match_dup 6))
10842 (cond_exec (match_dup 7)
10843 (set (match_dup 0) (match_dup 4)))]
10844 "
10845 {
10846 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10847 operands[2], operands[3]);
10848 enum rtx_code rc = GET_CODE (operands[1]);
10849
10850 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10851 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10852 if (mode == CCFPmode || mode == CCFPEmode)
10853 rc = reverse_condition_maybe_unordered (rc);
10854 else
10855 rc = reverse_condition (rc);
10856
10857 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10858 }"
10859 )
10860
10861 (define_split
10862 [(set (match_operand:SI 0 "s_register_operand" "")
10863 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10864 [(match_operand 2 "" "") (match_operand 3 "" "")])
10865 (match_operand 4 "" "")
10866 (match_dup 0)))
10867 (clobber (reg:CC CC_REGNUM))]
10868 "TARGET_ARM && reload_completed"
10869 [(set (match_dup 5) (match_dup 6))
10870 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10871 (set (match_dup 0) (match_dup 4)))]
10872 "
10873 {
10874 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10875 operands[2], operands[3]);
10876
10877 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10878 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10879 }"
10880 )
10881
10882 (define_split
10883 [(set (match_operand:SI 0 "s_register_operand" "")
10884 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10885 [(match_operand 2 "" "") (match_operand 3 "" "")])
10886 (match_operand 4 "" "")
10887 (match_operand 5 "" "")))
10888 (clobber (reg:CC CC_REGNUM))]
10889 "TARGET_ARM && reload_completed"
10890 [(set (match_dup 6) (match_dup 7))
10891 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10892 (set (match_dup 0) (match_dup 4)))
10893 (cond_exec (match_dup 8)
10894 (set (match_dup 0) (match_dup 5)))]
10895 "
10896 {
10897 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10898 operands[2], operands[3]);
10899 enum rtx_code rc = GET_CODE (operands[1]);
10900
10901 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10902 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10903 if (mode == CCFPmode || mode == CCFPEmode)
10904 rc = reverse_condition_maybe_unordered (rc);
10905 else
10906 rc = reverse_condition (rc);
10907
10908 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10909 }"
10910 )
10911
10912 (define_split
10913 [(set (match_operand:SI 0 "s_register_operand" "")
10914 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10915 [(match_operand:SI 2 "s_register_operand" "")
10916 (match_operand:SI 3 "arm_add_operand" "")])
10917 (match_operand:SI 4 "arm_rhs_operand" "")
10918 (not:SI
10919 (match_operand:SI 5 "s_register_operand" ""))))
10920 (clobber (reg:CC CC_REGNUM))]
10921 "TARGET_ARM && reload_completed"
10922 [(set (match_dup 6) (match_dup 7))
10923 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10924 (set (match_dup 0) (match_dup 4)))
10925 (cond_exec (match_dup 8)
10926 (set (match_dup 0) (not:SI (match_dup 5))))]
10927 "
10928 {
10929 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10930 operands[2], operands[3]);
10931 enum rtx_code rc = GET_CODE (operands[1]);
10932
10933 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10934 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10935 if (mode == CCFPmode || mode == CCFPEmode)
10936 rc = reverse_condition_maybe_unordered (rc);
10937 else
10938 rc = reverse_condition (rc);
10939
10940 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10941 }"
10942 )
10943
10944 (define_insn "*cond_move_not"
10945 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10946 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10947 [(match_operand 3 "cc_register" "") (const_int 0)])
10948 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10949 (not:SI
10950 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10951 "TARGET_ARM"
10952 "@
10953 mvn%D4\\t%0, %2
10954 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10955 [(set_attr "conds" "use")
10956 (set_attr "type" "mvn_reg,multiple")
10957 (set_attr "length" "4,8")]
10958 )
10959
10960 ;; The next two patterns occur when an AND operation is followed by a
10961 ;; scc insn sequence
10962
10963 (define_insn "*sign_extract_onebit"
10964 [(set (match_operand:SI 0 "s_register_operand" "=r")
10965 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10966 (const_int 1)
10967 (match_operand:SI 2 "const_int_operand" "n")))
10968 (clobber (reg:CC CC_REGNUM))]
10969 "TARGET_ARM"
10970 "*
10971 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10972 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10973 return \"mvnne\\t%0, #0\";
10974 "
10975 [(set_attr "conds" "clob")
10976 (set_attr "length" "8")
10977 (set_attr "type" "multiple")]
10978 )
10979
10980 (define_insn "*not_signextract_onebit"
10981 [(set (match_operand:SI 0 "s_register_operand" "=r")
10982 (not:SI
10983 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10984 (const_int 1)
10985 (match_operand:SI 2 "const_int_operand" "n"))))
10986 (clobber (reg:CC CC_REGNUM))]
10987 "TARGET_ARM"
10988 "*
10989 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10990 output_asm_insn (\"tst\\t%1, %2\", operands);
10991 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10992 return \"movne\\t%0, #0\";
10993 "
10994 [(set_attr "conds" "clob")
10995 (set_attr "length" "12")
10996 (set_attr "type" "multiple")]
10997 )
10998 ;; ??? The above patterns need auditing for Thumb-2
10999
11000 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
11001 ;; expressions. For simplicity, the first register is also in the unspec
11002 ;; part.
11003 ;; To avoid the usage of GNU extension, the length attribute is computed
11004 ;; in a C function arm_attr_length_push_multi.
11005 (define_insn "*push_multi"
11006 [(match_parallel 2 "multi_register_push"
11007 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11008 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11009 UNSPEC_PUSH_MULT))])]
11010 ""
11011 "*
11012 {
11013 int num_saves = XVECLEN (operands[2], 0);
11014
11015 /* For the StrongARM at least it is faster to
11016 use STR to store only a single register.
11017 In Thumb mode always use push, and the assembler will pick
11018 something appropriate. */
11019 if (num_saves == 1 && TARGET_ARM)
11020 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11021 else
11022 {
11023 int i;
11024 char pattern[100];
11025
11026 if (TARGET_32BIT)
11027 strcpy (pattern, \"push%?\\t{%1\");
11028 else
11029 strcpy (pattern, \"push\\t{%1\");
11030
11031 for (i = 1; i < num_saves; i++)
11032 {
11033 strcat (pattern, \", %|\");
11034 strcat (pattern,
11035 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11036 }
11037
11038 strcat (pattern, \"}\");
11039 output_asm_insn (pattern, operands);
11040 }
11041
11042 return \"\";
11043 }"
11044 [(set_attr "type" "store_16")
11045 (set (attr "length")
11046 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11047 )
11048
11049 (define_insn "stack_tie"
11050 [(set (mem:BLK (scratch))
11051 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11052 (match_operand:SI 1 "s_register_operand" "rk")]
11053 UNSPEC_PRLG_STK))]
11054 ""
11055 ""
11056 [(set_attr "length" "0")
11057 (set_attr "type" "block")]
11058 )
11059
11060 ;; Pop (as used in epilogue RTL)
11061 ;;
11062 (define_insn "*load_multiple_with_writeback"
11063 [(match_parallel 0 "load_multiple_operation"
11064 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11065 (plus:SI (match_dup 1)
11066 (match_operand:SI 2 "const_int_I_operand" "I")))
11067 (set (match_operand:SI 3 "s_register_operand" "=rk")
11068 (mem:SI (match_dup 1)))
11069 ])]
11070 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11071 "*
11072 {
11073 arm_output_multireg_pop (operands, /*return_pc=*/false,
11074 /*cond=*/const_true_rtx,
11075 /*reverse=*/false,
11076 /*update=*/true);
11077 return \"\";
11078 }
11079 "
11080 [(set_attr "type" "load_16")
11081 (set_attr "predicable" "yes")
11082 (set (attr "length")
11083 (symbol_ref "arm_attr_length_pop_multi (operands,
11084 /*return_pc=*/false,
11085 /*write_back_p=*/true)"))]
11086 )
11087
11088 ;; Pop with return (as used in epilogue RTL)
11089 ;;
11090 ;; This instruction is generated when the registers are popped at the end of
11091 ;; epilogue. Here, instead of popping the value into LR and then generating
11092 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11093 ;; with (return).
11094 (define_insn "*pop_multiple_with_writeback_and_return"
11095 [(match_parallel 0 "pop_multiple_return"
11096 [(return)
11097 (set (match_operand:SI 1 "s_register_operand" "+rk")
11098 (plus:SI (match_dup 1)
11099 (match_operand:SI 2 "const_int_I_operand" "I")))
11100 (set (match_operand:SI 3 "s_register_operand" "=rk")
11101 (mem:SI (match_dup 1)))
11102 ])]
11103 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11104 "*
11105 {
11106 arm_output_multireg_pop (operands, /*return_pc=*/true,
11107 /*cond=*/const_true_rtx,
11108 /*reverse=*/false,
11109 /*update=*/true);
11110 return \"\";
11111 }
11112 "
11113 [(set_attr "type" "load_16")
11114 (set_attr "predicable" "yes")
11115 (set (attr "length")
11116 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11117 /*write_back_p=*/true)"))]
11118 )
11119
11120 (define_insn "*pop_multiple_with_return"
11121 [(match_parallel 0 "pop_multiple_return"
11122 [(return)
11123 (set (match_operand:SI 2 "s_register_operand" "=rk")
11124 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11125 ])]
11126 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11127 "*
11128 {
11129 arm_output_multireg_pop (operands, /*return_pc=*/true,
11130 /*cond=*/const_true_rtx,
11131 /*reverse=*/false,
11132 /*update=*/false);
11133 return \"\";
11134 }
11135 "
11136 [(set_attr "type" "load_16")
11137 (set_attr "predicable" "yes")
11138 (set (attr "length")
11139 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11140 /*write_back_p=*/false)"))]
11141 )
11142
11143 ;; Load into PC and return
11144 (define_insn "*ldr_with_return"
11145 [(return)
11146 (set (reg:SI PC_REGNUM)
11147 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11148 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11149 "ldr%?\t%|pc, [%0], #4"
11150 [(set_attr "type" "load_4")
11151 (set_attr "predicable" "yes")]
11152 )
11153 ;; Pop for floating point registers (as used in epilogue RTL)
11154 (define_insn "*vfp_pop_multiple_with_writeback"
11155 [(match_parallel 0 "pop_multiple_fp"
11156 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11157 (plus:SI (match_dup 1)
11158 (match_operand:SI 2 "const_int_I_operand" "I")))
11159 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11160 (mem:DF (match_dup 1)))])]
11161 "TARGET_32BIT && TARGET_HARD_FLOAT"
11162 "*
11163 {
11164 int num_regs = XVECLEN (operands[0], 0);
11165 char pattern[100];
11166 rtx op_list[2];
11167 strcpy (pattern, \"vldm\\t\");
11168 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11169 strcat (pattern, \"!, {\");
11170 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11171 strcat (pattern, \"%P0\");
11172 if ((num_regs - 1) > 1)
11173 {
11174 strcat (pattern, \"-%P1\");
11175 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11176 }
11177
11178 strcat (pattern, \"}\");
11179 output_asm_insn (pattern, op_list);
11180 return \"\";
11181 }
11182 "
11183 [(set_attr "type" "load_16")
11184 (set_attr "conds" "unconditional")
11185 (set_attr "predicable" "no")]
11186 )
11187
11188 ;; Special patterns for dealing with the constant pool
11189
11190 (define_insn "align_4"
11191 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11192 "TARGET_EITHER"
11193 "*
11194 assemble_align (32);
11195 return \"\";
11196 "
11197 [(set_attr "type" "no_insn")]
11198 )
11199
11200 (define_insn "align_8"
11201 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11202 "TARGET_EITHER"
11203 "*
11204 assemble_align (64);
11205 return \"\";
11206 "
11207 [(set_attr "type" "no_insn")]
11208 )
11209
11210 (define_insn "consttable_end"
11211 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11212 "TARGET_EITHER"
11213 "*
11214 making_const_table = FALSE;
11215 return \"\";
11216 "
11217 [(set_attr "type" "no_insn")]
11218 )
11219
11220 (define_insn "consttable_1"
11221 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11222 "TARGET_EITHER"
11223 "*
11224 making_const_table = TRUE;
11225 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11226 assemble_zeros (3);
11227 return \"\";
11228 "
11229 [(set_attr "length" "4")
11230 (set_attr "type" "no_insn")]
11231 )
11232
11233 (define_insn "consttable_2"
11234 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11235 "TARGET_EITHER"
11236 "*
11237 {
11238 rtx x = operands[0];
11239 making_const_table = TRUE;
11240 switch (GET_MODE_CLASS (GET_MODE (x)))
11241 {
11242 case MODE_FLOAT:
11243 arm_emit_fp16_const (x);
11244 break;
11245 default:
11246 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11247 assemble_zeros (2);
11248 break;
11249 }
11250 return \"\";
11251 }"
11252 [(set_attr "length" "4")
11253 (set_attr "type" "no_insn")]
11254 )
11255
11256 (define_insn "consttable_4"
11257 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11258 "TARGET_EITHER"
11259 "*
11260 {
11261 rtx x = operands[0];
11262 making_const_table = TRUE;
11263 scalar_float_mode float_mode;
11264 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11265 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11266 else
11267 {
11268 /* XXX: Sometimes gcc does something really dumb and ends up with
11269 a HIGH in a constant pool entry, usually because it's trying to
11270 load into a VFP register. We know this will always be used in
11271 combination with a LO_SUM which ignores the high bits, so just
11272 strip off the HIGH. */
11273 if (GET_CODE (x) == HIGH)
11274 x = XEXP (x, 0);
11275 assemble_integer (x, 4, BITS_PER_WORD, 1);
11276 mark_symbol_refs_as_used (x);
11277 }
11278 return \"\";
11279 }"
11280 [(set_attr "length" "4")
11281 (set_attr "type" "no_insn")]
11282 )
11283
11284 (define_insn "consttable_8"
11285 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11286 "TARGET_EITHER"
11287 "*
11288 {
11289 making_const_table = TRUE;
11290 scalar_float_mode float_mode;
11291 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11292 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11293 float_mode, BITS_PER_WORD);
11294 else
11295 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11296 return \"\";
11297 }"
11298 [(set_attr "length" "8")
11299 (set_attr "type" "no_insn")]
11300 )
11301
11302 (define_insn "consttable_16"
11303 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11304 "TARGET_EITHER"
11305 "*
11306 {
11307 making_const_table = TRUE;
11308 scalar_float_mode float_mode;
11309 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11310 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11311 float_mode, BITS_PER_WORD);
11312 else
11313 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11314 return \"\";
11315 }"
11316 [(set_attr "length" "16")
11317 (set_attr "type" "no_insn")]
11318 )
11319
11320 ;; V5 Instructions,
11321
11322 (define_insn "clzsi2"
11323 [(set (match_operand:SI 0 "s_register_operand" "=r")
11324 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11325 "TARGET_32BIT && arm_arch5"
11326 "clz%?\\t%0, %1"
11327 [(set_attr "predicable" "yes")
11328 (set_attr "predicable_short_it" "no")
11329 (set_attr "type" "clz")])
11330
11331 (define_insn "rbitsi2"
11332 [(set (match_operand:SI 0 "s_register_operand" "=r")
11333 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11334 "TARGET_32BIT && arm_arch_thumb2"
11335 "rbit%?\\t%0, %1"
11336 [(set_attr "predicable" "yes")
11337 (set_attr "predicable_short_it" "no")
11338 (set_attr "type" "clz")])
11339
11340 ;; Keep this as a CTZ expression until after reload and then split
11341 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11342 ;; to fold with any other expression.
11343
11344 (define_insn_and_split "ctzsi2"
11345 [(set (match_operand:SI 0 "s_register_operand" "=r")
11346 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11347 "TARGET_32BIT && arm_arch_thumb2"
11348 "#"
11349 "&& reload_completed"
11350 [(const_int 0)]
11351 "
11352 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11353 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11354 DONE;
11355 ")
11356
11357 ;; V5E instructions.
11358
11359 (define_insn "prefetch"
11360 [(prefetch (match_operand:SI 0 "address_operand" "p")
11361 (match_operand:SI 1 "" "")
11362 (match_operand:SI 2 "" ""))]
11363 "TARGET_32BIT && arm_arch5e"
11364 "pld\\t%a0"
11365 [(set_attr "type" "load_4")]
11366 )
11367
11368 ;; General predication pattern
11369
11370 (define_cond_exec
11371 [(match_operator 0 "arm_comparison_operator"
11372 [(match_operand 1 "cc_register" "")
11373 (const_int 0)])]
11374 "TARGET_32BIT
11375 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11376 ""
11377 [(set_attr "predicated" "yes")]
11378 )
11379
11380 (define_insn "force_register_use"
11381 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11382 ""
11383 "%@ %0 needed"
11384 [(set_attr "length" "0")
11385 (set_attr "type" "no_insn")]
11386 )
11387
11388
11389 ;; Patterns for exception handling
11390
11391 (define_expand "eh_return"
11392 [(use (match_operand 0 "general_operand" ""))]
11393 "TARGET_EITHER"
11394 "
11395 {
11396 if (TARGET_32BIT)
11397 emit_insn (gen_arm_eh_return (operands[0]));
11398 else
11399 emit_insn (gen_thumb_eh_return (operands[0]));
11400 DONE;
11401 }"
11402 )
11403
11404 ;; We can't expand this before we know where the link register is stored.
11405 (define_insn_and_split "arm_eh_return"
11406 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11407 VUNSPEC_EH_RETURN)
11408 (clobber (match_scratch:SI 1 "=&r"))]
11409 "TARGET_ARM"
11410 "#"
11411 "&& reload_completed"
11412 [(const_int 0)]
11413 "
11414 {
11415 arm_set_return_address (operands[0], operands[1]);
11416 DONE;
11417 }"
11418 )
11419
11420 \f
11421 ;; TLS support
11422
11423 (define_insn "load_tp_hard"
11424 [(set (match_operand:SI 0 "register_operand" "=r")
11425 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11426 "TARGET_HARD_TP"
11427 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11428 [(set_attr "predicable" "yes")
11429 (set_attr "type" "mrs")]
11430 )
11431
11432 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11433 (define_insn "load_tp_soft"
11434 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11435 (clobber (reg:SI LR_REGNUM))
11436 (clobber (reg:SI IP_REGNUM))
11437 (clobber (reg:CC CC_REGNUM))]
11438 "TARGET_SOFT_TP"
11439 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11440 [(set_attr "conds" "clob")
11441 (set_attr "type" "branch")]
11442 )
11443
11444 ;; tls descriptor call
11445 (define_insn "tlscall"
11446 [(set (reg:SI R0_REGNUM)
11447 (unspec:SI [(reg:SI R0_REGNUM)
11448 (match_operand:SI 0 "" "X")
11449 (match_operand 1 "" "")] UNSPEC_TLS))
11450 (clobber (reg:SI R1_REGNUM))
11451 (clobber (reg:SI LR_REGNUM))
11452 (clobber (reg:SI CC_REGNUM))]
11453 "TARGET_GNU2_TLS"
11454 {
11455 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11456 INTVAL (operands[1]));
11457 return "bl\\t%c0(tlscall)";
11458 }
11459 [(set_attr "conds" "clob")
11460 (set_attr "length" "4")
11461 (set_attr "type" "branch")]
11462 )
11463
11464 ;; For thread pointer builtin
11465 (define_expand "get_thread_pointersi"
11466 [(match_operand:SI 0 "s_register_operand" "=r")]
11467 ""
11468 "
11469 {
11470 arm_load_tp (operands[0]);
11471 DONE;
11472 }")
11473
11474 ;;
11475
11476 ;; We only care about the lower 16 bits of the constant
11477 ;; being inserted into the upper 16 bits of the register.
11478 (define_insn "*arm_movtas_ze"
11479 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11480 (const_int 16)
11481 (const_int 16))
11482 (match_operand:SI 1 "const_int_operand" ""))]
11483 "TARGET_HAVE_MOVT"
11484 "@
11485 movt%?\t%0, %L1
11486 movt\t%0, %L1"
11487 [(set_attr "arch" "32,v8mb")
11488 (set_attr "predicable" "yes")
11489 (set_attr "predicable_short_it" "no")
11490 (set_attr "length" "4")
11491 (set_attr "type" "alu_sreg")]
11492 )
11493
11494 (define_insn "*arm_rev"
11495 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11496 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11497 "arm_arch6"
11498 "@
11499 rev\t%0, %1
11500 rev%?\t%0, %1
11501 rev%?\t%0, %1"
11502 [(set_attr "arch" "t1,t2,32")
11503 (set_attr "length" "2,2,4")
11504 (set_attr "predicable" "no,yes,yes")
11505 (set_attr "predicable_short_it" "no")
11506 (set_attr "type" "rev")]
11507 )
11508
11509 (define_expand "arm_legacy_rev"
11510 [(set (match_operand:SI 2 "s_register_operand" "")
11511 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11512 (const_int 16))
11513 (match_dup 1)))
11514 (set (match_dup 2)
11515 (lshiftrt:SI (match_dup 2)
11516 (const_int 8)))
11517 (set (match_operand:SI 3 "s_register_operand" "")
11518 (rotatert:SI (match_dup 1)
11519 (const_int 8)))
11520 (set (match_dup 2)
11521 (and:SI (match_dup 2)
11522 (const_int -65281)))
11523 (set (match_operand:SI 0 "s_register_operand" "")
11524 (xor:SI (match_dup 3)
11525 (match_dup 2)))]
11526 "TARGET_32BIT"
11527 ""
11528 )
11529
11530 ;; Reuse temporaries to keep register pressure down.
11531 (define_expand "thumb_legacy_rev"
11532 [(set (match_operand:SI 2 "s_register_operand" "")
11533 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11534 (const_int 24)))
11535 (set (match_operand:SI 3 "s_register_operand" "")
11536 (lshiftrt:SI (match_dup 1)
11537 (const_int 24)))
11538 (set (match_dup 3)
11539 (ior:SI (match_dup 3)
11540 (match_dup 2)))
11541 (set (match_operand:SI 4 "s_register_operand" "")
11542 (const_int 16))
11543 (set (match_operand:SI 5 "s_register_operand" "")
11544 (rotatert:SI (match_dup 1)
11545 (match_dup 4)))
11546 (set (match_dup 2)
11547 (ashift:SI (match_dup 5)
11548 (const_int 24)))
11549 (set (match_dup 5)
11550 (lshiftrt:SI (match_dup 5)
11551 (const_int 24)))
11552 (set (match_dup 5)
11553 (ior:SI (match_dup 5)
11554 (match_dup 2)))
11555 (set (match_dup 5)
11556 (rotatert:SI (match_dup 5)
11557 (match_dup 4)))
11558 (set (match_operand:SI 0 "s_register_operand" "")
11559 (ior:SI (match_dup 5)
11560 (match_dup 3)))]
11561 "TARGET_THUMB"
11562 ""
11563 )
11564
11565 ;; ARM-specific expansion of signed mod by power of 2
11566 ;; using conditional negate.
11567 ;; For r0 % n where n is a power of 2 produce:
11568 ;; rsbs r1, r0, #0
11569 ;; and r0, r0, #(n - 1)
11570 ;; and r1, r1, #(n - 1)
11571 ;; rsbpl r0, r1, #0
11572
11573 (define_expand "modsi3"
11574 [(match_operand:SI 0 "register_operand" "")
11575 (match_operand:SI 1 "register_operand" "")
11576 (match_operand:SI 2 "const_int_operand" "")]
11577 "TARGET_32BIT"
11578 {
11579 HOST_WIDE_INT val = INTVAL (operands[2]);
11580
11581 if (val <= 0
11582 || exact_log2 (val) <= 0)
11583 FAIL;
11584
11585 rtx mask = GEN_INT (val - 1);
11586
11587 /* In the special case of x0 % 2 we can do the even shorter:
11588 cmp r0, #0
11589 and r0, r0, #1
11590 rsblt r0, r0, #0. */
11591
11592 if (val == 2)
11593 {
11594 rtx cc_reg = arm_gen_compare_reg (LT,
11595 operands[1], const0_rtx, NULL_RTX);
11596 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11597 rtx masked = gen_reg_rtx (SImode);
11598
11599 emit_insn (gen_andsi3 (masked, operands[1], mask));
11600 emit_move_insn (operands[0],
11601 gen_rtx_IF_THEN_ELSE (SImode, cond,
11602 gen_rtx_NEG (SImode,
11603 masked),
11604 masked));
11605 DONE;
11606 }
11607
11608 rtx neg_op = gen_reg_rtx (SImode);
11609 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11610 operands[1]));
11611
11612 /* Extract the condition register and mode. */
11613 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11614 rtx cc_reg = SET_DEST (cmp);
11615 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11616
11617 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11618
11619 rtx masked_neg = gen_reg_rtx (SImode);
11620 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11621
11622 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11623 during expand does not always work. Do an IF_THEN_ELSE instead. */
11624 emit_move_insn (operands[0],
11625 gen_rtx_IF_THEN_ELSE (SImode, cond,
11626 gen_rtx_NEG (SImode, masked_neg),
11627 operands[0]));
11628
11629
11630 DONE;
11631 }
11632 )
11633
11634 (define_expand "bswapsi2"
11635 [(set (match_operand:SI 0 "s_register_operand" "=r")
11636 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11637 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11638 "
11639 if (!arm_arch6)
11640 {
11641 rtx op2 = gen_reg_rtx (SImode);
11642 rtx op3 = gen_reg_rtx (SImode);
11643
11644 if (TARGET_THUMB)
11645 {
11646 rtx op4 = gen_reg_rtx (SImode);
11647 rtx op5 = gen_reg_rtx (SImode);
11648
11649 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11650 op2, op3, op4, op5));
11651 }
11652 else
11653 {
11654 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11655 op2, op3));
11656 }
11657
11658 DONE;
11659 }
11660 "
11661 )
11662
11663 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11664 ;; and unsigned variants, respectively. For rev16, expose
11665 ;; byte-swapping in the lower 16 bits only.
11666 (define_insn "*arm_revsh"
11667 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11668 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11669 "arm_arch6"
11670 "@
11671 revsh\t%0, %1
11672 revsh%?\t%0, %1
11673 revsh%?\t%0, %1"
11674 [(set_attr "arch" "t1,t2,32")
11675 (set_attr "length" "2,2,4")
11676 (set_attr "type" "rev")]
11677 )
11678
11679 (define_insn "*arm_rev16"
11680 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11681 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11682 "arm_arch6"
11683 "@
11684 rev16\t%0, %1
11685 rev16%?\t%0, %1
11686 rev16%?\t%0, %1"
11687 [(set_attr "arch" "t1,t2,32")
11688 (set_attr "length" "2,2,4")
11689 (set_attr "type" "rev")]
11690 )
11691
11692 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11693 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11694 ;; each valid permutation.
11695
11696 (define_insn "arm_rev16si2"
11697 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11698 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11699 (const_int 8))
11700 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11701 (and:SI (lshiftrt:SI (match_dup 1)
11702 (const_int 8))
11703 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11704 "arm_arch6
11705 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11706 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11707 "rev16\\t%0, %1"
11708 [(set_attr "arch" "t1,t2,32")
11709 (set_attr "length" "2,2,4")
11710 (set_attr "type" "rev")]
11711 )
11712
11713 (define_insn "arm_rev16si2_alt"
11714 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11715 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11716 (const_int 8))
11717 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11718 (and:SI (ashift:SI (match_dup 1)
11719 (const_int 8))
11720 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11721 "arm_arch6
11722 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11723 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11724 "rev16\\t%0, %1"
11725 [(set_attr "arch" "t1,t2,32")
11726 (set_attr "length" "2,2,4")
11727 (set_attr "type" "rev")]
11728 )
11729
11730 (define_expand "bswaphi2"
11731 [(set (match_operand:HI 0 "s_register_operand" "=r")
11732 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11733 "arm_arch6"
11734 ""
11735 )
11736
11737 ;; Patterns for LDRD/STRD in Thumb2 mode
11738
11739 (define_insn "*thumb2_ldrd"
11740 [(set (match_operand:SI 0 "s_register_operand" "=r")
11741 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11742 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11743 (set (match_operand:SI 3 "s_register_operand" "=r")
11744 (mem:SI (plus:SI (match_dup 1)
11745 (match_operand:SI 4 "const_int_operand" ""))))]
11746 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11747 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11748 && (operands_ok_ldrd_strd (operands[0], operands[3],
11749 operands[1], INTVAL (operands[2]),
11750 false, true))"
11751 "ldrd%?\t%0, %3, [%1, %2]"
11752 [(set_attr "type" "load_8")
11753 (set_attr "predicable" "yes")
11754 (set_attr "predicable_short_it" "no")])
11755
11756 (define_insn "*thumb2_ldrd_base"
11757 [(set (match_operand:SI 0 "s_register_operand" "=r")
11758 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11759 (set (match_operand:SI 2 "s_register_operand" "=r")
11760 (mem:SI (plus:SI (match_dup 1)
11761 (const_int 4))))]
11762 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11763 && (operands_ok_ldrd_strd (operands[0], operands[2],
11764 operands[1], 0, false, true))"
11765 "ldrd%?\t%0, %2, [%1]"
11766 [(set_attr "type" "load_8")
11767 (set_attr "predicable" "yes")
11768 (set_attr "predicable_short_it" "no")])
11769
11770 (define_insn "*thumb2_ldrd_base_neg"
11771 [(set (match_operand:SI 0 "s_register_operand" "=r")
11772 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11773 (const_int -4))))
11774 (set (match_operand:SI 2 "s_register_operand" "=r")
11775 (mem:SI (match_dup 1)))]
11776 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11777 && (operands_ok_ldrd_strd (operands[0], operands[2],
11778 operands[1], -4, false, true))"
11779 "ldrd%?\t%0, %2, [%1, #-4]"
11780 [(set_attr "type" "load_8")
11781 (set_attr "predicable" "yes")
11782 (set_attr "predicable_short_it" "no")])
11783
11784 (define_insn "*thumb2_strd"
11785 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11786 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11787 (match_operand:SI 2 "s_register_operand" "r"))
11788 (set (mem:SI (plus:SI (match_dup 0)
11789 (match_operand:SI 3 "const_int_operand" "")))
11790 (match_operand:SI 4 "s_register_operand" "r"))]
11791 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11792 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11793 && (operands_ok_ldrd_strd (operands[2], operands[4],
11794 operands[0], INTVAL (operands[1]),
11795 false, false))"
11796 "strd%?\t%2, %4, [%0, %1]"
11797 [(set_attr "type" "store_8")
11798 (set_attr "predicable" "yes")
11799 (set_attr "predicable_short_it" "no")])
11800
11801 (define_insn "*thumb2_strd_base"
11802 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11803 (match_operand:SI 1 "s_register_operand" "r"))
11804 (set (mem:SI (plus:SI (match_dup 0)
11805 (const_int 4)))
11806 (match_operand:SI 2 "s_register_operand" "r"))]
11807 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11808 && (operands_ok_ldrd_strd (operands[1], operands[2],
11809 operands[0], 0, false, false))"
11810 "strd%?\t%1, %2, [%0]"
11811 [(set_attr "type" "store_8")
11812 (set_attr "predicable" "yes")
11813 (set_attr "predicable_short_it" "no")])
11814
11815 (define_insn "*thumb2_strd_base_neg"
11816 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11817 (const_int -4)))
11818 (match_operand:SI 1 "s_register_operand" "r"))
11819 (set (mem:SI (match_dup 0))
11820 (match_operand:SI 2 "s_register_operand" "r"))]
11821 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11822 && (operands_ok_ldrd_strd (operands[1], operands[2],
11823 operands[0], -4, false, false))"
11824 "strd%?\t%1, %2, [%0, #-4]"
11825 [(set_attr "type" "store_8")
11826 (set_attr "predicable" "yes")
11827 (set_attr "predicable_short_it" "no")])
11828
11829 ;; ARMv8 CRC32 instructions.
11830 (define_insn "<crc_variant>"
11831 [(set (match_operand:SI 0 "s_register_operand" "=r")
11832 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11833 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11834 CRC))]
11835 "TARGET_CRC32"
11836 "<crc_variant>\\t%0, %1, %2"
11837 [(set_attr "type" "crc")
11838 (set_attr "conds" "unconditional")]
11839 )
11840
11841 ;; Load the load/store double peephole optimizations.
11842 (include "ldrdstrd.md")
11843
11844 ;; Load the load/store multiple patterns
11845 (include "ldmstm.md")
11846
11847 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11848 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11849 ;; The operands are validated through the load_multiple_operation
11850 ;; match_parallel predicate rather than through constraints so enable it only
11851 ;; after reload.
11852 (define_insn "*load_multiple"
11853 [(match_parallel 0 "load_multiple_operation"
11854 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11855 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11856 ])]
11857 "TARGET_32BIT && reload_completed"
11858 "*
11859 {
11860 arm_output_multireg_pop (operands, /*return_pc=*/false,
11861 /*cond=*/const_true_rtx,
11862 /*reverse=*/false,
11863 /*update=*/false);
11864 return \"\";
11865 }
11866 "
11867 [(set_attr "predicable" "yes")]
11868 )
11869
11870 (define_expand "copysignsf3"
11871 [(match_operand:SF 0 "register_operand")
11872 (match_operand:SF 1 "register_operand")
11873 (match_operand:SF 2 "register_operand")]
11874 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11875 "{
11876 emit_move_insn (operands[0], operands[2]);
11877 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11878 GEN_INT (31), GEN_INT (0),
11879 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11880 DONE;
11881 }"
11882 )
11883
11884 (define_expand "copysigndf3"
11885 [(match_operand:DF 0 "register_operand")
11886 (match_operand:DF 1 "register_operand")
11887 (match_operand:DF 2 "register_operand")]
11888 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11889 "{
11890 rtx op0_low = gen_lowpart (SImode, operands[0]);
11891 rtx op0_high = gen_highpart (SImode, operands[0]);
11892 rtx op1_low = gen_lowpart (SImode, operands[1]);
11893 rtx op1_high = gen_highpart (SImode, operands[1]);
11894 rtx op2_high = gen_highpart (SImode, operands[2]);
11895
11896 rtx scratch1 = gen_reg_rtx (SImode);
11897 rtx scratch2 = gen_reg_rtx (SImode);
11898 emit_move_insn (scratch1, op2_high);
11899 emit_move_insn (scratch2, op1_high);
11900
11901 emit_insn(gen_rtx_SET(scratch1,
11902 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11903 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11904 emit_move_insn (op0_low, op1_low);
11905 emit_move_insn (op0_high, scratch2);
11906
11907 DONE;
11908 }"
11909 )
11910
11911 ;; movmisalign patterns for HImode and SImode.
11912 (define_expand "movmisalign<mode>"
11913 [(match_operand:HSI 0 "general_operand")
11914 (match_operand:HSI 1 "general_operand")]
11915 "unaligned_access"
11916 {
11917 /* This pattern is not permitted to fail during expansion: if both arguments
11918 are non-registers (e.g. memory := constant), force operand 1 into a
11919 register. */
11920 rtx (* gen_unaligned_load)(rtx, rtx);
11921 rtx tmp_dest = operands[0];
11922 if (!s_register_operand (operands[0], <MODE>mode)
11923 && !s_register_operand (operands[1], <MODE>mode))
11924 operands[1] = force_reg (<MODE>mode, operands[1]);
11925
11926 if (<MODE>mode == HImode)
11927 {
11928 gen_unaligned_load = gen_unaligned_loadhiu;
11929 tmp_dest = gen_reg_rtx (SImode);
11930 }
11931 else
11932 gen_unaligned_load = gen_unaligned_loadsi;
11933
11934 if (MEM_P (operands[1]))
11935 {
11936 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11937 if (<MODE>mode == HImode)
11938 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11939 }
11940 else
11941 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11942
11943 DONE;
11944 })
11945
11946 (define_insn "<cdp>"
11947 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11948 (match_operand:SI 1 "immediate_operand" "n")
11949 (match_operand:SI 2 "immediate_operand" "n")
11950 (match_operand:SI 3 "immediate_operand" "n")
11951 (match_operand:SI 4 "immediate_operand" "n")
11952 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11953 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11954 {
11955 arm_const_bounds (operands[0], 0, 16);
11956 arm_const_bounds (operands[1], 0, 16);
11957 arm_const_bounds (operands[2], 0, (1 << 5));
11958 arm_const_bounds (operands[3], 0, (1 << 5));
11959 arm_const_bounds (operands[4], 0, (1 << 5));
11960 arm_const_bounds (operands[5], 0, 8);
11961 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11962 }
11963 [(set_attr "length" "4")
11964 (set_attr "type" "coproc")])
11965
11966 (define_insn "*ldc"
11967 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11968 (match_operand:SI 1 "immediate_operand" "n")
11969 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11970 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11971 {
11972 arm_const_bounds (operands[0], 0, 16);
11973 arm_const_bounds (operands[1], 0, (1 << 5));
11974 return "<ldc>\\tp%c0, CR%c1, %2";
11975 }
11976 [(set_attr "length" "4")
11977 (set_attr "type" "coproc")])
11978
11979 (define_insn "*stc"
11980 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11981 (match_operand:SI 1 "immediate_operand" "n")
11982 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11983 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11984 {
11985 arm_const_bounds (operands[0], 0, 16);
11986 arm_const_bounds (operands[1], 0, (1 << 5));
11987 return "<stc>\\tp%c0, CR%c1, %2";
11988 }
11989 [(set_attr "length" "4")
11990 (set_attr "type" "coproc")])
11991
11992 (define_expand "<ldc>"
11993 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11994 (match_operand:SI 1 "immediate_operand")
11995 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11996 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11997
11998 (define_expand "<stc>"
11999 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12000 (match_operand:SI 1 "immediate_operand")
12001 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12002 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12003
12004 (define_insn "<mcr>"
12005 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12006 (match_operand:SI 1 "immediate_operand" "n")
12007 (match_operand:SI 2 "s_register_operand" "r")
12008 (match_operand:SI 3 "immediate_operand" "n")
12009 (match_operand:SI 4 "immediate_operand" "n")
12010 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12011 (use (match_dup 2))]
12012 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12013 {
12014 arm_const_bounds (operands[0], 0, 16);
12015 arm_const_bounds (operands[1], 0, 8);
12016 arm_const_bounds (operands[3], 0, (1 << 5));
12017 arm_const_bounds (operands[4], 0, (1 << 5));
12018 arm_const_bounds (operands[5], 0, 8);
12019 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12020 }
12021 [(set_attr "length" "4")
12022 (set_attr "type" "coproc")])
12023
12024 (define_insn "<mrc>"
12025 [(set (match_operand:SI 0 "s_register_operand" "=r")
12026 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12027 (match_operand:SI 2 "immediate_operand" "n")
12028 (match_operand:SI 3 "immediate_operand" "n")
12029 (match_operand:SI 4 "immediate_operand" "n")
12030 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12031 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12032 {
12033 arm_const_bounds (operands[1], 0, 16);
12034 arm_const_bounds (operands[2], 0, 8);
12035 arm_const_bounds (operands[3], 0, (1 << 5));
12036 arm_const_bounds (operands[4], 0, (1 << 5));
12037 arm_const_bounds (operands[5], 0, 8);
12038 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12039 }
12040 [(set_attr "length" "4")
12041 (set_attr "type" "coproc")])
12042
12043 (define_insn "<mcrr>"
12044 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12045 (match_operand:SI 1 "immediate_operand" "n")
12046 (match_operand:DI 2 "s_register_operand" "r")
12047 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12048 (use (match_dup 2))]
12049 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12050 {
12051 arm_const_bounds (operands[0], 0, 16);
12052 arm_const_bounds (operands[1], 0, 8);
12053 arm_const_bounds (operands[3], 0, (1 << 5));
12054 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12055 }
12056 [(set_attr "length" "4")
12057 (set_attr "type" "coproc")])
12058
12059 (define_insn "<mrrc>"
12060 [(set (match_operand:DI 0 "s_register_operand" "=r")
12061 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12062 (match_operand:SI 2 "immediate_operand" "n")
12063 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12064 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12065 {
12066 arm_const_bounds (operands[1], 0, 16);
12067 arm_const_bounds (operands[2], 0, 8);
12068 arm_const_bounds (operands[3], 0, (1 << 5));
12069 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12070 }
12071 [(set_attr "length" "4")
12072 (set_attr "type" "coproc")])
12073
12074 ;; Vector bits common to IWMMXT and Neon
12075 (include "vec-common.md")
12076 ;; Load the Intel Wireless Multimedia Extension patterns
12077 (include "iwmmxt.md")
12078 ;; Load the VFP co-processor patterns
12079 (include "vfp.md")
12080 ;; Thumb-1 patterns
12081 (include "thumb1.md")
12082 ;; Thumb-2 patterns
12083 (include "thumb2.md")
12084 ;; Neon patterns
12085 (include "neon.md")
12086 ;; Crypto patterns
12087 (include "crypto.md")
12088 ;; Synchronization Primitives
12089 (include "sync.md")
12090 ;; Fixed-point patterns
12091 (include "arm-fixed.md")