]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm.md
[Mechanical Patch ARM/AArch64 1/2] Rename load/store scheduling types to encode data...
[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 if (operands[2] == CONST1_RTX (SImode))
4063 {
4064 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
4065 DONE;
4066 }
4067
4068 /* Ideally we should use iwmmxt here if we could know that operands[1]
4069 ends up already living in an iwmmxt register. Otherwise it's
4070 cheaper to have the alternate code being generated than moving
4071 values to iwmmxt regs and back. */
4072
4073 /* Expand operation using core-registers.
4074 'FAIL' would achieve the same thing, but this is a bit smarter. */
4075 scratch1 = gen_reg_rtx (SImode);
4076 scratch2 = gen_reg_rtx (SImode);
4077 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4078 operands[2], scratch1, scratch2);
4079 DONE;
4080 }
4081 "
4082 )
4083
4084 (define_insn "arm_ashldi3_1bit"
4085 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4086 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4087 (const_int 1)))
4088 (clobber (reg:CC CC_REGNUM))]
4089 "TARGET_32BIT"
4090 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4091 [(set_attr "conds" "clob")
4092 (set_attr "length" "8")
4093 (set_attr "type" "multiple")]
4094 )
4095
4096 (define_expand "ashlsi3"
4097 [(set (match_operand:SI 0 "s_register_operand" "")
4098 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4099 (match_operand:SI 2 "arm_rhs_operand" "")))]
4100 "TARGET_EITHER"
4101 "
4102 if (CONST_INT_P (operands[2])
4103 && (UINTVAL (operands[2])) > 31)
4104 {
4105 emit_insn (gen_movsi (operands[0], const0_rtx));
4106 DONE;
4107 }
4108 "
4109 )
4110
4111 (define_expand "ashrdi3"
4112 [(set (match_operand:DI 0 "s_register_operand" "")
4113 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4114 (match_operand:SI 2 "reg_or_int_operand" "")))]
4115 "TARGET_32BIT"
4116 "
4117 if (TARGET_NEON)
4118 {
4119 /* Delay the decision whether to use NEON or core-regs until
4120 register allocation. */
4121 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4122 DONE;
4123 }
4124
4125 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4126 ; /* No special preparation statements; expand pattern as above. */
4127 else
4128 {
4129 rtx scratch1, scratch2;
4130
4131 if (operands[2] == CONST1_RTX (SImode))
4132 {
4133 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4134 DONE;
4135 }
4136
4137 /* Ideally we should use iwmmxt here if we could know that operands[1]
4138 ends up already living in an iwmmxt register. Otherwise it's
4139 cheaper to have the alternate code being generated than moving
4140 values to iwmmxt regs and back. */
4141
4142 /* Expand operation using core-registers.
4143 'FAIL' would achieve the same thing, but this is a bit smarter. */
4144 scratch1 = gen_reg_rtx (SImode);
4145 scratch2 = gen_reg_rtx (SImode);
4146 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4147 operands[2], scratch1, scratch2);
4148 DONE;
4149 }
4150 "
4151 )
4152
4153 (define_insn "arm_ashrdi3_1bit"
4154 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4155 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4156 (const_int 1)))
4157 (clobber (reg:CC CC_REGNUM))]
4158 "TARGET_32BIT"
4159 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4160 [(set_attr "conds" "clob")
4161 (set_attr "length" "8")
4162 (set_attr "type" "multiple")]
4163 )
4164
4165 (define_expand "ashrsi3"
4166 [(set (match_operand:SI 0 "s_register_operand" "")
4167 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4168 (match_operand:SI 2 "arm_rhs_operand" "")))]
4169 "TARGET_EITHER"
4170 "
4171 if (CONST_INT_P (operands[2])
4172 && UINTVAL (operands[2]) > 31)
4173 operands[2] = GEN_INT (31);
4174 "
4175 )
4176
4177 (define_expand "lshrdi3"
4178 [(set (match_operand:DI 0 "s_register_operand" "")
4179 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4180 (match_operand:SI 2 "reg_or_int_operand" "")))]
4181 "TARGET_32BIT"
4182 "
4183 if (TARGET_NEON)
4184 {
4185 /* Delay the decision whether to use NEON or core-regs until
4186 register allocation. */
4187 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4188 DONE;
4189 }
4190
4191 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4192 ; /* No special preparation statements; expand pattern as above. */
4193 else
4194 {
4195 rtx scratch1, scratch2;
4196
4197 if (operands[2] == CONST1_RTX (SImode))
4198 {
4199 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4200 DONE;
4201 }
4202
4203 /* Ideally we should use iwmmxt here if we could know that operands[1]
4204 ends up already living in an iwmmxt register. Otherwise it's
4205 cheaper to have the alternate code being generated than moving
4206 values to iwmmxt regs and back. */
4207
4208 /* Expand operation using core-registers.
4209 'FAIL' would achieve the same thing, but this is a bit smarter. */
4210 scratch1 = gen_reg_rtx (SImode);
4211 scratch2 = gen_reg_rtx (SImode);
4212 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4213 operands[2], scratch1, scratch2);
4214 DONE;
4215 }
4216 "
4217 )
4218
4219 (define_insn "arm_lshrdi3_1bit"
4220 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4221 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4222 (const_int 1)))
4223 (clobber (reg:CC CC_REGNUM))]
4224 "TARGET_32BIT"
4225 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4226 [(set_attr "conds" "clob")
4227 (set_attr "length" "8")
4228 (set_attr "type" "multiple")]
4229 )
4230
4231 (define_expand "lshrsi3"
4232 [(set (match_operand:SI 0 "s_register_operand" "")
4233 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4234 (match_operand:SI 2 "arm_rhs_operand" "")))]
4235 "TARGET_EITHER"
4236 "
4237 if (CONST_INT_P (operands[2])
4238 && (UINTVAL (operands[2])) > 31)
4239 {
4240 emit_insn (gen_movsi (operands[0], const0_rtx));
4241 DONE;
4242 }
4243 "
4244 )
4245
4246 (define_expand "rotlsi3"
4247 [(set (match_operand:SI 0 "s_register_operand" "")
4248 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4249 (match_operand:SI 2 "reg_or_int_operand" "")))]
4250 "TARGET_32BIT"
4251 "
4252 if (CONST_INT_P (operands[2]))
4253 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4254 else
4255 {
4256 rtx reg = gen_reg_rtx (SImode);
4257 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4258 operands[2] = reg;
4259 }
4260 "
4261 )
4262
4263 (define_expand "rotrsi3"
4264 [(set (match_operand:SI 0 "s_register_operand" "")
4265 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4266 (match_operand:SI 2 "arm_rhs_operand" "")))]
4267 "TARGET_EITHER"
4268 "
4269 if (TARGET_32BIT)
4270 {
4271 if (CONST_INT_P (operands[2])
4272 && UINTVAL (operands[2]) > 31)
4273 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4274 }
4275 else /* TARGET_THUMB1 */
4276 {
4277 if (CONST_INT_P (operands [2]))
4278 operands [2] = force_reg (SImode, operands[2]);
4279 }
4280 "
4281 )
4282
4283 (define_insn "*arm_shiftsi3"
4284 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4285 (match_operator:SI 3 "shift_operator"
4286 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4287 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4288 "TARGET_32BIT"
4289 "* return arm_output_shift(operands, 0);"
4290 [(set_attr "predicable" "yes")
4291 (set_attr "arch" "t2,t2,*,*")
4292 (set_attr "predicable_short_it" "yes,yes,no,no")
4293 (set_attr "length" "4")
4294 (set_attr "shift" "1")
4295 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4296 )
4297
4298 (define_insn "*shiftsi3_compare0"
4299 [(set (reg:CC_NOOV CC_REGNUM)
4300 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4301 [(match_operand:SI 1 "s_register_operand" "r,r")
4302 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4303 (const_int 0)))
4304 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4305 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4306 "TARGET_32BIT"
4307 "* return arm_output_shift(operands, 1);"
4308 [(set_attr "conds" "set")
4309 (set_attr "shift" "1")
4310 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4311 )
4312
4313 (define_insn "*shiftsi3_compare0_scratch"
4314 [(set (reg:CC_NOOV CC_REGNUM)
4315 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4316 [(match_operand:SI 1 "s_register_operand" "r,r")
4317 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4318 (const_int 0)))
4319 (clobber (match_scratch:SI 0 "=r,r"))]
4320 "TARGET_32BIT"
4321 "* return arm_output_shift(operands, 1);"
4322 [(set_attr "conds" "set")
4323 (set_attr "shift" "1")
4324 (set_attr "type" "shift_imm,shift_reg")]
4325 )
4326
4327 (define_insn "*not_shiftsi"
4328 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4329 (not:SI (match_operator:SI 3 "shift_operator"
4330 [(match_operand:SI 1 "s_register_operand" "r,r")
4331 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4332 "TARGET_32BIT"
4333 "mvn%?\\t%0, %1%S3"
4334 [(set_attr "predicable" "yes")
4335 (set_attr "predicable_short_it" "no")
4336 (set_attr "shift" "1")
4337 (set_attr "arch" "32,a")
4338 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4339
4340 (define_insn "*not_shiftsi_compare0"
4341 [(set (reg:CC_NOOV CC_REGNUM)
4342 (compare:CC_NOOV
4343 (not:SI (match_operator:SI 3 "shift_operator"
4344 [(match_operand:SI 1 "s_register_operand" "r,r")
4345 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4346 (const_int 0)))
4347 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4348 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4349 "TARGET_32BIT"
4350 "mvns%?\\t%0, %1%S3"
4351 [(set_attr "conds" "set")
4352 (set_attr "shift" "1")
4353 (set_attr "arch" "32,a")
4354 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4355
4356 (define_insn "*not_shiftsi_compare0_scratch"
4357 [(set (reg:CC_NOOV CC_REGNUM)
4358 (compare:CC_NOOV
4359 (not:SI (match_operator:SI 3 "shift_operator"
4360 [(match_operand:SI 1 "s_register_operand" "r,r")
4361 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4362 (const_int 0)))
4363 (clobber (match_scratch:SI 0 "=r,r"))]
4364 "TARGET_32BIT"
4365 "mvns%?\\t%0, %1%S3"
4366 [(set_attr "conds" "set")
4367 (set_attr "shift" "1")
4368 (set_attr "arch" "32,a")
4369 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4370
4371 ;; We don't really have extzv, but defining this using shifts helps
4372 ;; to reduce register pressure later on.
4373
4374 (define_expand "extzv"
4375 [(set (match_operand 0 "s_register_operand" "")
4376 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4377 (match_operand 2 "const_int_operand" "")
4378 (match_operand 3 "const_int_operand" "")))]
4379 "TARGET_THUMB1 || arm_arch_thumb2"
4380 "
4381 {
4382 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4383 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4384
4385 if (arm_arch_thumb2)
4386 {
4387 HOST_WIDE_INT width = INTVAL (operands[2]);
4388 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4389
4390 if (unaligned_access && MEM_P (operands[1])
4391 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4392 {
4393 rtx base_addr;
4394
4395 if (BYTES_BIG_ENDIAN)
4396 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4397 - bitpos;
4398
4399 if (width == 32)
4400 {
4401 base_addr = adjust_address (operands[1], SImode,
4402 bitpos / BITS_PER_UNIT);
4403 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4404 }
4405 else
4406 {
4407 rtx dest = operands[0];
4408 rtx tmp = gen_reg_rtx (SImode);
4409
4410 /* We may get a paradoxical subreg here. Strip it off. */
4411 if (GET_CODE (dest) == SUBREG
4412 && GET_MODE (dest) == SImode
4413 && GET_MODE (SUBREG_REG (dest)) == HImode)
4414 dest = SUBREG_REG (dest);
4415
4416 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4417 FAIL;
4418
4419 base_addr = adjust_address (operands[1], HImode,
4420 bitpos / BITS_PER_UNIT);
4421 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4422 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4423 }
4424 DONE;
4425 }
4426 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4427 {
4428 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4429 operands[3]));
4430 DONE;
4431 }
4432 else
4433 FAIL;
4434 }
4435
4436 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4437 FAIL;
4438
4439 operands[3] = GEN_INT (rshift);
4440
4441 if (lshift == 0)
4442 {
4443 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4444 DONE;
4445 }
4446
4447 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4448 operands[3], gen_reg_rtx (SImode)));
4449 DONE;
4450 }"
4451 )
4452
4453 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4454
4455 (define_expand "extzv_t1"
4456 [(set (match_operand:SI 4 "s_register_operand" "")
4457 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4458 (match_operand:SI 2 "const_int_operand" "")))
4459 (set (match_operand:SI 0 "s_register_operand" "")
4460 (lshiftrt:SI (match_dup 4)
4461 (match_operand:SI 3 "const_int_operand" "")))]
4462 "TARGET_THUMB1"
4463 "")
4464
4465 (define_expand "extv"
4466 [(set (match_operand 0 "s_register_operand" "")
4467 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4468 (match_operand 2 "const_int_operand" "")
4469 (match_operand 3 "const_int_operand" "")))]
4470 "arm_arch_thumb2"
4471 {
4472 HOST_WIDE_INT width = INTVAL (operands[2]);
4473 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4474
4475 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4476 && (bitpos % BITS_PER_UNIT) == 0)
4477 {
4478 rtx base_addr;
4479
4480 if (BYTES_BIG_ENDIAN)
4481 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4482
4483 if (width == 32)
4484 {
4485 base_addr = adjust_address (operands[1], SImode,
4486 bitpos / BITS_PER_UNIT);
4487 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4488 }
4489 else
4490 {
4491 rtx dest = operands[0];
4492 rtx tmp = gen_reg_rtx (SImode);
4493
4494 /* We may get a paradoxical subreg here. Strip it off. */
4495 if (GET_CODE (dest) == SUBREG
4496 && GET_MODE (dest) == SImode
4497 && GET_MODE (SUBREG_REG (dest)) == HImode)
4498 dest = SUBREG_REG (dest);
4499
4500 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4501 FAIL;
4502
4503 base_addr = adjust_address (operands[1], HImode,
4504 bitpos / BITS_PER_UNIT);
4505 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4506 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4507 }
4508
4509 DONE;
4510 }
4511 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4512 FAIL;
4513 else if (GET_MODE (operands[0]) == SImode
4514 && GET_MODE (operands[1]) == SImode)
4515 {
4516 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4517 operands[3]));
4518 DONE;
4519 }
4520
4521 FAIL;
4522 })
4523
4524 ; Helper to expand register forms of extv with the proper modes.
4525
4526 (define_expand "extv_regsi"
4527 [(set (match_operand:SI 0 "s_register_operand" "")
4528 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4529 (match_operand 2 "const_int_operand" "")
4530 (match_operand 3 "const_int_operand" "")))]
4531 ""
4532 {
4533 })
4534
4535 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4536
4537 (define_insn "unaligned_loadsi"
4538 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4539 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4540 UNSPEC_UNALIGNED_LOAD))]
4541 "unaligned_access"
4542 "ldr%?\t%0, %1\t@ unaligned"
4543 [(set_attr "arch" "t2,any")
4544 (set_attr "length" "2,4")
4545 (set_attr "predicable" "yes")
4546 (set_attr "predicable_short_it" "yes,no")
4547 (set_attr "type" "load_4")])
4548
4549 (define_insn "unaligned_loadhis"
4550 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4551 (sign_extend:SI
4552 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4553 UNSPEC_UNALIGNED_LOAD)))]
4554 "unaligned_access"
4555 "ldrsh%?\t%0, %1\t@ unaligned"
4556 [(set_attr "arch" "t2,any")
4557 (set_attr "length" "2,4")
4558 (set_attr "predicable" "yes")
4559 (set_attr "predicable_short_it" "yes,no")
4560 (set_attr "type" "load_byte")])
4561
4562 (define_insn "unaligned_loadhiu"
4563 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4564 (zero_extend:SI
4565 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4566 UNSPEC_UNALIGNED_LOAD)))]
4567 "unaligned_access"
4568 "ldrh%?\t%0, %1\t@ unaligned"
4569 [(set_attr "arch" "t2,any")
4570 (set_attr "length" "2,4")
4571 (set_attr "predicable" "yes")
4572 (set_attr "predicable_short_it" "yes,no")
4573 (set_attr "type" "load_byte")])
4574
4575 (define_insn "unaligned_storesi"
4576 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4577 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4578 UNSPEC_UNALIGNED_STORE))]
4579 "unaligned_access"
4580 "str%?\t%1, %0\t@ unaligned"
4581 [(set_attr "arch" "t2,any")
4582 (set_attr "length" "2,4")
4583 (set_attr "predicable" "yes")
4584 (set_attr "predicable_short_it" "yes,no")
4585 (set_attr "type" "store_4")])
4586
4587 (define_insn "unaligned_storehi"
4588 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4589 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4590 UNSPEC_UNALIGNED_STORE))]
4591 "unaligned_access"
4592 "strh%?\t%1, %0\t@ unaligned"
4593 [(set_attr "arch" "t2,any")
4594 (set_attr "length" "2,4")
4595 (set_attr "predicable" "yes")
4596 (set_attr "predicable_short_it" "yes,no")
4597 (set_attr "type" "store_4")])
4598
4599
4600 (define_insn "*extv_reg"
4601 [(set (match_operand:SI 0 "s_register_operand" "=r")
4602 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4603 (match_operand:SI 2 "const_int_operand" "n")
4604 (match_operand:SI 3 "const_int_operand" "n")))]
4605 "arm_arch_thumb2
4606 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4607 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4608 "sbfx%?\t%0, %1, %3, %2"
4609 [(set_attr "length" "4")
4610 (set_attr "predicable" "yes")
4611 (set_attr "predicable_short_it" "no")
4612 (set_attr "type" "bfm")]
4613 )
4614
4615 (define_insn "extzv_t2"
4616 [(set (match_operand:SI 0 "s_register_operand" "=r")
4617 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4618 (match_operand:SI 2 "const_int_operand" "n")
4619 (match_operand:SI 3 "const_int_operand" "n")))]
4620 "arm_arch_thumb2
4621 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4622 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4623 "ubfx%?\t%0, %1, %3, %2"
4624 [(set_attr "length" "4")
4625 (set_attr "predicable" "yes")
4626 (set_attr "predicable_short_it" "no")
4627 (set_attr "type" "bfm")]
4628 )
4629
4630
4631 ;; Division instructions
4632 (define_insn "divsi3"
4633 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4634 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4635 (match_operand:SI 2 "s_register_operand" "r,r")))]
4636 "TARGET_IDIV"
4637 "@
4638 sdiv%?\t%0, %1, %2
4639 sdiv\t%0, %1, %2"
4640 [(set_attr "arch" "32,v8mb")
4641 (set_attr "predicable" "yes")
4642 (set_attr "predicable_short_it" "no")
4643 (set_attr "type" "sdiv")]
4644 )
4645
4646 (define_insn "udivsi3"
4647 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4648 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4649 (match_operand:SI 2 "s_register_operand" "r,r")))]
4650 "TARGET_IDIV"
4651 "@
4652 udiv%?\t%0, %1, %2
4653 udiv\t%0, %1, %2"
4654 [(set_attr "arch" "32,v8mb")
4655 (set_attr "predicable" "yes")
4656 (set_attr "predicable_short_it" "no")
4657 (set_attr "type" "udiv")]
4658 )
4659
4660 \f
4661 ;; Unary arithmetic insns
4662
4663 (define_expand "negvsi3"
4664 [(match_operand:SI 0 "register_operand")
4665 (match_operand:SI 1 "register_operand")
4666 (match_operand 2 "")]
4667 "TARGET_32BIT"
4668 {
4669 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4670 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4671
4672 DONE;
4673 })
4674
4675 (define_expand "negvdi3"
4676 [(match_operand:DI 0 "register_operand")
4677 (match_operand:DI 1 "register_operand")
4678 (match_operand 2 "")]
4679 "TARGET_ARM"
4680 {
4681 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4682 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4683
4684 DONE;
4685 })
4686
4687
4688 (define_insn_and_split "negdi2_compare"
4689 [(set (reg:CC CC_REGNUM)
4690 (compare:CC
4691 (const_int 0)
4692 (match_operand:DI 1 "register_operand" "0,r")))
4693 (set (match_operand:DI 0 "register_operand" "=r,&r")
4694 (minus:DI (const_int 0) (match_dup 1)))]
4695 "TARGET_ARM"
4696 "#"
4697 "&& reload_completed"
4698 [(parallel [(set (reg:CC CC_REGNUM)
4699 (compare:CC (const_int 0) (match_dup 1)))
4700 (set (match_dup 0) (minus:SI (const_int 0)
4701 (match_dup 1)))])
4702 (parallel [(set (reg:CC CC_REGNUM)
4703 (compare:CC (const_int 0) (match_dup 3)))
4704 (set (match_dup 2)
4705 (minus:SI
4706 (minus:SI (const_int 0) (match_dup 3))
4707 (ltu:SI (reg:CC_C CC_REGNUM)
4708 (const_int 0))))])]
4709 {
4710 operands[2] = gen_highpart (SImode, operands[0]);
4711 operands[0] = gen_lowpart (SImode, operands[0]);
4712 operands[3] = gen_highpart (SImode, operands[1]);
4713 operands[1] = gen_lowpart (SImode, operands[1]);
4714 }
4715 [(set_attr "conds" "set")
4716 (set_attr "length" "8")
4717 (set_attr "type" "multiple")]
4718 )
4719
4720 (define_expand "negdi2"
4721 [(parallel
4722 [(set (match_operand:DI 0 "s_register_operand" "")
4723 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4724 (clobber (reg:CC CC_REGNUM))])]
4725 "TARGET_EITHER"
4726 {
4727 if (TARGET_NEON)
4728 {
4729 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4730 DONE;
4731 }
4732 }
4733 )
4734
4735 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4736 ;; The first alternative allows the common case of a *full* overlap.
4737 (define_insn_and_split "*negdi2_insn"
4738 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4739 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4740 (clobber (reg:CC CC_REGNUM))]
4741 "TARGET_32BIT"
4742 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4743 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4744 "&& reload_completed"
4745 [(parallel [(set (reg:CC CC_REGNUM)
4746 (compare:CC (const_int 0) (match_dup 1)))
4747 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4748 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4749 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4750 {
4751 operands[2] = gen_highpart (SImode, operands[0]);
4752 operands[0] = gen_lowpart (SImode, operands[0]);
4753 operands[3] = gen_highpart (SImode, operands[1]);
4754 operands[1] = gen_lowpart (SImode, operands[1]);
4755 }
4756 [(set_attr "conds" "clob")
4757 (set_attr "length" "8")
4758 (set_attr "type" "multiple")]
4759 )
4760
4761 (define_insn "*negsi2_carryin_compare"
4762 [(set (reg:CC CC_REGNUM)
4763 (compare:CC (const_int 0)
4764 (match_operand:SI 1 "s_register_operand" "r")))
4765 (set (match_operand:SI 0 "s_register_operand" "=r")
4766 (minus:SI (minus:SI (const_int 0)
4767 (match_dup 1))
4768 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4769 "TARGET_ARM"
4770 "rscs\\t%0, %1, #0"
4771 [(set_attr "conds" "set")
4772 (set_attr "type" "alus_imm")]
4773 )
4774
4775 (define_expand "negsi2"
4776 [(set (match_operand:SI 0 "s_register_operand" "")
4777 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4778 "TARGET_EITHER"
4779 ""
4780 )
4781
4782 (define_insn "*arm_negsi2"
4783 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4784 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4785 "TARGET_32BIT"
4786 "rsb%?\\t%0, %1, #0"
4787 [(set_attr "predicable" "yes")
4788 (set_attr "predicable_short_it" "yes,no")
4789 (set_attr "arch" "t2,*")
4790 (set_attr "length" "4")
4791 (set_attr "type" "alu_sreg")]
4792 )
4793
4794 (define_expand "negsf2"
4795 [(set (match_operand:SF 0 "s_register_operand" "")
4796 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4797 "TARGET_32BIT && TARGET_HARD_FLOAT"
4798 ""
4799 )
4800
4801 (define_expand "negdf2"
4802 [(set (match_operand:DF 0 "s_register_operand" "")
4803 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4804 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4805 "")
4806
4807 (define_insn_and_split "*zextendsidi_negsi"
4808 [(set (match_operand:DI 0 "s_register_operand" "=r")
4809 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4810 "TARGET_32BIT"
4811 "#"
4812 ""
4813 [(set (match_dup 2)
4814 (neg:SI (match_dup 1)))
4815 (set (match_dup 3)
4816 (const_int 0))]
4817 {
4818 operands[2] = gen_lowpart (SImode, operands[0]);
4819 operands[3] = gen_highpart (SImode, operands[0]);
4820 }
4821 [(set_attr "length" "8")
4822 (set_attr "type" "multiple")]
4823 )
4824
4825 ;; Negate an extended 32-bit value.
4826 (define_insn_and_split "*negdi_extendsidi"
4827 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4828 (neg:DI (sign_extend:DI
4829 (match_operand:SI 1 "s_register_operand" "l,r"))))
4830 (clobber (reg:CC CC_REGNUM))]
4831 "TARGET_32BIT"
4832 "#"
4833 "&& reload_completed"
4834 [(const_int 0)]
4835 {
4836 rtx low = gen_lowpart (SImode, operands[0]);
4837 rtx high = gen_highpart (SImode, operands[0]);
4838
4839 if (reg_overlap_mentioned_p (low, operands[1]))
4840 {
4841 /* Input overlaps the low word of the output. Use:
4842 asr Rhi, Rin, #31
4843 rsbs Rlo, Rin, #0
4844 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4845 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4846
4847 emit_insn (gen_rtx_SET (high,
4848 gen_rtx_ASHIFTRT (SImode, operands[1],
4849 GEN_INT (31))));
4850
4851 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4852 if (TARGET_ARM)
4853 emit_insn (gen_rtx_SET (high,
4854 gen_rtx_MINUS (SImode,
4855 gen_rtx_MINUS (SImode,
4856 const0_rtx,
4857 high),
4858 gen_rtx_LTU (SImode,
4859 cc_reg,
4860 const0_rtx))));
4861 else
4862 {
4863 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4864 emit_insn (gen_rtx_SET (high,
4865 gen_rtx_MINUS (SImode,
4866 gen_rtx_MINUS (SImode,
4867 high,
4868 two_x),
4869 gen_rtx_LTU (SImode,
4870 cc_reg,
4871 const0_rtx))));
4872 }
4873 }
4874 else
4875 {
4876 /* No overlap, or overlap on high word. Use:
4877 rsb Rlo, Rin, #0
4878 bic Rhi, Rlo, Rin
4879 asr Rhi, Rhi, #31
4880 Flags not needed for this sequence. */
4881 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4882 emit_insn (gen_rtx_SET (high,
4883 gen_rtx_AND (SImode,
4884 gen_rtx_NOT (SImode, operands[1]),
4885 low)));
4886 emit_insn (gen_rtx_SET (high,
4887 gen_rtx_ASHIFTRT (SImode, high,
4888 GEN_INT (31))));
4889 }
4890 DONE;
4891 }
4892 [(set_attr "length" "12")
4893 (set_attr "arch" "t2,*")
4894 (set_attr "type" "multiple")]
4895 )
4896
4897 (define_insn_and_split "*negdi_zero_extendsidi"
4898 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4899 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4900 (clobber (reg:CC CC_REGNUM))]
4901 "TARGET_32BIT"
4902 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4903 ;; Don't care what register is input to sbc,
4904 ;; since we just need to propagate the carry.
4905 "&& reload_completed"
4906 [(parallel [(set (reg:CC CC_REGNUM)
4907 (compare:CC (const_int 0) (match_dup 1)))
4908 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4909 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4910 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4911 {
4912 operands[2] = gen_highpart (SImode, operands[0]);
4913 operands[0] = gen_lowpart (SImode, operands[0]);
4914 }
4915 [(set_attr "conds" "clob")
4916 (set_attr "length" "8")
4917 (set_attr "type" "multiple")] ;; length in thumb is 4
4918 )
4919
4920 ;; abssi2 doesn't really clobber the condition codes if a different register
4921 ;; is being set. To keep things simple, assume during rtl manipulations that
4922 ;; it does, but tell the final scan operator the truth. Similarly for
4923 ;; (neg (abs...))
4924
4925 (define_expand "abssi2"
4926 [(parallel
4927 [(set (match_operand:SI 0 "s_register_operand" "")
4928 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4929 (clobber (match_dup 2))])]
4930 "TARGET_EITHER"
4931 "
4932 if (TARGET_THUMB1)
4933 operands[2] = gen_rtx_SCRATCH (SImode);
4934 else
4935 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4936 ")
4937
4938 (define_insn_and_split "*arm_abssi2"
4939 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4940 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4941 (clobber (reg:CC CC_REGNUM))]
4942 "TARGET_ARM"
4943 "#"
4944 "&& reload_completed"
4945 [(const_int 0)]
4946 {
4947 /* if (which_alternative == 0) */
4948 if (REGNO(operands[0]) == REGNO(operands[1]))
4949 {
4950 /* Emit the pattern:
4951 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4952 [(set (reg:CC CC_REGNUM)
4953 (compare:CC (match_dup 0) (const_int 0)))
4954 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4955 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4956 */
4957 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4958 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4959 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4960 (gen_rtx_LT (SImode,
4961 gen_rtx_REG (CCmode, CC_REGNUM),
4962 const0_rtx)),
4963 (gen_rtx_SET (operands[0],
4964 (gen_rtx_MINUS (SImode,
4965 const0_rtx,
4966 operands[1]))))));
4967 DONE;
4968 }
4969 else
4970 {
4971 /* Emit the pattern:
4972 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4973 [(set (match_dup 0)
4974 (xor:SI (match_dup 1)
4975 (ashiftrt:SI (match_dup 1) (const_int 31))))
4976 (set (match_dup 0)
4977 (minus:SI (match_dup 0)
4978 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4979 */
4980 emit_insn (gen_rtx_SET (operands[0],
4981 gen_rtx_XOR (SImode,
4982 gen_rtx_ASHIFTRT (SImode,
4983 operands[1],
4984 GEN_INT (31)),
4985 operands[1])));
4986 emit_insn (gen_rtx_SET (operands[0],
4987 gen_rtx_MINUS (SImode,
4988 operands[0],
4989 gen_rtx_ASHIFTRT (SImode,
4990 operands[1],
4991 GEN_INT (31)))));
4992 DONE;
4993 }
4994 }
4995 [(set_attr "conds" "clob,*")
4996 (set_attr "shift" "1")
4997 (set_attr "predicable" "no, yes")
4998 (set_attr "length" "8")
4999 (set_attr "type" "multiple")]
5000 )
5001
5002 (define_insn_and_split "*arm_neg_abssi2"
5003 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
5004 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
5005 (clobber (reg:CC CC_REGNUM))]
5006 "TARGET_ARM"
5007 "#"
5008 "&& reload_completed"
5009 [(const_int 0)]
5010 {
5011 /* if (which_alternative == 0) */
5012 if (REGNO (operands[0]) == REGNO (operands[1]))
5013 {
5014 /* Emit the pattern:
5015 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
5016 */
5017 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
5018 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
5019 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
5020 gen_rtx_GT (SImode,
5021 gen_rtx_REG (CCmode, CC_REGNUM),
5022 const0_rtx),
5023 gen_rtx_SET (operands[0],
5024 (gen_rtx_MINUS (SImode,
5025 const0_rtx,
5026 operands[1])))));
5027 }
5028 else
5029 {
5030 /* Emit the pattern:
5031 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
5032 */
5033 emit_insn (gen_rtx_SET (operands[0],
5034 gen_rtx_XOR (SImode,
5035 gen_rtx_ASHIFTRT (SImode,
5036 operands[1],
5037 GEN_INT (31)),
5038 operands[1])));
5039 emit_insn (gen_rtx_SET (operands[0],
5040 gen_rtx_MINUS (SImode,
5041 gen_rtx_ASHIFTRT (SImode,
5042 operands[1],
5043 GEN_INT (31)),
5044 operands[0])));
5045 }
5046 DONE;
5047 }
5048 [(set_attr "conds" "clob,*")
5049 (set_attr "shift" "1")
5050 (set_attr "predicable" "no, yes")
5051 (set_attr "length" "8")
5052 (set_attr "type" "multiple")]
5053 )
5054
5055 (define_expand "abssf2"
5056 [(set (match_operand:SF 0 "s_register_operand" "")
5057 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5058 "TARGET_32BIT && TARGET_HARD_FLOAT"
5059 "")
5060
5061 (define_expand "absdf2"
5062 [(set (match_operand:DF 0 "s_register_operand" "")
5063 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5064 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5065 "")
5066
5067 (define_expand "sqrtsf2"
5068 [(set (match_operand:SF 0 "s_register_operand" "")
5069 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5070 "TARGET_32BIT && TARGET_HARD_FLOAT"
5071 "")
5072
5073 (define_expand "sqrtdf2"
5074 [(set (match_operand:DF 0 "s_register_operand" "")
5075 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5076 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5077 "")
5078
5079 (define_expand "one_cmpldi2"
5080 [(set (match_operand:DI 0 "s_register_operand" "")
5081 (not:DI (match_operand:DI 1 "s_register_operand" "")))]
5082 "TARGET_32BIT"
5083 "
5084 if (!TARGET_NEON && !TARGET_IWMMXT)
5085 {
5086 rtx low = simplify_gen_unary (NOT, SImode,
5087 gen_lowpart (SImode, operands[1]),
5088 SImode);
5089 rtx high = simplify_gen_unary (NOT, SImode,
5090 gen_highpart_mode (SImode, DImode,
5091 operands[1]),
5092 SImode);
5093
5094 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low));
5095 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high));
5096
5097 DONE;
5098 }
5099 /* Otherwise expand pattern as above. */
5100 "
5101 )
5102
5103 (define_insn_and_split "*one_cmpldi2_insn"
5104 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5105 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5106 "TARGET_32BIT"
5107 "@
5108 vmvn\t%P0, %P1
5109 #
5110 #
5111 vmvn\t%P0, %P1"
5112 "TARGET_32BIT && reload_completed
5113 && arm_general_register_operand (operands[0], DImode)"
5114 [(set (match_dup 0) (not:SI (match_dup 1)))
5115 (set (match_dup 2) (not:SI (match_dup 3)))]
5116 "
5117 {
5118 operands[2] = gen_highpart (SImode, operands[0]);
5119 operands[0] = gen_lowpart (SImode, operands[0]);
5120 operands[3] = gen_highpart (SImode, operands[1]);
5121 operands[1] = gen_lowpart (SImode, operands[1]);
5122 }"
5123 [(set_attr "length" "*,8,8,*")
5124 (set_attr "predicable" "no,yes,yes,no")
5125 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5126 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5127 )
5128
5129 (define_expand "one_cmplsi2"
5130 [(set (match_operand:SI 0 "s_register_operand" "")
5131 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5132 "TARGET_EITHER"
5133 ""
5134 )
5135
5136 (define_insn "*arm_one_cmplsi2"
5137 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5138 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5139 "TARGET_32BIT"
5140 "mvn%?\\t%0, %1"
5141 [(set_attr "predicable" "yes")
5142 (set_attr "predicable_short_it" "yes,no")
5143 (set_attr "arch" "t2,*")
5144 (set_attr "length" "4")
5145 (set_attr "type" "mvn_reg")]
5146 )
5147
5148 (define_insn "*notsi_compare0"
5149 [(set (reg:CC_NOOV CC_REGNUM)
5150 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5151 (const_int 0)))
5152 (set (match_operand:SI 0 "s_register_operand" "=r")
5153 (not:SI (match_dup 1)))]
5154 "TARGET_32BIT"
5155 "mvns%?\\t%0, %1"
5156 [(set_attr "conds" "set")
5157 (set_attr "type" "mvn_reg")]
5158 )
5159
5160 (define_insn "*notsi_compare0_scratch"
5161 [(set (reg:CC_NOOV CC_REGNUM)
5162 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5163 (const_int 0)))
5164 (clobber (match_scratch:SI 0 "=r"))]
5165 "TARGET_32BIT"
5166 "mvns%?\\t%0, %1"
5167 [(set_attr "conds" "set")
5168 (set_attr "type" "mvn_reg")]
5169 )
5170 \f
5171 ;; Fixed <--> Floating conversion insns
5172
5173 (define_expand "floatsihf2"
5174 [(set (match_operand:HF 0 "general_operand" "")
5175 (float:HF (match_operand:SI 1 "general_operand" "")))]
5176 "TARGET_EITHER"
5177 "
5178 {
5179 rtx op1 = gen_reg_rtx (SFmode);
5180 expand_float (op1, operands[1], 0);
5181 op1 = convert_to_mode (HFmode, op1, 0);
5182 emit_move_insn (operands[0], op1);
5183 DONE;
5184 }"
5185 )
5186
5187 (define_expand "floatdihf2"
5188 [(set (match_operand:HF 0 "general_operand" "")
5189 (float:HF (match_operand:DI 1 "general_operand" "")))]
5190 "TARGET_EITHER"
5191 "
5192 {
5193 rtx op1 = gen_reg_rtx (SFmode);
5194 expand_float (op1, operands[1], 0);
5195 op1 = convert_to_mode (HFmode, op1, 0);
5196 emit_move_insn (operands[0], op1);
5197 DONE;
5198 }"
5199 )
5200
5201 (define_expand "floatsisf2"
5202 [(set (match_operand:SF 0 "s_register_operand" "")
5203 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5204 "TARGET_32BIT && TARGET_HARD_FLOAT"
5205 "
5206 ")
5207
5208 (define_expand "floatsidf2"
5209 [(set (match_operand:DF 0 "s_register_operand" "")
5210 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5211 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5212 "
5213 ")
5214
5215 (define_expand "fix_trunchfsi2"
5216 [(set (match_operand:SI 0 "general_operand" "")
5217 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5218 "TARGET_EITHER"
5219 "
5220 {
5221 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5222 expand_fix (operands[0], op1, 0);
5223 DONE;
5224 }"
5225 )
5226
5227 (define_expand "fix_trunchfdi2"
5228 [(set (match_operand:DI 0 "general_operand" "")
5229 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5230 "TARGET_EITHER"
5231 "
5232 {
5233 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5234 expand_fix (operands[0], op1, 0);
5235 DONE;
5236 }"
5237 )
5238
5239 (define_expand "fix_truncsfsi2"
5240 [(set (match_operand:SI 0 "s_register_operand" "")
5241 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5242 "TARGET_32BIT && TARGET_HARD_FLOAT"
5243 "
5244 ")
5245
5246 (define_expand "fix_truncdfsi2"
5247 [(set (match_operand:SI 0 "s_register_operand" "")
5248 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5249 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5250 "
5251 ")
5252
5253 ;; Truncation insns
5254
5255 (define_expand "truncdfsf2"
5256 [(set (match_operand:SF 0 "s_register_operand" "")
5257 (float_truncate:SF
5258 (match_operand:DF 1 "s_register_operand" "")))]
5259 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5260 ""
5261 )
5262
5263 ;; DFmode to HFmode conversions on targets without a single-step hardware
5264 ;; instruction for it would have to go through SFmode. This is dangerous
5265 ;; as it introduces double rounding.
5266 ;;
5267 ;; Disable this pattern unless we are in an unsafe math mode, or we have
5268 ;; a single-step instruction.
5269
5270 (define_expand "truncdfhf2"
5271 [(set (match_operand:HF 0 "s_register_operand" "")
5272 (float_truncate:HF
5273 (match_operand:DF 1 "s_register_operand" "")))]
5274 "(TARGET_EITHER && flag_unsafe_math_optimizations)
5275 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
5276 {
5277 /* We don't have a direct instruction for this, so we must be in
5278 an unsafe math mode, and going via SFmode. */
5279
5280 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5281 {
5282 rtx op1;
5283 op1 = convert_to_mode (SFmode, operands[1], 0);
5284 op1 = convert_to_mode (HFmode, op1, 0);
5285 emit_move_insn (operands[0], op1);
5286 DONE;
5287 }
5288 /* Otherwise, we will pick this up as a single instruction with
5289 no intermediary rounding. */
5290 }
5291 )
5292 \f
5293 ;; Zero and sign extension instructions.
5294
5295 (define_insn "zero_extend<mode>di2"
5296 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5297 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5298 "<qhs_zextenddi_cstr>")))]
5299 "TARGET_32BIT <qhs_zextenddi_cond>"
5300 "#"
5301 [(set_attr "length" "8,4,8,8")
5302 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5303 (set_attr "ce_count" "2")
5304 (set_attr "predicable" "yes")
5305 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5306 )
5307
5308 (define_insn "extend<mode>di2"
5309 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5310 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5311 "<qhs_extenddi_cstr>")))]
5312 "TARGET_32BIT <qhs_sextenddi_cond>"
5313 "#"
5314 [(set_attr "length" "8,4,8,8,8")
5315 (set_attr "ce_count" "2")
5316 (set_attr "shift" "1")
5317 (set_attr "predicable" "yes")
5318 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5319 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5320 )
5321
5322 ;; Splits for all extensions to DImode
5323 (define_split
5324 [(set (match_operand:DI 0 "s_register_operand" "")
5325 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5326 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5327 [(set (match_dup 0) (match_dup 1))]
5328 {
5329 rtx lo_part = gen_lowpart (SImode, operands[0]);
5330 machine_mode src_mode = GET_MODE (operands[1]);
5331
5332 if (REG_P (operands[0])
5333 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5334 emit_clobber (operands[0]);
5335 if (!REG_P (lo_part) || src_mode != SImode
5336 || !rtx_equal_p (lo_part, operands[1]))
5337 {
5338 if (src_mode == SImode)
5339 emit_move_insn (lo_part, operands[1]);
5340 else
5341 emit_insn (gen_rtx_SET (lo_part,
5342 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5343 operands[1] = lo_part;
5344 }
5345 operands[0] = gen_highpart (SImode, operands[0]);
5346 operands[1] = const0_rtx;
5347 })
5348
5349 (define_split
5350 [(set (match_operand:DI 0 "s_register_operand" "")
5351 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5352 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5353 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5354 {
5355 rtx lo_part = gen_lowpart (SImode, operands[0]);
5356 machine_mode src_mode = GET_MODE (operands[1]);
5357
5358 if (REG_P (operands[0])
5359 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5360 emit_clobber (operands[0]);
5361
5362 if (!REG_P (lo_part) || src_mode != SImode
5363 || !rtx_equal_p (lo_part, operands[1]))
5364 {
5365 if (src_mode == SImode)
5366 emit_move_insn (lo_part, operands[1]);
5367 else
5368 emit_insn (gen_rtx_SET (lo_part,
5369 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5370 operands[1] = lo_part;
5371 }
5372 operands[0] = gen_highpart (SImode, operands[0]);
5373 })
5374
5375 (define_expand "zero_extendhisi2"
5376 [(set (match_operand:SI 0 "s_register_operand" "")
5377 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5378 "TARGET_EITHER"
5379 {
5380 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5381 {
5382 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5383 DONE;
5384 }
5385 if (!arm_arch6 && !MEM_P (operands[1]))
5386 {
5387 rtx t = gen_lowpart (SImode, operands[1]);
5388 rtx tmp = gen_reg_rtx (SImode);
5389 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5390 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5391 DONE;
5392 }
5393 })
5394
5395 (define_split
5396 [(set (match_operand:SI 0 "s_register_operand" "")
5397 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5398 "!TARGET_THUMB2 && !arm_arch6"
5399 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5400 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5401 {
5402 operands[2] = gen_lowpart (SImode, operands[1]);
5403 })
5404
5405 (define_insn "*arm_zero_extendhisi2"
5406 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5407 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5408 "TARGET_ARM && arm_arch4 && !arm_arch6"
5409 "@
5410 #
5411 ldrh%?\\t%0, %1"
5412 [(set_attr "type" "alu_shift_reg,load_byte")
5413 (set_attr "predicable" "yes")]
5414 )
5415
5416 (define_insn "*arm_zero_extendhisi2_v6"
5417 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5418 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5419 "TARGET_ARM && arm_arch6"
5420 "@
5421 uxth%?\\t%0, %1
5422 ldrh%?\\t%0, %1"
5423 [(set_attr "predicable" "yes")
5424 (set_attr "type" "extend,load_byte")]
5425 )
5426
5427 (define_insn "*arm_zero_extendhisi2addsi"
5428 [(set (match_operand:SI 0 "s_register_operand" "=r")
5429 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5430 (match_operand:SI 2 "s_register_operand" "r")))]
5431 "TARGET_INT_SIMD"
5432 "uxtah%?\\t%0, %2, %1"
5433 [(set_attr "type" "alu_shift_reg")
5434 (set_attr "predicable" "yes")
5435 (set_attr "predicable_short_it" "no")]
5436 )
5437
5438 (define_expand "zero_extendqisi2"
5439 [(set (match_operand:SI 0 "s_register_operand" "")
5440 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5441 "TARGET_EITHER"
5442 {
5443 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5444 {
5445 emit_insn (gen_andsi3 (operands[0],
5446 gen_lowpart (SImode, operands[1]),
5447 GEN_INT (255)));
5448 DONE;
5449 }
5450 if (!arm_arch6 && !MEM_P (operands[1]))
5451 {
5452 rtx t = gen_lowpart (SImode, operands[1]);
5453 rtx tmp = gen_reg_rtx (SImode);
5454 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5455 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5456 DONE;
5457 }
5458 })
5459
5460 (define_split
5461 [(set (match_operand:SI 0 "s_register_operand" "")
5462 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5463 "!arm_arch6"
5464 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5465 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5466 {
5467 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5468 if (TARGET_ARM)
5469 {
5470 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5471 DONE;
5472 }
5473 })
5474
5475 (define_insn "*arm_zero_extendqisi2"
5476 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5477 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5478 "TARGET_ARM && !arm_arch6"
5479 "@
5480 #
5481 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5482 [(set_attr "length" "8,4")
5483 (set_attr "type" "alu_shift_reg,load_byte")
5484 (set_attr "predicable" "yes")]
5485 )
5486
5487 (define_insn "*arm_zero_extendqisi2_v6"
5488 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5489 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5490 "TARGET_ARM && arm_arch6"
5491 "@
5492 uxtb%?\\t%0, %1
5493 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5494 [(set_attr "type" "extend,load_byte")
5495 (set_attr "predicable" "yes")]
5496 )
5497
5498 (define_insn "*arm_zero_extendqisi2addsi"
5499 [(set (match_operand:SI 0 "s_register_operand" "=r")
5500 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5501 (match_operand:SI 2 "s_register_operand" "r")))]
5502 "TARGET_INT_SIMD"
5503 "uxtab%?\\t%0, %2, %1"
5504 [(set_attr "predicable" "yes")
5505 (set_attr "predicable_short_it" "no")
5506 (set_attr "type" "alu_shift_reg")]
5507 )
5508
5509 (define_split
5510 [(set (match_operand:SI 0 "s_register_operand" "")
5511 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5512 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5513 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5514 [(set (match_dup 2) (match_dup 1))
5515 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5516 ""
5517 )
5518
5519 (define_split
5520 [(set (match_operand:SI 0 "s_register_operand" "")
5521 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5522 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5523 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5524 [(set (match_dup 2) (match_dup 1))
5525 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5526 ""
5527 )
5528
5529
5530 (define_split
5531 [(set (match_operand:SI 0 "s_register_operand" "")
5532 (IOR_XOR:SI (and:SI (ashift:SI
5533 (match_operand:SI 1 "s_register_operand" "")
5534 (match_operand:SI 2 "const_int_operand" ""))
5535 (match_operand:SI 3 "const_int_operand" ""))
5536 (zero_extend:SI
5537 (match_operator 5 "subreg_lowpart_operator"
5538 [(match_operand:SI 4 "s_register_operand" "")]))))]
5539 "TARGET_32BIT
5540 && (UINTVAL (operands[3])
5541 == (GET_MODE_MASK (GET_MODE (operands[5]))
5542 & (GET_MODE_MASK (GET_MODE (operands[5]))
5543 << (INTVAL (operands[2])))))"
5544 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5545 (match_dup 4)))
5546 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5547 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5548 )
5549
5550 (define_insn "*compareqi_eq0"
5551 [(set (reg:CC_Z CC_REGNUM)
5552 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5553 (const_int 0)))]
5554 "TARGET_32BIT"
5555 "tst%?\\t%0, #255"
5556 [(set_attr "conds" "set")
5557 (set_attr "predicable" "yes")
5558 (set_attr "predicable_short_it" "no")
5559 (set_attr "type" "logic_imm")]
5560 )
5561
5562 (define_expand "extendhisi2"
5563 [(set (match_operand:SI 0 "s_register_operand" "")
5564 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5565 "TARGET_EITHER"
5566 {
5567 if (TARGET_THUMB1)
5568 {
5569 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5570 DONE;
5571 }
5572 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5573 {
5574 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5575 DONE;
5576 }
5577
5578 if (!arm_arch6 && !MEM_P (operands[1]))
5579 {
5580 rtx t = gen_lowpart (SImode, operands[1]);
5581 rtx tmp = gen_reg_rtx (SImode);
5582 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5583 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5584 DONE;
5585 }
5586 })
5587
5588 (define_split
5589 [(parallel
5590 [(set (match_operand:SI 0 "register_operand" "")
5591 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5592 (clobber (match_scratch:SI 2 ""))])]
5593 "!arm_arch6"
5594 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5595 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5596 {
5597 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5598 })
5599
5600 ;; This pattern will only be used when ldsh is not available
5601 (define_expand "extendhisi2_mem"
5602 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5603 (set (match_dup 3)
5604 (zero_extend:SI (match_dup 7)))
5605 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5606 (set (match_operand:SI 0 "" "")
5607 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5608 "TARGET_ARM"
5609 "
5610 {
5611 rtx mem1, mem2;
5612 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5613
5614 mem1 = change_address (operands[1], QImode, addr);
5615 mem2 = change_address (operands[1], QImode,
5616 plus_constant (Pmode, addr, 1));
5617 operands[0] = gen_lowpart (SImode, operands[0]);
5618 operands[1] = mem1;
5619 operands[2] = gen_reg_rtx (SImode);
5620 operands[3] = gen_reg_rtx (SImode);
5621 operands[6] = gen_reg_rtx (SImode);
5622 operands[7] = mem2;
5623
5624 if (BYTES_BIG_ENDIAN)
5625 {
5626 operands[4] = operands[2];
5627 operands[5] = operands[3];
5628 }
5629 else
5630 {
5631 operands[4] = operands[3];
5632 operands[5] = operands[2];
5633 }
5634 }"
5635 )
5636
5637 (define_split
5638 [(set (match_operand:SI 0 "register_operand" "")
5639 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5640 "!arm_arch6"
5641 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5642 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5643 {
5644 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5645 })
5646
5647 (define_insn "*arm_extendhisi2"
5648 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5649 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5650 "TARGET_ARM && arm_arch4 && !arm_arch6"
5651 "@
5652 #
5653 ldrsh%?\\t%0, %1"
5654 [(set_attr "length" "8,4")
5655 (set_attr "type" "alu_shift_reg,load_byte")
5656 (set_attr "predicable" "yes")]
5657 )
5658
5659 ;; ??? Check Thumb-2 pool range
5660 (define_insn "*arm_extendhisi2_v6"
5661 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5662 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5663 "TARGET_32BIT && arm_arch6"
5664 "@
5665 sxth%?\\t%0, %1
5666 ldrsh%?\\t%0, %1"
5667 [(set_attr "type" "extend,load_byte")
5668 (set_attr "predicable" "yes")
5669 (set_attr "predicable_short_it" "no")]
5670 )
5671
5672 (define_insn "*arm_extendhisi2addsi"
5673 [(set (match_operand:SI 0 "s_register_operand" "=r")
5674 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5675 (match_operand:SI 2 "s_register_operand" "r")))]
5676 "TARGET_INT_SIMD"
5677 "sxtah%?\\t%0, %2, %1"
5678 [(set_attr "type" "alu_shift_reg")]
5679 )
5680
5681 (define_expand "extendqihi2"
5682 [(set (match_dup 2)
5683 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5684 (const_int 24)))
5685 (set (match_operand:HI 0 "s_register_operand" "")
5686 (ashiftrt:SI (match_dup 2)
5687 (const_int 24)))]
5688 "TARGET_ARM"
5689 "
5690 {
5691 if (arm_arch4 && MEM_P (operands[1]))
5692 {
5693 emit_insn (gen_rtx_SET (operands[0],
5694 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5695 DONE;
5696 }
5697 if (!s_register_operand (operands[1], QImode))
5698 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5699 operands[0] = gen_lowpart (SImode, operands[0]);
5700 operands[1] = gen_lowpart (SImode, operands[1]);
5701 operands[2] = gen_reg_rtx (SImode);
5702 }"
5703 )
5704
5705 (define_insn "*arm_extendqihi_insn"
5706 [(set (match_operand:HI 0 "s_register_operand" "=r")
5707 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5708 "TARGET_ARM && arm_arch4"
5709 "ldrsb%?\\t%0, %1"
5710 [(set_attr "type" "load_byte")
5711 (set_attr "predicable" "yes")]
5712 )
5713
5714 (define_expand "extendqisi2"
5715 [(set (match_operand:SI 0 "s_register_operand" "")
5716 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5717 "TARGET_EITHER"
5718 {
5719 if (!arm_arch4 && MEM_P (operands[1]))
5720 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5721
5722 if (!arm_arch6 && !MEM_P (operands[1]))
5723 {
5724 rtx t = gen_lowpart (SImode, operands[1]);
5725 rtx tmp = gen_reg_rtx (SImode);
5726 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5727 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5728 DONE;
5729 }
5730 })
5731
5732 (define_split
5733 [(set (match_operand:SI 0 "register_operand" "")
5734 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5735 "!arm_arch6"
5736 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5737 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5738 {
5739 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5740 })
5741
5742 (define_insn "*arm_extendqisi"
5743 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5744 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5745 "TARGET_ARM && arm_arch4 && !arm_arch6"
5746 "@
5747 #
5748 ldrsb%?\\t%0, %1"
5749 [(set_attr "length" "8,4")
5750 (set_attr "type" "alu_shift_reg,load_byte")
5751 (set_attr "predicable" "yes")]
5752 )
5753
5754 (define_insn "*arm_extendqisi_v6"
5755 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5756 (sign_extend:SI
5757 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5758 "TARGET_ARM && arm_arch6"
5759 "@
5760 sxtb%?\\t%0, %1
5761 ldrsb%?\\t%0, %1"
5762 [(set_attr "type" "extend,load_byte")
5763 (set_attr "predicable" "yes")]
5764 )
5765
5766 (define_insn "*arm_extendqisi2addsi"
5767 [(set (match_operand:SI 0 "s_register_operand" "=r")
5768 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5769 (match_operand:SI 2 "s_register_operand" "r")))]
5770 "TARGET_INT_SIMD"
5771 "sxtab%?\\t%0, %2, %1"
5772 [(set_attr "type" "alu_shift_reg")
5773 (set_attr "predicable" "yes")
5774 (set_attr "predicable_short_it" "no")]
5775 )
5776
5777 (define_expand "extendsfdf2"
5778 [(set (match_operand:DF 0 "s_register_operand" "")
5779 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5780 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5781 ""
5782 )
5783
5784 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5785 ;; must go through SFmode.
5786 ;;
5787 ;; This is always safe for an extend.
5788
5789 (define_expand "extendhfdf2"
5790 [(set (match_operand:DF 0 "s_register_operand" "")
5791 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))]
5792 "TARGET_EITHER"
5793 {
5794 /* We don't have a direct instruction for this, so go via SFmode. */
5795 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5796 {
5797 rtx op1;
5798 op1 = convert_to_mode (SFmode, operands[1], 0);
5799 op1 = convert_to_mode (DFmode, op1, 0);
5800 emit_insn (gen_movdf (operands[0], op1));
5801 DONE;
5802 }
5803 /* Otherwise, we're done producing RTL and will pick up the correct
5804 pattern to do this with one rounding-step in a single instruction. */
5805 }
5806 )
5807 \f
5808 ;; Move insns (including loads and stores)
5809
5810 ;; XXX Just some ideas about movti.
5811 ;; I don't think these are a good idea on the arm, there just aren't enough
5812 ;; registers
5813 ;;(define_expand "loadti"
5814 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5815 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5816 ;; "" "")
5817
5818 ;;(define_expand "storeti"
5819 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5820 ;; (match_operand:TI 1 "s_register_operand" ""))]
5821 ;; "" "")
5822
5823 ;;(define_expand "movti"
5824 ;; [(set (match_operand:TI 0 "general_operand" "")
5825 ;; (match_operand:TI 1 "general_operand" ""))]
5826 ;; ""
5827 ;; "
5828 ;;{
5829 ;; rtx insn;
5830 ;;
5831 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5832 ;; operands[1] = copy_to_reg (operands[1]);
5833 ;; if (MEM_P (operands[0]))
5834 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5835 ;; else if (MEM_P (operands[1]))
5836 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5837 ;; else
5838 ;; FAIL;
5839 ;;
5840 ;; emit_insn (insn);
5841 ;; DONE;
5842 ;;}")
5843
5844 ;; Recognize garbage generated above.
5845
5846 ;;(define_insn ""
5847 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5848 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5849 ;; ""
5850 ;; "*
5851 ;; {
5852 ;; register mem = (which_alternative < 3);
5853 ;; register const char *template;
5854 ;;
5855 ;; operands[mem] = XEXP (operands[mem], 0);
5856 ;; switch (which_alternative)
5857 ;; {
5858 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5859 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5860 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5861 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5862 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5863 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5864 ;; }
5865 ;; output_asm_insn (template, operands);
5866 ;; return \"\";
5867 ;; }")
5868
5869 (define_expand "movdi"
5870 [(set (match_operand:DI 0 "general_operand" "")
5871 (match_operand:DI 1 "general_operand" ""))]
5872 "TARGET_EITHER"
5873 "
5874 if (can_create_pseudo_p ())
5875 {
5876 if (!REG_P (operands[0]))
5877 operands[1] = force_reg (DImode, operands[1]);
5878 }
5879 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5880 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5881 {
5882 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5883 when expanding function calls. */
5884 gcc_assert (can_create_pseudo_p ());
5885 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5886 {
5887 /* Perform load into legal reg pair first, then move. */
5888 rtx reg = gen_reg_rtx (DImode);
5889 emit_insn (gen_movdi (reg, operands[1]));
5890 operands[1] = reg;
5891 }
5892 emit_move_insn (gen_lowpart (SImode, operands[0]),
5893 gen_lowpart (SImode, operands[1]));
5894 emit_move_insn (gen_highpart (SImode, operands[0]),
5895 gen_highpart (SImode, operands[1]));
5896 DONE;
5897 }
5898 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5899 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5900 {
5901 /* Avoid STRD's from an odd-numbered register pair in ARM state
5902 when expanding function prologue. */
5903 gcc_assert (can_create_pseudo_p ());
5904 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5905 ? gen_reg_rtx (DImode)
5906 : operands[0];
5907 emit_move_insn (gen_lowpart (SImode, split_dest),
5908 gen_lowpart (SImode, operands[1]));
5909 emit_move_insn (gen_highpart (SImode, split_dest),
5910 gen_highpart (SImode, operands[1]));
5911 if (split_dest != operands[0])
5912 emit_insn (gen_movdi (operands[0], split_dest));
5913 DONE;
5914 }
5915 "
5916 )
5917
5918 (define_insn "*arm_movdi"
5919 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5920 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5921 "TARGET_32BIT
5922 && !(TARGET_HARD_FLOAT)
5923 && !TARGET_IWMMXT
5924 && ( register_operand (operands[0], DImode)
5925 || register_operand (operands[1], DImode))"
5926 "*
5927 switch (which_alternative)
5928 {
5929 case 0:
5930 case 1:
5931 case 2:
5932 return \"#\";
5933 default:
5934 return output_move_double (operands, true, NULL);
5935 }
5936 "
5937 [(set_attr "length" "8,12,16,8,8")
5938 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5939 (set_attr "arm_pool_range" "*,*,*,1020,*")
5940 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5941 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5942 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5943 )
5944
5945 (define_split
5946 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5947 (match_operand:ANY64 1 "immediate_operand" ""))]
5948 "TARGET_32BIT
5949 && reload_completed
5950 && (arm_disable_literal_pool
5951 || (arm_const_double_inline_cost (operands[1])
5952 <= arm_max_const_double_inline_cost ()))"
5953 [(const_int 0)]
5954 "
5955 arm_split_constant (SET, SImode, curr_insn,
5956 INTVAL (gen_lowpart (SImode, operands[1])),
5957 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5958 arm_split_constant (SET, SImode, curr_insn,
5959 INTVAL (gen_highpart_mode (SImode,
5960 GET_MODE (operands[0]),
5961 operands[1])),
5962 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5963 DONE;
5964 "
5965 )
5966
5967 ; If optimizing for size, or if we have load delay slots, then
5968 ; we want to split the constant into two separate operations.
5969 ; In both cases this may split a trivial part into a single data op
5970 ; leaving a single complex constant to load. We can also get longer
5971 ; offsets in a LDR which means we get better chances of sharing the pool
5972 ; entries. Finally, we can normally do a better job of scheduling
5973 ; LDR instructions than we can with LDM.
5974 ; This pattern will only match if the one above did not.
5975 (define_split
5976 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5977 (match_operand:ANY64 1 "const_double_operand" ""))]
5978 "TARGET_ARM && reload_completed
5979 && arm_const_double_by_parts (operands[1])"
5980 [(set (match_dup 0) (match_dup 1))
5981 (set (match_dup 2) (match_dup 3))]
5982 "
5983 operands[2] = gen_highpart (SImode, operands[0]);
5984 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5985 operands[1]);
5986 operands[0] = gen_lowpart (SImode, operands[0]);
5987 operands[1] = gen_lowpart (SImode, operands[1]);
5988 "
5989 )
5990
5991 (define_split
5992 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5993 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5994 "TARGET_EITHER && reload_completed"
5995 [(set (match_dup 0) (match_dup 1))
5996 (set (match_dup 2) (match_dup 3))]
5997 "
5998 operands[2] = gen_highpart (SImode, operands[0]);
5999 operands[3] = gen_highpart (SImode, operands[1]);
6000 operands[0] = gen_lowpart (SImode, operands[0]);
6001 operands[1] = gen_lowpart (SImode, operands[1]);
6002
6003 /* Handle a partial overlap. */
6004 if (rtx_equal_p (operands[0], operands[3]))
6005 {
6006 rtx tmp0 = operands[0];
6007 rtx tmp1 = operands[1];
6008
6009 operands[0] = operands[2];
6010 operands[1] = operands[3];
6011 operands[2] = tmp0;
6012 operands[3] = tmp1;
6013 }
6014 "
6015 )
6016
6017 ;; We can't actually do base+index doubleword loads if the index and
6018 ;; destination overlap. Split here so that we at least have chance to
6019 ;; schedule.
6020 (define_split
6021 [(set (match_operand:DI 0 "s_register_operand" "")
6022 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
6023 (match_operand:SI 2 "s_register_operand" ""))))]
6024 "TARGET_LDRD
6025 && reg_overlap_mentioned_p (operands[0], operands[1])
6026 && reg_overlap_mentioned_p (operands[0], operands[2])"
6027 [(set (match_dup 4)
6028 (plus:SI (match_dup 1)
6029 (match_dup 2)))
6030 (set (match_dup 0)
6031 (mem:DI (match_dup 4)))]
6032 "
6033 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
6034 "
6035 )
6036
6037 (define_expand "movsi"
6038 [(set (match_operand:SI 0 "general_operand" "")
6039 (match_operand:SI 1 "general_operand" ""))]
6040 "TARGET_EITHER"
6041 "
6042 {
6043 rtx base, offset, tmp;
6044
6045 if (TARGET_32BIT || TARGET_HAVE_MOVT)
6046 {
6047 /* Everything except mem = const or mem = mem can be done easily. */
6048 if (MEM_P (operands[0]))
6049 operands[1] = force_reg (SImode, operands[1]);
6050 if (arm_general_register_operand (operands[0], SImode)
6051 && CONST_INT_P (operands[1])
6052 && !(const_ok_for_arm (INTVAL (operands[1]))
6053 || const_ok_for_arm (~INTVAL (operands[1]))))
6054 {
6055 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
6056 {
6057 emit_insn (gen_rtx_SET (operands[0], operands[1]));
6058 DONE;
6059 }
6060 else
6061 {
6062 arm_split_constant (SET, SImode, NULL_RTX,
6063 INTVAL (operands[1]), operands[0], NULL_RTX,
6064 optimize && can_create_pseudo_p ());
6065 DONE;
6066 }
6067 }
6068 }
6069 else /* Target doesn't have MOVT... */
6070 {
6071 if (can_create_pseudo_p ())
6072 {
6073 if (!REG_P (operands[0]))
6074 operands[1] = force_reg (SImode, operands[1]);
6075 }
6076 }
6077
6078 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
6079 {
6080 split_const (operands[1], &base, &offset);
6081 if (GET_CODE (base) == SYMBOL_REF
6082 && !offset_within_block_p (base, INTVAL (offset)))
6083 {
6084 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
6085 emit_move_insn (tmp, base);
6086 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6087 DONE;
6088 }
6089 }
6090
6091 /* Recognize the case where operand[1] is a reference to thread-local
6092 data and load its address to a register. */
6093 if (arm_tls_referenced_p (operands[1]))
6094 {
6095 rtx tmp = operands[1];
6096 rtx addend = NULL;
6097
6098 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6099 {
6100 addend = XEXP (XEXP (tmp, 0), 1);
6101 tmp = XEXP (XEXP (tmp, 0), 0);
6102 }
6103
6104 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6105 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6106
6107 tmp = legitimize_tls_address (tmp,
6108 !can_create_pseudo_p () ? operands[0] : 0);
6109 if (addend)
6110 {
6111 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6112 tmp = force_operand (tmp, operands[0]);
6113 }
6114 operands[1] = tmp;
6115 }
6116 else if (flag_pic
6117 && (CONSTANT_P (operands[1])
6118 || symbol_mentioned_p (operands[1])
6119 || label_mentioned_p (operands[1])))
6120 operands[1] = legitimize_pic_address (operands[1], SImode,
6121 (!can_create_pseudo_p ()
6122 ? operands[0]
6123 : 0));
6124 }
6125 "
6126 )
6127
6128 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6129 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6130 ;; so this does not matter.
6131 (define_insn "*arm_movt"
6132 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6133 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6134 (match_operand:SI 2 "general_operand" "i,i")))]
6135 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6136 "@
6137 movt%?\t%0, #:upper16:%c2
6138 movt\t%0, #:upper16:%c2"
6139 [(set_attr "arch" "32,v8mb")
6140 (set_attr "predicable" "yes")
6141 (set_attr "predicable_short_it" "no")
6142 (set_attr "length" "4")
6143 (set_attr "type" "alu_sreg")]
6144 )
6145
6146 (define_insn "*arm_movsi_insn"
6147 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6148 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6149 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6150 && ( register_operand (operands[0], SImode)
6151 || register_operand (operands[1], SImode))"
6152 "@
6153 mov%?\\t%0, %1
6154 mov%?\\t%0, %1
6155 mvn%?\\t%0, #%B1
6156 movw%?\\t%0, %1
6157 ldr%?\\t%0, %1
6158 str%?\\t%1, %0"
6159 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
6160 (set_attr "predicable" "yes")
6161 (set_attr "arch" "*,*,*,v6t2,*,*")
6162 (set_attr "pool_range" "*,*,*,*,4096,*")
6163 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6164 )
6165
6166 (define_split
6167 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6168 (match_operand:SI 1 "const_int_operand" ""))]
6169 "(TARGET_32BIT || TARGET_HAVE_MOVT)
6170 && (!(const_ok_for_arm (INTVAL (operands[1]))
6171 || const_ok_for_arm (~INTVAL (operands[1]))))"
6172 [(clobber (const_int 0))]
6173 "
6174 arm_split_constant (SET, SImode, NULL_RTX,
6175 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6176 DONE;
6177 "
6178 )
6179
6180 ;; A normal way to do (symbol + offset) requires three instructions at least
6181 ;; (depends on how big the offset is) as below:
6182 ;; movw r0, #:lower16:g
6183 ;; movw r0, #:upper16:g
6184 ;; adds r0, #4
6185 ;;
6186 ;; A better way would be:
6187 ;; movw r0, #:lower16:g+4
6188 ;; movw r0, #:upper16:g+4
6189 ;;
6190 ;; The limitation of this way is that the length of offset should be a 16-bit
6191 ;; signed value, because current assembler only supports REL type relocation for
6192 ;; such case. If the more powerful RELA type is supported in future, we should
6193 ;; update this pattern to go with better way.
6194 (define_split
6195 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6196 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6197 (match_operand:SI 2 "const_int_operand" ""))))]
6198 "TARGET_THUMB
6199 && TARGET_HAVE_MOVT
6200 && arm_disable_literal_pool
6201 && reload_completed
6202 && GET_CODE (operands[1]) == SYMBOL_REF"
6203 [(clobber (const_int 0))]
6204 "
6205 int offset = INTVAL (operands[2]);
6206
6207 if (offset < -0x8000 || offset > 0x7fff)
6208 {
6209 arm_emit_movpair (operands[0], operands[1]);
6210 emit_insn (gen_rtx_SET (operands[0],
6211 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6212 }
6213 else
6214 {
6215 rtx op = gen_rtx_CONST (SImode,
6216 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6217 arm_emit_movpair (operands[0], op);
6218 }
6219 "
6220 )
6221
6222 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6223 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6224 ;; and lo_sum would be merged back into memory load at cprop. However,
6225 ;; if the default is to prefer movt/movw rather than a load from the constant
6226 ;; pool, the performance is better.
6227 (define_split
6228 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6229 (match_operand:SI 1 "general_operand" ""))]
6230 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6231 && !flag_pic && !target_word_relocations
6232 && !arm_tls_referenced_p (operands[1])"
6233 [(clobber (const_int 0))]
6234 {
6235 arm_emit_movpair (operands[0], operands[1]);
6236 DONE;
6237 })
6238
6239 ;; When generating pic, we need to load the symbol offset into a register.
6240 ;; So that the optimizer does not confuse this with a normal symbol load
6241 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6242 ;; since that is the only type of relocation we can use.
6243
6244 ;; Wrap calculation of the whole PIC address in a single pattern for the
6245 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6246 ;; a PIC address involves two loads from memory, so we want to CSE it
6247 ;; as often as possible.
6248 ;; This pattern will be split into one of the pic_load_addr_* patterns
6249 ;; and a move after GCSE optimizations.
6250 ;;
6251 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6252 (define_expand "calculate_pic_address"
6253 [(set (match_operand:SI 0 "register_operand" "")
6254 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6255 (unspec:SI [(match_operand:SI 2 "" "")]
6256 UNSPEC_PIC_SYM))))]
6257 "flag_pic"
6258 )
6259
6260 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6261 (define_split
6262 [(set (match_operand:SI 0 "register_operand" "")
6263 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6264 (unspec:SI [(match_operand:SI 2 "" "")]
6265 UNSPEC_PIC_SYM))))]
6266 "flag_pic"
6267 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6268 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6269 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6270 )
6271
6272 ;; operand1 is the memory address to go into
6273 ;; pic_load_addr_32bit.
6274 ;; operand2 is the PIC label to be emitted
6275 ;; from pic_add_dot_plus_eight.
6276 ;; We do this to allow hoisting of the entire insn.
6277 (define_insn_and_split "pic_load_addr_unified"
6278 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6279 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6280 (match_operand:SI 2 "" "")]
6281 UNSPEC_PIC_UNIFIED))]
6282 "flag_pic"
6283 "#"
6284 "&& reload_completed"
6285 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6286 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6287 (match_dup 2)] UNSPEC_PIC_BASE))]
6288 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6289 [(set_attr "type" "load_4,load_4,load_4")
6290 (set_attr "pool_range" "4096,4094,1022")
6291 (set_attr "neg_pool_range" "4084,0,0")
6292 (set_attr "arch" "a,t2,t1")
6293 (set_attr "length" "8,6,4")]
6294 )
6295
6296 ;; The rather odd constraints on the following are to force reload to leave
6297 ;; the insn alone, and to force the minipool generation pass to then move
6298 ;; the GOT symbol to memory.
6299
6300 (define_insn "pic_load_addr_32bit"
6301 [(set (match_operand:SI 0 "s_register_operand" "=r")
6302 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6303 "TARGET_32BIT && flag_pic"
6304 "ldr%?\\t%0, %1"
6305 [(set_attr "type" "load_4")
6306 (set (attr "pool_range")
6307 (if_then_else (eq_attr "is_thumb" "no")
6308 (const_int 4096)
6309 (const_int 4094)))
6310 (set (attr "neg_pool_range")
6311 (if_then_else (eq_attr "is_thumb" "no")
6312 (const_int 4084)
6313 (const_int 0)))]
6314 )
6315
6316 (define_insn "pic_load_addr_thumb1"
6317 [(set (match_operand:SI 0 "s_register_operand" "=l")
6318 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6319 "TARGET_THUMB1 && flag_pic"
6320 "ldr\\t%0, %1"
6321 [(set_attr "type" "load_4")
6322 (set (attr "pool_range") (const_int 1018))]
6323 )
6324
6325 (define_insn "pic_add_dot_plus_four"
6326 [(set (match_operand:SI 0 "register_operand" "=r")
6327 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6328 (const_int 4)
6329 (match_operand 2 "" "")]
6330 UNSPEC_PIC_BASE))]
6331 "TARGET_THUMB"
6332 "*
6333 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6334 INTVAL (operands[2]));
6335 return \"add\\t%0, %|pc\";
6336 "
6337 [(set_attr "length" "2")
6338 (set_attr "type" "alu_sreg")]
6339 )
6340
6341 (define_insn "pic_add_dot_plus_eight"
6342 [(set (match_operand:SI 0 "register_operand" "=r")
6343 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6344 (const_int 8)
6345 (match_operand 2 "" "")]
6346 UNSPEC_PIC_BASE))]
6347 "TARGET_ARM"
6348 "*
6349 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6350 INTVAL (operands[2]));
6351 return \"add%?\\t%0, %|pc, %1\";
6352 "
6353 [(set_attr "predicable" "yes")
6354 (set_attr "type" "alu_sreg")]
6355 )
6356
6357 (define_insn "tls_load_dot_plus_eight"
6358 [(set (match_operand:SI 0 "register_operand" "=r")
6359 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6360 (const_int 8)
6361 (match_operand 2 "" "")]
6362 UNSPEC_PIC_BASE)))]
6363 "TARGET_ARM"
6364 "*
6365 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6366 INTVAL (operands[2]));
6367 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6368 "
6369 [(set_attr "predicable" "yes")
6370 (set_attr "type" "load_4")]
6371 )
6372
6373 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6374 ;; followed by a load. These sequences can be crunched down to
6375 ;; tls_load_dot_plus_eight by a peephole.
6376
6377 (define_peephole2
6378 [(set (match_operand:SI 0 "register_operand" "")
6379 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6380 (const_int 8)
6381 (match_operand 1 "" "")]
6382 UNSPEC_PIC_BASE))
6383 (set (match_operand:SI 2 "arm_general_register_operand" "")
6384 (mem:SI (match_dup 0)))]
6385 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6386 [(set (match_dup 2)
6387 (mem:SI (unspec:SI [(match_dup 3)
6388 (const_int 8)
6389 (match_dup 1)]
6390 UNSPEC_PIC_BASE)))]
6391 ""
6392 )
6393
6394 (define_insn "pic_offset_arm"
6395 [(set (match_operand:SI 0 "register_operand" "=r")
6396 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6397 (unspec:SI [(match_operand:SI 2 "" "X")]
6398 UNSPEC_PIC_OFFSET))))]
6399 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6400 "ldr%?\\t%0, [%1,%2]"
6401 [(set_attr "type" "load_4")]
6402 )
6403
6404 (define_expand "builtin_setjmp_receiver"
6405 [(label_ref (match_operand 0 "" ""))]
6406 "flag_pic"
6407 "
6408 {
6409 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6410 register. */
6411 if (arm_pic_register != INVALID_REGNUM)
6412 arm_load_pic_register (1UL << 3);
6413 DONE;
6414 }")
6415
6416 ;; If copying one reg to another we can set the condition codes according to
6417 ;; its value. Such a move is common after a return from subroutine and the
6418 ;; result is being tested against zero.
6419
6420 (define_insn "*movsi_compare0"
6421 [(set (reg:CC CC_REGNUM)
6422 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6423 (const_int 0)))
6424 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6425 (match_dup 1))]
6426 "TARGET_32BIT"
6427 "@
6428 cmp%?\\t%0, #0
6429 subs%?\\t%0, %1, #0"
6430 [(set_attr "conds" "set")
6431 (set_attr "type" "alus_imm,alus_imm")]
6432 )
6433
6434 ;; Subroutine to store a half word from a register into memory.
6435 ;; Operand 0 is the source register (HImode)
6436 ;; Operand 1 is the destination address in a register (SImode)
6437
6438 ;; In both this routine and the next, we must be careful not to spill
6439 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6440 ;; can generate unrecognizable rtl.
6441
6442 (define_expand "storehi"
6443 [;; store the low byte
6444 (set (match_operand 1 "" "") (match_dup 3))
6445 ;; extract the high byte
6446 (set (match_dup 2)
6447 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6448 ;; store the high byte
6449 (set (match_dup 4) (match_dup 5))]
6450 "TARGET_ARM"
6451 "
6452 {
6453 rtx op1 = operands[1];
6454 rtx addr = XEXP (op1, 0);
6455 enum rtx_code code = GET_CODE (addr);
6456
6457 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6458 || code == MINUS)
6459 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6460
6461 operands[4] = adjust_address (op1, QImode, 1);
6462 operands[1] = adjust_address (operands[1], QImode, 0);
6463 operands[3] = gen_lowpart (QImode, operands[0]);
6464 operands[0] = gen_lowpart (SImode, operands[0]);
6465 operands[2] = gen_reg_rtx (SImode);
6466 operands[5] = gen_lowpart (QImode, operands[2]);
6467 }"
6468 )
6469
6470 (define_expand "storehi_bigend"
6471 [(set (match_dup 4) (match_dup 3))
6472 (set (match_dup 2)
6473 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6474 (set (match_operand 1 "" "") (match_dup 5))]
6475 "TARGET_ARM"
6476 "
6477 {
6478 rtx op1 = operands[1];
6479 rtx addr = XEXP (op1, 0);
6480 enum rtx_code code = GET_CODE (addr);
6481
6482 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6483 || code == MINUS)
6484 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6485
6486 operands[4] = adjust_address (op1, QImode, 1);
6487 operands[1] = adjust_address (operands[1], QImode, 0);
6488 operands[3] = gen_lowpart (QImode, operands[0]);
6489 operands[0] = gen_lowpart (SImode, operands[0]);
6490 operands[2] = gen_reg_rtx (SImode);
6491 operands[5] = gen_lowpart (QImode, operands[2]);
6492 }"
6493 )
6494
6495 ;; Subroutine to store a half word integer constant into memory.
6496 (define_expand "storeinthi"
6497 [(set (match_operand 0 "" "")
6498 (match_operand 1 "" ""))
6499 (set (match_dup 3) (match_dup 2))]
6500 "TARGET_ARM"
6501 "
6502 {
6503 HOST_WIDE_INT value = INTVAL (operands[1]);
6504 rtx addr = XEXP (operands[0], 0);
6505 rtx op0 = operands[0];
6506 enum rtx_code code = GET_CODE (addr);
6507
6508 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6509 || code == MINUS)
6510 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6511
6512 operands[1] = gen_reg_rtx (SImode);
6513 if (BYTES_BIG_ENDIAN)
6514 {
6515 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6516 if ((value & 255) == ((value >> 8) & 255))
6517 operands[2] = operands[1];
6518 else
6519 {
6520 operands[2] = gen_reg_rtx (SImode);
6521 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6522 }
6523 }
6524 else
6525 {
6526 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6527 if ((value & 255) == ((value >> 8) & 255))
6528 operands[2] = operands[1];
6529 else
6530 {
6531 operands[2] = gen_reg_rtx (SImode);
6532 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6533 }
6534 }
6535
6536 operands[3] = adjust_address (op0, QImode, 1);
6537 operands[0] = adjust_address (operands[0], QImode, 0);
6538 operands[2] = gen_lowpart (QImode, operands[2]);
6539 operands[1] = gen_lowpart (QImode, operands[1]);
6540 }"
6541 )
6542
6543 (define_expand "storehi_single_op"
6544 [(set (match_operand:HI 0 "memory_operand" "")
6545 (match_operand:HI 1 "general_operand" ""))]
6546 "TARGET_32BIT && arm_arch4"
6547 "
6548 if (!s_register_operand (operands[1], HImode))
6549 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6550 "
6551 )
6552
6553 (define_expand "movhi"
6554 [(set (match_operand:HI 0 "general_operand" "")
6555 (match_operand:HI 1 "general_operand" ""))]
6556 "TARGET_EITHER"
6557 "
6558 if (TARGET_ARM)
6559 {
6560 if (can_create_pseudo_p ())
6561 {
6562 if (MEM_P (operands[0]))
6563 {
6564 if (arm_arch4)
6565 {
6566 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6567 DONE;
6568 }
6569 if (CONST_INT_P (operands[1]))
6570 emit_insn (gen_storeinthi (operands[0], operands[1]));
6571 else
6572 {
6573 if (MEM_P (operands[1]))
6574 operands[1] = force_reg (HImode, operands[1]);
6575 if (BYTES_BIG_ENDIAN)
6576 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6577 else
6578 emit_insn (gen_storehi (operands[1], operands[0]));
6579 }
6580 DONE;
6581 }
6582 /* Sign extend a constant, and keep it in an SImode reg. */
6583 else if (CONST_INT_P (operands[1]))
6584 {
6585 rtx reg = gen_reg_rtx (SImode);
6586 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6587
6588 /* If the constant is already valid, leave it alone. */
6589 if (!const_ok_for_arm (val))
6590 {
6591 /* If setting all the top bits will make the constant
6592 loadable in a single instruction, then set them.
6593 Otherwise, sign extend the number. */
6594
6595 if (const_ok_for_arm (~(val | ~0xffff)))
6596 val |= ~0xffff;
6597 else if (val & 0x8000)
6598 val |= ~0xffff;
6599 }
6600
6601 emit_insn (gen_movsi (reg, GEN_INT (val)));
6602 operands[1] = gen_lowpart (HImode, reg);
6603 }
6604 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6605 && MEM_P (operands[1]))
6606 {
6607 rtx reg = gen_reg_rtx (SImode);
6608
6609 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6610 operands[1] = gen_lowpart (HImode, reg);
6611 }
6612 else if (!arm_arch4)
6613 {
6614 if (MEM_P (operands[1]))
6615 {
6616 rtx base;
6617 rtx offset = const0_rtx;
6618 rtx reg = gen_reg_rtx (SImode);
6619
6620 if ((REG_P (base = XEXP (operands[1], 0))
6621 || (GET_CODE (base) == PLUS
6622 && (CONST_INT_P (offset = XEXP (base, 1)))
6623 && ((INTVAL(offset) & 1) != 1)
6624 && REG_P (base = XEXP (base, 0))))
6625 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6626 {
6627 rtx new_rtx;
6628
6629 new_rtx = widen_memory_access (operands[1], SImode,
6630 ((INTVAL (offset) & ~3)
6631 - INTVAL (offset)));
6632 emit_insn (gen_movsi (reg, new_rtx));
6633 if (((INTVAL (offset) & 2) != 0)
6634 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6635 {
6636 rtx reg2 = gen_reg_rtx (SImode);
6637
6638 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6639 reg = reg2;
6640 }
6641 }
6642 else
6643 emit_insn (gen_movhi_bytes (reg, operands[1]));
6644
6645 operands[1] = gen_lowpart (HImode, reg);
6646 }
6647 }
6648 }
6649 /* Handle loading a large integer during reload. */
6650 else if (CONST_INT_P (operands[1])
6651 && !const_ok_for_arm (INTVAL (operands[1]))
6652 && !const_ok_for_arm (~INTVAL (operands[1])))
6653 {
6654 /* Writing a constant to memory needs a scratch, which should
6655 be handled with SECONDARY_RELOADs. */
6656 gcc_assert (REG_P (operands[0]));
6657
6658 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6659 emit_insn (gen_movsi (operands[0], operands[1]));
6660 DONE;
6661 }
6662 }
6663 else if (TARGET_THUMB2)
6664 {
6665 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6666 if (can_create_pseudo_p ())
6667 {
6668 if (!REG_P (operands[0]))
6669 operands[1] = force_reg (HImode, operands[1]);
6670 /* Zero extend a constant, and keep it in an SImode reg. */
6671 else if (CONST_INT_P (operands[1]))
6672 {
6673 rtx reg = gen_reg_rtx (SImode);
6674 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6675
6676 emit_insn (gen_movsi (reg, GEN_INT (val)));
6677 operands[1] = gen_lowpart (HImode, reg);
6678 }
6679 }
6680 }
6681 else /* TARGET_THUMB1 */
6682 {
6683 if (can_create_pseudo_p ())
6684 {
6685 if (CONST_INT_P (operands[1]))
6686 {
6687 rtx reg = gen_reg_rtx (SImode);
6688
6689 emit_insn (gen_movsi (reg, operands[1]));
6690 operands[1] = gen_lowpart (HImode, reg);
6691 }
6692
6693 /* ??? We shouldn't really get invalid addresses here, but this can
6694 happen if we are passed a SP (never OK for HImode/QImode) or
6695 virtual register (also rejected as illegitimate for HImode/QImode)
6696 relative address. */
6697 /* ??? This should perhaps be fixed elsewhere, for instance, in
6698 fixup_stack_1, by checking for other kinds of invalid addresses,
6699 e.g. a bare reference to a virtual register. This may confuse the
6700 alpha though, which must handle this case differently. */
6701 if (MEM_P (operands[0])
6702 && !memory_address_p (GET_MODE (operands[0]),
6703 XEXP (operands[0], 0)))
6704 operands[0]
6705 = replace_equiv_address (operands[0],
6706 copy_to_reg (XEXP (operands[0], 0)));
6707
6708 if (MEM_P (operands[1])
6709 && !memory_address_p (GET_MODE (operands[1]),
6710 XEXP (operands[1], 0)))
6711 operands[1]
6712 = replace_equiv_address (operands[1],
6713 copy_to_reg (XEXP (operands[1], 0)));
6714
6715 if (MEM_P (operands[1]) && optimize > 0)
6716 {
6717 rtx reg = gen_reg_rtx (SImode);
6718
6719 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6720 operands[1] = gen_lowpart (HImode, reg);
6721 }
6722
6723 if (MEM_P (operands[0]))
6724 operands[1] = force_reg (HImode, operands[1]);
6725 }
6726 else if (CONST_INT_P (operands[1])
6727 && !satisfies_constraint_I (operands[1]))
6728 {
6729 /* Handle loading a large integer during reload. */
6730
6731 /* Writing a constant to memory needs a scratch, which should
6732 be handled with SECONDARY_RELOADs. */
6733 gcc_assert (REG_P (operands[0]));
6734
6735 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6736 emit_insn (gen_movsi (operands[0], operands[1]));
6737 DONE;
6738 }
6739 }
6740 "
6741 )
6742
6743 (define_expand "movhi_bytes"
6744 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6745 (set (match_dup 3)
6746 (zero_extend:SI (match_dup 6)))
6747 (set (match_operand:SI 0 "" "")
6748 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6749 "TARGET_ARM"
6750 "
6751 {
6752 rtx mem1, mem2;
6753 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6754
6755 mem1 = change_address (operands[1], QImode, addr);
6756 mem2 = change_address (operands[1], QImode,
6757 plus_constant (Pmode, addr, 1));
6758 operands[0] = gen_lowpart (SImode, operands[0]);
6759 operands[1] = mem1;
6760 operands[2] = gen_reg_rtx (SImode);
6761 operands[3] = gen_reg_rtx (SImode);
6762 operands[6] = mem2;
6763
6764 if (BYTES_BIG_ENDIAN)
6765 {
6766 operands[4] = operands[2];
6767 operands[5] = operands[3];
6768 }
6769 else
6770 {
6771 operands[4] = operands[3];
6772 operands[5] = operands[2];
6773 }
6774 }"
6775 )
6776
6777 (define_expand "movhi_bigend"
6778 [(set (match_dup 2)
6779 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6780 (const_int 16)))
6781 (set (match_dup 3)
6782 (ashiftrt:SI (match_dup 2) (const_int 16)))
6783 (set (match_operand:HI 0 "s_register_operand" "")
6784 (match_dup 4))]
6785 "TARGET_ARM"
6786 "
6787 operands[2] = gen_reg_rtx (SImode);
6788 operands[3] = gen_reg_rtx (SImode);
6789 operands[4] = gen_lowpart (HImode, operands[3]);
6790 "
6791 )
6792
6793 ;; Pattern to recognize insn generated default case above
6794 (define_insn "*movhi_insn_arch4"
6795 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6796 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6797 "TARGET_ARM
6798 && arm_arch4 && !TARGET_HARD_FLOAT
6799 && (register_operand (operands[0], HImode)
6800 || register_operand (operands[1], HImode))"
6801 "@
6802 mov%?\\t%0, %1\\t%@ movhi
6803 mvn%?\\t%0, #%B1\\t%@ movhi
6804 movw%?\\t%0, %L1\\t%@ movhi
6805 strh%?\\t%1, %0\\t%@ movhi
6806 ldrh%?\\t%0, %1\\t%@ movhi"
6807 [(set_attr "predicable" "yes")
6808 (set_attr "pool_range" "*,*,*,*,256")
6809 (set_attr "neg_pool_range" "*,*,*,*,244")
6810 (set_attr "arch" "*,*,v6t2,*,*")
6811 (set_attr_alternative "type"
6812 [(if_then_else (match_operand 1 "const_int_operand" "")
6813 (const_string "mov_imm" )
6814 (const_string "mov_reg"))
6815 (const_string "mvn_imm")
6816 (const_string "mov_imm")
6817 (const_string "store_4")
6818 (const_string "load_4")])]
6819 )
6820
6821 (define_insn "*movhi_bytes"
6822 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6823 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6824 "TARGET_ARM && !TARGET_HARD_FLOAT"
6825 "@
6826 mov%?\\t%0, %1\\t%@ movhi
6827 mov%?\\t%0, %1\\t%@ movhi
6828 mvn%?\\t%0, #%B1\\t%@ movhi"
6829 [(set_attr "predicable" "yes")
6830 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6831 )
6832
6833 ;; We use a DImode scratch because we may occasionally need an additional
6834 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6835 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6836 (define_expand "reload_outhi"
6837 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6838 (match_operand:HI 1 "s_register_operand" "r")
6839 (match_operand:DI 2 "s_register_operand" "=&l")])]
6840 "TARGET_EITHER"
6841 "if (TARGET_ARM)
6842 arm_reload_out_hi (operands);
6843 else
6844 thumb_reload_out_hi (operands);
6845 DONE;
6846 "
6847 )
6848
6849 (define_expand "reload_inhi"
6850 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6851 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6852 (match_operand:DI 2 "s_register_operand" "=&r")])]
6853 "TARGET_EITHER"
6854 "
6855 if (TARGET_ARM)
6856 arm_reload_in_hi (operands);
6857 else
6858 thumb_reload_out_hi (operands);
6859 DONE;
6860 ")
6861
6862 (define_expand "movqi"
6863 [(set (match_operand:QI 0 "general_operand" "")
6864 (match_operand:QI 1 "general_operand" ""))]
6865 "TARGET_EITHER"
6866 "
6867 /* Everything except mem = const or mem = mem can be done easily */
6868
6869 if (can_create_pseudo_p ())
6870 {
6871 if (CONST_INT_P (operands[1]))
6872 {
6873 rtx reg = gen_reg_rtx (SImode);
6874
6875 /* For thumb we want an unsigned immediate, then we are more likely
6876 to be able to use a movs insn. */
6877 if (TARGET_THUMB)
6878 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6879
6880 emit_insn (gen_movsi (reg, operands[1]));
6881 operands[1] = gen_lowpart (QImode, reg);
6882 }
6883
6884 if (TARGET_THUMB)
6885 {
6886 /* ??? We shouldn't really get invalid addresses here, but this can
6887 happen if we are passed a SP (never OK for HImode/QImode) or
6888 virtual register (also rejected as illegitimate for HImode/QImode)
6889 relative address. */
6890 /* ??? This should perhaps be fixed elsewhere, for instance, in
6891 fixup_stack_1, by checking for other kinds of invalid addresses,
6892 e.g. a bare reference to a virtual register. This may confuse the
6893 alpha though, which must handle this case differently. */
6894 if (MEM_P (operands[0])
6895 && !memory_address_p (GET_MODE (operands[0]),
6896 XEXP (operands[0], 0)))
6897 operands[0]
6898 = replace_equiv_address (operands[0],
6899 copy_to_reg (XEXP (operands[0], 0)));
6900 if (MEM_P (operands[1])
6901 && !memory_address_p (GET_MODE (operands[1]),
6902 XEXP (operands[1], 0)))
6903 operands[1]
6904 = replace_equiv_address (operands[1],
6905 copy_to_reg (XEXP (operands[1], 0)));
6906 }
6907
6908 if (MEM_P (operands[1]) && optimize > 0)
6909 {
6910 rtx reg = gen_reg_rtx (SImode);
6911
6912 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6913 operands[1] = gen_lowpart (QImode, reg);
6914 }
6915
6916 if (MEM_P (operands[0]))
6917 operands[1] = force_reg (QImode, operands[1]);
6918 }
6919 else if (TARGET_THUMB
6920 && CONST_INT_P (operands[1])
6921 && !satisfies_constraint_I (operands[1]))
6922 {
6923 /* Handle loading a large integer during reload. */
6924
6925 /* Writing a constant to memory needs a scratch, which should
6926 be handled with SECONDARY_RELOADs. */
6927 gcc_assert (REG_P (operands[0]));
6928
6929 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6930 emit_insn (gen_movsi (operands[0], operands[1]));
6931 DONE;
6932 }
6933 "
6934 )
6935
6936 (define_insn "*arm_movqi_insn"
6937 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6938 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6939 "TARGET_32BIT
6940 && ( register_operand (operands[0], QImode)
6941 || register_operand (operands[1], QImode))"
6942 "@
6943 mov%?\\t%0, %1
6944 mov%?\\t%0, %1
6945 mov%?\\t%0, %1
6946 mov%?\\t%0, %1
6947 mvn%?\\t%0, #%B1
6948 ldrb%?\\t%0, %1
6949 strb%?\\t%1, %0
6950 ldrb%?\\t%0, %1
6951 strb%?\\t%1, %0"
6952 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6953 (set_attr "predicable" "yes")
6954 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6955 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6956 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6957 )
6958
6959 ;; HFmode moves
6960 (define_expand "movhf"
6961 [(set (match_operand:HF 0 "general_operand" "")
6962 (match_operand:HF 1 "general_operand" ""))]
6963 "TARGET_EITHER"
6964 "
6965 if (TARGET_32BIT)
6966 {
6967 if (MEM_P (operands[0]))
6968 operands[1] = force_reg (HFmode, operands[1]);
6969 }
6970 else /* TARGET_THUMB1 */
6971 {
6972 if (can_create_pseudo_p ())
6973 {
6974 if (!REG_P (operands[0]))
6975 operands[1] = force_reg (HFmode, operands[1]);
6976 }
6977 }
6978 "
6979 )
6980
6981 (define_insn "*arm32_movhf"
6982 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6983 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6984 "TARGET_32BIT && !TARGET_HARD_FLOAT
6985 && ( s_register_operand (operands[0], HFmode)
6986 || s_register_operand (operands[1], HFmode))"
6987 "*
6988 switch (which_alternative)
6989 {
6990 case 0: /* ARM register from memory */
6991 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6992 case 1: /* memory from ARM register */
6993 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6994 case 2: /* ARM register from ARM register */
6995 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6996 case 3: /* ARM register from constant */
6997 {
6998 long bits;
6999 rtx ops[4];
7000
7001 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
7002 HFmode);
7003 ops[0] = operands[0];
7004 ops[1] = GEN_INT (bits);
7005 ops[2] = GEN_INT (bits & 0xff00);
7006 ops[3] = GEN_INT (bits & 0x00ff);
7007
7008 if (arm_arch_thumb2)
7009 output_asm_insn (\"movw%?\\t%0, %1\", ops);
7010 else
7011 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
7012 return \"\";
7013 }
7014 default:
7015 gcc_unreachable ();
7016 }
7017 "
7018 [(set_attr "conds" "unconditional")
7019 (set_attr "type" "load_4,store_4,mov_reg,multiple")
7020 (set_attr "length" "4,4,4,8")
7021 (set_attr "predicable" "yes")
7022 (set_attr "predicable_short_it" "no")]
7023 )
7024
7025 (define_expand "movsf"
7026 [(set (match_operand:SF 0 "general_operand" "")
7027 (match_operand:SF 1 "general_operand" ""))]
7028 "TARGET_EITHER"
7029 "
7030 if (TARGET_32BIT)
7031 {
7032 if (MEM_P (operands[0]))
7033 operands[1] = force_reg (SFmode, operands[1]);
7034 }
7035 else /* TARGET_THUMB1 */
7036 {
7037 if (can_create_pseudo_p ())
7038 {
7039 if (!REG_P (operands[0]))
7040 operands[1] = force_reg (SFmode, operands[1]);
7041 }
7042 }
7043 "
7044 )
7045
7046 ;; Transform a floating-point move of a constant into a core register into
7047 ;; an SImode operation.
7048 (define_split
7049 [(set (match_operand:SF 0 "arm_general_register_operand" "")
7050 (match_operand:SF 1 "immediate_operand" ""))]
7051 "TARGET_EITHER
7052 && reload_completed
7053 && CONST_DOUBLE_P (operands[1])"
7054 [(set (match_dup 2) (match_dup 3))]
7055 "
7056 operands[2] = gen_lowpart (SImode, operands[0]);
7057 operands[3] = gen_lowpart (SImode, operands[1]);
7058 if (operands[2] == 0 || operands[3] == 0)
7059 FAIL;
7060 "
7061 )
7062
7063 (define_insn "*arm_movsf_soft_insn"
7064 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
7065 (match_operand:SF 1 "general_operand" "r,mE,r"))]
7066 "TARGET_32BIT
7067 && TARGET_SOFT_FLOAT
7068 && (!MEM_P (operands[0])
7069 || register_operand (operands[1], SFmode))"
7070 "@
7071 mov%?\\t%0, %1
7072 ldr%?\\t%0, %1\\t%@ float
7073 str%?\\t%1, %0\\t%@ float"
7074 [(set_attr "predicable" "yes")
7075 (set_attr "predicable_short_it" "no")
7076 (set_attr "type" "mov_reg,load_4,store_4")
7077 (set_attr "arm_pool_range" "*,4096,*")
7078 (set_attr "thumb2_pool_range" "*,4094,*")
7079 (set_attr "arm_neg_pool_range" "*,4084,*")
7080 (set_attr "thumb2_neg_pool_range" "*,0,*")]
7081 )
7082
7083 (define_expand "movdf"
7084 [(set (match_operand:DF 0 "general_operand" "")
7085 (match_operand:DF 1 "general_operand" ""))]
7086 "TARGET_EITHER"
7087 "
7088 if (TARGET_32BIT)
7089 {
7090 if (MEM_P (operands[0]))
7091 operands[1] = force_reg (DFmode, operands[1]);
7092 }
7093 else /* TARGET_THUMB */
7094 {
7095 if (can_create_pseudo_p ())
7096 {
7097 if (!REG_P (operands[0]))
7098 operands[1] = force_reg (DFmode, operands[1]);
7099 }
7100 }
7101 "
7102 )
7103
7104 ;; Reloading a df mode value stored in integer regs to memory can require a
7105 ;; scratch reg.
7106 (define_expand "reload_outdf"
7107 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7108 (match_operand:DF 1 "s_register_operand" "r")
7109 (match_operand:SI 2 "s_register_operand" "=&r")]
7110 "TARGET_THUMB2"
7111 "
7112 {
7113 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7114
7115 if (code == REG)
7116 operands[2] = XEXP (operands[0], 0);
7117 else if (code == POST_INC || code == PRE_DEC)
7118 {
7119 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7120 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7121 emit_insn (gen_movdi (operands[0], operands[1]));
7122 DONE;
7123 }
7124 else if (code == PRE_INC)
7125 {
7126 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7127
7128 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7129 operands[2] = reg;
7130 }
7131 else if (code == POST_DEC)
7132 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7133 else
7134 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7135 XEXP (XEXP (operands[0], 0), 1)));
7136
7137 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7138 operands[1]));
7139
7140 if (code == POST_DEC)
7141 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7142
7143 DONE;
7144 }"
7145 )
7146
7147 (define_insn "*movdf_soft_insn"
7148 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7149 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7150 "TARGET_32BIT && TARGET_SOFT_FLOAT
7151 && ( register_operand (operands[0], DFmode)
7152 || register_operand (operands[1], DFmode))"
7153 "*
7154 switch (which_alternative)
7155 {
7156 case 0:
7157 case 1:
7158 case 2:
7159 return \"#\";
7160 default:
7161 return output_move_double (operands, true, NULL);
7162 }
7163 "
7164 [(set_attr "length" "8,12,16,8,8")
7165 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
7166 (set_attr "arm_pool_range" "*,*,*,1020,*")
7167 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7168 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7169 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7170 )
7171 \f
7172
7173 ;; load- and store-multiple insns
7174 ;; The arm can load/store any set of registers, provided that they are in
7175 ;; ascending order, but these expanders assume a contiguous set.
7176
7177 (define_expand "load_multiple"
7178 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7179 (match_operand:SI 1 "" ""))
7180 (use (match_operand:SI 2 "" ""))])]
7181 "TARGET_32BIT"
7182 {
7183 HOST_WIDE_INT offset = 0;
7184
7185 /* Support only fixed point registers. */
7186 if (!CONST_INT_P (operands[2])
7187 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7188 || INTVAL (operands[2]) < 2
7189 || !MEM_P (operands[1])
7190 || !REG_P (operands[0])
7191 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7192 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7193 FAIL;
7194
7195 operands[3]
7196 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7197 INTVAL (operands[2]),
7198 force_reg (SImode, XEXP (operands[1], 0)),
7199 FALSE, operands[1], &offset);
7200 })
7201
7202 (define_expand "store_multiple"
7203 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7204 (match_operand:SI 1 "" ""))
7205 (use (match_operand:SI 2 "" ""))])]
7206 "TARGET_32BIT"
7207 {
7208 HOST_WIDE_INT offset = 0;
7209
7210 /* Support only fixed point registers. */
7211 if (!CONST_INT_P (operands[2])
7212 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7213 || INTVAL (operands[2]) < 2
7214 || !REG_P (operands[1])
7215 || !MEM_P (operands[0])
7216 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7217 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7218 FAIL;
7219
7220 operands[3]
7221 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7222 INTVAL (operands[2]),
7223 force_reg (SImode, XEXP (operands[0], 0)),
7224 FALSE, operands[0], &offset);
7225 })
7226
7227
7228 (define_expand "setmemsi"
7229 [(match_operand:BLK 0 "general_operand" "")
7230 (match_operand:SI 1 "const_int_operand" "")
7231 (match_operand:SI 2 "const_int_operand" "")
7232 (match_operand:SI 3 "const_int_operand" "")]
7233 "TARGET_32BIT"
7234 {
7235 if (arm_gen_setmem (operands))
7236 DONE;
7237
7238 FAIL;
7239 })
7240
7241
7242 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7243 ;; We could let this apply for blocks of less than this, but it clobbers so
7244 ;; many registers that there is then probably a better way.
7245
7246 (define_expand "movmemqi"
7247 [(match_operand:BLK 0 "general_operand" "")
7248 (match_operand:BLK 1 "general_operand" "")
7249 (match_operand:SI 2 "const_int_operand" "")
7250 (match_operand:SI 3 "const_int_operand" "")]
7251 ""
7252 "
7253 if (TARGET_32BIT)
7254 {
7255 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7256 && !optimize_function_for_size_p (cfun))
7257 {
7258 if (gen_movmem_ldrd_strd (operands))
7259 DONE;
7260 FAIL;
7261 }
7262
7263 if (arm_gen_movmemqi (operands))
7264 DONE;
7265 FAIL;
7266 }
7267 else /* TARGET_THUMB1 */
7268 {
7269 if ( INTVAL (operands[3]) != 4
7270 || INTVAL (operands[2]) > 48)
7271 FAIL;
7272
7273 thumb_expand_movmemqi (operands);
7274 DONE;
7275 }
7276 "
7277 )
7278 \f
7279
7280 ;; Compare & branch insns
7281 ;; The range calculations are based as follows:
7282 ;; For forward branches, the address calculation returns the address of
7283 ;; the next instruction. This is 2 beyond the branch instruction.
7284 ;; For backward branches, the address calculation returns the address of
7285 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7286 ;; instruction for the shortest sequence, and 4 before the branch instruction
7287 ;; if we have to jump around an unconditional branch.
7288 ;; To the basic branch range the PC offset must be added (this is +4).
7289 ;; So for forward branches we have
7290 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7291 ;; And for backward branches we have
7292 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7293 ;;
7294 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7295 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7296
7297 (define_expand "cbranchsi4"
7298 [(set (pc) (if_then_else
7299 (match_operator 0 "expandable_comparison_operator"
7300 [(match_operand:SI 1 "s_register_operand" "")
7301 (match_operand:SI 2 "nonmemory_operand" "")])
7302 (label_ref (match_operand 3 "" ""))
7303 (pc)))]
7304 "TARGET_EITHER"
7305 "
7306 if (!TARGET_THUMB1)
7307 {
7308 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7309 FAIL;
7310 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7311 operands[3]));
7312 DONE;
7313 }
7314 if (thumb1_cmpneg_operand (operands[2], SImode))
7315 {
7316 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7317 operands[3], operands[0]));
7318 DONE;
7319 }
7320 if (!thumb1_cmp_operand (operands[2], SImode))
7321 operands[2] = force_reg (SImode, operands[2]);
7322 ")
7323
7324 (define_expand "cbranchsf4"
7325 [(set (pc) (if_then_else
7326 (match_operator 0 "expandable_comparison_operator"
7327 [(match_operand:SF 1 "s_register_operand" "")
7328 (match_operand:SF 2 "vfp_compare_operand" "")])
7329 (label_ref (match_operand 3 "" ""))
7330 (pc)))]
7331 "TARGET_32BIT && TARGET_HARD_FLOAT"
7332 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7333 operands[3])); DONE;"
7334 )
7335
7336 (define_expand "cbranchdf4"
7337 [(set (pc) (if_then_else
7338 (match_operator 0 "expandable_comparison_operator"
7339 [(match_operand:DF 1 "s_register_operand" "")
7340 (match_operand:DF 2 "vfp_compare_operand" "")])
7341 (label_ref (match_operand 3 "" ""))
7342 (pc)))]
7343 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7344 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7345 operands[3])); DONE;"
7346 )
7347
7348 (define_expand "cbranchdi4"
7349 [(set (pc) (if_then_else
7350 (match_operator 0 "expandable_comparison_operator"
7351 [(match_operand:DI 1 "s_register_operand" "")
7352 (match_operand:DI 2 "cmpdi_operand" "")])
7353 (label_ref (match_operand 3 "" ""))
7354 (pc)))]
7355 "TARGET_32BIT"
7356 "{
7357 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7358 FAIL;
7359 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7360 operands[3]));
7361 DONE;
7362 }"
7363 )
7364
7365 ;; Comparison and test insns
7366
7367 (define_insn "*arm_cmpsi_insn"
7368 [(set (reg:CC CC_REGNUM)
7369 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7370 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7371 "TARGET_32BIT"
7372 "@
7373 cmp%?\\t%0, %1
7374 cmp%?\\t%0, %1
7375 cmp%?\\t%0, %1
7376 cmp%?\\t%0, %1
7377 cmn%?\\t%0, #%n1"
7378 [(set_attr "conds" "set")
7379 (set_attr "arch" "t2,t2,any,any,any")
7380 (set_attr "length" "2,2,4,4,4")
7381 (set_attr "predicable" "yes")
7382 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7383 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7384 )
7385
7386 (define_insn "*cmpsi_shiftsi"
7387 [(set (reg:CC CC_REGNUM)
7388 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7389 (match_operator:SI 3 "shift_operator"
7390 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7391 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7392 "TARGET_32BIT"
7393 "cmp\\t%0, %1%S3"
7394 [(set_attr "conds" "set")
7395 (set_attr "shift" "1")
7396 (set_attr "arch" "32,a,a")
7397 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7398
7399 (define_insn "*cmpsi_shiftsi_swp"
7400 [(set (reg:CC_SWP CC_REGNUM)
7401 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7402 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7403 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7404 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7405 "TARGET_32BIT"
7406 "cmp%?\\t%0, %1%S3"
7407 [(set_attr "conds" "set")
7408 (set_attr "shift" "1")
7409 (set_attr "arch" "32,a,a")
7410 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7411
7412 (define_insn "*arm_cmpsi_negshiftsi_si"
7413 [(set (reg:CC_Z CC_REGNUM)
7414 (compare:CC_Z
7415 (neg:SI (match_operator:SI 1 "shift_operator"
7416 [(match_operand:SI 2 "s_register_operand" "r")
7417 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7418 (match_operand:SI 0 "s_register_operand" "r")))]
7419 "TARGET_ARM"
7420 "cmn%?\\t%0, %2%S1"
7421 [(set_attr "conds" "set")
7422 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7423 (const_string "alus_shift_imm")
7424 (const_string "alus_shift_reg")))
7425 (set_attr "predicable" "yes")]
7426 )
7427
7428 ;; DImode comparisons. The generic code generates branches that
7429 ;; if-conversion can not reduce to a conditional compare, so we do
7430 ;; that directly.
7431
7432 (define_insn_and_split "*arm_cmpdi_insn"
7433 [(set (reg:CC_NCV CC_REGNUM)
7434 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7435 (match_operand:DI 1 "arm_di_operand" "rDi")))
7436 (clobber (match_scratch:SI 2 "=r"))]
7437 "TARGET_32BIT"
7438 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7439 "&& reload_completed"
7440 [(set (reg:CC CC_REGNUM)
7441 (compare:CC (match_dup 0) (match_dup 1)))
7442 (parallel [(set (reg:CC CC_REGNUM)
7443 (compare:CC (match_dup 3) (match_dup 4)))
7444 (set (match_dup 2)
7445 (minus:SI (match_dup 5)
7446 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7447 {
7448 operands[3] = gen_highpart (SImode, operands[0]);
7449 operands[0] = gen_lowpart (SImode, operands[0]);
7450 if (CONST_INT_P (operands[1]))
7451 {
7452 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7453 DImode,
7454 operands[1])));
7455 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7456 }
7457 else
7458 {
7459 operands[4] = gen_highpart (SImode, operands[1]);
7460 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7461 }
7462 operands[1] = gen_lowpart (SImode, operands[1]);
7463 operands[2] = gen_lowpart (SImode, operands[2]);
7464 }
7465 [(set_attr "conds" "set")
7466 (set_attr "length" "8")
7467 (set_attr "type" "multiple")]
7468 )
7469
7470 (define_insn_and_split "*arm_cmpdi_unsigned"
7471 [(set (reg:CC_CZ CC_REGNUM)
7472 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7473 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7474
7475 "TARGET_32BIT"
7476 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7477 "&& reload_completed"
7478 [(set (reg:CC CC_REGNUM)
7479 (compare:CC (match_dup 2) (match_dup 3)))
7480 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7481 (set (reg:CC CC_REGNUM)
7482 (compare:CC (match_dup 0) (match_dup 1))))]
7483 {
7484 operands[2] = gen_highpart (SImode, operands[0]);
7485 operands[0] = gen_lowpart (SImode, operands[0]);
7486 if (CONST_INT_P (operands[1]))
7487 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7488 else
7489 operands[3] = gen_highpart (SImode, operands[1]);
7490 operands[1] = gen_lowpart (SImode, operands[1]);
7491 }
7492 [(set_attr "conds" "set")
7493 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7494 (set_attr "arch" "t2,t2,t2,a")
7495 (set_attr "length" "6,6,10,8")
7496 (set_attr "type" "multiple")]
7497 )
7498
7499 (define_insn "*arm_cmpdi_zero"
7500 [(set (reg:CC_Z CC_REGNUM)
7501 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7502 (const_int 0)))
7503 (clobber (match_scratch:SI 1 "=r"))]
7504 "TARGET_32BIT"
7505 "orrs%?\\t%1, %Q0, %R0"
7506 [(set_attr "conds" "set")
7507 (set_attr "type" "logics_reg")]
7508 )
7509
7510 ; This insn allows redundant compares to be removed by cse, nothing should
7511 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7512 ; is deleted later on. The match_dup will match the mode here, so that
7513 ; mode changes of the condition codes aren't lost by this even though we don't
7514 ; specify what they are.
7515
7516 (define_insn "*deleted_compare"
7517 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7518 "TARGET_32BIT"
7519 "\\t%@ deleted compare"
7520 [(set_attr "conds" "set")
7521 (set_attr "length" "0")
7522 (set_attr "type" "no_insn")]
7523 )
7524
7525 \f
7526 ;; Conditional branch insns
7527
7528 (define_expand "cbranch_cc"
7529 [(set (pc)
7530 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7531 (match_operand 2 "" "")])
7532 (label_ref (match_operand 3 "" ""))
7533 (pc)))]
7534 "TARGET_32BIT"
7535 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7536 operands[1], operands[2], NULL_RTX);
7537 operands[2] = const0_rtx;"
7538 )
7539
7540 ;;
7541 ;; Patterns to match conditional branch insns.
7542 ;;
7543
7544 (define_insn "arm_cond_branch"
7545 [(set (pc)
7546 (if_then_else (match_operator 1 "arm_comparison_operator"
7547 [(match_operand 2 "cc_register" "") (const_int 0)])
7548 (label_ref (match_operand 0 "" ""))
7549 (pc)))]
7550 "TARGET_32BIT"
7551 "*
7552 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7553 {
7554 arm_ccfsm_state += 2;
7555 return \"\";
7556 }
7557 return \"b%d1\\t%l0\";
7558 "
7559 [(set_attr "conds" "use")
7560 (set_attr "type" "branch")
7561 (set (attr "length")
7562 (if_then_else
7563 (and (match_test "TARGET_THUMB2")
7564 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7565 (le (minus (match_dup 0) (pc)) (const_int 256))))
7566 (const_int 2)
7567 (const_int 4)))]
7568 )
7569
7570 (define_insn "*arm_cond_branch_reversed"
7571 [(set (pc)
7572 (if_then_else (match_operator 1 "arm_comparison_operator"
7573 [(match_operand 2 "cc_register" "") (const_int 0)])
7574 (pc)
7575 (label_ref (match_operand 0 "" ""))))]
7576 "TARGET_32BIT"
7577 "*
7578 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7579 {
7580 arm_ccfsm_state += 2;
7581 return \"\";
7582 }
7583 return \"b%D1\\t%l0\";
7584 "
7585 [(set_attr "conds" "use")
7586 (set_attr "type" "branch")
7587 (set (attr "length")
7588 (if_then_else
7589 (and (match_test "TARGET_THUMB2")
7590 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7591 (le (minus (match_dup 0) (pc)) (const_int 256))))
7592 (const_int 2)
7593 (const_int 4)))]
7594 )
7595
7596 \f
7597
7598 ; scc insns
7599
7600 (define_expand "cstore_cc"
7601 [(set (match_operand:SI 0 "s_register_operand" "")
7602 (match_operator:SI 1 "" [(match_operand 2 "" "")
7603 (match_operand 3 "" "")]))]
7604 "TARGET_32BIT"
7605 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7606 operands[2], operands[3], NULL_RTX);
7607 operands[3] = const0_rtx;"
7608 )
7609
7610 (define_insn_and_split "*mov_scc"
7611 [(set (match_operand:SI 0 "s_register_operand" "=r")
7612 (match_operator:SI 1 "arm_comparison_operator_mode"
7613 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7614 "TARGET_ARM"
7615 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7616 "TARGET_ARM"
7617 [(set (match_dup 0)
7618 (if_then_else:SI (match_dup 1)
7619 (const_int 1)
7620 (const_int 0)))]
7621 ""
7622 [(set_attr "conds" "use")
7623 (set_attr "length" "8")
7624 (set_attr "type" "multiple")]
7625 )
7626
7627 (define_insn_and_split "*mov_negscc"
7628 [(set (match_operand:SI 0 "s_register_operand" "=r")
7629 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7630 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7631 "TARGET_ARM"
7632 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7633 "TARGET_ARM"
7634 [(set (match_dup 0)
7635 (if_then_else:SI (match_dup 1)
7636 (match_dup 3)
7637 (const_int 0)))]
7638 {
7639 operands[3] = GEN_INT (~0);
7640 }
7641 [(set_attr "conds" "use")
7642 (set_attr "length" "8")
7643 (set_attr "type" "multiple")]
7644 )
7645
7646 (define_insn_and_split "*mov_notscc"
7647 [(set (match_operand:SI 0 "s_register_operand" "=r")
7648 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7649 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7650 "TARGET_ARM"
7651 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7652 "TARGET_ARM"
7653 [(set (match_dup 0)
7654 (if_then_else:SI (match_dup 1)
7655 (match_dup 3)
7656 (match_dup 4)))]
7657 {
7658 operands[3] = GEN_INT (~1);
7659 operands[4] = GEN_INT (~0);
7660 }
7661 [(set_attr "conds" "use")
7662 (set_attr "length" "8")
7663 (set_attr "type" "multiple")]
7664 )
7665
7666 (define_expand "cstoresi4"
7667 [(set (match_operand:SI 0 "s_register_operand" "")
7668 (match_operator:SI 1 "expandable_comparison_operator"
7669 [(match_operand:SI 2 "s_register_operand" "")
7670 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7671 "TARGET_32BIT || TARGET_THUMB1"
7672 "{
7673 rtx op3, scratch, scratch2;
7674
7675 if (!TARGET_THUMB1)
7676 {
7677 if (!arm_add_operand (operands[3], SImode))
7678 operands[3] = force_reg (SImode, operands[3]);
7679 emit_insn (gen_cstore_cc (operands[0], operands[1],
7680 operands[2], operands[3]));
7681 DONE;
7682 }
7683
7684 if (operands[3] == const0_rtx)
7685 {
7686 switch (GET_CODE (operands[1]))
7687 {
7688 case EQ:
7689 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7690 break;
7691
7692 case NE:
7693 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7694 break;
7695
7696 case LE:
7697 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7698 NULL_RTX, 0, OPTAB_WIDEN);
7699 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7700 NULL_RTX, 0, OPTAB_WIDEN);
7701 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7702 operands[0], 1, OPTAB_WIDEN);
7703 break;
7704
7705 case GE:
7706 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7707 NULL_RTX, 1);
7708 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7709 NULL_RTX, 1, OPTAB_WIDEN);
7710 break;
7711
7712 case GT:
7713 scratch = expand_binop (SImode, ashr_optab, operands[2],
7714 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7715 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7716 NULL_RTX, 0, OPTAB_WIDEN);
7717 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7718 0, OPTAB_WIDEN);
7719 break;
7720
7721 /* LT is handled by generic code. No need for unsigned with 0. */
7722 default:
7723 FAIL;
7724 }
7725 DONE;
7726 }
7727
7728 switch (GET_CODE (operands[1]))
7729 {
7730 case EQ:
7731 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7732 NULL_RTX, 0, OPTAB_WIDEN);
7733 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7734 break;
7735
7736 case NE:
7737 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7738 NULL_RTX, 0, OPTAB_WIDEN);
7739 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7740 break;
7741
7742 case LE:
7743 op3 = force_reg (SImode, operands[3]);
7744
7745 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7746 NULL_RTX, 1, OPTAB_WIDEN);
7747 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7748 NULL_RTX, 0, OPTAB_WIDEN);
7749 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7750 op3, operands[2]));
7751 break;
7752
7753 case GE:
7754 op3 = operands[3];
7755 if (!thumb1_cmp_operand (op3, SImode))
7756 op3 = force_reg (SImode, op3);
7757 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7758 NULL_RTX, 0, OPTAB_WIDEN);
7759 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7760 NULL_RTX, 1, OPTAB_WIDEN);
7761 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7762 operands[2], op3));
7763 break;
7764
7765 case LEU:
7766 op3 = force_reg (SImode, operands[3]);
7767 scratch = force_reg (SImode, const0_rtx);
7768 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7769 op3, operands[2]));
7770 break;
7771
7772 case GEU:
7773 op3 = operands[3];
7774 if (!thumb1_cmp_operand (op3, SImode))
7775 op3 = force_reg (SImode, op3);
7776 scratch = force_reg (SImode, const0_rtx);
7777 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7778 operands[2], op3));
7779 break;
7780
7781 case LTU:
7782 op3 = operands[3];
7783 if (!thumb1_cmp_operand (op3, SImode))
7784 op3 = force_reg (SImode, op3);
7785 scratch = gen_reg_rtx (SImode);
7786 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7787 break;
7788
7789 case GTU:
7790 op3 = force_reg (SImode, operands[3]);
7791 scratch = gen_reg_rtx (SImode);
7792 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7793 break;
7794
7795 /* No good sequences for GT, LT. */
7796 default:
7797 FAIL;
7798 }
7799 DONE;
7800 }")
7801
7802 (define_expand "cstorehf4"
7803 [(set (match_operand:SI 0 "s_register_operand")
7804 (match_operator:SI 1 "expandable_comparison_operator"
7805 [(match_operand:HF 2 "s_register_operand")
7806 (match_operand:HF 3 "vfp_compare_operand")]))]
7807 "TARGET_VFP_FP16INST"
7808 {
7809 if (!arm_validize_comparison (&operands[1],
7810 &operands[2],
7811 &operands[3]))
7812 FAIL;
7813
7814 emit_insn (gen_cstore_cc (operands[0], operands[1],
7815 operands[2], operands[3]));
7816 DONE;
7817 }
7818 )
7819
7820 (define_expand "cstoresf4"
7821 [(set (match_operand:SI 0 "s_register_operand" "")
7822 (match_operator:SI 1 "expandable_comparison_operator"
7823 [(match_operand:SF 2 "s_register_operand" "")
7824 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7825 "TARGET_32BIT && TARGET_HARD_FLOAT"
7826 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7827 operands[2], operands[3])); DONE;"
7828 )
7829
7830 (define_expand "cstoredf4"
7831 [(set (match_operand:SI 0 "s_register_operand" "")
7832 (match_operator:SI 1 "expandable_comparison_operator"
7833 [(match_operand:DF 2 "s_register_operand" "")
7834 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7835 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7836 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7837 operands[2], operands[3])); DONE;"
7838 )
7839
7840 (define_expand "cstoredi4"
7841 [(set (match_operand:SI 0 "s_register_operand" "")
7842 (match_operator:SI 1 "expandable_comparison_operator"
7843 [(match_operand:DI 2 "s_register_operand" "")
7844 (match_operand:DI 3 "cmpdi_operand" "")]))]
7845 "TARGET_32BIT"
7846 "{
7847 if (!arm_validize_comparison (&operands[1],
7848 &operands[2],
7849 &operands[3]))
7850 FAIL;
7851 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7852 operands[3]));
7853 DONE;
7854 }"
7855 )
7856
7857 \f
7858 ;; Conditional move insns
7859
7860 (define_expand "movsicc"
7861 [(set (match_operand:SI 0 "s_register_operand" "")
7862 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7863 (match_operand:SI 2 "arm_not_operand" "")
7864 (match_operand:SI 3 "arm_not_operand" "")))]
7865 "TARGET_32BIT"
7866 "
7867 {
7868 enum rtx_code code;
7869 rtx ccreg;
7870
7871 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7872 &XEXP (operands[1], 1)))
7873 FAIL;
7874
7875 code = GET_CODE (operands[1]);
7876 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7877 XEXP (operands[1], 1), NULL_RTX);
7878 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7879 }"
7880 )
7881
7882 (define_expand "movhfcc"
7883 [(set (match_operand:HF 0 "s_register_operand")
7884 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7885 (match_operand:HF 2 "s_register_operand")
7886 (match_operand:HF 3 "s_register_operand")))]
7887 "TARGET_VFP_FP16INST"
7888 "
7889 {
7890 enum rtx_code code = GET_CODE (operands[1]);
7891 rtx ccreg;
7892
7893 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7894 &XEXP (operands[1], 1)))
7895 FAIL;
7896
7897 code = GET_CODE (operands[1]);
7898 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7899 XEXP (operands[1], 1), NULL_RTX);
7900 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7901 }"
7902 )
7903
7904 (define_expand "movsfcc"
7905 [(set (match_operand:SF 0 "s_register_operand" "")
7906 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7907 (match_operand:SF 2 "s_register_operand" "")
7908 (match_operand:SF 3 "s_register_operand" "")))]
7909 "TARGET_32BIT && TARGET_HARD_FLOAT"
7910 "
7911 {
7912 enum rtx_code code = GET_CODE (operands[1]);
7913 rtx ccreg;
7914
7915 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7916 &XEXP (operands[1], 1)))
7917 FAIL;
7918
7919 code = GET_CODE (operands[1]);
7920 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7921 XEXP (operands[1], 1), NULL_RTX);
7922 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7923 }"
7924 )
7925
7926 (define_expand "movdfcc"
7927 [(set (match_operand:DF 0 "s_register_operand" "")
7928 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7929 (match_operand:DF 2 "s_register_operand" "")
7930 (match_operand:DF 3 "s_register_operand" "")))]
7931 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7932 "
7933 {
7934 enum rtx_code code = GET_CODE (operands[1]);
7935 rtx ccreg;
7936
7937 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7938 &XEXP (operands[1], 1)))
7939 FAIL;
7940 code = GET_CODE (operands[1]);
7941 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7942 XEXP (operands[1], 1), NULL_RTX);
7943 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7944 }"
7945 )
7946
7947 (define_insn "*cmov<mode>"
7948 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7949 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7950 [(match_operand 2 "cc_register" "") (const_int 0)])
7951 (match_operand:SDF 3 "s_register_operand"
7952 "<F_constraint>")
7953 (match_operand:SDF 4 "s_register_operand"
7954 "<F_constraint>")))]
7955 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7956 "*
7957 {
7958 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7959 switch (code)
7960 {
7961 case ARM_GE:
7962 case ARM_GT:
7963 case ARM_EQ:
7964 case ARM_VS:
7965 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7966 case ARM_LT:
7967 case ARM_LE:
7968 case ARM_NE:
7969 case ARM_VC:
7970 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7971 default:
7972 gcc_unreachable ();
7973 }
7974 return \"\";
7975 }"
7976 [(set_attr "conds" "use")
7977 (set_attr "type" "fcsel")]
7978 )
7979
7980 (define_insn "*cmovhf"
7981 [(set (match_operand:HF 0 "s_register_operand" "=t")
7982 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7983 [(match_operand 2 "cc_register" "") (const_int 0)])
7984 (match_operand:HF 3 "s_register_operand" "t")
7985 (match_operand:HF 4 "s_register_operand" "t")))]
7986 "TARGET_VFP_FP16INST"
7987 "*
7988 {
7989 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7990 switch (code)
7991 {
7992 case ARM_GE:
7993 case ARM_GT:
7994 case ARM_EQ:
7995 case ARM_VS:
7996 return \"vsel%d1.f16\\t%0, %3, %4\";
7997 case ARM_LT:
7998 case ARM_LE:
7999 case ARM_NE:
8000 case ARM_VC:
8001 return \"vsel%D1.f16\\t%0, %4, %3\";
8002 default:
8003 gcc_unreachable ();
8004 }
8005 return \"\";
8006 }"
8007 [(set_attr "conds" "use")
8008 (set_attr "type" "fcsel")]
8009 )
8010
8011 (define_insn_and_split "*movsicc_insn"
8012 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
8013 (if_then_else:SI
8014 (match_operator 3 "arm_comparison_operator"
8015 [(match_operand 4 "cc_register" "") (const_int 0)])
8016 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
8017 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
8018 "TARGET_ARM"
8019 "@
8020 mov%D3\\t%0, %2
8021 mvn%D3\\t%0, #%B2
8022 mov%d3\\t%0, %1
8023 mvn%d3\\t%0, #%B1
8024 #
8025 #
8026 #
8027 #"
8028 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
8029 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
8030 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
8031 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
8032 "&& reload_completed"
8033 [(const_int 0)]
8034 {
8035 enum rtx_code rev_code;
8036 machine_mode mode;
8037 rtx rev_cond;
8038
8039 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8040 operands[3],
8041 gen_rtx_SET (operands[0], operands[1])));
8042
8043 rev_code = GET_CODE (operands[3]);
8044 mode = GET_MODE (operands[4]);
8045 if (mode == CCFPmode || mode == CCFPEmode)
8046 rev_code = reverse_condition_maybe_unordered (rev_code);
8047 else
8048 rev_code = reverse_condition (rev_code);
8049
8050 rev_cond = gen_rtx_fmt_ee (rev_code,
8051 VOIDmode,
8052 operands[4],
8053 const0_rtx);
8054 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
8055 rev_cond,
8056 gen_rtx_SET (operands[0], operands[2])));
8057 DONE;
8058 }
8059 [(set_attr "length" "4,4,4,4,8,8,8,8")
8060 (set_attr "conds" "use")
8061 (set_attr_alternative "type"
8062 [(if_then_else (match_operand 2 "const_int_operand" "")
8063 (const_string "mov_imm")
8064 (const_string "mov_reg"))
8065 (const_string "mvn_imm")
8066 (if_then_else (match_operand 1 "const_int_operand" "")
8067 (const_string "mov_imm")
8068 (const_string "mov_reg"))
8069 (const_string "mvn_imm")
8070 (const_string "multiple")
8071 (const_string "multiple")
8072 (const_string "multiple")
8073 (const_string "multiple")])]
8074 )
8075
8076 (define_insn "*movsfcc_soft_insn"
8077 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
8078 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
8079 [(match_operand 4 "cc_register" "") (const_int 0)])
8080 (match_operand:SF 1 "s_register_operand" "0,r")
8081 (match_operand:SF 2 "s_register_operand" "r,0")))]
8082 "TARGET_ARM && TARGET_SOFT_FLOAT"
8083 "@
8084 mov%D3\\t%0, %2
8085 mov%d3\\t%0, %1"
8086 [(set_attr "conds" "use")
8087 (set_attr "type" "mov_reg")]
8088 )
8089
8090 \f
8091 ;; Jump and linkage insns
8092
8093 (define_expand "jump"
8094 [(set (pc)
8095 (label_ref (match_operand 0 "" "")))]
8096 "TARGET_EITHER"
8097 ""
8098 )
8099
8100 (define_insn "*arm_jump"
8101 [(set (pc)
8102 (label_ref (match_operand 0 "" "")))]
8103 "TARGET_32BIT"
8104 "*
8105 {
8106 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8107 {
8108 arm_ccfsm_state += 2;
8109 return \"\";
8110 }
8111 return \"b%?\\t%l0\";
8112 }
8113 "
8114 [(set_attr "predicable" "yes")
8115 (set (attr "length")
8116 (if_then_else
8117 (and (match_test "TARGET_THUMB2")
8118 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8119 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8120 (const_int 2)
8121 (const_int 4)))
8122 (set_attr "type" "branch")]
8123 )
8124
8125 (define_expand "call"
8126 [(parallel [(call (match_operand 0 "memory_operand" "")
8127 (match_operand 1 "general_operand" ""))
8128 (use (match_operand 2 "" ""))
8129 (clobber (reg:SI LR_REGNUM))])]
8130 "TARGET_EITHER"
8131 "
8132 {
8133 rtx callee, pat;
8134 tree addr = MEM_EXPR (operands[0]);
8135
8136 /* In an untyped call, we can get NULL for operand 2. */
8137 if (operands[2] == NULL_RTX)
8138 operands[2] = const0_rtx;
8139
8140 /* Decide if we should generate indirect calls by loading the
8141 32-bit address of the callee into a register before performing the
8142 branch and link. */
8143 callee = XEXP (operands[0], 0);
8144 if (GET_CODE (callee) == SYMBOL_REF
8145 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8146 : !REG_P (callee))
8147 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8148
8149 if (detect_cmse_nonsecure_call (addr))
8150 {
8151 pat = gen_nonsecure_call_internal (operands[0], operands[1],
8152 operands[2]);
8153 emit_call_insn (pat);
8154 }
8155 else
8156 {
8157 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8158 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8159 }
8160 DONE;
8161 }"
8162 )
8163
8164 (define_expand "call_internal"
8165 [(parallel [(call (match_operand 0 "memory_operand" "")
8166 (match_operand 1 "general_operand" ""))
8167 (use (match_operand 2 "" ""))
8168 (clobber (reg:SI LR_REGNUM))])])
8169
8170 (define_expand "nonsecure_call_internal"
8171 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")]
8172 UNSPEC_NONSECURE_MEM)
8173 (match_operand 1 "general_operand" ""))
8174 (use (match_operand 2 "" ""))
8175 (clobber (reg:SI LR_REGNUM))
8176 (clobber (reg:SI 4))])]
8177 "use_cmse"
8178 "
8179 {
8180 rtx tmp;
8181 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
8182 gen_rtx_REG (SImode, 4),
8183 SImode);
8184
8185 operands[0] = replace_equiv_address (operands[0], tmp);
8186 }")
8187
8188 (define_insn "*call_reg_armv5"
8189 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8190 (match_operand 1 "" ""))
8191 (use (match_operand 2 "" ""))
8192 (clobber (reg:SI LR_REGNUM))]
8193 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8194 "blx%?\\t%0"
8195 [(set_attr "type" "call")]
8196 )
8197
8198 (define_insn "*call_reg_arm"
8199 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8200 (match_operand 1 "" ""))
8201 (use (match_operand 2 "" ""))
8202 (clobber (reg:SI LR_REGNUM))]
8203 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8204 "*
8205 return output_call (operands);
8206 "
8207 ;; length is worst case, normally it is only two
8208 [(set_attr "length" "12")
8209 (set_attr "type" "call")]
8210 )
8211
8212
8213 (define_expand "call_value"
8214 [(parallel [(set (match_operand 0 "" "")
8215 (call (match_operand 1 "memory_operand" "")
8216 (match_operand 2 "general_operand" "")))
8217 (use (match_operand 3 "" ""))
8218 (clobber (reg:SI LR_REGNUM))])]
8219 "TARGET_EITHER"
8220 "
8221 {
8222 rtx pat, callee;
8223 tree addr = MEM_EXPR (operands[1]);
8224
8225 /* In an untyped call, we can get NULL for operand 2. */
8226 if (operands[3] == 0)
8227 operands[3] = const0_rtx;
8228
8229 /* Decide if we should generate indirect calls by loading the
8230 32-bit address of the callee into a register before performing the
8231 branch and link. */
8232 callee = XEXP (operands[1], 0);
8233 if (GET_CODE (callee) == SYMBOL_REF
8234 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8235 : !REG_P (callee))
8236 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8237
8238 if (detect_cmse_nonsecure_call (addr))
8239 {
8240 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
8241 operands[2], operands[3]);
8242 emit_call_insn (pat);
8243 }
8244 else
8245 {
8246 pat = gen_call_value_internal (operands[0], operands[1],
8247 operands[2], operands[3]);
8248 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8249 }
8250 DONE;
8251 }"
8252 )
8253
8254 (define_expand "call_value_internal"
8255 [(parallel [(set (match_operand 0 "" "")
8256 (call (match_operand 1 "memory_operand" "")
8257 (match_operand 2 "general_operand" "")))
8258 (use (match_operand 3 "" ""))
8259 (clobber (reg:SI LR_REGNUM))])])
8260
8261 (define_expand "nonsecure_call_value_internal"
8262 [(parallel [(set (match_operand 0 "" "")
8263 (call (unspec:SI [(match_operand 1 "memory_operand" "")]
8264 UNSPEC_NONSECURE_MEM)
8265 (match_operand 2 "general_operand" "")))
8266 (use (match_operand 3 "" ""))
8267 (clobber (reg:SI LR_REGNUM))
8268 (clobber (reg:SI 4))])]
8269 "use_cmse"
8270 "
8271 {
8272 rtx tmp;
8273 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
8274 gen_rtx_REG (SImode, 4),
8275 SImode);
8276
8277 operands[1] = replace_equiv_address (operands[1], tmp);
8278 }")
8279
8280 (define_insn "*call_value_reg_armv5"
8281 [(set (match_operand 0 "" "")
8282 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8283 (match_operand 2 "" "")))
8284 (use (match_operand 3 "" ""))
8285 (clobber (reg:SI LR_REGNUM))]
8286 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8287 "blx%?\\t%1"
8288 [(set_attr "type" "call")]
8289 )
8290
8291 (define_insn "*call_value_reg_arm"
8292 [(set (match_operand 0 "" "")
8293 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8294 (match_operand 2 "" "")))
8295 (use (match_operand 3 "" ""))
8296 (clobber (reg:SI LR_REGNUM))]
8297 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8298 "*
8299 return output_call (&operands[1]);
8300 "
8301 [(set_attr "length" "12")
8302 (set_attr "type" "call")]
8303 )
8304
8305 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8306 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8307
8308 (define_insn "*call_symbol"
8309 [(call (mem:SI (match_operand:SI 0 "" ""))
8310 (match_operand 1 "" ""))
8311 (use (match_operand 2 "" ""))
8312 (clobber (reg:SI LR_REGNUM))]
8313 "TARGET_32BIT
8314 && !SIBLING_CALL_P (insn)
8315 && (GET_CODE (operands[0]) == SYMBOL_REF)
8316 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8317 "*
8318 {
8319 rtx op = operands[0];
8320
8321 /* Switch mode now when possible. */
8322 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8323 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8324 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8325
8326 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8327 }"
8328 [(set_attr "type" "call")]
8329 )
8330
8331 (define_insn "*call_value_symbol"
8332 [(set (match_operand 0 "" "")
8333 (call (mem:SI (match_operand:SI 1 "" ""))
8334 (match_operand:SI 2 "" "")))
8335 (use (match_operand 3 "" ""))
8336 (clobber (reg:SI LR_REGNUM))]
8337 "TARGET_32BIT
8338 && !SIBLING_CALL_P (insn)
8339 && (GET_CODE (operands[1]) == SYMBOL_REF)
8340 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8341 "*
8342 {
8343 rtx op = operands[1];
8344
8345 /* Switch mode now when possible. */
8346 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8347 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8348 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8349
8350 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8351 }"
8352 [(set_attr "type" "call")]
8353 )
8354
8355 (define_expand "sibcall_internal"
8356 [(parallel [(call (match_operand 0 "memory_operand" "")
8357 (match_operand 1 "general_operand" ""))
8358 (return)
8359 (use (match_operand 2 "" ""))])])
8360
8361 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8362 (define_expand "sibcall"
8363 [(parallel [(call (match_operand 0 "memory_operand" "")
8364 (match_operand 1 "general_operand" ""))
8365 (return)
8366 (use (match_operand 2 "" ""))])]
8367 "TARGET_32BIT"
8368 "
8369 {
8370 rtx pat;
8371
8372 if ((!REG_P (XEXP (operands[0], 0))
8373 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8374 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8375 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8376 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8377
8378 if (operands[2] == NULL_RTX)
8379 operands[2] = const0_rtx;
8380
8381 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8382 arm_emit_call_insn (pat, operands[0], true);
8383 DONE;
8384 }"
8385 )
8386
8387 (define_expand "sibcall_value_internal"
8388 [(parallel [(set (match_operand 0 "" "")
8389 (call (match_operand 1 "memory_operand" "")
8390 (match_operand 2 "general_operand" "")))
8391 (return)
8392 (use (match_operand 3 "" ""))])])
8393
8394 (define_expand "sibcall_value"
8395 [(parallel [(set (match_operand 0 "" "")
8396 (call (match_operand 1 "memory_operand" "")
8397 (match_operand 2 "general_operand" "")))
8398 (return)
8399 (use (match_operand 3 "" ""))])]
8400 "TARGET_32BIT"
8401 "
8402 {
8403 rtx pat;
8404
8405 if ((!REG_P (XEXP (operands[1], 0))
8406 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8407 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8408 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8409 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8410
8411 if (operands[3] == NULL_RTX)
8412 operands[3] = const0_rtx;
8413
8414 pat = gen_sibcall_value_internal (operands[0], operands[1],
8415 operands[2], operands[3]);
8416 arm_emit_call_insn (pat, operands[1], true);
8417 DONE;
8418 }"
8419 )
8420
8421 (define_insn "*sibcall_insn"
8422 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8423 (match_operand 1 "" ""))
8424 (return)
8425 (use (match_operand 2 "" ""))]
8426 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8427 "*
8428 if (which_alternative == 1)
8429 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8430 else
8431 {
8432 if (arm_arch5 || arm_arch4t)
8433 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8434 else
8435 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8436 }
8437 "
8438 [(set_attr "type" "call")]
8439 )
8440
8441 (define_insn "*sibcall_value_insn"
8442 [(set (match_operand 0 "" "")
8443 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8444 (match_operand 2 "" "")))
8445 (return)
8446 (use (match_operand 3 "" ""))]
8447 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8448 "*
8449 if (which_alternative == 1)
8450 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8451 else
8452 {
8453 if (arm_arch5 || arm_arch4t)
8454 return \"bx%?\\t%1\";
8455 else
8456 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8457 }
8458 "
8459 [(set_attr "type" "call")]
8460 )
8461
8462 (define_expand "<return_str>return"
8463 [(RETURNS)]
8464 "(TARGET_ARM || (TARGET_THUMB2
8465 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8466 && !IS_STACKALIGN (arm_current_func_type ())))
8467 <return_cond_false>"
8468 "
8469 {
8470 if (TARGET_THUMB2)
8471 {
8472 thumb2_expand_return (<return_simple_p>);
8473 DONE;
8474 }
8475 }
8476 "
8477 )
8478
8479 ;; Often the return insn will be the same as loading from memory, so set attr
8480 (define_insn "*arm_return"
8481 [(return)]
8482 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8483 "*
8484 {
8485 if (arm_ccfsm_state == 2)
8486 {
8487 arm_ccfsm_state += 2;
8488 return \"\";
8489 }
8490 return output_return_instruction (const_true_rtx, true, false, false);
8491 }"
8492 [(set_attr "type" "load_4")
8493 (set_attr "length" "12")
8494 (set_attr "predicable" "yes")]
8495 )
8496
8497 (define_insn "*cond_<return_str>return"
8498 [(set (pc)
8499 (if_then_else (match_operator 0 "arm_comparison_operator"
8500 [(match_operand 1 "cc_register" "") (const_int 0)])
8501 (RETURNS)
8502 (pc)))]
8503 "TARGET_ARM <return_cond_true>"
8504 "*
8505 {
8506 if (arm_ccfsm_state == 2)
8507 {
8508 arm_ccfsm_state += 2;
8509 return \"\";
8510 }
8511 return output_return_instruction (operands[0], true, false,
8512 <return_simple_p>);
8513 }"
8514 [(set_attr "conds" "use")
8515 (set_attr "length" "12")
8516 (set_attr "type" "load_4")]
8517 )
8518
8519 (define_insn "*cond_<return_str>return_inverted"
8520 [(set (pc)
8521 (if_then_else (match_operator 0 "arm_comparison_operator"
8522 [(match_operand 1 "cc_register" "") (const_int 0)])
8523 (pc)
8524 (RETURNS)))]
8525 "TARGET_ARM <return_cond_true>"
8526 "*
8527 {
8528 if (arm_ccfsm_state == 2)
8529 {
8530 arm_ccfsm_state += 2;
8531 return \"\";
8532 }
8533 return output_return_instruction (operands[0], true, true,
8534 <return_simple_p>);
8535 }"
8536 [(set_attr "conds" "use")
8537 (set_attr "length" "12")
8538 (set_attr "type" "load_4")]
8539 )
8540
8541 (define_insn "*arm_simple_return"
8542 [(simple_return)]
8543 "TARGET_ARM"
8544 "*
8545 {
8546 if (arm_ccfsm_state == 2)
8547 {
8548 arm_ccfsm_state += 2;
8549 return \"\";
8550 }
8551 return output_return_instruction (const_true_rtx, true, false, true);
8552 }"
8553 [(set_attr "type" "branch")
8554 (set_attr "length" "4")
8555 (set_attr "predicable" "yes")]
8556 )
8557
8558 ;; Generate a sequence of instructions to determine if the processor is
8559 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8560 ;; mask.
8561
8562 (define_expand "return_addr_mask"
8563 [(set (match_dup 1)
8564 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8565 (const_int 0)))
8566 (set (match_operand:SI 0 "s_register_operand" "")
8567 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8568 (const_int -1)
8569 (const_int 67108860)))] ; 0x03fffffc
8570 "TARGET_ARM"
8571 "
8572 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8573 ")
8574
8575 (define_insn "*check_arch2"
8576 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8577 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8578 (const_int 0)))]
8579 "TARGET_ARM"
8580 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8581 [(set_attr "length" "8")
8582 (set_attr "conds" "set")
8583 (set_attr "type" "multiple")]
8584 )
8585
8586 ;; Call subroutine returning any type.
8587
8588 (define_expand "untyped_call"
8589 [(parallel [(call (match_operand 0 "" "")
8590 (const_int 0))
8591 (match_operand 1 "" "")
8592 (match_operand 2 "" "")])]
8593 "TARGET_EITHER"
8594 "
8595 {
8596 int i;
8597 rtx par = gen_rtx_PARALLEL (VOIDmode,
8598 rtvec_alloc (XVECLEN (operands[2], 0)));
8599 rtx addr = gen_reg_rtx (Pmode);
8600 rtx mem;
8601 int size = 0;
8602
8603 emit_move_insn (addr, XEXP (operands[1], 0));
8604 mem = change_address (operands[1], BLKmode, addr);
8605
8606 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8607 {
8608 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8609
8610 /* Default code only uses r0 as a return value, but we could
8611 be using anything up to 4 registers. */
8612 if (REGNO (src) == R0_REGNUM)
8613 src = gen_rtx_REG (TImode, R0_REGNUM);
8614
8615 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8616 GEN_INT (size));
8617 size += GET_MODE_SIZE (GET_MODE (src));
8618 }
8619
8620 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8621
8622 size = 0;
8623
8624 for (i = 0; i < XVECLEN (par, 0); i++)
8625 {
8626 HOST_WIDE_INT offset = 0;
8627 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8628
8629 if (size != 0)
8630 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8631
8632 mem = change_address (mem, GET_MODE (reg), NULL);
8633 if (REGNO (reg) == R0_REGNUM)
8634 {
8635 /* On thumb we have to use a write-back instruction. */
8636 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8637 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8638 size = TARGET_ARM ? 16 : 0;
8639 }
8640 else
8641 {
8642 emit_move_insn (mem, reg);
8643 size = GET_MODE_SIZE (GET_MODE (reg));
8644 }
8645 }
8646
8647 /* The optimizer does not know that the call sets the function value
8648 registers we stored in the result block. We avoid problems by
8649 claiming that all hard registers are used and clobbered at this
8650 point. */
8651 emit_insn (gen_blockage ());
8652
8653 DONE;
8654 }"
8655 )
8656
8657 (define_expand "untyped_return"
8658 [(match_operand:BLK 0 "memory_operand" "")
8659 (match_operand 1 "" "")]
8660 "TARGET_EITHER"
8661 "
8662 {
8663 int i;
8664 rtx addr = gen_reg_rtx (Pmode);
8665 rtx mem;
8666 int size = 0;
8667
8668 emit_move_insn (addr, XEXP (operands[0], 0));
8669 mem = change_address (operands[0], BLKmode, addr);
8670
8671 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8672 {
8673 HOST_WIDE_INT offset = 0;
8674 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8675
8676 if (size != 0)
8677 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8678
8679 mem = change_address (mem, GET_MODE (reg), NULL);
8680 if (REGNO (reg) == R0_REGNUM)
8681 {
8682 /* On thumb we have to use a write-back instruction. */
8683 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8684 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8685 size = TARGET_ARM ? 16 : 0;
8686 }
8687 else
8688 {
8689 emit_move_insn (reg, mem);
8690 size = GET_MODE_SIZE (GET_MODE (reg));
8691 }
8692 }
8693
8694 /* Emit USE insns before the return. */
8695 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8696 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8697
8698 /* Construct the return. */
8699 expand_naked_return ();
8700
8701 DONE;
8702 }"
8703 )
8704
8705 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8706 ;; all of memory. This blocks insns from being moved across this point.
8707
8708 (define_insn "blockage"
8709 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8710 "TARGET_EITHER"
8711 ""
8712 [(set_attr "length" "0")
8713 (set_attr "type" "block")]
8714 )
8715
8716 (define_insn "probe_stack"
8717 [(set (match_operand:SI 0 "memory_operand" "=m")
8718 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8719 "TARGET_32BIT"
8720 "str%?\\tr0, %0"
8721 [(set_attr "type" "store_4")
8722 (set_attr "predicable" "yes")]
8723 )
8724
8725 (define_insn "probe_stack_range"
8726 [(set (match_operand:SI 0 "register_operand" "=r")
8727 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8728 (match_operand:SI 2 "register_operand" "r")]
8729 VUNSPEC_PROBE_STACK_RANGE))]
8730 "TARGET_32BIT"
8731 {
8732 return output_probe_stack_range (operands[0], operands[2]);
8733 }
8734 [(set_attr "type" "multiple")
8735 (set_attr "conds" "clob")]
8736 )
8737
8738 (define_expand "casesi"
8739 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8740 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8741 (match_operand:SI 2 "const_int_operand" "") ; total range
8742 (match_operand:SI 3 "" "") ; table label
8743 (match_operand:SI 4 "" "")] ; Out of range label
8744 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8745 "
8746 {
8747 enum insn_code code;
8748 if (operands[1] != const0_rtx)
8749 {
8750 rtx reg = gen_reg_rtx (SImode);
8751
8752 emit_insn (gen_addsi3 (reg, operands[0],
8753 gen_int_mode (-INTVAL (operands[1]),
8754 SImode)));
8755 operands[0] = reg;
8756 }
8757
8758 if (TARGET_ARM)
8759 code = CODE_FOR_arm_casesi_internal;
8760 else if (TARGET_THUMB1)
8761 code = CODE_FOR_thumb1_casesi_internal_pic;
8762 else if (flag_pic)
8763 code = CODE_FOR_thumb2_casesi_internal_pic;
8764 else
8765 code = CODE_FOR_thumb2_casesi_internal;
8766
8767 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8768 operands[2] = force_reg (SImode, operands[2]);
8769
8770 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8771 operands[3], operands[4]));
8772 DONE;
8773 }"
8774 )
8775
8776 ;; The USE in this pattern is needed to tell flow analysis that this is
8777 ;; a CASESI insn. It has no other purpose.
8778 (define_insn "arm_casesi_internal"
8779 [(parallel [(set (pc)
8780 (if_then_else
8781 (leu (match_operand:SI 0 "s_register_operand" "r")
8782 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8783 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8784 (label_ref (match_operand 2 "" ""))))
8785 (label_ref (match_operand 3 "" ""))))
8786 (clobber (reg:CC CC_REGNUM))
8787 (use (label_ref (match_dup 2)))])]
8788 "TARGET_ARM"
8789 "*
8790 if (flag_pic)
8791 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8792 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8793 "
8794 [(set_attr "conds" "clob")
8795 (set_attr "length" "12")
8796 (set_attr "type" "multiple")]
8797 )
8798
8799 (define_expand "indirect_jump"
8800 [(set (pc)
8801 (match_operand:SI 0 "s_register_operand" ""))]
8802 "TARGET_EITHER"
8803 "
8804 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8805 address and use bx. */
8806 if (TARGET_THUMB2)
8807 {
8808 rtx tmp;
8809 tmp = gen_reg_rtx (SImode);
8810 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8811 operands[0] = tmp;
8812 }
8813 "
8814 )
8815
8816 ;; NB Never uses BX.
8817 (define_insn "*arm_indirect_jump"
8818 [(set (pc)
8819 (match_operand:SI 0 "s_register_operand" "r"))]
8820 "TARGET_ARM"
8821 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8822 [(set_attr "predicable" "yes")
8823 (set_attr "type" "branch")]
8824 )
8825
8826 (define_insn "*load_indirect_jump"
8827 [(set (pc)
8828 (match_operand:SI 0 "memory_operand" "m"))]
8829 "TARGET_ARM"
8830 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8831 [(set_attr "type" "load_4")
8832 (set_attr "pool_range" "4096")
8833 (set_attr "neg_pool_range" "4084")
8834 (set_attr "predicable" "yes")]
8835 )
8836
8837 \f
8838 ;; Misc insns
8839
8840 (define_insn "nop"
8841 [(const_int 0)]
8842 "TARGET_EITHER"
8843 "nop"
8844 [(set (attr "length")
8845 (if_then_else (eq_attr "is_thumb" "yes")
8846 (const_int 2)
8847 (const_int 4)))
8848 (set_attr "type" "mov_reg")]
8849 )
8850
8851 (define_insn "trap"
8852 [(trap_if (const_int 1) (const_int 0))]
8853 ""
8854 "*
8855 if (TARGET_ARM)
8856 return \".inst\\t0xe7f000f0\";
8857 else
8858 return \".inst\\t0xdeff\";
8859 "
8860 [(set (attr "length")
8861 (if_then_else (eq_attr "is_thumb" "yes")
8862 (const_int 2)
8863 (const_int 4)))
8864 (set_attr "type" "trap")
8865 (set_attr "conds" "unconditional")]
8866 )
8867
8868 \f
8869 ;; Patterns to allow combination of arithmetic, cond code and shifts
8870
8871 (define_insn "*<arith_shift_insn>_multsi"
8872 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8873 (SHIFTABLE_OPS:SI
8874 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8875 (match_operand:SI 3 "power_of_two_operand" ""))
8876 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8877 "TARGET_32BIT"
8878 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8879 [(set_attr "predicable" "yes")
8880 (set_attr "predicable_short_it" "no")
8881 (set_attr "shift" "2")
8882 (set_attr "arch" "a,t2")
8883 (set_attr "type" "alu_shift_imm")])
8884
8885 (define_insn "*<arith_shift_insn>_shiftsi"
8886 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8887 (SHIFTABLE_OPS:SI
8888 (match_operator:SI 2 "shift_nomul_operator"
8889 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8890 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8891 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8892 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8893 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8894 [(set_attr "predicable" "yes")
8895 (set_attr "predicable_short_it" "no")
8896 (set_attr "shift" "3")
8897 (set_attr "arch" "a,t2,a")
8898 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8899
8900 (define_split
8901 [(set (match_operand:SI 0 "s_register_operand" "")
8902 (match_operator:SI 1 "shiftable_operator"
8903 [(match_operator:SI 2 "shiftable_operator"
8904 [(match_operator:SI 3 "shift_operator"
8905 [(match_operand:SI 4 "s_register_operand" "")
8906 (match_operand:SI 5 "reg_or_int_operand" "")])
8907 (match_operand:SI 6 "s_register_operand" "")])
8908 (match_operand:SI 7 "arm_rhs_operand" "")]))
8909 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8910 "TARGET_32BIT"
8911 [(set (match_dup 8)
8912 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8913 (match_dup 6)]))
8914 (set (match_dup 0)
8915 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8916 "")
8917
8918 (define_insn "*arith_shiftsi_compare0"
8919 [(set (reg:CC_NOOV CC_REGNUM)
8920 (compare:CC_NOOV
8921 (match_operator:SI 1 "shiftable_operator"
8922 [(match_operator:SI 3 "shift_operator"
8923 [(match_operand:SI 4 "s_register_operand" "r,r")
8924 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8925 (match_operand:SI 2 "s_register_operand" "r,r")])
8926 (const_int 0)))
8927 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8928 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8929 (match_dup 2)]))]
8930 "TARGET_32BIT"
8931 "%i1s%?\\t%0, %2, %4%S3"
8932 [(set_attr "conds" "set")
8933 (set_attr "shift" "4")
8934 (set_attr "arch" "32,a")
8935 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8936
8937 (define_insn "*arith_shiftsi_compare0_scratch"
8938 [(set (reg:CC_NOOV CC_REGNUM)
8939 (compare:CC_NOOV
8940 (match_operator:SI 1 "shiftable_operator"
8941 [(match_operator:SI 3 "shift_operator"
8942 [(match_operand:SI 4 "s_register_operand" "r,r")
8943 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8944 (match_operand:SI 2 "s_register_operand" "r,r")])
8945 (const_int 0)))
8946 (clobber (match_scratch:SI 0 "=r,r"))]
8947 "TARGET_32BIT"
8948 "%i1s%?\\t%0, %2, %4%S3"
8949 [(set_attr "conds" "set")
8950 (set_attr "shift" "4")
8951 (set_attr "arch" "32,a")
8952 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8953
8954 (define_insn "*sub_shiftsi"
8955 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8956 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8957 (match_operator:SI 2 "shift_operator"
8958 [(match_operand:SI 3 "s_register_operand" "r,r")
8959 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8960 "TARGET_32BIT"
8961 "sub%?\\t%0, %1, %3%S2"
8962 [(set_attr "predicable" "yes")
8963 (set_attr "shift" "3")
8964 (set_attr "arch" "32,a")
8965 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8966
8967 (define_insn "*sub_shiftsi_compare0"
8968 [(set (reg:CC_NOOV CC_REGNUM)
8969 (compare:CC_NOOV
8970 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8971 (match_operator:SI 2 "shift_operator"
8972 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8973 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8974 (const_int 0)))
8975 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8976 (minus:SI (match_dup 1)
8977 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8978 "TARGET_32BIT"
8979 "subs%?\\t%0, %1, %3%S2"
8980 [(set_attr "conds" "set")
8981 (set_attr "shift" "3")
8982 (set_attr "arch" "32,a,a")
8983 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8984
8985 (define_insn "*sub_shiftsi_compare0_scratch"
8986 [(set (reg:CC_NOOV CC_REGNUM)
8987 (compare:CC_NOOV
8988 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8989 (match_operator:SI 2 "shift_operator"
8990 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8991 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8992 (const_int 0)))
8993 (clobber (match_scratch:SI 0 "=r,r,r"))]
8994 "TARGET_32BIT"
8995 "subs%?\\t%0, %1, %3%S2"
8996 [(set_attr "conds" "set")
8997 (set_attr "shift" "3")
8998 (set_attr "arch" "32,a,a")
8999 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
9000 \f
9001
9002 (define_insn_and_split "*and_scc"
9003 [(set (match_operand:SI 0 "s_register_operand" "=r")
9004 (and:SI (match_operator:SI 1 "arm_comparison_operator"
9005 [(match_operand 2 "cc_register" "") (const_int 0)])
9006 (match_operand:SI 3 "s_register_operand" "r")))]
9007 "TARGET_ARM"
9008 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
9009 "&& reload_completed"
9010 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
9011 (cond_exec (match_dup 4) (set (match_dup 0)
9012 (and:SI (match_dup 3) (const_int 1))))]
9013 {
9014 machine_mode mode = GET_MODE (operands[2]);
9015 enum rtx_code rc = GET_CODE (operands[1]);
9016
9017 /* Note that operands[4] is the same as operands[1],
9018 but with VOIDmode as the result. */
9019 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9020 if (mode == CCFPmode || mode == CCFPEmode)
9021 rc = reverse_condition_maybe_unordered (rc);
9022 else
9023 rc = reverse_condition (rc);
9024 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9025 }
9026 [(set_attr "conds" "use")
9027 (set_attr "type" "multiple")
9028 (set_attr "length" "8")]
9029 )
9030
9031 (define_insn_and_split "*ior_scc"
9032 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9033 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
9034 [(match_operand 2 "cc_register" "") (const_int 0)])
9035 (match_operand:SI 3 "s_register_operand" "0,?r")))]
9036 "TARGET_ARM"
9037 "@
9038 orr%d1\\t%0, %3, #1
9039 #"
9040 "&& reload_completed
9041 && REGNO (operands [0]) != REGNO (operands[3])"
9042 ;; && which_alternative == 1
9043 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
9044 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
9045 (cond_exec (match_dup 4) (set (match_dup 0)
9046 (ior:SI (match_dup 3) (const_int 1))))]
9047 {
9048 machine_mode mode = GET_MODE (operands[2]);
9049 enum rtx_code rc = GET_CODE (operands[1]);
9050
9051 /* Note that operands[4] is the same as operands[1],
9052 but with VOIDmode as the result. */
9053 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9054 if (mode == CCFPmode || mode == CCFPEmode)
9055 rc = reverse_condition_maybe_unordered (rc);
9056 else
9057 rc = reverse_condition (rc);
9058 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
9059 }
9060 [(set_attr "conds" "use")
9061 (set_attr "length" "4,8")
9062 (set_attr "type" "logic_imm,multiple")]
9063 )
9064
9065 ; A series of splitters for the compare_scc pattern below. Note that
9066 ; order is important.
9067 (define_split
9068 [(set (match_operand:SI 0 "s_register_operand" "")
9069 (lt:SI (match_operand:SI 1 "s_register_operand" "")
9070 (const_int 0)))
9071 (clobber (reg:CC CC_REGNUM))]
9072 "TARGET_32BIT && reload_completed"
9073 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
9074
9075 (define_split
9076 [(set (match_operand:SI 0 "s_register_operand" "")
9077 (ge:SI (match_operand:SI 1 "s_register_operand" "")
9078 (const_int 0)))
9079 (clobber (reg:CC CC_REGNUM))]
9080 "TARGET_32BIT && reload_completed"
9081 [(set (match_dup 0) (not:SI (match_dup 1)))
9082 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
9083
9084 (define_split
9085 [(set (match_operand:SI 0 "s_register_operand" "")
9086 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9087 (const_int 0)))
9088 (clobber (reg:CC CC_REGNUM))]
9089 "arm_arch5 && TARGET_32BIT"
9090 [(set (match_dup 0) (clz:SI (match_dup 1)))
9091 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9092 )
9093
9094 (define_split
9095 [(set (match_operand:SI 0 "s_register_operand" "")
9096 (eq:SI (match_operand:SI 1 "s_register_operand" "")
9097 (const_int 0)))
9098 (clobber (reg:CC CC_REGNUM))]
9099 "TARGET_32BIT && reload_completed"
9100 [(parallel
9101 [(set (reg:CC CC_REGNUM)
9102 (compare:CC (const_int 1) (match_dup 1)))
9103 (set (match_dup 0)
9104 (minus:SI (const_int 1) (match_dup 1)))])
9105 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
9106 (set (match_dup 0) (const_int 0)))])
9107
9108 (define_split
9109 [(set (match_operand:SI 0 "s_register_operand" "")
9110 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9111 (match_operand:SI 2 "const_int_operand" "")))
9112 (clobber (reg:CC CC_REGNUM))]
9113 "TARGET_32BIT && reload_completed"
9114 [(parallel
9115 [(set (reg:CC CC_REGNUM)
9116 (compare:CC (match_dup 1) (match_dup 2)))
9117 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
9118 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
9119 (set (match_dup 0) (const_int 1)))]
9120 {
9121 operands[3] = GEN_INT (-INTVAL (operands[2]));
9122 })
9123
9124 (define_split
9125 [(set (match_operand:SI 0 "s_register_operand" "")
9126 (ne:SI (match_operand:SI 1 "s_register_operand" "")
9127 (match_operand:SI 2 "arm_add_operand" "")))
9128 (clobber (reg:CC CC_REGNUM))]
9129 "TARGET_32BIT && reload_completed"
9130 [(parallel
9131 [(set (reg:CC_NOOV CC_REGNUM)
9132 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
9133 (const_int 0)))
9134 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
9135 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
9136 (set (match_dup 0) (const_int 1)))])
9137
9138 (define_insn_and_split "*compare_scc"
9139 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9140 (match_operator:SI 1 "arm_comparison_operator"
9141 [(match_operand:SI 2 "s_register_operand" "r,r")
9142 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
9143 (clobber (reg:CC CC_REGNUM))]
9144 "TARGET_32BIT"
9145 "#"
9146 "&& reload_completed"
9147 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
9148 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
9149 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
9150 {
9151 rtx tmp1;
9152 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
9153 operands[2], operands[3]);
9154 enum rtx_code rc = GET_CODE (operands[1]);
9155
9156 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
9157
9158 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9159 if (mode == CCFPmode || mode == CCFPEmode)
9160 rc = reverse_condition_maybe_unordered (rc);
9161 else
9162 rc = reverse_condition (rc);
9163 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9164 }
9165 [(set_attr "type" "multiple")]
9166 )
9167
9168 ;; Attempt to improve the sequence generated by the compare_scc splitters
9169 ;; not to use conditional execution.
9170
9171 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9172 ;; clz Rd, reg1
9173 ;; lsr Rd, Rd, #5
9174 (define_peephole2
9175 [(set (reg:CC CC_REGNUM)
9176 (compare:CC (match_operand:SI 1 "register_operand" "")
9177 (const_int 0)))
9178 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9179 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9180 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9181 (set (match_dup 0) (const_int 1)))]
9182 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9183 [(set (match_dup 0) (clz:SI (match_dup 1)))
9184 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9185 )
9186
9187 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9188 ;; negs Rd, reg1
9189 ;; adc Rd, Rd, reg1
9190 (define_peephole2
9191 [(set (reg:CC CC_REGNUM)
9192 (compare:CC (match_operand:SI 1 "register_operand" "")
9193 (const_int 0)))
9194 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9195 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9196 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9197 (set (match_dup 0) (const_int 1)))
9198 (match_scratch:SI 2 "r")]
9199 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9200 [(parallel
9201 [(set (reg:CC CC_REGNUM)
9202 (compare:CC (const_int 0) (match_dup 1)))
9203 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9204 (set (match_dup 0)
9205 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9206 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9207 )
9208
9209 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9210 ;; sub Rd, Reg1, reg2
9211 ;; clz Rd, Rd
9212 ;; lsr Rd, Rd, #5
9213 (define_peephole2
9214 [(set (reg:CC CC_REGNUM)
9215 (compare:CC (match_operand:SI 1 "register_operand" "")
9216 (match_operand:SI 2 "arm_rhs_operand" "")))
9217 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9218 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9219 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9220 (set (match_dup 0) (const_int 1)))]
9221 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9222 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9223 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9224 (set (match_dup 0) (clz:SI (match_dup 0)))
9225 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9226 )
9227
9228
9229 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9230 ;; sub T1, Reg1, reg2
9231 ;; negs Rd, T1
9232 ;; adc Rd, Rd, T1
9233 (define_peephole2
9234 [(set (reg:CC CC_REGNUM)
9235 (compare:CC (match_operand:SI 1 "register_operand" "")
9236 (match_operand:SI 2 "arm_rhs_operand" "")))
9237 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9238 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9239 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9240 (set (match_dup 0) (const_int 1)))
9241 (match_scratch:SI 3 "r")]
9242 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9243 [(set (match_dup 3) (match_dup 4))
9244 (parallel
9245 [(set (reg:CC CC_REGNUM)
9246 (compare:CC (const_int 0) (match_dup 3)))
9247 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9248 (set (match_dup 0)
9249 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9250 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9251 "
9252 if (CONST_INT_P (operands[2]))
9253 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9254 else
9255 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9256 ")
9257
9258 (define_insn "*cond_move"
9259 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9260 (if_then_else:SI (match_operator 3 "equality_operator"
9261 [(match_operator 4 "arm_comparison_operator"
9262 [(match_operand 5 "cc_register" "") (const_int 0)])
9263 (const_int 0)])
9264 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9265 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9266 "TARGET_ARM"
9267 "*
9268 if (GET_CODE (operands[3]) == NE)
9269 {
9270 if (which_alternative != 1)
9271 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9272 if (which_alternative != 0)
9273 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9274 return \"\";
9275 }
9276 if (which_alternative != 0)
9277 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9278 if (which_alternative != 1)
9279 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9280 return \"\";
9281 "
9282 [(set_attr "conds" "use")
9283 (set_attr_alternative "type"
9284 [(if_then_else (match_operand 2 "const_int_operand" "")
9285 (const_string "mov_imm")
9286 (const_string "mov_reg"))
9287 (if_then_else (match_operand 1 "const_int_operand" "")
9288 (const_string "mov_imm")
9289 (const_string "mov_reg"))
9290 (const_string "multiple")])
9291 (set_attr "length" "4,4,8")]
9292 )
9293
9294 (define_insn "*cond_arith"
9295 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9296 (match_operator:SI 5 "shiftable_operator"
9297 [(match_operator:SI 4 "arm_comparison_operator"
9298 [(match_operand:SI 2 "s_register_operand" "r,r")
9299 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9300 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9301 (clobber (reg:CC CC_REGNUM))]
9302 "TARGET_ARM"
9303 "*
9304 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9305 return \"%i5\\t%0, %1, %2, lsr #31\";
9306
9307 output_asm_insn (\"cmp\\t%2, %3\", operands);
9308 if (GET_CODE (operands[5]) == AND)
9309 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9310 else if (GET_CODE (operands[5]) == MINUS)
9311 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9312 else if (which_alternative != 0)
9313 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9314 return \"%i5%d4\\t%0, %1, #1\";
9315 "
9316 [(set_attr "conds" "clob")
9317 (set_attr "length" "12")
9318 (set_attr "type" "multiple")]
9319 )
9320
9321 (define_insn "*cond_sub"
9322 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9323 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9324 (match_operator:SI 4 "arm_comparison_operator"
9325 [(match_operand:SI 2 "s_register_operand" "r,r")
9326 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9327 (clobber (reg:CC CC_REGNUM))]
9328 "TARGET_ARM"
9329 "*
9330 output_asm_insn (\"cmp\\t%2, %3\", operands);
9331 if (which_alternative != 0)
9332 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9333 return \"sub%d4\\t%0, %1, #1\";
9334 "
9335 [(set_attr "conds" "clob")
9336 (set_attr "length" "8,12")
9337 (set_attr "type" "multiple")]
9338 )
9339
9340 (define_insn "*cmp_ite0"
9341 [(set (match_operand 6 "dominant_cc_register" "")
9342 (compare
9343 (if_then_else:SI
9344 (match_operator 4 "arm_comparison_operator"
9345 [(match_operand:SI 0 "s_register_operand"
9346 "l,l,l,r,r,r,r,r,r")
9347 (match_operand:SI 1 "arm_add_operand"
9348 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9349 (match_operator:SI 5 "arm_comparison_operator"
9350 [(match_operand:SI 2 "s_register_operand"
9351 "l,r,r,l,l,r,r,r,r")
9352 (match_operand:SI 3 "arm_add_operand"
9353 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9354 (const_int 0))
9355 (const_int 0)))]
9356 "TARGET_32BIT"
9357 "*
9358 {
9359 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9360 {
9361 {\"cmp%d5\\t%0, %1\",
9362 \"cmp%d4\\t%2, %3\"},
9363 {\"cmn%d5\\t%0, #%n1\",
9364 \"cmp%d4\\t%2, %3\"},
9365 {\"cmp%d5\\t%0, %1\",
9366 \"cmn%d4\\t%2, #%n3\"},
9367 {\"cmn%d5\\t%0, #%n1\",
9368 \"cmn%d4\\t%2, #%n3\"}
9369 };
9370 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9371 {
9372 {\"cmp\\t%2, %3\",
9373 \"cmp\\t%0, %1\"},
9374 {\"cmp\\t%2, %3\",
9375 \"cmn\\t%0, #%n1\"},
9376 {\"cmn\\t%2, #%n3\",
9377 \"cmp\\t%0, %1\"},
9378 {\"cmn\\t%2, #%n3\",
9379 \"cmn\\t%0, #%n1\"}
9380 };
9381 static const char * const ite[2] =
9382 {
9383 \"it\\t%d5\",
9384 \"it\\t%d4\"
9385 };
9386 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9387 CMP_CMP, CMN_CMP, CMP_CMP,
9388 CMN_CMP, CMP_CMN, CMN_CMN};
9389 int swap =
9390 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9391
9392 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9393 if (TARGET_THUMB2) {
9394 output_asm_insn (ite[swap], operands);
9395 }
9396 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9397 return \"\";
9398 }"
9399 [(set_attr "conds" "set")
9400 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9401 (set_attr "type" "multiple")
9402 (set_attr_alternative "length"
9403 [(const_int 6)
9404 (const_int 8)
9405 (const_int 8)
9406 (const_int 8)
9407 (const_int 8)
9408 (if_then_else (eq_attr "is_thumb" "no")
9409 (const_int 8)
9410 (const_int 10))
9411 (if_then_else (eq_attr "is_thumb" "no")
9412 (const_int 8)
9413 (const_int 10))
9414 (if_then_else (eq_attr "is_thumb" "no")
9415 (const_int 8)
9416 (const_int 10))
9417 (if_then_else (eq_attr "is_thumb" "no")
9418 (const_int 8)
9419 (const_int 10))])]
9420 )
9421
9422 (define_insn "*cmp_ite1"
9423 [(set (match_operand 6 "dominant_cc_register" "")
9424 (compare
9425 (if_then_else:SI
9426 (match_operator 4 "arm_comparison_operator"
9427 [(match_operand:SI 0 "s_register_operand"
9428 "l,l,l,r,r,r,r,r,r")
9429 (match_operand:SI 1 "arm_add_operand"
9430 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9431 (match_operator:SI 5 "arm_comparison_operator"
9432 [(match_operand:SI 2 "s_register_operand"
9433 "l,r,r,l,l,r,r,r,r")
9434 (match_operand:SI 3 "arm_add_operand"
9435 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9436 (const_int 1))
9437 (const_int 0)))]
9438 "TARGET_32BIT"
9439 "*
9440 {
9441 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9442 {
9443 {\"cmp\\t%0, %1\",
9444 \"cmp\\t%2, %3\"},
9445 {\"cmn\\t%0, #%n1\",
9446 \"cmp\\t%2, %3\"},
9447 {\"cmp\\t%0, %1\",
9448 \"cmn\\t%2, #%n3\"},
9449 {\"cmn\\t%0, #%n1\",
9450 \"cmn\\t%2, #%n3\"}
9451 };
9452 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9453 {
9454 {\"cmp%d4\\t%2, %3\",
9455 \"cmp%D5\\t%0, %1\"},
9456 {\"cmp%d4\\t%2, %3\",
9457 \"cmn%D5\\t%0, #%n1\"},
9458 {\"cmn%d4\\t%2, #%n3\",
9459 \"cmp%D5\\t%0, %1\"},
9460 {\"cmn%d4\\t%2, #%n3\",
9461 \"cmn%D5\\t%0, #%n1\"}
9462 };
9463 static const char * const ite[2] =
9464 {
9465 \"it\\t%d4\",
9466 \"it\\t%D5\"
9467 };
9468 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9469 CMP_CMP, CMN_CMP, CMP_CMP,
9470 CMN_CMP, CMP_CMN, CMN_CMN};
9471 int swap =
9472 comparison_dominates_p (GET_CODE (operands[5]),
9473 reverse_condition (GET_CODE (operands[4])));
9474
9475 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9476 if (TARGET_THUMB2) {
9477 output_asm_insn (ite[swap], operands);
9478 }
9479 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9480 return \"\";
9481 }"
9482 [(set_attr "conds" "set")
9483 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9484 (set_attr_alternative "length"
9485 [(const_int 6)
9486 (const_int 8)
9487 (const_int 8)
9488 (const_int 8)
9489 (const_int 8)
9490 (if_then_else (eq_attr "is_thumb" "no")
9491 (const_int 8)
9492 (const_int 10))
9493 (if_then_else (eq_attr "is_thumb" "no")
9494 (const_int 8)
9495 (const_int 10))
9496 (if_then_else (eq_attr "is_thumb" "no")
9497 (const_int 8)
9498 (const_int 10))
9499 (if_then_else (eq_attr "is_thumb" "no")
9500 (const_int 8)
9501 (const_int 10))])
9502 (set_attr "type" "multiple")]
9503 )
9504
9505 (define_insn "*cmp_and"
9506 [(set (match_operand 6 "dominant_cc_register" "")
9507 (compare
9508 (and:SI
9509 (match_operator 4 "arm_comparison_operator"
9510 [(match_operand:SI 0 "s_register_operand"
9511 "l,l,l,r,r,r,r,r,r")
9512 (match_operand:SI 1 "arm_add_operand"
9513 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9514 (match_operator:SI 5 "arm_comparison_operator"
9515 [(match_operand:SI 2 "s_register_operand"
9516 "l,r,r,l,l,r,r,r,r")
9517 (match_operand:SI 3 "arm_add_operand"
9518 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9519 (const_int 0)))]
9520 "TARGET_32BIT"
9521 "*
9522 {
9523 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9524 {
9525 {\"cmp%d5\\t%0, %1\",
9526 \"cmp%d4\\t%2, %3\"},
9527 {\"cmn%d5\\t%0, #%n1\",
9528 \"cmp%d4\\t%2, %3\"},
9529 {\"cmp%d5\\t%0, %1\",
9530 \"cmn%d4\\t%2, #%n3\"},
9531 {\"cmn%d5\\t%0, #%n1\",
9532 \"cmn%d4\\t%2, #%n3\"}
9533 };
9534 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9535 {
9536 {\"cmp\\t%2, %3\",
9537 \"cmp\\t%0, %1\"},
9538 {\"cmp\\t%2, %3\",
9539 \"cmn\\t%0, #%n1\"},
9540 {\"cmn\\t%2, #%n3\",
9541 \"cmp\\t%0, %1\"},
9542 {\"cmn\\t%2, #%n3\",
9543 \"cmn\\t%0, #%n1\"}
9544 };
9545 static const char *const ite[2] =
9546 {
9547 \"it\\t%d5\",
9548 \"it\\t%d4\"
9549 };
9550 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9551 CMP_CMP, CMN_CMP, CMP_CMP,
9552 CMN_CMP, CMP_CMN, CMN_CMN};
9553 int swap =
9554 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9555
9556 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9557 if (TARGET_THUMB2) {
9558 output_asm_insn (ite[swap], operands);
9559 }
9560 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9561 return \"\";
9562 }"
9563 [(set_attr "conds" "set")
9564 (set_attr "predicable" "no")
9565 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9566 (set_attr_alternative "length"
9567 [(const_int 6)
9568 (const_int 8)
9569 (const_int 8)
9570 (const_int 8)
9571 (const_int 8)
9572 (if_then_else (eq_attr "is_thumb" "no")
9573 (const_int 8)
9574 (const_int 10))
9575 (if_then_else (eq_attr "is_thumb" "no")
9576 (const_int 8)
9577 (const_int 10))
9578 (if_then_else (eq_attr "is_thumb" "no")
9579 (const_int 8)
9580 (const_int 10))
9581 (if_then_else (eq_attr "is_thumb" "no")
9582 (const_int 8)
9583 (const_int 10))])
9584 (set_attr "type" "multiple")]
9585 )
9586
9587 (define_insn "*cmp_ior"
9588 [(set (match_operand 6 "dominant_cc_register" "")
9589 (compare
9590 (ior:SI
9591 (match_operator 4 "arm_comparison_operator"
9592 [(match_operand:SI 0 "s_register_operand"
9593 "l,l,l,r,r,r,r,r,r")
9594 (match_operand:SI 1 "arm_add_operand"
9595 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9596 (match_operator:SI 5 "arm_comparison_operator"
9597 [(match_operand:SI 2 "s_register_operand"
9598 "l,r,r,l,l,r,r,r,r")
9599 (match_operand:SI 3 "arm_add_operand"
9600 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9601 (const_int 0)))]
9602 "TARGET_32BIT"
9603 "*
9604 {
9605 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9606 {
9607 {\"cmp\\t%0, %1\",
9608 \"cmp\\t%2, %3\"},
9609 {\"cmn\\t%0, #%n1\",
9610 \"cmp\\t%2, %3\"},
9611 {\"cmp\\t%0, %1\",
9612 \"cmn\\t%2, #%n3\"},
9613 {\"cmn\\t%0, #%n1\",
9614 \"cmn\\t%2, #%n3\"}
9615 };
9616 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9617 {
9618 {\"cmp%D4\\t%2, %3\",
9619 \"cmp%D5\\t%0, %1\"},
9620 {\"cmp%D4\\t%2, %3\",
9621 \"cmn%D5\\t%0, #%n1\"},
9622 {\"cmn%D4\\t%2, #%n3\",
9623 \"cmp%D5\\t%0, %1\"},
9624 {\"cmn%D4\\t%2, #%n3\",
9625 \"cmn%D5\\t%0, #%n1\"}
9626 };
9627 static const char *const ite[2] =
9628 {
9629 \"it\\t%D4\",
9630 \"it\\t%D5\"
9631 };
9632 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9633 CMP_CMP, CMN_CMP, CMP_CMP,
9634 CMN_CMP, CMP_CMN, CMN_CMN};
9635 int swap =
9636 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9637
9638 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9639 if (TARGET_THUMB2) {
9640 output_asm_insn (ite[swap], operands);
9641 }
9642 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9643 return \"\";
9644 }
9645 "
9646 [(set_attr "conds" "set")
9647 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9648 (set_attr_alternative "length"
9649 [(const_int 6)
9650 (const_int 8)
9651 (const_int 8)
9652 (const_int 8)
9653 (const_int 8)
9654 (if_then_else (eq_attr "is_thumb" "no")
9655 (const_int 8)
9656 (const_int 10))
9657 (if_then_else (eq_attr "is_thumb" "no")
9658 (const_int 8)
9659 (const_int 10))
9660 (if_then_else (eq_attr "is_thumb" "no")
9661 (const_int 8)
9662 (const_int 10))
9663 (if_then_else (eq_attr "is_thumb" "no")
9664 (const_int 8)
9665 (const_int 10))])
9666 (set_attr "type" "multiple")]
9667 )
9668
9669 (define_insn_and_split "*ior_scc_scc"
9670 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9671 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9672 [(match_operand:SI 1 "s_register_operand" "r")
9673 (match_operand:SI 2 "arm_add_operand" "rIL")])
9674 (match_operator:SI 6 "arm_comparison_operator"
9675 [(match_operand:SI 4 "s_register_operand" "r")
9676 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9677 (clobber (reg:CC CC_REGNUM))]
9678 "TARGET_32BIT
9679 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9680 != CCmode)"
9681 "#"
9682 "TARGET_32BIT && reload_completed"
9683 [(set (match_dup 7)
9684 (compare
9685 (ior:SI
9686 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9687 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9688 (const_int 0)))
9689 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9690 "operands[7]
9691 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9692 DOM_CC_X_OR_Y),
9693 CC_REGNUM);"
9694 [(set_attr "conds" "clob")
9695 (set_attr "length" "16")
9696 (set_attr "type" "multiple")]
9697 )
9698
9699 ; If the above pattern is followed by a CMP insn, then the compare is
9700 ; redundant, since we can rework the conditional instruction that follows.
9701 (define_insn_and_split "*ior_scc_scc_cmp"
9702 [(set (match_operand 0 "dominant_cc_register" "")
9703 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9704 [(match_operand:SI 1 "s_register_operand" "r")
9705 (match_operand:SI 2 "arm_add_operand" "rIL")])
9706 (match_operator:SI 6 "arm_comparison_operator"
9707 [(match_operand:SI 4 "s_register_operand" "r")
9708 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9709 (const_int 0)))
9710 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9711 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9712 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9713 "TARGET_32BIT"
9714 "#"
9715 "TARGET_32BIT && reload_completed"
9716 [(set (match_dup 0)
9717 (compare
9718 (ior:SI
9719 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9720 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9721 (const_int 0)))
9722 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9723 ""
9724 [(set_attr "conds" "set")
9725 (set_attr "length" "16")
9726 (set_attr "type" "multiple")]
9727 )
9728
9729 (define_insn_and_split "*and_scc_scc"
9730 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9731 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9732 [(match_operand:SI 1 "s_register_operand" "r")
9733 (match_operand:SI 2 "arm_add_operand" "rIL")])
9734 (match_operator:SI 6 "arm_comparison_operator"
9735 [(match_operand:SI 4 "s_register_operand" "r")
9736 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9737 (clobber (reg:CC CC_REGNUM))]
9738 "TARGET_32BIT
9739 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9740 != CCmode)"
9741 "#"
9742 "TARGET_32BIT && reload_completed
9743 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9744 != CCmode)"
9745 [(set (match_dup 7)
9746 (compare
9747 (and:SI
9748 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9749 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9750 (const_int 0)))
9751 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9752 "operands[7]
9753 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9754 DOM_CC_X_AND_Y),
9755 CC_REGNUM);"
9756 [(set_attr "conds" "clob")
9757 (set_attr "length" "16")
9758 (set_attr "type" "multiple")]
9759 )
9760
9761 ; If the above pattern is followed by a CMP insn, then the compare is
9762 ; redundant, since we can rework the conditional instruction that follows.
9763 (define_insn_and_split "*and_scc_scc_cmp"
9764 [(set (match_operand 0 "dominant_cc_register" "")
9765 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9766 [(match_operand:SI 1 "s_register_operand" "r")
9767 (match_operand:SI 2 "arm_add_operand" "rIL")])
9768 (match_operator:SI 6 "arm_comparison_operator"
9769 [(match_operand:SI 4 "s_register_operand" "r")
9770 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9771 (const_int 0)))
9772 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9773 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9774 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9775 "TARGET_32BIT"
9776 "#"
9777 "TARGET_32BIT && reload_completed"
9778 [(set (match_dup 0)
9779 (compare
9780 (and:SI
9781 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9782 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9783 (const_int 0)))
9784 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9785 ""
9786 [(set_attr "conds" "set")
9787 (set_attr "length" "16")
9788 (set_attr "type" "multiple")]
9789 )
9790
9791 ;; If there is no dominance in the comparison, then we can still save an
9792 ;; instruction in the AND case, since we can know that the second compare
9793 ;; need only zero the value if false (if true, then the value is already
9794 ;; correct).
9795 (define_insn_and_split "*and_scc_scc_nodom"
9796 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9797 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9798 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9799 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9800 (match_operator:SI 6 "arm_comparison_operator"
9801 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9802 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9803 (clobber (reg:CC CC_REGNUM))]
9804 "TARGET_32BIT
9805 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9806 == CCmode)"
9807 "#"
9808 "TARGET_32BIT && reload_completed"
9809 [(parallel [(set (match_dup 0)
9810 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9811 (clobber (reg:CC CC_REGNUM))])
9812 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9813 (set (match_dup 0)
9814 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9815 (match_dup 0)
9816 (const_int 0)))]
9817 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9818 operands[4], operands[5]),
9819 CC_REGNUM);
9820 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9821 operands[5]);"
9822 [(set_attr "conds" "clob")
9823 (set_attr "length" "20")
9824 (set_attr "type" "multiple")]
9825 )
9826
9827 (define_split
9828 [(set (reg:CC_NOOV CC_REGNUM)
9829 (compare:CC_NOOV (ior:SI
9830 (and:SI (match_operand:SI 0 "s_register_operand" "")
9831 (const_int 1))
9832 (match_operator:SI 1 "arm_comparison_operator"
9833 [(match_operand:SI 2 "s_register_operand" "")
9834 (match_operand:SI 3 "arm_add_operand" "")]))
9835 (const_int 0)))
9836 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9837 "TARGET_ARM"
9838 [(set (match_dup 4)
9839 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9840 (match_dup 0)))
9841 (set (reg:CC_NOOV CC_REGNUM)
9842 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9843 (const_int 0)))]
9844 "")
9845
9846 (define_split
9847 [(set (reg:CC_NOOV CC_REGNUM)
9848 (compare:CC_NOOV (ior:SI
9849 (match_operator:SI 1 "arm_comparison_operator"
9850 [(match_operand:SI 2 "s_register_operand" "")
9851 (match_operand:SI 3 "arm_add_operand" "")])
9852 (and:SI (match_operand:SI 0 "s_register_operand" "")
9853 (const_int 1)))
9854 (const_int 0)))
9855 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9856 "TARGET_ARM"
9857 [(set (match_dup 4)
9858 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9859 (match_dup 0)))
9860 (set (reg:CC_NOOV CC_REGNUM)
9861 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9862 (const_int 0)))]
9863 "")
9864 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9865
9866 (define_insn_and_split "*negscc"
9867 [(set (match_operand:SI 0 "s_register_operand" "=r")
9868 (neg:SI (match_operator 3 "arm_comparison_operator"
9869 [(match_operand:SI 1 "s_register_operand" "r")
9870 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9871 (clobber (reg:CC CC_REGNUM))]
9872 "TARGET_ARM"
9873 "#"
9874 "&& reload_completed"
9875 [(const_int 0)]
9876 {
9877 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9878
9879 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9880 {
9881 /* Emit mov\\t%0, %1, asr #31 */
9882 emit_insn (gen_rtx_SET (operands[0],
9883 gen_rtx_ASHIFTRT (SImode,
9884 operands[1],
9885 GEN_INT (31))));
9886 DONE;
9887 }
9888 else if (GET_CODE (operands[3]) == NE)
9889 {
9890 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9891 if (CONST_INT_P (operands[2]))
9892 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9893 GEN_INT (- INTVAL (operands[2]))));
9894 else
9895 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9896
9897 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9898 gen_rtx_NE (SImode,
9899 cc_reg,
9900 const0_rtx),
9901 gen_rtx_SET (operands[0],
9902 GEN_INT (~0))));
9903 DONE;
9904 }
9905 else
9906 {
9907 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9908 emit_insn (gen_rtx_SET (cc_reg,
9909 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9910 enum rtx_code rc = GET_CODE (operands[3]);
9911
9912 rc = reverse_condition (rc);
9913 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9914 gen_rtx_fmt_ee (rc,
9915 VOIDmode,
9916 cc_reg,
9917 const0_rtx),
9918 gen_rtx_SET (operands[0], const0_rtx)));
9919 rc = GET_CODE (operands[3]);
9920 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9921 gen_rtx_fmt_ee (rc,
9922 VOIDmode,
9923 cc_reg,
9924 const0_rtx),
9925 gen_rtx_SET (operands[0],
9926 GEN_INT (~0))));
9927 DONE;
9928 }
9929 FAIL;
9930 }
9931 [(set_attr "conds" "clob")
9932 (set_attr "length" "12")
9933 (set_attr "type" "multiple")]
9934 )
9935
9936 (define_insn_and_split "movcond_addsi"
9937 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9938 (if_then_else:SI
9939 (match_operator 5 "comparison_operator"
9940 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9941 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9942 (const_int 0)])
9943 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9944 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9945 (clobber (reg:CC CC_REGNUM))]
9946 "TARGET_32BIT"
9947 "#"
9948 "&& reload_completed"
9949 [(set (reg:CC_NOOV CC_REGNUM)
9950 (compare:CC_NOOV
9951 (plus:SI (match_dup 3)
9952 (match_dup 4))
9953 (const_int 0)))
9954 (set (match_dup 0) (match_dup 1))
9955 (cond_exec (match_dup 6)
9956 (set (match_dup 0) (match_dup 2)))]
9957 "
9958 {
9959 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9960 operands[3], operands[4]);
9961 enum rtx_code rc = GET_CODE (operands[5]);
9962 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9963 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9964 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9965 rc = reverse_condition (rc);
9966 else
9967 std::swap (operands[1], operands[2]);
9968
9969 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9970 }
9971 "
9972 [(set_attr "conds" "clob")
9973 (set_attr "enabled_for_depr_it" "no,yes,yes")
9974 (set_attr "type" "multiple")]
9975 )
9976
9977 (define_insn "movcond"
9978 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9979 (if_then_else:SI
9980 (match_operator 5 "arm_comparison_operator"
9981 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9982 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9983 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9984 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9985 (clobber (reg:CC CC_REGNUM))]
9986 "TARGET_ARM"
9987 "*
9988 if (GET_CODE (operands[5]) == LT
9989 && (operands[4] == const0_rtx))
9990 {
9991 if (which_alternative != 1 && REG_P (operands[1]))
9992 {
9993 if (operands[2] == const0_rtx)
9994 return \"and\\t%0, %1, %3, asr #31\";
9995 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9996 }
9997 else if (which_alternative != 0 && REG_P (operands[2]))
9998 {
9999 if (operands[1] == const0_rtx)
10000 return \"bic\\t%0, %2, %3, asr #31\";
10001 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
10002 }
10003 /* The only case that falls through to here is when both ops 1 & 2
10004 are constants. */
10005 }
10006
10007 if (GET_CODE (operands[5]) == GE
10008 && (operands[4] == const0_rtx))
10009 {
10010 if (which_alternative != 1 && REG_P (operands[1]))
10011 {
10012 if (operands[2] == const0_rtx)
10013 return \"bic\\t%0, %1, %3, asr #31\";
10014 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
10015 }
10016 else if (which_alternative != 0 && REG_P (operands[2]))
10017 {
10018 if (operands[1] == const0_rtx)
10019 return \"and\\t%0, %2, %3, asr #31\";
10020 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
10021 }
10022 /* The only case that falls through to here is when both ops 1 & 2
10023 are constants. */
10024 }
10025 if (CONST_INT_P (operands[4])
10026 && !const_ok_for_arm (INTVAL (operands[4])))
10027 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
10028 else
10029 output_asm_insn (\"cmp\\t%3, %4\", operands);
10030 if (which_alternative != 0)
10031 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
10032 if (which_alternative != 1)
10033 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
10034 return \"\";
10035 "
10036 [(set_attr "conds" "clob")
10037 (set_attr "length" "8,8,12")
10038 (set_attr "type" "multiple")]
10039 )
10040
10041 ;; ??? The patterns below need checking for Thumb-2 usefulness.
10042
10043 (define_insn "*ifcompare_plus_move"
10044 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10045 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10046 [(match_operand:SI 4 "s_register_operand" "r,r")
10047 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10048 (plus:SI
10049 (match_operand:SI 2 "s_register_operand" "r,r")
10050 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
10051 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10052 (clobber (reg:CC CC_REGNUM))]
10053 "TARGET_ARM"
10054 "#"
10055 [(set_attr "conds" "clob")
10056 (set_attr "length" "8,12")
10057 (set_attr "type" "multiple")]
10058 )
10059
10060 (define_insn "*if_plus_move"
10061 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10062 (if_then_else:SI
10063 (match_operator 4 "arm_comparison_operator"
10064 [(match_operand 5 "cc_register" "") (const_int 0)])
10065 (plus:SI
10066 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10067 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
10068 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
10069 "TARGET_ARM"
10070 "@
10071 add%d4\\t%0, %2, %3
10072 sub%d4\\t%0, %2, #%n3
10073 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
10074 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
10075 [(set_attr "conds" "use")
10076 (set_attr "length" "4,4,8,8")
10077 (set_attr_alternative "type"
10078 [(if_then_else (match_operand 3 "const_int_operand" "")
10079 (const_string "alu_imm" )
10080 (const_string "alu_sreg"))
10081 (const_string "alu_imm")
10082 (const_string "multiple")
10083 (const_string "multiple")])]
10084 )
10085
10086 (define_insn "*ifcompare_move_plus"
10087 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10088 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10089 [(match_operand:SI 4 "s_register_operand" "r,r")
10090 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10091 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10092 (plus:SI
10093 (match_operand:SI 2 "s_register_operand" "r,r")
10094 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
10095 (clobber (reg:CC CC_REGNUM))]
10096 "TARGET_ARM"
10097 "#"
10098 [(set_attr "conds" "clob")
10099 (set_attr "length" "8,12")
10100 (set_attr "type" "multiple")]
10101 )
10102
10103 (define_insn "*if_move_plus"
10104 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
10105 (if_then_else:SI
10106 (match_operator 4 "arm_comparison_operator"
10107 [(match_operand 5 "cc_register" "") (const_int 0)])
10108 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
10109 (plus:SI
10110 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
10111 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
10112 "TARGET_ARM"
10113 "@
10114 add%D4\\t%0, %2, %3
10115 sub%D4\\t%0, %2, #%n3
10116 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
10117 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
10118 [(set_attr "conds" "use")
10119 (set_attr "length" "4,4,8,8")
10120 (set_attr_alternative "type"
10121 [(if_then_else (match_operand 3 "const_int_operand" "")
10122 (const_string "alu_imm" )
10123 (const_string "alu_sreg"))
10124 (const_string "alu_imm")
10125 (const_string "multiple")
10126 (const_string "multiple")])]
10127 )
10128
10129 (define_insn "*ifcompare_arith_arith"
10130 [(set (match_operand:SI 0 "s_register_operand" "=r")
10131 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
10132 [(match_operand:SI 5 "s_register_operand" "r")
10133 (match_operand:SI 6 "arm_add_operand" "rIL")])
10134 (match_operator:SI 8 "shiftable_operator"
10135 [(match_operand:SI 1 "s_register_operand" "r")
10136 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10137 (match_operator:SI 7 "shiftable_operator"
10138 [(match_operand:SI 3 "s_register_operand" "r")
10139 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
10140 (clobber (reg:CC CC_REGNUM))]
10141 "TARGET_ARM"
10142 "#"
10143 [(set_attr "conds" "clob")
10144 (set_attr "length" "12")
10145 (set_attr "type" "multiple")]
10146 )
10147
10148 (define_insn "*if_arith_arith"
10149 [(set (match_operand:SI 0 "s_register_operand" "=r")
10150 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
10151 [(match_operand 8 "cc_register" "") (const_int 0)])
10152 (match_operator:SI 6 "shiftable_operator"
10153 [(match_operand:SI 1 "s_register_operand" "r")
10154 (match_operand:SI 2 "arm_rhs_operand" "rI")])
10155 (match_operator:SI 7 "shiftable_operator"
10156 [(match_operand:SI 3 "s_register_operand" "r")
10157 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
10158 "TARGET_ARM"
10159 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10160 [(set_attr "conds" "use")
10161 (set_attr "length" "8")
10162 (set_attr "type" "multiple")]
10163 )
10164
10165 (define_insn "*ifcompare_arith_move"
10166 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10167 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10168 [(match_operand:SI 2 "s_register_operand" "r,r")
10169 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10170 (match_operator:SI 7 "shiftable_operator"
10171 [(match_operand:SI 4 "s_register_operand" "r,r")
10172 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10173 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10174 (clobber (reg:CC CC_REGNUM))]
10175 "TARGET_ARM"
10176 "*
10177 /* If we have an operation where (op x 0) is the identity operation and
10178 the conditional operator is LT or GE and we are comparing against zero and
10179 everything is in registers then we can do this in two instructions. */
10180 if (operands[3] == const0_rtx
10181 && GET_CODE (operands[7]) != AND
10182 && REG_P (operands[5])
10183 && REG_P (operands[1])
10184 && REGNO (operands[1]) == REGNO (operands[4])
10185 && REGNO (operands[4]) != REGNO (operands[0]))
10186 {
10187 if (GET_CODE (operands[6]) == LT)
10188 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10189 else if (GET_CODE (operands[6]) == GE)
10190 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10191 }
10192 if (CONST_INT_P (operands[3])
10193 && !const_ok_for_arm (INTVAL (operands[3])))
10194 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10195 else
10196 output_asm_insn (\"cmp\\t%2, %3\", operands);
10197 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10198 if (which_alternative != 0)
10199 return \"mov%D6\\t%0, %1\";
10200 return \"\";
10201 "
10202 [(set_attr "conds" "clob")
10203 (set_attr "length" "8,12")
10204 (set_attr "type" "multiple")]
10205 )
10206
10207 (define_insn "*if_arith_move"
10208 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10209 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10210 [(match_operand 6 "cc_register" "") (const_int 0)])
10211 (match_operator:SI 5 "shiftable_operator"
10212 [(match_operand:SI 2 "s_register_operand" "r,r")
10213 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10214 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10215 "TARGET_ARM"
10216 "@
10217 %I5%d4\\t%0, %2, %3
10218 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10219 [(set_attr "conds" "use")
10220 (set_attr "length" "4,8")
10221 (set_attr_alternative "type"
10222 [(if_then_else (match_operand 3 "const_int_operand" "")
10223 (const_string "alu_shift_imm" )
10224 (const_string "alu_shift_reg"))
10225 (const_string "multiple")])]
10226 )
10227
10228 (define_insn "*ifcompare_move_arith"
10229 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10230 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10231 [(match_operand:SI 4 "s_register_operand" "r,r")
10232 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10233 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10234 (match_operator:SI 7 "shiftable_operator"
10235 [(match_operand:SI 2 "s_register_operand" "r,r")
10236 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10237 (clobber (reg:CC CC_REGNUM))]
10238 "TARGET_ARM"
10239 "*
10240 /* If we have an operation where (op x 0) is the identity operation and
10241 the conditional operator is LT or GE and we are comparing against zero and
10242 everything is in registers then we can do this in two instructions */
10243 if (operands[5] == const0_rtx
10244 && GET_CODE (operands[7]) != AND
10245 && REG_P (operands[3])
10246 && REG_P (operands[1])
10247 && REGNO (operands[1]) == REGNO (operands[2])
10248 && REGNO (operands[2]) != REGNO (operands[0]))
10249 {
10250 if (GET_CODE (operands[6]) == GE)
10251 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10252 else if (GET_CODE (operands[6]) == LT)
10253 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10254 }
10255
10256 if (CONST_INT_P (operands[5])
10257 && !const_ok_for_arm (INTVAL (operands[5])))
10258 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10259 else
10260 output_asm_insn (\"cmp\\t%4, %5\", operands);
10261
10262 if (which_alternative != 0)
10263 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10264 return \"%I7%D6\\t%0, %2, %3\";
10265 "
10266 [(set_attr "conds" "clob")
10267 (set_attr "length" "8,12")
10268 (set_attr "type" "multiple")]
10269 )
10270
10271 (define_insn "*if_move_arith"
10272 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10273 (if_then_else:SI
10274 (match_operator 4 "arm_comparison_operator"
10275 [(match_operand 6 "cc_register" "") (const_int 0)])
10276 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10277 (match_operator:SI 5 "shiftable_operator"
10278 [(match_operand:SI 2 "s_register_operand" "r,r")
10279 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10280 "TARGET_ARM"
10281 "@
10282 %I5%D4\\t%0, %2, %3
10283 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10284 [(set_attr "conds" "use")
10285 (set_attr "length" "4,8")
10286 (set_attr_alternative "type"
10287 [(if_then_else (match_operand 3 "const_int_operand" "")
10288 (const_string "alu_shift_imm" )
10289 (const_string "alu_shift_reg"))
10290 (const_string "multiple")])]
10291 )
10292
10293 (define_insn "*ifcompare_move_not"
10294 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10295 (if_then_else:SI
10296 (match_operator 5 "arm_comparison_operator"
10297 [(match_operand:SI 3 "s_register_operand" "r,r")
10298 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10299 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10300 (not:SI
10301 (match_operand:SI 2 "s_register_operand" "r,r"))))
10302 (clobber (reg:CC CC_REGNUM))]
10303 "TARGET_ARM"
10304 "#"
10305 [(set_attr "conds" "clob")
10306 (set_attr "length" "8,12")
10307 (set_attr "type" "multiple")]
10308 )
10309
10310 (define_insn "*if_move_not"
10311 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10312 (if_then_else:SI
10313 (match_operator 4 "arm_comparison_operator"
10314 [(match_operand 3 "cc_register" "") (const_int 0)])
10315 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10316 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10317 "TARGET_ARM"
10318 "@
10319 mvn%D4\\t%0, %2
10320 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10321 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10322 [(set_attr "conds" "use")
10323 (set_attr "type" "mvn_reg")
10324 (set_attr "length" "4,8,8")
10325 (set_attr "type" "mvn_reg,multiple,multiple")]
10326 )
10327
10328 (define_insn "*ifcompare_not_move"
10329 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10330 (if_then_else:SI
10331 (match_operator 5 "arm_comparison_operator"
10332 [(match_operand:SI 3 "s_register_operand" "r,r")
10333 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10334 (not:SI
10335 (match_operand:SI 2 "s_register_operand" "r,r"))
10336 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10337 (clobber (reg:CC CC_REGNUM))]
10338 "TARGET_ARM"
10339 "#"
10340 [(set_attr "conds" "clob")
10341 (set_attr "length" "8,12")
10342 (set_attr "type" "multiple")]
10343 )
10344
10345 (define_insn "*if_not_move"
10346 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10347 (if_then_else:SI
10348 (match_operator 4 "arm_comparison_operator"
10349 [(match_operand 3 "cc_register" "") (const_int 0)])
10350 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10351 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10352 "TARGET_ARM"
10353 "@
10354 mvn%d4\\t%0, %2
10355 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10356 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10357 [(set_attr "conds" "use")
10358 (set_attr "type" "mvn_reg,multiple,multiple")
10359 (set_attr "length" "4,8,8")]
10360 )
10361
10362 (define_insn "*ifcompare_shift_move"
10363 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10364 (if_then_else:SI
10365 (match_operator 6 "arm_comparison_operator"
10366 [(match_operand:SI 4 "s_register_operand" "r,r")
10367 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10368 (match_operator:SI 7 "shift_operator"
10369 [(match_operand:SI 2 "s_register_operand" "r,r")
10370 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10371 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10372 (clobber (reg:CC CC_REGNUM))]
10373 "TARGET_ARM"
10374 "#"
10375 [(set_attr "conds" "clob")
10376 (set_attr "length" "8,12")
10377 (set_attr "type" "multiple")]
10378 )
10379
10380 (define_insn "*if_shift_move"
10381 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10382 (if_then_else:SI
10383 (match_operator 5 "arm_comparison_operator"
10384 [(match_operand 6 "cc_register" "") (const_int 0)])
10385 (match_operator:SI 4 "shift_operator"
10386 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10387 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10388 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10389 "TARGET_ARM"
10390 "@
10391 mov%d5\\t%0, %2%S4
10392 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10393 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10394 [(set_attr "conds" "use")
10395 (set_attr "shift" "2")
10396 (set_attr "length" "4,8,8")
10397 (set_attr_alternative "type"
10398 [(if_then_else (match_operand 3 "const_int_operand" "")
10399 (const_string "mov_shift" )
10400 (const_string "mov_shift_reg"))
10401 (const_string "multiple")
10402 (const_string "multiple")])]
10403 )
10404
10405 (define_insn "*ifcompare_move_shift"
10406 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10407 (if_then_else:SI
10408 (match_operator 6 "arm_comparison_operator"
10409 [(match_operand:SI 4 "s_register_operand" "r,r")
10410 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10411 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10412 (match_operator:SI 7 "shift_operator"
10413 [(match_operand:SI 2 "s_register_operand" "r,r")
10414 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10415 (clobber (reg:CC CC_REGNUM))]
10416 "TARGET_ARM"
10417 "#"
10418 [(set_attr "conds" "clob")
10419 (set_attr "length" "8,12")
10420 (set_attr "type" "multiple")]
10421 )
10422
10423 (define_insn "*if_move_shift"
10424 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10425 (if_then_else:SI
10426 (match_operator 5 "arm_comparison_operator"
10427 [(match_operand 6 "cc_register" "") (const_int 0)])
10428 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10429 (match_operator:SI 4 "shift_operator"
10430 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10431 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10432 "TARGET_ARM"
10433 "@
10434 mov%D5\\t%0, %2%S4
10435 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10436 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10437 [(set_attr "conds" "use")
10438 (set_attr "shift" "2")
10439 (set_attr "length" "4,8,8")
10440 (set_attr_alternative "type"
10441 [(if_then_else (match_operand 3 "const_int_operand" "")
10442 (const_string "mov_shift" )
10443 (const_string "mov_shift_reg"))
10444 (const_string "multiple")
10445 (const_string "multiple")])]
10446 )
10447
10448 (define_insn "*ifcompare_shift_shift"
10449 [(set (match_operand:SI 0 "s_register_operand" "=r")
10450 (if_then_else:SI
10451 (match_operator 7 "arm_comparison_operator"
10452 [(match_operand:SI 5 "s_register_operand" "r")
10453 (match_operand:SI 6 "arm_add_operand" "rIL")])
10454 (match_operator:SI 8 "shift_operator"
10455 [(match_operand:SI 1 "s_register_operand" "r")
10456 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10457 (match_operator:SI 9 "shift_operator"
10458 [(match_operand:SI 3 "s_register_operand" "r")
10459 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10460 (clobber (reg:CC CC_REGNUM))]
10461 "TARGET_ARM"
10462 "#"
10463 [(set_attr "conds" "clob")
10464 (set_attr "length" "12")
10465 (set_attr "type" "multiple")]
10466 )
10467
10468 (define_insn "*if_shift_shift"
10469 [(set (match_operand:SI 0 "s_register_operand" "=r")
10470 (if_then_else:SI
10471 (match_operator 5 "arm_comparison_operator"
10472 [(match_operand 8 "cc_register" "") (const_int 0)])
10473 (match_operator:SI 6 "shift_operator"
10474 [(match_operand:SI 1 "s_register_operand" "r")
10475 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10476 (match_operator:SI 7 "shift_operator"
10477 [(match_operand:SI 3 "s_register_operand" "r")
10478 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10479 "TARGET_ARM"
10480 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10481 [(set_attr "conds" "use")
10482 (set_attr "shift" "1")
10483 (set_attr "length" "8")
10484 (set (attr "type") (if_then_else
10485 (and (match_operand 2 "const_int_operand" "")
10486 (match_operand 4 "const_int_operand" ""))
10487 (const_string "mov_shift")
10488 (const_string "mov_shift_reg")))]
10489 )
10490
10491 (define_insn "*ifcompare_not_arith"
10492 [(set (match_operand:SI 0 "s_register_operand" "=r")
10493 (if_then_else:SI
10494 (match_operator 6 "arm_comparison_operator"
10495 [(match_operand:SI 4 "s_register_operand" "r")
10496 (match_operand:SI 5 "arm_add_operand" "rIL")])
10497 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10498 (match_operator:SI 7 "shiftable_operator"
10499 [(match_operand:SI 2 "s_register_operand" "r")
10500 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10501 (clobber (reg:CC CC_REGNUM))]
10502 "TARGET_ARM"
10503 "#"
10504 [(set_attr "conds" "clob")
10505 (set_attr "length" "12")
10506 (set_attr "type" "multiple")]
10507 )
10508
10509 (define_insn "*if_not_arith"
10510 [(set (match_operand:SI 0 "s_register_operand" "=r")
10511 (if_then_else:SI
10512 (match_operator 5 "arm_comparison_operator"
10513 [(match_operand 4 "cc_register" "") (const_int 0)])
10514 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10515 (match_operator:SI 6 "shiftable_operator"
10516 [(match_operand:SI 2 "s_register_operand" "r")
10517 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10518 "TARGET_ARM"
10519 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10520 [(set_attr "conds" "use")
10521 (set_attr "type" "mvn_reg")
10522 (set_attr "length" "8")]
10523 )
10524
10525 (define_insn "*ifcompare_arith_not"
10526 [(set (match_operand:SI 0 "s_register_operand" "=r")
10527 (if_then_else:SI
10528 (match_operator 6 "arm_comparison_operator"
10529 [(match_operand:SI 4 "s_register_operand" "r")
10530 (match_operand:SI 5 "arm_add_operand" "rIL")])
10531 (match_operator:SI 7 "shiftable_operator"
10532 [(match_operand:SI 2 "s_register_operand" "r")
10533 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10534 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10535 (clobber (reg:CC CC_REGNUM))]
10536 "TARGET_ARM"
10537 "#"
10538 [(set_attr "conds" "clob")
10539 (set_attr "length" "12")
10540 (set_attr "type" "multiple")]
10541 )
10542
10543 (define_insn "*if_arith_not"
10544 [(set (match_operand:SI 0 "s_register_operand" "=r")
10545 (if_then_else:SI
10546 (match_operator 5 "arm_comparison_operator"
10547 [(match_operand 4 "cc_register" "") (const_int 0)])
10548 (match_operator:SI 6 "shiftable_operator"
10549 [(match_operand:SI 2 "s_register_operand" "r")
10550 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10551 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10552 "TARGET_ARM"
10553 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10554 [(set_attr "conds" "use")
10555 (set_attr "type" "multiple")
10556 (set_attr "length" "8")]
10557 )
10558
10559 (define_insn "*ifcompare_neg_move"
10560 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10561 (if_then_else:SI
10562 (match_operator 5 "arm_comparison_operator"
10563 [(match_operand:SI 3 "s_register_operand" "r,r")
10564 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10565 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10566 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10567 (clobber (reg:CC CC_REGNUM))]
10568 "TARGET_ARM"
10569 "#"
10570 [(set_attr "conds" "clob")
10571 (set_attr "length" "8,12")
10572 (set_attr "type" "multiple")]
10573 )
10574
10575 (define_insn_and_split "*if_neg_move"
10576 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10577 (if_then_else:SI
10578 (match_operator 4 "arm_comparison_operator"
10579 [(match_operand 3 "cc_register" "") (const_int 0)])
10580 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10581 (match_operand:SI 1 "s_register_operand" "0,0")))]
10582 "TARGET_32BIT"
10583 "#"
10584 "&& reload_completed"
10585 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10586 (set (match_dup 0) (neg:SI (match_dup 2))))]
10587 ""
10588 [(set_attr "conds" "use")
10589 (set_attr "length" "4")
10590 (set_attr "arch" "t2,32")
10591 (set_attr "enabled_for_depr_it" "yes,no")
10592 (set_attr "type" "logic_shift_imm")]
10593 )
10594
10595 (define_insn "*ifcompare_move_neg"
10596 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10597 (if_then_else:SI
10598 (match_operator 5 "arm_comparison_operator"
10599 [(match_operand:SI 3 "s_register_operand" "r,r")
10600 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10601 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10602 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10603 (clobber (reg:CC CC_REGNUM))]
10604 "TARGET_ARM"
10605 "#"
10606 [(set_attr "conds" "clob")
10607 (set_attr "length" "8,12")
10608 (set_attr "type" "multiple")]
10609 )
10610
10611 (define_insn_and_split "*if_move_neg"
10612 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10613 (if_then_else:SI
10614 (match_operator 4 "arm_comparison_operator"
10615 [(match_operand 3 "cc_register" "") (const_int 0)])
10616 (match_operand:SI 1 "s_register_operand" "0,0")
10617 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10618 "TARGET_32BIT"
10619 "#"
10620 "&& reload_completed"
10621 [(cond_exec (match_dup 5)
10622 (set (match_dup 0) (neg:SI (match_dup 2))))]
10623 {
10624 machine_mode mode = GET_MODE (operands[3]);
10625 rtx_code rc = GET_CODE (operands[4]);
10626
10627 if (mode == CCFPmode || mode == CCFPEmode)
10628 rc = reverse_condition_maybe_unordered (rc);
10629 else
10630 rc = reverse_condition (rc);
10631
10632 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10633 }
10634 [(set_attr "conds" "use")
10635 (set_attr "length" "4")
10636 (set_attr "arch" "t2,32")
10637 (set_attr "enabled_for_depr_it" "yes,no")
10638 (set_attr "type" "logic_shift_imm")]
10639 )
10640
10641 (define_insn "*arith_adjacentmem"
10642 [(set (match_operand:SI 0 "s_register_operand" "=r")
10643 (match_operator:SI 1 "shiftable_operator"
10644 [(match_operand:SI 2 "memory_operand" "m")
10645 (match_operand:SI 3 "memory_operand" "m")]))
10646 (clobber (match_scratch:SI 4 "=r"))]
10647 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10648 "*
10649 {
10650 rtx ldm[3];
10651 rtx arith[4];
10652 rtx base_reg;
10653 HOST_WIDE_INT val1 = 0, val2 = 0;
10654
10655 if (REGNO (operands[0]) > REGNO (operands[4]))
10656 {
10657 ldm[1] = operands[4];
10658 ldm[2] = operands[0];
10659 }
10660 else
10661 {
10662 ldm[1] = operands[0];
10663 ldm[2] = operands[4];
10664 }
10665
10666 base_reg = XEXP (operands[2], 0);
10667
10668 if (!REG_P (base_reg))
10669 {
10670 val1 = INTVAL (XEXP (base_reg, 1));
10671 base_reg = XEXP (base_reg, 0);
10672 }
10673
10674 if (!REG_P (XEXP (operands[3], 0)))
10675 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10676
10677 arith[0] = operands[0];
10678 arith[3] = operands[1];
10679
10680 if (val1 < val2)
10681 {
10682 arith[1] = ldm[1];
10683 arith[2] = ldm[2];
10684 }
10685 else
10686 {
10687 arith[1] = ldm[2];
10688 arith[2] = ldm[1];
10689 }
10690
10691 ldm[0] = base_reg;
10692 if (val1 !=0 && val2 != 0)
10693 {
10694 rtx ops[3];
10695
10696 if (val1 == 4 || val2 == 4)
10697 /* Other val must be 8, since we know they are adjacent and neither
10698 is zero. */
10699 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10700 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10701 {
10702 ldm[0] = ops[0] = operands[4];
10703 ops[1] = base_reg;
10704 ops[2] = GEN_INT (val1);
10705 output_add_immediate (ops);
10706 if (val1 < val2)
10707 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10708 else
10709 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10710 }
10711 else
10712 {
10713 /* Offset is out of range for a single add, so use two ldr. */
10714 ops[0] = ldm[1];
10715 ops[1] = base_reg;
10716 ops[2] = GEN_INT (val1);
10717 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10718 ops[0] = ldm[2];
10719 ops[2] = GEN_INT (val2);
10720 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10721 }
10722 }
10723 else if (val1 != 0)
10724 {
10725 if (val1 < val2)
10726 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10727 else
10728 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10729 }
10730 else
10731 {
10732 if (val1 < val2)
10733 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10734 else
10735 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10736 }
10737 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10738 return \"\";
10739 }"
10740 [(set_attr "length" "12")
10741 (set_attr "predicable" "yes")
10742 (set_attr "type" "load_4")]
10743 )
10744
10745 ; This pattern is never tried by combine, so do it as a peephole
10746
10747 (define_peephole2
10748 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10749 (match_operand:SI 1 "arm_general_register_operand" ""))
10750 (set (reg:CC CC_REGNUM)
10751 (compare:CC (match_dup 1) (const_int 0)))]
10752 "TARGET_ARM"
10753 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10754 (set (match_dup 0) (match_dup 1))])]
10755 ""
10756 )
10757
10758 (define_split
10759 [(set (match_operand:SI 0 "s_register_operand" "")
10760 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10761 (const_int 0))
10762 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10763 [(match_operand:SI 3 "s_register_operand" "")
10764 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10765 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10766 "TARGET_ARM"
10767 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10768 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10769 (match_dup 5)))]
10770 ""
10771 )
10772
10773 ;; This split can be used because CC_Z mode implies that the following
10774 ;; branch will be an equality, or an unsigned inequality, so the sign
10775 ;; extension is not needed.
10776
10777 (define_split
10778 [(set (reg:CC_Z CC_REGNUM)
10779 (compare:CC_Z
10780 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10781 (const_int 24))
10782 (match_operand 1 "const_int_operand" "")))
10783 (clobber (match_scratch:SI 2 ""))]
10784 "TARGET_ARM
10785 && ((UINTVAL (operands[1]))
10786 == ((UINTVAL (operands[1])) >> 24) << 24)"
10787 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10788 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10789 "
10790 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10791 "
10792 )
10793 ;; ??? Check the patterns above for Thumb-2 usefulness
10794
10795 (define_expand "prologue"
10796 [(clobber (const_int 0))]
10797 "TARGET_EITHER"
10798 "if (TARGET_32BIT)
10799 arm_expand_prologue ();
10800 else
10801 thumb1_expand_prologue ();
10802 DONE;
10803 "
10804 )
10805
10806 (define_expand "epilogue"
10807 [(clobber (const_int 0))]
10808 "TARGET_EITHER"
10809 "
10810 if (crtl->calls_eh_return)
10811 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10812 if (TARGET_THUMB1)
10813 {
10814 thumb1_expand_epilogue ();
10815 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10816 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10817 }
10818 else if (HAVE_return)
10819 {
10820 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10821 no need for explicit testing again. */
10822 emit_jump_insn (gen_return ());
10823 }
10824 else if (TARGET_32BIT)
10825 {
10826 arm_expand_epilogue (true);
10827 }
10828 DONE;
10829 "
10830 )
10831
10832 ;; Note - although unspec_volatile's USE all hard registers,
10833 ;; USEs are ignored after relaod has completed. Thus we need
10834 ;; to add an unspec of the link register to ensure that flow
10835 ;; does not think that it is unused by the sibcall branch that
10836 ;; will replace the standard function epilogue.
10837 (define_expand "sibcall_epilogue"
10838 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10839 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10840 "TARGET_32BIT"
10841 "
10842 arm_expand_epilogue (false);
10843 DONE;
10844 "
10845 )
10846
10847 (define_expand "eh_epilogue"
10848 [(use (match_operand:SI 0 "register_operand" ""))
10849 (use (match_operand:SI 1 "register_operand" ""))
10850 (use (match_operand:SI 2 "register_operand" ""))]
10851 "TARGET_EITHER"
10852 "
10853 {
10854 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10855 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10856 {
10857 rtx ra = gen_rtx_REG (Pmode, 2);
10858
10859 emit_move_insn (ra, operands[2]);
10860 operands[2] = ra;
10861 }
10862 /* This is a hack -- we may have crystalized the function type too
10863 early. */
10864 cfun->machine->func_type = 0;
10865 }"
10866 )
10867
10868 ;; This split is only used during output to reduce the number of patterns
10869 ;; that need assembler instructions adding to them. We allowed the setting
10870 ;; of the conditions to be implicit during rtl generation so that
10871 ;; the conditional compare patterns would work. However this conflicts to
10872 ;; some extent with the conditional data operations, so we have to split them
10873 ;; up again here.
10874
10875 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10876 ;; conditional execution sufficient?
10877
10878 (define_split
10879 [(set (match_operand:SI 0 "s_register_operand" "")
10880 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10881 [(match_operand 2 "" "") (match_operand 3 "" "")])
10882 (match_dup 0)
10883 (match_operand 4 "" "")))
10884 (clobber (reg:CC CC_REGNUM))]
10885 "TARGET_ARM && reload_completed"
10886 [(set (match_dup 5) (match_dup 6))
10887 (cond_exec (match_dup 7)
10888 (set (match_dup 0) (match_dup 4)))]
10889 "
10890 {
10891 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10892 operands[2], operands[3]);
10893 enum rtx_code rc = GET_CODE (operands[1]);
10894
10895 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10896 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10897 if (mode == CCFPmode || mode == CCFPEmode)
10898 rc = reverse_condition_maybe_unordered (rc);
10899 else
10900 rc = reverse_condition (rc);
10901
10902 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10903 }"
10904 )
10905
10906 (define_split
10907 [(set (match_operand:SI 0 "s_register_operand" "")
10908 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10909 [(match_operand 2 "" "") (match_operand 3 "" "")])
10910 (match_operand 4 "" "")
10911 (match_dup 0)))
10912 (clobber (reg:CC CC_REGNUM))]
10913 "TARGET_ARM && reload_completed"
10914 [(set (match_dup 5) (match_dup 6))
10915 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10916 (set (match_dup 0) (match_dup 4)))]
10917 "
10918 {
10919 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10920 operands[2], operands[3]);
10921
10922 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10923 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10924 }"
10925 )
10926
10927 (define_split
10928 [(set (match_operand:SI 0 "s_register_operand" "")
10929 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10930 [(match_operand 2 "" "") (match_operand 3 "" "")])
10931 (match_operand 4 "" "")
10932 (match_operand 5 "" "")))
10933 (clobber (reg:CC CC_REGNUM))]
10934 "TARGET_ARM && reload_completed"
10935 [(set (match_dup 6) (match_dup 7))
10936 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10937 (set (match_dup 0) (match_dup 4)))
10938 (cond_exec (match_dup 8)
10939 (set (match_dup 0) (match_dup 5)))]
10940 "
10941 {
10942 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10943 operands[2], operands[3]);
10944 enum rtx_code rc = GET_CODE (operands[1]);
10945
10946 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10947 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10948 if (mode == CCFPmode || mode == CCFPEmode)
10949 rc = reverse_condition_maybe_unordered (rc);
10950 else
10951 rc = reverse_condition (rc);
10952
10953 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10954 }"
10955 )
10956
10957 (define_split
10958 [(set (match_operand:SI 0 "s_register_operand" "")
10959 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10960 [(match_operand:SI 2 "s_register_operand" "")
10961 (match_operand:SI 3 "arm_add_operand" "")])
10962 (match_operand:SI 4 "arm_rhs_operand" "")
10963 (not:SI
10964 (match_operand:SI 5 "s_register_operand" ""))))
10965 (clobber (reg:CC CC_REGNUM))]
10966 "TARGET_ARM && reload_completed"
10967 [(set (match_dup 6) (match_dup 7))
10968 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10969 (set (match_dup 0) (match_dup 4)))
10970 (cond_exec (match_dup 8)
10971 (set (match_dup 0) (not:SI (match_dup 5))))]
10972 "
10973 {
10974 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10975 operands[2], operands[3]);
10976 enum rtx_code rc = GET_CODE (operands[1]);
10977
10978 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10979 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10980 if (mode == CCFPmode || mode == CCFPEmode)
10981 rc = reverse_condition_maybe_unordered (rc);
10982 else
10983 rc = reverse_condition (rc);
10984
10985 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10986 }"
10987 )
10988
10989 (define_insn "*cond_move_not"
10990 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10991 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10992 [(match_operand 3 "cc_register" "") (const_int 0)])
10993 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10994 (not:SI
10995 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10996 "TARGET_ARM"
10997 "@
10998 mvn%D4\\t%0, %2
10999 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
11000 [(set_attr "conds" "use")
11001 (set_attr "type" "mvn_reg,multiple")
11002 (set_attr "length" "4,8")]
11003 )
11004
11005 ;; The next two patterns occur when an AND operation is followed by a
11006 ;; scc insn sequence
11007
11008 (define_insn "*sign_extract_onebit"
11009 [(set (match_operand:SI 0 "s_register_operand" "=r")
11010 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11011 (const_int 1)
11012 (match_operand:SI 2 "const_int_operand" "n")))
11013 (clobber (reg:CC CC_REGNUM))]
11014 "TARGET_ARM"
11015 "*
11016 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11017 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
11018 return \"mvnne\\t%0, #0\";
11019 "
11020 [(set_attr "conds" "clob")
11021 (set_attr "length" "8")
11022 (set_attr "type" "multiple")]
11023 )
11024
11025 (define_insn "*not_signextract_onebit"
11026 [(set (match_operand:SI 0 "s_register_operand" "=r")
11027 (not:SI
11028 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
11029 (const_int 1)
11030 (match_operand:SI 2 "const_int_operand" "n"))))
11031 (clobber (reg:CC CC_REGNUM))]
11032 "TARGET_ARM"
11033 "*
11034 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11035 output_asm_insn (\"tst\\t%1, %2\", operands);
11036 output_asm_insn (\"mvneq\\t%0, #0\", operands);
11037 return \"movne\\t%0, #0\";
11038 "
11039 [(set_attr "conds" "clob")
11040 (set_attr "length" "12")
11041 (set_attr "type" "multiple")]
11042 )
11043 ;; ??? The above patterns need auditing for Thumb-2
11044
11045 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
11046 ;; expressions. For simplicity, the first register is also in the unspec
11047 ;; part.
11048 ;; To avoid the usage of GNU extension, the length attribute is computed
11049 ;; in a C function arm_attr_length_push_multi.
11050 (define_insn "*push_multi"
11051 [(match_parallel 2 "multi_register_push"
11052 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
11053 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
11054 UNSPEC_PUSH_MULT))])]
11055 ""
11056 "*
11057 {
11058 int num_saves = XVECLEN (operands[2], 0);
11059
11060 /* For the StrongARM at least it is faster to
11061 use STR to store only a single register.
11062 In Thumb mode always use push, and the assembler will pick
11063 something appropriate. */
11064 if (num_saves == 1 && TARGET_ARM)
11065 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
11066 else
11067 {
11068 int i;
11069 char pattern[100];
11070
11071 if (TARGET_32BIT)
11072 strcpy (pattern, \"push%?\\t{%1\");
11073 else
11074 strcpy (pattern, \"push\\t{%1\");
11075
11076 for (i = 1; i < num_saves; i++)
11077 {
11078 strcat (pattern, \", %|\");
11079 strcat (pattern,
11080 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
11081 }
11082
11083 strcat (pattern, \"}\");
11084 output_asm_insn (pattern, operands);
11085 }
11086
11087 return \"\";
11088 }"
11089 [(set_attr "type" "store_16")
11090 (set (attr "length")
11091 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
11092 )
11093
11094 (define_insn "stack_tie"
11095 [(set (mem:BLK (scratch))
11096 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
11097 (match_operand:SI 1 "s_register_operand" "rk")]
11098 UNSPEC_PRLG_STK))]
11099 ""
11100 ""
11101 [(set_attr "length" "0")
11102 (set_attr "type" "block")]
11103 )
11104
11105 ;; Pop (as used in epilogue RTL)
11106 ;;
11107 (define_insn "*load_multiple_with_writeback"
11108 [(match_parallel 0 "load_multiple_operation"
11109 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11110 (plus:SI (match_dup 1)
11111 (match_operand:SI 2 "const_int_I_operand" "I")))
11112 (set (match_operand:SI 3 "s_register_operand" "=rk")
11113 (mem:SI (match_dup 1)))
11114 ])]
11115 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11116 "*
11117 {
11118 arm_output_multireg_pop (operands, /*return_pc=*/false,
11119 /*cond=*/const_true_rtx,
11120 /*reverse=*/false,
11121 /*update=*/true);
11122 return \"\";
11123 }
11124 "
11125 [(set_attr "type" "load_16")
11126 (set_attr "predicable" "yes")
11127 (set (attr "length")
11128 (symbol_ref "arm_attr_length_pop_multi (operands,
11129 /*return_pc=*/false,
11130 /*write_back_p=*/true)"))]
11131 )
11132
11133 ;; Pop with return (as used in epilogue RTL)
11134 ;;
11135 ;; This instruction is generated when the registers are popped at the end of
11136 ;; epilogue. Here, instead of popping the value into LR and then generating
11137 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
11138 ;; with (return).
11139 (define_insn "*pop_multiple_with_writeback_and_return"
11140 [(match_parallel 0 "pop_multiple_return"
11141 [(return)
11142 (set (match_operand:SI 1 "s_register_operand" "+rk")
11143 (plus:SI (match_dup 1)
11144 (match_operand:SI 2 "const_int_I_operand" "I")))
11145 (set (match_operand:SI 3 "s_register_operand" "=rk")
11146 (mem:SI (match_dup 1)))
11147 ])]
11148 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11149 "*
11150 {
11151 arm_output_multireg_pop (operands, /*return_pc=*/true,
11152 /*cond=*/const_true_rtx,
11153 /*reverse=*/false,
11154 /*update=*/true);
11155 return \"\";
11156 }
11157 "
11158 [(set_attr "type" "load_16")
11159 (set_attr "predicable" "yes")
11160 (set (attr "length")
11161 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11162 /*write_back_p=*/true)"))]
11163 )
11164
11165 (define_insn "*pop_multiple_with_return"
11166 [(match_parallel 0 "pop_multiple_return"
11167 [(return)
11168 (set (match_operand:SI 2 "s_register_operand" "=rk")
11169 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11170 ])]
11171 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11172 "*
11173 {
11174 arm_output_multireg_pop (operands, /*return_pc=*/true,
11175 /*cond=*/const_true_rtx,
11176 /*reverse=*/false,
11177 /*update=*/false);
11178 return \"\";
11179 }
11180 "
11181 [(set_attr "type" "load_16")
11182 (set_attr "predicable" "yes")
11183 (set (attr "length")
11184 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11185 /*write_back_p=*/false)"))]
11186 )
11187
11188 ;; Load into PC and return
11189 (define_insn "*ldr_with_return"
11190 [(return)
11191 (set (reg:SI PC_REGNUM)
11192 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11193 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11194 "ldr%?\t%|pc, [%0], #4"
11195 [(set_attr "type" "load_4")
11196 (set_attr "predicable" "yes")]
11197 )
11198 ;; Pop for floating point registers (as used in epilogue RTL)
11199 (define_insn "*vfp_pop_multiple_with_writeback"
11200 [(match_parallel 0 "pop_multiple_fp"
11201 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11202 (plus:SI (match_dup 1)
11203 (match_operand:SI 2 "const_int_I_operand" "I")))
11204 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11205 (mem:DF (match_dup 1)))])]
11206 "TARGET_32BIT && TARGET_HARD_FLOAT"
11207 "*
11208 {
11209 int num_regs = XVECLEN (operands[0], 0);
11210 char pattern[100];
11211 rtx op_list[2];
11212 strcpy (pattern, \"vldm\\t\");
11213 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11214 strcat (pattern, \"!, {\");
11215 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11216 strcat (pattern, \"%P0\");
11217 if ((num_regs - 1) > 1)
11218 {
11219 strcat (pattern, \"-%P1\");
11220 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11221 }
11222
11223 strcat (pattern, \"}\");
11224 output_asm_insn (pattern, op_list);
11225 return \"\";
11226 }
11227 "
11228 [(set_attr "type" "load_16")
11229 (set_attr "conds" "unconditional")
11230 (set_attr "predicable" "no")]
11231 )
11232
11233 ;; Special patterns for dealing with the constant pool
11234
11235 (define_insn "align_4"
11236 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11237 "TARGET_EITHER"
11238 "*
11239 assemble_align (32);
11240 return \"\";
11241 "
11242 [(set_attr "type" "no_insn")]
11243 )
11244
11245 (define_insn "align_8"
11246 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11247 "TARGET_EITHER"
11248 "*
11249 assemble_align (64);
11250 return \"\";
11251 "
11252 [(set_attr "type" "no_insn")]
11253 )
11254
11255 (define_insn "consttable_end"
11256 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11257 "TARGET_EITHER"
11258 "*
11259 making_const_table = FALSE;
11260 return \"\";
11261 "
11262 [(set_attr "type" "no_insn")]
11263 )
11264
11265 (define_insn "consttable_1"
11266 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11267 "TARGET_EITHER"
11268 "*
11269 making_const_table = TRUE;
11270 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11271 assemble_zeros (3);
11272 return \"\";
11273 "
11274 [(set_attr "length" "4")
11275 (set_attr "type" "no_insn")]
11276 )
11277
11278 (define_insn "consttable_2"
11279 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11280 "TARGET_EITHER"
11281 "*
11282 {
11283 rtx x = operands[0];
11284 making_const_table = TRUE;
11285 switch (GET_MODE_CLASS (GET_MODE (x)))
11286 {
11287 case MODE_FLOAT:
11288 arm_emit_fp16_const (x);
11289 break;
11290 default:
11291 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11292 assemble_zeros (2);
11293 break;
11294 }
11295 return \"\";
11296 }"
11297 [(set_attr "length" "4")
11298 (set_attr "type" "no_insn")]
11299 )
11300
11301 (define_insn "consttable_4"
11302 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11303 "TARGET_EITHER"
11304 "*
11305 {
11306 rtx x = operands[0];
11307 making_const_table = TRUE;
11308 scalar_float_mode float_mode;
11309 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
11310 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
11311 else
11312 {
11313 /* XXX: Sometimes gcc does something really dumb and ends up with
11314 a HIGH in a constant pool entry, usually because it's trying to
11315 load into a VFP register. We know this will always be used in
11316 combination with a LO_SUM which ignores the high bits, so just
11317 strip off the HIGH. */
11318 if (GET_CODE (x) == HIGH)
11319 x = XEXP (x, 0);
11320 assemble_integer (x, 4, BITS_PER_WORD, 1);
11321 mark_symbol_refs_as_used (x);
11322 }
11323 return \"\";
11324 }"
11325 [(set_attr "length" "4")
11326 (set_attr "type" "no_insn")]
11327 )
11328
11329 (define_insn "consttable_8"
11330 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11331 "TARGET_EITHER"
11332 "*
11333 {
11334 making_const_table = TRUE;
11335 scalar_float_mode float_mode;
11336 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11337 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11338 float_mode, BITS_PER_WORD);
11339 else
11340 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11341 return \"\";
11342 }"
11343 [(set_attr "length" "8")
11344 (set_attr "type" "no_insn")]
11345 )
11346
11347 (define_insn "consttable_16"
11348 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11349 "TARGET_EITHER"
11350 "*
11351 {
11352 making_const_table = TRUE;
11353 scalar_float_mode float_mode;
11354 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
11355 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11356 float_mode, BITS_PER_WORD);
11357 else
11358 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11359 return \"\";
11360 }"
11361 [(set_attr "length" "16")
11362 (set_attr "type" "no_insn")]
11363 )
11364
11365 ;; V5 Instructions,
11366
11367 (define_insn "clzsi2"
11368 [(set (match_operand:SI 0 "s_register_operand" "=r")
11369 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11370 "TARGET_32BIT && arm_arch5"
11371 "clz%?\\t%0, %1"
11372 [(set_attr "predicable" "yes")
11373 (set_attr "predicable_short_it" "no")
11374 (set_attr "type" "clz")])
11375
11376 (define_insn "rbitsi2"
11377 [(set (match_operand:SI 0 "s_register_operand" "=r")
11378 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11379 "TARGET_32BIT && arm_arch_thumb2"
11380 "rbit%?\\t%0, %1"
11381 [(set_attr "predicable" "yes")
11382 (set_attr "predicable_short_it" "no")
11383 (set_attr "type" "clz")])
11384
11385 ;; Keep this as a CTZ expression until after reload and then split
11386 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11387 ;; to fold with any other expression.
11388
11389 (define_insn_and_split "ctzsi2"
11390 [(set (match_operand:SI 0 "s_register_operand" "=r")
11391 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11392 "TARGET_32BIT && arm_arch_thumb2"
11393 "#"
11394 "&& reload_completed"
11395 [(const_int 0)]
11396 "
11397 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11398 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11399 DONE;
11400 ")
11401
11402 ;; V5E instructions.
11403
11404 (define_insn "prefetch"
11405 [(prefetch (match_operand:SI 0 "address_operand" "p")
11406 (match_operand:SI 1 "" "")
11407 (match_operand:SI 2 "" ""))]
11408 "TARGET_32BIT && arm_arch5e"
11409 "pld\\t%a0"
11410 [(set_attr "type" "load_4")]
11411 )
11412
11413 ;; General predication pattern
11414
11415 (define_cond_exec
11416 [(match_operator 0 "arm_comparison_operator"
11417 [(match_operand 1 "cc_register" "")
11418 (const_int 0)])]
11419 "TARGET_32BIT
11420 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11421 ""
11422 [(set_attr "predicated" "yes")]
11423 )
11424
11425 (define_insn "force_register_use"
11426 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11427 ""
11428 "%@ %0 needed"
11429 [(set_attr "length" "0")
11430 (set_attr "type" "no_insn")]
11431 )
11432
11433
11434 ;; Patterns for exception handling
11435
11436 (define_expand "eh_return"
11437 [(use (match_operand 0 "general_operand" ""))]
11438 "TARGET_EITHER"
11439 "
11440 {
11441 if (TARGET_32BIT)
11442 emit_insn (gen_arm_eh_return (operands[0]));
11443 else
11444 emit_insn (gen_thumb_eh_return (operands[0]));
11445 DONE;
11446 }"
11447 )
11448
11449 ;; We can't expand this before we know where the link register is stored.
11450 (define_insn_and_split "arm_eh_return"
11451 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11452 VUNSPEC_EH_RETURN)
11453 (clobber (match_scratch:SI 1 "=&r"))]
11454 "TARGET_ARM"
11455 "#"
11456 "&& reload_completed"
11457 [(const_int 0)]
11458 "
11459 {
11460 arm_set_return_address (operands[0], operands[1]);
11461 DONE;
11462 }"
11463 )
11464
11465 \f
11466 ;; TLS support
11467
11468 (define_insn "load_tp_hard"
11469 [(set (match_operand:SI 0 "register_operand" "=r")
11470 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11471 "TARGET_HARD_TP"
11472 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11473 [(set_attr "predicable" "yes")
11474 (set_attr "type" "mrs")]
11475 )
11476
11477 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11478 (define_insn "load_tp_soft"
11479 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11480 (clobber (reg:SI LR_REGNUM))
11481 (clobber (reg:SI IP_REGNUM))
11482 (clobber (reg:CC CC_REGNUM))]
11483 "TARGET_SOFT_TP"
11484 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11485 [(set_attr "conds" "clob")
11486 (set_attr "type" "branch")]
11487 )
11488
11489 ;; tls descriptor call
11490 (define_insn "tlscall"
11491 [(set (reg:SI R0_REGNUM)
11492 (unspec:SI [(reg:SI R0_REGNUM)
11493 (match_operand:SI 0 "" "X")
11494 (match_operand 1 "" "")] UNSPEC_TLS))
11495 (clobber (reg:SI R1_REGNUM))
11496 (clobber (reg:SI LR_REGNUM))
11497 (clobber (reg:SI CC_REGNUM))]
11498 "TARGET_GNU2_TLS"
11499 {
11500 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11501 INTVAL (operands[1]));
11502 return "bl\\t%c0(tlscall)";
11503 }
11504 [(set_attr "conds" "clob")
11505 (set_attr "length" "4")
11506 (set_attr "type" "branch")]
11507 )
11508
11509 ;; For thread pointer builtin
11510 (define_expand "get_thread_pointersi"
11511 [(match_operand:SI 0 "s_register_operand" "=r")]
11512 ""
11513 "
11514 {
11515 arm_load_tp (operands[0]);
11516 DONE;
11517 }")
11518
11519 ;;
11520
11521 ;; We only care about the lower 16 bits of the constant
11522 ;; being inserted into the upper 16 bits of the register.
11523 (define_insn "*arm_movtas_ze"
11524 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11525 (const_int 16)
11526 (const_int 16))
11527 (match_operand:SI 1 "const_int_operand" ""))]
11528 "TARGET_HAVE_MOVT"
11529 "@
11530 movt%?\t%0, %L1
11531 movt\t%0, %L1"
11532 [(set_attr "arch" "32,v8mb")
11533 (set_attr "predicable" "yes")
11534 (set_attr "predicable_short_it" "no")
11535 (set_attr "length" "4")
11536 (set_attr "type" "alu_sreg")]
11537 )
11538
11539 (define_insn "*arm_rev"
11540 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11541 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11542 "arm_arch6"
11543 "@
11544 rev\t%0, %1
11545 rev%?\t%0, %1
11546 rev%?\t%0, %1"
11547 [(set_attr "arch" "t1,t2,32")
11548 (set_attr "length" "2,2,4")
11549 (set_attr "predicable" "no,yes,yes")
11550 (set_attr "predicable_short_it" "no")
11551 (set_attr "type" "rev")]
11552 )
11553
11554 (define_expand "arm_legacy_rev"
11555 [(set (match_operand:SI 2 "s_register_operand" "")
11556 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11557 (const_int 16))
11558 (match_dup 1)))
11559 (set (match_dup 2)
11560 (lshiftrt:SI (match_dup 2)
11561 (const_int 8)))
11562 (set (match_operand:SI 3 "s_register_operand" "")
11563 (rotatert:SI (match_dup 1)
11564 (const_int 8)))
11565 (set (match_dup 2)
11566 (and:SI (match_dup 2)
11567 (const_int -65281)))
11568 (set (match_operand:SI 0 "s_register_operand" "")
11569 (xor:SI (match_dup 3)
11570 (match_dup 2)))]
11571 "TARGET_32BIT"
11572 ""
11573 )
11574
11575 ;; Reuse temporaries to keep register pressure down.
11576 (define_expand "thumb_legacy_rev"
11577 [(set (match_operand:SI 2 "s_register_operand" "")
11578 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11579 (const_int 24)))
11580 (set (match_operand:SI 3 "s_register_operand" "")
11581 (lshiftrt:SI (match_dup 1)
11582 (const_int 24)))
11583 (set (match_dup 3)
11584 (ior:SI (match_dup 3)
11585 (match_dup 2)))
11586 (set (match_operand:SI 4 "s_register_operand" "")
11587 (const_int 16))
11588 (set (match_operand:SI 5 "s_register_operand" "")
11589 (rotatert:SI (match_dup 1)
11590 (match_dup 4)))
11591 (set (match_dup 2)
11592 (ashift:SI (match_dup 5)
11593 (const_int 24)))
11594 (set (match_dup 5)
11595 (lshiftrt:SI (match_dup 5)
11596 (const_int 24)))
11597 (set (match_dup 5)
11598 (ior:SI (match_dup 5)
11599 (match_dup 2)))
11600 (set (match_dup 5)
11601 (rotatert:SI (match_dup 5)
11602 (match_dup 4)))
11603 (set (match_operand:SI 0 "s_register_operand" "")
11604 (ior:SI (match_dup 5)
11605 (match_dup 3)))]
11606 "TARGET_THUMB"
11607 ""
11608 )
11609
11610 ;; ARM-specific expansion of signed mod by power of 2
11611 ;; using conditional negate.
11612 ;; For r0 % n where n is a power of 2 produce:
11613 ;; rsbs r1, r0, #0
11614 ;; and r0, r0, #(n - 1)
11615 ;; and r1, r1, #(n - 1)
11616 ;; rsbpl r0, r1, #0
11617
11618 (define_expand "modsi3"
11619 [(match_operand:SI 0 "register_operand" "")
11620 (match_operand:SI 1 "register_operand" "")
11621 (match_operand:SI 2 "const_int_operand" "")]
11622 "TARGET_32BIT"
11623 {
11624 HOST_WIDE_INT val = INTVAL (operands[2]);
11625
11626 if (val <= 0
11627 || exact_log2 (val) <= 0)
11628 FAIL;
11629
11630 rtx mask = GEN_INT (val - 1);
11631
11632 /* In the special case of x0 % 2 we can do the even shorter:
11633 cmp r0, #0
11634 and r0, r0, #1
11635 rsblt r0, r0, #0. */
11636
11637 if (val == 2)
11638 {
11639 rtx cc_reg = arm_gen_compare_reg (LT,
11640 operands[1], const0_rtx, NULL_RTX);
11641 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11642 rtx masked = gen_reg_rtx (SImode);
11643
11644 emit_insn (gen_andsi3 (masked, operands[1], mask));
11645 emit_move_insn (operands[0],
11646 gen_rtx_IF_THEN_ELSE (SImode, cond,
11647 gen_rtx_NEG (SImode,
11648 masked),
11649 masked));
11650 DONE;
11651 }
11652
11653 rtx neg_op = gen_reg_rtx (SImode);
11654 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11655 operands[1]));
11656
11657 /* Extract the condition register and mode. */
11658 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11659 rtx cc_reg = SET_DEST (cmp);
11660 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11661
11662 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11663
11664 rtx masked_neg = gen_reg_rtx (SImode);
11665 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11666
11667 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11668 during expand does not always work. Do an IF_THEN_ELSE instead. */
11669 emit_move_insn (operands[0],
11670 gen_rtx_IF_THEN_ELSE (SImode, cond,
11671 gen_rtx_NEG (SImode, masked_neg),
11672 operands[0]));
11673
11674
11675 DONE;
11676 }
11677 )
11678
11679 (define_expand "bswapsi2"
11680 [(set (match_operand:SI 0 "s_register_operand" "=r")
11681 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11682 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11683 "
11684 if (!arm_arch6)
11685 {
11686 rtx op2 = gen_reg_rtx (SImode);
11687 rtx op3 = gen_reg_rtx (SImode);
11688
11689 if (TARGET_THUMB)
11690 {
11691 rtx op4 = gen_reg_rtx (SImode);
11692 rtx op5 = gen_reg_rtx (SImode);
11693
11694 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11695 op2, op3, op4, op5));
11696 }
11697 else
11698 {
11699 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11700 op2, op3));
11701 }
11702
11703 DONE;
11704 }
11705 "
11706 )
11707
11708 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11709 ;; and unsigned variants, respectively. For rev16, expose
11710 ;; byte-swapping in the lower 16 bits only.
11711 (define_insn "*arm_revsh"
11712 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11713 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11714 "arm_arch6"
11715 "@
11716 revsh\t%0, %1
11717 revsh%?\t%0, %1
11718 revsh%?\t%0, %1"
11719 [(set_attr "arch" "t1,t2,32")
11720 (set_attr "length" "2,2,4")
11721 (set_attr "type" "rev")]
11722 )
11723
11724 (define_insn "*arm_rev16"
11725 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11726 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11727 "arm_arch6"
11728 "@
11729 rev16\t%0, %1
11730 rev16%?\t%0, %1
11731 rev16%?\t%0, %1"
11732 [(set_attr "arch" "t1,t2,32")
11733 (set_attr "length" "2,2,4")
11734 (set_attr "type" "rev")]
11735 )
11736
11737 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11738 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11739 ;; each valid permutation.
11740
11741 (define_insn "arm_rev16si2"
11742 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11743 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11744 (const_int 8))
11745 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11746 (and:SI (lshiftrt:SI (match_dup 1)
11747 (const_int 8))
11748 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11749 "arm_arch6
11750 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11751 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11752 "rev16\\t%0, %1"
11753 [(set_attr "arch" "t1,t2,32")
11754 (set_attr "length" "2,2,4")
11755 (set_attr "type" "rev")]
11756 )
11757
11758 (define_insn "arm_rev16si2_alt"
11759 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11760 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11761 (const_int 8))
11762 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11763 (and:SI (ashift:SI (match_dup 1)
11764 (const_int 8))
11765 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11766 "arm_arch6
11767 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11768 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11769 "rev16\\t%0, %1"
11770 [(set_attr "arch" "t1,t2,32")
11771 (set_attr "length" "2,2,4")
11772 (set_attr "type" "rev")]
11773 )
11774
11775 (define_expand "bswaphi2"
11776 [(set (match_operand:HI 0 "s_register_operand" "=r")
11777 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11778 "arm_arch6"
11779 ""
11780 )
11781
11782 ;; Patterns for LDRD/STRD in Thumb2 mode
11783
11784 (define_insn "*thumb2_ldrd"
11785 [(set (match_operand:SI 0 "s_register_operand" "=r")
11786 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11787 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11788 (set (match_operand:SI 3 "s_register_operand" "=r")
11789 (mem:SI (plus:SI (match_dup 1)
11790 (match_operand:SI 4 "const_int_operand" ""))))]
11791 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11792 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11793 && (operands_ok_ldrd_strd (operands[0], operands[3],
11794 operands[1], INTVAL (operands[2]),
11795 false, true))"
11796 "ldrd%?\t%0, %3, [%1, %2]"
11797 [(set_attr "type" "load_8")
11798 (set_attr "predicable" "yes")
11799 (set_attr "predicable_short_it" "no")])
11800
11801 (define_insn "*thumb2_ldrd_base"
11802 [(set (match_operand:SI 0 "s_register_operand" "=r")
11803 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11804 (set (match_operand:SI 2 "s_register_operand" "=r")
11805 (mem:SI (plus:SI (match_dup 1)
11806 (const_int 4))))]
11807 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11808 && (operands_ok_ldrd_strd (operands[0], operands[2],
11809 operands[1], 0, false, true))"
11810 "ldrd%?\t%0, %2, [%1]"
11811 [(set_attr "type" "load_8")
11812 (set_attr "predicable" "yes")
11813 (set_attr "predicable_short_it" "no")])
11814
11815 (define_insn "*thumb2_ldrd_base_neg"
11816 [(set (match_operand:SI 0 "s_register_operand" "=r")
11817 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11818 (const_int -4))))
11819 (set (match_operand:SI 2 "s_register_operand" "=r")
11820 (mem:SI (match_dup 1)))]
11821 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11822 && (operands_ok_ldrd_strd (operands[0], operands[2],
11823 operands[1], -4, false, true))"
11824 "ldrd%?\t%0, %2, [%1, #-4]"
11825 [(set_attr "type" "load_8")
11826 (set_attr "predicable" "yes")
11827 (set_attr "predicable_short_it" "no")])
11828
11829 (define_insn "*thumb2_strd"
11830 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11831 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11832 (match_operand:SI 2 "s_register_operand" "r"))
11833 (set (mem:SI (plus:SI (match_dup 0)
11834 (match_operand:SI 3 "const_int_operand" "")))
11835 (match_operand:SI 4 "s_register_operand" "r"))]
11836 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11837 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11838 && (operands_ok_ldrd_strd (operands[2], operands[4],
11839 operands[0], INTVAL (operands[1]),
11840 false, false))"
11841 "strd%?\t%2, %4, [%0, %1]"
11842 [(set_attr "type" "store_8")
11843 (set_attr "predicable" "yes")
11844 (set_attr "predicable_short_it" "no")])
11845
11846 (define_insn "*thumb2_strd_base"
11847 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11848 (match_operand:SI 1 "s_register_operand" "r"))
11849 (set (mem:SI (plus:SI (match_dup 0)
11850 (const_int 4)))
11851 (match_operand:SI 2 "s_register_operand" "r"))]
11852 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11853 && (operands_ok_ldrd_strd (operands[1], operands[2],
11854 operands[0], 0, false, false))"
11855 "strd%?\t%1, %2, [%0]"
11856 [(set_attr "type" "store_8")
11857 (set_attr "predicable" "yes")
11858 (set_attr "predicable_short_it" "no")])
11859
11860 (define_insn "*thumb2_strd_base_neg"
11861 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11862 (const_int -4)))
11863 (match_operand:SI 1 "s_register_operand" "r"))
11864 (set (mem:SI (match_dup 0))
11865 (match_operand:SI 2 "s_register_operand" "r"))]
11866 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11867 && (operands_ok_ldrd_strd (operands[1], operands[2],
11868 operands[0], -4, false, false))"
11869 "strd%?\t%1, %2, [%0, #-4]"
11870 [(set_attr "type" "store_8")
11871 (set_attr "predicable" "yes")
11872 (set_attr "predicable_short_it" "no")])
11873
11874 ;; ARMv8 CRC32 instructions.
11875 (define_insn "<crc_variant>"
11876 [(set (match_operand:SI 0 "s_register_operand" "=r")
11877 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11878 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11879 CRC))]
11880 "TARGET_CRC32"
11881 "<crc_variant>\\t%0, %1, %2"
11882 [(set_attr "type" "crc")
11883 (set_attr "conds" "unconditional")]
11884 )
11885
11886 ;; Load the load/store double peephole optimizations.
11887 (include "ldrdstrd.md")
11888
11889 ;; Load the load/store multiple patterns
11890 (include "ldmstm.md")
11891
11892 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11893 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11894 ;; The operands are validated through the load_multiple_operation
11895 ;; match_parallel predicate rather than through constraints so enable it only
11896 ;; after reload.
11897 (define_insn "*load_multiple"
11898 [(match_parallel 0 "load_multiple_operation"
11899 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11900 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11901 ])]
11902 "TARGET_32BIT && reload_completed"
11903 "*
11904 {
11905 arm_output_multireg_pop (operands, /*return_pc=*/false,
11906 /*cond=*/const_true_rtx,
11907 /*reverse=*/false,
11908 /*update=*/false);
11909 return \"\";
11910 }
11911 "
11912 [(set_attr "predicable" "yes")]
11913 )
11914
11915 (define_expand "copysignsf3"
11916 [(match_operand:SF 0 "register_operand")
11917 (match_operand:SF 1 "register_operand")
11918 (match_operand:SF 2 "register_operand")]
11919 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11920 "{
11921 emit_move_insn (operands[0], operands[2]);
11922 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11923 GEN_INT (31), GEN_INT (0),
11924 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11925 DONE;
11926 }"
11927 )
11928
11929 (define_expand "copysigndf3"
11930 [(match_operand:DF 0 "register_operand")
11931 (match_operand:DF 1 "register_operand")
11932 (match_operand:DF 2 "register_operand")]
11933 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11934 "{
11935 rtx op0_low = gen_lowpart (SImode, operands[0]);
11936 rtx op0_high = gen_highpart (SImode, operands[0]);
11937 rtx op1_low = gen_lowpart (SImode, operands[1]);
11938 rtx op1_high = gen_highpart (SImode, operands[1]);
11939 rtx op2_high = gen_highpart (SImode, operands[2]);
11940
11941 rtx scratch1 = gen_reg_rtx (SImode);
11942 rtx scratch2 = gen_reg_rtx (SImode);
11943 emit_move_insn (scratch1, op2_high);
11944 emit_move_insn (scratch2, op1_high);
11945
11946 emit_insn(gen_rtx_SET(scratch1,
11947 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11948 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11949 emit_move_insn (op0_low, op1_low);
11950 emit_move_insn (op0_high, scratch2);
11951
11952 DONE;
11953 }"
11954 )
11955
11956 ;; movmisalign patterns for HImode and SImode.
11957 (define_expand "movmisalign<mode>"
11958 [(match_operand:HSI 0 "general_operand")
11959 (match_operand:HSI 1 "general_operand")]
11960 "unaligned_access"
11961 {
11962 /* This pattern is not permitted to fail during expansion: if both arguments
11963 are non-registers (e.g. memory := constant), force operand 1 into a
11964 register. */
11965 rtx (* gen_unaligned_load)(rtx, rtx);
11966 rtx tmp_dest = operands[0];
11967 if (!s_register_operand (operands[0], <MODE>mode)
11968 && !s_register_operand (operands[1], <MODE>mode))
11969 operands[1] = force_reg (<MODE>mode, operands[1]);
11970
11971 if (<MODE>mode == HImode)
11972 {
11973 gen_unaligned_load = gen_unaligned_loadhiu;
11974 tmp_dest = gen_reg_rtx (SImode);
11975 }
11976 else
11977 gen_unaligned_load = gen_unaligned_loadsi;
11978
11979 if (MEM_P (operands[1]))
11980 {
11981 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11982 if (<MODE>mode == HImode)
11983 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11984 }
11985 else
11986 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11987
11988 DONE;
11989 })
11990
11991 (define_insn "<cdp>"
11992 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11993 (match_operand:SI 1 "immediate_operand" "n")
11994 (match_operand:SI 2 "immediate_operand" "n")
11995 (match_operand:SI 3 "immediate_operand" "n")
11996 (match_operand:SI 4 "immediate_operand" "n")
11997 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11998 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11999 {
12000 arm_const_bounds (operands[0], 0, 16);
12001 arm_const_bounds (operands[1], 0, 16);
12002 arm_const_bounds (operands[2], 0, (1 << 5));
12003 arm_const_bounds (operands[3], 0, (1 << 5));
12004 arm_const_bounds (operands[4], 0, (1 << 5));
12005 arm_const_bounds (operands[5], 0, 8);
12006 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
12007 }
12008 [(set_attr "length" "4")
12009 (set_attr "type" "coproc")])
12010
12011 (define_insn "*ldc"
12012 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12013 (match_operand:SI 1 "immediate_operand" "n")
12014 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
12015 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
12016 {
12017 arm_const_bounds (operands[0], 0, 16);
12018 arm_const_bounds (operands[1], 0, (1 << 5));
12019 return "<ldc>\\tp%c0, CR%c1, %2";
12020 }
12021 [(set_attr "length" "4")
12022 (set_attr "type" "coproc")])
12023
12024 (define_insn "*stc"
12025 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12026 (match_operand:SI 1 "immediate_operand" "n")
12027 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
12028 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
12029 {
12030 arm_const_bounds (operands[0], 0, 16);
12031 arm_const_bounds (operands[1], 0, (1 << 5));
12032 return "<stc>\\tp%c0, CR%c1, %2";
12033 }
12034 [(set_attr "length" "4")
12035 (set_attr "type" "coproc")])
12036
12037 (define_expand "<ldc>"
12038 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12039 (match_operand:SI 1 "immediate_operand")
12040 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
12041 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
12042
12043 (define_expand "<stc>"
12044 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
12045 (match_operand:SI 1 "immediate_operand")
12046 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
12047 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
12048
12049 (define_insn "<mcr>"
12050 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12051 (match_operand:SI 1 "immediate_operand" "n")
12052 (match_operand:SI 2 "s_register_operand" "r")
12053 (match_operand:SI 3 "immediate_operand" "n")
12054 (match_operand:SI 4 "immediate_operand" "n")
12055 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
12056 (use (match_dup 2))]
12057 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
12058 {
12059 arm_const_bounds (operands[0], 0, 16);
12060 arm_const_bounds (operands[1], 0, 8);
12061 arm_const_bounds (operands[3], 0, (1 << 5));
12062 arm_const_bounds (operands[4], 0, (1 << 5));
12063 arm_const_bounds (operands[5], 0, 8);
12064 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
12065 }
12066 [(set_attr "length" "4")
12067 (set_attr "type" "coproc")])
12068
12069 (define_insn "<mrc>"
12070 [(set (match_operand:SI 0 "s_register_operand" "=r")
12071 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
12072 (match_operand:SI 2 "immediate_operand" "n")
12073 (match_operand:SI 3 "immediate_operand" "n")
12074 (match_operand:SI 4 "immediate_operand" "n")
12075 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
12076 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
12077 {
12078 arm_const_bounds (operands[1], 0, 16);
12079 arm_const_bounds (operands[2], 0, 8);
12080 arm_const_bounds (operands[3], 0, (1 << 5));
12081 arm_const_bounds (operands[4], 0, (1 << 5));
12082 arm_const_bounds (operands[5], 0, 8);
12083 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
12084 }
12085 [(set_attr "length" "4")
12086 (set_attr "type" "coproc")])
12087
12088 (define_insn "<mcrr>"
12089 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
12090 (match_operand:SI 1 "immediate_operand" "n")
12091 (match_operand:DI 2 "s_register_operand" "r")
12092 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
12093 (use (match_dup 2))]
12094 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
12095 {
12096 arm_const_bounds (operands[0], 0, 16);
12097 arm_const_bounds (operands[1], 0, 8);
12098 arm_const_bounds (operands[3], 0, (1 << 5));
12099 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
12100 }
12101 [(set_attr "length" "4")
12102 (set_attr "type" "coproc")])
12103
12104 (define_insn "<mrrc>"
12105 [(set (match_operand:DI 0 "s_register_operand" "=r")
12106 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
12107 (match_operand:SI 2 "immediate_operand" "n")
12108 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
12109 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
12110 {
12111 arm_const_bounds (operands[1], 0, 16);
12112 arm_const_bounds (operands[2], 0, 8);
12113 arm_const_bounds (operands[3], 0, (1 << 5));
12114 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
12115 }
12116 [(set_attr "length" "4")
12117 (set_attr "type" "coproc")])
12118
12119 ;; Vector bits common to IWMMXT and Neon
12120 (include "vec-common.md")
12121 ;; Load the Intel Wireless Multimedia Extension patterns
12122 (include "iwmmxt.md")
12123 ;; Load the VFP co-processor patterns
12124 (include "vfp.md")
12125 ;; Thumb-1 patterns
12126 (include "thumb1.md")
12127 ;; Thumb-2 patterns
12128 (include "thumb2.md")
12129 ;; Neon patterns
12130 (include "neon.md")
12131 ;; Crypto patterns
12132 (include "crypto.md")
12133 ;; Synchronization Primitives
12134 (include "sync.md")
12135 ;; Fixed-point patterns
12136 (include "arm-fixed.md")